<?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 - RPGMaker VX/VXAce (RGSS2/3) Engines]]></title>
		<link>https://www.save-point.org/</link>
		<description><![CDATA[Save-Point - https://www.save-point.org]]></description>
		<pubDate>Thu, 30 Apr 2026 18:42:13 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[SCREEN SIZE for RMVXAce]]></title>
			<link>https://www.save-point.org/thread-13460.html</link>
			<pubDate>Mon, 13 Apr 2026 18:41:49 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=5">DerVVulfman</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-13460.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">SCREEN SIZE for RMVXAce</span></span><br />
<span style="font-size: medium;" class="mycode_size">Version: 1.0</span></div>
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Introduction</span></span><br />
I had been tinkering with the manipulation of the available gaming area for RPGMaker XP games.  And I did well with a barebones script that did not require the use of any external .DLL outside of Win32 manipulations, a script based upon the work of Selwyn (formerly Squall).<br />
<br />
This specific script is an adapation of my XP version,  but altered for use with RPGMaker VX Ace. Simpler in design due to updates made in the Viewport class and Weather system.<br />
<br />
<span style="font-style: italic;" class="mycode_i"><span style="color: #E82A1F;" class="mycode_color">The Game.Exe's Fullscreen mode reverts to a fixed 640x480 resolution so the [ALT]+[ENTER] key combination is disabled. Fullscreen mode is literally disabled by intent with this setup.</span></span><br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Screenshots</span></span><br />
None.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Script</span></span><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='+';}"/> Instruction/Header</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** SCREEN SIZE for VXACE<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Version 1.0<br />
#&nbsp;&nbsp;&nbsp;&nbsp;By DerVVulfman<br />
#&nbsp;&nbsp;&nbsp;&nbsp;04-13-2026 (MM-DD-YYYY)<br />
#&nbsp;&nbsp;&nbsp;&nbsp;RGSS3 / RPGMaker VX Ace<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;INTRODUCTION:<br />
#&nbsp;&nbsp;=============<br />
#&nbsp;&nbsp;I had been tinkering with the manipulation of the available gaming area for<br />
#&nbsp;&nbsp;RPGMaker XP games.&nbsp;&nbsp;And I did well with a barebones script that did not re-<br />
#&nbsp;&nbsp;quire the use of any external .DLL outside of Win32 manipulations, a script<br />
#&nbsp;&nbsp;based upon the work of Selwyn (formerly Squall).<br />
#<br />
#&nbsp;&nbsp;This specific script is an adapation of my XP version,&nbsp;&nbsp;but altered for use<br />
#&nbsp;&nbsp;with RPGMaker VX Ace. Simpler in design due to updates made in the Viewport<br />
#&nbsp;&nbsp;class and Weather system.<br />
#<br />
#&nbsp;&nbsp;ALERT: The Game.Exe's Fullscreen mode reverts to a fixed 640x480 resolution<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; so the [ALT]+[ENTER] key combination is disabled. Fullscreen mode is<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; literally disabled by intent with this setup.<br />
#<br />
#<br />
#&nbsp;&nbsp; ------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;INSTRUCTIONS:<br />
#&nbsp;&nbsp;=============<br />
#&nbsp;&nbsp;I would hope this is clear.&nbsp;&nbsp;It is mostly plug-and-play, only requiring you<br />
#&nbsp;&nbsp;to set some configurable values within the ScrnSize module&nbsp;&nbsp;at the very top<br />
#&nbsp;&nbsp;of the actual system code.&nbsp;&nbsp;And all the variable options have detailed des-<br />
#&nbsp;&nbsp;criptions of what is being set.<br />
#<br />
#&nbsp;&nbsp;NOTE: If you are using&nbsp;&nbsp;other scripts that perform alterations&nbsp;&nbsp;to the size<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of screen contents (YanFly's Core as an example), ensure both are set<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to the same resolution.<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;COMPATABILITY:<br />
#&nbsp;&nbsp;==============<br />
#&nbsp;&nbsp;Designed for RPGMaker VXAce.<br />
#<br />
#&nbsp;&nbsp;Alters the screen size, so other scripts that adjust viewport settings will<br />
#&nbsp;&nbsp;need to be likewise altered.<br />
#<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;CREDITS AND THANKS:<br />
#&nbsp;&nbsp;===================<br />
#&nbsp;&nbsp;The very basics of this system&nbsp;&nbsp;comes from the DLL-free version of Selwyn's<br />
#&nbsp;&nbsp;resolution script. <br />
#<br />
#&nbsp;&nbsp;And thanks goes to ViperDamascus&nbsp;&nbsp;who was looking for a script&nbsp;&nbsp;to increase <br />
#&nbsp;&nbsp;VXAce's screen size beyond the 640x480 maximum.<br />
#<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;TERMS and CONDITIONS:<br />
#&nbsp;&nbsp;=====================<br />
#&nbsp;&nbsp;Free for use, even in commercial scripts. However, I require due credit for<br />
#&nbsp;&nbsp;myself, Selwyn who crafted the basics, and ViperDamascus for the request.<br />
#<br />
#<br />
#==============================================================================<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** ScrnSize<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This module handles the adjustable screen size for games that utilize<br />
#&nbsp;&nbsp;resolution scripts to alter game window dimensions.<br />
#==============================================================================<br />
<br />
module ScrnSize<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;# GAME SCREEN RESOLUTION<br />
&nbsp;&nbsp;# ======================<br />
&nbsp;&nbsp;# The absolute necessity... defining the size of the visible area of your<br />
&nbsp;&nbsp;# game on the screen. You will see below some dimensions tested, and then<br />
&nbsp;&nbsp;# commented out. Even reducing the size to older RPGMaker 2000 scale exe-<br />
&nbsp;&nbsp;# cuted just fine.<br />
&nbsp;&nbsp;# &lt; -- IT IS RECOMMENDED THAT THE DEFINED VALUES BE MULTIPLES OF 32! -- &gt;<br />
&nbsp;&nbsp;# -----------------------------------------------------------------------<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp;&nbsp;&nbsp;&nbsp; = 1280&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Screen area width in pixels<br />
&nbsp;&nbsp;&nbsp;&nbsp;Height&nbsp;&nbsp;&nbsp;&nbsp;= 736&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Screen area height in pixels.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp;&nbsp;&nbsp;&nbsp; = 640<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Height&nbsp;&nbsp;&nbsp;&nbsp;= 480<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp;&nbsp;&nbsp;&nbsp; = 320<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Height&nbsp;&nbsp;&nbsp;&nbsp;= 200<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;# GAME INI NAMING<br />
&nbsp;&nbsp;# ===============<br />
&nbsp;&nbsp;# A necessity if you are renaming the Game Executable (eg Game.exe). When<br />
&nbsp;&nbsp;# your game/project is run, it looks for its requisite .ini file which it<br />
&nbsp;&nbsp;# assumes to have the same name as its executable. Many leave the name of<br />
&nbsp;&nbsp;# the executable alone. But if you choose to rename Game.exe to Trek.exe,<br />
&nbsp;&nbsp;# it will search for Trek.ini. And if the assumed ini does not exist, the<br />
&nbsp;&nbsp;# game will fail.<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# The resolution changing system relies upon retriving the windows handle<br />
&nbsp;&nbsp;# for the game when it executes.&nbsp;&nbsp;And for this, it needs the current name<br />
&nbsp;&nbsp;# of the Game's INI file.&nbsp;&nbsp;So if you do change the name of the executable<br />
&nbsp;&nbsp;# (and thus the name of the INI), it needs the name defined below.<br />
&nbsp;&nbsp;# -----------------------------------------------------------------------<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;INI_Name&nbsp;&nbsp;= 'Game.ini'<br />
<br />
<br />
&nbsp;&nbsp;# GAME EXECUTION SPEED<br />
&nbsp;&nbsp;# ====================<br />
&nbsp;&nbsp;# This is an old trick,&nbsp;&nbsp;changing the speed of the executable to make the<br />
&nbsp;&nbsp;# game itself run faster.&nbsp;&nbsp;RPGMaker XP was set to a default 40 frames per<br />
&nbsp;&nbsp;# second while RPGMaker VX and VXAce to a native 60 frames per second.<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# -----------------------------------------------------------------------<br />
&nbsp;&nbsp;# Changing this value affects all...&nbsp;&nbsp;script/code speed,&nbsp;&nbsp;character speed<br />
&nbsp;&nbsp;# in the fieldmap, battle animations, and the like.<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# RANGE: 10-120. VXAce will not exceed 120fps nor go slower than 10.<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# NOTE: Smooth mode refreshes graphics ever frame based on this value.<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Normal mode only refreshes every other frame.<br />
&nbsp;&nbsp;# -----------------------------------------------------------------------<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;Graphics.frame_rate = 40&nbsp;&nbsp;<br />
<br />
<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ●● Resolution<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This module uses the Win32API to connect to the RPGMaker XP game window and<br />
#&nbsp;&nbsp;re-sizes the window based on the game developer's preferences.<br />
#==============================================================================<br />
<br />
module Resolution<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● instance variables<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;attr_reader :state<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● initialize<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Acquire desired window settings from configuration<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ==================================================<br />
&nbsp;&nbsp;&nbsp;&nbsp;@reswidth&nbsp;&nbsp; = ScrnSize::Width<br />
&nbsp;&nbsp;&nbsp;&nbsp;@resheight&nbsp;&nbsp;= ScrnSize::Height<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Set instance variables for calling basic Win32 functions<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ========================================================&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ini&nbsp;&nbsp;&nbsp;&nbsp; = Win32API.new('kernel32', 'GetPrivateProfileString','PPPPLP', 'L')<br />
&nbsp;&nbsp;&nbsp;&nbsp;title&nbsp;&nbsp; = "&#92;0" * 256<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Get Window Title<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ================================================&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ini.call('Game', 'Title', '', title, 256, '.&#92;&#92;' + ScrnSize::INI_Name)<br />
&nbsp;&nbsp;&nbsp;&nbsp;title.delete!("&#92;0")<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Acquire Metrics from the Win32 API<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ================================================&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;@window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = Win32API.new('user32', 'FindWindow',&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'PP', <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'I').call("RGSS Player", title)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_long = Win32API.new('user32', 'SetWindowLong',&nbsp;&nbsp;&nbsp;&nbsp;'LIL', 'L')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_pos&nbsp;&nbsp;= Win32API.new('user32', 'SetWindowPos',&nbsp;&nbsp;&nbsp;&nbsp; 'LLIIIII', 'I')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@gsm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Win32API.new('user32', 'GetSystemMetrics', 'I', 'I')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@gcr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Win32API.new('user32', 'GetClientRect',&nbsp;&nbsp;&nbsp;&nbsp;'LP', 'I')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@kbe&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Win32API.new('user32', 'keybd_event',&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'LLLL', '')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@gaks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = Win32API.new('user32', 'GetAsyncKeyState', 'L', 'I')<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Render message and exit if size is not supported<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ================================================<br />
&nbsp;&nbsp;&nbsp;&nbsp;@default_size = self.size<br />
&nbsp;&nbsp;&nbsp;&nbsp;if size[0] &lt; @reswidth or size[1] &lt; @resheight<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("&#92;"#{title}&#92;" requires a minimum screen resolution " +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"of [#{@reswidth} x #{@resheight}]&#92;r&#92;n&#92;r&#92;n" +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&#92;tYour Resolution: [#{@default_size[0]} x #{@default_size[1]}]")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Apply Resolution Change<br />
&nbsp;&nbsp;&nbsp;&nbsp;# =======================<br />
&nbsp;&nbsp;&nbsp;&nbsp;@state = "default"<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.default<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● fullscreen<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def fullscreen<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@default_size = size<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_long.call(@window, -16, 0x14000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_pos.call(@window, -1, 0, 0, (@reswidth+2), (@resheight+2), 64)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@state = "fullscreen"<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● default<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def default<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;x = @default_size[0] / 2 - ((@reswidth/2) + 3)<br />
&nbsp;&nbsp;&nbsp;&nbsp;y = @default_size[1] / 2 - ((@resheight/2) + 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_long.call(@window, -16, 0x14CA0000)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_pos.call(@window, 0, x, y, (@reswidth+8), (@resheight+27), 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@state = "default"<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● trigger?(key)<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def trigger?(key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return @gaks.call(key) &amp; 0x01 == 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● private<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;private :fullscreen<br />
&nbsp;&nbsp;private :default<br />
&nbsp;&nbsp;private :trigger?<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● size<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def size<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;width&nbsp;&nbsp; = @gsm.call(0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;height&nbsp;&nbsp;= @gsm.call(1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;return width, height<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● change<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def change<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @state == "default"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.fullscreen<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.default<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● update<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if trigger?(121) # F10<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.change<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;if Input.trigger?(Input::ALT) or Input.press?(Input::ALT)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@kbe.call(18, 0, 2, 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● module functions<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;module_function :initialize<br />
&nbsp;&nbsp;module_function :fullscreen<br />
&nbsp;&nbsp;module_function :default<br />
&nbsp;&nbsp;module_function :trigger?<br />
&nbsp;&nbsp;module_function :size<br />
&nbsp;&nbsp;module_function :change<br />
&nbsp;&nbsp;module_function :update<br />
&nbsp;&nbsp;#<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ●● Input<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;A class that handles input data from a gamepad or keyboard.<br />
#==============================================================================<br />
<br />
class &lt;&lt; Input<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● Alias Listings (with F12 Stack prevention)<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;alias res_update update unless &#36;@<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● Input.update<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def Input.update<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Perform the original call<br />
&nbsp;&nbsp;&nbsp;&nbsp;res_update<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Update the Resolution<br />
&nbsp;&nbsp;&nbsp;&nbsp;Resolution.update<br />
&nbsp;&nbsp;end<br />
end<br />
<br />
<br />
<br />
# Execute at start<br />
Resolution.initialize</code></div></div></div>
		</div>
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Instructions</span></span><br />
Plenty, and in the script.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Compatibility</span></span><br />
Designed for RPGMaker XP<br />
<br />
Alters the screen size, so other scripts that adjust viewport settings will need to be likewise altered.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Credits and Thanks</span></span><br />
The very basics of this system  comes from the DLL-free version of Selwyn's resolution script. <br />
<br />
And thanks goes to ViperDamascus  who was looking for a script  to increase VXAce's screen size beyond the 640x480 maximum.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Terms and Conditions</span></span><br />
Free for use, even in commercial scripts. However, I require due credit for myself, Selwyn who crafted the basics, and ViperDamascus for the request.]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">SCREEN SIZE for RMVXAce</span></span><br />
<span style="font-size: medium;" class="mycode_size">Version: 1.0</span></div>
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Introduction</span></span><br />
I had been tinkering with the manipulation of the available gaming area for RPGMaker XP games.  And I did well with a barebones script that did not require the use of any external .DLL outside of Win32 manipulations, a script based upon the work of Selwyn (formerly Squall).<br />
<br />
This specific script is an adapation of my XP version,  but altered for use with RPGMaker VX Ace. Simpler in design due to updates made in the Viewport class and Weather system.<br />
<br />
<span style="font-style: italic;" class="mycode_i"><span style="color: #E82A1F;" class="mycode_color">The Game.Exe's Fullscreen mode reverts to a fixed 640x480 resolution so the [ALT]+[ENTER] key combination is disabled. Fullscreen mode is literally disabled by intent with this setup.</span></span><br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Screenshots</span></span><br />
None.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Script</span></span><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='+';}"/> Instruction/Header</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** SCREEN SIZE for VXACE<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Version 1.0<br />
#&nbsp;&nbsp;&nbsp;&nbsp;By DerVVulfman<br />
#&nbsp;&nbsp;&nbsp;&nbsp;04-13-2026 (MM-DD-YYYY)<br />
#&nbsp;&nbsp;&nbsp;&nbsp;RGSS3 / RPGMaker VX Ace<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;INTRODUCTION:<br />
#&nbsp;&nbsp;=============<br />
#&nbsp;&nbsp;I had been tinkering with the manipulation of the available gaming area for<br />
#&nbsp;&nbsp;RPGMaker XP games.&nbsp;&nbsp;And I did well with a barebones script that did not re-<br />
#&nbsp;&nbsp;quire the use of any external .DLL outside of Win32 manipulations, a script<br />
#&nbsp;&nbsp;based upon the work of Selwyn (formerly Squall).<br />
#<br />
#&nbsp;&nbsp;This specific script is an adapation of my XP version,&nbsp;&nbsp;but altered for use<br />
#&nbsp;&nbsp;with RPGMaker VX Ace. Simpler in design due to updates made in the Viewport<br />
#&nbsp;&nbsp;class and Weather system.<br />
#<br />
#&nbsp;&nbsp;ALERT: The Game.Exe's Fullscreen mode reverts to a fixed 640x480 resolution<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; so the [ALT]+[ENTER] key combination is disabled. Fullscreen mode is<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; literally disabled by intent with this setup.<br />
#<br />
#<br />
#&nbsp;&nbsp; ------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;INSTRUCTIONS:<br />
#&nbsp;&nbsp;=============<br />
#&nbsp;&nbsp;I would hope this is clear.&nbsp;&nbsp;It is mostly plug-and-play, only requiring you<br />
#&nbsp;&nbsp;to set some configurable values within the ScrnSize module&nbsp;&nbsp;at the very top<br />
#&nbsp;&nbsp;of the actual system code.&nbsp;&nbsp;And all the variable options have detailed des-<br />
#&nbsp;&nbsp;criptions of what is being set.<br />
#<br />
#&nbsp;&nbsp;NOTE: If you are using&nbsp;&nbsp;other scripts that perform alterations&nbsp;&nbsp;to the size<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of screen contents (YanFly's Core as an example), ensure both are set<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to the same resolution.<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;COMPATABILITY:<br />
#&nbsp;&nbsp;==============<br />
#&nbsp;&nbsp;Designed for RPGMaker VXAce.<br />
#<br />
#&nbsp;&nbsp;Alters the screen size, so other scripts that adjust viewport settings will<br />
#&nbsp;&nbsp;need to be likewise altered.<br />
#<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;CREDITS AND THANKS:<br />
#&nbsp;&nbsp;===================<br />
#&nbsp;&nbsp;The very basics of this system&nbsp;&nbsp;comes from the DLL-free version of Selwyn's<br />
#&nbsp;&nbsp;resolution script. <br />
#<br />
#&nbsp;&nbsp;And thanks goes to ViperDamascus&nbsp;&nbsp;who was looking for a script&nbsp;&nbsp;to increase <br />
#&nbsp;&nbsp;VXAce's screen size beyond the 640x480 maximum.<br />
#<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;TERMS and CONDITIONS:<br />
#&nbsp;&nbsp;=====================<br />
#&nbsp;&nbsp;Free for use, even in commercial scripts. However, I require due credit for<br />
#&nbsp;&nbsp;myself, Selwyn who crafted the basics, and ViperDamascus for the request.<br />
#<br />
#<br />
#==============================================================================<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** ScrnSize<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This module handles the adjustable screen size for games that utilize<br />
#&nbsp;&nbsp;resolution scripts to alter game window dimensions.<br />
#==============================================================================<br />
<br />
module ScrnSize<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;# GAME SCREEN RESOLUTION<br />
&nbsp;&nbsp;# ======================<br />
&nbsp;&nbsp;# The absolute necessity... defining the size of the visible area of your<br />
&nbsp;&nbsp;# game on the screen. You will see below some dimensions tested, and then<br />
&nbsp;&nbsp;# commented out. Even reducing the size to older RPGMaker 2000 scale exe-<br />
&nbsp;&nbsp;# cuted just fine.<br />
&nbsp;&nbsp;# &lt; -- IT IS RECOMMENDED THAT THE DEFINED VALUES BE MULTIPLES OF 32! -- &gt;<br />
&nbsp;&nbsp;# -----------------------------------------------------------------------<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp;&nbsp;&nbsp;&nbsp; = 1280&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Screen area width in pixels<br />
&nbsp;&nbsp;&nbsp;&nbsp;Height&nbsp;&nbsp;&nbsp;&nbsp;= 736&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Screen area height in pixels.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp;&nbsp;&nbsp;&nbsp; = 640<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Height&nbsp;&nbsp;&nbsp;&nbsp;= 480<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp;&nbsp;&nbsp;&nbsp; = 320<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Height&nbsp;&nbsp;&nbsp;&nbsp;= 200<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;# GAME INI NAMING<br />
&nbsp;&nbsp;# ===============<br />
&nbsp;&nbsp;# A necessity if you are renaming the Game Executable (eg Game.exe). When<br />
&nbsp;&nbsp;# your game/project is run, it looks for its requisite .ini file which it<br />
&nbsp;&nbsp;# assumes to have the same name as its executable. Many leave the name of<br />
&nbsp;&nbsp;# the executable alone. But if you choose to rename Game.exe to Trek.exe,<br />
&nbsp;&nbsp;# it will search for Trek.ini. And if the assumed ini does not exist, the<br />
&nbsp;&nbsp;# game will fail.<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# The resolution changing system relies upon retriving the windows handle<br />
&nbsp;&nbsp;# for the game when it executes.&nbsp;&nbsp;And for this, it needs the current name<br />
&nbsp;&nbsp;# of the Game's INI file.&nbsp;&nbsp;So if you do change the name of the executable<br />
&nbsp;&nbsp;# (and thus the name of the INI), it needs the name defined below.<br />
&nbsp;&nbsp;# -----------------------------------------------------------------------<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;INI_Name&nbsp;&nbsp;= 'Game.ini'<br />
<br />
<br />
&nbsp;&nbsp;# GAME EXECUTION SPEED<br />
&nbsp;&nbsp;# ====================<br />
&nbsp;&nbsp;# This is an old trick,&nbsp;&nbsp;changing the speed of the executable to make the<br />
&nbsp;&nbsp;# game itself run faster.&nbsp;&nbsp;RPGMaker XP was set to a default 40 frames per<br />
&nbsp;&nbsp;# second while RPGMaker VX and VXAce to a native 60 frames per second.<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# -----------------------------------------------------------------------<br />
&nbsp;&nbsp;# Changing this value affects all...&nbsp;&nbsp;script/code speed,&nbsp;&nbsp;character speed<br />
&nbsp;&nbsp;# in the fieldmap, battle animations, and the like.<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# RANGE: 10-120. VXAce will not exceed 120fps nor go slower than 10.<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# NOTE: Smooth mode refreshes graphics ever frame based on this value.<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Normal mode only refreshes every other frame.<br />
&nbsp;&nbsp;# -----------------------------------------------------------------------<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;Graphics.frame_rate = 40&nbsp;&nbsp;<br />
<br />
<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ●● Resolution<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This module uses the Win32API to connect to the RPGMaker XP game window and<br />
#&nbsp;&nbsp;re-sizes the window based on the game developer's preferences.<br />
#==============================================================================<br />
<br />
module Resolution<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● instance variables<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;attr_reader :state<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● initialize<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Acquire desired window settings from configuration<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ==================================================<br />
&nbsp;&nbsp;&nbsp;&nbsp;@reswidth&nbsp;&nbsp; = ScrnSize::Width<br />
&nbsp;&nbsp;&nbsp;&nbsp;@resheight&nbsp;&nbsp;= ScrnSize::Height<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Set instance variables for calling basic Win32 functions<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ========================================================&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ini&nbsp;&nbsp;&nbsp;&nbsp; = Win32API.new('kernel32', 'GetPrivateProfileString','PPPPLP', 'L')<br />
&nbsp;&nbsp;&nbsp;&nbsp;title&nbsp;&nbsp; = "&#92;0" * 256<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Get Window Title<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ================================================&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ini.call('Game', 'Title', '', title, 256, '.&#92;&#92;' + ScrnSize::INI_Name)<br />
&nbsp;&nbsp;&nbsp;&nbsp;title.delete!("&#92;0")<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Acquire Metrics from the Win32 API<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ================================================&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;@window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = Win32API.new('user32', 'FindWindow',&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'PP', <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'I').call("RGSS Player", title)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_long = Win32API.new('user32', 'SetWindowLong',&nbsp;&nbsp;&nbsp;&nbsp;'LIL', 'L')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_pos&nbsp;&nbsp;= Win32API.new('user32', 'SetWindowPos',&nbsp;&nbsp;&nbsp;&nbsp; 'LLIIIII', 'I')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@gsm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Win32API.new('user32', 'GetSystemMetrics', 'I', 'I')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@gcr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Win32API.new('user32', 'GetClientRect',&nbsp;&nbsp;&nbsp;&nbsp;'LP', 'I')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@kbe&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Win32API.new('user32', 'keybd_event',&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'LLLL', '')<br />
&nbsp;&nbsp;&nbsp;&nbsp;@gaks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = Win32API.new('user32', 'GetAsyncKeyState', 'L', 'I')<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Render message and exit if size is not supported<br />
&nbsp;&nbsp;&nbsp;&nbsp;# ================================================<br />
&nbsp;&nbsp;&nbsp;&nbsp;@default_size = self.size<br />
&nbsp;&nbsp;&nbsp;&nbsp;if size[0] &lt; @reswidth or size[1] &lt; @resheight<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("&#92;"#{title}&#92;" requires a minimum screen resolution " +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"of [#{@reswidth} x #{@resheight}]&#92;r&#92;n&#92;r&#92;n" +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&#92;tYour Resolution: [#{@default_size[0]} x #{@default_size[1]}]")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Apply Resolution Change<br />
&nbsp;&nbsp;&nbsp;&nbsp;# =======================<br />
&nbsp;&nbsp;&nbsp;&nbsp;@state = "default"<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.default<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● fullscreen<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def fullscreen<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@default_size = size<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_long.call(@window, -16, 0x14000000)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_pos.call(@window, -1, 0, 0, (@reswidth+2), (@resheight+2), 64)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@state = "fullscreen"<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● default<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def default<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;x = @default_size[0] / 2 - ((@reswidth/2) + 3)<br />
&nbsp;&nbsp;&nbsp;&nbsp;y = @default_size[1] / 2 - ((@resheight/2) + 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_long.call(@window, -16, 0x14CA0000)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@set_win_pos.call(@window, 0, x, y, (@reswidth+8), (@resheight+27), 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@state = "default"<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● trigger?(key)<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def trigger?(key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return @gaks.call(key) &amp; 0x01 == 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● private<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;private :fullscreen<br />
&nbsp;&nbsp;private :default<br />
&nbsp;&nbsp;private :trigger?<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● size<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def size<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;width&nbsp;&nbsp; = @gsm.call(0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;height&nbsp;&nbsp;= @gsm.call(1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;return width, height<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● change<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def change<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @state == "default"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.fullscreen<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.default<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● update<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if trigger?(121) # F10<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.change<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;if Input.trigger?(Input::ALT) or Input.press?(Input::ALT)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@kbe.call(18, 0, 2, 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● module functions<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;module_function :initialize<br />
&nbsp;&nbsp;module_function :fullscreen<br />
&nbsp;&nbsp;module_function :default<br />
&nbsp;&nbsp;module_function :trigger?<br />
&nbsp;&nbsp;module_function :size<br />
&nbsp;&nbsp;module_function :change<br />
&nbsp;&nbsp;module_function :update<br />
&nbsp;&nbsp;#<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ●● Input<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;A class that handles input data from a gamepad or keyboard.<br />
#==============================================================================<br />
<br />
class &lt;&lt; Input<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● Alias Listings (with F12 Stack prevention)<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;alias res_update update unless &#36;@<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# ● Input.update<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def Input.update<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Perform the original call<br />
&nbsp;&nbsp;&nbsp;&nbsp;res_update<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Update the Resolution<br />
&nbsp;&nbsp;&nbsp;&nbsp;Resolution.update<br />
&nbsp;&nbsp;end<br />
end<br />
<br />
<br />
<br />
# Execute at start<br />
Resolution.initialize</code></div></div></div>
		</div>
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Instructions</span></span><br />
Plenty, and in the script.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Compatibility</span></span><br />
Designed for RPGMaker XP<br />
<br />
Alters the screen size, so other scripts that adjust viewport settings will need to be likewise altered.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Credits and Thanks</span></span><br />
The very basics of this system  comes from the DLL-free version of Selwyn's resolution script. <br />
<br />
And thanks goes to ViperDamascus  who was looking for a script  to increase VXAce's screen size beyond the 640x480 maximum.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Terms and Conditions</span></span><br />
Free for use, even in commercial scripts. However, I require due credit for myself, Selwyn who crafted the basics, and ViperDamascus for the request.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Error reporting extension!]]></title>
			<link>https://www.save-point.org/thread-13433.html</link>
			<pubDate>Mon, 16 Mar 2026 08:59:15 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=9170">Kayzee</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-13433.html</guid>
			<description><![CDATA[Here is a handy script I made a while ago to give more detailed error reports and print them to the console! It gives a full trace of where the error happened and the last called functions so you know what the problem might be! Has some limitations. Sometimes the report is too big for the little popup and it will be blank, but it should show the error in the console! Also doesn't properly trace errors inside events, so that might be something to add later.<br />
<br />
Oh! And you can use "Error_Handler.do_trace()" to print a backtrace to the console in scripts whenever you want for debugging too!<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# * Error handling functions.<br />
#==============================================================================<br />
<br />
module Error_Handler<br />
  <br />
  def self.script_names<br />
    unless @script_names<br />
      @script_names = load_data('Data/Scripts.rvdata2')<br />
      @script_names.collect! {|script|  script[1]  }<br />
    end<br />
    @script_names<br />
  end<br />
  <br />
  def self.do_backtrace(error)<br />
    backtrace = self.parse_trace(error.backtrace)<br />
    error_line = backtrace.first<br />
    backtrace[0] = ''<br />
    return error_line + ": " + error.message + " (#{error.class})" + backtrace.join("&#92;n&#92;tfrom ") + "&#92;n"<br />
  end<br />
  <br />
  def self.parse_trace(trace)<br />
    out = []<br />
    trace.each_with_index do |line,i|<br />
      if line =~ /{(.*)}(.*)/<br />
        out &lt;&lt; (script_names[&#36;1.to_i] + &#36;2)<br />
      elsif line.start_with?(':1:')<br />
        break<br />
      else<br />
        out &lt;&lt; line<br />
      end<br />
    end<br />
    out<br />
  end<br />
  <br />
  def trace_me<br />
    begin<br />
      raise<br />
    rescue =&gt; exception<br />
      puts trace = Error_Handler.do_backtrace(exception)<br />
    end<br />
  end<br />
  <br />
end<br />
<br />
alias rgss_main_without_rescue rgss_main<br />
<br />
def rgss_main(&amp;block)<br />
  begin<br />
    rgss_main_without_rescue do<br />
      begin<br />
        block.call<br />
      rescue SystemExit<br />
        exit<br />
      rescue Exception =&gt; error<br />
        trace = Error_Handler.do_backtrace(error)<br />
        print(trace)<br />
        raise(error.class, trace, [error.backtrace.first])<br />
      end<br />
    end<br />
  end<br />
<br />
end</code></div></div><br />
Hope it's helpful!]]></description>
			<content:encoded><![CDATA[Here is a handy script I made a while ago to give more detailed error reports and print them to the console! It gives a full trace of where the error happened and the last called functions so you know what the problem might be! Has some limitations. Sometimes the report is too big for the little popup and it will be blank, but it should show the error in the console! Also doesn't properly trace errors inside events, so that might be something to add later.<br />
<br />
Oh! And you can use "Error_Handler.do_trace()" to print a backtrace to the console in scripts whenever you want for debugging too!<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# * Error handling functions.<br />
#==============================================================================<br />
<br />
module Error_Handler<br />
  <br />
  def self.script_names<br />
    unless @script_names<br />
      @script_names = load_data('Data/Scripts.rvdata2')<br />
      @script_names.collect! {|script|  script[1]  }<br />
    end<br />
    @script_names<br />
  end<br />
  <br />
  def self.do_backtrace(error)<br />
    backtrace = self.parse_trace(error.backtrace)<br />
    error_line = backtrace.first<br />
    backtrace[0] = ''<br />
    return error_line + ": " + error.message + " (#{error.class})" + backtrace.join("&#92;n&#92;tfrom ") + "&#92;n"<br />
  end<br />
  <br />
  def self.parse_trace(trace)<br />
    out = []<br />
    trace.each_with_index do |line,i|<br />
      if line =~ /{(.*)}(.*)/<br />
        out &lt;&lt; (script_names[&#36;1.to_i] + &#36;2)<br />
      elsif line.start_with?(':1:')<br />
        break<br />
      else<br />
        out &lt;&lt; line<br />
      end<br />
    end<br />
    out<br />
  end<br />
  <br />
  def trace_me<br />
    begin<br />
      raise<br />
    rescue =&gt; exception<br />
      puts trace = Error_Handler.do_backtrace(exception)<br />
    end<br />
  end<br />
  <br />
end<br />
<br />
alias rgss_main_without_rescue rgss_main<br />
<br />
def rgss_main(&amp;block)<br />
  begin<br />
    rgss_main_without_rescue do<br />
      begin<br />
        block.call<br />
      rescue SystemExit<br />
        exit<br />
      rescue Exception =&gt; error<br />
        trace = Error_Handler.do_backtrace(error)<br />
        print(trace)<br />
        raise(error.class, trace, [error.backtrace.first])<br />
      end<br />
    end<br />
  end<br />
<br />
end</code></div></div><br />
Hope it's helpful!]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[KReviveOnce VX]]></title>
			<link>https://www.save-point.org/thread-13347.html</link>
			<pubDate>Wed, 10 Dec 2025 17:49:13 +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-13347.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">KReviveOnce VX</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 />
Sometimes your heroes deserve a second chance to defeat that terrible mega boss. Or you might simply think that their story should not end because they were just too weak after an epic battle as to also <img src="https://www.save-point.org/images/smilies/ejlol/worried.gif" alt="Worried" title="Worried" class="smilie smilie_216" /> worry about facing a couple of slimes right away.<br />
<br />
No matter what your excuse might be, now your heroes can be automatically revived once!<br />
<br />
Just set a specific state ID and the HP percentage they will recover and that's it!<br />
<br />
<img src="https://www.save-point.org/images/smilies/ejlol/sweathappy.gif" alt="Happy with a sweat" title="Happy with a sweat" class="smilie smilie_31" /> Of course, if a given hero dies without having that state listed at that critical moment, it's <img src="https://www.save-point.org/images/smilies/ejlol/skull.gif" alt="Skull" title="Skull" class="smilie smilie_214" /> game over for him or her! <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">The Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KReviveOnce VX * #<br />
#&nbsp;&nbsp; Scripter : Kyonides<br />
#&nbsp;&nbsp; 2025-12-10<br />
<br />
# Let your heroes revive ONCE if they got a very specific state before<br />
# they met their premature demises.<br />
<br />
module KRevive<br />
&nbsp;&nbsp;ONCE_STATE_ID = 25<br />
&nbsp;&nbsp;ONCE_STATE_PERC = 25<br />
end<br />
<br />
class Game_Battler<br />
&nbsp;&nbsp;alias :kyon_revive_once_gm_btlr_remove_state :remove_state<br />
&nbsp;&nbsp;def check_revive_once(state_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@can_revive = (KRevive::ONCE_STATE_ID == state_id and state?(state_id))<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def remove_state(state_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;check_revive_once(state_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_revive_once_gm_btlr_remove_state(state_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;apply_revive_once<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def apply_revive_once<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @can_revive and !state?(KRevive::ONCE_STATE_ID) and @hp &lt; 2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@states.delete(1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@hp = maxhp * KRevive::ONCE_STATE_PERC<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;@can_revive = false<br />
&nbsp;&nbsp;end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer.<br />
Include me in your game credits.<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">KReviveOnce VX</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 />
Sometimes your heroes deserve a second chance to defeat that terrible mega boss. Or you might simply think that their story should not end because they were just too weak after an epic battle as to also <img src="https://www.save-point.org/images/smilies/ejlol/worried.gif" alt="Worried" title="Worried" class="smilie smilie_216" /> worry about facing a couple of slimes right away.<br />
<br />
No matter what your excuse might be, now your heroes can be automatically revived once!<br />
<br />
Just set a specific state ID and the HP percentage they will recover and that's it!<br />
<br />
<img src="https://www.save-point.org/images/smilies/ejlol/sweathappy.gif" alt="Happy with a sweat" title="Happy with a sweat" class="smilie smilie_31" /> Of course, if a given hero dies without having that state listed at that critical moment, it's <img src="https://www.save-point.org/images/smilies/ejlol/skull.gif" alt="Skull" title="Skull" class="smilie smilie_214" /> game over for him or her! <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">The Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KReviveOnce VX * #<br />
#&nbsp;&nbsp; Scripter : Kyonides<br />
#&nbsp;&nbsp; 2025-12-10<br />
<br />
# Let your heroes revive ONCE if they got a very specific state before<br />
# they met their premature demises.<br />
<br />
module KRevive<br />
&nbsp;&nbsp;ONCE_STATE_ID = 25<br />
&nbsp;&nbsp;ONCE_STATE_PERC = 25<br />
end<br />
<br />
class Game_Battler<br />
&nbsp;&nbsp;alias :kyon_revive_once_gm_btlr_remove_state :remove_state<br />
&nbsp;&nbsp;def check_revive_once(state_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@can_revive = (KRevive::ONCE_STATE_ID == state_id and state?(state_id))<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def remove_state(state_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;check_revive_once(state_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_revive_once_gm_btlr_remove_state(state_id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;apply_revive_once<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def apply_revive_once<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @can_revive and !state?(KRevive::ONCE_STATE_ID) and @hp &lt; 2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@states.delete(1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@hp = maxhp * KRevive::ONCE_STATE_PERC<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;@can_revive = false<br />
&nbsp;&nbsp;end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer.<br />
Include me in your game credits.<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[Hex Colors RG]]></title>
			<link>https://www.save-point.org/thread-13316.html</link>
			<pubDate>Tue, 18 Nov 2025 07:03:31 +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-13316.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">Hex Colors RG</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 />
I'm back to leave you another scriptlet that will allow you to use hex colors in your windows and sprites with ease.<br />
<br />
This code will work on RMXP, RMVX and even RMVX ACE! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
<br />
Just use it like this:<br />
<br />
For Windows:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>self.contents.font.color = hex_color("FF00FF")</code></div></div><br />
For Sprites:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>self.bitmap.font.color = hex_color("FF00FF")</code></div></div><br />
In this particular case, your text will become purple-ish! <img src="https://www.save-point.org/images/smilies/ejlol/virus.gif" alt="Virus" title="Virus" class="smilie smilie_75" /> <br />
<br />
You can also add 2 extra characters to set the alpha value of your custom color manually.<br />
<br />
In both cases you can add the # pound sign at the beginning of the string, but it's not mandatory.<br />
<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># * Hex Colors RG * # <br />
#  Scripter : Kyonides<br />
#  2025-11-18<br />
<br />
module Hex<br />
  def hex_color(hex)<br />
    digits = hex.size<br />
    hex.sub!("#", "")<br />
    red = hex[0, 2].to_i(16)<br />
    green = hex[2, 2].to_i(16)<br />
    blue = hex[4, 2].to_i(16)<br />
    alpha = digits == 8 ? hex[6, 2] : 255<br />
    Color.new(red, green, blue, alpha)<br />
  end<br />
end<br />
<br />
class Window_Base<br />
  include Hex<br />
end<br />
<br />
class Sprite<br />
  include Hex<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
It's free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer. That's all you need to know. <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">Hex Colors RG</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 />
I'm back to leave you another scriptlet that will allow you to use hex colors in your windows and sprites with ease.<br />
<br />
This code will work on RMXP, RMVX and even RMVX ACE! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
<br />
Just use it like this:<br />
<br />
For Windows:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>self.contents.font.color = hex_color("FF00FF")</code></div></div><br />
For Sprites:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>self.bitmap.font.color = hex_color("FF00FF")</code></div></div><br />
In this particular case, your text will become purple-ish! <img src="https://www.save-point.org/images/smilies/ejlol/virus.gif" alt="Virus" title="Virus" class="smilie smilie_75" /> <br />
<br />
You can also add 2 extra characters to set the alpha value of your custom color manually.<br />
<br />
In both cases you can add the # pound sign at the beginning of the string, but it's not mandatory.<br />
<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># * Hex Colors RG * # <br />
#  Scripter : Kyonides<br />
#  2025-11-18<br />
<br />
module Hex<br />
  def hex_color(hex)<br />
    digits = hex.size<br />
    hex.sub!("#", "")<br />
    red = hex[0, 2].to_i(16)<br />
    green = hex[2, 2].to_i(16)<br />
    blue = hex[4, 2].to_i(16)<br />
    alpha = digits == 8 ? hex[6, 2] : 255<br />
    Color.new(red, green, blue, alpha)<br />
  end<br />
end<br />
<br />
class Window_Base<br />
  include Hex<br />
end<br />
<br />
class Sprite<br />
  include Hex<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
It's free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer. That's all you need to know. <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[Ekuipment Points VX]]></title>
			<link>https://www.save-point.org/thread-13302.html</link>
			<pubDate>Thu, 06 Nov 2025 07:05: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-13302.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">Ekuipment Points VX</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 />
Limit the type of weapons or armor pieces your heroes will be able to equip!<br />
If your heroes want to replace their equipment, they better earn enough EP first!<br />
Another way to explain it would be to call it an equipment weight script.<br />
<br />
The script lets you set the default and custom EP the actor will start with. The same is valid for weapons and pieces of armor.<br />
Actors can also gain more EP by leveling up.<br />
<br />
Inside the <span style="font-weight: bold;" class="mycode_b">EkuipPoints</span> module you can find the WEAPON_POINTS, ARMOR_POINTS, ACTOR_POINTS &amp; the ACTOR_LEVEL_POINTS constants that will let you customize the EP earned by actors and the EP costs of their equipment.<br />
<br />
You can also change the X &amp; Y coordinates of windows or EP labels at will.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">NOTES</span><br />
<br />
Actors have no note boxes. This is why you need to depend on the ACTOR_POINTS &amp; ACTOR_LEVEL_POINTS constants to set their EP accordingly.<br />
To open the equipment window in battle, during the actor's command phase, press the RM's X button. Normally, it's linked to your A key on the keyboard.<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/tR16yB5f/ekuipment-points-vx001.jpg" loading="lazy"  alt="[Image: ekuipment-points-vx001.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/dQ7Cv5Bf/ekuipment-points-vx002.jpg" loading="lazy"  alt="[Image: ekuipment-points-vx002.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/L4qPRxTw/ekuipment-points-vx003.jpg" loading="lazy"  alt="[Image: ekuipment-points-vx003.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/QNbT8KmY/ekuipment-points-vx004.jpg" loading="lazy"  alt="[Image: ekuipment-points-vx004.jpg]" class="mycode_img" /><br />
</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># * Ekuipment Points VX - No Shield Edition * #<br />
#   Scripter : Kyonides<br />
#   v1.2.6 - 2025-11-12<br />
<br />
# Limit the type of weapons or armor pieces your heroes will be able to equip!<br />
# If heroes want to replace their equipment, they better earn enough EP first!<br />
<br />
# Note Tag: &lt;ep n&gt; where n is a positive number.<br />
<br />
# * Optional Script Calls * #<br />
# Block a given actor's change equipment feature, especially useful in battle:<br />
#  boolean stands for true OR false only.<br />
#   &#36;game_actors[ActorID].block_equip_change = boolean<br />
#   &#36;game_party.members[Index].block_equip_change = boolean<br />
<br />
# Block the party's change equipment feature at once:<br />
#   &#36;game_party.block_equip_change = boolean<br />
<br />
# Increase a given actor's equipment points:<br />
#   &#36;game_actors[ActorID].ep_plus += Number<br />
#   &#36;game_party.members[Index].ep_plus += Number<br />
<br />
module EkuipPoints<br />
  LABEL = "EP"<br />
  LABEL_LENGTH = { :status =&gt; 1, :ep_stats =&gt; 1 }<br />
  LABEL_LENGTH.default = 2<br />
  EP_LABEL_COLOR = [40, 242, 254] # [R,G,B]<br />
  GAUGE_COLOR1   = [255, 180, 60] # [R,G,B]<br />
  GAUGE_COLOR2   = [180, 255, 60] # [R,G,B]<br />
  EP_COST_X = 170<br />
  EP_STATUS_XY_WH    = [192, 122, 128, 6]<br />
  ACTOR_EP_WIN_XY_WH = [0, 280, 144, 56]<br />
  BATTLE_EQUIP_WIN_XY  = [80, 288]<br />
  ACTOR_STATS_WIN_OPA  = 255<br />
  BATTLE_EQUIP_WIN_OPA = 255<br />
  ACTOR_STATS_WIN_BACK_OPA  = 255<br />
  BATTLE_EQUIP_WIN_BACK_OPA = 255<br />
  EQUIP_BASE_POINTS = 1<br />
  # Alternate Armor Types Settings - Leave Empty If Not Needed<br />
  # 1 - Shield<br />
  # 2 - Helmet<br />
  # 3 - Body Armor<br />
  # 4 - Accessory<br />
  ARMOR_TYPES = [3, 4, 4, 4]<br />
  ACTOR_POINTS = {}<br />
  ACTOR_POINTS.default = 4<br />
  # [ActorID] = BasePoints<br />
  ACTOR_POINTS[1] = 6<br />
  ACTOR_POINTS[2] = 7<br />
  ACTOR_LEVEL_POINTS = {}<br />
  ACTOR_LEVEL_POINTS.default = { :levels =&gt; 10, :ep =&gt; 1 }<br />
  # [ActorID] = { :levels =&gt; LevelsNeeded, :ep =&gt; ExtraPoints }<br />
  ACTOR_LEVEL_POINTS[1] = { :levels =&gt; 8, :ep =&gt; 2 }<br />
end<br />
<br />
module RPG<br />
  class BaseItem<br />
    BASE_EP = EkuipPoints::EQUIP_BASE_POINTS<br />
    def note_ep<br />
      @note[/&lt;ep (&#92;d+)/i]<br />
      &#36;1 ? &#36;1.to_i : BASE_EP<br />
    end<br />
<br />
    def ep_cost<br />
      @ep_cost ||= note_ep<br />
    end<br />
  end<br />
<br />
  class Equipment<br />
    def ep_cost<br />
      0<br />
    end<br />
  end<br />
end<br />
<br />
module EkuipPoints<br />
  module ItemList<br />
    def draw_item_name(item, rx, ry, enabled=true)<br />
      return unless item<br />
      super<br />
      rect = item_rect(index)<br />
      rect.x = rx<br />
      rect.y = ry<br />
      rect.width -= rx<br />
      f = contents.font<br />
      f.color = ep_color<br />
      f.color.alpha = 160 unless enabled<br />
      number = sprintf("%2d", item.ep_cost)<br />
      contents.draw_text(rect, number, 2)<br />
    end<br />
  end<br />
end<br />
<br />
class Game_Actor<br />
  alias :kyon_ekuip_points_gm_act_stp :setup<br />
  alias :kyon_ekuip_points_gm_act_lvl_up :level_up<br />
  alias :kyon_ekuip_points_gm_act_lvl_dn :level_down<br />
  def setup(actor_id)<br />
    kyon_ekuip_points_gm_act_stp(actor_id)<br />
    @armor1_id = actor.armor3_id<br />
    @armor3_id = 0<br />
    @maxep_base = EkuipPoints::ACTOR_POINTS[actor_id]<br />
    hash = EkuipPoints::ACTOR_LEVEL_POINTS[actor_id]<br />
    @base_ep_levels = hash[:levels]<br />
    @base_level_ep = hash[:ep]<br />
    @ep_plus = 0<br />
    calc_level_ep<br />
  end<br />
<br />
  def calc_level_ep<br />
    @level_ep = @level / @base_ep_levels * @base_level_ep<br />
  end<br />
<br />
  def level_up<br />
    kyon_ekuip_points_gm_act_lvl_up<br />
    calc_level_ep<br />
  end<br />
<br />
  def level_down<br />
    kyon_ekuip_points_gm_act_lvl_dn<br />
    calc_level_ep<br />
  end<br />
<br />
  def maxep<br />
    @maxep_base + @level_ep + @ep_plus<br />
  end<br />
<br />
  def ep_used<br />
    list = equips.compact<br />
    list.inject(0) {|total, item| total + item.ep_cost }<br />
  end<br />
<br />
  def ep_left<br />
    self.maxep - self.ep_used<br />
  end<br />
<br />
  def enough_ep?(equip_type, item)<br />
    return true unless item<br />
    equipment = equips[equip_type] || RPG::Equipment.new<br />
    used = self.ep_used - equipment.ep_cost<br />
    return true if used == 0<br />
    used += item.ep_cost<br />
    self.maxep &gt;= used<br />
  end<br />
  attr_accessor :ep_plus, :block_equip_change<br />
end<br />
<br />
class Game_Party<br />
  def block_equip_change=(state)<br />
    members.each {|actor| actor.block_equip_change = state }<br />
  end<br />
end<br />
<br />
class Window_Base<br />
  def ep_color<br />
    @ep_color ||= Color.new(*EkuipPoints::EP_LABEL_COLOR)<br />
  end<br />
<br />
  def ep_gauge_color1<br />
    @ep_gauge_color1 ||= Color.new(*EkuipPoints::GAUGE_COLOR1)<br />
  end<br />
<br />
  def ep_gauge_color2<br />
    @ep_gauge_color2 ||= Color.new(*EkuipPoints::GAUGE_COLOR2)<br />
  end<br />
<br />
  def draw_ep_left(actor, lx, ly, lw, lh=4, large=nil)<br />
    left = actor.ep_left<br />
    gw = lw * left / actor.maxep<br />
    gc1 = ep_gauge_color1<br />
    gc2 = ep_gauge_color2<br />
    c = self.contents<br />
    c.fill_rect(lx, ly + WLH - lh - 2, lw, lh, gauge_back_color)<br />
    c.gradient_fill_rect(lx, ly + WLH - lh - 2, gw, lh, gc1, gc2)<br />
    c.font.color = system_color<br />
    label = EkuipPoints::LABEL<br />
    length = EkuipPoints::LABEL_LENGTH[class_type]<br />
    label = label[0, length]<br />
    c.draw_text(lx, ly, lw, WLH, label)<br />
    c.font.color = normal_color<br />
    if large<br />
      c.draw_text(lx, ly, lw / 2 + 4, WLH, left.to_s, 2)<br />
      c.draw_text(lx, ly, lw / 2 + 16, WLH, "/", 2)<br />
      c.draw_text(lx, ly, lw, WLH, actor.maxep.to_s, 2)<br />
    else<br />
      c.draw_text(lx, ly, lw, WLH, left.to_s, 2)<br />
    end<br />
  end<br />
end<br />
<br />
class Window_MenuStatus<br />
  def refresh<br />
    self.contents.clear<br />
    @item_max = &#36;game_party.members.size<br />
    &#36;game_party.members.each {|actor| draw_actor_data(actor) }<br />
  end<br />
<br />
  def draw_actor_data(actor)<br />
    draw_actor_face(actor, 2, actor.index * 96 + 2, 92)<br />
    dx = 104<br />
    dy = actor.index * 96 + WLH / 2<br />
    draw_actor_name(actor, dx, dy)<br />
    draw_actor_class(actor, dx + 120, dy)<br />
    draw_actor_level(actor, dx, dy + WLH * 1)<br />
    draw_ep_left(actor, dx + 60, dy + WLH * 1, 50)<br />
    draw_actor_state(actor, dx, dy + WLH * 2)<br />
    draw_actor_hp(actor, dx + 120, dy + WLH * 1)<br />
    draw_actor_mp(actor, dx + 120, dy + WLH * 2)<br />
  end<br />
<br />
  def class_type<br />
    :menu_status<br />
  end<br />
end<br />
<br />
class Window_Equip<br />
  include EkuipPoints::ItemList<br />
  def update<br />
    last_index = @index<br />
    super<br />
    if @index != last_index<br />
      @item_window.equip_type = @index<br />
    end<br />
  end<br />
<br />
  def refresh<br />
    self.contents.clear<br />
    @data = []<br />
    for item in @actor.equips do @data.push(item) end<br />
    @item_max = @data.size<br />
    self.contents.font.color = system_color<br />
    if @actor.two_swords_style<br />
      self.contents.draw_text(4, WLH * 0, 92, WLH, Vocab.weapon1)<br />
      self.contents.draw_text(4, WLH * 1, 92, WLH, Vocab.weapon2)<br />
    else<br />
      self.contents.draw_text(4, WLH * 0, 92, WLH, Vocab.weapon)<br />
      self.contents.draw_text(4, WLH * 1, 92, WLH, Vocab.armor3)<br />
    end<br />
    self.contents.draw_text(4, WLH * 2, 92, WLH, Vocab.armor4)<br />
    self.contents.draw_text(4, WLH * 3, 92, WLH, Vocab.armor4)<br />
    self.contents.draw_text(4, WLH * 4, 92, WLH, Vocab.armor4)<br />
    draw_item_name(@data[0], 92, WLH * 0)<br />
    draw_item_name(@data[1], 92, WLH * 1)<br />
    draw_item_name(@data[2], 92, WLH * 2)<br />
    draw_item_name(@data[3], 92, WLH * 3)<br />
    draw_item_name(@data[4], 92, WLH * 4)<br />
  end<br />
  attr_writer :item_window<br />
end<br />
<br />
class Window_EquipMod &lt; Window_Selectable<br />
  include EkuipPoints::ItemList<br />
  def initialize(wx, wy, actor)<br />
    super(wx, wy, 336, WLH * 4 + 32)<br />
    self.z = 1000<br />
    self.opacity = EkuipPoints::BATTLE_EQUIP_WIN_OPA<br />
    self.back_opacity = EkuipPoints::BATTLE_EQUIP_WIN_BACK_OPA<br />
    @actor = actor<br />
    refresh<br />
    self.index = 0<br />
  end<br />
<br />
  def row_max<br />
    5<br />
  end<br />
<br />
  def item<br />
    @data[@index]<br />
  end<br />
<br />
  def refresh<br />
    self.contents.clear<br />
    @data = []<br />
    @actor.equips.each {|item| @data &lt;&lt; item }<br />
    @item_max = @data.size<br />
    self.contents.font.color = system_color<br />
    if @actor.two_swords_style<br />
      self.contents.draw_text(4, WLH * 0, 92, WLH, Vocab.weapon1)<br />
      self.contents.draw_text(4, WLH * 1, 92, WLH, Vocab.weapon2)<br />
    else<br />
      self.contents.draw_text(4, WLH * 0, 92, WLH, Vocab.weapon)<br />
      self.contents.draw_text(4, WLH * 1, 92, WLH, Vocab.armor3)<br />
    end<br />
    self.contents.draw_text(4, WLH * 2, 92, WLH, Vocab.armor4)<br />
    self.contents.draw_text(4, WLH * 3, 92, WLH, Vocab.armor4)<br />
    self.contents.draw_text(4, WLH * 4, 92, WLH, Vocab.armor4)<br />
    draw_item_name(@data[0], 92, WLH * 0)<br />
    draw_item_name(@data[1], 92, WLH * 1)<br />
    draw_item_name(@data[2], 92, WLH * 2)<br />
    draw_item_name(@data[3], 92, WLH * 3)<br />
    draw_item_name(@data[4], 92, WLH * 4)<br />
  end<br />
<br />
  def update_help<br />
    @help_window.set_text(item ? item.description : "")<br />
  end<br />
end<br />
<br />
class Window_EquipItem<br />
  EQUIP_TYPES = [0] + EkuipPoints::ARMOR_TYPES<br />
  alias :kyon_ekuip_points_win_eqpitm_init :initialize<br />
  alias :kyon_ekuip_points_win_eqpitm_refr :refresh<br />
  def initialize(wx, wy, width, height, actor, equip_type)<br />
    @row_index = equip_type<br />
    kyon_ekuip_points_win_eqpitm_init(wx, wy, width, height, actor, equip_type)<br />
    self.index = -1<br />
  end<br />
<br />
  def refresh<br />
    @has_armor_types ||= EQUIP_TYPES.size &gt; 1<br />
    kyon_ekuip_points_win_eqpitm_refr<br />
  end<br />
<br />
  def reset_index<br />
    self.index = 0 if @index &lt; 0<br />
  end<br />
<br />
  def enable?(item)<br />
    @actor.enough_ep?(@row_index, item)<br />
  end<br />
<br />
  def equip_type=(type)<br />
    @row_index = type<br />
    type = 0 if @actor.two_swords_style &amp;&amp; type == 1<br />
    type = EQUIP_TYPES[type] if type &gt; 0 and EQUIP_TYPES.size &gt; 1<br />
    @equip_type = type<br />
    refresh<br />
  end<br />
<br />
  def draw_item(index)<br />
    rect = item_rect(index)<br />
    c = self.contents<br />
    c.clear_rect(rect)<br />
    item = @data[index]<br />
    return unless item<br />
    number = &#36;game_party.item_number(item)<br />
    enabled = enable?(item)<br />
    rect.width -= 4<br />
    draw_item_name(item, rect.x, rect.y, enabled)<br />
    c.draw_text(rect, sprintf(":%2d", number), 2)<br />
    f = c.font<br />
    f.color = ep_color<br />
    f.color.alpha = 160 unless enabled<br />
    rect.x += EkuipPoints::EP_COST_X<br />
    rect.width = 40<br />
    number = item.ep_cost<br />
    c.draw_text(rect, sprintf("%2d", number), 2)<br />
  end<br />
end<br />
<br />
class Window_EquipStatus<br />
  alias :kyon_ekuip_points_win_eqpstts_ref :refresh<br />
  def refresh<br />
    kyon_ekuip_points_win_eqpstts_ref<br />
    draw_ep_left(@actor, 122, 0, 50)<br />
  end<br />
<br />
  def class_type<br />
    :equip_status<br />
  end<br />
end<br />
<br />
class Window_Status<br />
  alias :kyon_ekuip_points_win_stts_drw_bsc_info :draw_basic_info<br />
  def draw_basic_info(dx, dy)<br />
    kyon_ekuip_points_win_stts_drw_bsc_info(dx, dy)<br />
    ex, ey, ew, eh = EkuipPoints::EP_STATUS_XY_WH<br />
    draw_ep_left(@actor, dx + ex, dy + ey, ew, eh, true)<br />
  end<br />
<br />
  def class_type<br />
    :status<br />
  end<br />
end<br />
<br />
module EkuipPoints<br />
  class ActorStatsWindow &lt; Window_Base<br />
    def initialize(actor)<br />
      super(*ACTOR_EP_WIN_XY_WH)<br />
      self.opacity = ACTOR_STATS_WIN_OPA<br />
      self.back_opacity = ACTOR_STATS_WIN_BACK_OPA<br />
      self.z = 2000<br />
      @actor = actor<br />
      @hw = self.contents.width / 2<br />
      refresh<br />
    end<br />
<br />
    def refresh<br />
      self.contents.clear<br />
      draw_actor_name(@actor, 0, 0)<br />
      draw_ep_left(@actor, @hw, 0, @hw, 4)<br />
    end<br />
<br />
    def class_type<br />
      :ep_stats<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Equip<br />
  alias :kyon_ekuip_points_scn_eqp_stt :start<br />
  alias :kyon_ekuip_points_scn_eqp_up_eqp_sel :update_equip_selection<br />
  def start<br />
    kyon_ekuip_points_scn_eqp_stt<br />
    @equip_window.item_window = @item_window<br />
  end<br />
<br />
  def create_item_windows<br />
    types = Window_EquipItem::EQUIP_TYPES<br />
    @item_window = Window_EquipItem.new(0, 208, 544, 208, @actor, 0)<br />
    @item_window.help_window = @help_window<br />
    @item_window.active = false<br />
    @item_window.index = -1<br />
    @item_windows = [@item_window]<br />
  end<br />
<br />
  def update<br />
    super<br />
    update_menu_background<br />
    @help_window.update<br />
    update_status_window<br />
    if @equip_window.active<br />
      update_equip_selection<br />
    elsif @item_window.active<br />
      update_item_selection<br />
    end<br />
  end<br />
<br />
  def update_equip_selection<br />
    @equip_window.update<br />
    kyon_ekuip_points_scn_eqp_up_eqp_sel<br />
  end<br />
<br />
  def update_item_selection<br />
    @item_window.update<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      @equip_window.active = true<br />
      @item_window.active = false<br />
      @item_window.index = -1<br />
      return<br />
    elsif Input.trigger?(Input::C)<br />
      item = @item_window.item<br />
      pos = @equip_window.index<br />
      if item and !@actor.enough_ep?(pos, item)<br />
        Sound.play_buzzer<br />
        return<br />
      end<br />
      Sound.play_equip<br />
      @actor.change_equip(pos, item)<br />
      @equip_window.active = true<br />
      @item_window.active = false<br />
      @item_window.index = -1<br />
      @item_window.refresh<br />
      @equip_window.refresh<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Battle<br />
  alias :kyon_ekuip_points_scn_btl_up :update<br />
  alias :kyon_ekuip_points_scn_btl_up_act_cmdsel :update_actor_command_selection<br />
  def create_equipment_windows<br />
    actor = @active_battler<br />
    if actor.block_equip_change<br />
      Sound.play_buzzer<br />
      return<br />
    end<br />
    Sound.play_decision<br />
    wx, wy = EkuipPoints::BATTLE_EQUIP_WIN_XY<br />
    ww = Graphics.width<br />
    wh = Graphics.height - @actor_command_window.height<br />
    @ep_window = EkuipPoints::ActorStatsWindow.new(actor)<br />
    @equip_window = Window_EquipMod.new(wx, wy, actor)<br />
    @equip_item_window = Window_EquipItem.new(0, 0, ww, wh, actor, 0)<br />
    @equip_windows = [@ep_window, @equip_window, @equip_item_window]<br />
    @actor_command_window.active = false<br />
    @equip_index = 0<br />
    @equip_item = true<br />
  end<br />
<br />
  def dispose_equipment_windows<br />
    Sound.play_cancel<br />
    @equip_windows.each {|window| window.dispose }<br />
    @actor_command_window.active = true<br />
    @equip_item = false<br />
  end<br />
<br />
  def update<br />
    if @equip_item<br />
      update_equipment<br />
    else<br />
      kyon_ekuip_points_scn_btl_up<br />
    end<br />
  end<br />
<br />
  def update_equipment<br />
    update_basic(true)<br />
    update_info_viewport<br />
    case @equip_index<br />
    when 0<br />
      update_equip_type<br />
    when 1<br />
      update_equip_list<br />
    end<br />
  end<br />
<br />
  def refresh_equip_type<br />
    type = @equip_window.index<br />
    @equip_item_window.equip_type = type<br />
    @equip_item_window.index = -1<br />
  end<br />
<br />
  def update_equip_type<br />
    @equip_window.update<br />
    if Input.trigger?(Input::B)<br />
      dispose_equipment_windows<br />
      return<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      @equip_item_window.active = true<br />
      @equip_window.active = false<br />
      @equip_item_window.reset_index<br />
      return @equip_index = 1<br />
    elsif Input.trigger?(Input::DOWN)<br />
      refresh_equip_type<br />
      return<br />
    elsif Input.trigger?(Input::UP)<br />
      refresh_equip_type<br />
    end<br />
  end<br />
<br />
  def back_to_main_equip<br />
    @equip_item_window.index = -1<br />
    @equip_item_window.active = false<br />
    @equip_window.active = true<br />
    @equip_index = 0<br />
  end<br />
<br />
  def update_equip_list<br />
    @equip_item_window.update<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      back_to_main_equip<br />
      return<br />
    elsif Input.trigger?(Input::C)<br />
      pos = @equip_window.index<br />
      item = @equip_item_window.item<br />
      if item and !@active_battler.enough_ep?(pos, item)<br />
        Sound.play_buzzer<br />
        return<br />
      end<br />
      Sound.play_equip<br />
      @active_battler.change_equip(pos, item)<br />
      @equip_item_window.refresh<br />
      @equip_window.refresh<br />
      @ep_window.refresh<br />
      back_to_main_equip<br />
    end<br />
  end<br />
<br />
  def update_actor_command_selection<br />
    if Input.trigger?(Input::X)<br />
      create_equipment_windows<br />
      return<br />
    end<br />
    kyon_ekuip_points_scn_btl_up_act_cmdsel<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: x-large;" class="mycode_size"><a href="https://www.mediafire.com/folder/kh1bibfguxbll/EkuipmentPoints" target="_blank" rel="noopener" class="mycode_url">DOWNLOAD DEMO</a></span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer for non-commercial use.<br />
Include me in your game credits! <img src="https://www.save-point.org/images/smilies/ejlol/grin.gif" alt="Grinning" title="Grinning" class="smilie smilie_25" /><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">Ekuipment Points VX</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 />
Limit the type of weapons or armor pieces your heroes will be able to equip!<br />
If your heroes want to replace their equipment, they better earn enough EP first!<br />
Another way to explain it would be to call it an equipment weight script.<br />
<br />
The script lets you set the default and custom EP the actor will start with. The same is valid for weapons and pieces of armor.<br />
Actors can also gain more EP by leveling up.<br />
<br />
Inside the <span style="font-weight: bold;" class="mycode_b">EkuipPoints</span> module you can find the WEAPON_POINTS, ARMOR_POINTS, ACTOR_POINTS &amp; the ACTOR_LEVEL_POINTS constants that will let you customize the EP earned by actors and the EP costs of their equipment.<br />
<br />
You can also change the X &amp; Y coordinates of windows or EP labels at will.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">NOTES</span><br />
<br />
Actors have no note boxes. This is why you need to depend on the ACTOR_POINTS &amp; ACTOR_LEVEL_POINTS constants to set their EP accordingly.<br />
To open the equipment window in battle, during the actor's command phase, press the RM's X button. Normally, it's linked to your A key on the keyboard.<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/tR16yB5f/ekuipment-points-vx001.jpg" loading="lazy"  alt="[Image: ekuipment-points-vx001.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/dQ7Cv5Bf/ekuipment-points-vx002.jpg" loading="lazy"  alt="[Image: ekuipment-points-vx002.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/L4qPRxTw/ekuipment-points-vx003.jpg" loading="lazy"  alt="[Image: ekuipment-points-vx003.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/QNbT8KmY/ekuipment-points-vx004.jpg" loading="lazy"  alt="[Image: ekuipment-points-vx004.jpg]" class="mycode_img" /><br />
</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># * Ekuipment Points VX - No Shield Edition * #<br />
#   Scripter : Kyonides<br />
#   v1.2.6 - 2025-11-12<br />
<br />
# Limit the type of weapons or armor pieces your heroes will be able to equip!<br />
# If heroes want to replace their equipment, they better earn enough EP first!<br />
<br />
# Note Tag: &lt;ep n&gt; where n is a positive number.<br />
<br />
# * Optional Script Calls * #<br />
# Block a given actor's change equipment feature, especially useful in battle:<br />
#  boolean stands for true OR false only.<br />
#   &#36;game_actors[ActorID].block_equip_change = boolean<br />
#   &#36;game_party.members[Index].block_equip_change = boolean<br />
<br />
# Block the party's change equipment feature at once:<br />
#   &#36;game_party.block_equip_change = boolean<br />
<br />
# Increase a given actor's equipment points:<br />
#   &#36;game_actors[ActorID].ep_plus += Number<br />
#   &#36;game_party.members[Index].ep_plus += Number<br />
<br />
module EkuipPoints<br />
  LABEL = "EP"<br />
  LABEL_LENGTH = { :status =&gt; 1, :ep_stats =&gt; 1 }<br />
  LABEL_LENGTH.default = 2<br />
  EP_LABEL_COLOR = [40, 242, 254] # [R,G,B]<br />
  GAUGE_COLOR1   = [255, 180, 60] # [R,G,B]<br />
  GAUGE_COLOR2   = [180, 255, 60] # [R,G,B]<br />
  EP_COST_X = 170<br />
  EP_STATUS_XY_WH    = [192, 122, 128, 6]<br />
  ACTOR_EP_WIN_XY_WH = [0, 280, 144, 56]<br />
  BATTLE_EQUIP_WIN_XY  = [80, 288]<br />
  ACTOR_STATS_WIN_OPA  = 255<br />
  BATTLE_EQUIP_WIN_OPA = 255<br />
  ACTOR_STATS_WIN_BACK_OPA  = 255<br />
  BATTLE_EQUIP_WIN_BACK_OPA = 255<br />
  EQUIP_BASE_POINTS = 1<br />
  # Alternate Armor Types Settings - Leave Empty If Not Needed<br />
  # 1 - Shield<br />
  # 2 - Helmet<br />
  # 3 - Body Armor<br />
  # 4 - Accessory<br />
  ARMOR_TYPES = [3, 4, 4, 4]<br />
  ACTOR_POINTS = {}<br />
  ACTOR_POINTS.default = 4<br />
  # [ActorID] = BasePoints<br />
  ACTOR_POINTS[1] = 6<br />
  ACTOR_POINTS[2] = 7<br />
  ACTOR_LEVEL_POINTS = {}<br />
  ACTOR_LEVEL_POINTS.default = { :levels =&gt; 10, :ep =&gt; 1 }<br />
  # [ActorID] = { :levels =&gt; LevelsNeeded, :ep =&gt; ExtraPoints }<br />
  ACTOR_LEVEL_POINTS[1] = { :levels =&gt; 8, :ep =&gt; 2 }<br />
end<br />
<br />
module RPG<br />
  class BaseItem<br />
    BASE_EP = EkuipPoints::EQUIP_BASE_POINTS<br />
    def note_ep<br />
      @note[/&lt;ep (&#92;d+)/i]<br />
      &#36;1 ? &#36;1.to_i : BASE_EP<br />
    end<br />
<br />
    def ep_cost<br />
      @ep_cost ||= note_ep<br />
    end<br />
  end<br />
<br />
  class Equipment<br />
    def ep_cost<br />
      0<br />
    end<br />
  end<br />
end<br />
<br />
module EkuipPoints<br />
  module ItemList<br />
    def draw_item_name(item, rx, ry, enabled=true)<br />
      return unless item<br />
      super<br />
      rect = item_rect(index)<br />
      rect.x = rx<br />
      rect.y = ry<br />
      rect.width -= rx<br />
      f = contents.font<br />
      f.color = ep_color<br />
      f.color.alpha = 160 unless enabled<br />
      number = sprintf("%2d", item.ep_cost)<br />
      contents.draw_text(rect, number, 2)<br />
    end<br />
  end<br />
end<br />
<br />
class Game_Actor<br />
  alias :kyon_ekuip_points_gm_act_stp :setup<br />
  alias :kyon_ekuip_points_gm_act_lvl_up :level_up<br />
  alias :kyon_ekuip_points_gm_act_lvl_dn :level_down<br />
  def setup(actor_id)<br />
    kyon_ekuip_points_gm_act_stp(actor_id)<br />
    @armor1_id = actor.armor3_id<br />
    @armor3_id = 0<br />
    @maxep_base = EkuipPoints::ACTOR_POINTS[actor_id]<br />
    hash = EkuipPoints::ACTOR_LEVEL_POINTS[actor_id]<br />
    @base_ep_levels = hash[:levels]<br />
    @base_level_ep = hash[:ep]<br />
    @ep_plus = 0<br />
    calc_level_ep<br />
  end<br />
<br />
  def calc_level_ep<br />
    @level_ep = @level / @base_ep_levels * @base_level_ep<br />
  end<br />
<br />
  def level_up<br />
    kyon_ekuip_points_gm_act_lvl_up<br />
    calc_level_ep<br />
  end<br />
<br />
  def level_down<br />
    kyon_ekuip_points_gm_act_lvl_dn<br />
    calc_level_ep<br />
  end<br />
<br />
  def maxep<br />
    @maxep_base + @level_ep + @ep_plus<br />
  end<br />
<br />
  def ep_used<br />
    list = equips.compact<br />
    list.inject(0) {|total, item| total + item.ep_cost }<br />
  end<br />
<br />
  def ep_left<br />
    self.maxep - self.ep_used<br />
  end<br />
<br />
  def enough_ep?(equip_type, item)<br />
    return true unless item<br />
    equipment = equips[equip_type] || RPG::Equipment.new<br />
    used = self.ep_used - equipment.ep_cost<br />
    return true if used == 0<br />
    used += item.ep_cost<br />
    self.maxep &gt;= used<br />
  end<br />
  attr_accessor :ep_plus, :block_equip_change<br />
end<br />
<br />
class Game_Party<br />
  def block_equip_change=(state)<br />
    members.each {|actor| actor.block_equip_change = state }<br />
  end<br />
end<br />
<br />
class Window_Base<br />
  def ep_color<br />
    @ep_color ||= Color.new(*EkuipPoints::EP_LABEL_COLOR)<br />
  end<br />
<br />
  def ep_gauge_color1<br />
    @ep_gauge_color1 ||= Color.new(*EkuipPoints::GAUGE_COLOR1)<br />
  end<br />
<br />
  def ep_gauge_color2<br />
    @ep_gauge_color2 ||= Color.new(*EkuipPoints::GAUGE_COLOR2)<br />
  end<br />
<br />
  def draw_ep_left(actor, lx, ly, lw, lh=4, large=nil)<br />
    left = actor.ep_left<br />
    gw = lw * left / actor.maxep<br />
    gc1 = ep_gauge_color1<br />
    gc2 = ep_gauge_color2<br />
    c = self.contents<br />
    c.fill_rect(lx, ly + WLH - lh - 2, lw, lh, gauge_back_color)<br />
    c.gradient_fill_rect(lx, ly + WLH - lh - 2, gw, lh, gc1, gc2)<br />
    c.font.color = system_color<br />
    label = EkuipPoints::LABEL<br />
    length = EkuipPoints::LABEL_LENGTH[class_type]<br />
    label = label[0, length]<br />
    c.draw_text(lx, ly, lw, WLH, label)<br />
    c.font.color = normal_color<br />
    if large<br />
      c.draw_text(lx, ly, lw / 2 + 4, WLH, left.to_s, 2)<br />
      c.draw_text(lx, ly, lw / 2 + 16, WLH, "/", 2)<br />
      c.draw_text(lx, ly, lw, WLH, actor.maxep.to_s, 2)<br />
    else<br />
      c.draw_text(lx, ly, lw, WLH, left.to_s, 2)<br />
    end<br />
  end<br />
end<br />
<br />
class Window_MenuStatus<br />
  def refresh<br />
    self.contents.clear<br />
    @item_max = &#36;game_party.members.size<br />
    &#36;game_party.members.each {|actor| draw_actor_data(actor) }<br />
  end<br />
<br />
  def draw_actor_data(actor)<br />
    draw_actor_face(actor, 2, actor.index * 96 + 2, 92)<br />
    dx = 104<br />
    dy = actor.index * 96 + WLH / 2<br />
    draw_actor_name(actor, dx, dy)<br />
    draw_actor_class(actor, dx + 120, dy)<br />
    draw_actor_level(actor, dx, dy + WLH * 1)<br />
    draw_ep_left(actor, dx + 60, dy + WLH * 1, 50)<br />
    draw_actor_state(actor, dx, dy + WLH * 2)<br />
    draw_actor_hp(actor, dx + 120, dy + WLH * 1)<br />
    draw_actor_mp(actor, dx + 120, dy + WLH * 2)<br />
  end<br />
<br />
  def class_type<br />
    :menu_status<br />
  end<br />
end<br />
<br />
class Window_Equip<br />
  include EkuipPoints::ItemList<br />
  def update<br />
    last_index = @index<br />
    super<br />
    if @index != last_index<br />
      @item_window.equip_type = @index<br />
    end<br />
  end<br />
<br />
  def refresh<br />
    self.contents.clear<br />
    @data = []<br />
    for item in @actor.equips do @data.push(item) end<br />
    @item_max = @data.size<br />
    self.contents.font.color = system_color<br />
    if @actor.two_swords_style<br />
      self.contents.draw_text(4, WLH * 0, 92, WLH, Vocab.weapon1)<br />
      self.contents.draw_text(4, WLH * 1, 92, WLH, Vocab.weapon2)<br />
    else<br />
      self.contents.draw_text(4, WLH * 0, 92, WLH, Vocab.weapon)<br />
      self.contents.draw_text(4, WLH * 1, 92, WLH, Vocab.armor3)<br />
    end<br />
    self.contents.draw_text(4, WLH * 2, 92, WLH, Vocab.armor4)<br />
    self.contents.draw_text(4, WLH * 3, 92, WLH, Vocab.armor4)<br />
    self.contents.draw_text(4, WLH * 4, 92, WLH, Vocab.armor4)<br />
    draw_item_name(@data[0], 92, WLH * 0)<br />
    draw_item_name(@data[1], 92, WLH * 1)<br />
    draw_item_name(@data[2], 92, WLH * 2)<br />
    draw_item_name(@data[3], 92, WLH * 3)<br />
    draw_item_name(@data[4], 92, WLH * 4)<br />
  end<br />
  attr_writer :item_window<br />
end<br />
<br />
class Window_EquipMod &lt; Window_Selectable<br />
  include EkuipPoints::ItemList<br />
  def initialize(wx, wy, actor)<br />
    super(wx, wy, 336, WLH * 4 + 32)<br />
    self.z = 1000<br />
    self.opacity = EkuipPoints::BATTLE_EQUIP_WIN_OPA<br />
    self.back_opacity = EkuipPoints::BATTLE_EQUIP_WIN_BACK_OPA<br />
    @actor = actor<br />
    refresh<br />
    self.index = 0<br />
  end<br />
<br />
  def row_max<br />
    5<br />
  end<br />
<br />
  def item<br />
    @data[@index]<br />
  end<br />
<br />
  def refresh<br />
    self.contents.clear<br />
    @data = []<br />
    @actor.equips.each {|item| @data &lt;&lt; item }<br />
    @item_max = @data.size<br />
    self.contents.font.color = system_color<br />
    if @actor.two_swords_style<br />
      self.contents.draw_text(4, WLH * 0, 92, WLH, Vocab.weapon1)<br />
      self.contents.draw_text(4, WLH * 1, 92, WLH, Vocab.weapon2)<br />
    else<br />
      self.contents.draw_text(4, WLH * 0, 92, WLH, Vocab.weapon)<br />
      self.contents.draw_text(4, WLH * 1, 92, WLH, Vocab.armor3)<br />
    end<br />
    self.contents.draw_text(4, WLH * 2, 92, WLH, Vocab.armor4)<br />
    self.contents.draw_text(4, WLH * 3, 92, WLH, Vocab.armor4)<br />
    self.contents.draw_text(4, WLH * 4, 92, WLH, Vocab.armor4)<br />
    draw_item_name(@data[0], 92, WLH * 0)<br />
    draw_item_name(@data[1], 92, WLH * 1)<br />
    draw_item_name(@data[2], 92, WLH * 2)<br />
    draw_item_name(@data[3], 92, WLH * 3)<br />
    draw_item_name(@data[4], 92, WLH * 4)<br />
  end<br />
<br />
  def update_help<br />
    @help_window.set_text(item ? item.description : "")<br />
  end<br />
end<br />
<br />
class Window_EquipItem<br />
  EQUIP_TYPES = [0] + EkuipPoints::ARMOR_TYPES<br />
  alias :kyon_ekuip_points_win_eqpitm_init :initialize<br />
  alias :kyon_ekuip_points_win_eqpitm_refr :refresh<br />
  def initialize(wx, wy, width, height, actor, equip_type)<br />
    @row_index = equip_type<br />
    kyon_ekuip_points_win_eqpitm_init(wx, wy, width, height, actor, equip_type)<br />
    self.index = -1<br />
  end<br />
<br />
  def refresh<br />
    @has_armor_types ||= EQUIP_TYPES.size &gt; 1<br />
    kyon_ekuip_points_win_eqpitm_refr<br />
  end<br />
<br />
  def reset_index<br />
    self.index = 0 if @index &lt; 0<br />
  end<br />
<br />
  def enable?(item)<br />
    @actor.enough_ep?(@row_index, item)<br />
  end<br />
<br />
  def equip_type=(type)<br />
    @row_index = type<br />
    type = 0 if @actor.two_swords_style &amp;&amp; type == 1<br />
    type = EQUIP_TYPES[type] if type &gt; 0 and EQUIP_TYPES.size &gt; 1<br />
    @equip_type = type<br />
    refresh<br />
  end<br />
<br />
  def draw_item(index)<br />
    rect = item_rect(index)<br />
    c = self.contents<br />
    c.clear_rect(rect)<br />
    item = @data[index]<br />
    return unless item<br />
    number = &#36;game_party.item_number(item)<br />
    enabled = enable?(item)<br />
    rect.width -= 4<br />
    draw_item_name(item, rect.x, rect.y, enabled)<br />
    c.draw_text(rect, sprintf(":%2d", number), 2)<br />
    f = c.font<br />
    f.color = ep_color<br />
    f.color.alpha = 160 unless enabled<br />
    rect.x += EkuipPoints::EP_COST_X<br />
    rect.width = 40<br />
    number = item.ep_cost<br />
    c.draw_text(rect, sprintf("%2d", number), 2)<br />
  end<br />
end<br />
<br />
class Window_EquipStatus<br />
  alias :kyon_ekuip_points_win_eqpstts_ref :refresh<br />
  def refresh<br />
    kyon_ekuip_points_win_eqpstts_ref<br />
    draw_ep_left(@actor, 122, 0, 50)<br />
  end<br />
<br />
  def class_type<br />
    :equip_status<br />
  end<br />
end<br />
<br />
class Window_Status<br />
  alias :kyon_ekuip_points_win_stts_drw_bsc_info :draw_basic_info<br />
  def draw_basic_info(dx, dy)<br />
    kyon_ekuip_points_win_stts_drw_bsc_info(dx, dy)<br />
    ex, ey, ew, eh = EkuipPoints::EP_STATUS_XY_WH<br />
    draw_ep_left(@actor, dx + ex, dy + ey, ew, eh, true)<br />
  end<br />
<br />
  def class_type<br />
    :status<br />
  end<br />
end<br />
<br />
module EkuipPoints<br />
  class ActorStatsWindow &lt; Window_Base<br />
    def initialize(actor)<br />
      super(*ACTOR_EP_WIN_XY_WH)<br />
      self.opacity = ACTOR_STATS_WIN_OPA<br />
      self.back_opacity = ACTOR_STATS_WIN_BACK_OPA<br />
      self.z = 2000<br />
      @actor = actor<br />
      @hw = self.contents.width / 2<br />
      refresh<br />
    end<br />
<br />
    def refresh<br />
      self.contents.clear<br />
      draw_actor_name(@actor, 0, 0)<br />
      draw_ep_left(@actor, @hw, 0, @hw, 4)<br />
    end<br />
<br />
    def class_type<br />
      :ep_stats<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Equip<br />
  alias :kyon_ekuip_points_scn_eqp_stt :start<br />
  alias :kyon_ekuip_points_scn_eqp_up_eqp_sel :update_equip_selection<br />
  def start<br />
    kyon_ekuip_points_scn_eqp_stt<br />
    @equip_window.item_window = @item_window<br />
  end<br />
<br />
  def create_item_windows<br />
    types = Window_EquipItem::EQUIP_TYPES<br />
    @item_window = Window_EquipItem.new(0, 208, 544, 208, @actor, 0)<br />
    @item_window.help_window = @help_window<br />
    @item_window.active = false<br />
    @item_window.index = -1<br />
    @item_windows = [@item_window]<br />
  end<br />
<br />
  def update<br />
    super<br />
    update_menu_background<br />
    @help_window.update<br />
    update_status_window<br />
    if @equip_window.active<br />
      update_equip_selection<br />
    elsif @item_window.active<br />
      update_item_selection<br />
    end<br />
  end<br />
<br />
  def update_equip_selection<br />
    @equip_window.update<br />
    kyon_ekuip_points_scn_eqp_up_eqp_sel<br />
  end<br />
<br />
  def update_item_selection<br />
    @item_window.update<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      @equip_window.active = true<br />
      @item_window.active = false<br />
      @item_window.index = -1<br />
      return<br />
    elsif Input.trigger?(Input::C)<br />
      item = @item_window.item<br />
      pos = @equip_window.index<br />
      if item and !@actor.enough_ep?(pos, item)<br />
        Sound.play_buzzer<br />
        return<br />
      end<br />
      Sound.play_equip<br />
      @actor.change_equip(pos, item)<br />
      @equip_window.active = true<br />
      @item_window.active = false<br />
      @item_window.index = -1<br />
      @item_window.refresh<br />
      @equip_window.refresh<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Battle<br />
  alias :kyon_ekuip_points_scn_btl_up :update<br />
  alias :kyon_ekuip_points_scn_btl_up_act_cmdsel :update_actor_command_selection<br />
  def create_equipment_windows<br />
    actor = @active_battler<br />
    if actor.block_equip_change<br />
      Sound.play_buzzer<br />
      return<br />
    end<br />
    Sound.play_decision<br />
    wx, wy = EkuipPoints::BATTLE_EQUIP_WIN_XY<br />
    ww = Graphics.width<br />
    wh = Graphics.height - @actor_command_window.height<br />
    @ep_window = EkuipPoints::ActorStatsWindow.new(actor)<br />
    @equip_window = Window_EquipMod.new(wx, wy, actor)<br />
    @equip_item_window = Window_EquipItem.new(0, 0, ww, wh, actor, 0)<br />
    @equip_windows = [@ep_window, @equip_window, @equip_item_window]<br />
    @actor_command_window.active = false<br />
    @equip_index = 0<br />
    @equip_item = true<br />
  end<br />
<br />
  def dispose_equipment_windows<br />
    Sound.play_cancel<br />
    @equip_windows.each {|window| window.dispose }<br />
    @actor_command_window.active = true<br />
    @equip_item = false<br />
  end<br />
<br />
  def update<br />
    if @equip_item<br />
      update_equipment<br />
    else<br />
      kyon_ekuip_points_scn_btl_up<br />
    end<br />
  end<br />
<br />
  def update_equipment<br />
    update_basic(true)<br />
    update_info_viewport<br />
    case @equip_index<br />
    when 0<br />
      update_equip_type<br />
    when 1<br />
      update_equip_list<br />
    end<br />
  end<br />
<br />
  def refresh_equip_type<br />
    type = @equip_window.index<br />
    @equip_item_window.equip_type = type<br />
    @equip_item_window.index = -1<br />
  end<br />
<br />
  def update_equip_type<br />
    @equip_window.update<br />
    if Input.trigger?(Input::B)<br />
      dispose_equipment_windows<br />
      return<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      @equip_item_window.active = true<br />
      @equip_window.active = false<br />
      @equip_item_window.reset_index<br />
      return @equip_index = 1<br />
    elsif Input.trigger?(Input::DOWN)<br />
      refresh_equip_type<br />
      return<br />
    elsif Input.trigger?(Input::UP)<br />
      refresh_equip_type<br />
    end<br />
  end<br />
<br />
  def back_to_main_equip<br />
    @equip_item_window.index = -1<br />
    @equip_item_window.active = false<br />
    @equip_window.active = true<br />
    @equip_index = 0<br />
  end<br />
<br />
  def update_equip_list<br />
    @equip_item_window.update<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      back_to_main_equip<br />
      return<br />
    elsif Input.trigger?(Input::C)<br />
      pos = @equip_window.index<br />
      item = @equip_item_window.item<br />
      if item and !@active_battler.enough_ep?(pos, item)<br />
        Sound.play_buzzer<br />
        return<br />
      end<br />
      Sound.play_equip<br />
      @active_battler.change_equip(pos, item)<br />
      @equip_item_window.refresh<br />
      @equip_window.refresh<br />
      @ep_window.refresh<br />
      back_to_main_equip<br />
    end<br />
  end<br />
<br />
  def update_actor_command_selection<br />
    if Input.trigger?(Input::X)<br />
      create_equipment_windows<br />
      return<br />
    end<br />
    kyon_ekuip_points_scn_btl_up_act_cmdsel<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: x-large;" class="mycode_size"><a href="https://www.mediafire.com/folder/kh1bibfguxbll/EkuipmentPoints" target="_blank" rel="noopener" class="mycode_url">DOWNLOAD DEMO</a></span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer for non-commercial use.<br />
Include me in your game credits! <img src="https://www.save-point.org/images/smilies/ejlol/grin.gif" alt="Grinning" title="Grinning" class="smilie smilie_25" /><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[Scene_File FIX]]></title>
			<link>https://www.save-point.org/thread-13277.html</link>
			<pubDate>Sat, 11 Oct 2025 22:30: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-13277.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">Scene_File FIX</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">for VX ACE</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 />
Scripts like GOBJ try to catch weird stuff the RM engine does when creating visual objects or disposing of them, but I think it's a terrible approach because they simply ignore the bugs already contained in the default scripts.<br />
<br />
Yes, I know that VX ACE includes 2 bug fixes by default nowadays. Still, they're not all inclusive at all. There's one potential issue that has been ignored for quite a long time: the disposal of a Viewport object BEFORE its children have been disposed. Those children objects include Sprites and Windows. A perfect example of this is the Scene_File class, the parent class of Scene_Save and Scene_Load.<br />
<br />
In the default script you can find the terminate method that says:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>  def terminate<br />
    super<br />
    @savefile_viewport.dispose<br />
    @savefile_windows.each {|window| window.dispose }<br />
  end</code></div></div><br />
That means that the Scene_File class and its children classes are disposing of the Viewport right before it takes care of the Savefile windows. A bad choice indeed. It should always followed the opposite order.<br />
<br />
Get rid of:<br />
<br />
<ol type="1" class="mycode_list"><li>The <span style="font-weight: bold;" class="mycode_b">children objects first</span><br />
</li>
<li>Then dispose of the <span style="font-weight: bold;" class="mycode_b">parent object</span> safely.<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">How can you fix it?</span></span><br />
<br />
Well, the solution is QUITE SIMPLE: just invert the order in which those objects get disposed of, and that's it. So you'd only need to paste the following code in the bug fix section of the Script Editor and you'll be fine:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * Scene_File FIX * #<br />
<br />
class Scene_File<br />
  def terminate<br />
    super<br />
    @savefile_windows.each {|window| window.dispose }<br />
    @savefile_viewport.dispose<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Why is this fix relatively important for you as a game developer?</span></span><br />
<br />
It might not look impressive or critical at all, yet, it's highly convenient to prevent the engine from trying to do stuff in the incorrect / not-so-logical order in the first place. Debugger scripts like GOBJ will try to catch all those windows or their custom contents as critical objects that need to be notified otherwise.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
None.]]></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">Scene_File FIX</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">for VX ACE</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 />
Scripts like GOBJ try to catch weird stuff the RM engine does when creating visual objects or disposing of them, but I think it's a terrible approach because they simply ignore the bugs already contained in the default scripts.<br />
<br />
Yes, I know that VX ACE includes 2 bug fixes by default nowadays. Still, they're not all inclusive at all. There's one potential issue that has been ignored for quite a long time: the disposal of a Viewport object BEFORE its children have been disposed. Those children objects include Sprites and Windows. A perfect example of this is the Scene_File class, the parent class of Scene_Save and Scene_Load.<br />
<br />
In the default script you can find the terminate method that says:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>  def terminate<br />
    super<br />
    @savefile_viewport.dispose<br />
    @savefile_windows.each {|window| window.dispose }<br />
  end</code></div></div><br />
That means that the Scene_File class and its children classes are disposing of the Viewport right before it takes care of the Savefile windows. A bad choice indeed. It should always followed the opposite order.<br />
<br />
Get rid of:<br />
<br />
<ol type="1" class="mycode_list"><li>The <span style="font-weight: bold;" class="mycode_b">children objects first</span><br />
</li>
<li>Then dispose of the <span style="font-weight: bold;" class="mycode_b">parent object</span> safely.<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">How can you fix it?</span></span><br />
<br />
Well, the solution is QUITE SIMPLE: just invert the order in which those objects get disposed of, and that's it. So you'd only need to paste the following code in the bug fix section of the Script Editor and you'll be fine:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * Scene_File FIX * #<br />
<br />
class Scene_File<br />
  def terminate<br />
    super<br />
    @savefile_windows.each {|window| window.dispose }<br />
    @savefile_viewport.dispose<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Why is this fix relatively important for you as a game developer?</span></span><br />
<br />
It might not look impressive or critical at all, yet, it's highly convenient to prevent the engine from trying to do stuff in the incorrect / not-so-logical order in the first place. Debugger scripts like GOBJ will try to catch all those windows or their custom contents as critical objects that need to be notified otherwise.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
None.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[KInfoMenu VX]]></title>
			<link>https://www.save-point.org/thread-12923.html</link>
			<pubDate>Wed, 17 Sep 2025 02:20: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-12923.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">KInfoMenu VX</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"><span style="font-size: medium;" class="mycode_size">Introduction</span></span><br />
<br />
The script allows you to create some sort of tutorial menu with lots of options using a GUI similar to my other script <span style="font-weight: bold;" class="mycode_b">FancyChoices VX</span>.<br />
As the <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /> game developer you can define what texts and pictures you will display on screen. You can also play SE if deemed necessary.<br />
<br />
<div style="text-align: center;" class="mycode_align">Nope, this is <span style="font-weight: bold;" class="mycode_b"><span style="font-style: italic;" class="mycode_i">NOT a Plug &amp; Play</span></span> script at all, guys! <img src="https://www.save-point.org/images/smilies/ejlol/confused.gif" alt="Confused" title="Confused" class="smilie smilie_39" /></div>
<br />
If you want to customize it, you will have to edit several CONSTANTS in the KInfoMenu module first.<br />
<br />
All texts will be shown on top of the option boxes or on a typical message window. This also means that your typical note tags like \n[1] or \c[2] will work normally. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
<br />
The pictures will be shown on the center of the screen right when its corresponding text message gets displayed there.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Understanding the Options Feature</span></span><br />
<br />
There are 3 different levels of options, namely the Main Choices plus the first and second subcategories. Those subcategories depend on Hashes to let you customize its contents.<br />
<br />
Option labels are simple to understand, they are just a list of texts:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>SUB_CAT1["Combat"]  = ["Allies", "Enemies", "FF Menu", "Section 4", "Section 5", "Section 6", "Section 7"]</code></div></div><br />
"Combat" is a key that can be found in the Main Choices list:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>MAIN_CHOICES    = ["Combat", "Controls", "Concepts"]</code></div></div><br />
So both subcategories should use keys that already exist on the previous subcategory or the main choices list.<br />
<br />
The text hashes sport 3 keys and their respective values. Those keys are :text, :se and :pic and that's it. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><br />
<br />
You can leave the :pic and :se hashes empty if you need to, but you can add custom pictures or SFX at any given time. Just follow this example:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>SUB_CAT1_TEXTS["Enemies"] = {<br />
  :se =&gt; { 1 =&gt; "Battle1", 2 =&gt; "Battle2" },<br />
  :pic =&gt; { 1 =&gt; "093-Monster07", 2 =&gt; "099-Monster13" },  <br />
  :text =&gt; [<br />
    "You're not given a chance to think twice.",<br />
    "All mobs definitely hate you.",<br />
    "They'll sweep the floor with your death body",<br />
    "while laughing maniacally.",<br />
    "Please don't challenge them unless you know",<br />
    "very well what you're doing.",<br />
    "You've been warned!",<br />
  ] }</code></div></div><br />
So you need to pick a CONSTANT, then call its option key, and make it contain a { Hash }.<br />
The :se and :pic keys use page indexes as their hash keys, but you can skip pages at will.<br />
The :text hash has a very interesting feature that you should know about from the very beginning. If you plan to display less than 4 lines of text on a given <img src="https://www.save-point.org/images/smilies/ejlol/book.gif" alt="Book" title="Book" class="smilie smilie_163" /> page, and you expect another page to show up next after pressing the OK button, you will have to add empty Strings "" and a comma , per empty line. And this is mandatory. <img src="https://www.save-point.org/images/smilies/ejlol/angry.gif" alt="Angry" title="Angry" class="smilie smilie_28" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">A Friendly Reminder</span></span><br />
<br />
If a key like "Section 4" does not exist either in <span style="font-weight: bold;" class="mycode_b">SUB_CAT1_TEXTS</span> or <span style="font-weight: bold;" class="mycode_b">SUB_CAT2_TEXTS</span>, the script will skip the whole enchilada to prevent it from crashing.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">NOTES</span></span><br />
<br />
The comments include an explanation that claims that calling the custom scene is optional. <img src="https://www.save-point.org/images/smilies/ejlol/sweathappy.gif" alt="Happy with a sweat" title="Happy with a sweat" class="smilie smilie_31" /> Well, that is only true if you pretend to customize your main menu to include an option to open the KInfoMenu scene. If you are planning to use any NPC as an interface for this tutorial menu, you will have to make that script call at all costs. <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /><br />
<br />
The <span style="font-weight: bold;" class="mycode_b">WINDOW_BACK_OP</span> constant will let you set the message window's back opacity.<br />
<br />
I don't care if there are other ways to achieve the same goal. I just wanted to create this special menu, and 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 />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Screenshots</span></span><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='+';}"/> Several Snapshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<span style="font-weight: bold;" class="mycode_b">NOTE:</span> The \i[n] note tags would get replaced by an icon in no time IF you have included a custom message script in your game project.<br />
<img src="https://i.postimg.cc/J4jDyvt7/kinfomenu-vx001.jpg" loading="lazy"  alt="[Image: kinfomenu-vx001.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/T2z53fdH/kinfomenu-vx002.jpg" loading="lazy"  alt="[Image: kinfomenu-vx002.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/mhW4fdG8/kinfomenu-vx003.jpg" loading="lazy"  alt="[Image: kinfomenu-vx003.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/jqwJTLb7/kinfomenu-vx004.jpg" loading="lazy"  alt="[Image: kinfomenu-vx004.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/Mpxc15j7/kinfomenu-vx005.jpg" loading="lazy"  alt="[Image: kinfomenu-vx005.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">The Script</span></span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KInfoMenu VX * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   v1.2.3 - 2025-09-17<br />
#   Not a Plug &amp; Play Script!<br />
<br />
# This scriptlet lets you setup a simple tutorial menu.<br />
<br />
# NOTES on Message Window's Contents:<br />
<br />
# For the message window, empty lines are equally as important as normal ones.<br />
# They are used as fillers, and this matters a lot whenever you're trying to<br />
# display multiple pages on screen. If you ever skip them, you'll soon notice<br />
# that certain lines of text do appear sooner than expected.<br />
<br />
# * Optional Script Call * #<br />
# &#36;scene = KInfoMenu::Scene.new<br />
<br />
module KInfoMenu<br />
  BACKDROP         = "Title"<br />
  TITLE_FILENAME   = "title480"<br />
# BGM Options: "" for no song, "Some Name" for any specific BGM<br />
  TUTORIAL_BGM     = "Ship"<br />
  TEXT_ALIGN_X     = :center<br />
  CHOICE_ALIGN_X   = :center<br />
  CHOICE_TOP_Y     = 76<br />
  CHOICE_MARGIN_Y  = 16<br />
  CHOICE_ROW_MAX   = 6<br />
  MAIN_CHOICE_FILE = "box280"<br />
  SUB_CHOICE_FILE  = "box240"<br />
  CHOICE_CURSOR    = "cursor_shield"<br />
  MAIN_TITLE       = "Tutorial Menu"<br />
  MAIN_CHOICES     = ["Combat", "Controls", "Concepts"]<br />
  FACE_FILENAME    = "Actor1"<br />
  FACE_INDEX       = 0<br />
  WINDOW_BACKDROP  = 0 # 0, 1 or 2 only!<br />
  WINDOW_POSITION  = 2 # 0, 1 or 2 only!<br />
  WINDOW_BACK_OP   = 255<br />
  WINDOW_CONFIG = [FACE_FILENAME, FACE_INDEX, WINDOW_BACKDROP, WINDOW_POSITION]<br />
# - Message Window's Contents - #<br />
  INTRO_TEXTS = ["Welcome to the Great Hero's Tutorial!",<br />
                 "I'm your valorous host &#92;c[2]&#92;n[1]&#92;c[0].",<br />
                 "Nice to meet you!&#92;i[12]"]<br />
# - The Don't Touch These Lines Section - #<br />
  MAIN_CHO_COLS  = 1<br />
  SUB_CAT1       = {}<br />
  SUB_CAT2       = {}<br />
  SUB_CAT1_TEXTS = {}<br />
  SUB_CAT2_TEXTS = {}<br />
  SUB_CAT1.default       = []<br />
  SUB_CAT2.default       = []<br />
  SUB_CAT1_TEXTS.default = {}<br />
  SUB_CAT2_TEXTS.default = {}<br />
# - End of Section - #<br />
  SUB_CAT1["Combat"]   = ["Allies", "Enemies", "FF Menu", "Section 4",<br />
                          "Section 5", "Section 6", "Section 7"]<br />
  SUB_CAT1["Controls"] = ["Decision", "Cancel"]<br />
  SUB_CAT1["Concepts"] = ["Concepts 1", "Concepts 2", "Concepts 3"]<br />
  SUB_CAT1_TEXTS["Allies"] = {<br />
  :se =&gt; {},<br />
  :pic =&gt; {},<br />
  :text =&gt; [<br />
    "Most of the time your allies will be very useless.",<br />
    "Just keep them alive to avoid making very large",<br />
    "donations to your local priest to heal those",<br />
    "reckless companions after every single battle."<br />
  ] }<br />
  SUB_CAT1_TEXTS["Enemies"] = {<br />
  :se =&gt; { 1 =&gt; "Battle1", 2 =&gt; "Battle2" },<br />
  :pic =&gt; { 1 =&gt; "Mimic", 2 =&gt; "Assassin" },<br />
  :text =&gt; [<br />
    "You're not given a chance to think twice.",<br />
    "All mobs definitely hate you.",<br />
    "They'll sweep the floor with your death body",<br />
    "while laughing maniacally.",<br />
    "Please don't challenge them unless you know",<br />
    "very well what you're doing.&#92;|",<br />
    "You've been warned!",<br />
    ""<br />
  ] }<br />
  SUB_CAT1_TEXTS["FF Menu"] = {<br />
  :se =&gt; {},<br />
  :pic =&gt; { 1 =&gt; "FF9_MenuBar old" },<br />
  :text =&gt; [<br />
    "This tutorial uses an old fashioned FF9 menubar.",<br />
    "We don't know when it will be replaced by a",<br />
    "new one. The game developer has refused to",<br />
    "address the issue on social media."<br />
  ] }<br />
  SUB_CAT2["Concepts 1"] = ["Concept 1", "Concept 2", "Concept 3"]<br />
  SUB_CAT2_TEXTS["Concept 1"] = {<br />
  :se =&gt; {},<br />
  :pic =&gt; {},<br />
  :text =&gt; [<br />
    "You've chosen the Proof of Concept #1!&#92;|",<br />
    "Hurray..."<br />
  ] }<br />
<br />
class TextBox<br />
  def initialize(pos, total, vp=nil)<br />
    @index = pos<br />
    @max = total<br />
    @row_max = CHOICE_ROW_MAX<br />
    @col_max = (@max / @row_max) + 1<br />
    @viewport = vp<br />
    @backdrop = Sprite.new(vp)<br />
    @label = Sprite.new(vp)<br />
    @label.z = 50<br />
  end<br />
<br />
  def set_image(filename)<br />
    @filename = filename<br />
    set_bitmap<br />
    set_text_bitmap<br />
    reset_alignment<br />
  end<br />
<br />
  def set_bitmap<br />
    bitmap = Cache.picture(@filename)<br />
    @width = bitmap.width<br />
    @height = bitmap.height<br />
    @rect = bitmap.rect<br />
    @col_width = Graphics.width<br />
    @center_x = (@col_width - @width) / 2<br />
    @backdrop.bitmap = bitmap<br />
  end<br />
<br />
  def set_align_x<br />
    case TEXT_ALIGN_X<br />
    when :left<br />
      0<br />
    when :center<br />
      1<br />
    when :right<br />
      2<br />
    else<br />
      TEXT_ALIGN_X<br />
    end<br />
  end<br />
<br />
  def set_text_bitmap<br />
    @align_x = set_align_x<br />
    @label.bitmap = Bitmap.new(@width, @height)<br />
  end<br />
<br />
  def set_title_xy<br />
    @backdrop.x = @center_x<br />
    @backdrop.y = 8<br />
  end<br />
<br />
  def set_align_xy<br />
    h = @height + CHOICE_MARGIN_Y<br />
    if @max &lt; @row_max<br />
      @backdrop.x = @center_x<br />
      @backdrop.y = CHOICE_TOP_Y + @index * h<br />
    else<br />
      n = @index % @col_max<br />
      cw = @col_width / 2<br />
      @backdrop.x = n * cw + (cw - @width) / 2<br />
      @backdrop.y = CHOICE_TOP_Y + @index / @col_max * h<br />
    end<br />
  end<br />
<br />
  def reset_alignment<br />
    @index ? set_align_xy : set_title_xy<br />
    @label.x = @backdrop.x<br />
    @label.y = @backdrop.y<br />
  end<br />
<br />
  def x<br />
    @backdrop.x<br />
  end<br />
<br />
  def y<br />
    @backdrop.y<br />
  end<br />
<br />
  def set_text(text)<br />
    @text = text<br />
    bit = @label.bitmap<br />
    bit.clear<br />
    bit.draw_text(@rect, text, @align_x)<br />
  end<br />
<br />
  def dispose<br />
    @label.bitmap.dispose<br />
    @label.dispose<br />
    @backdrop.bitmap.dispose<br />
    @backdrop.dispose<br />
  end<br />
  attr_reader :height, :text<br />
end<br />
<br />
class MessageWindow &lt; Window_Message<br />
  def initialize<br />
    super<br />
    self.opacity = @background == 0 ? 255 : 0<br />
    self.back_opacity = WINDOW_BACK_OP<br />
  end<br />
<br />
  def reset_window<br />
    @background = &#36;game_message.background<br />
    @position = &#36;game_message.position<br />
    self.opacity = @background == 0 ? 255 : 0<br />
    self.back_opacity = WINDOW_BACK_OP<br />
    case @position<br />
    when 0  # Top<br />
      self.y = 0<br />
      @gold_window.y = 360<br />
    when 1  # Middle<br />
      self.y = 144<br />
      @gold_window.y = 0<br />
    when 2  # Bottom<br />
      self.y = 288<br />
      @gold_window.y = 0<br />
    end<br />
  end<br />
<br />
  def new_page?<br />
    @text and !@text.empty? and @line_count &gt;= MAX_LINE<br />
  end<br />
<br />
  def input_pause<br />
    if Input.trigger?(Input::B) or Input.trigger?(Input::C)<br />
      &#36;game_message.new_page = new_page?<br />
    end<br />
    super<br />
  end<br />
<br />
  def open_message<br />
    start_message<br />
    open<br />
    self.visible = true<br />
  end<br />
<br />
  def clear_contents<br />
    self.pause = false<br />
    self.index = -1<br />
    @gold_window.close<br />
    @number_input_window.active = false<br />
    @number_input_window.visible = false<br />
  end<br />
end<br />
<br />
class Spriteset<br />
  def initialize<br />
    create_variables<br />
    create_backdrop<br />
    create_viewports<br />
    create_title<br />
    create_picture<br />
    create_main_choices<br />
    create_cursors<br />
    update_box(0)<br />
    @sprites = @cursors + [@backdrop, @picture]<br />
  end<br />
<br />
  def create_variables<br />
    @index = 0<br />
    @section_index = 0<br />
    @subsection_index = 0<br />
    @sound = RPG::SE.new<br />
    @cursors = []<br />
    @sections = []<br />
    @subsections = []<br />
    @main_boxes = []<br />
    @section_boxes = []<br />
    @subsection_boxes = []<br />
    @section_viewports = []<br />
    @subsection_viewports = []<br />
  end<br />
<br />
  def create_backdrop<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = Cache.system(BACKDROP)<br />
  end<br />
<br />
  def create_viewports<br />
    @viewport_rect = [0, 0, Graphics.width, Graphics.height]<br />
    @main_viewport = Viewport.new(*@viewport_rect)<br />
    @picture_viewport = Viewport.new(*@viewport_rect)<br />
    @picture_viewport.z = 1000<br />
  end<br />
<br />
  def create_title<br />
    @title = TextBox.new(nil, 0, nil)<br />
    @title.set_image(TITLE_FILENAME)<br />
    @title.set_text(MAIN_TITLE)<br />
  end<br />
<br />
  def create_picture<br />
    @picture = Sprite.new(@picture_viewport)<br />
    @picture.y = 48<br />
    @picture.visible = false<br />
    @picture.bitmap = Bitmap.new(Graphics.width, Graphics.height - 96)<br />
  end<br />
<br />
  def create_main_choices<br />
    filename = MAIN_CHOICE_FILE<br />
    total = MAIN_CHOICES.size<br />
    MAIN_CHOICES.each_with_index do |choice, n|<br />
      box = TextBox.new(n, total, @main_viewport)<br />
      box.set_image(filename)<br />
      box.set_text(choice)<br />
      @main_boxes &lt;&lt; box<br />
    end<br />
    @item_max = @main_boxes.size<br />
  end<br />
<br />
  def create_cursors<br />
    box = @main_boxes[@index]<br />
    @main_cursor = Sprite.new(@main_viewport)<br />
    @main_cursor.z = 100<br />
    @main_cursor.bitmap = Cache.system(CHOICE_CURSOR)<br />
    @main_cursor.x = box.x + 4<br />
    @offset_y = (box.height - @main_cursor.bitmap.height) / 2<br />
    @main_cursor.y = box.y + @offset_y<br />
    @section_cursor = Sprite.new<br />
    @section_cursor.visible = false<br />
    @section_cursor.z = 100<br />
    @section_cursor.bitmap = Cache.system(CHOICE_CURSOR)<br />
    @subsection_cursor = Sprite.new<br />
    @subsection_cursor.visible = false<br />
    @subsection_cursor.z = 100<br />
    @subsection_cursor.bitmap = Cache.system(CHOICE_CURSOR)<br />
    @cursors &lt;&lt; @main_cursor &lt;&lt; @section_cursor &lt;&lt; @subsection_cursor<br />
  end<br />
<br />
  def update_main<br />
    if Input.trigger?(Input::UP)<br />
      Sound.play_cursor<br />
      update_box(-1)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      Sound.play_cursor<br />
      update_box(1)<br />
    end<br />
  end<br />
<br />
  def update_box(n)<br />
    @index = (@index + n) % @item_max<br />
    box = @main_boxes[@index]<br />
    @section_title = box.text<br />
    @main_cursor.x = box.x + 4<br />
    @main_cursor.y = box.y + @offset_y<br />
  end<br />
<br />
  def show_main<br />
    @title.set_text(MAIN_TITLE)<br />
    @main_viewport.visible = true<br />
  end<br />
<br />
  def hide_main<br />
    @main_viewport.visible = false<br />
  end<br />
<br />
  def find_section_viewport<br />
    @section_viewports[@index] ||= Viewport.new(*@viewport_rect)<br />
  end<br />
<br />
  def find_subsections<br />
    @sections[@index] ||= SUB_CAT1[@section_title].dup<br />
  end<br />
<br />
  def find_section_boxes<br />
    @section_boxes[@index] ||= []<br />
  end<br />
<br />
  def setup_section<br />
    @section_viewport = find_section_viewport<br />
    @section_list = find_subsections<br />
    @current_boxes = find_section_boxes<br />
    create_section if @current_boxes.empty?<br />
    reset_section<br />
    update_section_box(0)<br />
    @title.set_text(@section_title)<br />
    @section_viewport.visible = true<br />
  end<br />
<br />
  def create_section<br />
    return if @section_list.empty?<br />
    filename = SUB_CHOICE_FILE<br />
    total = @section_list.size<br />
    @section_list.each_with_index do |choice, n|<br />
      box = TextBox.new(n, total, @section_viewport)<br />
      box.set_image(filename)<br />
      box.set_text(choice)<br />
      @current_boxes &lt;&lt; box<br />
    end<br />
  end<br />
<br />
  def reset_section<br />
    @section_max = @current_boxes.size<br />
    @col_max = (@section_max / CHOICE_ROW_MAX) + 1<br />
    @section_index = 0<br />
    box = @current_boxes[@section_index]<br />
    @section_oy1 = (box.height - @section_cursor.bitmap.height) / 2<br />
    @section_cursor.visible = box ? true : false<br />
  end<br />
<br />
  def show_section<br />
    @title.set_text(@section_title)<br />
    @section_viewport.visible = true<br />
    @section_cursor.visible = true<br />
  end<br />
<br />
  def hide_section(clear)<br />
    @section_cursor.visible = false<br />
    @section_viewport.visible = false<br />
    return unless clear<br />
    @section_viewport = @current_boxes = nil<br />
    @section_index = 0<br />
  end<br />
<br />
  def update_section<br />
    if Input.trigger?(Input::UP)<br />
      Sound.play_cursor<br />
      update_section_box(-@col_max)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      Sound.play_cursor<br />
      update_section_box(@col_max)<br />
      return<br />
    end<br />
    return if @col_max == 1<br />
    if Input.trigger?(Input::LEFT)<br />
      Sound.play_cursor<br />
      update_section_box(-1)<br />
      return<br />
    elsif Input.trigger?(Input::RIGHT)<br />
      Sound.play_cursor<br />
      update_section_box(1)<br />
    end<br />
  end<br />
<br />
  def update_section_box(n)<br />
    @section_index = (@section_index + n) % @section_max<br />
    box = @current_boxes[@section_index]<br />
    @subsection_title1 = box.text<br />
    @section_cursor.x = box.x + 4<br />
    @section_cursor.y = box.y + @section_oy1<br />
  end<br />
<br />
  def set_pictures(pictures)<br />
    @page_index = 1<br />
    @pictures = pictures<br />
    show_picture<br />
  end<br />
<br />
  def show_picture<br />
    picture = @pictures[@page_index]<br />
    return unless picture<br />
    @picture.bitmap.dispose<br />
    @picture.bitmap = bit = Cache.picture(picture)<br />
    @picture.x = (Graphics.width - bit.width) / 2<br />
    @picture.y = (Graphics.height - bit.height - 128) / 2<br />
    @picture.visible = true<br />
  end<br />
<br />
  def set_sfx(sfx)<br />
    @sfx = sfx<br />
    play_sound<br />
  end<br />
<br />
  def play_sound<br />
    @sound.name = @sfx[@page_index] || ""<br />
    @sound.play<br />
  end<br />
<br />
  def find_subsection_viewport<br />
    @subsection_viewports[@section_index] ||= Viewport.new(*@viewport_rect)<br />
  end<br />
<br />
  def find_subsections_lvl2<br />
    @subsections[@section_index] ||= SUB_CAT2[@subsection_title1].dup<br />
  end<br />
<br />
  def find_subsection_boxes<br />
    @subsection_boxes[@section_index] ||= []<br />
  end<br />
<br />
  def setup_subsection<br />
    @subsection_viewport = find_subsection_viewport<br />
    @subsection_list = find_subsections_lvl2<br />
    @current_subboxes = find_subsection_boxes<br />
    create_subsection if @current_subboxes.empty?<br />
    reset_subsection<br />
    update_subsection_box(0)<br />
    box = @current_subboxes[@subsection_index]<br />
    @subsection_title2 = box ? box.text : ""<br />
    @title.set_text(@subsection_title1)<br />
    @subsection_viewport.visible = true<br />
  end<br />
<br />
  def create_subsection<br />
    return if @subsection_list.empty?<br />
    filename = SUB_CHOICE_FILE<br />
    total = @subsection_list.size<br />
    @subsection_list.each_with_index do |choice, n|<br />
      box = TextBox.new(n, total, @subsection_viewport)<br />
      box.set_image(filename)<br />
      box.set_text(choice)<br />
      @current_subboxes &lt;&lt; box<br />
    end<br />
  end<br />
<br />
  def reset_subsection<br />
    @subsection_max = @current_subboxes.size<br />
    @subcol_max = (@subsection_max / CHOICE_ROW_MAX) + 1<br />
    @subsection_index = 0<br />
    box = @current_subboxes[@subsection_index]<br />
    @section_oy2 = (box.height - @subsection_cursor.bitmap.height) / 2<br />
    @subsection_cursor.visible = box ? true : false<br />
  end<br />
<br />
  def hide_subsection<br />
    @subsection_cursor.visible = false<br />
    @subsection_viewport.visible = false<br />
    @subsection_viewport = @current_subboxes = nil<br />
    @subsection_index = 0<br />
  end<br />
<br />
  def update_subsection<br />
    if Input.trigger?(Input::UP)<br />
      Sound.play_cursor<br />
      update_subsection_box(-@subcol_max)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      Sound.play_cursor<br />
      update_subsection_box(@subcol_max)<br />
      return<br />
    end<br />
    return if @subcol_max == 1<br />
    if Input.trigger?(Input::LEFT)<br />
      Sound.play_cursor<br />
      update_subsection_box(-1)<br />
      return<br />
    elsif Input.trigger?(Input::RIGHT)<br />
      Sound.play_cursor<br />
      update_subsection_box(1)<br />
    end<br />
  end<br />
<br />
  def update_subsection_box(n)<br />
    @subsection_index = (@subsection_index + n) % @subsection_max<br />
    box = @current_subboxes[@subsection_index]<br />
    @subsection_title2 = box.text<br />
    @subsection_cursor.x = box.x + 4<br />
    @subsection_cursor.y = box.y + @section_oy2<br />
  end<br />
<br />
  def hide_picture<br />
    @picture.bitmap.dispose<br />
    @picture.bitmap = Bitmap.new(Graphics.width, Graphics.height - 96)<br />
    @picture.visible = false<br />
  end<br />
<br />
  def update_extras<br />
    return unless &#36;game_message.new_page<br />
    &#36;game_message.new_page = nil<br />
    @page_index += 1<br />
    show_picture<br />
    play_sound<br />
  end<br />
<br />
  def dispose<br />
    @sprites.each do |sprite|<br />
      sprite.bitmap.dispose<br />
      sprite.dispose<br />
    end<br />
    @subsection_boxes.each do |boxes|<br />
      next unless boxes<br />
      boxes.each {|box| box.dispose }<br />
    end<br />
    @section_boxes.each do |boxes|<br />
      next unless boxes<br />
      boxes.each {|box| box.dispose }<br />
    end<br />
    @main_boxes.each {|box| box.dispose }<br />
    @title.dispose<br />
    @section_viewports.each {|vp| vp.dispose if vp }<br />
    @picture_viewport.dispose<br />
    @main_viewport.dispose<br />
    @section_boxes.clear<br />
    @main_boxes.clear<br />
    @section_viewports.clear<br />
  end<br />
  attr_reader :subsection_title1, :subsection_title2<br />
end<br />
<br />
class Scene<br />
  def initialize(index=nil)<br />
    @main_menu_index = index<br />
    @map_bgm = RPG::BGM.last<br />
    @bgm = RPG::BGM.new<br />
    return if TUTORIAL_BGM.empty?<br />
    @bgm.name = TUTORIAL_BGM<br />
    @bgm.play<br />
  end<br />
<br />
  def main<br />
    start<br />
    Graphics.transition<br />
    update_basic while @stage<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def start<br />
    @stage = :message<br />
    @next_stage = :main<br />
    @spriteset = Spriteset.new<br />
    @message_window = MessageWindow.new<br />
    &#36;game_message.setup_message(*WINDOW_CONFIG)<br />
    &#36;game_message.set_tutorial_texts(INTRO_TEXTS)<br />
  end<br />
<br />
  def update_basic<br />
    Graphics.update<br />
    Input.update<br />
    update<br />
  end<br />
<br />
  def close_message<br />
    &#36;game_message.texts.clear<br />
    @message_window.clear_contents<br />
    @message_window.visible = false<br />
    @spriteset.hide_picture<br />
    @stage = @next_stage<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :message<br />
      update_message<br />
    when :main<br />
      update_main<br />
    when :section<br />
      update_section<br />
    when :subsection<br />
      update_subsection<br />
    end<br />
  end<br />
<br />
  def update_message<br />
    @message_window.update<br />
    while &#36;game_message.visible<br />
      Graphics.update<br />
      Input.update<br />
      @message_window.update<br />
      @spriteset.update_extras<br />
    end<br />
    close_message<br />
  end<br />
<br />
  def update_main<br />
    @spriteset.update_main<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      if @main_menu_index<br />
        &#36;scene = Scene_Menu.new(@main_menu_index)<br />
      else<br />
        &#36;scene = Scene_Map.new<br />
      end<br />
      return @stage = nil<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      @spriteset.hide_main<br />
      @spriteset.setup_section<br />
      @stage = :section<br />
    end<br />
  end<br />
<br />
  def update_section<br />
    @spriteset.update_section<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      @spriteset.hide_section(true)<br />
      @spriteset.show_main<br />
      return @stage = :main<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      key = @spriteset.subsection_title1<br />
      if SUB_CAT2[key].any?<br />
        show_subsection<br />
      else<br />
        show_section_message(key)<br />
      end<br />
    end<br />
  end<br />
<br />
  def show_subsection<br />
    @spriteset.hide_section(nil)<br />
    @spriteset.setup_subsection<br />
    @stage = :subsection<br />
  end<br />
<br />
  def show_section_message(key)<br />
    data = SUB_CAT1_TEXTS[key].dup<br />
    return if data.empty?<br />
    pictures = data[:pic]<br />
    message = data[:text]<br />
    sfx = data[:se]<br />
    &#36;game_message.setup_message(*WINDOW_CONFIG)<br />
    &#36;game_message.set_tutorial_texts(message)<br />
    @message_window.open_message<br />
    @spriteset.set_pictures(pictures)<br />
    @spriteset.set_sfx(sfx)<br />
    @next_stage = :section<br />
    @stage = :message<br />
  end<br />
<br />
  def update_subsection<br />
    @spriteset.update_subsection<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      @spriteset.hide_subsection<br />
      @spriteset.show_section<br />
      return @stage = :section<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      key = @spriteset.subsection_title2<br />
      data = SUB_CAT2_TEXTS[key]<br />
      return if data.empty?<br />
      message = data[:text]<br />
      pictures = data[:pic]<br />
      sfx = data[:se]<br />
      &#36;game_message.setup_message(*WINDOW_CONFIG)<br />
      &#36;game_message.set_tutorial_texts(message)<br />
      @message_window.open_message<br />
      @spriteset.set_pictures(pictures)<br />
      @spriteset.set_sfx(sfx)<br />
      @next_stage = :subsection<br />
      @stage = :message<br />
    end<br />
  end<br />
<br />
  def terminate<br />
    @message_window.dispose<br />
    @spriteset.dispose<br />
    &#36;game_message.custom_scene = nil<br />
    &#36;game_message.clear<br />
    return if TUTORIAL_BGM.empty?<br />
    if &#36;game_map.autoplay_bgm?<br />
      &#36;game_map.autoplay<br />
    elsif @map_bgm<br />
      @map_bgm.play<br />
    end<br />
  end<br />
end<br />
<br />
end<br />
<br />
class Game_Message<br />
  def setup_message(*options)<br />
    options = options.dup<br />
    @face_name = options.shift<br />
    @face_index = options.shift<br />
    @background = options.shift<br />
    @position = options.shift<br />
    @custom_scene = true<br />
  end<br />
<br />
  def set_tutorial_texts(original_texts)<br />
    @texts = original_texts.dup<br />
    @texts.each do |line|<br />
      line.gsub!("&#92;e", "&#92;&#92;c[")<br />
      line.gsub!(/(.)&#92;^/) { "#{&#36;1}&#92;&#92;^" }<br />
      line.gsub!(/([^&#92;&#92;])&#92;|/) { "#{&#36;1}&#92;&#92;|" }<br />
      line.gsub!(/(&#92;-|,|;|:|!)&#92;./) { "#{&#36;1}&#92;&#92;." }<br />
      line.gsub!(/[&#92;b]/i, "&#92;&#92;b")<br />
      line.gsub!(/([^&#92;&#92;])i&#92;[([0-9]+)&#92;]/i) { "#{&#36;1}&#92;&#92;i[#{&#36;2}]" }<br />
      line.gsub!(/&#92;n&#92;[([0-9]+)&#92;]/i) { "&#92;&#92;n[#{&#36;1}]" }<br />
    end<br />
    @visible = true<br />
  end<br />
  attr_accessor :new_page, :custom_scene<br />
end<br />
<br />
class Game_Map<br />
  def autoplay_bgm?<br />
    @map.autoplay_bgm<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer for non-commercial games. <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /><br />
Include my nickname in your game credits.<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">KInfoMenu VX</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"><span style="font-size: medium;" class="mycode_size">Introduction</span></span><br />
<br />
The script allows you to create some sort of tutorial menu with lots of options using a GUI similar to my other script <span style="font-weight: bold;" class="mycode_b">FancyChoices VX</span>.<br />
As the <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /> game developer you can define what texts and pictures you will display on screen. You can also play SE if deemed necessary.<br />
<br />
<div style="text-align: center;" class="mycode_align">Nope, this is <span style="font-weight: bold;" class="mycode_b"><span style="font-style: italic;" class="mycode_i">NOT a Plug &amp; Play</span></span> script at all, guys! <img src="https://www.save-point.org/images/smilies/ejlol/confused.gif" alt="Confused" title="Confused" class="smilie smilie_39" /></div>
<br />
If you want to customize it, you will have to edit several CONSTANTS in the KInfoMenu module first.<br />
<br />
All texts will be shown on top of the option boxes or on a typical message window. This also means that your typical note tags like \n[1] or \c[2] will work normally. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
<br />
The pictures will be shown on the center of the screen right when its corresponding text message gets displayed there.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Understanding the Options Feature</span></span><br />
<br />
There are 3 different levels of options, namely the Main Choices plus the first and second subcategories. Those subcategories depend on Hashes to let you customize its contents.<br />
<br />
Option labels are simple to understand, they are just a list of texts:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>SUB_CAT1["Combat"]  = ["Allies", "Enemies", "FF Menu", "Section 4", "Section 5", "Section 6", "Section 7"]</code></div></div><br />
"Combat" is a key that can be found in the Main Choices list:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>MAIN_CHOICES    = ["Combat", "Controls", "Concepts"]</code></div></div><br />
So both subcategories should use keys that already exist on the previous subcategory or the main choices list.<br />
<br />
The text hashes sport 3 keys and their respective values. Those keys are :text, :se and :pic and that's it. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><br />
<br />
You can leave the :pic and :se hashes empty if you need to, but you can add custom pictures or SFX at any given time. Just follow this example:<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>SUB_CAT1_TEXTS["Enemies"] = {<br />
  :se =&gt; { 1 =&gt; "Battle1", 2 =&gt; "Battle2" },<br />
  :pic =&gt; { 1 =&gt; "093-Monster07", 2 =&gt; "099-Monster13" },  <br />
  :text =&gt; [<br />
    "You're not given a chance to think twice.",<br />
    "All mobs definitely hate you.",<br />
    "They'll sweep the floor with your death body",<br />
    "while laughing maniacally.",<br />
    "Please don't challenge them unless you know",<br />
    "very well what you're doing.",<br />
    "You've been warned!",<br />
  ] }</code></div></div><br />
So you need to pick a CONSTANT, then call its option key, and make it contain a { Hash }.<br />
The :se and :pic keys use page indexes as their hash keys, but you can skip pages at will.<br />
The :text hash has a very interesting feature that you should know about from the very beginning. If you plan to display less than 4 lines of text on a given <img src="https://www.save-point.org/images/smilies/ejlol/book.gif" alt="Book" title="Book" class="smilie smilie_163" /> page, and you expect another page to show up next after pressing the OK button, you will have to add empty Strings "" and a comma , per empty line. And this is mandatory. <img src="https://www.save-point.org/images/smilies/ejlol/angry.gif" alt="Angry" title="Angry" class="smilie smilie_28" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">A Friendly Reminder</span></span><br />
<br />
If a key like "Section 4" does not exist either in <span style="font-weight: bold;" class="mycode_b">SUB_CAT1_TEXTS</span> or <span style="font-weight: bold;" class="mycode_b">SUB_CAT2_TEXTS</span>, the script will skip the whole enchilada to prevent it from crashing.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">NOTES</span></span><br />
<br />
The comments include an explanation that claims that calling the custom scene is optional. <img src="https://www.save-point.org/images/smilies/ejlol/sweathappy.gif" alt="Happy with a sweat" title="Happy with a sweat" class="smilie smilie_31" /> Well, that is only true if you pretend to customize your main menu to include an option to open the KInfoMenu scene. If you are planning to use any NPC as an interface for this tutorial menu, you will have to make that script call at all costs. <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /><br />
<br />
The <span style="font-weight: bold;" class="mycode_b">WINDOW_BACK_OP</span> constant will let you set the message window's back opacity.<br />
<br />
I don't care if there are other ways to achieve the same goal. I just wanted to create this special menu, and 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 />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">Screenshots</span></span><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='+';}"/> Several Snapshots</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;">
<span style="font-weight: bold;" class="mycode_b">NOTE:</span> The \i[n] note tags would get replaced by an icon in no time IF you have included a custom message script in your game project.<br />
<img src="https://i.postimg.cc/J4jDyvt7/kinfomenu-vx001.jpg" loading="lazy"  alt="[Image: kinfomenu-vx001.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/T2z53fdH/kinfomenu-vx002.jpg" loading="lazy"  alt="[Image: kinfomenu-vx002.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/mhW4fdG8/kinfomenu-vx003.jpg" loading="lazy"  alt="[Image: kinfomenu-vx003.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/jqwJTLb7/kinfomenu-vx004.jpg" loading="lazy"  alt="[Image: kinfomenu-vx004.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/Mpxc15j7/kinfomenu-vx005.jpg" loading="lazy"  alt="[Image: kinfomenu-vx005.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">The Script</span></span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KInfoMenu VX * #<br />
#   Scripter : Kyonides Arkanthes<br />
#   v1.2.3 - 2025-09-17<br />
#   Not a Plug &amp; Play Script!<br />
<br />
# This scriptlet lets you setup a simple tutorial menu.<br />
<br />
# NOTES on Message Window's Contents:<br />
<br />
# For the message window, empty lines are equally as important as normal ones.<br />
# They are used as fillers, and this matters a lot whenever you're trying to<br />
# display multiple pages on screen. If you ever skip them, you'll soon notice<br />
# that certain lines of text do appear sooner than expected.<br />
<br />
# * Optional Script Call * #<br />
# &#36;scene = KInfoMenu::Scene.new<br />
<br />
module KInfoMenu<br />
  BACKDROP         = "Title"<br />
  TITLE_FILENAME   = "title480"<br />
# BGM Options: "" for no song, "Some Name" for any specific BGM<br />
  TUTORIAL_BGM     = "Ship"<br />
  TEXT_ALIGN_X     = :center<br />
  CHOICE_ALIGN_X   = :center<br />
  CHOICE_TOP_Y     = 76<br />
  CHOICE_MARGIN_Y  = 16<br />
  CHOICE_ROW_MAX   = 6<br />
  MAIN_CHOICE_FILE = "box280"<br />
  SUB_CHOICE_FILE  = "box240"<br />
  CHOICE_CURSOR    = "cursor_shield"<br />
  MAIN_TITLE       = "Tutorial Menu"<br />
  MAIN_CHOICES     = ["Combat", "Controls", "Concepts"]<br />
  FACE_FILENAME    = "Actor1"<br />
  FACE_INDEX       = 0<br />
  WINDOW_BACKDROP  = 0 # 0, 1 or 2 only!<br />
  WINDOW_POSITION  = 2 # 0, 1 or 2 only!<br />
  WINDOW_BACK_OP   = 255<br />
  WINDOW_CONFIG = [FACE_FILENAME, FACE_INDEX, WINDOW_BACKDROP, WINDOW_POSITION]<br />
# - Message Window's Contents - #<br />
  INTRO_TEXTS = ["Welcome to the Great Hero's Tutorial!",<br />
                 "I'm your valorous host &#92;c[2]&#92;n[1]&#92;c[0].",<br />
                 "Nice to meet you!&#92;i[12]"]<br />
# - The Don't Touch These Lines Section - #<br />
  MAIN_CHO_COLS  = 1<br />
  SUB_CAT1       = {}<br />
  SUB_CAT2       = {}<br />
  SUB_CAT1_TEXTS = {}<br />
  SUB_CAT2_TEXTS = {}<br />
  SUB_CAT1.default       = []<br />
  SUB_CAT2.default       = []<br />
  SUB_CAT1_TEXTS.default = {}<br />
  SUB_CAT2_TEXTS.default = {}<br />
# - End of Section - #<br />
  SUB_CAT1["Combat"]   = ["Allies", "Enemies", "FF Menu", "Section 4",<br />
                          "Section 5", "Section 6", "Section 7"]<br />
  SUB_CAT1["Controls"] = ["Decision", "Cancel"]<br />
  SUB_CAT1["Concepts"] = ["Concepts 1", "Concepts 2", "Concepts 3"]<br />
  SUB_CAT1_TEXTS["Allies"] = {<br />
  :se =&gt; {},<br />
  :pic =&gt; {},<br />
  :text =&gt; [<br />
    "Most of the time your allies will be very useless.",<br />
    "Just keep them alive to avoid making very large",<br />
    "donations to your local priest to heal those",<br />
    "reckless companions after every single battle."<br />
  ] }<br />
  SUB_CAT1_TEXTS["Enemies"] = {<br />
  :se =&gt; { 1 =&gt; "Battle1", 2 =&gt; "Battle2" },<br />
  :pic =&gt; { 1 =&gt; "Mimic", 2 =&gt; "Assassin" },<br />
  :text =&gt; [<br />
    "You're not given a chance to think twice.",<br />
    "All mobs definitely hate you.",<br />
    "They'll sweep the floor with your death body",<br />
    "while laughing maniacally.",<br />
    "Please don't challenge them unless you know",<br />
    "very well what you're doing.&#92;|",<br />
    "You've been warned!",<br />
    ""<br />
  ] }<br />
  SUB_CAT1_TEXTS["FF Menu"] = {<br />
  :se =&gt; {},<br />
  :pic =&gt; { 1 =&gt; "FF9_MenuBar old" },<br />
  :text =&gt; [<br />
    "This tutorial uses an old fashioned FF9 menubar.",<br />
    "We don't know when it will be replaced by a",<br />
    "new one. The game developer has refused to",<br />
    "address the issue on social media."<br />
  ] }<br />
  SUB_CAT2["Concepts 1"] = ["Concept 1", "Concept 2", "Concept 3"]<br />
  SUB_CAT2_TEXTS["Concept 1"] = {<br />
  :se =&gt; {},<br />
  :pic =&gt; {},<br />
  :text =&gt; [<br />
    "You've chosen the Proof of Concept #1!&#92;|",<br />
    "Hurray..."<br />
  ] }<br />
<br />
class TextBox<br />
  def initialize(pos, total, vp=nil)<br />
    @index = pos<br />
    @max = total<br />
    @row_max = CHOICE_ROW_MAX<br />
    @col_max = (@max / @row_max) + 1<br />
    @viewport = vp<br />
    @backdrop = Sprite.new(vp)<br />
    @label = Sprite.new(vp)<br />
    @label.z = 50<br />
  end<br />
<br />
  def set_image(filename)<br />
    @filename = filename<br />
    set_bitmap<br />
    set_text_bitmap<br />
    reset_alignment<br />
  end<br />
<br />
  def set_bitmap<br />
    bitmap = Cache.picture(@filename)<br />
    @width = bitmap.width<br />
    @height = bitmap.height<br />
    @rect = bitmap.rect<br />
    @col_width = Graphics.width<br />
    @center_x = (@col_width - @width) / 2<br />
    @backdrop.bitmap = bitmap<br />
  end<br />
<br />
  def set_align_x<br />
    case TEXT_ALIGN_X<br />
    when :left<br />
      0<br />
    when :center<br />
      1<br />
    when :right<br />
      2<br />
    else<br />
      TEXT_ALIGN_X<br />
    end<br />
  end<br />
<br />
  def set_text_bitmap<br />
    @align_x = set_align_x<br />
    @label.bitmap = Bitmap.new(@width, @height)<br />
  end<br />
<br />
  def set_title_xy<br />
    @backdrop.x = @center_x<br />
    @backdrop.y = 8<br />
  end<br />
<br />
  def set_align_xy<br />
    h = @height + CHOICE_MARGIN_Y<br />
    if @max &lt; @row_max<br />
      @backdrop.x = @center_x<br />
      @backdrop.y = CHOICE_TOP_Y + @index * h<br />
    else<br />
      n = @index % @col_max<br />
      cw = @col_width / 2<br />
      @backdrop.x = n * cw + (cw - @width) / 2<br />
      @backdrop.y = CHOICE_TOP_Y + @index / @col_max * h<br />
    end<br />
  end<br />
<br />
  def reset_alignment<br />
    @index ? set_align_xy : set_title_xy<br />
    @label.x = @backdrop.x<br />
    @label.y = @backdrop.y<br />
  end<br />
<br />
  def x<br />
    @backdrop.x<br />
  end<br />
<br />
  def y<br />
    @backdrop.y<br />
  end<br />
<br />
  def set_text(text)<br />
    @text = text<br />
    bit = @label.bitmap<br />
    bit.clear<br />
    bit.draw_text(@rect, text, @align_x)<br />
  end<br />
<br />
  def dispose<br />
    @label.bitmap.dispose<br />
    @label.dispose<br />
    @backdrop.bitmap.dispose<br />
    @backdrop.dispose<br />
  end<br />
  attr_reader :height, :text<br />
end<br />
<br />
class MessageWindow &lt; Window_Message<br />
  def initialize<br />
    super<br />
    self.opacity = @background == 0 ? 255 : 0<br />
    self.back_opacity = WINDOW_BACK_OP<br />
  end<br />
<br />
  def reset_window<br />
    @background = &#36;game_message.background<br />
    @position = &#36;game_message.position<br />
    self.opacity = @background == 0 ? 255 : 0<br />
    self.back_opacity = WINDOW_BACK_OP<br />
    case @position<br />
    when 0  # Top<br />
      self.y = 0<br />
      @gold_window.y = 360<br />
    when 1  # Middle<br />
      self.y = 144<br />
      @gold_window.y = 0<br />
    when 2  # Bottom<br />
      self.y = 288<br />
      @gold_window.y = 0<br />
    end<br />
  end<br />
<br />
  def new_page?<br />
    @text and !@text.empty? and @line_count &gt;= MAX_LINE<br />
  end<br />
<br />
  def input_pause<br />
    if Input.trigger?(Input::B) or Input.trigger?(Input::C)<br />
      &#36;game_message.new_page = new_page?<br />
    end<br />
    super<br />
  end<br />
<br />
  def open_message<br />
    start_message<br />
    open<br />
    self.visible = true<br />
  end<br />
<br />
  def clear_contents<br />
    self.pause = false<br />
    self.index = -1<br />
    @gold_window.close<br />
    @number_input_window.active = false<br />
    @number_input_window.visible = false<br />
  end<br />
end<br />
<br />
class Spriteset<br />
  def initialize<br />
    create_variables<br />
    create_backdrop<br />
    create_viewports<br />
    create_title<br />
    create_picture<br />
    create_main_choices<br />
    create_cursors<br />
    update_box(0)<br />
    @sprites = @cursors + [@backdrop, @picture]<br />
  end<br />
<br />
  def create_variables<br />
    @index = 0<br />
    @section_index = 0<br />
    @subsection_index = 0<br />
    @sound = RPG::SE.new<br />
    @cursors = []<br />
    @sections = []<br />
    @subsections = []<br />
    @main_boxes = []<br />
    @section_boxes = []<br />
    @subsection_boxes = []<br />
    @section_viewports = []<br />
    @subsection_viewports = []<br />
  end<br />
<br />
  def create_backdrop<br />
    @backdrop = Sprite.new<br />
    @backdrop.bitmap = Cache.system(BACKDROP)<br />
  end<br />
<br />
  def create_viewports<br />
    @viewport_rect = [0, 0, Graphics.width, Graphics.height]<br />
    @main_viewport = Viewport.new(*@viewport_rect)<br />
    @picture_viewport = Viewport.new(*@viewport_rect)<br />
    @picture_viewport.z = 1000<br />
  end<br />
<br />
  def create_title<br />
    @title = TextBox.new(nil, 0, nil)<br />
    @title.set_image(TITLE_FILENAME)<br />
    @title.set_text(MAIN_TITLE)<br />
  end<br />
<br />
  def create_picture<br />
    @picture = Sprite.new(@picture_viewport)<br />
    @picture.y = 48<br />
    @picture.visible = false<br />
    @picture.bitmap = Bitmap.new(Graphics.width, Graphics.height - 96)<br />
  end<br />
<br />
  def create_main_choices<br />
    filename = MAIN_CHOICE_FILE<br />
    total = MAIN_CHOICES.size<br />
    MAIN_CHOICES.each_with_index do |choice, n|<br />
      box = TextBox.new(n, total, @main_viewport)<br />
      box.set_image(filename)<br />
      box.set_text(choice)<br />
      @main_boxes &lt;&lt; box<br />
    end<br />
    @item_max = @main_boxes.size<br />
  end<br />
<br />
  def create_cursors<br />
    box = @main_boxes[@index]<br />
    @main_cursor = Sprite.new(@main_viewport)<br />
    @main_cursor.z = 100<br />
    @main_cursor.bitmap = Cache.system(CHOICE_CURSOR)<br />
    @main_cursor.x = box.x + 4<br />
    @offset_y = (box.height - @main_cursor.bitmap.height) / 2<br />
    @main_cursor.y = box.y + @offset_y<br />
    @section_cursor = Sprite.new<br />
    @section_cursor.visible = false<br />
    @section_cursor.z = 100<br />
    @section_cursor.bitmap = Cache.system(CHOICE_CURSOR)<br />
    @subsection_cursor = Sprite.new<br />
    @subsection_cursor.visible = false<br />
    @subsection_cursor.z = 100<br />
    @subsection_cursor.bitmap = Cache.system(CHOICE_CURSOR)<br />
    @cursors &lt;&lt; @main_cursor &lt;&lt; @section_cursor &lt;&lt; @subsection_cursor<br />
  end<br />
<br />
  def update_main<br />
    if Input.trigger?(Input::UP)<br />
      Sound.play_cursor<br />
      update_box(-1)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      Sound.play_cursor<br />
      update_box(1)<br />
    end<br />
  end<br />
<br />
  def update_box(n)<br />
    @index = (@index + n) % @item_max<br />
    box = @main_boxes[@index]<br />
    @section_title = box.text<br />
    @main_cursor.x = box.x + 4<br />
    @main_cursor.y = box.y + @offset_y<br />
  end<br />
<br />
  def show_main<br />
    @title.set_text(MAIN_TITLE)<br />
    @main_viewport.visible = true<br />
  end<br />
<br />
  def hide_main<br />
    @main_viewport.visible = false<br />
  end<br />
<br />
  def find_section_viewport<br />
    @section_viewports[@index] ||= Viewport.new(*@viewport_rect)<br />
  end<br />
<br />
  def find_subsections<br />
    @sections[@index] ||= SUB_CAT1[@section_title].dup<br />
  end<br />
<br />
  def find_section_boxes<br />
    @section_boxes[@index] ||= []<br />
  end<br />
<br />
  def setup_section<br />
    @section_viewport = find_section_viewport<br />
    @section_list = find_subsections<br />
    @current_boxes = find_section_boxes<br />
    create_section if @current_boxes.empty?<br />
    reset_section<br />
    update_section_box(0)<br />
    @title.set_text(@section_title)<br />
    @section_viewport.visible = true<br />
  end<br />
<br />
  def create_section<br />
    return if @section_list.empty?<br />
    filename = SUB_CHOICE_FILE<br />
    total = @section_list.size<br />
    @section_list.each_with_index do |choice, n|<br />
      box = TextBox.new(n, total, @section_viewport)<br />
      box.set_image(filename)<br />
      box.set_text(choice)<br />
      @current_boxes &lt;&lt; box<br />
    end<br />
  end<br />
<br />
  def reset_section<br />
    @section_max = @current_boxes.size<br />
    @col_max = (@section_max / CHOICE_ROW_MAX) + 1<br />
    @section_index = 0<br />
    box = @current_boxes[@section_index]<br />
    @section_oy1 = (box.height - @section_cursor.bitmap.height) / 2<br />
    @section_cursor.visible = box ? true : false<br />
  end<br />
<br />
  def show_section<br />
    @title.set_text(@section_title)<br />
    @section_viewport.visible = true<br />
    @section_cursor.visible = true<br />
  end<br />
<br />
  def hide_section(clear)<br />
    @section_cursor.visible = false<br />
    @section_viewport.visible = false<br />
    return unless clear<br />
    @section_viewport = @current_boxes = nil<br />
    @section_index = 0<br />
  end<br />
<br />
  def update_section<br />
    if Input.trigger?(Input::UP)<br />
      Sound.play_cursor<br />
      update_section_box(-@col_max)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      Sound.play_cursor<br />
      update_section_box(@col_max)<br />
      return<br />
    end<br />
    return if @col_max == 1<br />
    if Input.trigger?(Input::LEFT)<br />
      Sound.play_cursor<br />
      update_section_box(-1)<br />
      return<br />
    elsif Input.trigger?(Input::RIGHT)<br />
      Sound.play_cursor<br />
      update_section_box(1)<br />
    end<br />
  end<br />
<br />
  def update_section_box(n)<br />
    @section_index = (@section_index + n) % @section_max<br />
    box = @current_boxes[@section_index]<br />
    @subsection_title1 = box.text<br />
    @section_cursor.x = box.x + 4<br />
    @section_cursor.y = box.y + @section_oy1<br />
  end<br />
<br />
  def set_pictures(pictures)<br />
    @page_index = 1<br />
    @pictures = pictures<br />
    show_picture<br />
  end<br />
<br />
  def show_picture<br />
    picture = @pictures[@page_index]<br />
    return unless picture<br />
    @picture.bitmap.dispose<br />
    @picture.bitmap = bit = Cache.picture(picture)<br />
    @picture.x = (Graphics.width - bit.width) / 2<br />
    @picture.y = (Graphics.height - bit.height - 128) / 2<br />
    @picture.visible = true<br />
  end<br />
<br />
  def set_sfx(sfx)<br />
    @sfx = sfx<br />
    play_sound<br />
  end<br />
<br />
  def play_sound<br />
    @sound.name = @sfx[@page_index] || ""<br />
    @sound.play<br />
  end<br />
<br />
  def find_subsection_viewport<br />
    @subsection_viewports[@section_index] ||= Viewport.new(*@viewport_rect)<br />
  end<br />
<br />
  def find_subsections_lvl2<br />
    @subsections[@section_index] ||= SUB_CAT2[@subsection_title1].dup<br />
  end<br />
<br />
  def find_subsection_boxes<br />
    @subsection_boxes[@section_index] ||= []<br />
  end<br />
<br />
  def setup_subsection<br />
    @subsection_viewport = find_subsection_viewport<br />
    @subsection_list = find_subsections_lvl2<br />
    @current_subboxes = find_subsection_boxes<br />
    create_subsection if @current_subboxes.empty?<br />
    reset_subsection<br />
    update_subsection_box(0)<br />
    box = @current_subboxes[@subsection_index]<br />
    @subsection_title2 = box ? box.text : ""<br />
    @title.set_text(@subsection_title1)<br />
    @subsection_viewport.visible = true<br />
  end<br />
<br />
  def create_subsection<br />
    return if @subsection_list.empty?<br />
    filename = SUB_CHOICE_FILE<br />
    total = @subsection_list.size<br />
    @subsection_list.each_with_index do |choice, n|<br />
      box = TextBox.new(n, total, @subsection_viewport)<br />
      box.set_image(filename)<br />
      box.set_text(choice)<br />
      @current_subboxes &lt;&lt; box<br />
    end<br />
  end<br />
<br />
  def reset_subsection<br />
    @subsection_max = @current_subboxes.size<br />
    @subcol_max = (@subsection_max / CHOICE_ROW_MAX) + 1<br />
    @subsection_index = 0<br />
    box = @current_subboxes[@subsection_index]<br />
    @section_oy2 = (box.height - @subsection_cursor.bitmap.height) / 2<br />
    @subsection_cursor.visible = box ? true : false<br />
  end<br />
<br />
  def hide_subsection<br />
    @subsection_cursor.visible = false<br />
    @subsection_viewport.visible = false<br />
    @subsection_viewport = @current_subboxes = nil<br />
    @subsection_index = 0<br />
  end<br />
<br />
  def update_subsection<br />
    if Input.trigger?(Input::UP)<br />
      Sound.play_cursor<br />
      update_subsection_box(-@subcol_max)<br />
      return<br />
    elsif Input.trigger?(Input::DOWN)<br />
      Sound.play_cursor<br />
      update_subsection_box(@subcol_max)<br />
      return<br />
    end<br />
    return if @subcol_max == 1<br />
    if Input.trigger?(Input::LEFT)<br />
      Sound.play_cursor<br />
      update_subsection_box(-1)<br />
      return<br />
    elsif Input.trigger?(Input::RIGHT)<br />
      Sound.play_cursor<br />
      update_subsection_box(1)<br />
    end<br />
  end<br />
<br />
  def update_subsection_box(n)<br />
    @subsection_index = (@subsection_index + n) % @subsection_max<br />
    box = @current_subboxes[@subsection_index]<br />
    @subsection_title2 = box.text<br />
    @subsection_cursor.x = box.x + 4<br />
    @subsection_cursor.y = box.y + @section_oy2<br />
  end<br />
<br />
  def hide_picture<br />
    @picture.bitmap.dispose<br />
    @picture.bitmap = Bitmap.new(Graphics.width, Graphics.height - 96)<br />
    @picture.visible = false<br />
  end<br />
<br />
  def update_extras<br />
    return unless &#36;game_message.new_page<br />
    &#36;game_message.new_page = nil<br />
    @page_index += 1<br />
    show_picture<br />
    play_sound<br />
  end<br />
<br />
  def dispose<br />
    @sprites.each do |sprite|<br />
      sprite.bitmap.dispose<br />
      sprite.dispose<br />
    end<br />
    @subsection_boxes.each do |boxes|<br />
      next unless boxes<br />
      boxes.each {|box| box.dispose }<br />
    end<br />
    @section_boxes.each do |boxes|<br />
      next unless boxes<br />
      boxes.each {|box| box.dispose }<br />
    end<br />
    @main_boxes.each {|box| box.dispose }<br />
    @title.dispose<br />
    @section_viewports.each {|vp| vp.dispose if vp }<br />
    @picture_viewport.dispose<br />
    @main_viewport.dispose<br />
    @section_boxes.clear<br />
    @main_boxes.clear<br />
    @section_viewports.clear<br />
  end<br />
  attr_reader :subsection_title1, :subsection_title2<br />
end<br />
<br />
class Scene<br />
  def initialize(index=nil)<br />
    @main_menu_index = index<br />
    @map_bgm = RPG::BGM.last<br />
    @bgm = RPG::BGM.new<br />
    return if TUTORIAL_BGM.empty?<br />
    @bgm.name = TUTORIAL_BGM<br />
    @bgm.play<br />
  end<br />
<br />
  def main<br />
    start<br />
    Graphics.transition<br />
    update_basic while @stage<br />
    Graphics.freeze<br />
    terminate<br />
  end<br />
<br />
  def start<br />
    @stage = :message<br />
    @next_stage = :main<br />
    @spriteset = Spriteset.new<br />
    @message_window = MessageWindow.new<br />
    &#36;game_message.setup_message(*WINDOW_CONFIG)<br />
    &#36;game_message.set_tutorial_texts(INTRO_TEXTS)<br />
  end<br />
<br />
  def update_basic<br />
    Graphics.update<br />
    Input.update<br />
    update<br />
  end<br />
<br />
  def close_message<br />
    &#36;game_message.texts.clear<br />
    @message_window.clear_contents<br />
    @message_window.visible = false<br />
    @spriteset.hide_picture<br />
    @stage = @next_stage<br />
  end<br />
<br />
  def update<br />
    case @stage<br />
    when :message<br />
      update_message<br />
    when :main<br />
      update_main<br />
    when :section<br />
      update_section<br />
    when :subsection<br />
      update_subsection<br />
    end<br />
  end<br />
<br />
  def update_message<br />
    @message_window.update<br />
    while &#36;game_message.visible<br />
      Graphics.update<br />
      Input.update<br />
      @message_window.update<br />
      @spriteset.update_extras<br />
    end<br />
    close_message<br />
  end<br />
<br />
  def update_main<br />
    @spriteset.update_main<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      if @main_menu_index<br />
        &#36;scene = Scene_Menu.new(@main_menu_index)<br />
      else<br />
        &#36;scene = Scene_Map.new<br />
      end<br />
      return @stage = nil<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      @spriteset.hide_main<br />
      @spriteset.setup_section<br />
      @stage = :section<br />
    end<br />
  end<br />
<br />
  def update_section<br />
    @spriteset.update_section<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      @spriteset.hide_section(true)<br />
      @spriteset.show_main<br />
      return @stage = :main<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      key = @spriteset.subsection_title1<br />
      if SUB_CAT2[key].any?<br />
        show_subsection<br />
      else<br />
        show_section_message(key)<br />
      end<br />
    end<br />
  end<br />
<br />
  def show_subsection<br />
    @spriteset.hide_section(nil)<br />
    @spriteset.setup_subsection<br />
    @stage = :subsection<br />
  end<br />
<br />
  def show_section_message(key)<br />
    data = SUB_CAT1_TEXTS[key].dup<br />
    return if data.empty?<br />
    pictures = data[:pic]<br />
    message = data[:text]<br />
    sfx = data[:se]<br />
    &#36;game_message.setup_message(*WINDOW_CONFIG)<br />
    &#36;game_message.set_tutorial_texts(message)<br />
    @message_window.open_message<br />
    @spriteset.set_pictures(pictures)<br />
    @spriteset.set_sfx(sfx)<br />
    @next_stage = :section<br />
    @stage = :message<br />
  end<br />
<br />
  def update_subsection<br />
    @spriteset.update_subsection<br />
    if Input.trigger?(Input::B)<br />
      Sound.play_cancel<br />
      @spriteset.hide_subsection<br />
      @spriteset.show_section<br />
      return @stage = :section<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      key = @spriteset.subsection_title2<br />
      data = SUB_CAT2_TEXTS[key]<br />
      return if data.empty?<br />
      message = data[:text]<br />
      pictures = data[:pic]<br />
      sfx = data[:se]<br />
      &#36;game_message.setup_message(*WINDOW_CONFIG)<br />
      &#36;game_message.set_tutorial_texts(message)<br />
      @message_window.open_message<br />
      @spriteset.set_pictures(pictures)<br />
      @spriteset.set_sfx(sfx)<br />
      @next_stage = :subsection<br />
      @stage = :message<br />
    end<br />
  end<br />
<br />
  def terminate<br />
    @message_window.dispose<br />
    @spriteset.dispose<br />
    &#36;game_message.custom_scene = nil<br />
    &#36;game_message.clear<br />
    return if TUTORIAL_BGM.empty?<br />
    if &#36;game_map.autoplay_bgm?<br />
      &#36;game_map.autoplay<br />
    elsif @map_bgm<br />
      @map_bgm.play<br />
    end<br />
  end<br />
end<br />
<br />
end<br />
<br />
class Game_Message<br />
  def setup_message(*options)<br />
    options = options.dup<br />
    @face_name = options.shift<br />
    @face_index = options.shift<br />
    @background = options.shift<br />
    @position = options.shift<br />
    @custom_scene = true<br />
  end<br />
<br />
  def set_tutorial_texts(original_texts)<br />
    @texts = original_texts.dup<br />
    @texts.each do |line|<br />
      line.gsub!("&#92;e", "&#92;&#92;c[")<br />
      line.gsub!(/(.)&#92;^/) { "#{&#36;1}&#92;&#92;^" }<br />
      line.gsub!(/([^&#92;&#92;])&#92;|/) { "#{&#36;1}&#92;&#92;|" }<br />
      line.gsub!(/(&#92;-|,|;|:|!)&#92;./) { "#{&#36;1}&#92;&#92;." }<br />
      line.gsub!(/[&#92;b]/i, "&#92;&#92;b")<br />
      line.gsub!(/([^&#92;&#92;])i&#92;[([0-9]+)&#92;]/i) { "#{&#36;1}&#92;&#92;i[#{&#36;2}]" }<br />
      line.gsub!(/&#92;n&#92;[([0-9]+)&#92;]/i) { "&#92;&#92;n[#{&#36;1}]" }<br />
    end<br />
    @visible = true<br />
  end<br />
  attr_accessor :new_page, :custom_scene<br />
end<br />
<br />
class Game_Map<br />
  def autoplay_bgm?<br />
    @map.autoplay_bgm<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer for non-commercial games. <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /><br />
Include my nickname in your game credits.<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[FPLE ACE Addon/Enhancement.]]></title>
			<link>https://www.save-point.org/thread-12834.html</link>
			<pubDate>Thu, 11 Sep 2025 16:42:22 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=9095">5Brainplay</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-12834.html</guid>
			<description><![CDATA[@A.I. Topical Post. Tag.<br />
<br />
I upgraded FPLE Ace Using Claude.AI, Integrated a 4-Side &amp; 6-Side box comment, which can create buildings/grass boxes/objects.<br />
6 Side had type2+d1 &amp; type1+d1)) but changed it to a type 0 to save FPS, you can add it back if you want.<br />
<br />
For below/Above, type 0 objects you want to walk over add, 1-Side, to them.<br />
I added code the following code so these player facing objects without 1-Side push forward, for NPCs.<br />
if dy == 0 &amp;&amp; dx == 0 &amp;&amp; surface.character.fple_type == 0 &amp;&amp; surface.character.fple_one_side == false.<br />
<br />
(Fit,Type1,D1,1Side,V2) objects have a side profile added to them, but should always be, same not below/above.<br />
you can jump over these with a moveset thuf-on/step forward step forward thur-off, they are a type of ledge.<br />
<br />
You may have to code in your own.  (Fit,Type2,D1,1Side,V2), I'm not currently tested to check its same function.<br />
<br />
I've worked out a fix for rotation letting you see events thur walls briefly, here is the 1st rough draft of the script.<br />
I would have posted a few days sooner, but was having issues with strafing crashing the game for some reason.<br />
<br />
The resolution is also no longer Default, it's 608x417, you can place it back with the original script, or pick Res 2.<br />
<br />
The Enhanced Script requires Background Addon to function properly, I've not worked out the private call issue.<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#========================Author: MGC=============================<br />
# First Person Labyrinth Explorer (FPLE) Engine - VX Ace version.<br />
# v.1.5 old, now upgraded to v.1.8 using Claude.AI by 5Brainplay.<br />
#================================================================<br />
# This script allows the map to be displayed in first-person view,<br />
# while maintaining tile-by-tile movement, similar to the<br />
# Etrian Odyssey series (Nintendo DS/3DS). # THIS IS NOT A SCRIPT FOR MAKING AN FPS, BUT AN FPRPG.<br />
#<br />
# This is a port of version 1.5 of the FPLE for RPG Maker XP, with<br />
# a few small additions.<br />
#<br />
# Features:<br />
# - Can only be enabled on certain maps in the project<br />
# - Forward/backward movement, left/right movement<br />
# and 90° rotation<br />
# - Ability to lower quality while moving to reduce lag<br />
# - Translucency and blend type support<br />
# for events<br />
#<br />
# Limitations:<br />
# - Not really suitable for moving events from one tile to another.<br />
# This should work, but use sparingly. # - Animations are displayed above everything<br />
# - The player cannot jump or move diagonally<br />
# - The resolution must be the default, i.e., 544px x 416px<br />
# - No transparency for walls<br />
# - No different heights: a single level for the floor and ceiling<br />
#<br />
# Instructions:<br />
# This script must be placed below the original scripts but above "Main"<br />
# It requires the MGC_FPLE_Ace_1_1.dll file<br />
#<br />
# - Map Creation<br />
# Maps must be exported into the project from the dedicated editor,<br />
# present in the Marta project starting with version 1.0.0<br />
#<br />
# - Events<br />
# Events with a graphical representation are displayed<br />
# vertically (like walls), centered, and always facing the<br />
# player. The "Comment..." command allows you to control this display:<br />
# "Type 0": Always faces the player (default)<br />
# "Type 1": Horizontally oriented in the RM editor view (top view)<br />
# "Type 2": Vertically oriented in the RM editor view (top view)<br />
# "Stretch": The image is stretched to the dimensions of a wall (square)<br />
# "Fit": The image is stretched to fit within the dimensions of a wall, the<br />
# aspect ratio is maintained. Automatically applied if<br />
# the dimensions exceed those of a wall (new in VX Ace)<br />
# "Zoom X.X": zoom the image (new in VX Ace), for example, to double<br />
# the dimensions, write: "Zoom 2.0"<br />
# "V-Align 0": vertical alignment at the top (at ceiling level)<br />
# "V-Align 1": vertical alignment in the center (default)<br />
# "V-Align 2": vertical alignment at the bottom (at floor level)<br />
# "D-Align 0": depth alignment in front/left, for types 1 and 2<br />
# "D-Align 1": depth alignment in the center, for types 1 and 2 (default)<br />
# "D-Align 2": depth alignment in the back/right, for types 1 and 2<br />
# "1-Side": texture applied to one side only =&gt; appears mirrored behind<br />
# "2-Side": texture applied to two side only =&gt; appears mirrored behind #Extra Unused Call To Code#<br />
# "4-Side": texture applied to four sides to create the illusion of box<br />
# "6-Side":  texture applied to four sides to create the illusion of grass.<br />
# - Technical Parameters<br />
# In the CONFIGURATION section at the beginning of the script, you will find the<br />
# following constants whose values can be modified:<br />
# - VIEW_DISTANCE: "Surfaces" (textured square polygons of fixed<br />
# dimensions representing tiles and events) are only<br />
# displayed within a certain distance around<br />
# the player. This constant represents this distance,<br />
# expressed in tiles (default value: 6). The higher<br />
# this value, the greater the risk of lag.<br />
# - RESOLUTION: Drawing the entire screen every frame requires<br />
# a lot of resources. During movement, it is<br />
# possible to use a lower screen resolution and the<br />
# Render will then be zoomed to fit 544px x 416px.<br />
# 0: Maximum resolution (544px*416px) Changed to (840px*560px)<br />
# 1: Medium resolution (408px*312px)  Changed to (608px*417px)<br />
# 2: Low resolution (272px*208px) Changed to (544px*417px)<br />
# 3: Minimum resolution (204px*156px) Changed to (408px*278px)<br />
# 4: Test resolution (204px*156px) Changed to (332px*222px)<br />
# - ALWAYS_SAME_RES: If true, the same resolution will be used when stationary<br />
# as when moving (see RESOLUTION)<br />
# If false, the maximum resolution will be used when stationary<br />
# (default value)<br />
# - LIGHT_DISTANCE: To prevent surfaces from suddenly appearing on the screen,<br />
# this constant represents the distance in tiles beyond<br />
# which the opacity of the surfaces will be zero.<br />
# The opacity change is gradual. If there is<br />
# no parallax, the screen background is black and the<br />
# surfaces will become increasingly darker with distance.<br />
# A value of 0 disables this feature.<br />
#<br />
# - Commands that can be used in scripts (possible via the "Script..."<br />
# command of an event):<br />
# - &#36;game_temp.set_view(new_view_distance)<br />
# - &#36;game_temp.set_light(new_light_distance)<br />
# - &#36;game_temp.increase_light<br />
# - &#36;game_temp.decrease_light<br />
#============================<br />
module FPLE<br />
  #-----------------------------<br />
  # * CONFIGURATION<br />
  #-----------------------------<br />
  VIEW_DISTANCE = 22 # in tiles, &gt; 0<br />
  LIGHT_DISTANCE = 11 # in tiles, &gt;=0, 0=deactivated<br />
  RESOLUTION = 1 # quality when moving, 0=max, 1=medium, 2=low, 3=ugly<br />
  ALWAYS_SAME_RES = true # if true, quality at stand = quality when moving<br />
                          # if false, quality at stand = quality max<br />
  SKIP_DISTANT_CHARS = true  # Skip character updates beyond view distance<br />
  BATCH_SURFACE_UPDATES = true  # Update surfaces in batches<br />
  AGGRESSIVE_CULLING = true     # More aggressive visibility culling<br />
end<br />
#==============================<br />
# ** FPLE Core<br />
#==============================<br />
module FPLE<br />
  #-----------------------------<br />
  # * Constantes<br />
  #-----------------------------<br />
  MAP_SIDES = [4, 3, 5, 2]<br />
  MAP_SIDES_LEFT = [5, 4, 2, 3]<br />
  MAP_SIDES_RIGHT = [3, 2, 4, 5]<br />
  PLAYER_MOVE_FORWARD = [[0, 1], [-1, 0], [1, 0], [0, -1]]<br />
  PLAYER_MOVE_SPEED = [0, 1, 2, 4, 6, 8, 12]<br />
  TURN_LEFT = [6, 2, 8, 4]<br />
  COS_TABLE = [4096, 4095, 4094, 4090, 4086,<br />
  4080, 4074, 4065, 4056, 4046, 4034, 4021, 4006, 3991, 3974,<br />
  3956, 3937, 3917, 3896, 3873, 3849, 3824, 3798, 3770, 3742,<br />
  3712, 3681, 3650, 3617, 3582, 3547, 3511, 3474, 3435, 3396,<br />
  3355, 3314, 3271, 3228, 3183, 3138, 3091, 3044, 2996, 2946,<br />
  2896, 2845, 2793, 2741, 2687, 2633, 2578, 2522, 2465, 2408,<br />
  2349, 2290, 2231, 2171, 2110, 2048, 1986, 1923, 1860, 1796,<br />
  1731, 1666, 1600, 1534, 1468, 1401, 1334, 1266, 1198, 1129,<br />
  1060, 991, 921, 852, 782, 711, 641, 570, 499, 428,<br />
  357, 286, 214, 143, 71, 0]<br />
  RENDER = Win32API.new("MGC_FPLE_Ace_1_2", "RenderFPLE", "lll", "l") # [1.5]<br />
  RENDER_ROT = Win32API.new("MGC_FPLE_Ace_1_2", "RenderFPLErot", "lll", "l") # [1.5]<br />
  #-----------------------------<br />
  # * Retourne l'angle d'orientation<br />
  # return Integer<br />
  #-----------------------------<br />
  def self.angle<br />
    return @angle<br />
  end<br />
  #-----------------------------<br />
  # * Retourne le décalage horizontal<br />
  # return Integer<br />
  #-----------------------------<br />
  def self.offset_x<br />
    return @offset_x<br />
  end<br />
  #-----------------------------<br />
  # * Retourne le décalage en profondeur<br />
  # return Integer<br />
  #-----------------------------<br />
  def self.offset_y<br />
    return @offset_y<br />
  end<br />
  #-----------------------------<br />
  # * Initialisation<br />
  # param spriteset : FPLE::Spriteset_Map<br />
  # param viewport : Viewport<br />
  #-----------------------------<br />
  def self.initialize_fple(spriteset, viewport)<br />
    @spriteset = spriteset<br />
    @sprite_screen = Sprite.new(viewport)<br />
    @sprite_move = Sprite.new(viewport)<br />
    self.initialize_bitmaps<br />
    @offset_x = 0<br />
    @offset_y = 0<br />
    @sprite_move.visible = false<br />
    @lux_distance = &#36;game_system.fple_light_distance &lt;&lt; 5<br />
    @angle = 0<br />
    @trig = 0<br />
    self.refresh_trig<br />
    @count = 0<br />
    &#36;game_temp.force_render = true<br />
    self.update<br />
  end<br />
  #-----------------------------<br />
  # * Création des objets Bitmap devant contenir le rendu 3D<br />
  #-----------------------------<br />
  def self.initialize_bitmaps<br />
    case &#36;game_system.fple_resolution<br />
    when 0<br />
      width = 840<br />
      height = 560<br />
      coefficient_resolution = 0.75<br />
    when 1<br />
      width = 608<br />
      height = 417<br />
      coefficient_resolution = 1<br />
    when 2<br />
      width = 544<br />
      height = 417<br />
      coefficient_resolution = 1.133<br />
    when 3<br />
      width = 408<br />
      height = 278<br />
      coefficient_resolution = 1.5<br />
    when 4<br />
      width = 332<br />
      height = 222<br />
      coefficient_resolution = 2<br />
    end<br />
    if &#36;game_system.fple_always_same_res<br />
      @sprite_screen.bitmap = Bitmap.new(width, height)<br />
      @sprite_screen.zoom_x = coefficient_resolution<br />
      @sprite_screen.zoom_y = coefficient_resolution<br />
    else<br />
      @sprite_screen.bitmap = Bitmap.new(608, 417)<br />
    end<br />
    @sprite_move.bitmap = Bitmap.new(width, height)<br />
    @sprite_move.zoom_x = coefficient_resolution<br />
    @sprite_move.zoom_y = coefficient_resolution<br />
  end<br />
  #-----------------------------<br />
  # * Cherche les valeurs de sinus et cosinus en focntion de l'angle<br />
  #-----------------------------<br />
  def self.refresh_trig<br />
    @cos = FPLE::COS_TABLE[@angle]<br />
    @sin = FPLE::COS_TABLE[91 - @angle]<br />
  end<br />
  #-----------------------------<br />
  # * Dispose<br />
  #-----------------------------<br />
  def self.dispose<br />
    @sprite_screen.dispose<br />
    @sprite_move.dispose<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update<br />
  #-----------------------------<br />
<br />
# Modify the update method to use a more complete background fill<br />
def self.update<br />
  # Run garbage collection periodically during non-movement to reduce memory spikes.<br />
  if !&#36;game_temp.movement &amp;&amp; Graphics.frame_count % 120 == 0<br />
    GC.start<br />
  end<br />
<br />
  # Check if the player is actively moving or changing the view.<br />
  if &#36;game_temp.movement<br />
    case &#36;game_temp.movement_dir<br />
    when 0 # fading distance + 1<br />
      self.increase_fading_distance<br />
    when 1 # fading distance - 1<br />
      self.decrease_fading_distance<br />
    when 3 # set fading distance<br />
      self.set_fading_distance<br />
    when 2 # Move backward<br />
      self.move_backward<br />
    when 4 # Strafe left<br />
      self.strafe_left<br />
    when 6 # Strafe right<br />
      self.strafe_right<br />
    when 8 # Move forward<br />
      self.move_forward<br />
    when 9 # Turn right<br />
      self.turn_right<br />
    when 10 # turn left<br />
      self.turn_left<br />
    end<br />
  <br />
    # Apply method 2 refactoring for sprite and rendering logic<br />
    sprite_moving = &#36;game_temp.movement<br />
    active_sprite = sprite_moving ? @sprite_move : @sprite_screen<br />
    inactive_sprite = sprite_moving ? @sprite_screen : @sprite_move<br />
    active_sprite.visible = true<br />
    inactive_sprite.visible = false<br />
   if @angle != 0<br />
      # Use lighter background color during rotation to prevent bleeding<br />
      bg_color = Color.new(115, 190, 215, 255)  # Much lighter sky blue background<br />
      active_sprite.bitmap.fill_rect(0, 0, active_sprite.bitmap.width,<br />
                                     active_sprite.bitmap.height, bg_color)<br />
    end<br />
    # Clear the active sprite bitmap<br />
    active_sprite.bitmap.clear unless &#36;game_temp.movement_dir == 9 || &#36;game_temp.movement_dir == 10 &amp;&amp; &#36;game_player.moving?<br />
    # Determine if we should use rotation (only during movement and when angle != 0)<br />
    use_rotation = sprite_moving &amp;&amp; @angle != 0<br />
    if use_rotation<br />
      params = [@offset_y, @offset_x, @lux_distance, &#36;game_player.direction, @trig, @cos, @sin, &#36;game_map.fple_map.texturesets]<br />
      FPLE::RENDER_ROT.call(active_sprite.bitmap.__id__, &#36;game_map.surfaces.__id__, params.__id__)<br />
    else<br />
      params = [@offset_y, @offset_x, @lux_distance, &#36;game_player.direction, &#36;game_map.fple_map.texturesets]<br />
      FPLE::RENDER.call(active_sprite.bitmap.__id__, &#36;game_map.surfaces.__id__, params.__id__)<br />
    end<br />
    # Handle post-movement logic<br />
    unless sprite_moving<br />
      &#36;game_player.update_nonmoving(&#36;game_temp.last_moving) if &#36;game_temp.last_moving<br />
    end<br />
  # This block handles rendering when the player is not moving, but other<br />
  # events or conditions (like character surfaces) need updating.<br />
  elsif &#36;game_player.moving? || &#36;game_temp.force_render<br />
    # Process updates for characters and events.<br />
    &#36;game_map.refresh_surfaces<br />
  <br />
    # Extract common character update logic to avoid duplication<br />
    update_character = lambda do |event|<br />
      # Only process if SKIP_DISTANT_CHARS is enabled<br />
      return unless FPLE::SKIP_DISTANT_CHARS<br />
    <br />
      dist_x = (&#36;game_player.real_x / 32) - (event.x)<br />
      dist_y = (&#36;game_player.real_y / 32) - (event.y)<br />
      distance = Math.sqrt(dist_x**2 + dist_y**2)<br />
      return if distance &gt; FPLE::VIEW_DISTANCE<br />
    <br />
      event.update_fple_surface<br />
    end<br />
    # === START OF BATCH AND CULLING FIX ===<br />
    # Updates characters in batches to avoid lag spikes, with optional distance skipping.<br />
    if FPLE::BATCH_SURFACE_UPDATES<br />
      &#36;game_map.events.values.each_with_index do |event, i|<br />
        # Only update a fraction of the events each frame.<br />
        if @count % 5 == i % 5<br />
          update_character.call(event)<br />
        end<br />
      end<br />
    else<br />
      # Fallback for no batching.<br />
      &#36;game_map.events.each_value(&amp;update_character)<br />
    end<br />
    # === END OF BATCH AND CULLING FIX ===<br />
  <br />
    &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    @sprite_screen.bitmap.clear<br />
  <br />
    # Use consistent parameter structure<br />
    params = [@offset_y, @offset_x, @lux_distance, &#36;game_player.direction, &#36;game_map.fple_map.texturesets]<br />
    FPLE::RENDER.call(@sprite_screen.bitmap.__id__, &#36;game_map.surfaces.__id__, params.__id__)<br />
  <br />
    &#36;game_temp.force_render = false<br />
    @count += 1<br />
  end<br />
end<br />
  #-----------------------------<br />
  # * Frame Update - Augmentation de la distance d'éclairage<br />
  #-----------------------------<br />
  def self.increase_fading_distance<br />
    @count += 2<br />
    @lux_distance += 2<br />
    if @count == 32<br />
      @count = 0<br />
      &#36;game_temp.movement = false<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Diminution de la distance d'éclairage<br />
  #-----------------------------<br />
  def self.decrease_fading_distance<br />
    if @lux_distance == 0<br />
      @count = 0<br />
      &#36;game_temp.movement = false<br />
    else<br />
      @count += 2<br />
      @lux_distance -= 2<br />
      if @count == 32<br />
        @count = 0<br />
        &#36;game_temp.movement = false<br />
      end<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Définition d'une nouvelle distance d'éclairage<br />
  #-----------------------------<br />
  def self.set_fading_distance<br />
    @lux_distance = &#36;game_system.fple_light_distance &lt;&lt; 5<br />
    &#36;game_temp.movement = false<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Déplacement en arrière<br />
  #-----------------------------<br />
  def self.move_backward<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
      &#36;game_temp.movement_init = true<br />
      @offset_y = 128<br />
    end<br />
    @offset_y -= &#36;game_player.move_speed_fple<br />
    if @offset_y &lt;= 0<br />
      @offset_y = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_temp.last_moving = true<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Déplacement latéral vers la gauche<br />
  #-----------------------------<br />
  def self.strafe_left<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_surfaces_strafe(0)<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
      &#36;game_temp.movement_init = true<br />
      @offset_x = 128<br />
    end<br />
    @offset_x -= &#36;game_player.move_speed_fple<br />
    if @offset_x &lt;= 0<br />
      @offset_x = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_temp.last_moving = true<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Déplacement latéral vers la droite<br />
  #-----------------------------<br />
  def self.strafe_right<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces_strafe(-1)<br />
      &#36;game_temp.movement_init = true<br />
    end<br />
    @offset_x += &#36;game_player.move_speed_fple<br />
    if @offset_x &gt;= 128<br />
      @offset_x = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_temp.last_moving = true<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Déplacement en avant<br />
  #-----------------------------<br />
  def self.move_forward<br />
    @offset_y += &#36;game_player.move_speed_fple<br />
    if @offset_y &gt;= 128<br />
      @offset_y = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_temp.last_moving = true<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Rotation vers la droite<br />
  #-----------------------------<br />
  def self.turn_right<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces_turn_right(@spriteset.character_surfaces)<br />
      &#36;game_temp.movement_init = true<br />
    end<br />
    @angle += 5<br />
    @trig = 1<br />
    refresh_trig<br />
    if @angle == 90<br />
      @angle = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Rotation vers la gauche<br />
  #-----------------------------<br />
  def self.turn_left<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces_turn_left(@spriteset.character_surfaces)<br />
      &#36;game_temp.movement_init = true<br />
      @angle = 90<br />
    end<br />
    @angle -= 5<br />
    @trig = 0<br />
    refresh_trig<br />
    if @angle == 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
end<br />
#==============================<br />
# ** DataManager<br />
#==============================<br />
module DataManager<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  class &lt;&lt; self<br />
    unless @already_aliased_fple<br />
      alias save_game_without_rescue_fple save_game_without_rescue<br />
      @already_aliased_fple = true<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Execute Save (No Exception Processing)<br />
  #-----------------------------<br />
  def self.save_game_without_rescue(index)<br />
    if &#36;game_map.fple_map # [1.2]<br />
      textureset = &#36;game_map.fple_map.textureset<br />
      texturesets = &#36;game_map.fple_map.texturesets<br />
      &#36;game_map.fple_map.textureset = nil<br />
      &#36;game_map.fple_map.texturesets = nil<br />
    end<br />
    rc = save_game_without_rescue_fple(index)<br />
    if &#36;game_map.fple_map # [1.2]<br />
      &#36;game_map.fple_map.texturesets = texturesets<br />
      &#36;game_map.fple_map.textureset = textureset<br />
    end<br />
    return rc<br />
  end<br />
end<br />
#============================<br />
# ** Game_System<br />
#============================<br />
class Game_System<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias initialize_fple initialize<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Public Instance Variables<br />
  #-----------------------------<br />
  attr_accessor :fple # Boolean<br />
  attr_accessor :fple_view_distance # Integer (&gt;0)<br />
  attr_accessor :fple_light_distance # Integer (&gt;=0, 0:deactivated)<br />
  attr_accessor :fple_resolution # Integer (0:max, 1:medium, 2:low, 3:ugly)<br />
  attr_accessor :fple_always_same_res # Boolean<br />
  #-----------------------------<br />
  # * Object Initialization<br />
  #-----------------------------<br />
  def initialize<br />
    initialize_fple<br />
    self.fple = false<br />
    self.fple_view_distance = FPLE::VIEW_DISTANCE<br />
    self.fple_light_distance = FPLE::LIGHT_DISTANCE<br />
    self.fple_resolution = FPLE::RESOLUTION<br />
    self.fple_always_same_res = FPLE::ALWAYS_SAME_RES<br />
  end<br />
end<br />
#==============================<br />
# ** Game_Temp<br />
#==============================<br />
class Game_Temp<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias initialize_fple initialize<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Public Instance Variables<br />
  #-----------------------------<br />
  attr_accessor :movement_init # Boolean<br />
  attr_accessor :movement # Boolean<br />
  attr_accessor :movement_dir # Integer {2, 4, 6, 8}<br />
  attr_accessor :last_moving # Boolean<br />
  attr_accessor :force_render # Boolean<br />
  #-----------------------------<br />
  # * Object Initialization<br />
  #-----------------------------<br />
  def initialize<br />
    initialize_fple<br />
    self.movement_init = false<br />
    self.movement = false<br />
    self.movement_dir = 8<br />
    self.last_moving = false<br />
    self.force_render = false<br />
  end<br />
  #-----------------------------<br />
  # * Set view distance<br />
  # param distance : Integer<br />
  #-----------------------------<br />
  def set_view(distance)<br />
    if distance &lt; 0 then distance = 0 end<br />
    &#36;game_system.fple_view_distance = distance<br />
    self.force_render = true<br />
  end<br />
  #-----------------------------<br />
  # * Set light distance<br />
  # param distance : Integer<br />
  #-----------------------------<br />
  def set_light(distance)<br />
    if distance &lt; 0 then distance = 0 end<br />
    &#36;game_system.fple_light_distance = distance<br />
    self.movement = true<br />
    self.movement_dir = 3<br />
  end<br />
  #-----------------------------<br />
  # * Increase light distance<br />
  #-----------------------------<br />
  def increase_light<br />
    &#36;game_system.fple_light_distance += 1<br />
    self.movement = true<br />
    self.movement_dir = 0<br />
  end<br />
  #-----------------------------<br />
  # * Decrease light distance<br />
  #-----------------------------<br />
  def decrease_light<br />
    if &#36;game_system.fple_light_distance &gt; 0<br />
      &#36;game_system.fple_light_distance -= 1<br />
    end<br />
    self.movement = true<br />
    self.movement_dir = 1<br />
  end<br />
end<br />
#============================<br />
# ** Game_Map<br />
#============================<br />
class Game_Map<br />
public<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias initialize_fple initialize<br />
    alias setup_fple setup<br />
    alias refresh_fple refresh<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Public Instance Variables<br />
  #-----------------------------<br />
  attr_accessor :surfaces # Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  # * Object Initialization<br />
  #-----------------------------<br />
  def initialize<br />
    initialize_fple<br />
    self.surfaces = []<br />
    @x_ref = 0<br />
    @y_ref = 0<br />
    @distance_cache = {}<br />
    @last_player_pos = [0, 0]<br />
  end<br />
  #-----------------------------<br />
  # * Setup<br />
  # param map_id : Integer<br />
  #-----------------------------<br />
  def setup(map_id)<br />
    @map_id = map_id<br />
    @map = load_data(sprintf("Data/Map%03d.rvdata2", @map_id))<br />
    if is_fple?<br />
      load_fple_map<br />
      &#36;game_system.fple = true<br />
    elsif &#36;game_system.fple<br />
      &#36;game_system.fple = false<br />
    end<br />
    setup_fple(map_id)<br />
  end<br />
  #-----------------------------<br />
  # * Refresh<br />
  #-----------------------------<br />
  def refresh<br />
    refresh_fple<br />
    if is_fple?<br />
      unless @fple_map.textureset<br />
        load_fple_map<br />
      end<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Vérifie s'il s'agit d'une carte FPLE<br />
  # return String<br />
  #-----------------------------<br />
  def is_fple?<br />
    return @map.note[/&#92;[fple:&#92;w+&#92;]/]<br />
  end<br />
  #-----------------------------<br />
  # * Charge la carte FPLE associée<br />
  #-----------------------------<br />
  def load_fple_map<br />
    if @fple_map then @fple_map.dispose end<br />
    @map.note[/&#92;[fple:(&#92;w+)&#92;]/]<br />
    File.open('Data_FPLE/' + &#36;1 + '.fple', "rb") {|file|<br />
      map_data = Marshal.load(file)<br />
      @fple_map = FPLE::Map.new(map_data.width, map_data.height,<br />
      map_data.map_name, map_data.tileset_name, map_data.data,<br />
      map_data.subsets_mapping, map_data.textureset_data)<br />
    }<br />
  end<br />
  #-----------------------------<br />
  # * Retourne la carte FPLE associée<br />
  # return FPLE::Map<br />
  #-----------------------------<br />
  def fple_map<br />
    @fple_map<br />
  end<br />
  #-----------------------------<br />
  # * Retourne le nom du tileset<br />
  # return String<br />
  #-----------------------------<br />
  def tileset_name<br />
    if &#36;game_system.fple<br />
      return @fple_map.tileset_name<br />
    else<br />
      return ""<br />
    end<br />
  end<br />
end<br />
  #-----------------------------<br />
   def cached_distance(event_id, event_x, event_y)<br />
    player_pos = [&#36;game_player.x, &#36;game_player.y]<br />
  <br />
    # Clear cache if player moved<br />
    if @last_player_pos != player_pos<br />
      @distance_cache.clear<br />
      @last_player_pos = player_pos<br />
    end<br />
  <br />
    cache_key = [event_id, event_x, event_y]<br />
    return @distance_cache[cache_key] if @distance_cache.has_key?(cache_key)<br />
  <br />
    dist_x = (player_pos[0] - event_x).abs<br />
    dist_y = (player_pos[1] - event_y).abs<br />
    distance = Math.sqrt(dist_x * dist_x + dist_y * dist_y)<br />
  <br />
    @distance_cache[cache_key] = distance<br />
    return distance<br />
  end<br />
    #-----------------------------<br />
  # * Recherche les surfaces visibles de la carte en fonction de<br />
  # l'orientation du joueur<br />
    #-----------------------------<br />
  def refresh_surfaces<br />
    @current_dir = &#36;game_player.direction<br />
    self.surfaces = []<br />
    @x_ref = &#36;game_player.x<br />
    @y_ref = &#36;game_player.y<br />
    case &#36;game_player.direction<br />
    when 2<br />
      surfaces_temp = refresh_surfaces_down<br />
    when 4<br />
      surfaces_temp = refresh_surfaces_left<br />
    when 6<br />
      surfaces_temp = refresh_surfaces_right<br />
    when 8<br />
      surfaces_temp = refresh_surfaces_up<br />
    end<br />
  <br />
    # set surfaces z attributes with z-fighting prevention<br />
    surfaces_temp.each {|surface| set_surface_z(surface)}<br />
    surfaces.concat(surfaces_temp)<br />
  <br />
    # Enhanced sorting with z-fighting prevention<br />
    if @last_surface_count != surfaces.length || &#36;game_temp.force_render<br />
      surfaces.sort! { |a, b|<br />
        z_diff = b[5] - a[5]<br />
        if z_diff.abs &lt; 0.001 # Very close z-values<br />
          # Use additional criteria for stable sorting<br />
          secondary = (b[1].abs + b[2].abs) - (a[1].abs + a[2].abs)<br />
          secondary.zero? ? b.object_id &lt;=&gt; a.object_id : secondary<br />
        else<br />
          z_diff &lt;=&gt; 0<br />
        end<br />
      }<br />
      @last_surface_count = surfaces.length<br />
    end<br />
  end<br />
     def add_character_surfaces_down_with_rotation_fix(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      dy = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
      dx = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 2)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_up_with_rotation_fix(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      dy = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
      dx = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 8)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_left_with_rotation_fix(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      dy = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
      dx = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 4)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_right_with_rotation_fix(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      dy = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
      dx = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 6)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Add surfaces for single-sided events only during rotation<br />
  #-----------------------------<br />
  def add_character_surfaces_down_single_only(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      # Only process single-sided events<br />
      #next if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
      dy = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
      dx = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 2)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_up_single_only(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      # Only process single-sided events<br />
      #next if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
      dy = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
      dx = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 8)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
def add_character_surfaces_left_single_only(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      # Only process single-sided events<br />
      #next if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
      dy = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
      dx = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 4)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_right_single_only(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      # Only process single-sided events<br />
      #next if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
      dy = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
      dx = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 6)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
<br />
      def add_two_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    # Handle special case where player is at same position as box<br />
        j = i &lt;&lt; 7<br />
    if dy.between?(128, j) &amp;&amp; dx.between?(-j, j)<br />
    event_id = surface.character.id rescue 0<br />
    base_z_offset = (event_id % 1000) * 0.0001<br />
    distance = Math.sqrt(dy * dy + dx * dx)<br />
  <br />
    # Determine visible faces based on position<br />
      faces_to_render = []<br />
  <br />
    # Front face (player looking at object)<br />
    if dy &gt; 32<br />
      faces_to_render &lt;&lt; {type: 1, d_align: 0, z_priority: 5, name: :front}<br />
    end<br />
  <br />
    # Back face<br />
    if dy &lt; -32<br />
      faces_to_render &lt;&lt; {type: 1, d_align: 2, z_priority: 0, name: :back}<br />
    end<br />
  <br />
    # Left face - FIXED: Use proper alignment values<br />
    if dx &lt; -32<br />
      faces_to_render &lt;&lt; {type: 2, d_align: 0, z_priority: 4, name: :left}<br />
    end<br />
  <br />
    # Right face - FIXED: Use proper alignment values<br />
    if dx &gt; 32<br />
      faces_to_render &lt;&lt; {type: 2, d_align: 2, z_priority: 1, name: :right}<br />
    end<br />
  <br />
    # For very close viewing, always show some faces<br />
    if distance &lt; 96<br />
      if faces_to_render.empty?<br />
        faces_to_render &lt;&lt; {type: 1, d_align: 0, z_priority: 5, name: :front}<br />
        faces_to_render &lt;&lt; {type: 2, d_align: 0, z_priority: 4, name: :left}<br />
      end<br />
    end<br />
  <br />
    # Render at least one face<br />
    if faces_to_render.empty?<br />
      faces_to_render &lt;&lt; {type: 1, d_align: 0, z_priority: 5, name: :front}<br />
    end<br />
    end<br />
  <br />
    # Render the faces<br />
    faces_to_render.each_with_index do |face_config, face_index|<br />
      side_dy = dy<br />
      side_dx = dx<br />
    <br />
      # FIXED: Apply position adjustments with proper bounds checking<br />
      if face_config[:type] == 1 # Horizontal face<br />
        if face_config[:d_align] == 0 # Front<br />
          side_dy -= 64<br />
        elsif face_config[:d_align] == 2 # Back<br />
          side_dy += 64<br />
        end<br />
      elsif face_config[:type] == 2 # Vertical face<br />
        if face_config[:d_align] == 0 # Left<br />
          side_dx -= 64<br />
        elsif face_config[:d_align] == 2 # Right<br />
          side_dx += 64<br />
        end<br />
      end<br />
    <br />
      # Calculate z-modifier<br />
      z_modifier = base_z_offset + (face_config[:z_priority] * 0.008) + (face_index * 0.001)<br />
    <br />
      surface_data = [0, side_dy, side_dx, 5, 0, 0,<br />
                      surface.bitmap.__id__, face_config[:type],<br />
                      surface.character.fple_v_align, surface.character.fple_stretch,<br />
                      surface.opacity, surface.blend_type,<br />
                      surface.fit, surface.zoom, 0, z_modifier]<br />
    <br />
      surfaces_temp.push(surface_data)<br />
    end<br />
  <br />
    surface.displayed = true<br />
  end<br />
  #-----------------------------<br />
  # * FIXED: Four-sided surfaces - ensure proper type assignment<br />
  #-----------------------------<br />
  def add_four_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    # Handle special case where player is at same position as box<br />
        j = i &lt;&lt; 7<br />
    if dy.between?(128, j) &amp;&amp; dx.between?(-j, j)<br />
    event_id = surface.character.id rescue 0<br />
    base_z_offset = (event_id % 1000) * 0.0001<br />
  <br />
    # Always render all 4 sides for 4-sided boxes<br />
    faces_to_render = [<br />
      {type: 1, d_align: 0, z_priority: 3, name: :front},  # Front<br />
      {type: 1, d_align: 2, z_priority: 0, name: :back},   # Back<br />
      {type: 2, d_align: 0, z_priority: 3, name: :left},     # Left<br />
      {type: 2, d_align: 2, z_priority: 1, name: :right},    # Right<br />
    ]<br />
  <br />
    # Render all faces with strafe-safe positioning<br />
    faces_to_render.each_with_index do |face_config, face_index|<br />
      side_dy = dy<br />
      side_dx = dx<br />
    <br />
      # FIXED: Apply position adjustments with bounds checking and strafe compensation<br />
      if face_config[:type] == 1 # Horizontal face<br />
        if face_config[:d_align] == 0 # Front<br />
          side_dy -= 64<br />
        elsif face_config[:d_align] == 2 # Back<br />
          side_dy += 64<br />
        end<br />
      elsif face_config[:type] == 2 # Vertical face<br />
        if face_config[:d_align] == 0 # Left<br />
          side_dx -= 64<br />
        elsif face_config[:d_align] == 2 # Right<br />
          side_dx += 64<br />
        end<br />
      end<br />
    <br />
      # Calculate z-modifier<br />
      z_modifier = base_z_offset + (face_config[:z_priority] * 0.01) + (face_index * 0.001)<br />
    <br />
      surface_data = [0, side_dy, side_dx, 5, 0, 0,<br />
                      surface.bitmap.__id__, face_config[:type],<br />
                      surface.character.fple_v_align, surface.character.fple_stretch,<br />
                      surface.opacity, surface.blend_type,<br />
                      surface.fit, surface.zoom, 0, z_modifier]<br />
    <br />
      surfaces_temp.push(surface_data)<br />
    end<br />
  <br />
    surface.displayed = true<br />
  end<br />
end<br />
  #-----------------------------<br />
  # * FIXED: Six-sided surfaces - ensure proper type assignment<br />
  #-----------------------------<br />
def add_six_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    j = i &lt;&lt; 7<br />
    if dy.between?(128, j) &amp;&amp; dx.between?(-j, j)<br />
    event_id = surface.character.id rescue 0<br />
    base_z_offset = (event_id % 1000) * 0.0001<br />
  <br />
    # Render all 6 sides for maximum visibility<br />
  <br />
      faces_to_render = [<br />
      {type: 0, d_align: 1, z_priority: 2, name: :center_h}, # Center horizontal<br />
      {type: 1, d_align: 0, z_priority: 4, name: :front},    # Front<br />
      {type: 1, d_align: 2, z_priority: 0, name: :back},     # Back<br />
      {type: 2, d_align: 0, z_priority: 3, name: :left},    # Left<br />
      {type: 2, d_align: 2, z_priority: 1, name: :right},  # Right<br />
    ]<br />
    # Render all faces with strafe protection<br />
    faces_to_render.each_with_index do |face_config, face_index|<br />
      side_dy = dy<br />
      side_dx = dx<br />
    <br />
      # FIXED: Apply position adjustments with strafe-aware bounds checking<br />
      if face_config[:type] == 1 # Horizontal face<br />
        if face_config[:d_align] == 0 # Front<br />
          side_dy -= 64<br />
        elsif face_config[:d_align] == 2 # Back<br />
          side_dy += 64<br />
        end<br />
      elsif face_config[:type] == 2 # Vertical face<br />
        if face_config[:d_align] == 0 # Left<br />
          side_dx -= 64<br />
        elsif face_config[:d_align] == 2 # Right<br />
          side_dx += 64<br />
        end<br />
      end<br />
    <br />
      # Calculate z-modifier<br />
      z_modifier = base_z_offset + (face_config[:z_priority] * 0.008) + (face_index * 0.001)<br />
    <br />
      surface_data = [0, side_dy, side_dx, 5, 0, 0,<br />
                      surface.bitmap.__id__, face_config[:type],<br />
                      surface.character.fple_v_align, surface.character.fple_stretch,<br />
                      surface.opacity, surface.blend_type,<br />
                      surface.fit, surface.zoom, 0, z_modifier]<br />
    <br />
      surfaces_temp.push(surface_data)<br />
    end<br />
  <br />
    surface.displayed = true<br />
  end<br />
  end<br />
    # Render all 6 sides for maximum visibility<br />
  #-----------------------------<br />
  # * Calcul de la priorité d'affichage d'une surface<br />
  # param surface : Array&lt;Integer&gt;<br />
  #-----------------------------<br />
  def set_surface_z(surface)<br />
    if surface[3] &lt; 5 # map surfaces<br />
      base_z = (surface[1].abs &lt;&lt; 5) + surface[2].abs<br />
      <br />
      # Apply rotation compensation for map surfaces<br />
      if FPLE.angle &gt; 0<br />
        rotation_factor = FPLE.angle / 90.0<br />
        # Increase z-depth for surfaces during rotation to prevent bleeding<br />
        base_z += (rotation_factor * 1000).to_i<br />
      end<br />
      <br />
      surface[5] = base_z<br />
    else # character surfaces<br />
      base_z = (surface[1].abs &gt;&gt; 1) + (surface[2].abs &gt;&gt; 6) - 2<br />
    <br />
      # Check if surface has z-modifier (from multi-sided rendering)<br />
      z_modifier = surface[15] || 0<br />
    <br />
      # Enhanced rotation compensation for character surfaces<br />
      if FPLE.angle &gt; 0<br />
        rotation_factor = FPLE.angle / 90.0<br />
        <br />
        # Push character surfaces further back during rotation<br />
        rotation_penalty = rotation_factor * 500<br />
        <br />
        # Additional penalty based on distance from player<br />
        distance_penalty = Math.sqrt(surface[1] * surface[1] + surface[2] * surface[2]) * 0.1<br />
        <br />
        base_z += (rotation_penalty + distance_penalty).to_i<br />
      end<br />
    <br />
      # Surface type and alignment offsets<br />
      type_offset = surface[7] || 0<br />
      align_offset = surface[8] || 0<br />
    <br />
      z_offset = case type_offset<br />
      when 1 # Horizontal walls<br />
        case surface[2] &lt;=&gt; 0<br />
        when -1 then 0.4  # Left side<br />
        when 0 then 0.2   # Center  <br />
        when 1 then 0.0   # Right side<br />
        end<br />
      when 2 # Vertical walls<br />
        case surface[1] &lt;=&gt; 0<br />
        when -1 then 0.3  # Front<br />
        when 0 then 0.1   # Center<br />
        when 1 then -0.1  # Back<br />
        end<br />
      else<br />
        0 # Default for type 0<br />
      end<br />
    <br />
      # Vertical alignment offset<br />
    if &#36;game_temp.movement_dir == 10 &amp;&amp; &#36;game_player.moving?<br />
      v_align_offset = 0<br />
    else<br />
      v_align_offset = case align_offset<br />
      when 0 then 0.03   # Top<br />
      when 1 then 0.01   # Middle<br />
      when 2 then -32.01 # Bottom<br />
      else 0<br />
      end<br />
    end<br />
    <br />
    surface[5] = base_z.to_f + z_offset + v_align_offset + z_modifier<br />
  end<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces visibles des évènements en fonction de<br />
  # l'orientation du joueur<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  #-----------------------------<br />
# This method updates the list of character surfaces based on visibility and player direction.<br />
public<br />
def refresh_character_surfaces(character_surfaces)<br />
    return if character_surfaces.empty?<br />
  <br />
    max_dist = (&#36;game_system.fple_view_distance || 10) + 3  # Large buffer<br />
    visible_surfaces = character_surfaces.select do |surface|<br />
      next false unless surface.character &amp;&amp; surface.visible &amp;&amp; surface.opacity &gt; 0<br />
    <br />
      # Very generous distance-based filtering<br />
      char = surface.character<br />
      dist_x = (&#36;game_player.x - char.x).abs<br />
      dist_y = (&#36;game_player.y - char.y).abs<br />
    <br />
      dist_x &lt;= max_dist &amp;&amp; dist_y &lt;= max_dist<br />
    end<br />
  <br />
    visible_surfaces = character_surfaces.select { |s|<br />
      s.character &amp;&amp; s.visible &amp;&amp; s.opacity &gt; 0<br />
    }<br />
  <br />
    clear_character_surfaces(visible_surfaces)<br />
  <br />
    # During rotation, we need to render from multiple directions<br />
    if FPLE.angle &gt; 0<br />
      # For multi-sided events during rotation, only render once from current direction<br />
      # to prevent duplicate/rotating surfaces<br />
      current_surfaces = case &#36;game_player.direction<br />
      when 2 then add_character_surfaces_down_with_rotation_fix(visible_surfaces)<br />
      when 4 then add_character_surfaces_left_with_rotation_fix(visible_surfaces)<br />
      when 6 then add_character_surfaces_right_with_rotation_fix(visible_surfaces)<br />
      when 8 then add_character_surfaces_up_with_rotation_fix(visible_surfaces)<br />
      end<br />
    <br />
      # Only add next direction surfaces for single-sided events<br />
      clear_character_surfaces_for_single_sided(visible_surfaces)<br />
      next_surfaces = case &#36;game_player.direction<br />
      when 2 then add_character_surfaces_right_single_only(visible_surfaces)<br />
      when 4 then add_character_surfaces_down_single_only(visible_surfaces)<br />
      when 6 then add_character_surfaces_up_single_only(visible_surfaces)<br />
      when 8 then add_character_surfaces_left_single_only(visible_surfaces)<br />
      end<br />
    <br />
      surfaces_temp = current_surfaces + next_surfaces<br />
    else<br />
      # Normal rendering - single direction<br />
      surfaces_temp = case &#36;game_player.direction<br />
      when 2 then add_character_surfaces_down(visible_surfaces)<br />
      when 4 then add_character_surfaces_left(visible_surfaces)<br />
      when 6 then add_character_surfaces_right(visible_surfaces)<br />
      when 8 then add_character_surfaces_up(visible_surfaces)<br />
      else []<br />
      end<br />
    end<br />
    surfaces_temp.each { |surface| set_surface_z(surface) }<br />
    @surfaces.concat(surfaces_temp)<br />
    #Old#@surfaces.sort! { |a, b| b[5] - a[5] }<br />
<br />
      # Enhanced sorting<br />
    @surfaces.sort! do |a, b|<br />
      z_diff = b[5] - a[5]<br />
      if z_diff.abs &lt; 0.0001<br />
        (b[1].abs + b[2].abs) - (a[1].abs + a[2].abs)<br />
      else<br />
        z_diff &lt;=&gt; 0<br />
      end<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Réinitialise l'indicateur d'affichage des surfaces liées aux évènements<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  #-----------------------------<br />
  def clear_character_surfaces(character_surfaces)<br />
    character_surfaces.each {|surface| surface.displayed = false}<br />
  end<br />
<br />
  def clear_character_surfaces_for_single_sided(character_surfaces)<br />
    character_surfaces.each do |surface|<br />
      # Only clear single-sided events - keep multi-sided events as displayed<br />
      unless surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
        surface.displayed = false<br />
      end<br />
    end<br />
  end<br />
<br />
  def cleanup_distant_surfaces<br />
    return unless @surfaces<br />
  <br />
    # Only cleanup if we have a lot of surfaces<br />
    max_surfaces = 300 # Very generous limit<br />
    if @surfaces.length &gt; max_surfaces<br />
      # Keep only the closest surfaces<br />
      @surfaces.sort_by! { |s| s[1].abs + s[2].abs }<br />
      @surfaces = @surfaces.first(max_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Vérifie la visibilité d'une surface liée à un évènement et l'ajoute<br />
  # à la liste des surfaces à afficher le cas échéant<br />
  # param surface : FPLE::Surface_Characters<br />
  # param dy : Integer<br />
  # param dx : Integer<br />
  # param surfaces_temp : Array&lt;Array&lt;integer&gt;&gt;<br />
  # param i : Integer<br />
  # param dir : Integer<br />
  #-----------------------------<br />
# This method adds a character surface to the list for rendering if it is visible.<br />
# `surface`: The FPLE surface object for the character.<br />
# `dy`: The change in y-coordinate from the player.<br />
# `dx`: The change in x-coordinate from the player.<br />
# `surfaces_temp`: The array to which the new surface will be added.<br />
# `i`: The view distance index used for calculation.<br />
# `dir`: The player's direction.<br />
def add_character_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
  return unless surface.character &amp;&amp; surface.character.fple_type<br />
<br />
  # Distance culling - more generous for multi-sided events<br />
  distance_sq = dy * dy + dx * dx<br />
  max_distance = &#36;game_system.fple_view_distance || 10<br />
<br />
  # Use larger buffer for multi-sided events to prevent edge clipping<br />
  if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
    rotation_buffer = FPLE.angle &gt; 0 ? 1.5 : 1.3<br />
  else<br />
    rotation_buffer = FPLE.angle &gt; 0 ? 2.0 : 1.0<br />
  end<br />
<br />
  max_distance_sq = (max_distance * 96 * rotation_buffer) ** 2<br />
  return if distance_sq &gt; max_distance_sq<br />
<br />
  # Early opacity check<br />
  return if surface.opacity &lt;= 0<br />
<br />
  # Handle multi-sided boxes<br />
  if surface.character.fple_two_side<br />
    add_two_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    return<br />
  elsif surface.character.fple_four_side<br />
    add_four_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    return<br />
  elsif surface.character.fple_six_side<br />
    add_six_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    return<br />
  end<br />
<br />
  # Original single-surface logic for regular events<br />
  j = i &lt;&lt; 7<br />
  if dy == 0 &amp;&amp; dx == 0 &amp;&amp; surface.character.fple_type == 0 &amp;&amp; surface.character.fple_one_side == false<br />
    surface.set_relative_attributes(dir)<br />
    safe_dy = 128<br />
    surface_data = [0, safe_dy, 0, 5, 0, 0,<br />
                    surface.bitmap.__id__,<br />
                    0, # Keep type 0 for face-player events at same position<br />
                    surface.character.fple_v_align,<br />
                    surface.character.fple_stretch,<br />
                    surface.opacity,<br />
                    surface.blend_type,<br />
                    surface.fit,<br />
                    surface.zoom,<br />
                    surface.mirror]<br />
    surfaces_temp.push(surface_data)<br />
    surface.displayed = true<br />
    elsif dy.between?(128, j) &amp;&amp; dx.between?(-j, j)<br />
    # Position adjustments for wall types<br />
    if surface.v_align == 2<br />
      dy -= 16 unless surface.fit == 1<br />
    end<br />
  <br />
    surface.set_relative_attributes(dir)<br />
  <br />
    if surface.type == 1<br />
      if surface.d_align == 0<br />
        dy -= 64<br />
      elsif surface.d_align == 2<br />
        dy += 64<br />
      elsif surface.d_align == 1 &amp;&amp; surface.v_align == 2<br />
        dy -= 16 unless &#36;game_player.moving?<br />
      end<br />
    elsif surface.type == 2<br />
      if surface.d_align == 0<br />
        dx -= 64<br />
      elsif surface.d_align == 2<br />
        dx += 64<br />
      elsif surface.d_align == 1 &amp;&amp; surface.v_align == 2<br />
        dx -= 16 unless &#36;game_player.moving?<br />
      end<br />
    end<br />
  <br />
    surface_data = [0, dy, dx, 5, 0, 0,<br />
                    surface.bitmap.__id__, surface.type,<br />
                    surface.v_align, surface.character.fple_stretch,<br />
                    surface.opacity, surface.blend_type,<br />
                    surface.fit, surface.zoom, surface.mirror]<br />
    surfaces_temp.push(surface_data)<br />
    surface.displayed = true<br />
  end<br />
end<br />
#-----------------------------<br />
def should_render_one_side_event(character, player_dir)<br />
  return true unless character.fple_one_side<br />
<br />
  # Get the event's original type<br />
  original_type = character.fple_type<br />
<br />
  case original_type<br />
  when 0 # Always face player - render from all directions<br />
    return true<br />
  when 1 # Horizontal wall in editor view<br />
    # Only render when looking from north or south<br />
    return [2, 8].include?(player_dir)<br />
  when 2 # Vertical wall in editor view<br />
    # Only render when looking from east or west<br />
    return [4, 6].include?(player_dir)<br />
  end<br />
<br />
  return true<br />
end<br />
  #-----------------------------<br />
def should_render_two_side_event(character, player_dir)<br />
  return true unless character.fple_two_side<br />
<br />
  # Get the event's original type<br />
  original_type = character.fple_type<br />
<br />
  case original_type<br />
  when 0 # Always face player - render from all directions<br />
    return true<br />
  when 1 # Horizontal wall in editor view<br />
    # Only render when looking from north or south<br />
    return [2, 8].include?(player_dir)<br />
  when 2 # Vertical wall in editor view<br />
    # Only render when looking from east or west<br />
    return [4, 6].include?(player_dir)<br />
  end<br />
<br />
  return true<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers le bas<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #----------------------------z<br />
<br />
   #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers le haut<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
def add_character_surfaces_up(character_surfaces)<br />
  surfaces_temp = []<br />
  i = &#36;game_system.fple_view_distance<br />
  character_surfaces.each {|surface|<br />
    if surface.displayed then next end<br />
    # Check directional visibility for 2-side events<br />
    next unless should_render_two_side_event(surface.character, 8)<br />
  <br />
    dy = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
    dx = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
    add_character_surfaces(surface, dy, dx, surfaces_temp, i, 8)<br />
  }<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers le bas<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
def add_character_surfaces_down(character_surfaces)<br />
  surfaces_temp = []<br />
  i = &#36;game_system.fple_view_distance<br />
  character_surfaces.each {|surface|<br />
    if surface.displayed then next end<br />
    # Check directional visibility for 2-side events<br />
    next unless should_render_two_side_event(surface.character, 2)<br />
  <br />
    dy = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
    dx = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
    add_character_surfaces(surface, dy, dx, surfaces_temp, i, 2)<br />
  }<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers la gauche<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
def add_character_surfaces_left(character_surfaces)<br />
  surfaces_temp = []<br />
  i = &#36;game_system.fple_view_distance<br />
  character_surfaces.each {|surface|<br />
    if surface.displayed then next end<br />
    # Check directional visibility for 2-side events<br />
    next unless should_render_two_side_event(surface.character, 4)<br />
  <br />
    dy = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
    dx = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
    add_character_surfaces(surface, dy, dx, surfaces_temp, i, 4)<br />
  }<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers la droite<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
def add_character_surfaces_right(character_surfaces)<br />
  surfaces_temp = []<br />
  i = &#36;game_system.fple_view_distance<br />
  character_surfaces.each {|surface|<br />
    if surface.displayed then next end<br />
    # Check directional visibility for 2-side events<br />
    next unless should_render_two_side_event(surface.character, 6)<br />
  <br />
    dy = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
    dx = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
    add_character_surfaces(surface, dy, dx, surfaces_temp, i, 6)<br />
  }<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces visibles quand le joueur tourne vers la droite<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  #-----------------------------<br />
<br />
def position_occluded_during_rotation?(x, y, player_x, player_y, check_direction)<br />
  # Calculate the path from player to target position<br />
  dx = x - player_x<br />
  dy = y - player_y<br />
  <br />
    if @fple_map.get_data(x, y)[0] &gt; 0<br />
      return false unless &#36;game_map.region_id(&#36;game_player.x, &#36;game_player.y) == 0<br />
    else<br />
  end<br />
  <br />
  # Don't occlude events that are directly adjacent (doors on walls)<br />
  if dx.abs &lt;= 1 &amp;&amp; dy.abs &lt;= 1 &amp;&amp; (dx.abs + dy.abs) == 1<br />
    return false<br />
  end<br />
  <br />
  # For single-tile distances, check adjacent walls<br />
  if dx.abs &lt;= 1 &amp;&amp; dy.abs &lt;= 1<br />
    case check_direction<br />
    when 2 # Down<br />
      # Check for walls between player and target going down<br />
      return @fple_map.get_data(player_x, player_y + 1)[0] &gt; 0 if dy &gt; 0<br />
    when 4 # Left  <br />
      # Check for walls between player and target going left<br />
      return @fple_map.get_data(player_x - 1, player_y)[0] &gt; 0 if dx &lt; 0<br />
    when 6 # Right<br />
      # Check for walls between player and target going right  <br />
      return @fple_map.get_data(player_x + 1, player_y)[0] &gt; 0 if dx &gt; 0<br />
    when 8 # Up<br />
      # Check for walls between player and target going up<br />
      return @fple_map.get_data(player_x, player_y - 1)[0] &gt; 0 if dy &lt; 0<br />
    end<br />
  end<br />
  <br />
  # For longer distances, use line-of-sight checking<br />
  return line_of_sight_blocked?(player_x, player_y, x, y)<br />
end<br />
  <br />
#-----------------------------<br />
# * Check if line of sight is blocked by walls<br />
# param x1, y1 : Integer - start coordinates<br />
# param x2, y2 : Integer - end coordinates  <br />
# return Boolean - true if blocked<br />
#-----------------------------<br />
def line_of_sight_blocked?(x1, y1, x2, y2)<br />
  # Simple bresenham-like algorithm to check for wall blocking<br />
  dx = (x2 - x1).abs<br />
  dy = (y2 - y1).abs<br />
  <br />
  return false if dx == 0 &amp;&amp; dy == 0<br />
  <br />
  x_step = x1 &lt; x2 ? 1 : -1<br />
  y_step = y1 &lt; y2 ? 1 : -1<br />
  <br />
  # Check key points along the path<br />
  if dx &gt; dy<br />
    # More horizontal movement<br />
    (1..dx).each do |i|<br />
      check_x = x1 + (i * x_step)<br />
      check_y = y1 + ((i * dy * y_step) / dx)<br />
      return true if @fple_map.get_data(check_x, check_y)[0] &gt; 0<br />
    end<br />
  else<br />
    # More vertical movement  <br />
    (1..dy).each do |i|<br />
      check_x = x1 + ((i * dx * x_step) / dy)<br />
      check_y = y1 + (i * y_step)<br />
      return true if @fple_map.get_data(check_x, check_y)[0] &gt; 0<br />
    end<br />
  end<br />
  <br />
  false<br />
end<br />
<br />
#-----------------------------<br />
# * Enhanced character surface filtering with occlusion<br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
# param player_dir : Integer - current player direction<br />
# param rotation_dir : Integer - direction of rotation (next direction)<br />
# return Array&lt;FPLE::Surface_Characters&gt; - filtered surfaces<br />
#-----------------------------<br />
def filter_character_surfaces_with_occlusion(character_surfaces, player_dir, rotation_dir = nil)<br />
  return [] if character_surfaces.empty?<br />
  <br />
  player_x = &#36;game_player.x<br />
  player_y = &#36;game_player.y<br />
  filtered_surfaces = []<br />
  <br />
  character_surfaces.each do |surface|<br />
    next unless surface.character &amp;&amp; surface.visible &amp;&amp; surface.opacity &gt; 0<br />
    <br />
    char_x = surface.character.x<br />
    char_y = surface.character.y<br />
    <br />
    # Skip if too distant<br />
    dist_x = (player_x - char_x).abs  <br />
    dist_y = (player_y - char_y).abs<br />
    max_dist = &#36;game_system.fple_view_distance + 2<br />
    next if dist_x &gt; max_dist || dist_y &gt; max_dist<br />
    <br />
    # Check occlusion for current direction<br />
    current_occluded = position_occluded_during_rotation?(char_x, char_y, player_x, player_y, player_dir)<br />
    <br />
    # Check occlusion for rotation direction if specified<br />
    rotation_occluded = rotation_dir ?<br />
      position_occluded_during_rotation?(char_x, char_y, player_x, player_y, rotation_dir) : false<br />
    <br />
    # Include surface if visible from either direction<br />
    unless current_occluded &amp;&amp; rotation_occluded<br />
      filtered_surfaces &lt;&lt; surface<br />
    end<br />
  end<br />
  <br />
  filtered_surfaces<br />
end<br />
<br />
#-----------------------------<br />
# * Recherche les surfaces visibles quand le joueur tourne vers la droite<br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
#-----------------------------<br />
def refresh_surfaces_turn_right(character_surfaces)<br />
  @current_dir = &#36;game_player.direction<br />
  self.surfaces = []<br />
  @x_ref = &#36;game_player.x<br />
  @y_ref = &#36;game_player.y<br />
  surfaces_temp = refresh_current_surface<br />
  <br />
  # Filter character surfaces with occlusion checking<br />
  filtered_surfaces = filter_character_surfaces_with_occlusion(character_surfaces, @current_dir,<br />
    case @current_dir<br />
    when 2 then 6  # Down -&gt; Right<br />
    when 4 then 2  # Left -&gt; Down  <br />
    when 6 then 8  # Right -&gt; Up<br />
    when 8 then 4  # Up -&gt; Left<br />
    end)<br />
  <br />
  clear_character_surfaces(filtered_surfaces)<br />
  <br />
  case &#36;game_player.direction<br />
  when 2<br />
    surfaces_temp1 = refresh_surfaces_down<br />
    @current_dir = 6<br />
    surfaces_temp2 = refresh_surfaces_right(false)<br />
    @current_dir = 2<br />
    surfaces_temp1 += add_character_surfaces_down(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_right(filtered_surfaces)<br />
  when 4<br />
    surfaces_temp1 = refresh_surfaces_left<br />
    @current_dir = 2<br />
    surfaces_temp2 = refresh_surfaces_down(false)<br />
    @current_dir = 4<br />
    surfaces_temp1 += add_character_surfaces_left(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_down(filtered_surfaces)<br />
  when 6<br />
    surfaces_temp1 = refresh_surfaces_right<br />
    @current_dir = 8<br />
    surfaces_temp2 = refresh_surfaces_up(false)<br />
    @current_dir = 6<br />
    surfaces_temp1 += add_character_surfaces_right(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_up(filtered_surfaces)<br />
  when 8<br />
    surfaces_temp1 = refresh_surfaces_up<br />
    @current_dir = 4<br />
    surfaces_temp2 = refresh_surfaces_left(false)<br />
    @current_dir = 8<br />
    surfaces_temp1 += add_character_surfaces_up(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_left(filtered_surfaces)<br />
  end<br />
  <br />
  surfaces_temp1.each {|surface| adjust_surface_for_rotation(surface)}<br />
  <br />
  # set surfaces z attributes<br />
  (surfaces_temp + surfaces_temp1 + surfaces_temp2).each {|surface|<br />
    set_surface_z(surface)<br />
  }<br />
  surfaces.concat(surfaces_temp + surfaces_temp1 + surfaces_temp2)<br />
  surfaces.sort! {|a, b| b[5] - a[5]}<br />
end<br />
<br />
#-----------------------------<br />
# * Recherche les surfaces visibles quand le joueur tourne vers la gauche<br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
#-----------------------------<br />
def refresh_surfaces_turn_left(character_surfaces)<br />
  @current_dir = &#36;game_player.direction<br />
  self.surfaces = []<br />
  @x_ref = &#36;game_player.x<br />
  @y_ref = &#36;game_player.y<br />
  surfaces_temp = refresh_current_surface<br />
  <br />
  # Filter character surfaces with occlusion checking<br />
  filtered_surfaces = filter_character_surfaces_with_occlusion(character_surfaces, @current_dir,<br />
    case @current_dir<br />
    when 2 then 4  # Down -&gt; Left<br />
    when 4 then 8  # Left -&gt; Up<br />
    when 6 then 2  # Right -&gt; Down<br />
    when 8 then 6  # Up -&gt; Right<br />
    end)<br />
  <br />
  clear_character_surfaces(filtered_surfaces)<br />
  <br />
  case &#36;game_player.direction<br />
  when 2<br />
    @current_dir = 4<br />
    surfaces_temp1 = refresh_surfaces_left<br />
    @current_dir = 2<br />
    surfaces_temp2 = refresh_surfaces_down(false)<br />
    surfaces_temp1 += add_character_surfaces_left(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_down(filtered_surfaces)<br />
  when 4<br />
    @current_dir = 8<br />
    surfaces_temp1 = refresh_surfaces_up<br />
    @current_dir = 4<br />
    surfaces_temp2 = refresh_surfaces_left(false)<br />
    surfaces_temp1 += add_character_surfaces_up(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_left(filtered_surfaces)<br />
  when 6<br />
    @current_dir = 2<br />
    surfaces_temp1 = refresh_surfaces_down<br />
    @current_dir = 6<br />
    surfaces_temp2 = refresh_surfaces_right(false)<br />
    surfaces_temp1 += add_character_surfaces_down(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_right(filtered_surfaces)<br />
  when 8<br />
    @current_dir = 6<br />
    surfaces_temp1 = refresh_surfaces_right<br />
    @current_dir = 8<br />
    surfaces_temp2 = refresh_surfaces_up(false)<br />
    surfaces_temp1 += add_character_surfaces_right(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_up(filtered_surfaces)<br />
  end<br />
  <br />
  surfaces_temp1.each {|surface| adjust_surface_for_rotation(surface)}<br />
  <br />
  # set surfaces z attributes<br />
  (surfaces_temp + surfaces_temp1 + surfaces_temp2).each {|surface|<br />
    set_surface_z(surface)<br />
  }<br />
  surfaces.concat(surfaces_temp + surfaces_temp1 + surfaces_temp2)<br />
  surfaces.sort! {|a, b| b[5] - a[5]}<br />
end<br />
<br />
#-----------------------------<br />
# * Enhanced turn up method (if needed for your system)<br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
#-----------------------------<br />
def refresh_surfaces_turn_up(character_surfaces)<br />
  @current_dir = &#36;game_player.direction<br />
  self.surfaces = []<br />
  @x_ref = &#36;game_player.x<br />
  @y_ref = &#36;game_player.y<br />
  surfaces_temp = refresh_current_surface<br />
  <br />
  # Filter character surfaces with occlusion checking<br />
  filtered_surfaces = filter_character_surfaces_with_occlusion(character_surfaces, @current_dir, 8)<br />
  <br />
  clear_character_surfaces(filtered_surfaces)<br />
  <br />
  # Render current direction surfaces<br />
  surfaces_temp1 = case &#36;game_player.direction<br />
  when 2 then refresh_surfaces_down<br />
  when 4 then refresh_surfaces_left  <br />
  when 6 then refresh_surfaces_right<br />
  when 8 then refresh_surfaces_up<br />
  else []<br />
  end<br />
  <br />
  # Render up direction surfaces<br />
  @current_dir = 8<br />
  surfaces_temp2 = refresh_surfaces_up(false)<br />
  @current_dir = &#36;game_player.direction<br />
  <br />
  # Add character surfaces<br />
  surfaces_temp1 += case &#36;game_player.direction<br />
  when 2 then add_character_surfaces_down(filtered_surfaces)<br />
  when 4 then add_character_surfaces_left(filtered_surfaces)<br />
  when 6 then add_character_surfaces_right(filtered_surfaces)<br />
  when 8 then add_character_surfaces_up(filtered_surfaces)<br />
  else []<br />
  end<br />
  <br />
  surfaces_temp2 += add_character_surfaces_up(filtered_surfaces)<br />
  <br />
  surfaces_temp1.each {|surface| adjust_surface_for_rotation(surface)} unless &#36;game_player.direction == 8<br />
  <br />
  # set surfaces z attributes<br />
  (surfaces_temp + surfaces_temp1 + surfaces_temp2).each {|surface|<br />
    set_surface_z(surface)<br />
  }<br />
  surfaces.concat(surfaces_temp + surfaces_temp1 + surfaces_temp2)<br />
  surfaces.sort! {|a, b| b[5] - a[5]}<br />
end<br />
<br />
#-----------------------------<br />
# * Enhanced turn down method (if needed for your system)  <br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
#-----------------------------<br />
def refresh_surfaces_turn_down(character_surfaces)<br />
  @current_dir = &#36;game_player.direction<br />
  self.surfaces = []<br />
  @x_ref = &#36;game_player.x<br />
  @y_ref = &#36;game_player.y<br />
  surfaces_temp = refresh_current_surface<br />
  <br />
  # Filter character surfaces with occlusion checking<br />
  filtered_surfaces = filter_character_surfaces_with_occlusion(character_surfaces, @current_dir, 2)<br />
  <br />
  clear_character_surfaces(filtered_surfaces)<br />
  <br />
  # Render current direction surfaces<br />
  surfaces_temp1 = case &#36;game_player.direction<br />
  when 2 then refresh_surfaces_down<br />
  when 4 then refresh_surfaces_left<br />
  when 6 then refresh_surfaces_right<br />
  when 8 then refresh_surfaces_up<br />
  else []<br />
  end<br />
  <br />
  # Render down direction surfaces<br />
  @current_dir = 2<br />
  surfaces_temp2 = refresh_surfaces_down(false)<br />
  @current_dir = &#36;game_player.direction<br />
  <br />
  # Add character surfaces<br />
  surfaces_temp1 += case &#36;game_player.direction<br />
  when 2 then add_character_surfaces_down(filtered_surfaces)<br />
  when 4 then add_character_surfaces_left(filtered_surfaces)<br />
  when 6 then add_character_surfaces_right(filtered_surfaces)<br />
  when 8 then add_character_surfaces_up(filtered_surfaces)<br />
  else []<br />
  end<br />
  <br />
  surfaces_temp2 += add_character_surfaces_down(filtered_surfaces)<br />
  <br />
  surfaces_temp1.each {|surface| adjust_surface_for_rotation(surface)} unless &#36;game_player.direction == 2<br />
  <br />
  # set surfaces z attributes<br />
  (surfaces_temp + surfaces_temp1 + surfaces_temp2).each {|surface|<br />
    set_surface_z(surface)<br />
  }<br />
  surfaces.concat(surfaces_temp + surfaces_temp1 + surfaces_temp2)<br />
  surfaces.sort! {|a, b| b[5] - a[5]}<br />
end<br />
  #-----------------------------<br />
  # * Correction des attributs d'une surface visible pendant une rotation<br />
  # param surface : Array&lt;Integer&gt;<br />
  #-----------------------------<br />
  def adjust_surface_for_rotation(surface)<br />
    if surface[3] &lt; 5<br />
      dy = surface[1]<br />
      surface[1] = -surface[2]<br />
      surface[2] = dy<br />
      if surface[3] &lt; 2<br />
        surface[3] = 1 - surface[3]<br />
      end<br />
    else<br />
      if surface[7] &gt; 0<br />
        surface[7] = 3 - surface[7]<br />
      end  <br />
      dy = surface[1]<br />
      surface[1] = -surface[2]<br />
      surface[2] = dy<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral<br />
  # param offset : Integer<br />
  #-----------------------------<br />
  def refresh_surfaces_strafe(offset)<br />
    @current_dir = &#36;game_player.direction<br />
    @x_ref = &#36;game_player.x<br />
    @y_ref = &#36;game_player.y<br />
    case &#36;game_player.direction<br />
    when 2<br />
      @x_ref -= offset<br />
      surfaces_temp = refresh_surfaces_down_strafe<br />
    when 4<br />
      @y_ref -= offset<br />
      surfaces_temp = refresh_surfaces_left_strafe<br />
    when 6<br />
      @y_ref += offset<br />
      surfaces_temp = refresh_surfaces_right_strafe<br />
    when 8<br />
      @x_ref += offset<br />
      surfaces_temp = refresh_surfaces_up_strafe<br />
    end<br />
    # set surfaces z attributes<br />
    surfaces_temp.each {|surface| set_surface_z(surface)}<br />
    surfaces.concat(surfaces_temp)<br />
    surfaces.sort! {|a, b| b[5] - a[5]}<br />
  end<br />
  #-----------------------------<br />
  # * Rafraîchit la surface à la position du joueur<br />
  # return Array&lt;Array&lt;integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_current_surface<br />
    surfaces_temp = []<br />
    get_surface_ground(surfaces_temp, @x_ref, @y_ref, 0, 0)<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche les surfaces visibles de la carte quand le joueur est<br />
  # orienté vers le haut<br />
  # param right_ground : Boolean<br />
  # return Array&lt;Array&lt;integer&gt;&gt;<br />
  #-----------------------------<br />
def refresh_surfaces_up(right_ground = true)<br />
  surfaces_temp = []<br />
  base_distance = &#36;game_system.fple_view_distance<br />
  # Add extra tiles during rotation<br />
  i = FPLE.angle &gt; 0 ? base_distance + 1 : base_distance<br />
<br />
  while i &gt; 0<br />
    # peripherical ground/ceiling sprites<br />
    get_surface_ground(surfaces_temp, @x_ref - i, @y_ref - i, i &lt;&lt; 1, -i &lt;&lt; 1)<br />
    if right_ground<br />
      get_surface_ground(surfaces_temp, @x_ref + i, @y_ref - i, i &lt;&lt; 1, i &lt;&lt; 1)<br />
    end<br />
    klim = i - 1<br />
    (-klim..klim).each {|k|<br />
      add_surfaces(surfaces_temp, @x_ref + k, @y_ref - i, i &lt;&lt; 1, k &lt;&lt; 1, 0, 1)<br />
    }<br />
    i -= 1<br />
  end<br />
  return surfaces_temp<br />
end<br />
def refresh_surfaces_down(right_ground = true)<br />
  surfaces_temp = []<br />
  base_distance = &#36;game_system.fple_view_distance<br />
  # Add extra tiles during rotation<br />
  i = FPLE.angle &gt; 0 ? base_distance + 1 : base_distance<br />
<br />
  while i &gt; 0<br />
    # peripherical ground sprites<br />
    get_surface_ground(surfaces_temp, @x_ref + i, @y_ref + i, i &lt;&lt; 1, -i &lt;&lt; 1)<br />
    if right_ground<br />
      get_surface_ground(surfaces_temp, @x_ref - i, @y_ref + i, i &lt;&lt; 1, i &lt;&lt; 1)<br />
    end<br />
    klim = i - 1<br />
    (-klim..klim).each {|k|<br />
      add_surfaces(surfaces_temp, @x_ref - k, @y_ref + i, i &lt;&lt; 1, k &lt;&lt; 1, 0, -1)<br />
    }<br />
    i -= 1<br />
  end<br />
  return surfaces_temp<br />
end<br />
def refresh_surfaces_left(right_ground = true)<br />
  surfaces_temp = []<br />
  base_distance = &#36;game_system.fple_view_distance<br />
  # Add extra tiles during rotation<br />
  i = FPLE.angle &gt; 0 ? base_distance + 1 : base_distance<br />
<br />
  while i &gt; 0<br />
    # peripherical ground sprites<br />
    get_surface_ground(surfaces_temp, @x_ref - i, @y_ref + i, i &lt;&lt; 1, -i &lt;&lt; 1)<br />
    if right_ground<br />
      get_surface_ground(surfaces_temp, @x_ref - i, @y_ref - i, i &lt;&lt; 1, i &lt;&lt; 1)<br />
    end<br />
    klim = i - 1<br />
    (-klim..klim).each {|k|<br />
      add_surfaces(surfaces_temp, @x_ref - i, @y_ref - k, i &lt;&lt; 1, k &lt;&lt; 1, 1, 0)<br />
    }<br />
    i -= 1<br />
  end<br />
  return surfaces_temp<br />
end<br />
def refresh_surfaces_right(right_ground = true)<br />
  surfaces_temp = []<br />
  base_distance = &#36;game_system.fple_view_distance<br />
  # Add extra tiles during rotation<br />
  i = FPLE.angle &gt; 0 ? base_distance + 1 : base_distance<br />
<br />
  while i &gt; 0<br />
    # peripherical ground sprites<br />
    get_surface_ground(surfaces_temp, @x_ref + i, @y_ref - i, i &lt;&lt; 1, -i &lt;&lt; 1)<br />
    if right_ground<br />
      get_surface_ground(surfaces_temp, @x_ref + i, @y_ref + i, i &lt;&lt; 1, i &lt;&lt; 1)<br />
    end<br />
    klim = i - 1<br />
    (-klim..klim).each {|k|<br />
      add_surfaces(surfaces_temp, @x_ref + i, @y_ref + k, i &lt;&lt; 1, k &lt;&lt; 1, -1, 0)<br />
    }<br />
    i -= 1<br />
  end<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Vérifie si un sol ou un plafond doit être affiché<br />
  # param surfaces_temp : Array&lt;Array&lt;Integer&gt;&gt;<br />
  # param x : Integer<br />
  # param y : Integer<br />
  # param dy : Integer<br />
  # param dx : Integer<br />
  #-----------------------------<br />
  def get_surface_ground(surfaces_temp, x, y, dy, dx)<br />
    if @fple_map.get_data(x, y)[0] == 0 # no wall tile<br />
      add_surface_ground(surfaces_temp, x, y, dy, dx)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Ajoute une surface de sol ou de plafond qui doit être affichée<br />
  # param surfaces_temp : Array&lt;Array&lt;Integer&gt;&gt;<br />
  # param x : Integer<br />
  # param y : Integer<br />
  # param dy : Integer<br />
  # param dx : Integer<br />
  #-----------------------------<br />
  def add_surface_ground(surfaces_temp, x, y, dy, dx)<br />
    g_texture_id = @fple_map.get_data(x, y)[1]<br />
    c_texture_id = @fple_map.get_data(x, y)[19]<br />
    if @fple_map.is_texture_id_valid?(g_texture_id)<br />
      if @fple_map.is_texture_id_valid?(c_texture_id)<br />
        surfaces_temp.push([g_texture_id, dy, dx, 4, c_texture_id, 0,<br />
        @fple_map.get_textureset_id(g_texture_id),<br />
        @fple_map.get_textureset_width(g_texture_id),<br />
        @fple_map.get_textureset_id(c_texture_id),<br />
        @fple_map.get_textureset_width(c_texture_id)])<br />
      else<br />
        surfaces_temp.push([g_texture_id, dy, dx, 2, 0, 0,<br />
        @fple_map.get_textureset_id(g_texture_id),<br />
        @fple_map.get_textureset_width(g_texture_id), 0, 8])<br />
      end<br />
    elsif @fple_map.is_texture_id_valid?(c_texture_id)<br />
      surfaces_temp.push([c_texture_id, dy, dx, 3, 0, 0,<br />
      @fple_map.get_textureset_id(c_texture_id),<br />
      @fple_map.get_textureset_width(c_texture_id), 0, 8])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles<br />
  # param surfaces_temp : Array&lt;Array&lt;Integer&gt;&gt;<br />
  # param x : Integer<br />
  # param y : Integer<br />
  # param dy : Integer<br />
  # param dx : Integer<br />
  # param oy : Integer<br />
  # param ox : Integer<br />
  #-----------------------------<br />
  def add_surfaces(surfaces_temp, x, y, dy, dx, ox, oy)<br />
    if @fple_map.get_data(x, y)[0] &gt; 0 # wall tile<br />
      if @fple_map.get_data(x + ox, y + oy)[0] == 0 # --&gt; visible !<br />
        texture_id = @fple_map.get_data(x, y)[<br />
        FPLE::MAP_SIDES[@current_dir - 1 &gt;&gt; 1]]<br />
        if @fple_map.is_texture_id_valid?(texture_id)<br />
          surfaces_temp.push([texture_id, dy - 1, dx, 1, 0, 0,<br />
          @fple_map.get_textureset_id(texture_id),<br />
          @fple_map.get_textureset_width(texture_id), 0, 8])<br />
        end<br />
      end<br />
    else<br />
      # ground/ceiling sprite<br />
      add_surface_ground(surfaces_temp, x, y, dy, dx)<br />
      # side walls<br />
      if dx &lt;= 0 # left<br />
        if @fple_map.get_data(x - oy, y + ox)[0] &gt; 0 # side wall tile<br />
          texture_id = @fple_map.get_data(x - oy, y + ox)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, dy, dx - 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      if dx &gt;= 0 # right<br />
        if @fple_map.get_data(x + oy, y - ox)[0] &gt; 0 # side wall tile<br />
          texture_id = @fple_map.get_data(x + oy, y - ox)[<br />
          FPLE::MAP_SIDES_RIGHT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, dy, dx + 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral quand le<br />
  # joueur est orienté vers le haut<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_surfaces_up_strafe<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    while i &gt; 0<br />
      get_surface_ground(surfaces_temp, @x_ref + i + 1, @y_ref - i, i &lt;&lt; 1,<br />
      i + 1 &lt;&lt; 1)<br />
      add_surfaces_strafe(surfaces_temp, @x_ref + i,  @y_ref - i, i &lt;&lt; 1, 0, 1)<br />
      # middle side wall<br />
      if @fple_map.get_data(@x_ref + 1, @y_ref - i)[0] == 0 # no wall tile<br />
        if @fple_map.get_data(@x_ref, @y_ref - i)[0] &gt; 0 # side wall tile (Left)<br />
          texture_id = @fple_map.get_data(@x_ref, @y_ref - i)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, i &lt;&lt; 1, 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      i -= 1<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral quand le<br />
  # joueur est orienté vers le bas<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_surfaces_down_strafe<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    while i &gt; 0<br />
      get_surface_ground(surfaces_temp, @x_ref - i - 1, @y_ref + i, i &lt;&lt; 1,<br />
      i + 1 &lt;&lt; 1)<br />
      add_surfaces_strafe(surfaces_temp, @x_ref - i,  @y_ref + i, i &lt;&lt; 1, 0, -1)<br />
      # middle side wall<br />
      if @fple_map.get_data(@x_ref - 1, @y_ref + i)[0] == 0 # no wall tile<br />
        if @fple_map.get_data(@x_ref, @y_ref + i)[0] &gt; 0 # side wall tile (Left)<br />
          texture_id = @fple_map.get_data(@x_ref, @y_ref + i)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, i &lt;&lt; 1, 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      i -= 1<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral quand le<br />
  # joueur est orienté vers la gauche<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_surfaces_left_strafe<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    while i &gt; 0<br />
      get_surface_ground(surfaces_temp, @x_ref - i, @y_ref - i - 1, i &lt;&lt; 1,<br />
      i + 1 &lt;&lt; 1)<br />
      add_surfaces_strafe(surfaces_temp, @x_ref - i,  @y_ref - i, i &lt;&lt; 1, 1, 0)<br />
      # middle side wall<br />
      if @fple_map.get_data(@x_ref - i, @y_ref - 1)[0] == 0 # no wall tile<br />
        if @fple_map.get_data(@x_ref - i, @y_ref)[0] &gt; 0 # side wall tile (Left)<br />
          texture_id = @fple_map.get_data(@x_ref - i, @y_ref)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, i &lt;&lt; 1, 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      i -= 1<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral quand le<br />
  # joueur est orienté vers la droite<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_surfaces_right_strafe<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    while i &gt; 0<br />
      get_surface_ground(surfaces_temp, @x_ref + i, @y_ref + i + 1, i &lt;&lt; 1,<br />
      i + 1 &lt;&lt; 1)<br />
      add_surfaces_strafe(surfaces_temp, @x_ref + i,  @y_ref + i, i &lt;&lt; 1, -1, 0)<br />
      # middle side wall<br />
      if @fple_map.get_data(@x_ref + i, @y_ref + 1)[0] == 0 # no wall tile<br />
        if @fple_map.get_data(@x_ref + i, @y_ref)[0] &gt; 0 # side wall tile (Left)<br />
          texture_id = @fple_map.get_data(@x_ref + i, @y_ref)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, i &lt;&lt; 1, 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      i -= 1<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral<br />
  # param surfaces_temp : Array&lt;Array&lt;Integer&gt;&gt;<br />
  # param x : Integer<br />
  # param y : Integer<br />
  # param dxy : Integer<br />
  # param oy : Integer<br />
  # param ox : Integer<br />
  #-----------------------------<br />
  def add_surfaces_strafe(surfaces_temp, x, y, dxy, ox, oy)<br />
    if @fple_map.get_data(x, y)[0] &gt; 0 # wall tile<br />
      if @fple_map.get_data(x + ox, y + oy)[0] == 0 # --&gt; visible !<br />
        texture_id = @fple_map.get_data(x, y)[<br />
        FPLE::MAP_SIDES[@current_dir - 1 &gt;&gt; 1]]<br />
        if @fple_map.is_texture_id_valid?(texture_id)<br />
          surfaces_temp.push([texture_id, dxy - 1, dxy, 1, 0, 0,<br />
          @fple_map.get_textureset_id(texture_id),<br />
          @fple_map.get_textureset_width(texture_id), 0, 8])<br />
        end<br />
      end<br />
    else<br />
      # side wall (Right)<br />
      if @fple_map.get_data(x + oy, y - ox)[0] &gt; 0 # side wall tile<br />
        texture_id = @fple_map.get_data(x + oy, y - ox)[<br />
        FPLE::MAP_SIDES_RIGHT[@current_dir - 1 &gt;&gt; 1]]<br />
        if @fple_map.is_texture_id_valid?(texture_id)<br />
          surfaces_temp.push([texture_id, dxy, dxy + 1, 0, 0, 0,<br />
          @fple_map.get_textureset_id(texture_id),<br />
          @fple_map.get_textureset_width(texture_id), 0, 8])<br />
        end<br />
      end<br />
    end<br />
end<br />
#==============================<br />
# ** Game_Character<br />
#==============================<br />
class Game_Character &lt; Game_CharacterBase<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias moving_fple_game_character? moving?<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Determine if Moving<br />
  # return Boolean<br />
  #-----------------------------<br />
  def moving?<br />
    if &#36;game_system.fple<br />
      return &#36;game_temp.movement || moving_fple_game_character?<br />
    else<br />
      return moving_fple_game_character?<br />
    end<br />
  end<br />
end<br />
#==============================<br />
# ** Game_Player<br />
#==============================<br />
class Game_Player &lt; Game_Character<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility) - mod [1.1]<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias move_straight_fple_game_player move_straight<br />
    alias move_diagonal_fple_game_player move_diagonal<br />
    alias turn_right_90_fple_game_player turn_right_90<br />
    alias turn_left_90_fple_game_player turn_left_90<br />
    alias move_by_input_fple_game_player move_by_input<br />
    alias update_nonmoving_fple_game_player update_nonmoving<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Initialize Public Member Variables<br />
  #-----------------------------<br />
  def init_public_members<br />
    super<br />
    @direction = 8<br />
  end<br />
  #-----------------------------<br />
  # * Move Straight<br />
  # param d : Integer<br />
  # param turn_ok : Boolean<br />
  #-----------------------------<br />
  def move_straight(d, turn_ok = true)<br />
    if &#36;game_system.fple<br />
      case d<br />
      when 2<br />
        case &#36;game_player.direction<br />
        when 2<br />
          go_forward<br />
        when 4<br />
          strafe_left<br />
        when 6<br />
          strafe_right<br />
        when 8<br />
          go_backward<br />
        end<br />
      when 4<br />
        case &#36;game_player.direction<br />
        when 2<br />
          strafe_right<br />
        when 4<br />
          go_forward<br />
        when 6<br />
          go_backward<br />
        when 8<br />
          strafe_left<br />
        end<br />
      when 6<br />
        case &#36;game_player.direction<br />
        when 2<br />
          strafe_left<br />
        when 4<br />
          go_backward<br />
        when 6<br />
          go_forward<br />
        when 8<br />
          strafe_right<br />
        end<br />
      when 8<br />
        case &#36;game_player.direction<br />
        when 2<br />
          go_backward<br />
        when 4<br />
          strafe_right<br />
        when 6<br />
          strafe_left<br />
        when 8<br />
          go_forward<br />
        end<br />
      end<br />
    else<br />
      move_straight_fple_game_player(d, turn_ok)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Move Diagonally<br />
  # param horz : Integer<br />
  # param vert : Integer<br />
  #-----------------------------<br />
  def move_diagonal(horz, vert)<br />
    unless &#36;game_system.fple<br />
      move_diagonal_fple_game_player(horz, vert)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Jump<br />
  # param x_plus : Integer<br />
  # param y_plus : Integer<br />
  #-----------------------------<br />
  def jump(x_plus, y_plus)<br />
    unless &#36;game_system.fple<br />
      super(x_plus, y_plus) # [1.1]<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Turn 90° Right<br />
  #-----------------------------<br />
  def turn_right_90<br />
    turn_right_90_fple_game_player<br />
    if &#36;game_system.fple &amp;&amp; !@direction_fix<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 9<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Turn 90° Left<br />
  #-----------------------------<br />
  def turn_left_90<br />
    turn_left_90_fple_game_player<br />
    if &#36;game_system.fple &amp;&amp; !@direction_fix<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 10<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Go Forward<br />
  #-----------------------------<br />
  def go_forward<br />
    mvt_data = FPLE::PLAYER_MOVE_FORWARD[(@direction &gt;&gt; 1) - 1]<br />
    if passable?(@x, @y, @direction)<br />
      @x += mvt_data[0]<br />
      @y += mvt_data[1]<br />
      increase_steps<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 8<br />
    else<br />
      check_event_trigger_touch(@x + mvt_data[0], @y + mvt_data[1])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Go Backward<br />
  #-----------------------------<br />
  def go_backward<br />
    target_dir = 10 - @direction<br />
    mvt_data = FPLE::PLAYER_MOVE_FORWARD[(target_dir &gt;&gt; 1) - 1]<br />
    if passable?(@x, @y, target_dir)<br />
      @x += mvt_data[0]<br />
      @y += mvt_data[1]<br />
      increase_steps<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 2<br />
    else<br />
      check_event_trigger_touch(@x + mvt_data[0], @y + mvt_data[1])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Strafe Left<br />
  #-----------------------------<br />
  def strafe_left<br />
    target_dir = FPLE::TURN_LEFT[(@direction &gt;&gt; 1) - 1]<br />
    mvt_data = FPLE::PLAYER_MOVE_FORWARD[(target_dir &gt;&gt; 1) - 1]<br />
    if passable?(@x, @y, target_dir)<br />
      @x += mvt_data[0]<br />
      @y += mvt_data[1]<br />
      increase_steps<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 4<br />
    else<br />
      check_event_trigger_touch(@x + mvt_data[0], @y + mvt_data[1])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Strafe Right<br />
  #-----------------------------<br />
  def strafe_right<br />
    target_dir = 10 - FPLE::TURN_LEFT[(@direction &gt;&gt; 1) - 1]<br />
    mvt_data = FPLE::PLAYER_MOVE_FORWARD[(target_dir &gt;&gt; 1) - 1]<br />
    if passable?(@x, @y, target_dir)<br />
      @x += mvt_data[0]<br />
      @y += mvt_data[1]<br />
      increase_steps<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 6<br />
    else<br />
      check_event_trigger_touch(@x + mvt_data[0], @y + mvt_data[1])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Processing of Movement via input from the Directional Buttons<br />
  #-----------------------------<br />
  def move_by_input<br />
    if &#36;game_system.fple<br />
      if !movable? || &#36;game_map.interpreter.running? then return end<br />
      if Input.press?(:L)<br />
        strafe_left<br />
      elsif Input.press?(:R)<br />
        strafe_right<br />
      else<br />
        case Input.dir4<br />
        when 2; go_backward<br />
        when 4; turn_left_90<br />
        when 6; turn_right_90<br />
        when 8; go_forward<br />
        end<br />
      end<br />
    else<br />
      move_by_input_fple_game_player<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Processing when not moving<br />
  # param last_moving : Boolean<br />
  #-----------------------------<br />
  def update_nonmoving(last_moving)<br />
    if &#36;game_map.interpreter.running? then return end<br />
    update_nonmoving_fple_game_player(last_moving)<br />
    if last_moving then &#36;game_temp.last_moving = false end<br />
  end<br />
  #-----------------------------<br />
  # * Move speed in FPLE mode<br />
  # return Integer<br />
  #-----------------------------<br />
  def move_speed_fple<br />
    return FPLE::PLAYER_MOVE_SPEED[real_move_speed]<br />
  end<br />
end<br />
#==============================<br />
# ** Game_Event<br />
#==============================<br />
class Game_Event &lt; Game_Character<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias refresh_fple_game_character refresh<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Public Instance Variables<br />
  #-----------------------------<br />
  attr_reader :fple_type # Integer 0:face the player<br />
                         #         1:horizontal wall in the RMXP editor view<br />
                         #         2:vertical wall in the RMXP editor view<br />
                         #         3:4-sided box (NEW)<br />
                         #         4:6-sided box (NEW)<br />
  attr_reader :fple_v_align # Integer - Vertical align {0:up, 1:middle, 2:down}<br />
  attr_reader :fple_d_align # Integer - Depth align {0:front/left, 1:middle, 2:back/right}<br />
  attr_reader :fple_stretch # Integer (0/1)<br />
  attr_reader :fple_fit # Integer (0/1)<br />
  attr_reader :fple_zoom # Integer (1024 &lt;=&gt; zoom = 1.0)<br />
  attr_reader :fple_one_side # Boolean (0/1)<br />
  attr_reader :fple_two_side # Boolean - NEW: indicates 6-sided box mode<br />
  attr_reader :fple_four_side # Boolean - NEW: indicates 4-sided box mode<br />
  attr_reader :fple_six_side # Boolean - NEW: indicates 6-sided box mode<br />
  #-----------------------------<br />
  # * Scan the event's commands list<br />
  # param page : RPG::Event::Page<br />
  #-----------------------------<br />
  def check_commands(page)<br />
    @fple_type = 0<br />
    @fple_v_align = 1<br />
    @fple_d_align = 1<br />
    @fple_stretch = 0<br />
    @fple_fit = 0<br />
    @fple_zoom = 1024<br />
    @fple_one_side = false # [1.5]<br />
    @fple_two_side = false # NEW<br />
    @fple_four_side = false # NEW<br />
    @fple_six_side = false # NEW<br />
    command_list = page.list<br />
    (0..command_list.length - 2).each {|k|<br />
      command = command_list[k]<br />
      if command.code == 108<br />
        comments = command.parameters[0]<br />
        if comments[/Type/]<br />
          @fple_type = comments[/&#92;d+/].to_i<br />
          if @fple_type &lt; 0 || @fple_type &gt; 2 then @fple_type = 0 end<br />
        end<br />
        if comments[/V-Align/]<br />
          @fple_v_align = comments[/&#92;d+/].to_i<br />
          if @fple_v_align &lt; 0 || @fple_v_align &gt; 2 then @fple_v_align = 1 end<br />
        end<br />
        if comments[/D-Align/]<br />
          @fple_d_align = comments[/&#92;d+/].to_i<br />
          if @fple_d_align &lt; 0 || @fple_d_align &gt; 2 then @fple_d_align = 1 end<br />
        end<br />
        if comments[/Stretch/]<br />
          @fple_stretch = 1<br />
        end<br />
        if comments[/Fit/]<br />
          @fple_fit = 1<br />
        end<br />
        if comments[/Zoom/]<br />
          @fple_zoom = (comments[/&#92;d+&#92;.&#92;d+/].to_f * 1024).round<br />
        end<br />
        if comments[/1-Side/] # [1.5]<br />
          @fple_one_side = true<br />
        end<br />
        if comments[/2-Side/] # NEW<br />
          @fple_four_side = true<br />
        end<br />
        if comments[/4-Side/] # NEW<br />
          @fple_four_side = true<br />
        end<br />
        if comments[/6-Side/] # NEW<br />
          @fple_six_side = true<br />
        end<br />
      end<br />
    }<br />
    if @fple_type == 0 then @fple_d_align = 1 end<br />
    if @fple_stretch == 1 then @fple_v_align = 1 end<br />
    if @fple_two_side<br />
    elsif @fple_four_side<br />
      @fple_type = 3 # Special type for 4-sided boxes<br />
      @fple_d_align = 1 # Center alignment makes most sense<br />
    elsif @fple_six_side<br />
      @fple_type = 4 # Special type for 6-sided boxes<br />
      @fple_d_align = 1 # Center alignment makes most sense<br />
    end<br />
  end<br />
<br />
  #-----------------------------<br />
  # * Refresh<br />
  #-----------------------------<br />
  def refresh<br />
    refresh_fple_game_character<br />
    if @page then check_commands(@page) end<br />
  end<br />
end<br />
#==============================<br />
# ** FPLE::Map_Data<br />
#==============================<br />
module FPLE<br />
  class Map_Data<br />
    #-----------------------------<br />
    # * Public Instance Variables<br />
    #-----------------------------<br />
    attr_accessor :data, :tileset_name, :map_name<br />
    attr_accessor :used_tiles_map, :textureset_data, :subsets_mapping<br />
    attr_reader :map_id, :width, :height<br />
  end<br />
end<br />
#==============================<br />
# ** FPLE::Map<br />
#==============================<br />
module FPLE<br />
  class Map<br />
    #-----------------------------<br />
    # * Public Instance Variables<br />
    #-----------------------------<br />
    attr_accessor :data, :tileset_name, :map_name<br />
    attr_reader :map_id, :width, :height<br />
    attr_accessor :textureset<br />
    attr_accessor :texturesets<br />
    #-----------------------------<br />
    # * Initialisation<br />
    # param width : integer (largeur de la carte, donc égal à &#36;game_map.width)<br />
    # param height : integer (hauteur de la carte, donc égal à &#36;game_map.height)<br />
    # param name : String (nom du fichier de la carte FPLE)<br />
    # param tileset_name : String (nom du tileset utilisé)<br />
    # param map_data : Array[width * height]&lt;Array&lt;integer&gt;&gt;<br />
    # param subsets_mapping : Hash&lt;Integer,String&gt; {texture_id=&gt;subset_name}<br />
    # param textureset_data : Array&lt;Array&gt; données de création du textureset<br />
    #-----------------------------<br />
    def initialize(width, height, name, tileset_name, map_data = nil,<br />
      subsets_mapping = nil, textureset_data = nil)<br />
      @width = width<br />
      @height = height<br />
      self.map_name = name<br />
      self.data = Array.new(width * height)<br />
      data.each_index {|index| data[index] = map_data[index]}<br />
      self.tileset_name = tileset_name<br />
      @subsets_mapping = subsets_mapping<br />
      create_textureset_from_data(textureset_data)<br />
    end<br />
    #-----------------------------<br />
    # * Retourne les données d'un tile par ses coordonées<br />
    # param x : integer ([0, width[)<br />
    # param y : integer ([0, height[)<br />
    # return Array[10]&lt;integer&gt; (map_Data)<br />
    #-----------------------------<br />
    def get_data(x, y)<br />
      ret = data[get_index(x, y)]<br />
      ret = [-1] unless ret<br />
      return ret<br />
    end<br />
    #-----------------------------<br />
    # * Retourne l'index d'un tile par ses coordonées<br />
    # param x : integer ([0, width[)<br />
    # param y : integer ([0, height[)<br />
    # return integer (&gt; 0)<br />
    #-----------------------------<br />
    def get_index(x, y)<br />
      return x + y * width<br />
    end<br />
    #-----------------------------<br />
    # * Retourne l'abscisse d'un tile par son index<br />
    # return integer ([0, width[)<br />
    #-----------------------------<br />
    def get_x(index)<br />
      return index - width * (index / width)<br />
    end<br />
    #-----------------------------<br />
    # * Retourne l'ordonnée d'un tile par son index<br />
    # return integer ([0, height[)<br />
    #-----------------------------<br />
    def get_y(index)<br />
      return index / width<br />
    end<br />
    #-----------------------------<br />
    # * Création du textureset<br />
    # param textureset_data : Array&lt;Array&gt; données de création du textureset<br />
    #-----------------------------<br />
        def get_texture_lazy(texture_id)<br />
      @texture_cache ||= {}<br />
      return @texture_cache[texture_id] if @texture_cache.has_key?(texture_id)<br />
    <br />
      # Only load texture if it will be used<br />
      if is_texture_id_valid?(texture_id)<br />
        @texture_cache[texture_id] = load_texture(texture_id)<br />
      else<br />
        @texture_cache[texture_id] = nil<br />
      end<br />
    <br />
      return @texture_cache[texture_id]<br />
    end<br />
  #-----------------------------<br />
    def create_textureset_from_data(textureset_data)<br />
      rect = Rect.new(0, 0, 32, 32)<br />
      textureset_height = 1 + (textureset_data.size &gt;&gt; 3) &lt;&lt; 5<br />
      self.textureset = Bitmap.new(256, textureset_height)<br />
      src = Cache.tileset(tileset_name)<br />
      textureset_data.each_index {|texture_id|<br />
        t_dat = textureset_data[texture_id]<br />
        if t_dat<br />
          x_trg = texture_id - (texture_id &gt;&gt; 3 &lt;&lt; 3) &lt;&lt; 5<br />
          y_trg = texture_id &gt;&gt; 3 &lt;&lt; 5<br />
          rect.x = t_dat[0]<br />
          rect.y = t_dat[1]<br />
          if t_dat[0] == 0 &amp;&amp; t_dat[1] == 0<br />
            @texture_id_nil = texture_id<br />
          end<br />
          textureset.blt(x_trg, y_trg, src, rect)<br />
        end<br />
      }<br />
      @texturesets = [textureset]<br />
      @texturesets_widths = [8]<br />
      @texturesets_mapping_ids = {}<br />
      subsets_names_list = []<br />
      if @subsets_mapping<br />
        @subsets_mapping.each {|texture_id, subset_name|<br />
          if subsets_names_list.include?(subset_name)<br />
            @texturesets_mapping_ids[texture_id] =<br />
            subsets_names_list.index(subset_name) + 1<br />
          else<br />
            subsets_names_list &lt;&lt; subset_name<br />
            subset = Cache.tileset(subset_name)<br />
            texturesets &lt;&lt; subset<br />
            for k in 5..9<br />
              if subset.width &gt;&gt; k == 1<br />
                @texturesets_widths &lt;&lt; k<br />
                break<br />
              end<br />
            end<br />
            @texturesets_mapping_ids[texture_id] = subsets_names_list.size<br />
          end<br />
        }<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Retourne l'index du textureset pour une texture<br />
    # param textureset_data : Integer<br />
    # return Integer<br />
    #-----------------------------<br />
    def get_textureset_id(texture_id)<br />
      if @texturesets_mapping_ids.has_key?(texture_id)<br />
        return @texturesets_mapping_ids[texture_id]<br />
      else<br />
        return 0<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Retourne la largeur du textureset pour une texture<br />
    # param textureset_data : Integer<br />
    # return Integer<br />
    #-----------------------------<br />
    def get_textureset_width(texture_id)<br />
      return @texturesets_widths[get_textureset_id(texture_id)]<br />
    end<br />
    #-----------------------------<br />
    # * Dispose<br />
    #-----------------------------<br />
    def dispose<br />
      if textureset then textureset.dispose end<br />
    end<br />
    #-----------------------------<br />
    # * Is texture valid<br />
    # param texture_id : Integer<br />
    # return Boolean<br />
    #-----------------------------<br />
    def is_texture_id_valid?(texture_id)<br />
      return texture_id &amp;&amp; texture_id != @texture_id_nil<br />
    end<br />
  end<br />
end<br />
#==============================<br />
# ** Spriteset_Weather<br />
#==============================<br />
class Spriteset_Weather<br />
  #-----------------------------<br />
  # * Modification of sprites coordinates when moving forward and backward<br />
  #-----------------------------<br />
  def update_fple<br />
    @sprites.each {|sprite|<br />
      if &#36;game_temp.movement_dir == 8<br />
        sprite.x += (sprite.x + @ox - 272) / 8<br />
        sprite.y += (sprite.y + @oy - 208) / 8<br />
        sprite.opacity += 8<br />
      elsif &#36;game_temp.movement_dir == 2<br />
        sprite.x -= (sprite.x + @ox - 272) / 8<br />
        sprite.y -= (sprite.y + @oy - 139) / 8<br />
        sprite.opacity -= 8<br />
      end<br />
    }<br />
  end<br />
end<br />
#==============================<br />
# ** FPLE::Spriteset_Map<br />
#==============================<br />
module FPLE<br />
  class Spriteset_Map &lt; ::Spriteset_Map<br />
    #-----------------------------<br />
    # * Public Instance Variables<br />
    #-----------------------------<br />
    attr_reader :character_surfaces # Array&lt;FPLE::Surface_Characters&gt;<br />
    attr_reader :viewport1 # Viewport<br />
    #-----------------------------<br />
    # * Create Tilemap<br />
    #-----------------------------<br />
    def create_tilemap<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Create Character Surfaces<br />
    #-----------------------------<br />
    def create_characters<br />
      @character_surfaces = []<br />
      &#36;game_map.events.values.each {|event|<br />
        character_surfaces &lt;&lt; FPLE::Surface_Character.new(self, event)<br />
      }<br />
      @map_id = &#36;game_map.map_id<br />
      initialize_fple_rendering<br />
    end<br />
    #-----------------------------<br />
    # * Create Airship Shadow Sprite<br />
    #-----------------------------<br />
    def create_shadow<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Initialize FPLE rendering<br />
    #-----------------------------<br />
    def initialize_fple_rendering<br />
      FPLE.initialize_fple(self, @viewport1)<br />
    end<br />
    #-----------------------------<br />
    # * Dispose<br />
    #-----------------------------<br />
    def dispose<br />
      dispose_fple_rendering<br />
      super<br />
    end<br />
    #-----------------------------<br />
    # * Dispose of FPLE rendering<br />
    #-----------------------------<br />
    def dispose_fple_rendering<br />
      FPLE.dispose<br />
    end<br />
    #-----------------------------<br />
    # * Free Tilemap<br />
    #-----------------------------<br />
    def dispose_tilemap<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Dispose of Character Surfaces<br />
    #-----------------------------<br />
    def dispose_characters<br />
      @character_surfaces.each {|surface| surface.dispose}<br />
    end<br />
    #-----------------------------<br />
    # * Free Airship Shadow Sprite<br />
    #-----------------------------<br />
    def dispose_shadow<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Update Tileset<br />
    #-----------------------------<br />
    def update_tileset<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Update Tilemap<br />
    #-----------------------------<br />
    def update_tilemap<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Update Parallax<br />
    #-----------------------------<br />
    def update_parallax<br />
      super<br />
      if @parallax.bitmap<br />
        @parallax.ox += (@parallax.bitmap.width * FPLE.angle) / 90<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Update Character Sprite<br />
    #-----------------------------<br />
    def update_characters<br />
      unless @map_id == &#36;game_map.map_id then refresh_characters end<br />
      character_surfaces.each {|surface| surface.update}<br />
      update_fple_rendering<br />
    end<br />
    #-----------------------------<br />
    # * Update FPLE Rendering<br />
    #-----------------------------<br />
    def update_fple_rendering<br />
      FPLE.update<br />
    end<br />
    #-----------------------------<br />
    # * Update Airship Shadow Sprite<br />
    #-----------------------------<br />
    def update_shadow<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Update Weather<br />
    #-----------------------------<br />
    def update_weather<br />
      @weather.type = &#36;game_map.screen.weather_type<br />
      @weather.power = &#36;game_map.screen.weather_power<br />
      @weather.ox = &#36;game_map.display_x * 32 +<br />
      (Graphics.width * FPLE.angle) / 90 +<br />
      (Graphics.width * FPLE.offset_x &gt;&gt; 5)<br />
      @weather.oy = &#36;game_map.display_y * 32<br />
      @weather.update<br />
      if FPLE.offset_y &gt; 0 then @weather.update_fple end<br />
    end<br />
  end<br />
end<br />
#==============================<br />
# ** FPLE::Surface_Character<br />
#==============================<br />
module FPLE<br />
  class Surface_Character<br />
    #-----------------------------<br />
    # * Public Instance Variables<br />
    #-----------------------------<br />
    attr_accessor :character # Game_Event<br />
    attr_accessor :bitmap_set # Bitmap<br />
    attr_accessor :bitmap # Bitmap<br />
    attr_accessor :visible # Boolean<br />
    attr_accessor :opacity # Integer<br />
    attr_accessor :blend_type # Integer<br />
    attr_accessor :dx # Integer<br />
    attr_accessor :dy # Integer<br />
    attr_accessor :displayed # Boolean<br />
    attr_reader :spriteset # FPLE::Spriteset_Map<br />
    attr_reader :type # Integer<br />
    attr_reader :v_align # Integer<br />
    attr_reader :d_align # Integer<br />
    attr_reader :fit # Integer (0/1)<br />
    attr_reader :zoom # Integer (1024 &lt;=&gt; zoom = 1.0)<br />
    attr_reader :mirror # Integer (0/1) # [1.5]<br />
    #-----------------------------<br />
    # * Object Initialization<br />
    # param spriteset : FPLE::Spriteset_Map<br />
    # param character : Game_Event<br />
    #-----------------------------<br />
    def initialize(spriteset, character = nil)<br />
      @spriteset = spriteset<br />
      self.character = character<br />
      self.displayed = false<br />
      @need_refresh = false<br />
      @dx_old = 0<br />
      @dy_old = 0<br />
      @sx_old = -1<br />
      @sy_old = -1<br />
      @visible_old<br />
      @opacity_old<br />
      @blend_type_old<br />
      @sprite_temp = nil<br />
      @balloon_duration = 0<br />
      if character<br />
        @fit = character.fple_fit<br />
        @zoom = character.fple_zoom<br />
      else<br />
        @fit = 0<br />
        @zoom = 1024<br />
      end<br />
      @mirror = 0 # [1.5]<br />
      update<br />
    end<br />
    #-----------------------------<br />
    # * Dispose<br />
    #-----------------------------<br />
    def dispose<br />
      if @sprite_temp<br />
        @sprite_temp.dispose<br />
        @sprite_temp = nil<br />
      end<br />
      if bitmap_set then self.bitmap_set.dispose end<br />
      if bitmap then self.bitmap.dispose end<br />
    end<br />
    #-----------------------------<br />
    # * Get tile set image that includes the designated tile<br />
    # param tile_id : Integer<br />
    #-----------------------------<br />
    def tileset_bitmap(tile_id)<br />
      set_number = tile_id / 256<br />
      return Cache.system("TileB") if set_number == 0<br />
      return Cache.system("TileC") if set_number == 1<br />
      return Cache.system("TileD") if set_number == 2<br />
      return Cache.system("TileE") if set_number == 3<br />
      return nil<br />
    end<br />
    #-----------------------------<br />
    # * Frame Update<br />
    #-----------------------------<br />
    def update<br />
      update_bitmap<br />
      update_src_rect<br />
      update_position<br />
      update_other<br />
      update_balloon<br />
      setup_new_effect<br />
      if need_refresh? then force_render end<br />
    end<br />
    #-----------------------------<br />
    # * Update Transfer Origin Bitmap<br />
    #-----------------------------<br />
    def update_bitmap<br />
      if graphic_changed?<br />
        @tile_id = @character.tile_id<br />
        @character_name = @character.character_name<br />
        @character_index = @character.character_index<br />
        if @tile_id &gt; 0<br />
          set_tile_bitmap<br />
        else<br />
          set_character_bitmap<br />
        end<br />
        @need_refresh = true<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Determine if Graphic Changed<br />
    #-----------------------------<br />
    def graphic_changed?<br />
      @tile_id != character.tile_id ||<br />
      @character_name != character.character_name ||<br />
      @character_index != character.character_index<br />
    end<br />
    #-----------------------------<br />
    # * Set Tile Bitmap<br />
    #-----------------------------<br />
    def set_tile_bitmap<br />
      @sx = (@tile_id / 128 % 2 * 8 + @tile_id % 8) * 32;<br />
      @sy = @tile_id % 256 / 8 % 16 * 32;<br />
      self.bitmap_set = tileset_bitmap(@tile_id)<br />
      @cw = 32<br />
      @ch = 32<br />
      self.bitmap = Bitmap.new(@cw, @ch)<br />
    end<br />
    #-----------------------------<br />
    # * Set Character Bitmap<br />
    #-----------------------------<br />
    def set_character_bitmap<br />
      self.bitmap_set = Cache.character(@character_name)<br />
      sign = @character_name[/^[&#92;!&#92;&#36;]./]<br />
      if sign &amp;&amp; sign.include?('&#36;')<br />
        @cw = bitmap_set.width / 3<br />
        @ch = bitmap_set.height / 4<br />
      else<br />
        @cw = bitmap_set.width / 12<br />
        @ch = bitmap_set.height / 8<br />
      end<br />
      self.bitmap = Bitmap.new(@cw, @ch)<br />
    end<br />
    #-----------------------------<br />
    # * Update Transfer Origin Rectangle<br />
    #-----------------------------<br />
    def update_src_rect<br />
      if @tile_id == 0<br />
        index = character.character_index<br />
        pattern = character.pattern &lt; 3 ? character.pattern : 1<br />
        @sx = (index % 4 * 3 + pattern) * @cw<br />
        unless character.direction_fix<br />
          case &#36;game_player.direction<br />
          when 2<br />
            direction = 10 - character.direction<br />
          when 4<br />
            direction = 10 - FPLE::TURN_LEFT[(character.direction &gt;&gt; 1) - 1]<br />
          when 6<br />
            direction = FPLE::TURN_LEFT[(character.direction &gt;&gt; 1) - 1]<br />
          when 8<br />
            direction = character.direction<br />
          end<br />
        else<br />
          direction = character.direction<br />
        end<br />
        @sy = ((index &gt;&gt; 2 &lt;&lt; 2) + (direction - 2 &gt;&gt; 1)) * @ch<br />
      end<br />
      if @sx_old != @sx || @sy_old != @sy<br />
        return if @sx == @sx_old &amp;&amp; @sy == @sy_old &amp;&amp; !@bitmap_dirty<br />
        self.bitmap.clear<br />
        self.bitmap.blt(0, 0, bitmap_set, Rect.new(@sx, @sy, @cw, @ch))<br />
         @sx_old = @sx<br />
    @sy_old = @sy<br />
    @bitmap_dirty = false<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Update Position<br />
    #-----------------------------<br />
    def update_position<br />
      self.dx = (128 * character.real_x).to_i<br />
      self.dy = (128 * character.real_y).to_i<br />
    end<br />
    #-----------------------------<br />
    # * Update Other<br />
    #-----------------------------<br />
    def update_other<br />
      self.opacity = character.opacity<br />
      self.blend_type = character.blend_type<br />
      self.visible = !character.transparent<br />
    end<br />
    #-----------------------------<br />
    # * Set New Effect<br />
    #-----------------------------<br />
    def setup_new_effect<br />
      if character.animation_id &gt; 0<br />
        if displayed<br />
          unless @sprite_temp<br />
            # create a temporary sprite to launch animation<br />
            @sprite_temp = Sprite_Base.new(spriteset.viewport1)<br />
          end<br />
          coordinates = find_coordinates<br />
          if coordinates<br />
            @sprite_temp.x = coordinates[0]<br />
            @sprite_temp.y = coordinates[1]<br />
            animation = &#36;data_animations[character.animation_id]<br />
            @sprite_temp.start_animation(animation)<br />
          else<br />
            @sprite_temp.dispose<br />
            @sprite_temp = nil<br />
          end<br />
        end<br />
        character.animation_id = 0<br />
      end<br />
      if @sprite_temp<br />
        @sprite_temp.update<br />
        unless @sprite_temp.animation?<br />
          @sprite_temp.dispose<br />
          @sprite_temp = nil<br />
        end<br />
      end<br />
      if !@balloon_sprite &amp;&amp; character.balloon_id != 0<br />
        @balloon_id = character.balloon_id<br />
        start_balloon<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Determine if Changed<br />
    #-----------------------------<br />
    def need_refresh?<br />
      @need_refresh || @dx_old != dx || @dy_old != dy ||<br />
      @sx_old != @sx || @sy_old != @sy ||<br />
      @visible_old != visible || @opacity_old != opacity ||<br />
      @blend_type_old != blend_type<br />
    end<br />
    #-----------------------------<br />
    # * Force Render<br />
    #-----------------------------<br />
    def force_render<br />
      if displayed then &#36;game_temp.force_render = true end<br />
      @dx_old = dx<br />
      @dy_old = dy<br />
      @sx_old = @sx<br />
      @sy_old = @sy<br />
      @visible_old = visible<br />
      @opacity_old = opacity<br />
      @blend_type_old = blend_type<br />
      @need_refresh = false<br />
    end<br />
    #-----------------------------<br />
    # * Refresh FPLE attributes sepending on the relative frame of reference<br />
    # param direction : Integer<br />
    #-----------------------------<br />
def set_relative_attributes(direction)<br />
      # For 4-sided and 6-sided surfaces, we don't need to change attributes<br />
      # since all sides are rendered automatically<br />
      if character.fple_four_side<br />
        @type = 3 # Special identifier for 4-sided<br />
        @d_align = character.fple_d_align<br />
        @v_align = character.fple_v_align<br />
        @mirror = 0 # Could add logic for different mirror states per side if needed<br />
        return<br />
      elsif character.fple_six_side<br />
        @type = 4 # Special identifier for 6-sided<br />
        @d_align = character.fple_d_align<br />
        @v_align = character.fple_v_align<br />
        @mirror = 0 # Could add logic for different mirror states per side if needed<br />
        return<br />
      end<br />
      # Original logic for single surfaces<br />
      case direction<br />
      when 2<br />
        @type = character.fple_type<br />
        @d_align = 2 - character.fple_d_align<br />
        if character.fple_one_side<br />
          @mirror = 1<br />
          if type == 2 &amp;&amp; (&#36;game_player.x &lt;&lt; 7) - dx &lt;= 0<br />
            @mirror = 0<br />
          end<br />
        end<br />
      when 4<br />
        if character.fple_type &gt; 0<br />
          @type = 3 - character.fple_type<br />
        else<br />
          @type = 0<br />
        end<br />
        if character.fple_type &lt; 2<br />
          @d_align = character.fple_d_align<br />
        elsif character.fple_type == 2<br />
          @d_align = 2 - character.fple_d_align<br />
        end<br />
        if character.fple_one_side<br />
          @mirror = 1<br />
          if type == 2 &amp;&amp; (&#36;game_player.y &lt;&lt; 7) - dy &gt; 0<br />
            @mirror = 0<br />
          end<br />
        end<br />
      when 6<br />
        if character.fple_type &gt; 0<br />
          @type = 3 - character.fple_type<br />
        else<br />
          @type = 0<br />
        end<br />
        if character.fple_type &lt; 2<br />
          @d_align = 2 - character.fple_d_align<br />
        elsif character.fple_type == 2<br />
          @d_align = character.fple_d_align<br />
        end<br />
        if character.fple_one_side<br />
          @mirror = 0<br />
          if type == 2 &amp;&amp; (&#36;game_player.y &lt;&lt; 7) - dy &lt; 0<br />
            @mirror = 1<br />
          end<br />
        end<br />
      when 8<br />
        @type = character.fple_type<br />
        @d_align = character.fple_d_align<br />
        if character.fple_one_side<br />
          @mirror = 0<br />
          if type == 2 &amp;&amp; (&#36;game_player.x &lt;&lt; 7) - dx &gt;= 0<br />
            @mirror = 1<br />
          end<br />
        end<br />
      end<br />
      @v_align = character.fple_v_align<br />
    end<br />
    #-----------------------------<br />
    # * Calculate screen coordinates to display animations<br />
    # return Array[2]&lt;Integer&gt;<br />
    #-----------------------------<br />
  def find_coordinates<br />
      direction = &#36;game_player.direction<br />
      case direction<br />
      when 2<br />
        y = dy - (&#36;game_player.y &lt;&lt; 7)<br />
        x = (&#36;game_player.x &lt;&lt; 7) - dx<br />
      when 4<br />
        y = (&#36;game_player.x &lt;&lt; 7) - dx<br />
        x = (&#36;game_player.y &lt;&lt; 7) - dy<br />
      when 6<br />
        y = dx - (&#36;game_player.x &lt;&lt; 7)<br />
        x = dy - (&#36;game_player.y &lt;&lt; 7)<br />
      when 8<br />
        y = (&#36;game_player.y &lt;&lt; 7) - dy<br />
        x = dx - (&#36;game_player.x &lt;&lt; 7)<br />
      end<br />
      if y == 0 then return nil end<br />
      offset_x = 0<br />
      offset_y = 0<br />
      if character.fple_v_align != 1<br />
        x1_proj = 272 + (272 * x - (136 &lt;&lt; 7)) / y<br />
        x2_proj = 272 + (272 * x + (136 &lt;&lt; 7)) / y<br />
        offset_x = x2_proj - x1_proj &gt;&gt; 1<br />
        offset_y = offset_x<br />
        if bitmap<br />
          offset_x -= (bitmap.width &gt;&gt; 1)<br />
          offset_y -= (bitmap.height &gt;&gt; 1)<br />
        end<br />
      end<br />
      x_proj = 272 + (272 * x) / y<br />
      y_proj = ((544 * y) - (272 &lt;&lt; 7)) / (y &lt;&lt; 1)<br />
      if character.fple_v_align == 0<br />
        y_proj -= offset_y<br />
      elsif character.fple_v_align == 2<br />
        y_proj += offset_y<br />
      end<br />
      return [x_proj, y_proj]<br />
    end<br />
    #-----------------------------<br />
    # * Start Balloon Icon Display<br />
    #-----------------------------<br />
    def start_balloon<br />
      dispose_balloon<br />
      @balloon_duration = 8 * balloon_speed + balloon_wait<br />
      @balloon_sprite = ::Sprite.new(spriteset.viewport1)<br />
      @balloon_sprite.bitmap = Cache.system("Balloon")<br />
      @balloon_sprite.ox = -16<br />
      @balloon_sprite.oy = +128<br />
      update_balloon<br />
    end<br />
    #-----------------------------<br />
    # * Dispose of Balloon Icon<br />
    #-----------------------------<br />
    def dispose_balloon<br />
      if @balloon_sprite<br />
        @balloon_sprite.dispose<br />
        @balloon_sprite = nil<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Update Balloon Icon<br />
    #-----------------------------<br />
    def update_balloon<br />
      if @balloon_duration &gt; 0<br />
        @balloon_duration -= 1<br />
        if @balloon_duration &gt; 0<br />
          coordinates = find_coordinates<br />
          if coordinates<br />
            @balloon_sprite.x = coordinates[0]<br />
            @balloon_sprite.y = coordinates[1]<br />
            @balloon_sprite.z = 9999<br />
            sx = balloon_frame_index * 32<br />
            sy = (@balloon_id - 1) * 32<br />
            @balloon_sprite.src_rect.set(sx, sy, 32, 32)<br />
          else<br />
            end_balloon<br />
          end<br />
        else<br />
          end_balloon<br />
        end<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * End Balloon Icon<br />
    #-----------------------------<br />
    def end_balloon<br />
      dispose_balloon<br />
      character.balloon_id = 0<br />
    end<br />
    #-----------------------------<br />
    # * Balloon Icon Display Speed<br />
    #-----------------------------<br />
    def balloon_speed<br />
      return 8<br />
    end<br />
    #-----------------------------<br />
    # * Wait Time for Last Frame of Balloon<br />
    #-----------------------------<br />
    def balloon_wait<br />
      return 12<br />
    end<br />
    #-----------------------------<br />
    # * Frame Number of Balloon Icon<br />
    #-----------------------------<br />
    def balloon_frame_index<br />
      return 7 - [(@balloon_duration - balloon_wait) / balloon_speed, 0].max<br />
    end<br />
  end<br />
end<br />
<br />
#==============================<br />
# ** Scene_Map<br />
#==============================<br />
class Scene_Map &lt; Scene_Base<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias create_spriteset_fple create_spriteset<br />
    alias perform_transfer_fple perform_transfer<br />
    alias post_transfer_fple post_transfer<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Create Sprite Set<br />
  #-----------------------------<br />
  def create_spriteset<br />
    if &#36;game_system.fple<br />
      @spriteset = FPLE::Spriteset_Map.new<br />
    else<br />
      create_spriteset_fple<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Player Transfer Processing<br />
  #-----------------------------<br />
  def perform_transfer<br />
    @exec_transfer = &#36;game_player.transfer?<br />
    @fple_old = &#36;game_system.fple<br />
    perform_transfer_fple<br />
  end<br />
  #-----------------------------<br />
  # * Post Processing for Transferring Player<br />
  #-----------------------------<br />
  def post_transfer<br />
    if @exec_transfer &amp;&amp; @fple_old != &#36;game_system.fple<br />
      @spriteset.dispose<br />
      create_spriteset<br />
    end<br />
    if &#36;game_system.fple<br />
      &#36;game_temp.force_render = true<br />
    end<br />
    post_transfer_fple<br />
  end<br />
end</code></div></div><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** FPLE Background Picture Addon - Enhanced<br />
#v.1.5 old, now upgraded to v.1.8 using Claude.AI by 5Brainplay.<br />
#==============================================================================<br />
# This addon creates a background picture that renders behind all FPLE surfaces<br />
# but in front of the engine's default background to prevent color bleeding.<br />
# The background now positions itself at VIEW_DISTANCE + 1 for proper depth.<br />
#==============================================================================<br />
<br />
module FPLE<br />
  #--------------------------------------------------------------------------<br />
  # * Background Picture Configuration<br />
  #--------------------------------------------------------------------------<br />
  BACKGROUND_ENABLED = false      # Enable/disable background picture<br />
  BACKGROUND_COLOR = Color.new(115, 190, 215, 255)  # Default color (R,G,B,A)<br />
  BACKGROUND_PICTURE_FILE = nil  # Optional: use "filename" for custom image<br />
  BACKGROUND_Z_DEPTH = -999    # Z-depth (negative = behind everything)<br />
end<br />
<br />
#==============================================================================<br />
# ** FPLE Core - Modified<br />
#==============================================================================<br />
module FPLE<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased initialization method<br />
  #--------------------------------------------------------------------------<br />
  class &lt;&lt; self<br />
    unless @background_addon_aliased<br />
      alias initialize_fple_background initialize_fple<br />
      @background_addon_aliased = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Initialize with background<br />
  #--------------------------------------------------------------------------<br />
  def self.initialize_fple(spriteset, viewport)<br />
    initialize_fple_background(spriteset, viewport)<br />
    if BACKGROUND_ENABLED<br />
      create_background_picture(viewport)<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create background picture with view distance integration<br />
  #--------------------------------------------------------------------------<br />
  def self.create_background_picture(viewport)<br />
    @background_sprite = Sprite.new(viewport)<br />
    @background_sprite.z = BACKGROUND_Z_DEPTH<br />
    <br />
    if BACKGROUND_PICTURE_FILE &amp;&amp; FileTest.exist?("Graphics/Pictures/#{BACKGROUND_PICTURE_FILE}.png")<br />
      # Use custom image file<br />
      @background_sprite.bitmap = Cache.picture(BACKGROUND_PICTURE_FILE)<br />
    else<br />
      # Create solid color background<br />
      @background_sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height)<br />
      @background_sprite.bitmap.fill_rect(0, 0, Graphics.width, Graphics.height, BACKGROUND_COLOR)<br />
    end<br />
    <br />
    # Position behind everything but visible<br />
    @background_sprite.x = 0<br />
    @background_sprite.y = 0<br />
    <br />
    # Add background surface to the surfaces array for proper depth rendering<br />
    create_background_surface<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create background surface at VIEW_DISTANCE + 1<br />
  #--------------------------------------------------------------------------<br />
  def self.create_background_surface<br />
    # Calculate the distance to render the background at (VIEW_DISTANCE + 1)<br />
    background_distance = (&#36;game_system.fple_view_distance + 1) &lt;&lt; 7<br />
    <br />
    # Create a background surface that will be processed by the 3D engine<br />
    @background_surface = [<br />
      0,                          # texture_id (0 = no texture, use solid color)<br />
      background_distance,        # dy (depth distance)<br />
      0,                          # dx (horizontal offset)<br />
      6,                          # type (6 = background plane, custom type)<br />
      0,                          # secondary texture<br />
      0,                          # z-order placeholder<br />
      0,                          # textureset_id<br />
      8,                          # textureset_width<br />
      BACKGROUND_COLOR.red,       # red component<br />
      BACKGROUND_COLOR.green,     # green component<br />
      BACKGROUND_COLOR.blue,      # blue component<br />
      BACKGROUND_COLOR.alpha      # alpha component<br />
    ]<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Add background surface to game map surfaces<br />
  #--------------------------------------------------------------------------<br />
  def self.add_background_to_surfaces<br />
    return unless BACKGROUND_ENABLED &amp;&amp; @background_surface<br />
    <br />
    # Calculate proper z-depth for background<br />
    distance = (&#36;game_system.fple_view_distance) &lt;&lt; 1<br />
    @background_surface[5] = distance &lt;&lt; 5  # Set z-order<br />
    <br />
    # Add background surface to the main surfaces array if not already present<br />
    unless &#36;game_map.surfaces.any? { |surface| surface[3] == 6 }<br />
      &#36;game_map.surfaces.push(@background_surface.dup)<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Aliased dispose method<br />
  #--------------------------------------------------------------------------<br />
  class &lt;&lt; self<br />
    unless @dispose_background_aliased<br />
      alias dispose_background dispose<br />
      @dispose_background_aliased = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Dispose with background cleanup<br />
  #--------------------------------------------------------------------------<br />
  def self.dispose<br />
    dispose_background<br />
    if @background_sprite<br />
      @background_sprite.dispose<br />
      @background_sprite = nil<br />
    end<br />
    @background_surface = nil<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Update background (called during movement/rotation)<br />
  #--------------------------------------------------------------------------<br />
  def self.update_background<br />
    return unless @background_surface &amp;&amp; BACKGROUND_ENABLED<br />
    <br />
    # Update the background distance based on current view distance<br />
    background_distance = (&#36;game_system.fple_view_distance) &lt;&lt; 7<br />
    @background_surface[1] = background_distance<br />
    <br />
    # Update z-order<br />
    distance = (&#36;game_system.fple_view_distance) &lt;&lt; 1<br />
    @background_surface[5] = distance &lt;&lt; 5<br />
    <br />
    # Add parallax effects if desired<br />
    if @angle != 0<br />
      # Slight horizontal shift based on rotation<br />
      @background_surface[2] = (@angle * 2)  # Adjust multiplier as needed<br />
    else<br />
      @background_surface[2] = 0<br />
    end<br />
    <br />
    # Adjust for movement offsets if desired (subtle parallax)<br />
    # @background_surface[2] += @offset_x / 8<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Aliased update method<br />
  #--------------------------------------------------------------------------<br />
  class &lt;&lt; self<br />
    unless @update_background_aliased<br />
      alias update_fple_background update<br />
      @update_background_aliased = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Update with background<br />
  #--------------------------------------------------------------------------<br />
  def self.update<br />
    update_fple_background<br />
    if BACKGROUND_ENABLED<br />
      update_background<br />
      add_background_to_surfaces<br />
    end<br />
  end<br />
end<br />
<br />
#==============================================================================<br />
# ** Game_Map - Background Integration<br />
#==============================================================================<br />
class Game_Map<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased refresh_surfaces method<br />
  #--------------------------------------------------------------------------<br />
  unless @background_surfaces_aliased<br />
    alias refresh_surfaces_background refresh_surfaces<br />
    @background_surfaces_aliased = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Refresh surfaces with background integration<br />
  #--------------------------------------------------------------------------<br />
  def refresh_surfaces<br />
    refresh_surfaces_background<br />
      surfaces.sort! { |a, b| b[5] - a[5] } if surfaces.any? { |s| s[3] == 6 }<br />
  end<br />
end<br />
<br />
#==============================================================================<br />
# ** Game_Interpreter - Script Commands<br />
#==============================================================================<br />
class Game_Interpreter<br />
  #--------------------------------------------------------------------------<br />
  # * Change FPLE Background Color<br />
  #--------------------------------------------------------------------------<br />
  def change_fple_background_color(red, green, blue, alpha = 255)<br />
    return unless &#36;game_system.fple &amp;&amp; FPLE::BACKGROUND_ENABLED<br />
    <br />
    # Update the background surface color<br />
    if FPLE.instance_variable_get(:@background_surface)<br />
      surface = FPLE.instance_variable_get(:@background_surface)<br />
      surface[8] = red<br />
      surface[9] = green<br />
      surface[10] = blue<br />
      surface[11] = alpha<br />
    end<br />
    <br />
    # Also update the sprite for immediate visual feedback<br />
    if FPLE.instance_variable_get(:@background_sprite)<br />
      sprite = FPLE.instance_variable_get(:@background_sprite)<br />
      color = Color.new(red, green, blue, alpha)<br />
      sprite.bitmap.fill_rect(0, 0, Graphics.width, Graphics.height, color)<br />
    end<br />
    <br />
    &#36;game_temp.force_render = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Change FPLE Background Picture<br />
  #--------------------------------------------------------------------------<br />
  def change_fple_background_picture(filename)<br />
    return unless &#36;game_system.fple &amp;&amp; FPLE::BACKGROUND_ENABLED<br />
    <br />
    if FPLE.instance_variable_get(:@background_sprite)<br />
      sprite = FPLE.instance_variable_get(:@background_sprite)<br />
      sprite.bitmap.dispose if sprite.bitmap<br />
      <br />
      if filename &amp;&amp; FileTest.exist?("Graphics/Pictures/#{filename}.png")<br />
        sprite.bitmap = Cache.picture(filename)<br />
        # When using a picture, set surface type to use texture instead of color<br />
        if FPLE.instance_variable_get(:@background_surface)<br />
          surface = FPLE.instance_variable_get(:@background_surface)<br />
          surface[0] = 1  # Enable texture rendering<br />
        end<br />
      else<br />
        # Fallback to solid color<br />
        sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height)<br />
        sprite.bitmap.fill_rect(0, 0, Graphics.width, Graphics.height, FPLE::BACKGROUND_COLOR)<br />
        # Reset to color mode<br />
        if FPLE.instance_variable_get(:@background_surface)<br />
          surface = FPLE.instance_variable_get(:@background_surface)<br />
          surface[0] = 0  # Disable texture, use color<br />
        end<br />
      end<br />
    end<br />
    <br />
    &#36;game_temp.force_render = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Toggle FPLE Background<br />
  #--------------------------------------------------------------------------<br />
  def toggle_fple_background(enabled)<br />
    return unless &#36;game_system.fple<br />
    <br />
    if FPLE.instance_variable_get(:@background_sprite)<br />
      sprite = FPLE.instance_variable_get(:@background_sprite)<br />
      sprite.visible = enabled<br />
    end<br />
    <br />
    # Remove or add background surface based on enabled state<br />
    if enabled<br />
      FPLE.add_background_to_surfaces<br />
    else<br />
      &#36;game_map.surfaces.reject! { |surface| surface[3] == 6 }<br />
    end<br />
    <br />
    &#36;game_temp.force_render = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Update Background Distance (call when VIEW_DISTANCE changes)<br />
  #--------------------------------------------------------------------------<br />
  def update_background_distance<br />
    return unless &#36;game_system.fple &amp;&amp; FPLE::BACKGROUND_ENABLED<br />
    <br />
    if FPLE.instance_variable_get(:@background_surface)<br />
      FPLE.update_background<br />
      &#36;game_temp.force_render = true<br />
    end<br />
  end<br />
end<br />
<br />
#==============================================================================<br />
# ** Game_Temp - Background Integration<br />
#==============================================================================<br />
class Game_Temp<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased set_view method to update background distance<br />
  #--------------------------------------------------------------------------<br />
  unless @background_view_aliased<br />
    alias set_view_background set_view<br />
    @background_view_aliased = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Set view distance with background update<br />
  #--------------------------------------------------------------------------<br />
  def set_view(distance)<br />
    set_view_background(distance)<br />
    <br />
    # Update background distance when view distance changes<br />
    if &#36;game_system.fple &amp;&amp; FPLE::BACKGROUND_ENABLED<br />
      FPLE.update_background<br />
    end<br />
  end<br />
end<br />
<br />
#==============================================================================<br />
# ** Usage Instructions<br />
#==============================================================================<br />
# Place this script below the main FPLE script but above Main.<br />
#<br />
# Configuration:<br />
# - BACKGROUND_ENABLED: Set to true/false to enable/disable<br />
# - BACKGROUND_COLOR: Set the RGB color (0-255 for each value)  <br />
# - BACKGROUND_PICTURE_FILE: Optional - use a picture file instead of solid color<br />
# - BACKGROUND_Z_DEPTH: Z-depth value (negative = behind surfaces)<br />
#<br />
# The background will automatically render at VIEW_DISTANCE + 1, providing<br />
# a backdrop that appears behind all game surfaces but maintains proper depth.<br />
#<br />
# Script Commands (use in events):<br />
# - change_fple_background_color(255, 0, 0)    # Change to red<br />
# - change_fple_background_picture("sunset")   # Use Graphics/Pictures/sunset.png  <br />
# - toggle_fple_background(false)              # Hide background<br />
# - toggle_fple_background(true)               # Show background<br />
# - update_background_distance                 # Refresh after VIEW_DISTANCE changes<br />
#==============================================================================</code></div></div><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#===============================================================================<br />
# FPLE Ground Tile Swap Addon v1.1<br />
# v.1.5 old, now upgraded to v.1.8 using Claude.AI by 5Brainplay.<br />
# Author: Assistant<br />
#===============================================================================<br />
# This addon allows swapping ground tiles in FPLE maps during gameplay.<br />
# Place this script below the main FPLE script but above "Main"<br />
#<br />
# Features:<br />
# - Swap ground tiles at specific coordinates<br />
# - Batch swap multiple tiles<br />
# - Restore original tiles<br />
# - Event-based tile swapping<br />
# - Animated tile transitions (optional)<br />
# - Region-based ground tile swapping<br />
# - Animated region tiles<br />
#<br />
# Usage Examples:<br />
# &#36;game_map.swap_ground_tile(x, y, new_texture_id)<br />
# &#36;game_map.restore_ground_tile(x, y)<br />
# &#36;game_map.batch_swap_ground_tiles([[x1, y1, texture1], [x2, y2, texture2]])<br />
# &#36;game_map.swap_region_ground_tiles(region_id, texture_id)<br />
#<br />
# Event Commands:<br />
# In event "Script..." command:<br />
# swap_ground(x, y, texture_id)<br />
# restore_ground(x, y)<br />
# swap_region_ground(region_id, texture_id)<br />
# animate_region_ground(region_id, base_texture_id)<br />
#===============================================================================<br />
#==============================================================================<br />
# ** Game_Map - Ground Tile Swapping Extensions<br />
#==============================================================================<br />
class Game_Map<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased methods<br />
  #--------------------------------------------------------------------------<br />
  unless @already_aliased_ground_swap<br />
    alias initialize_ground_swap initialize<br />
    alias setup_ground_swap setup<br />
    @already_aliased_ground_swap = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Public Instance Variables<br />
  #--------------------------------------------------------------------------<br />
  attr_accessor :original_ground_tiles  # Hash to store original tile data<br />
  attr_accessor :swapped_ground_tiles   # Hash to track swapped tiles<br />
  attr_accessor :animated_ground_tiles  # Hash to store animation data<br />
  attr_accessor :ground_animation_timer # Integer for frame counting<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Object Initialization<br />
  #--------------------------------------------------------------------------<br />
  def initialize<br />
    initialize_ground_swap<br />
    @original_ground_tiles = {}<br />
    @swapped_ground_tiles = {}<br />
    @animated_ground_tiles = {}<br />
    @ground_animation_timer = 0<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Setup<br />
  #--------------------------------------------------------------------------<br />
  def setup(map_id)<br />
    setup_ground_swap(map_id)<br />
    @original_ground_tiles = {}<br />
    @swapped_ground_tiles = {}<br />
    @animated_ground_tiles = {}<br />
    @ground_animation_timer = 0<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Swap Ground Tile at Specific Coordinates<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate  <br />
  # param new_texture_id : Integer - New ground texture ID<br />
  # param animate : Boolean - Whether to animate the transition (optional)<br />
  #--------------------------------------------------------------------------<br />
  def swap_ground_tile(x, y, new_texture_id, animate = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless valid_coordinates?(x, y)<br />
    <br />
    key = [x, y]<br />
    <br />
    # Store original tile data if not already stored<br />
    unless @original_ground_tiles.has_key?(key)<br />
      original_data = @fple_map.get_data(x, y).dup<br />
      @original_ground_tiles[key] = original_data<br />
    end<br />
    <br />
    # Use FPLE's proper method to change ground texture<br />
    if @fple_map.respond_to?(:change_ground)<br />
      @fple_map.change_ground(x, y, new_texture_id)<br />
    elsif @fple_map.respond_to?(:set_ground_tile)<br />
      @fple_map.set_ground_tile(x, y, new_texture_id)<br />
    else<br />
      # Fallback: try to modify the data structure directly<br />
      current_data = @fple_map.get_data(x, y)<br />
      if current_data &amp;&amp; current_data.size &gt; 1<br />
        current_data[1] = new_texture_id<br />
      else<br />
        return false<br />
      end<br />
    end<br />
    <br />
    @swapped_ground_tiles[key] = new_texture_id<br />
    <br />
    # Remove from animated tiles when doing a simple swap<br />
    @animated_ground_tiles.delete(key)<br />
    <br />
    # Trigger visual update<br />
    if animate<br />
      animate_tile_swap(x, y)<br />
    else<br />
      force_surface_refresh<br />
    end<br />
    <br />
    return true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Animated Ground Tile (cycles through next 3 tiles)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate  <br />
  # param base_texture_id : Integer - Base texture ID (will use this +1, +2, +3)<br />
  # param frame_duration : Integer - Frames to wait between texture changes<br />
  # param animate : Boolean - Whether to animate the initial transition<br />
  #--------------------------------------------------------------------------<br />
  def create_animated_ground_tile(x, y, base_texture_id, frame_duration = 30, animate = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless valid_coordinates?(x, y)<br />
    <br />
    key = [x, y]<br />
    <br />
    # Store original tile data if not already stored<br />
    unless @original_ground_tiles.has_key?(key)<br />
      original_data = @fple_map.get_data(x, y).dup<br />
      @original_ground_tiles[key] = original_data<br />
    end<br />
    <br />
    # Setup animation data<br />
    animation_data = {<br />
      :frames =&gt; [base_texture_id, base_texture_id + 1, base_texture_id + 2],<br />
      :current_frame =&gt; 0,<br />
      :frame_duration =&gt; frame_duration,<br />
      :frame_counter =&gt; 0<br />
    }<br />
    <br />
    @animated_ground_tiles[key] = animation_data<br />
    @swapped_ground_tiles[key] = base_texture_id<br />
    <br />
    # Set initial texture<br />
    current_data = @fple_map.get_data(x, y)<br />
    if current_data &amp;&amp; current_data.size &gt; 1<br />
      current_data[1] = base_texture_id<br />
      <br />
      # Trigger visual update<br />
      if animate<br />
        animate_tile_swap(x, y)<br />
      else<br />
        force_surface_refresh<br />
      end<br />
      <br />
      return true<br />
    end<br />
    <br />
    return false<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore Original Ground Tile<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  #--------------------------------------------------------------------------<br />
  def restore_ground_tile(x, y)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless valid_coordinates?(x, y)<br />
    <br />
    key = [x, y]<br />
    <br />
    if @original_ground_tiles.has_key?(key)<br />
      # Restore original data<br />
      original_data = @original_ground_tiles[key]<br />
      current_data = @fple_map.get_data(x, y)<br />
      <br />
      if current_data &amp;&amp; original_data<br />
        current_data[1] = original_data[1]  # Restore ground texture<br />
        @swapped_ground_tiles.delete(key)<br />
        @animated_ground_tiles.delete(key)  # Remove animation data<br />
        <br />
        force_surface_refresh<br />
        return true<br />
      end<br />
    end<br />
    <br />
    return false<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Batch Swap Multiple Ground Tiles<br />
  # param tile_data : Array&lt;Array&gt; - [[x, y, texture_id], ...]<br />
  #--------------------------------------------------------------------------<br />
  def batch_swap_ground_tiles(tile_data)<br />
    return unless is_fple? &amp;&amp; tile_data.is_a?(Array)<br />
    <br />
    success_count = 0<br />
    tile_data.each do |data|<br />
      next unless data.is_a?(Array) &amp;&amp; data.size &gt;= 3<br />
      x, y, texture_id = data[0], data[1], data[2]<br />
      success_count += 1 if swap_ground_tile(x, y, texture_id, false)<br />
    end<br />
    <br />
    force_surface_refresh if success_count &gt; 0<br />
    return success_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore All Swapped Ground Tiles<br />
  #--------------------------------------------------------------------------<br />
  def restore_all_ground_tiles<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    <br />
    restored_count = 0<br />
    @swapped_ground_tiles.keys.each do |key|<br />
      x, y = key[0], key[1]<br />
      restored_count += 1 if restore_ground_tile(x, y)<br />
    end<br />
    <br />
    force_surface_refresh if restored_count &gt; 0<br />
    return restored_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Swap All Ground Tiles in a Specific Region<br />
  # param region_id : Integer - Region ID to target (1-63, or 0 for no region)<br />
  # param new_texture_id : Integer - New ground texture ID for all tiles in region<br />
  # param animate : Boolean - Whether to animate the transitions (optional)<br />
  # param exclude_events : Boolean - Whether to skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def swap_region_ground_tiles(region_id, new_texture_id, animate = false, exclude_events = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless region_id &gt;= 0 &amp;&amp; region_id &lt;= 63<br />
    <br />
    success_count = 0<br />
    <br />
    # Loop through all tiles in the map<br />
    (0...width).each do |x|<br />
      (0...height).each do |y|<br />
        # Check if this tile has the target region ID<br />
        if region_id(x, y) == region_id<br />
          # Skip tiles with events if requested<br />
          if exclude_events &amp;&amp; events_xy(x, y).any?<br />
            next<br />
          end<br />
          <br />
          # Swap the ground tile<br />
          if swap_ground_tile(x, y, new_texture_id, false)<br />
            success_count += 1<br />
          end<br />
        end<br />
      end<br />
    end<br />
    <br />
    # Handle animation/refresh after all swaps are done<br />
    if success_count &gt; 0<br />
      if animate<br />
        # Create a region-wide flash effect<br />
        &#36;game_map.screen.start_flash(Color.new(255, 255, 255, 80), 15)<br />
      end<br />
      force_surface_refresh<br />
    end<br />
    <br />
    return success_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Animated Ground Tiles for Entire Region<br />
  # param region_id : Integer - Region ID to target (1-63, or 0 for no region)<br />
  # param base_texture_id : Integer - Base texture ID (will use this +1, +2)<br />
  # param frame_duration : Integer - Frames to wait between texture changes<br />
  # param animate : Boolean - Whether to animate the initial transition<br />
  # param exclude_events : Boolean - Whether to skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def animate_region_ground_tiles(region_id, base_texture_id, frame_duration = 30, animate = false, exclude_events = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless region_id &gt;= 0 &amp;&amp; region_id &lt;= 63<br />
    <br />
    success_count = 0<br />
    <br />
    # Loop through all tiles in the map<br />
    (0...width).each do |x|<br />
      (0...height).each do |y|<br />
        # Check if this tile has the target region ID<br />
        if region_id(x, y) == region_id<br />
          # Skip tiles with events if requested<br />
          if exclude_events &amp;&amp; events_xy(x, y).any?<br />
            next<br />
          end<br />
          <br />
          # Create animated ground tile<br />
          if create_animated_ground_tile(x, y, base_texture_id, frame_duration, false)<br />
            success_count += 1<br />
          end<br />
        end<br />
      end<br />
    end<br />
    <br />
    # Handle animation/refresh after all animations are set up<br />
    if success_count &gt; 0<br />
      if animate<br />
        # Create a region-wide flash effect<br />
        &#36;game_map.screen.start_flash(Color.new(200, 255, 200, 100), 20)<br />
      end<br />
      force_surface_refresh<br />
    end<br />
    <br />
    return success_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore All Ground Tiles in a Specific Region<br />
  # param region_id : Integer - Region ID to target (1-63, or 0 for no region)<br />
  # param exclude_events : Boolean - Whether to skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def restore_region_ground_tiles(region_id, exclude_events = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless region_id &gt;= 0 &amp;&amp; region_id &lt;= 63<br />
    <br />
    restored_count = 0<br />
    <br />
    # Loop through all swapped tiles and restore those in the target region<br />
    @swapped_ground_tiles.keys.each do |key|<br />
      x, y = key[0], key[1]<br />
      <br />
      # Check if this tile is in the target region<br />
      if region_id(x, y) == region_id<br />
        # Skip tiles with events if requested<br />
        if exclude_events &amp;&amp; events_xy(x, y).any?<br />
          next<br />
        end<br />
        <br />
        # Restore the ground tile<br />
        if restore_ground_tile(x, y)<br />
          restored_count += 1<br />
        end<br />
      end<br />
    end<br />
    <br />
    force_surface_refresh if restored_count &gt; 0<br />
    return restored_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Check if Ground Tile is Swapped<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def ground_tile_swapped?(x, y)<br />
    return @swapped_ground_tiles.has_key?([x, y])<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Check if Ground Tile is Animated<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def ground_tile_animated?(x, y)<br />
    return @animated_ground_tiles.has_key?([x, y])<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Update Ground Tile Animations (call this from Scene_Map update)<br />
  #--------------------------------------------------------------------------<br />
  def update_ground_animations<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return if @animated_ground_tiles.empty?<br />
    <br />
    @ground_animation_timer += 1<br />
    needs_refresh = false<br />
    <br />
    @animated_ground_tiles.each do |key, animation_data|<br />
      animation_data[:frame_counter] += 1<br />
      <br />
      if animation_data[:frame_counter] &gt;= animation_data[:frame_duration]<br />
        # Reset counter and advance frame<br />
        animation_data[:frame_counter] = 0<br />
        animation_data[:current_frame] = (animation_data[:current_frame] + 1) % animation_data[:frames].size<br />
        <br />
        # Update the tile texture using proper FPLE methods<br />
        x, y = key[0], key[1]<br />
        new_texture_id = animation_data[:frames][animation_data[:current_frame]]<br />
        <br />
        # Use FPLE's proper method to change ground texture<br />
        success = false<br />
        if @fple_map.respond_to?(:change_ground)<br />
          @fple_map.change_ground(x, y, new_texture_id)<br />
          success = true<br />
        elsif @fple_map.respond_to?(:set_ground_tile)<br />
          @fple_map.set_ground_tile(x, y, new_texture_id)<br />
          success = true<br />
        else<br />
          # Fallback: try to modify the data structure directly<br />
          current_data = @fple_map.get_data(x, y)<br />
          if current_data &amp;&amp; current_data.is_a?(Array) &amp;&amp; current_data.size &gt; 1<br />
            current_data[1] = new_texture_id<br />
            success = true<br />
          end<br />
        end<br />
        <br />
        if success<br />
          @swapped_ground_tiles[key] = new_texture_id<br />
          needs_refresh = true<br />
        end<br />
      end<br />
    end<br />
    <br />
    force_surface_refresh if needs_refresh<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Get Current Ground Texture ID<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Integer<br />
  #--------------------------------------------------------------------------<br />
  def get_ground_texture_id(x, y)<br />
    return nil unless valid_coordinates?(x, y) &amp;&amp; @fple_map<br />
    <br />
    tile_data = @fple_map.get_data(x, y)<br />
    return tile_data ? tile_data[1] : nil<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Get Original Ground Texture ID<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Integer<br />
  #--------------------------------------------------------------------------<br />
  def get_original_ground_texture_id(x, y)<br />
    key = [x, y]<br />
    if @original_ground_tiles.has_key?(key)<br />
      return @original_ground_tiles[key][1]<br />
    else<br />
      return get_ground_texture_id(x, y)<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Animate Tile Swap (Simple fade effect)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  #--------------------------------------------------------------------------<br />
  def animate_tile_swap(x, y)<br />
    # This is a placeholder for animation<br />
    # In a full implementation, you might want to:<br />
    # - Create temporary sprites for transition effects<br />
    # - Use screen flashes or particle effects<br />
    # - Gradually fade between old and new textures<br />
    <br />
    &#36;game_map.screen.start_flash(Color.new(255, 255, 255, 60), 10)<br />
    force_surface_refresh<br />
  end<br />
  <br />
  private<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Validate Coordinates<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def valid_coordinates?(x, y)<br />
    return x &gt;= 0 &amp;&amp; x &lt; width &amp;&amp; y &gt;= 0 &amp;&amp; y &lt; height<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Force Surface Refresh<br />
  #--------------------------------------------------------------------------<br />
  def force_surface_refresh<br />
    &#36;game_temp.force_render = true if &#36;game_temp<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Game_Interpreter - Event Commands for Ground Swapping<br />
#==============================================================================<br />
class Game_Interpreter<br />
  #--------------------------------------------------------------------------<br />
  # * Swap Ground Tile (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # param texture_id : Integer - New ground texture ID<br />
  #--------------------------------------------------------------------------<br />
  def swap_ground(x, y, texture_id)<br />
    &#36;game_map.swap_ground_tile(x, y, texture_id, true)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Animated Ground Tile (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # param base_texture_id : Integer - Base texture ID (uses this +1, +2)<br />
  # param frame_duration : Integer - Frames between animation changes (default: 30)<br />
  #--------------------------------------------------------------------------<br />
  def animate_ground(x, y, base_texture_id, frame_duration = 30)<br />
    &#36;game_map.create_animated_ground_tile(x, y, base_texture_id, frame_duration, true)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore Ground Tile (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  #--------------------------------------------------------------------------<br />
  def restore_ground(x, y)<br />
    &#36;game_map.restore_ground_tile(x, y)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Batch Swap Ground Tiles (Event Command)<br />
  # param tile_array : Array&lt;Array&gt; - [[x, y, texture_id], ...]<br />
  #--------------------------------------------------------------------------<br />
  def batch_swap_ground(tile_array)<br />
    &#36;game_map.batch_swap_ground_tiles(tile_array)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore All Ground Tiles (Event Command)<br />
  #--------------------------------------------------------------------------<br />
  def restore_all_ground<br />
    &#36;game_map.restore_all_ground_tiles<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Swap All Ground Tiles in Region (Event Command)<br />
  # param region_id : Integer - Region ID to target (1-63, or 0 for no region)<br />
  # param texture_id : Integer - New ground texture ID<br />
  # param exclude_events : Boolean - Skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def swap_region_ground(region_id, texture_id, exclude_events = false)<br />
    &#36;game_map.swap_region_ground_tiles(region_id, texture_id, true, exclude_events)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Animated Ground Tiles for Region (Event Command)<br />
  # param region_id : Integer - Region ID to target<br />
  # param base_texture_id : Integer - Base texture ID (uses this +1, +2)<br />
  # param frame_duration : Integer - Frames between animation changes (default: 30)<br />
  # param exclude_events : Boolean - Skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def animate_region_ground(region_id, base_texture_id, frame_duration = 30, exclude_events = false)<br />
    &#36;game_map.animate_region_ground_tiles(region_id, base_texture_id, frame_duration, true, exclude_events)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore All Ground Tiles in Region (Event Command)<br />
  # param region_id : Integer - Region ID to target<br />
  # param exclude_events : Boolean - Skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def restore_region_ground(region_id, exclude_events = false)<br />
    &#36;game_map.restore_region_ground_tiles(region_id, exclude_events)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Check if Ground Tile is Swapped (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def ground_swapped?(x, y)<br />
    return &#36;game_map.ground_tile_swapped?(x, y)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Check if Ground Tile is Animated (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def ground_animated?(x, y)<br />
    return &#36;game_map.ground_tile_animated?(x, y)<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Game_Temp - Additional Switches and Variables<br />
#==============================================================================<br />
class Game_Temp<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased methods<br />
  #--------------------------------------------------------------------------<br />
  unless @already_aliased_ground_swap_temp<br />
    alias initialize_ground_swap_temp initialize<br />
    @already_aliased_ground_swap_temp = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Public Instance Variables<br />
  #--------------------------------------------------------------------------<br />
  attr_accessor :ground_swap_animation  # Boolean - Enable swap animations<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Object Initialization<br />
  #--------------------------------------------------------------------------<br />
  def initialize<br />
    initialize_ground_swap_temp<br />
    @ground_swap_animation = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Enable/Disable Ground Swap Animations<br />
  # param enabled : Boolean<br />
  #--------------------------------------------------------------------------<br />
  def set_ground_swap_animation(enabled)<br />
    @ground_swap_animation = enabled<br />
  end<br />
end<br />
#==============================================================================<br />
# ** DataManager - Save/Load Support<br />
#==============================================================================<br />
module DataManager<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased methods<br />
  #--------------------------------------------------------------------------<br />
  class &lt;&lt; self<br />
    unless @already_aliased_ground_swap_data<br />
      alias make_save_contents_ground_swap make_save_contents<br />
      alias extract_save_contents_ground_swap extract_save_contents<br />
      @already_aliased_ground_swap_data = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Save Contents<br />
  #--------------------------------------------------------------------------<br />
  def self.make_save_contents<br />
    contents = make_save_contents_ground_swap<br />
    contents[:ground_swaps] = {<br />
      :original_tiles =&gt; &#36;game_map.original_ground_tiles,<br />
      :swapped_tiles =&gt; &#36;game_map.swapped_ground_tiles,<br />
      :animated_tiles =&gt; &#36;game_map.animated_ground_tiles<br />
    }<br />
    contents<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Extract Save Contents<br />
  #--------------------------------------------------------------------------<br />
  def self.extract_save_contents(contents)<br />
    extract_save_contents_ground_swap(contents)<br />
    if contents[:ground_swaps]<br />
      &#36;game_map.original_ground_tiles = contents[:ground_swaps][:original_tiles] || {}<br />
      &#36;game_map.swapped_ground_tiles = contents[:ground_swaps][:swapped_tiles] || {}<br />
      &#36;game_map.animated_ground_tiles = contents[:ground_swaps][:animated_tiles] || {}<br />
    end<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Scene_Map - Animation Updates<br />
#==============================================================================<br />
class Scene_Map &lt; Scene_Base<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased methods<br />
  #--------------------------------------------------------------------------<br />
  unless @already_aliased_ground_swap_scene<br />
    alias update_ground_swap_scene update<br />
    @already_aliased_ground_swap_scene = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Frame Update<br />
  #--------------------------------------------------------------------------<br />
  def update<br />
    update_ground_swap_scene<br />
    &#36;game_map.update_ground_animations if &#36;game_system.fple<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Usage Examples and Helper Methods<br />
#==============================================================================<br />
# Example usage in events:<br />
#<br />
# Script Command Examples:<br />
# swap_ground(5, 3, 10)                         # Swap tile at (5,3) to texture 10<br />
# animate_ground(5, 3, 15, 60)                  # Animate tile at (5,3) using textures 15,16,17 with 60-frame delays<br />
# animate_ground(2, 4, 20)                      # Animate tile at (2,4) using textures 20,21,22 with default 30-frame delays<br />
# restore_ground(5, 3)                          # Restore original tile at (5,3)<br />
# batch_swap_ground([[1,1,5], [1,2,5]])        # Swap multiple tiles at once<br />
# restore_all_ground                            # Restore all swapped tiles<br />
# swap_region_ground(5, 10)                     # Swap all tiles in region 5 to texture 10<br />
# swap_region_ground(3, 15, true)               # Swap region 3, skip tiles with events<br />
# animate_region_ground(2, 20)                  # Animate all tiles in region 2 using textures 20,21,22<br />
# animate_region_ground(4, 25, 60, true)        # Animate region 4 with 60-frame delays, skip events<br />
# restore_region_ground(5)                      # Restore all tiles in region 5 to original<br />
# restore_region_ground(3, true)                # Restore region 3, skip tiles with events<br />
#<br />
# Conditional Branch Examples:<br />
# if ground_swapped?(5, 3)<br />
#   # Do something if tile is swapped<br />
# end<br />
#<br />
# if ground_animated?(5, 3)<br />
#   # Do something if tile is animated<br />
# end<br />
#<br />
# Advanced Script Examples:<br />
# &#36;game_map.create_animated_ground_tile(&#36;game_player.x, &#36;game_player.y, 15, 45)<br />
# &#36;game_map.swap_ground_tile(&#36;game_player.x, &#36;game_player.y, 15)<br />
# texture_id = &#36;game_map.get_ground_texture_id(5, 3)<br />
# original_id = &#36;game_map.get_original_ground_texture_id(5, 3)<br />
# count = &#36;game_map.swap_region_ground_tiles(1, 12, false, true)<br />
# &#36;game_map.animate_region_ground_tiles(7, 30, 45)<br />
# Global helper methods for easier access<br />
def swap_ground_tile(x, y, texture_id, animate = true)<br />
  &#36;game_map.swap_ground_tile(x, y, texture_id, animate)<br />
end<br />
def create_animated_ground_tile(x, y, base_texture_id, frame_duration = 30, animate = true)<br />
  &#36;game_map.create_animated_ground_tile(x, y, base_texture_id, frame_duration, animate)<br />
end<br />
def restore_ground_tile(x, y)<br />
  &#36;game_map.restore_ground_tile(x, y)<br />
end<br />
def ground_tile_swapped?(x, y)<br />
  &#36;game_map.ground_tile_swapped?(x, y)<br />
end<br />
def ground_tile_animated?(x, y)<br />
  &#36;game_map.ground_tile_animated?(x, y)<br />
end<br />
def swap_region_ground_tiles(region_id, texture_id, animate = true, exclude_events = false)<br />
  &#36;game_map.swap_region_ground_tiles(region_id, texture_id, animate, exclude_events)<br />
end<br />
def animate_region_ground_tiles(region_id, base_texture_id, frame_duration = 30, animate = true, exclude_events = false)<br />
  &#36;game_map.animate_region_ground_tiles(region_id, base_texture_id, frame_duration, animate, exclude_events)<br />
end<br />
def restore_region_ground_tiles(region_id, exclude_events = false)<br />
  &#36;game_map.restore_region_ground_tiles(region_id, exclude_events)<br />
end</code></div></div><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** FPLE Third Person Player Sprite<br />
# v.1.5 old, now upgraded to v.1.8 using Claude.AI by 5Brainplay. <br />
#==============================================================================<br />
# This script adds a third-person view sprite of the player character that<br />
# appears on screen during FPLE mode. The sprite can be positioned, scaled,<br />
# and configured to show the player's current state.<br />
#==============================================================================<br />
module FPLE<br />
  #--------------------------------------------------------------------------<br />
  # * Player Sprite Configuration<br />
  #--------------------------------------------------------------------------<br />
  PLAYER_SPRITE_DEFAULT_X = 300              # Default X position on screen<br />
  PLAYER_SPRITE_DEFAULT_Y = 450             # Default Y position on screen<br />
  PLAYER_SPRITE_DEFAULT_SCALE = 3.0         # Default scale multiplier<br />
  PLAYER_SPRITE_DEFAULT_OPACITY = 255       # Default opacity (0-255)<br />
  PLAYER_SPRITE_Z = 1000                    # Z-order (higher = in front)<br />
  PLAYER_SPRITE_DEFAULT_ANIMATE = true      # Default enable walking animation<br />
  PLAYER_SPRITE_UPDATE_DIRECTION = false     # Update sprite direction based on player facing<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Player Sprite Settings (Dynamic)<br />
  #--------------------------------------------------------------------------<br />
  @@player_sprite_enabled = true<br />
  @@player_sprite_animate = PLAYER_SPRITE_DEFAULT_ANIMATE<br />
  <br />
  def self.player_sprite_enabled<br />
    @@player_sprite_enabled<br />
  end<br />
  <br />
  def self.player_sprite_enabled=(value)<br />
    @@player_sprite_enabled = value<br />
  end<br />
  <br />
  def self.player_sprite_animate<br />
    @@player_sprite_animate<br />
  end<br />
  <br />
  def self.player_sprite_animate=(value)<br />
    @@player_sprite_animate = value<br />
  end<br />
end<br />
#==============================================================================<br />
# ** FPLE::Player_Sprite<br />
#==============================================================================<br />
module FPLE<br />
  class Player_Sprite &lt; Sprite<br />
    #--------------------------------------------------------------------------<br />
    # * Object Initialization<br />
    #--------------------------------------------------------------------------<br />
    def initialize(viewport = nil)<br />
      super(viewport)<br />
      @character = &#36;game_player<br />
      @tile_id = 0<br />
      @character_name = ""<br />
      @character_index = 0<br />
      @pattern = 0<br />
      @direction = 8<br />
      @animation_count = 0<br />
      @stop_count = 0<br />
      @jump_count = 0<br />
      <br />
      # Set initial position and properties<br />
      self.x = FPLE::PLAYER_SPRITE_DEFAULT_X<br />
      self.y = FPLE::PLAYER_SPRITE_DEFAULT_Y<br />
      self.z = FPLE::PLAYER_SPRITE_Z<br />
      self.zoom_x = FPLE::PLAYER_SPRITE_DEFAULT_SCALE<br />
      self.zoom_y = FPLE::PLAYER_SPRITE_DEFAULT_SCALE<br />
      self.opacity = FPLE::PLAYER_SPRITE_DEFAULT_OPACITY<br />
      <br />
      update<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Frame Update<br />
    #--------------------------------------------------------------------------<br />
    def update<br />
      super<br />
      if FPLE.player_sprite_enabled<br />
        update_bitmap<br />
        update_src_rect<br />
        update_visibility<br />
        update_animation if FPLE.player_sprite_animate<br />
      else<br />
        self.visible = false<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Transfer Origin Bitmap<br />
    #--------------------------------------------------------------------------<br />
    def update_bitmap<br />
      if graphic_changed?<br />
        @tile_id = @character.tile_id<br />
        @character_name = @character.character_name<br />
        @character_index = @character.character_index<br />
        if @tile_id &gt; 0<br />
          set_tile_bitmap<br />
        else<br />
          set_character_bitmap<br />
        end<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Determine if Graphic Changed<br />
    #--------------------------------------------------------------------------<br />
    def graphic_changed?<br />
      @tile_id != @character.tile_id ||<br />
      @character_name != @character.character_name ||<br />
      @character_index != @character.character_index<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Tile Bitmap<br />
    #--------------------------------------------------------------------------<br />
    def set_tile_bitmap<br />
      sx = (@tile_id / 128 % 2 * 8 + @tile_id % 8) * 32<br />
      sy = @tile_id % 256 / 8 % 16 * 32<br />
      self.bitmap = tileset_bitmap(@tile_id)<br />
      self.src_rect.set(sx, sy, 32, 32)<br />
      self.ox = 16<br />
      self.oy = 32<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Character Bitmap<br />
    #--------------------------------------------------------------------------<br />
    def set_character_bitmap<br />
      self.bitmap = Cache.character(@character_name)<br />
      sign = @character_name[/^[&#92;!&#92;&#36;]./]<br />
      if sign &amp;&amp; sign.include?('&#36;')<br />
        @cw = bitmap.width / 3<br />
        @ch = bitmap.height / 4<br />
      else<br />
        @cw = bitmap.width / 12<br />
        @ch = bitmap.height / 8<br />
      end<br />
      self.ox = @cw / 2<br />
      self.oy = @ch<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Get Tileset Bitmap<br />
    #--------------------------------------------------------------------------<br />
    def tileset_bitmap(tile_id)<br />
      set_number = tile_id / 256<br />
      return Cache.system("TileB") if set_number == 0<br />
      return Cache.system("TileC") if set_number == 1<br />
      return Cache.system("TileD") if set_number == 2<br />
      return Cache.system("TileE") if set_number == 3<br />
      return nil<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Transfer Origin Rectangle<br />
    #--------------------------------------------------------------------------<br />
    def update_src_rect<br />
      if @tile_id == 0<br />
        index = @character.character_index<br />
        pattern = @pattern &lt; 3 ? @pattern : 1<br />
        sx = (index % 4 * 3 + pattern) * @cw<br />
        <br />
        # Update direction based on player facing if enabled<br />
        if FPLE::PLAYER_SPRITE_UPDATE_DIRECTION<br />
          @direction = @character.direction<br />
        end<br />
        <br />
        sy = (index / 4 * 4 + (@direction - 2) / 2) * @ch<br />
        self.src_rect.set(sx, sy, @cw, @ch)<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Visibility<br />
    #--------------------------------------------------------------------------<br />
    def update_visibility<br />
      self.opacity = @character.opacity<br />
      self.blend_type = @character.blend_type<br />
      self.visible = !@character.transparent &amp;&amp; FPLE.player_sprite_enabled<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Animation<br />
    #--------------------------------------------------------------------------<br />
    def update_animation<br />
      if &#36;game_temp.movement<br />
        # Player is moving, animate the sprite<br />
        @stop_count = 0<br />
        update_animation_pattern<br />
      else<br />
        # Player is stationary<br />
        @stop_count += 1<br />
        if @stop_count &gt; 20  # Stop animation after standing still<br />
          @pattern = 1  # Default standing pattern<br />
          @animation_count = 0<br />
        end<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Animation Pattern<br />
    #--------------------------------------------------------------------------<br />
    def update_animation_pattern<br />
      @animation_count += 1.5<br />
      if @animation_count &gt; 18<br />
        if @pattern == 0<br />
          @pattern = 1<br />
        elsif @pattern == 1<br />
          @pattern = 2<br />
        elsif @pattern == 2<br />
          @pattern = 1<br />
        end<br />
        @animation_count = 0<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Position<br />
    #--------------------------------------------------------------------------<br />
    def set_position(x, y)<br />
      self.x = x<br />
      self.y = y<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Scale<br />
    #--------------------------------------------------------------------------<br />
    def set_scale(scale_x, scale_y = nil)<br />
      scale_y = scale_x if scale_y.nil?<br />
      self.zoom_x = scale_x<br />
      self.zoom_y = scale_y<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Direction (for manual control)<br />
    #--------------------------------------------------------------------------<br />
    def set_direction(direction)<br />
      @direction = direction<br />
    end<br />
  end<br />
end<br />
#==============================================================================<br />
# ** FPLE::Spriteset_Map - Modified<br />
#==============================================================================<br />
# Add player sprite support to the existing FPLE spriteset<br />
module FPLE<br />
  class Spriteset_Map &lt; ::Spriteset_Map<br />
    #--------------------------------------------------------------------------<br />
    # * Aliased methods for player sprite<br />
    #--------------------------------------------------------------------------<br />
    unless @already_aliased_player_sprite<br />
      alias create_characters_with_player_sprite create_characters<br />
      alias dispose_characters_with_player_sprite dispose_characters<br />
      alias update_characters_with_player_sprite update_characters<br />
      @already_aliased_player_sprite = true<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Create Characters (with player sprite)<br />
    #--------------------------------------------------------------------------<br />
    def create_characters<br />
      create_characters_with_player_sprite<br />
      create_player_sprite<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Create Player Sprite<br />
    #--------------------------------------------------------------------------<br />
    def create_player_sprite<br />
      if FPLE.player_sprite_enabled<br />
        @player_sprite = FPLE::Player_Sprite.new(@viewport1)<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Dispose of Characters (with player sprite)<br />
    #--------------------------------------------------------------------------<br />
    def dispose_characters<br />
      dispose_player_sprite<br />
      dispose_characters_with_player_sprite<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Dispose of Player Sprite<br />
    #--------------------------------------------------------------------------<br />
    def dispose_player_sprite<br />
      if @player_sprite<br />
        @player_sprite.dispose<br />
        @player_sprite = nil<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Characters (with player sprite)<br />
    #--------------------------------------------------------------------------<br />
    def update_characters<br />
      update_characters_with_player_sprite<br />
      update_player_sprite<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Player Sprite<br />
    #--------------------------------------------------------------------------<br />
    def update_player_sprite<br />
      if @player_sprite<br />
        @player_sprite.update<br />
      end<br />
    end<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Game_Temp - Player Sprite Commands<br />
#==============================================================================<br />
class Game_Temp<br />
  #--------------------------------------------------------------------------<br />
  # * Show Player Sprite<br />
  #--------------------------------------------------------------------------<br />
  def show_player_sprite<br />
    if &#36;game_system.fple<br />
      FPLE.player_sprite_enabled = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Hide Player Sprite<br />
  #--------------------------------------------------------------------------<br />
  def hide_player_sprite<br />
    if &#36;game_system.fple<br />
      FPLE.player_sprite_enabled = false<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Set Player Sprite Position<br />
  #--------------------------------------------------------------------------<br />
  def set_player_sprite_position(x, y)<br />
    if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
      spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
      if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
        spriteset.instance_variable_get(:@player_sprite).set_position(x, y)<br />
      end<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Set Player Sprite Scale<br />
  #--------------------------------------------------------------------------<br />
  def set_player_sprite_scale(scale_x, scale_y = nil)<br />
    if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
      spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
      if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
        spriteset.instance_variable_get(:@player_sprite).set_scale(scale_x, scale_y)<br />
      end<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Get Player Sprite Position<br />
  #--------------------------------------------------------------------------<br />
  def get_player_sprite_position<br />
    if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
      spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
      if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
        sprite = spriteset.instance_variable_get(:@player_sprite)<br />
        return [sprite.x, sprite.y]<br />
      end<br />
    end<br />
    return [0, 0]<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Reset Player Sprite to Default Position<br />
  #--------------------------------------------------------------------------<br />
  def reset_player_sprite_position<br />
    set_player_sprite_position(FPLE::PLAYER_SPRITE_DEFAULT_X, FPLE::PLAYER_SPRITE_DEFAULT_Y)<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Script Call Methods - Global functions for easier access<br />
#==============================================================================<br />
#--------------------------------------------------------------------------<br />
# * Simple script call to set player sprite position<br />
# Usage in script call: set_player_sprite_xy(300, 450)<br />
#--------------------------------------------------------------------------<br />
def set_player_sprite_xy(x, y)<br />
  if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
    spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
    if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
      spriteset.instance_variable_get(:@player_sprite).set_position(x, y)<br />
    end<br />
  end<br />
end<br />
#--------------------------------------------------------------------------<br />
# * Alternative: More direct access to the player sprite<br />
# Usage in script call: player_sprite_position(100, 200)<br />
#--------------------------------------------------------------------------<br />
def player_sprite_position(x, y)<br />
  &#36;game_temp.set_player_sprite_position(x, y)<br />
end<br />
#--------------------------------------------------------------------------<br />
# * Set individual coordinates<br />
# Usage: set_player_sprite_x(150) or set_player_sprite_y(300)<br />
#--------------------------------------------------------------------------<br />
def set_player_sprite_x(x)<br />
  if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
    spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
    if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
      sprite = spriteset.instance_variable_get(:@player_sprite)<br />
      sprite.set_position(x, sprite.y)<br />
    end<br />
  end<br />
end<br />
def set_player_sprite_y(y)<br />
  if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
    spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
    if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
      sprite = spriteset.instance_variable_get(:@player_sprite)<br />
      sprite.set_position(sprite.x, y)<br />
    end<br />
  end<br />
end</code></div></div>]]></description>
			<content:encoded><![CDATA[@A.I. Topical Post. Tag.<br />
<br />
I upgraded FPLE Ace Using Claude.AI, Integrated a 4-Side &amp; 6-Side box comment, which can create buildings/grass boxes/objects.<br />
6 Side had type2+d1 &amp; type1+d1)) but changed it to a type 0 to save FPS, you can add it back if you want.<br />
<br />
For below/Above, type 0 objects you want to walk over add, 1-Side, to them.<br />
I added code the following code so these player facing objects without 1-Side push forward, for NPCs.<br />
if dy == 0 &amp;&amp; dx == 0 &amp;&amp; surface.character.fple_type == 0 &amp;&amp; surface.character.fple_one_side == false.<br />
<br />
(Fit,Type1,D1,1Side,V2) objects have a side profile added to them, but should always be, same not below/above.<br />
you can jump over these with a moveset thuf-on/step forward step forward thur-off, they are a type of ledge.<br />
<br />
You may have to code in your own.  (Fit,Type2,D1,1Side,V2), I'm not currently tested to check its same function.<br />
<br />
I've worked out a fix for rotation letting you see events thur walls briefly, here is the 1st rough draft of the script.<br />
I would have posted a few days sooner, but was having issues with strafing crashing the game for some reason.<br />
<br />
The resolution is also no longer Default, it's 608x417, you can place it back with the original script, or pick Res 2.<br />
<br />
The Enhanced Script requires Background Addon to function properly, I've not worked out the private call issue.<br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#========================Author: MGC=============================<br />
# First Person Labyrinth Explorer (FPLE) Engine - VX Ace version.<br />
# v.1.5 old, now upgraded to v.1.8 using Claude.AI by 5Brainplay.<br />
#================================================================<br />
# This script allows the map to be displayed in first-person view,<br />
# while maintaining tile-by-tile movement, similar to the<br />
# Etrian Odyssey series (Nintendo DS/3DS). # THIS IS NOT A SCRIPT FOR MAKING AN FPS, BUT AN FPRPG.<br />
#<br />
# This is a port of version 1.5 of the FPLE for RPG Maker XP, with<br />
# a few small additions.<br />
#<br />
# Features:<br />
# - Can only be enabled on certain maps in the project<br />
# - Forward/backward movement, left/right movement<br />
# and 90° rotation<br />
# - Ability to lower quality while moving to reduce lag<br />
# - Translucency and blend type support<br />
# for events<br />
#<br />
# Limitations:<br />
# - Not really suitable for moving events from one tile to another.<br />
# This should work, but use sparingly. # - Animations are displayed above everything<br />
# - The player cannot jump or move diagonally<br />
# - The resolution must be the default, i.e., 544px x 416px<br />
# - No transparency for walls<br />
# - No different heights: a single level for the floor and ceiling<br />
#<br />
# Instructions:<br />
# This script must be placed below the original scripts but above "Main"<br />
# It requires the MGC_FPLE_Ace_1_1.dll file<br />
#<br />
# - Map Creation<br />
# Maps must be exported into the project from the dedicated editor,<br />
# present in the Marta project starting with version 1.0.0<br />
#<br />
# - Events<br />
# Events with a graphical representation are displayed<br />
# vertically (like walls), centered, and always facing the<br />
# player. The "Comment..." command allows you to control this display:<br />
# "Type 0": Always faces the player (default)<br />
# "Type 1": Horizontally oriented in the RM editor view (top view)<br />
# "Type 2": Vertically oriented in the RM editor view (top view)<br />
# "Stretch": The image is stretched to the dimensions of a wall (square)<br />
# "Fit": The image is stretched to fit within the dimensions of a wall, the<br />
# aspect ratio is maintained. Automatically applied if<br />
# the dimensions exceed those of a wall (new in VX Ace)<br />
# "Zoom X.X": zoom the image (new in VX Ace), for example, to double<br />
# the dimensions, write: "Zoom 2.0"<br />
# "V-Align 0": vertical alignment at the top (at ceiling level)<br />
# "V-Align 1": vertical alignment in the center (default)<br />
# "V-Align 2": vertical alignment at the bottom (at floor level)<br />
# "D-Align 0": depth alignment in front/left, for types 1 and 2<br />
# "D-Align 1": depth alignment in the center, for types 1 and 2 (default)<br />
# "D-Align 2": depth alignment in the back/right, for types 1 and 2<br />
# "1-Side": texture applied to one side only =&gt; appears mirrored behind<br />
# "2-Side": texture applied to two side only =&gt; appears mirrored behind #Extra Unused Call To Code#<br />
# "4-Side": texture applied to four sides to create the illusion of box<br />
# "6-Side":  texture applied to four sides to create the illusion of grass.<br />
# - Technical Parameters<br />
# In the CONFIGURATION section at the beginning of the script, you will find the<br />
# following constants whose values can be modified:<br />
# - VIEW_DISTANCE: "Surfaces" (textured square polygons of fixed<br />
# dimensions representing tiles and events) are only<br />
# displayed within a certain distance around<br />
# the player. This constant represents this distance,<br />
# expressed in tiles (default value: 6). The higher<br />
# this value, the greater the risk of lag.<br />
# - RESOLUTION: Drawing the entire screen every frame requires<br />
# a lot of resources. During movement, it is<br />
# possible to use a lower screen resolution and the<br />
# Render will then be zoomed to fit 544px x 416px.<br />
# 0: Maximum resolution (544px*416px) Changed to (840px*560px)<br />
# 1: Medium resolution (408px*312px)  Changed to (608px*417px)<br />
# 2: Low resolution (272px*208px) Changed to (544px*417px)<br />
# 3: Minimum resolution (204px*156px) Changed to (408px*278px)<br />
# 4: Test resolution (204px*156px) Changed to (332px*222px)<br />
# - ALWAYS_SAME_RES: If true, the same resolution will be used when stationary<br />
# as when moving (see RESOLUTION)<br />
# If false, the maximum resolution will be used when stationary<br />
# (default value)<br />
# - LIGHT_DISTANCE: To prevent surfaces from suddenly appearing on the screen,<br />
# this constant represents the distance in tiles beyond<br />
# which the opacity of the surfaces will be zero.<br />
# The opacity change is gradual. If there is<br />
# no parallax, the screen background is black and the<br />
# surfaces will become increasingly darker with distance.<br />
# A value of 0 disables this feature.<br />
#<br />
# - Commands that can be used in scripts (possible via the "Script..."<br />
# command of an event):<br />
# - &#36;game_temp.set_view(new_view_distance)<br />
# - &#36;game_temp.set_light(new_light_distance)<br />
# - &#36;game_temp.increase_light<br />
# - &#36;game_temp.decrease_light<br />
#============================<br />
module FPLE<br />
  #-----------------------------<br />
  # * CONFIGURATION<br />
  #-----------------------------<br />
  VIEW_DISTANCE = 22 # in tiles, &gt; 0<br />
  LIGHT_DISTANCE = 11 # in tiles, &gt;=0, 0=deactivated<br />
  RESOLUTION = 1 # quality when moving, 0=max, 1=medium, 2=low, 3=ugly<br />
  ALWAYS_SAME_RES = true # if true, quality at stand = quality when moving<br />
                          # if false, quality at stand = quality max<br />
  SKIP_DISTANT_CHARS = true  # Skip character updates beyond view distance<br />
  BATCH_SURFACE_UPDATES = true  # Update surfaces in batches<br />
  AGGRESSIVE_CULLING = true     # More aggressive visibility culling<br />
end<br />
#==============================<br />
# ** FPLE Core<br />
#==============================<br />
module FPLE<br />
  #-----------------------------<br />
  # * Constantes<br />
  #-----------------------------<br />
  MAP_SIDES = [4, 3, 5, 2]<br />
  MAP_SIDES_LEFT = [5, 4, 2, 3]<br />
  MAP_SIDES_RIGHT = [3, 2, 4, 5]<br />
  PLAYER_MOVE_FORWARD = [[0, 1], [-1, 0], [1, 0], [0, -1]]<br />
  PLAYER_MOVE_SPEED = [0, 1, 2, 4, 6, 8, 12]<br />
  TURN_LEFT = [6, 2, 8, 4]<br />
  COS_TABLE = [4096, 4095, 4094, 4090, 4086,<br />
  4080, 4074, 4065, 4056, 4046, 4034, 4021, 4006, 3991, 3974,<br />
  3956, 3937, 3917, 3896, 3873, 3849, 3824, 3798, 3770, 3742,<br />
  3712, 3681, 3650, 3617, 3582, 3547, 3511, 3474, 3435, 3396,<br />
  3355, 3314, 3271, 3228, 3183, 3138, 3091, 3044, 2996, 2946,<br />
  2896, 2845, 2793, 2741, 2687, 2633, 2578, 2522, 2465, 2408,<br />
  2349, 2290, 2231, 2171, 2110, 2048, 1986, 1923, 1860, 1796,<br />
  1731, 1666, 1600, 1534, 1468, 1401, 1334, 1266, 1198, 1129,<br />
  1060, 991, 921, 852, 782, 711, 641, 570, 499, 428,<br />
  357, 286, 214, 143, 71, 0]<br />
  RENDER = Win32API.new("MGC_FPLE_Ace_1_2", "RenderFPLE", "lll", "l") # [1.5]<br />
  RENDER_ROT = Win32API.new("MGC_FPLE_Ace_1_2", "RenderFPLErot", "lll", "l") # [1.5]<br />
  #-----------------------------<br />
  # * Retourne l'angle d'orientation<br />
  # return Integer<br />
  #-----------------------------<br />
  def self.angle<br />
    return @angle<br />
  end<br />
  #-----------------------------<br />
  # * Retourne le décalage horizontal<br />
  # return Integer<br />
  #-----------------------------<br />
  def self.offset_x<br />
    return @offset_x<br />
  end<br />
  #-----------------------------<br />
  # * Retourne le décalage en profondeur<br />
  # return Integer<br />
  #-----------------------------<br />
  def self.offset_y<br />
    return @offset_y<br />
  end<br />
  #-----------------------------<br />
  # * Initialisation<br />
  # param spriteset : FPLE::Spriteset_Map<br />
  # param viewport : Viewport<br />
  #-----------------------------<br />
  def self.initialize_fple(spriteset, viewport)<br />
    @spriteset = spriteset<br />
    @sprite_screen = Sprite.new(viewport)<br />
    @sprite_move = Sprite.new(viewport)<br />
    self.initialize_bitmaps<br />
    @offset_x = 0<br />
    @offset_y = 0<br />
    @sprite_move.visible = false<br />
    @lux_distance = &#36;game_system.fple_light_distance &lt;&lt; 5<br />
    @angle = 0<br />
    @trig = 0<br />
    self.refresh_trig<br />
    @count = 0<br />
    &#36;game_temp.force_render = true<br />
    self.update<br />
  end<br />
  #-----------------------------<br />
  # * Création des objets Bitmap devant contenir le rendu 3D<br />
  #-----------------------------<br />
  def self.initialize_bitmaps<br />
    case &#36;game_system.fple_resolution<br />
    when 0<br />
      width = 840<br />
      height = 560<br />
      coefficient_resolution = 0.75<br />
    when 1<br />
      width = 608<br />
      height = 417<br />
      coefficient_resolution = 1<br />
    when 2<br />
      width = 544<br />
      height = 417<br />
      coefficient_resolution = 1.133<br />
    when 3<br />
      width = 408<br />
      height = 278<br />
      coefficient_resolution = 1.5<br />
    when 4<br />
      width = 332<br />
      height = 222<br />
      coefficient_resolution = 2<br />
    end<br />
    if &#36;game_system.fple_always_same_res<br />
      @sprite_screen.bitmap = Bitmap.new(width, height)<br />
      @sprite_screen.zoom_x = coefficient_resolution<br />
      @sprite_screen.zoom_y = coefficient_resolution<br />
    else<br />
      @sprite_screen.bitmap = Bitmap.new(608, 417)<br />
    end<br />
    @sprite_move.bitmap = Bitmap.new(width, height)<br />
    @sprite_move.zoom_x = coefficient_resolution<br />
    @sprite_move.zoom_y = coefficient_resolution<br />
  end<br />
  #-----------------------------<br />
  # * Cherche les valeurs de sinus et cosinus en focntion de l'angle<br />
  #-----------------------------<br />
  def self.refresh_trig<br />
    @cos = FPLE::COS_TABLE[@angle]<br />
    @sin = FPLE::COS_TABLE[91 - @angle]<br />
  end<br />
  #-----------------------------<br />
  # * Dispose<br />
  #-----------------------------<br />
  def self.dispose<br />
    @sprite_screen.dispose<br />
    @sprite_move.dispose<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update<br />
  #-----------------------------<br />
<br />
# Modify the update method to use a more complete background fill<br />
def self.update<br />
  # Run garbage collection periodically during non-movement to reduce memory spikes.<br />
  if !&#36;game_temp.movement &amp;&amp; Graphics.frame_count % 120 == 0<br />
    GC.start<br />
  end<br />
<br />
  # Check if the player is actively moving or changing the view.<br />
  if &#36;game_temp.movement<br />
    case &#36;game_temp.movement_dir<br />
    when 0 # fading distance + 1<br />
      self.increase_fading_distance<br />
    when 1 # fading distance - 1<br />
      self.decrease_fading_distance<br />
    when 3 # set fading distance<br />
      self.set_fading_distance<br />
    when 2 # Move backward<br />
      self.move_backward<br />
    when 4 # Strafe left<br />
      self.strafe_left<br />
    when 6 # Strafe right<br />
      self.strafe_right<br />
    when 8 # Move forward<br />
      self.move_forward<br />
    when 9 # Turn right<br />
      self.turn_right<br />
    when 10 # turn left<br />
      self.turn_left<br />
    end<br />
  <br />
    # Apply method 2 refactoring for sprite and rendering logic<br />
    sprite_moving = &#36;game_temp.movement<br />
    active_sprite = sprite_moving ? @sprite_move : @sprite_screen<br />
    inactive_sprite = sprite_moving ? @sprite_screen : @sprite_move<br />
    active_sprite.visible = true<br />
    inactive_sprite.visible = false<br />
   if @angle != 0<br />
      # Use lighter background color during rotation to prevent bleeding<br />
      bg_color = Color.new(115, 190, 215, 255)  # Much lighter sky blue background<br />
      active_sprite.bitmap.fill_rect(0, 0, active_sprite.bitmap.width,<br />
                                     active_sprite.bitmap.height, bg_color)<br />
    end<br />
    # Clear the active sprite bitmap<br />
    active_sprite.bitmap.clear unless &#36;game_temp.movement_dir == 9 || &#36;game_temp.movement_dir == 10 &amp;&amp; &#36;game_player.moving?<br />
    # Determine if we should use rotation (only during movement and when angle != 0)<br />
    use_rotation = sprite_moving &amp;&amp; @angle != 0<br />
    if use_rotation<br />
      params = [@offset_y, @offset_x, @lux_distance, &#36;game_player.direction, @trig, @cos, @sin, &#36;game_map.fple_map.texturesets]<br />
      FPLE::RENDER_ROT.call(active_sprite.bitmap.__id__, &#36;game_map.surfaces.__id__, params.__id__)<br />
    else<br />
      params = [@offset_y, @offset_x, @lux_distance, &#36;game_player.direction, &#36;game_map.fple_map.texturesets]<br />
      FPLE::RENDER.call(active_sprite.bitmap.__id__, &#36;game_map.surfaces.__id__, params.__id__)<br />
    end<br />
    # Handle post-movement logic<br />
    unless sprite_moving<br />
      &#36;game_player.update_nonmoving(&#36;game_temp.last_moving) if &#36;game_temp.last_moving<br />
    end<br />
  # This block handles rendering when the player is not moving, but other<br />
  # events or conditions (like character surfaces) need updating.<br />
  elsif &#36;game_player.moving? || &#36;game_temp.force_render<br />
    # Process updates for characters and events.<br />
    &#36;game_map.refresh_surfaces<br />
  <br />
    # Extract common character update logic to avoid duplication<br />
    update_character = lambda do |event|<br />
      # Only process if SKIP_DISTANT_CHARS is enabled<br />
      return unless FPLE::SKIP_DISTANT_CHARS<br />
    <br />
      dist_x = (&#36;game_player.real_x / 32) - (event.x)<br />
      dist_y = (&#36;game_player.real_y / 32) - (event.y)<br />
      distance = Math.sqrt(dist_x**2 + dist_y**2)<br />
      return if distance &gt; FPLE::VIEW_DISTANCE<br />
    <br />
      event.update_fple_surface<br />
    end<br />
    # === START OF BATCH AND CULLING FIX ===<br />
    # Updates characters in batches to avoid lag spikes, with optional distance skipping.<br />
    if FPLE::BATCH_SURFACE_UPDATES<br />
      &#36;game_map.events.values.each_with_index do |event, i|<br />
        # Only update a fraction of the events each frame.<br />
        if @count % 5 == i % 5<br />
          update_character.call(event)<br />
        end<br />
      end<br />
    else<br />
      # Fallback for no batching.<br />
      &#36;game_map.events.each_value(&amp;update_character)<br />
    end<br />
    # === END OF BATCH AND CULLING FIX ===<br />
  <br />
    &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    @sprite_screen.bitmap.clear<br />
  <br />
    # Use consistent parameter structure<br />
    params = [@offset_y, @offset_x, @lux_distance, &#36;game_player.direction, &#36;game_map.fple_map.texturesets]<br />
    FPLE::RENDER.call(@sprite_screen.bitmap.__id__, &#36;game_map.surfaces.__id__, params.__id__)<br />
  <br />
    &#36;game_temp.force_render = false<br />
    @count += 1<br />
  end<br />
end<br />
  #-----------------------------<br />
  # * Frame Update - Augmentation de la distance d'éclairage<br />
  #-----------------------------<br />
  def self.increase_fading_distance<br />
    @count += 2<br />
    @lux_distance += 2<br />
    if @count == 32<br />
      @count = 0<br />
      &#36;game_temp.movement = false<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Diminution de la distance d'éclairage<br />
  #-----------------------------<br />
  def self.decrease_fading_distance<br />
    if @lux_distance == 0<br />
      @count = 0<br />
      &#36;game_temp.movement = false<br />
    else<br />
      @count += 2<br />
      @lux_distance -= 2<br />
      if @count == 32<br />
        @count = 0<br />
        &#36;game_temp.movement = false<br />
      end<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Définition d'une nouvelle distance d'éclairage<br />
  #-----------------------------<br />
  def self.set_fading_distance<br />
    @lux_distance = &#36;game_system.fple_light_distance &lt;&lt; 5<br />
    &#36;game_temp.movement = false<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Déplacement en arrière<br />
  #-----------------------------<br />
  def self.move_backward<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
      &#36;game_temp.movement_init = true<br />
      @offset_y = 128<br />
    end<br />
    @offset_y -= &#36;game_player.move_speed_fple<br />
    if @offset_y &lt;= 0<br />
      @offset_y = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_temp.last_moving = true<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Déplacement latéral vers la gauche<br />
  #-----------------------------<br />
  def self.strafe_left<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_surfaces_strafe(0)<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
      &#36;game_temp.movement_init = true<br />
      @offset_x = 128<br />
    end<br />
    @offset_x -= &#36;game_player.move_speed_fple<br />
    if @offset_x &lt;= 0<br />
      @offset_x = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_temp.last_moving = true<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Déplacement latéral vers la droite<br />
  #-----------------------------<br />
  def self.strafe_right<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces_strafe(-1)<br />
      &#36;game_temp.movement_init = true<br />
    end<br />
    @offset_x += &#36;game_player.move_speed_fple<br />
    if @offset_x &gt;= 128<br />
      @offset_x = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_temp.last_moving = true<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Déplacement en avant<br />
  #-----------------------------<br />
  def self.move_forward<br />
    @offset_y += &#36;game_player.move_speed_fple<br />
    if @offset_y &gt;= 128<br />
      @offset_y = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_temp.last_moving = true<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Rotation vers la droite<br />
  #-----------------------------<br />
  def self.turn_right<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces_turn_right(@spriteset.character_surfaces)<br />
      &#36;game_temp.movement_init = true<br />
    end<br />
    @angle += 5<br />
    @trig = 1<br />
    refresh_trig<br />
    if @angle == 90<br />
      @angle = 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Frame Update - Rotation vers la gauche<br />
  #-----------------------------<br />
  def self.turn_left<br />
    unless &#36;game_temp.movement_init<br />
      &#36;game_map.refresh_surfaces_turn_left(@spriteset.character_surfaces)<br />
      &#36;game_temp.movement_init = true<br />
      @angle = 90<br />
    end<br />
    @angle -= 5<br />
    @trig = 0<br />
    refresh_trig<br />
    if @angle == 0<br />
      &#36;game_temp.movement = false<br />
      &#36;game_map.refresh_surfaces<br />
      &#36;game_map.refresh_character_surfaces(@spriteset.character_surfaces)<br />
    end<br />
  end<br />
end<br />
#==============================<br />
# ** DataManager<br />
#==============================<br />
module DataManager<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  class &lt;&lt; self<br />
    unless @already_aliased_fple<br />
      alias save_game_without_rescue_fple save_game_without_rescue<br />
      @already_aliased_fple = true<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Execute Save (No Exception Processing)<br />
  #-----------------------------<br />
  def self.save_game_without_rescue(index)<br />
    if &#36;game_map.fple_map # [1.2]<br />
      textureset = &#36;game_map.fple_map.textureset<br />
      texturesets = &#36;game_map.fple_map.texturesets<br />
      &#36;game_map.fple_map.textureset = nil<br />
      &#36;game_map.fple_map.texturesets = nil<br />
    end<br />
    rc = save_game_without_rescue_fple(index)<br />
    if &#36;game_map.fple_map # [1.2]<br />
      &#36;game_map.fple_map.texturesets = texturesets<br />
      &#36;game_map.fple_map.textureset = textureset<br />
    end<br />
    return rc<br />
  end<br />
end<br />
#============================<br />
# ** Game_System<br />
#============================<br />
class Game_System<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias initialize_fple initialize<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Public Instance Variables<br />
  #-----------------------------<br />
  attr_accessor :fple # Boolean<br />
  attr_accessor :fple_view_distance # Integer (&gt;0)<br />
  attr_accessor :fple_light_distance # Integer (&gt;=0, 0:deactivated)<br />
  attr_accessor :fple_resolution # Integer (0:max, 1:medium, 2:low, 3:ugly)<br />
  attr_accessor :fple_always_same_res # Boolean<br />
  #-----------------------------<br />
  # * Object Initialization<br />
  #-----------------------------<br />
  def initialize<br />
    initialize_fple<br />
    self.fple = false<br />
    self.fple_view_distance = FPLE::VIEW_DISTANCE<br />
    self.fple_light_distance = FPLE::LIGHT_DISTANCE<br />
    self.fple_resolution = FPLE::RESOLUTION<br />
    self.fple_always_same_res = FPLE::ALWAYS_SAME_RES<br />
  end<br />
end<br />
#==============================<br />
# ** Game_Temp<br />
#==============================<br />
class Game_Temp<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias initialize_fple initialize<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Public Instance Variables<br />
  #-----------------------------<br />
  attr_accessor :movement_init # Boolean<br />
  attr_accessor :movement # Boolean<br />
  attr_accessor :movement_dir # Integer {2, 4, 6, 8}<br />
  attr_accessor :last_moving # Boolean<br />
  attr_accessor :force_render # Boolean<br />
  #-----------------------------<br />
  # * Object Initialization<br />
  #-----------------------------<br />
  def initialize<br />
    initialize_fple<br />
    self.movement_init = false<br />
    self.movement = false<br />
    self.movement_dir = 8<br />
    self.last_moving = false<br />
    self.force_render = false<br />
  end<br />
  #-----------------------------<br />
  # * Set view distance<br />
  # param distance : Integer<br />
  #-----------------------------<br />
  def set_view(distance)<br />
    if distance &lt; 0 then distance = 0 end<br />
    &#36;game_system.fple_view_distance = distance<br />
    self.force_render = true<br />
  end<br />
  #-----------------------------<br />
  # * Set light distance<br />
  # param distance : Integer<br />
  #-----------------------------<br />
  def set_light(distance)<br />
    if distance &lt; 0 then distance = 0 end<br />
    &#36;game_system.fple_light_distance = distance<br />
    self.movement = true<br />
    self.movement_dir = 3<br />
  end<br />
  #-----------------------------<br />
  # * Increase light distance<br />
  #-----------------------------<br />
  def increase_light<br />
    &#36;game_system.fple_light_distance += 1<br />
    self.movement = true<br />
    self.movement_dir = 0<br />
  end<br />
  #-----------------------------<br />
  # * Decrease light distance<br />
  #-----------------------------<br />
  def decrease_light<br />
    if &#36;game_system.fple_light_distance &gt; 0<br />
      &#36;game_system.fple_light_distance -= 1<br />
    end<br />
    self.movement = true<br />
    self.movement_dir = 1<br />
  end<br />
end<br />
#============================<br />
# ** Game_Map<br />
#============================<br />
class Game_Map<br />
public<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias initialize_fple initialize<br />
    alias setup_fple setup<br />
    alias refresh_fple refresh<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Public Instance Variables<br />
  #-----------------------------<br />
  attr_accessor :surfaces # Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  # * Object Initialization<br />
  #-----------------------------<br />
  def initialize<br />
    initialize_fple<br />
    self.surfaces = []<br />
    @x_ref = 0<br />
    @y_ref = 0<br />
    @distance_cache = {}<br />
    @last_player_pos = [0, 0]<br />
  end<br />
  #-----------------------------<br />
  # * Setup<br />
  # param map_id : Integer<br />
  #-----------------------------<br />
  def setup(map_id)<br />
    @map_id = map_id<br />
    @map = load_data(sprintf("Data/Map%03d.rvdata2", @map_id))<br />
    if is_fple?<br />
      load_fple_map<br />
      &#36;game_system.fple = true<br />
    elsif &#36;game_system.fple<br />
      &#36;game_system.fple = false<br />
    end<br />
    setup_fple(map_id)<br />
  end<br />
  #-----------------------------<br />
  # * Refresh<br />
  #-----------------------------<br />
  def refresh<br />
    refresh_fple<br />
    if is_fple?<br />
      unless @fple_map.textureset<br />
        load_fple_map<br />
      end<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Vérifie s'il s'agit d'une carte FPLE<br />
  # return String<br />
  #-----------------------------<br />
  def is_fple?<br />
    return @map.note[/&#92;[fple:&#92;w+&#92;]/]<br />
  end<br />
  #-----------------------------<br />
  # * Charge la carte FPLE associée<br />
  #-----------------------------<br />
  def load_fple_map<br />
    if @fple_map then @fple_map.dispose end<br />
    @map.note[/&#92;[fple:(&#92;w+)&#92;]/]<br />
    File.open('Data_FPLE/' + &#36;1 + '.fple', "rb") {|file|<br />
      map_data = Marshal.load(file)<br />
      @fple_map = FPLE::Map.new(map_data.width, map_data.height,<br />
      map_data.map_name, map_data.tileset_name, map_data.data,<br />
      map_data.subsets_mapping, map_data.textureset_data)<br />
    }<br />
  end<br />
  #-----------------------------<br />
  # * Retourne la carte FPLE associée<br />
  # return FPLE::Map<br />
  #-----------------------------<br />
  def fple_map<br />
    @fple_map<br />
  end<br />
  #-----------------------------<br />
  # * Retourne le nom du tileset<br />
  # return String<br />
  #-----------------------------<br />
  def tileset_name<br />
    if &#36;game_system.fple<br />
      return @fple_map.tileset_name<br />
    else<br />
      return ""<br />
    end<br />
  end<br />
end<br />
  #-----------------------------<br />
   def cached_distance(event_id, event_x, event_y)<br />
    player_pos = [&#36;game_player.x, &#36;game_player.y]<br />
  <br />
    # Clear cache if player moved<br />
    if @last_player_pos != player_pos<br />
      @distance_cache.clear<br />
      @last_player_pos = player_pos<br />
    end<br />
  <br />
    cache_key = [event_id, event_x, event_y]<br />
    return @distance_cache[cache_key] if @distance_cache.has_key?(cache_key)<br />
  <br />
    dist_x = (player_pos[0] - event_x).abs<br />
    dist_y = (player_pos[1] - event_y).abs<br />
    distance = Math.sqrt(dist_x * dist_x + dist_y * dist_y)<br />
  <br />
    @distance_cache[cache_key] = distance<br />
    return distance<br />
  end<br />
    #-----------------------------<br />
  # * Recherche les surfaces visibles de la carte en fonction de<br />
  # l'orientation du joueur<br />
    #-----------------------------<br />
  def refresh_surfaces<br />
    @current_dir = &#36;game_player.direction<br />
    self.surfaces = []<br />
    @x_ref = &#36;game_player.x<br />
    @y_ref = &#36;game_player.y<br />
    case &#36;game_player.direction<br />
    when 2<br />
      surfaces_temp = refresh_surfaces_down<br />
    when 4<br />
      surfaces_temp = refresh_surfaces_left<br />
    when 6<br />
      surfaces_temp = refresh_surfaces_right<br />
    when 8<br />
      surfaces_temp = refresh_surfaces_up<br />
    end<br />
  <br />
    # set surfaces z attributes with z-fighting prevention<br />
    surfaces_temp.each {|surface| set_surface_z(surface)}<br />
    surfaces.concat(surfaces_temp)<br />
  <br />
    # Enhanced sorting with z-fighting prevention<br />
    if @last_surface_count != surfaces.length || &#36;game_temp.force_render<br />
      surfaces.sort! { |a, b|<br />
        z_diff = b[5] - a[5]<br />
        if z_diff.abs &lt; 0.001 # Very close z-values<br />
          # Use additional criteria for stable sorting<br />
          secondary = (b[1].abs + b[2].abs) - (a[1].abs + a[2].abs)<br />
          secondary.zero? ? b.object_id &lt;=&gt; a.object_id : secondary<br />
        else<br />
          z_diff &lt;=&gt; 0<br />
        end<br />
      }<br />
      @last_surface_count = surfaces.length<br />
    end<br />
  end<br />
     def add_character_surfaces_down_with_rotation_fix(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      dy = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
      dx = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 2)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_up_with_rotation_fix(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      dy = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
      dx = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 8)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_left_with_rotation_fix(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      dy = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
      dx = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 4)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_right_with_rotation_fix(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      dy = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
      dx = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 6)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Add surfaces for single-sided events only during rotation<br />
  #-----------------------------<br />
  def add_character_surfaces_down_single_only(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      # Only process single-sided events<br />
      #next if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
      dy = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
      dx = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 2)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_up_single_only(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      # Only process single-sided events<br />
      #next if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
      dy = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
      dx = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 8)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
def add_character_surfaces_left_single_only(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      # Only process single-sided events<br />
      #next if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
      dy = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
      dx = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 4)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  def add_character_surfaces_right_single_only(character_surfaces)<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    character_surfaces.each do |surface|<br />
      next if surface.displayed # Skip if already processed<br />
      # Only process single-sided events<br />
      #next if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
      dy = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
      dx = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
      add_character_surfaces(surface, dy, dx, surfaces_temp, i, 6)<br />
    end<br />
    return surfaces_temp<br />
  end<br />
<br />
      def add_two_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    # Handle special case where player is at same position as box<br />
        j = i &lt;&lt; 7<br />
    if dy.between?(128, j) &amp;&amp; dx.between?(-j, j)<br />
    event_id = surface.character.id rescue 0<br />
    base_z_offset = (event_id % 1000) * 0.0001<br />
    distance = Math.sqrt(dy * dy + dx * dx)<br />
  <br />
    # Determine visible faces based on position<br />
      faces_to_render = []<br />
  <br />
    # Front face (player looking at object)<br />
    if dy &gt; 32<br />
      faces_to_render &lt;&lt; {type: 1, d_align: 0, z_priority: 5, name: :front}<br />
    end<br />
  <br />
    # Back face<br />
    if dy &lt; -32<br />
      faces_to_render &lt;&lt; {type: 1, d_align: 2, z_priority: 0, name: :back}<br />
    end<br />
  <br />
    # Left face - FIXED: Use proper alignment values<br />
    if dx &lt; -32<br />
      faces_to_render &lt;&lt; {type: 2, d_align: 0, z_priority: 4, name: :left}<br />
    end<br />
  <br />
    # Right face - FIXED: Use proper alignment values<br />
    if dx &gt; 32<br />
      faces_to_render &lt;&lt; {type: 2, d_align: 2, z_priority: 1, name: :right}<br />
    end<br />
  <br />
    # For very close viewing, always show some faces<br />
    if distance &lt; 96<br />
      if faces_to_render.empty?<br />
        faces_to_render &lt;&lt; {type: 1, d_align: 0, z_priority: 5, name: :front}<br />
        faces_to_render &lt;&lt; {type: 2, d_align: 0, z_priority: 4, name: :left}<br />
      end<br />
    end<br />
  <br />
    # Render at least one face<br />
    if faces_to_render.empty?<br />
      faces_to_render &lt;&lt; {type: 1, d_align: 0, z_priority: 5, name: :front}<br />
    end<br />
    end<br />
  <br />
    # Render the faces<br />
    faces_to_render.each_with_index do |face_config, face_index|<br />
      side_dy = dy<br />
      side_dx = dx<br />
    <br />
      # FIXED: Apply position adjustments with proper bounds checking<br />
      if face_config[:type] == 1 # Horizontal face<br />
        if face_config[:d_align] == 0 # Front<br />
          side_dy -= 64<br />
        elsif face_config[:d_align] == 2 # Back<br />
          side_dy += 64<br />
        end<br />
      elsif face_config[:type] == 2 # Vertical face<br />
        if face_config[:d_align] == 0 # Left<br />
          side_dx -= 64<br />
        elsif face_config[:d_align] == 2 # Right<br />
          side_dx += 64<br />
        end<br />
      end<br />
    <br />
      # Calculate z-modifier<br />
      z_modifier = base_z_offset + (face_config[:z_priority] * 0.008) + (face_index * 0.001)<br />
    <br />
      surface_data = [0, side_dy, side_dx, 5, 0, 0,<br />
                      surface.bitmap.__id__, face_config[:type],<br />
                      surface.character.fple_v_align, surface.character.fple_stretch,<br />
                      surface.opacity, surface.blend_type,<br />
                      surface.fit, surface.zoom, 0, z_modifier]<br />
    <br />
      surfaces_temp.push(surface_data)<br />
    end<br />
  <br />
    surface.displayed = true<br />
  end<br />
  #-----------------------------<br />
  # * FIXED: Four-sided surfaces - ensure proper type assignment<br />
  #-----------------------------<br />
  def add_four_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    # Handle special case where player is at same position as box<br />
        j = i &lt;&lt; 7<br />
    if dy.between?(128, j) &amp;&amp; dx.between?(-j, j)<br />
    event_id = surface.character.id rescue 0<br />
    base_z_offset = (event_id % 1000) * 0.0001<br />
  <br />
    # Always render all 4 sides for 4-sided boxes<br />
    faces_to_render = [<br />
      {type: 1, d_align: 0, z_priority: 3, name: :front},  # Front<br />
      {type: 1, d_align: 2, z_priority: 0, name: :back},   # Back<br />
      {type: 2, d_align: 0, z_priority: 3, name: :left},     # Left<br />
      {type: 2, d_align: 2, z_priority: 1, name: :right},    # Right<br />
    ]<br />
  <br />
    # Render all faces with strafe-safe positioning<br />
    faces_to_render.each_with_index do |face_config, face_index|<br />
      side_dy = dy<br />
      side_dx = dx<br />
    <br />
      # FIXED: Apply position adjustments with bounds checking and strafe compensation<br />
      if face_config[:type] == 1 # Horizontal face<br />
        if face_config[:d_align] == 0 # Front<br />
          side_dy -= 64<br />
        elsif face_config[:d_align] == 2 # Back<br />
          side_dy += 64<br />
        end<br />
      elsif face_config[:type] == 2 # Vertical face<br />
        if face_config[:d_align] == 0 # Left<br />
          side_dx -= 64<br />
        elsif face_config[:d_align] == 2 # Right<br />
          side_dx += 64<br />
        end<br />
      end<br />
    <br />
      # Calculate z-modifier<br />
      z_modifier = base_z_offset + (face_config[:z_priority] * 0.01) + (face_index * 0.001)<br />
    <br />
      surface_data = [0, side_dy, side_dx, 5, 0, 0,<br />
                      surface.bitmap.__id__, face_config[:type],<br />
                      surface.character.fple_v_align, surface.character.fple_stretch,<br />
                      surface.opacity, surface.blend_type,<br />
                      surface.fit, surface.zoom, 0, z_modifier]<br />
    <br />
      surfaces_temp.push(surface_data)<br />
    end<br />
  <br />
    surface.displayed = true<br />
  end<br />
end<br />
  #-----------------------------<br />
  # * FIXED: Six-sided surfaces - ensure proper type assignment<br />
  #-----------------------------<br />
def add_six_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    j = i &lt;&lt; 7<br />
    if dy.between?(128, j) &amp;&amp; dx.between?(-j, j)<br />
    event_id = surface.character.id rescue 0<br />
    base_z_offset = (event_id % 1000) * 0.0001<br />
  <br />
    # Render all 6 sides for maximum visibility<br />
  <br />
      faces_to_render = [<br />
      {type: 0, d_align: 1, z_priority: 2, name: :center_h}, # Center horizontal<br />
      {type: 1, d_align: 0, z_priority: 4, name: :front},    # Front<br />
      {type: 1, d_align: 2, z_priority: 0, name: :back},     # Back<br />
      {type: 2, d_align: 0, z_priority: 3, name: :left},    # Left<br />
      {type: 2, d_align: 2, z_priority: 1, name: :right},  # Right<br />
    ]<br />
    # Render all faces with strafe protection<br />
    faces_to_render.each_with_index do |face_config, face_index|<br />
      side_dy = dy<br />
      side_dx = dx<br />
    <br />
      # FIXED: Apply position adjustments with strafe-aware bounds checking<br />
      if face_config[:type] == 1 # Horizontal face<br />
        if face_config[:d_align] == 0 # Front<br />
          side_dy -= 64<br />
        elsif face_config[:d_align] == 2 # Back<br />
          side_dy += 64<br />
        end<br />
      elsif face_config[:type] == 2 # Vertical face<br />
        if face_config[:d_align] == 0 # Left<br />
          side_dx -= 64<br />
        elsif face_config[:d_align] == 2 # Right<br />
          side_dx += 64<br />
        end<br />
      end<br />
    <br />
      # Calculate z-modifier<br />
      z_modifier = base_z_offset + (face_config[:z_priority] * 0.008) + (face_index * 0.001)<br />
    <br />
      surface_data = [0, side_dy, side_dx, 5, 0, 0,<br />
                      surface.bitmap.__id__, face_config[:type],<br />
                      surface.character.fple_v_align, surface.character.fple_stretch,<br />
                      surface.opacity, surface.blend_type,<br />
                      surface.fit, surface.zoom, 0, z_modifier]<br />
    <br />
      surfaces_temp.push(surface_data)<br />
    end<br />
  <br />
    surface.displayed = true<br />
  end<br />
  end<br />
    # Render all 6 sides for maximum visibility<br />
  #-----------------------------<br />
  # * Calcul de la priorité d'affichage d'une surface<br />
  # param surface : Array&lt;Integer&gt;<br />
  #-----------------------------<br />
  def set_surface_z(surface)<br />
    if surface[3] &lt; 5 # map surfaces<br />
      base_z = (surface[1].abs &lt;&lt; 5) + surface[2].abs<br />
      <br />
      # Apply rotation compensation for map surfaces<br />
      if FPLE.angle &gt; 0<br />
        rotation_factor = FPLE.angle / 90.0<br />
        # Increase z-depth for surfaces during rotation to prevent bleeding<br />
        base_z += (rotation_factor * 1000).to_i<br />
      end<br />
      <br />
      surface[5] = base_z<br />
    else # character surfaces<br />
      base_z = (surface[1].abs &gt;&gt; 1) + (surface[2].abs &gt;&gt; 6) - 2<br />
    <br />
      # Check if surface has z-modifier (from multi-sided rendering)<br />
      z_modifier = surface[15] || 0<br />
    <br />
      # Enhanced rotation compensation for character surfaces<br />
      if FPLE.angle &gt; 0<br />
        rotation_factor = FPLE.angle / 90.0<br />
        <br />
        # Push character surfaces further back during rotation<br />
        rotation_penalty = rotation_factor * 500<br />
        <br />
        # Additional penalty based on distance from player<br />
        distance_penalty = Math.sqrt(surface[1] * surface[1] + surface[2] * surface[2]) * 0.1<br />
        <br />
        base_z += (rotation_penalty + distance_penalty).to_i<br />
      end<br />
    <br />
      # Surface type and alignment offsets<br />
      type_offset = surface[7] || 0<br />
      align_offset = surface[8] || 0<br />
    <br />
      z_offset = case type_offset<br />
      when 1 # Horizontal walls<br />
        case surface[2] &lt;=&gt; 0<br />
        when -1 then 0.4  # Left side<br />
        when 0 then 0.2   # Center  <br />
        when 1 then 0.0   # Right side<br />
        end<br />
      when 2 # Vertical walls<br />
        case surface[1] &lt;=&gt; 0<br />
        when -1 then 0.3  # Front<br />
        when 0 then 0.1   # Center<br />
        when 1 then -0.1  # Back<br />
        end<br />
      else<br />
        0 # Default for type 0<br />
      end<br />
    <br />
      # Vertical alignment offset<br />
    if &#36;game_temp.movement_dir == 10 &amp;&amp; &#36;game_player.moving?<br />
      v_align_offset = 0<br />
    else<br />
      v_align_offset = case align_offset<br />
      when 0 then 0.03   # Top<br />
      when 1 then 0.01   # Middle<br />
      when 2 then -32.01 # Bottom<br />
      else 0<br />
      end<br />
    end<br />
    <br />
    surface[5] = base_z.to_f + z_offset + v_align_offset + z_modifier<br />
  end<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces visibles des évènements en fonction de<br />
  # l'orientation du joueur<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  #-----------------------------<br />
# This method updates the list of character surfaces based on visibility and player direction.<br />
public<br />
def refresh_character_surfaces(character_surfaces)<br />
    return if character_surfaces.empty?<br />
  <br />
    max_dist = (&#36;game_system.fple_view_distance || 10) + 3  # Large buffer<br />
    visible_surfaces = character_surfaces.select do |surface|<br />
      next false unless surface.character &amp;&amp; surface.visible &amp;&amp; surface.opacity &gt; 0<br />
    <br />
      # Very generous distance-based filtering<br />
      char = surface.character<br />
      dist_x = (&#36;game_player.x - char.x).abs<br />
      dist_y = (&#36;game_player.y - char.y).abs<br />
    <br />
      dist_x &lt;= max_dist &amp;&amp; dist_y &lt;= max_dist<br />
    end<br />
  <br />
    visible_surfaces = character_surfaces.select { |s|<br />
      s.character &amp;&amp; s.visible &amp;&amp; s.opacity &gt; 0<br />
    }<br />
  <br />
    clear_character_surfaces(visible_surfaces)<br />
  <br />
    # During rotation, we need to render from multiple directions<br />
    if FPLE.angle &gt; 0<br />
      # For multi-sided events during rotation, only render once from current direction<br />
      # to prevent duplicate/rotating surfaces<br />
      current_surfaces = case &#36;game_player.direction<br />
      when 2 then add_character_surfaces_down_with_rotation_fix(visible_surfaces)<br />
      when 4 then add_character_surfaces_left_with_rotation_fix(visible_surfaces)<br />
      when 6 then add_character_surfaces_right_with_rotation_fix(visible_surfaces)<br />
      when 8 then add_character_surfaces_up_with_rotation_fix(visible_surfaces)<br />
      end<br />
    <br />
      # Only add next direction surfaces for single-sided events<br />
      clear_character_surfaces_for_single_sided(visible_surfaces)<br />
      next_surfaces = case &#36;game_player.direction<br />
      when 2 then add_character_surfaces_right_single_only(visible_surfaces)<br />
      when 4 then add_character_surfaces_down_single_only(visible_surfaces)<br />
      when 6 then add_character_surfaces_up_single_only(visible_surfaces)<br />
      when 8 then add_character_surfaces_left_single_only(visible_surfaces)<br />
      end<br />
    <br />
      surfaces_temp = current_surfaces + next_surfaces<br />
    else<br />
      # Normal rendering - single direction<br />
      surfaces_temp = case &#36;game_player.direction<br />
      when 2 then add_character_surfaces_down(visible_surfaces)<br />
      when 4 then add_character_surfaces_left(visible_surfaces)<br />
      when 6 then add_character_surfaces_right(visible_surfaces)<br />
      when 8 then add_character_surfaces_up(visible_surfaces)<br />
      else []<br />
      end<br />
    end<br />
    surfaces_temp.each { |surface| set_surface_z(surface) }<br />
    @surfaces.concat(surfaces_temp)<br />
    #Old#@surfaces.sort! { |a, b| b[5] - a[5] }<br />
<br />
      # Enhanced sorting<br />
    @surfaces.sort! do |a, b|<br />
      z_diff = b[5] - a[5]<br />
      if z_diff.abs &lt; 0.0001<br />
        (b[1].abs + b[2].abs) - (a[1].abs + a[2].abs)<br />
      else<br />
        z_diff &lt;=&gt; 0<br />
      end<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Réinitialise l'indicateur d'affichage des surfaces liées aux évènements<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  #-----------------------------<br />
  def clear_character_surfaces(character_surfaces)<br />
    character_surfaces.each {|surface| surface.displayed = false}<br />
  end<br />
<br />
  def clear_character_surfaces_for_single_sided(character_surfaces)<br />
    character_surfaces.each do |surface|<br />
      # Only clear single-sided events - keep multi-sided events as displayed<br />
      unless surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
        surface.displayed = false<br />
      end<br />
    end<br />
  end<br />
<br />
  def cleanup_distant_surfaces<br />
    return unless @surfaces<br />
  <br />
    # Only cleanup if we have a lot of surfaces<br />
    max_surfaces = 300 # Very generous limit<br />
    if @surfaces.length &gt; max_surfaces<br />
      # Keep only the closest surfaces<br />
      @surfaces.sort_by! { |s| s[1].abs + s[2].abs }<br />
      @surfaces = @surfaces.first(max_surfaces)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Vérifie la visibilité d'une surface liée à un évènement et l'ajoute<br />
  # à la liste des surfaces à afficher le cas échéant<br />
  # param surface : FPLE::Surface_Characters<br />
  # param dy : Integer<br />
  # param dx : Integer<br />
  # param surfaces_temp : Array&lt;Array&lt;integer&gt;&gt;<br />
  # param i : Integer<br />
  # param dir : Integer<br />
  #-----------------------------<br />
# This method adds a character surface to the list for rendering if it is visible.<br />
# `surface`: The FPLE surface object for the character.<br />
# `dy`: The change in y-coordinate from the player.<br />
# `dx`: The change in x-coordinate from the player.<br />
# `surfaces_temp`: The array to which the new surface will be added.<br />
# `i`: The view distance index used for calculation.<br />
# `dir`: The player's direction.<br />
def add_character_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
  return unless surface.character &amp;&amp; surface.character.fple_type<br />
<br />
  # Distance culling - more generous for multi-sided events<br />
  distance_sq = dy * dy + dx * dx<br />
  max_distance = &#36;game_system.fple_view_distance || 10<br />
<br />
  # Use larger buffer for multi-sided events to prevent edge clipping<br />
  if surface.character.fple_four_side || surface.character.fple_six_side || surface.character.fple_two_side<br />
    rotation_buffer = FPLE.angle &gt; 0 ? 1.5 : 1.3<br />
  else<br />
    rotation_buffer = FPLE.angle &gt; 0 ? 2.0 : 1.0<br />
  end<br />
<br />
  max_distance_sq = (max_distance * 96 * rotation_buffer) ** 2<br />
  return if distance_sq &gt; max_distance_sq<br />
<br />
  # Early opacity check<br />
  return if surface.opacity &lt;= 0<br />
<br />
  # Handle multi-sided boxes<br />
  if surface.character.fple_two_side<br />
    add_two_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    return<br />
  elsif surface.character.fple_four_side<br />
    add_four_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    return<br />
  elsif surface.character.fple_six_side<br />
    add_six_sided_surfaces(surface, dy, dx, surfaces_temp, i, dir)<br />
    return<br />
  end<br />
<br />
  # Original single-surface logic for regular events<br />
  j = i &lt;&lt; 7<br />
  if dy == 0 &amp;&amp; dx == 0 &amp;&amp; surface.character.fple_type == 0 &amp;&amp; surface.character.fple_one_side == false<br />
    surface.set_relative_attributes(dir)<br />
    safe_dy = 128<br />
    surface_data = [0, safe_dy, 0, 5, 0, 0,<br />
                    surface.bitmap.__id__,<br />
                    0, # Keep type 0 for face-player events at same position<br />
                    surface.character.fple_v_align,<br />
                    surface.character.fple_stretch,<br />
                    surface.opacity,<br />
                    surface.blend_type,<br />
                    surface.fit,<br />
                    surface.zoom,<br />
                    surface.mirror]<br />
    surfaces_temp.push(surface_data)<br />
    surface.displayed = true<br />
    elsif dy.between?(128, j) &amp;&amp; dx.between?(-j, j)<br />
    # Position adjustments for wall types<br />
    if surface.v_align == 2<br />
      dy -= 16 unless surface.fit == 1<br />
    end<br />
  <br />
    surface.set_relative_attributes(dir)<br />
  <br />
    if surface.type == 1<br />
      if surface.d_align == 0<br />
        dy -= 64<br />
      elsif surface.d_align == 2<br />
        dy += 64<br />
      elsif surface.d_align == 1 &amp;&amp; surface.v_align == 2<br />
        dy -= 16 unless &#36;game_player.moving?<br />
      end<br />
    elsif surface.type == 2<br />
      if surface.d_align == 0<br />
        dx -= 64<br />
      elsif surface.d_align == 2<br />
        dx += 64<br />
      elsif surface.d_align == 1 &amp;&amp; surface.v_align == 2<br />
        dx -= 16 unless &#36;game_player.moving?<br />
      end<br />
    end<br />
  <br />
    surface_data = [0, dy, dx, 5, 0, 0,<br />
                    surface.bitmap.__id__, surface.type,<br />
                    surface.v_align, surface.character.fple_stretch,<br />
                    surface.opacity, surface.blend_type,<br />
                    surface.fit, surface.zoom, surface.mirror]<br />
    surfaces_temp.push(surface_data)<br />
    surface.displayed = true<br />
  end<br />
end<br />
#-----------------------------<br />
def should_render_one_side_event(character, player_dir)<br />
  return true unless character.fple_one_side<br />
<br />
  # Get the event's original type<br />
  original_type = character.fple_type<br />
<br />
  case original_type<br />
  when 0 # Always face player - render from all directions<br />
    return true<br />
  when 1 # Horizontal wall in editor view<br />
    # Only render when looking from north or south<br />
    return [2, 8].include?(player_dir)<br />
  when 2 # Vertical wall in editor view<br />
    # Only render when looking from east or west<br />
    return [4, 6].include?(player_dir)<br />
  end<br />
<br />
  return true<br />
end<br />
  #-----------------------------<br />
def should_render_two_side_event(character, player_dir)<br />
  return true unless character.fple_two_side<br />
<br />
  # Get the event's original type<br />
  original_type = character.fple_type<br />
<br />
  case original_type<br />
  when 0 # Always face player - render from all directions<br />
    return true<br />
  when 1 # Horizontal wall in editor view<br />
    # Only render when looking from north or south<br />
    return [2, 8].include?(player_dir)<br />
  when 2 # Vertical wall in editor view<br />
    # Only render when looking from east or west<br />
    return [4, 6].include?(player_dir)<br />
  end<br />
<br />
  return true<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers le bas<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #----------------------------z<br />
<br />
   #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers le haut<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
def add_character_surfaces_up(character_surfaces)<br />
  surfaces_temp = []<br />
  i = &#36;game_system.fple_view_distance<br />
  character_surfaces.each {|surface|<br />
    if surface.displayed then next end<br />
    # Check directional visibility for 2-side events<br />
    next unless should_render_two_side_event(surface.character, 8)<br />
  <br />
    dy = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
    dx = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
    add_character_surfaces(surface, dy, dx, surfaces_temp, i, 8)<br />
  }<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers le bas<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
def add_character_surfaces_down(character_surfaces)<br />
  surfaces_temp = []<br />
  i = &#36;game_system.fple_view_distance<br />
  character_surfaces.each {|surface|<br />
    if surface.displayed then next end<br />
    # Check directional visibility for 2-side events<br />
    next unless should_render_two_side_event(surface.character, 2)<br />
  <br />
    dy = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
    dx = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
    add_character_surfaces(surface, dy, dx, surfaces_temp, i, 2)<br />
  }<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers la gauche<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
def add_character_surfaces_left(character_surfaces)<br />
  surfaces_temp = []<br />
  i = &#36;game_system.fple_view_distance<br />
  character_surfaces.each {|surface|<br />
    if surface.displayed then next end<br />
    # Check directional visibility for 2-side events<br />
    next unless should_render_two_side_event(surface.character, 4)<br />
  <br />
    dy = (&#36;game_player.x &lt;&lt; 7) - surface.dx<br />
    dx = (&#36;game_player.y &lt;&lt; 7) - surface.dy<br />
    add_character_surfaces(surface, dy, dx, surfaces_temp, i, 4)<br />
  }<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces liées à un évènement visibles quand le joueur est<br />
  # orienté vers la droite<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
def add_character_surfaces_right(character_surfaces)<br />
  surfaces_temp = []<br />
  i = &#36;game_system.fple_view_distance<br />
  character_surfaces.each {|surface|<br />
    if surface.displayed then next end<br />
    # Check directional visibility for 2-side events<br />
    next unless should_render_two_side_event(surface.character, 6)<br />
  <br />
    dy = surface.dx - (&#36;game_player.x &lt;&lt; 7)<br />
    dx = surface.dy - (&#36;game_player.y &lt;&lt; 7)<br />
    add_character_surfaces(surface, dy, dx, surfaces_temp, i, 6)<br />
  }<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Recherche les surfaces visibles quand le joueur tourne vers la droite<br />
  # param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
  #-----------------------------<br />
<br />
def position_occluded_during_rotation?(x, y, player_x, player_y, check_direction)<br />
  # Calculate the path from player to target position<br />
  dx = x - player_x<br />
  dy = y - player_y<br />
  <br />
    if @fple_map.get_data(x, y)[0] &gt; 0<br />
      return false unless &#36;game_map.region_id(&#36;game_player.x, &#36;game_player.y) == 0<br />
    else<br />
  end<br />
  <br />
  # Don't occlude events that are directly adjacent (doors on walls)<br />
  if dx.abs &lt;= 1 &amp;&amp; dy.abs &lt;= 1 &amp;&amp; (dx.abs + dy.abs) == 1<br />
    return false<br />
  end<br />
  <br />
  # For single-tile distances, check adjacent walls<br />
  if dx.abs &lt;= 1 &amp;&amp; dy.abs &lt;= 1<br />
    case check_direction<br />
    when 2 # Down<br />
      # Check for walls between player and target going down<br />
      return @fple_map.get_data(player_x, player_y + 1)[0] &gt; 0 if dy &gt; 0<br />
    when 4 # Left  <br />
      # Check for walls between player and target going left<br />
      return @fple_map.get_data(player_x - 1, player_y)[0] &gt; 0 if dx &lt; 0<br />
    when 6 # Right<br />
      # Check for walls between player and target going right  <br />
      return @fple_map.get_data(player_x + 1, player_y)[0] &gt; 0 if dx &gt; 0<br />
    when 8 # Up<br />
      # Check for walls between player and target going up<br />
      return @fple_map.get_data(player_x, player_y - 1)[0] &gt; 0 if dy &lt; 0<br />
    end<br />
  end<br />
  <br />
  # For longer distances, use line-of-sight checking<br />
  return line_of_sight_blocked?(player_x, player_y, x, y)<br />
end<br />
  <br />
#-----------------------------<br />
# * Check if line of sight is blocked by walls<br />
# param x1, y1 : Integer - start coordinates<br />
# param x2, y2 : Integer - end coordinates  <br />
# return Boolean - true if blocked<br />
#-----------------------------<br />
def line_of_sight_blocked?(x1, y1, x2, y2)<br />
  # Simple bresenham-like algorithm to check for wall blocking<br />
  dx = (x2 - x1).abs<br />
  dy = (y2 - y1).abs<br />
  <br />
  return false if dx == 0 &amp;&amp; dy == 0<br />
  <br />
  x_step = x1 &lt; x2 ? 1 : -1<br />
  y_step = y1 &lt; y2 ? 1 : -1<br />
  <br />
  # Check key points along the path<br />
  if dx &gt; dy<br />
    # More horizontal movement<br />
    (1..dx).each do |i|<br />
      check_x = x1 + (i * x_step)<br />
      check_y = y1 + ((i * dy * y_step) / dx)<br />
      return true if @fple_map.get_data(check_x, check_y)[0] &gt; 0<br />
    end<br />
  else<br />
    # More vertical movement  <br />
    (1..dy).each do |i|<br />
      check_x = x1 + ((i * dx * x_step) / dy)<br />
      check_y = y1 + (i * y_step)<br />
      return true if @fple_map.get_data(check_x, check_y)[0] &gt; 0<br />
    end<br />
  end<br />
  <br />
  false<br />
end<br />
<br />
#-----------------------------<br />
# * Enhanced character surface filtering with occlusion<br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
# param player_dir : Integer - current player direction<br />
# param rotation_dir : Integer - direction of rotation (next direction)<br />
# return Array&lt;FPLE::Surface_Characters&gt; - filtered surfaces<br />
#-----------------------------<br />
def filter_character_surfaces_with_occlusion(character_surfaces, player_dir, rotation_dir = nil)<br />
  return [] if character_surfaces.empty?<br />
  <br />
  player_x = &#36;game_player.x<br />
  player_y = &#36;game_player.y<br />
  filtered_surfaces = []<br />
  <br />
  character_surfaces.each do |surface|<br />
    next unless surface.character &amp;&amp; surface.visible &amp;&amp; surface.opacity &gt; 0<br />
    <br />
    char_x = surface.character.x<br />
    char_y = surface.character.y<br />
    <br />
    # Skip if too distant<br />
    dist_x = (player_x - char_x).abs  <br />
    dist_y = (player_y - char_y).abs<br />
    max_dist = &#36;game_system.fple_view_distance + 2<br />
    next if dist_x &gt; max_dist || dist_y &gt; max_dist<br />
    <br />
    # Check occlusion for current direction<br />
    current_occluded = position_occluded_during_rotation?(char_x, char_y, player_x, player_y, player_dir)<br />
    <br />
    # Check occlusion for rotation direction if specified<br />
    rotation_occluded = rotation_dir ?<br />
      position_occluded_during_rotation?(char_x, char_y, player_x, player_y, rotation_dir) : false<br />
    <br />
    # Include surface if visible from either direction<br />
    unless current_occluded &amp;&amp; rotation_occluded<br />
      filtered_surfaces &lt;&lt; surface<br />
    end<br />
  end<br />
  <br />
  filtered_surfaces<br />
end<br />
<br />
#-----------------------------<br />
# * Recherche les surfaces visibles quand le joueur tourne vers la droite<br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
#-----------------------------<br />
def refresh_surfaces_turn_right(character_surfaces)<br />
  @current_dir = &#36;game_player.direction<br />
  self.surfaces = []<br />
  @x_ref = &#36;game_player.x<br />
  @y_ref = &#36;game_player.y<br />
  surfaces_temp = refresh_current_surface<br />
  <br />
  # Filter character surfaces with occlusion checking<br />
  filtered_surfaces = filter_character_surfaces_with_occlusion(character_surfaces, @current_dir,<br />
    case @current_dir<br />
    when 2 then 6  # Down -&gt; Right<br />
    when 4 then 2  # Left -&gt; Down  <br />
    when 6 then 8  # Right -&gt; Up<br />
    when 8 then 4  # Up -&gt; Left<br />
    end)<br />
  <br />
  clear_character_surfaces(filtered_surfaces)<br />
  <br />
  case &#36;game_player.direction<br />
  when 2<br />
    surfaces_temp1 = refresh_surfaces_down<br />
    @current_dir = 6<br />
    surfaces_temp2 = refresh_surfaces_right(false)<br />
    @current_dir = 2<br />
    surfaces_temp1 += add_character_surfaces_down(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_right(filtered_surfaces)<br />
  when 4<br />
    surfaces_temp1 = refresh_surfaces_left<br />
    @current_dir = 2<br />
    surfaces_temp2 = refresh_surfaces_down(false)<br />
    @current_dir = 4<br />
    surfaces_temp1 += add_character_surfaces_left(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_down(filtered_surfaces)<br />
  when 6<br />
    surfaces_temp1 = refresh_surfaces_right<br />
    @current_dir = 8<br />
    surfaces_temp2 = refresh_surfaces_up(false)<br />
    @current_dir = 6<br />
    surfaces_temp1 += add_character_surfaces_right(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_up(filtered_surfaces)<br />
  when 8<br />
    surfaces_temp1 = refresh_surfaces_up<br />
    @current_dir = 4<br />
    surfaces_temp2 = refresh_surfaces_left(false)<br />
    @current_dir = 8<br />
    surfaces_temp1 += add_character_surfaces_up(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_left(filtered_surfaces)<br />
  end<br />
  <br />
  surfaces_temp1.each {|surface| adjust_surface_for_rotation(surface)}<br />
  <br />
  # set surfaces z attributes<br />
  (surfaces_temp + surfaces_temp1 + surfaces_temp2).each {|surface|<br />
    set_surface_z(surface)<br />
  }<br />
  surfaces.concat(surfaces_temp + surfaces_temp1 + surfaces_temp2)<br />
  surfaces.sort! {|a, b| b[5] - a[5]}<br />
end<br />
<br />
#-----------------------------<br />
# * Recherche les surfaces visibles quand le joueur tourne vers la gauche<br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
#-----------------------------<br />
def refresh_surfaces_turn_left(character_surfaces)<br />
  @current_dir = &#36;game_player.direction<br />
  self.surfaces = []<br />
  @x_ref = &#36;game_player.x<br />
  @y_ref = &#36;game_player.y<br />
  surfaces_temp = refresh_current_surface<br />
  <br />
  # Filter character surfaces with occlusion checking<br />
  filtered_surfaces = filter_character_surfaces_with_occlusion(character_surfaces, @current_dir,<br />
    case @current_dir<br />
    when 2 then 4  # Down -&gt; Left<br />
    when 4 then 8  # Left -&gt; Up<br />
    when 6 then 2  # Right -&gt; Down<br />
    when 8 then 6  # Up -&gt; Right<br />
    end)<br />
  <br />
  clear_character_surfaces(filtered_surfaces)<br />
  <br />
  case &#36;game_player.direction<br />
  when 2<br />
    @current_dir = 4<br />
    surfaces_temp1 = refresh_surfaces_left<br />
    @current_dir = 2<br />
    surfaces_temp2 = refresh_surfaces_down(false)<br />
    surfaces_temp1 += add_character_surfaces_left(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_down(filtered_surfaces)<br />
  when 4<br />
    @current_dir = 8<br />
    surfaces_temp1 = refresh_surfaces_up<br />
    @current_dir = 4<br />
    surfaces_temp2 = refresh_surfaces_left(false)<br />
    surfaces_temp1 += add_character_surfaces_up(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_left(filtered_surfaces)<br />
  when 6<br />
    @current_dir = 2<br />
    surfaces_temp1 = refresh_surfaces_down<br />
    @current_dir = 6<br />
    surfaces_temp2 = refresh_surfaces_right(false)<br />
    surfaces_temp1 += add_character_surfaces_down(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_right(filtered_surfaces)<br />
  when 8<br />
    @current_dir = 6<br />
    surfaces_temp1 = refresh_surfaces_right<br />
    @current_dir = 8<br />
    surfaces_temp2 = refresh_surfaces_up(false)<br />
    surfaces_temp1 += add_character_surfaces_right(filtered_surfaces)<br />
    surfaces_temp2 += add_character_surfaces_up(filtered_surfaces)<br />
  end<br />
  <br />
  surfaces_temp1.each {|surface| adjust_surface_for_rotation(surface)}<br />
  <br />
  # set surfaces z attributes<br />
  (surfaces_temp + surfaces_temp1 + surfaces_temp2).each {|surface|<br />
    set_surface_z(surface)<br />
  }<br />
  surfaces.concat(surfaces_temp + surfaces_temp1 + surfaces_temp2)<br />
  surfaces.sort! {|a, b| b[5] - a[5]}<br />
end<br />
<br />
#-----------------------------<br />
# * Enhanced turn up method (if needed for your system)<br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
#-----------------------------<br />
def refresh_surfaces_turn_up(character_surfaces)<br />
  @current_dir = &#36;game_player.direction<br />
  self.surfaces = []<br />
  @x_ref = &#36;game_player.x<br />
  @y_ref = &#36;game_player.y<br />
  surfaces_temp = refresh_current_surface<br />
  <br />
  # Filter character surfaces with occlusion checking<br />
  filtered_surfaces = filter_character_surfaces_with_occlusion(character_surfaces, @current_dir, 8)<br />
  <br />
  clear_character_surfaces(filtered_surfaces)<br />
  <br />
  # Render current direction surfaces<br />
  surfaces_temp1 = case &#36;game_player.direction<br />
  when 2 then refresh_surfaces_down<br />
  when 4 then refresh_surfaces_left  <br />
  when 6 then refresh_surfaces_right<br />
  when 8 then refresh_surfaces_up<br />
  else []<br />
  end<br />
  <br />
  # Render up direction surfaces<br />
  @current_dir = 8<br />
  surfaces_temp2 = refresh_surfaces_up(false)<br />
  @current_dir = &#36;game_player.direction<br />
  <br />
  # Add character surfaces<br />
  surfaces_temp1 += case &#36;game_player.direction<br />
  when 2 then add_character_surfaces_down(filtered_surfaces)<br />
  when 4 then add_character_surfaces_left(filtered_surfaces)<br />
  when 6 then add_character_surfaces_right(filtered_surfaces)<br />
  when 8 then add_character_surfaces_up(filtered_surfaces)<br />
  else []<br />
  end<br />
  <br />
  surfaces_temp2 += add_character_surfaces_up(filtered_surfaces)<br />
  <br />
  surfaces_temp1.each {|surface| adjust_surface_for_rotation(surface)} unless &#36;game_player.direction == 8<br />
  <br />
  # set surfaces z attributes<br />
  (surfaces_temp + surfaces_temp1 + surfaces_temp2).each {|surface|<br />
    set_surface_z(surface)<br />
  }<br />
  surfaces.concat(surfaces_temp + surfaces_temp1 + surfaces_temp2)<br />
  surfaces.sort! {|a, b| b[5] - a[5]}<br />
end<br />
<br />
#-----------------------------<br />
# * Enhanced turn down method (if needed for your system)  <br />
# param character_surfaces : Array&lt;FPLE::Surface_Characters&gt;<br />
#-----------------------------<br />
def refresh_surfaces_turn_down(character_surfaces)<br />
  @current_dir = &#36;game_player.direction<br />
  self.surfaces = []<br />
  @x_ref = &#36;game_player.x<br />
  @y_ref = &#36;game_player.y<br />
  surfaces_temp = refresh_current_surface<br />
  <br />
  # Filter character surfaces with occlusion checking<br />
  filtered_surfaces = filter_character_surfaces_with_occlusion(character_surfaces, @current_dir, 2)<br />
  <br />
  clear_character_surfaces(filtered_surfaces)<br />
  <br />
  # Render current direction surfaces<br />
  surfaces_temp1 = case &#36;game_player.direction<br />
  when 2 then refresh_surfaces_down<br />
  when 4 then refresh_surfaces_left<br />
  when 6 then refresh_surfaces_right<br />
  when 8 then refresh_surfaces_up<br />
  else []<br />
  end<br />
  <br />
  # Render down direction surfaces<br />
  @current_dir = 2<br />
  surfaces_temp2 = refresh_surfaces_down(false)<br />
  @current_dir = &#36;game_player.direction<br />
  <br />
  # Add character surfaces<br />
  surfaces_temp1 += case &#36;game_player.direction<br />
  when 2 then add_character_surfaces_down(filtered_surfaces)<br />
  when 4 then add_character_surfaces_left(filtered_surfaces)<br />
  when 6 then add_character_surfaces_right(filtered_surfaces)<br />
  when 8 then add_character_surfaces_up(filtered_surfaces)<br />
  else []<br />
  end<br />
  <br />
  surfaces_temp2 += add_character_surfaces_down(filtered_surfaces)<br />
  <br />
  surfaces_temp1.each {|surface| adjust_surface_for_rotation(surface)} unless &#36;game_player.direction == 2<br />
  <br />
  # set surfaces z attributes<br />
  (surfaces_temp + surfaces_temp1 + surfaces_temp2).each {|surface|<br />
    set_surface_z(surface)<br />
  }<br />
  surfaces.concat(surfaces_temp + surfaces_temp1 + surfaces_temp2)<br />
  surfaces.sort! {|a, b| b[5] - a[5]}<br />
end<br />
  #-----------------------------<br />
  # * Correction des attributs d'une surface visible pendant une rotation<br />
  # param surface : Array&lt;Integer&gt;<br />
  #-----------------------------<br />
  def adjust_surface_for_rotation(surface)<br />
    if surface[3] &lt; 5<br />
      dy = surface[1]<br />
      surface[1] = -surface[2]<br />
      surface[2] = dy<br />
      if surface[3] &lt; 2<br />
        surface[3] = 1 - surface[3]<br />
      end<br />
    else<br />
      if surface[7] &gt; 0<br />
        surface[7] = 3 - surface[7]<br />
      end  <br />
      dy = surface[1]<br />
      surface[1] = -surface[2]<br />
      surface[2] = dy<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral<br />
  # param offset : Integer<br />
  #-----------------------------<br />
  def refresh_surfaces_strafe(offset)<br />
    @current_dir = &#36;game_player.direction<br />
    @x_ref = &#36;game_player.x<br />
    @y_ref = &#36;game_player.y<br />
    case &#36;game_player.direction<br />
    when 2<br />
      @x_ref -= offset<br />
      surfaces_temp = refresh_surfaces_down_strafe<br />
    when 4<br />
      @y_ref -= offset<br />
      surfaces_temp = refresh_surfaces_left_strafe<br />
    when 6<br />
      @y_ref += offset<br />
      surfaces_temp = refresh_surfaces_right_strafe<br />
    when 8<br />
      @x_ref += offset<br />
      surfaces_temp = refresh_surfaces_up_strafe<br />
    end<br />
    # set surfaces z attributes<br />
    surfaces_temp.each {|surface| set_surface_z(surface)}<br />
    surfaces.concat(surfaces_temp)<br />
    surfaces.sort! {|a, b| b[5] - a[5]}<br />
  end<br />
  #-----------------------------<br />
  # * Rafraîchit la surface à la position du joueur<br />
  # return Array&lt;Array&lt;integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_current_surface<br />
    surfaces_temp = []<br />
    get_surface_ground(surfaces_temp, @x_ref, @y_ref, 0, 0)<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche les surfaces visibles de la carte quand le joueur est<br />
  # orienté vers le haut<br />
  # param right_ground : Boolean<br />
  # return Array&lt;Array&lt;integer&gt;&gt;<br />
  #-----------------------------<br />
def refresh_surfaces_up(right_ground = true)<br />
  surfaces_temp = []<br />
  base_distance = &#36;game_system.fple_view_distance<br />
  # Add extra tiles during rotation<br />
  i = FPLE.angle &gt; 0 ? base_distance + 1 : base_distance<br />
<br />
  while i &gt; 0<br />
    # peripherical ground/ceiling sprites<br />
    get_surface_ground(surfaces_temp, @x_ref - i, @y_ref - i, i &lt;&lt; 1, -i &lt;&lt; 1)<br />
    if right_ground<br />
      get_surface_ground(surfaces_temp, @x_ref + i, @y_ref - i, i &lt;&lt; 1, i &lt;&lt; 1)<br />
    end<br />
    klim = i - 1<br />
    (-klim..klim).each {|k|<br />
      add_surfaces(surfaces_temp, @x_ref + k, @y_ref - i, i &lt;&lt; 1, k &lt;&lt; 1, 0, 1)<br />
    }<br />
    i -= 1<br />
  end<br />
  return surfaces_temp<br />
end<br />
def refresh_surfaces_down(right_ground = true)<br />
  surfaces_temp = []<br />
  base_distance = &#36;game_system.fple_view_distance<br />
  # Add extra tiles during rotation<br />
  i = FPLE.angle &gt; 0 ? base_distance + 1 : base_distance<br />
<br />
  while i &gt; 0<br />
    # peripherical ground sprites<br />
    get_surface_ground(surfaces_temp, @x_ref + i, @y_ref + i, i &lt;&lt; 1, -i &lt;&lt; 1)<br />
    if right_ground<br />
      get_surface_ground(surfaces_temp, @x_ref - i, @y_ref + i, i &lt;&lt; 1, i &lt;&lt; 1)<br />
    end<br />
    klim = i - 1<br />
    (-klim..klim).each {|k|<br />
      add_surfaces(surfaces_temp, @x_ref - k, @y_ref + i, i &lt;&lt; 1, k &lt;&lt; 1, 0, -1)<br />
    }<br />
    i -= 1<br />
  end<br />
  return surfaces_temp<br />
end<br />
def refresh_surfaces_left(right_ground = true)<br />
  surfaces_temp = []<br />
  base_distance = &#36;game_system.fple_view_distance<br />
  # Add extra tiles during rotation<br />
  i = FPLE.angle &gt; 0 ? base_distance + 1 : base_distance<br />
<br />
  while i &gt; 0<br />
    # peripherical ground sprites<br />
    get_surface_ground(surfaces_temp, @x_ref - i, @y_ref + i, i &lt;&lt; 1, -i &lt;&lt; 1)<br />
    if right_ground<br />
      get_surface_ground(surfaces_temp, @x_ref - i, @y_ref - i, i &lt;&lt; 1, i &lt;&lt; 1)<br />
    end<br />
    klim = i - 1<br />
    (-klim..klim).each {|k|<br />
      add_surfaces(surfaces_temp, @x_ref - i, @y_ref - k, i &lt;&lt; 1, k &lt;&lt; 1, 1, 0)<br />
    }<br />
    i -= 1<br />
  end<br />
  return surfaces_temp<br />
end<br />
def refresh_surfaces_right(right_ground = true)<br />
  surfaces_temp = []<br />
  base_distance = &#36;game_system.fple_view_distance<br />
  # Add extra tiles during rotation<br />
  i = FPLE.angle &gt; 0 ? base_distance + 1 : base_distance<br />
<br />
  while i &gt; 0<br />
    # peripherical ground sprites<br />
    get_surface_ground(surfaces_temp, @x_ref + i, @y_ref - i, i &lt;&lt; 1, -i &lt;&lt; 1)<br />
    if right_ground<br />
      get_surface_ground(surfaces_temp, @x_ref + i, @y_ref + i, i &lt;&lt; 1, i &lt;&lt; 1)<br />
    end<br />
    klim = i - 1<br />
    (-klim..klim).each {|k|<br />
      add_surfaces(surfaces_temp, @x_ref + i, @y_ref + k, i &lt;&lt; 1, k &lt;&lt; 1, -1, 0)<br />
    }<br />
    i -= 1<br />
  end<br />
  return surfaces_temp<br />
end<br />
  #-----------------------------<br />
  # * Vérifie si un sol ou un plafond doit être affiché<br />
  # param surfaces_temp : Array&lt;Array&lt;Integer&gt;&gt;<br />
  # param x : Integer<br />
  # param y : Integer<br />
  # param dy : Integer<br />
  # param dx : Integer<br />
  #-----------------------------<br />
  def get_surface_ground(surfaces_temp, x, y, dy, dx)<br />
    if @fple_map.get_data(x, y)[0] == 0 # no wall tile<br />
      add_surface_ground(surfaces_temp, x, y, dy, dx)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Ajoute une surface de sol ou de plafond qui doit être affichée<br />
  # param surfaces_temp : Array&lt;Array&lt;Integer&gt;&gt;<br />
  # param x : Integer<br />
  # param y : Integer<br />
  # param dy : Integer<br />
  # param dx : Integer<br />
  #-----------------------------<br />
  def add_surface_ground(surfaces_temp, x, y, dy, dx)<br />
    g_texture_id = @fple_map.get_data(x, y)[1]<br />
    c_texture_id = @fple_map.get_data(x, y)[19]<br />
    if @fple_map.is_texture_id_valid?(g_texture_id)<br />
      if @fple_map.is_texture_id_valid?(c_texture_id)<br />
        surfaces_temp.push([g_texture_id, dy, dx, 4, c_texture_id, 0,<br />
        @fple_map.get_textureset_id(g_texture_id),<br />
        @fple_map.get_textureset_width(g_texture_id),<br />
        @fple_map.get_textureset_id(c_texture_id),<br />
        @fple_map.get_textureset_width(c_texture_id)])<br />
      else<br />
        surfaces_temp.push([g_texture_id, dy, dx, 2, 0, 0,<br />
        @fple_map.get_textureset_id(g_texture_id),<br />
        @fple_map.get_textureset_width(g_texture_id), 0, 8])<br />
      end<br />
    elsif @fple_map.is_texture_id_valid?(c_texture_id)<br />
      surfaces_temp.push([c_texture_id, dy, dx, 3, 0, 0,<br />
      @fple_map.get_textureset_id(c_texture_id),<br />
      @fple_map.get_textureset_width(c_texture_id), 0, 8])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles<br />
  # param surfaces_temp : Array&lt;Array&lt;Integer&gt;&gt;<br />
  # param x : Integer<br />
  # param y : Integer<br />
  # param dy : Integer<br />
  # param dx : Integer<br />
  # param oy : Integer<br />
  # param ox : Integer<br />
  #-----------------------------<br />
  def add_surfaces(surfaces_temp, x, y, dy, dx, ox, oy)<br />
    if @fple_map.get_data(x, y)[0] &gt; 0 # wall tile<br />
      if @fple_map.get_data(x + ox, y + oy)[0] == 0 # --&gt; visible !<br />
        texture_id = @fple_map.get_data(x, y)[<br />
        FPLE::MAP_SIDES[@current_dir - 1 &gt;&gt; 1]]<br />
        if @fple_map.is_texture_id_valid?(texture_id)<br />
          surfaces_temp.push([texture_id, dy - 1, dx, 1, 0, 0,<br />
          @fple_map.get_textureset_id(texture_id),<br />
          @fple_map.get_textureset_width(texture_id), 0, 8])<br />
        end<br />
      end<br />
    else<br />
      # ground/ceiling sprite<br />
      add_surface_ground(surfaces_temp, x, y, dy, dx)<br />
      # side walls<br />
      if dx &lt;= 0 # left<br />
        if @fple_map.get_data(x - oy, y + ox)[0] &gt; 0 # side wall tile<br />
          texture_id = @fple_map.get_data(x - oy, y + ox)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, dy, dx - 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      if dx &gt;= 0 # right<br />
        if @fple_map.get_data(x + oy, y - ox)[0] &gt; 0 # side wall tile<br />
          texture_id = @fple_map.get_data(x + oy, y - ox)[<br />
          FPLE::MAP_SIDES_RIGHT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, dy, dx + 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral quand le<br />
  # joueur est orienté vers le haut<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_surfaces_up_strafe<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    while i &gt; 0<br />
      get_surface_ground(surfaces_temp, @x_ref + i + 1, @y_ref - i, i &lt;&lt; 1,<br />
      i + 1 &lt;&lt; 1)<br />
      add_surfaces_strafe(surfaces_temp, @x_ref + i,  @y_ref - i, i &lt;&lt; 1, 0, 1)<br />
      # middle side wall<br />
      if @fple_map.get_data(@x_ref + 1, @y_ref - i)[0] == 0 # no wall tile<br />
        if @fple_map.get_data(@x_ref, @y_ref - i)[0] &gt; 0 # side wall tile (Left)<br />
          texture_id = @fple_map.get_data(@x_ref, @y_ref - i)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, i &lt;&lt; 1, 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      i -= 1<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral quand le<br />
  # joueur est orienté vers le bas<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_surfaces_down_strafe<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    while i &gt; 0<br />
      get_surface_ground(surfaces_temp, @x_ref - i - 1, @y_ref + i, i &lt;&lt; 1,<br />
      i + 1 &lt;&lt; 1)<br />
      add_surfaces_strafe(surfaces_temp, @x_ref - i,  @y_ref + i, i &lt;&lt; 1, 0, -1)<br />
      # middle side wall<br />
      if @fple_map.get_data(@x_ref - 1, @y_ref + i)[0] == 0 # no wall tile<br />
        if @fple_map.get_data(@x_ref, @y_ref + i)[0] &gt; 0 # side wall tile (Left)<br />
          texture_id = @fple_map.get_data(@x_ref, @y_ref + i)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, i &lt;&lt; 1, 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      i -= 1<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral quand le<br />
  # joueur est orienté vers la gauche<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_surfaces_left_strafe<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    while i &gt; 0<br />
      get_surface_ground(surfaces_temp, @x_ref - i, @y_ref - i - 1, i &lt;&lt; 1,<br />
      i + 1 &lt;&lt; 1)<br />
      add_surfaces_strafe(surfaces_temp, @x_ref - i,  @y_ref - i, i &lt;&lt; 1, 1, 0)<br />
      # middle side wall<br />
      if @fple_map.get_data(@x_ref - i, @y_ref - 1)[0] == 0 # no wall tile<br />
        if @fple_map.get_data(@x_ref - i, @y_ref)[0] &gt; 0 # side wall tile (Left)<br />
          texture_id = @fple_map.get_data(@x_ref - i, @y_ref)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, i &lt;&lt; 1, 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      i -= 1<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral quand le<br />
  # joueur est orienté vers la droite<br />
  # return Array&lt;Array&lt;Integer&gt;&gt;<br />
  #-----------------------------<br />
  def refresh_surfaces_right_strafe<br />
    surfaces_temp = []<br />
    i = &#36;game_system.fple_view_distance<br />
    while i &gt; 0<br />
      get_surface_ground(surfaces_temp, @x_ref + i, @y_ref + i + 1, i &lt;&lt; 1,<br />
      i + 1 &lt;&lt; 1)<br />
      add_surfaces_strafe(surfaces_temp, @x_ref + i,  @y_ref + i, i &lt;&lt; 1, -1, 0)<br />
      # middle side wall<br />
      if @fple_map.get_data(@x_ref + i, @y_ref + 1)[0] == 0 # no wall tile<br />
        if @fple_map.get_data(@x_ref + i, @y_ref)[0] &gt; 0 # side wall tile (Left)<br />
          texture_id = @fple_map.get_data(@x_ref + i, @y_ref)[<br />
          FPLE::MAP_SIDES_LEFT[@current_dir - 1 &gt;&gt; 1]]<br />
          if @fple_map.is_texture_id_valid?(texture_id)<br />
            surfaces_temp.push([texture_id, i &lt;&lt; 1, 1, 0, 0, 0,<br />
            @fple_map.get_textureset_id(texture_id),<br />
            @fple_map.get_textureset_width(texture_id), 0, 8])<br />
          end<br />
        end<br />
      end<br />
      i -= 1<br />
    end<br />
    return surfaces_temp<br />
  end<br />
  #-----------------------------<br />
  # * Recherche des surfaces visibles en déplacement latéral<br />
  # param surfaces_temp : Array&lt;Array&lt;Integer&gt;&gt;<br />
  # param x : Integer<br />
  # param y : Integer<br />
  # param dxy : Integer<br />
  # param oy : Integer<br />
  # param ox : Integer<br />
  #-----------------------------<br />
  def add_surfaces_strafe(surfaces_temp, x, y, dxy, ox, oy)<br />
    if @fple_map.get_data(x, y)[0] &gt; 0 # wall tile<br />
      if @fple_map.get_data(x + ox, y + oy)[0] == 0 # --&gt; visible !<br />
        texture_id = @fple_map.get_data(x, y)[<br />
        FPLE::MAP_SIDES[@current_dir - 1 &gt;&gt; 1]]<br />
        if @fple_map.is_texture_id_valid?(texture_id)<br />
          surfaces_temp.push([texture_id, dxy - 1, dxy, 1, 0, 0,<br />
          @fple_map.get_textureset_id(texture_id),<br />
          @fple_map.get_textureset_width(texture_id), 0, 8])<br />
        end<br />
      end<br />
    else<br />
      # side wall (Right)<br />
      if @fple_map.get_data(x + oy, y - ox)[0] &gt; 0 # side wall tile<br />
        texture_id = @fple_map.get_data(x + oy, y - ox)[<br />
        FPLE::MAP_SIDES_RIGHT[@current_dir - 1 &gt;&gt; 1]]<br />
        if @fple_map.is_texture_id_valid?(texture_id)<br />
          surfaces_temp.push([texture_id, dxy, dxy + 1, 0, 0, 0,<br />
          @fple_map.get_textureset_id(texture_id),<br />
          @fple_map.get_textureset_width(texture_id), 0, 8])<br />
        end<br />
      end<br />
    end<br />
end<br />
#==============================<br />
# ** Game_Character<br />
#==============================<br />
class Game_Character &lt; Game_CharacterBase<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias moving_fple_game_character? moving?<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Determine if Moving<br />
  # return Boolean<br />
  #-----------------------------<br />
  def moving?<br />
    if &#36;game_system.fple<br />
      return &#36;game_temp.movement || moving_fple_game_character?<br />
    else<br />
      return moving_fple_game_character?<br />
    end<br />
  end<br />
end<br />
#==============================<br />
# ** Game_Player<br />
#==============================<br />
class Game_Player &lt; Game_Character<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility) - mod [1.1]<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias move_straight_fple_game_player move_straight<br />
    alias move_diagonal_fple_game_player move_diagonal<br />
    alias turn_right_90_fple_game_player turn_right_90<br />
    alias turn_left_90_fple_game_player turn_left_90<br />
    alias move_by_input_fple_game_player move_by_input<br />
    alias update_nonmoving_fple_game_player update_nonmoving<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Initialize Public Member Variables<br />
  #-----------------------------<br />
  def init_public_members<br />
    super<br />
    @direction = 8<br />
  end<br />
  #-----------------------------<br />
  # * Move Straight<br />
  # param d : Integer<br />
  # param turn_ok : Boolean<br />
  #-----------------------------<br />
  def move_straight(d, turn_ok = true)<br />
    if &#36;game_system.fple<br />
      case d<br />
      when 2<br />
        case &#36;game_player.direction<br />
        when 2<br />
          go_forward<br />
        when 4<br />
          strafe_left<br />
        when 6<br />
          strafe_right<br />
        when 8<br />
          go_backward<br />
        end<br />
      when 4<br />
        case &#36;game_player.direction<br />
        when 2<br />
          strafe_right<br />
        when 4<br />
          go_forward<br />
        when 6<br />
          go_backward<br />
        when 8<br />
          strafe_left<br />
        end<br />
      when 6<br />
        case &#36;game_player.direction<br />
        when 2<br />
          strafe_left<br />
        when 4<br />
          go_backward<br />
        when 6<br />
          go_forward<br />
        when 8<br />
          strafe_right<br />
        end<br />
      when 8<br />
        case &#36;game_player.direction<br />
        when 2<br />
          go_backward<br />
        when 4<br />
          strafe_right<br />
        when 6<br />
          strafe_left<br />
        when 8<br />
          go_forward<br />
        end<br />
      end<br />
    else<br />
      move_straight_fple_game_player(d, turn_ok)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Move Diagonally<br />
  # param horz : Integer<br />
  # param vert : Integer<br />
  #-----------------------------<br />
  def move_diagonal(horz, vert)<br />
    unless &#36;game_system.fple<br />
      move_diagonal_fple_game_player(horz, vert)<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Jump<br />
  # param x_plus : Integer<br />
  # param y_plus : Integer<br />
  #-----------------------------<br />
  def jump(x_plus, y_plus)<br />
    unless &#36;game_system.fple<br />
      super(x_plus, y_plus) # [1.1]<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Turn 90° Right<br />
  #-----------------------------<br />
  def turn_right_90<br />
    turn_right_90_fple_game_player<br />
    if &#36;game_system.fple &amp;&amp; !@direction_fix<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 9<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Turn 90° Left<br />
  #-----------------------------<br />
  def turn_left_90<br />
    turn_left_90_fple_game_player<br />
    if &#36;game_system.fple &amp;&amp; !@direction_fix<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 10<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Go Forward<br />
  #-----------------------------<br />
  def go_forward<br />
    mvt_data = FPLE::PLAYER_MOVE_FORWARD[(@direction &gt;&gt; 1) - 1]<br />
    if passable?(@x, @y, @direction)<br />
      @x += mvt_data[0]<br />
      @y += mvt_data[1]<br />
      increase_steps<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 8<br />
    else<br />
      check_event_trigger_touch(@x + mvt_data[0], @y + mvt_data[1])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Go Backward<br />
  #-----------------------------<br />
  def go_backward<br />
    target_dir = 10 - @direction<br />
    mvt_data = FPLE::PLAYER_MOVE_FORWARD[(target_dir &gt;&gt; 1) - 1]<br />
    if passable?(@x, @y, target_dir)<br />
      @x += mvt_data[0]<br />
      @y += mvt_data[1]<br />
      increase_steps<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 2<br />
    else<br />
      check_event_trigger_touch(@x + mvt_data[0], @y + mvt_data[1])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Strafe Left<br />
  #-----------------------------<br />
  def strafe_left<br />
    target_dir = FPLE::TURN_LEFT[(@direction &gt;&gt; 1) - 1]<br />
    mvt_data = FPLE::PLAYER_MOVE_FORWARD[(target_dir &gt;&gt; 1) - 1]<br />
    if passable?(@x, @y, target_dir)<br />
      @x += mvt_data[0]<br />
      @y += mvt_data[1]<br />
      increase_steps<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 4<br />
    else<br />
      check_event_trigger_touch(@x + mvt_data[0], @y + mvt_data[1])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Strafe Right<br />
  #-----------------------------<br />
  def strafe_right<br />
    target_dir = 10 - FPLE::TURN_LEFT[(@direction &gt;&gt; 1) - 1]<br />
    mvt_data = FPLE::PLAYER_MOVE_FORWARD[(target_dir &gt;&gt; 1) - 1]<br />
    if passable?(@x, @y, target_dir)<br />
      @x += mvt_data[0]<br />
      @y += mvt_data[1]<br />
      increase_steps<br />
      &#36;game_temp.movement_init = false<br />
      &#36;game_temp.movement = true<br />
      &#36;game_temp.movement_dir = 6<br />
    else<br />
      check_event_trigger_touch(@x + mvt_data[0], @y + mvt_data[1])<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Processing of Movement via input from the Directional Buttons<br />
  #-----------------------------<br />
  def move_by_input<br />
    if &#36;game_system.fple<br />
      if !movable? || &#36;game_map.interpreter.running? then return end<br />
      if Input.press?(:L)<br />
        strafe_left<br />
      elsif Input.press?(:R)<br />
        strafe_right<br />
      else<br />
        case Input.dir4<br />
        when 2; go_backward<br />
        when 4; turn_left_90<br />
        when 6; turn_right_90<br />
        when 8; go_forward<br />
        end<br />
      end<br />
    else<br />
      move_by_input_fple_game_player<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Processing when not moving<br />
  # param last_moving : Boolean<br />
  #-----------------------------<br />
  def update_nonmoving(last_moving)<br />
    if &#36;game_map.interpreter.running? then return end<br />
    update_nonmoving_fple_game_player(last_moving)<br />
    if last_moving then &#36;game_temp.last_moving = false end<br />
  end<br />
  #-----------------------------<br />
  # * Move speed in FPLE mode<br />
  # return Integer<br />
  #-----------------------------<br />
  def move_speed_fple<br />
    return FPLE::PLAYER_MOVE_SPEED[real_move_speed]<br />
  end<br />
end<br />
#==============================<br />
# ** Game_Event<br />
#==============================<br />
class Game_Event &lt; Game_Character<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias refresh_fple_game_character refresh<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Public Instance Variables<br />
  #-----------------------------<br />
  attr_reader :fple_type # Integer 0:face the player<br />
                         #         1:horizontal wall in the RMXP editor view<br />
                         #         2:vertical wall in the RMXP editor view<br />
                         #         3:4-sided box (NEW)<br />
                         #         4:6-sided box (NEW)<br />
  attr_reader :fple_v_align # Integer - Vertical align {0:up, 1:middle, 2:down}<br />
  attr_reader :fple_d_align # Integer - Depth align {0:front/left, 1:middle, 2:back/right}<br />
  attr_reader :fple_stretch # Integer (0/1)<br />
  attr_reader :fple_fit # Integer (0/1)<br />
  attr_reader :fple_zoom # Integer (1024 &lt;=&gt; zoom = 1.0)<br />
  attr_reader :fple_one_side # Boolean (0/1)<br />
  attr_reader :fple_two_side # Boolean - NEW: indicates 6-sided box mode<br />
  attr_reader :fple_four_side # Boolean - NEW: indicates 4-sided box mode<br />
  attr_reader :fple_six_side # Boolean - NEW: indicates 6-sided box mode<br />
  #-----------------------------<br />
  # * Scan the event's commands list<br />
  # param page : RPG::Event::Page<br />
  #-----------------------------<br />
  def check_commands(page)<br />
    @fple_type = 0<br />
    @fple_v_align = 1<br />
    @fple_d_align = 1<br />
    @fple_stretch = 0<br />
    @fple_fit = 0<br />
    @fple_zoom = 1024<br />
    @fple_one_side = false # [1.5]<br />
    @fple_two_side = false # NEW<br />
    @fple_four_side = false # NEW<br />
    @fple_six_side = false # NEW<br />
    command_list = page.list<br />
    (0..command_list.length - 2).each {|k|<br />
      command = command_list[k]<br />
      if command.code == 108<br />
        comments = command.parameters[0]<br />
        if comments[/Type/]<br />
          @fple_type = comments[/&#92;d+/].to_i<br />
          if @fple_type &lt; 0 || @fple_type &gt; 2 then @fple_type = 0 end<br />
        end<br />
        if comments[/V-Align/]<br />
          @fple_v_align = comments[/&#92;d+/].to_i<br />
          if @fple_v_align &lt; 0 || @fple_v_align &gt; 2 then @fple_v_align = 1 end<br />
        end<br />
        if comments[/D-Align/]<br />
          @fple_d_align = comments[/&#92;d+/].to_i<br />
          if @fple_d_align &lt; 0 || @fple_d_align &gt; 2 then @fple_d_align = 1 end<br />
        end<br />
        if comments[/Stretch/]<br />
          @fple_stretch = 1<br />
        end<br />
        if comments[/Fit/]<br />
          @fple_fit = 1<br />
        end<br />
        if comments[/Zoom/]<br />
          @fple_zoom = (comments[/&#92;d+&#92;.&#92;d+/].to_f * 1024).round<br />
        end<br />
        if comments[/1-Side/] # [1.5]<br />
          @fple_one_side = true<br />
        end<br />
        if comments[/2-Side/] # NEW<br />
          @fple_four_side = true<br />
        end<br />
        if comments[/4-Side/] # NEW<br />
          @fple_four_side = true<br />
        end<br />
        if comments[/6-Side/] # NEW<br />
          @fple_six_side = true<br />
        end<br />
      end<br />
    }<br />
    if @fple_type == 0 then @fple_d_align = 1 end<br />
    if @fple_stretch == 1 then @fple_v_align = 1 end<br />
    if @fple_two_side<br />
    elsif @fple_four_side<br />
      @fple_type = 3 # Special type for 4-sided boxes<br />
      @fple_d_align = 1 # Center alignment makes most sense<br />
    elsif @fple_six_side<br />
      @fple_type = 4 # Special type for 6-sided boxes<br />
      @fple_d_align = 1 # Center alignment makes most sense<br />
    end<br />
  end<br />
<br />
  #-----------------------------<br />
  # * Refresh<br />
  #-----------------------------<br />
  def refresh<br />
    refresh_fple_game_character<br />
    if @page then check_commands(@page) end<br />
  end<br />
end<br />
#==============================<br />
# ** FPLE::Map_Data<br />
#==============================<br />
module FPLE<br />
  class Map_Data<br />
    #-----------------------------<br />
    # * Public Instance Variables<br />
    #-----------------------------<br />
    attr_accessor :data, :tileset_name, :map_name<br />
    attr_accessor :used_tiles_map, :textureset_data, :subsets_mapping<br />
    attr_reader :map_id, :width, :height<br />
  end<br />
end<br />
#==============================<br />
# ** FPLE::Map<br />
#==============================<br />
module FPLE<br />
  class Map<br />
    #-----------------------------<br />
    # * Public Instance Variables<br />
    #-----------------------------<br />
    attr_accessor :data, :tileset_name, :map_name<br />
    attr_reader :map_id, :width, :height<br />
    attr_accessor :textureset<br />
    attr_accessor :texturesets<br />
    #-----------------------------<br />
    # * Initialisation<br />
    # param width : integer (largeur de la carte, donc égal à &#36;game_map.width)<br />
    # param height : integer (hauteur de la carte, donc égal à &#36;game_map.height)<br />
    # param name : String (nom du fichier de la carte FPLE)<br />
    # param tileset_name : String (nom du tileset utilisé)<br />
    # param map_data : Array[width * height]&lt;Array&lt;integer&gt;&gt;<br />
    # param subsets_mapping : Hash&lt;Integer,String&gt; {texture_id=&gt;subset_name}<br />
    # param textureset_data : Array&lt;Array&gt; données de création du textureset<br />
    #-----------------------------<br />
    def initialize(width, height, name, tileset_name, map_data = nil,<br />
      subsets_mapping = nil, textureset_data = nil)<br />
      @width = width<br />
      @height = height<br />
      self.map_name = name<br />
      self.data = Array.new(width * height)<br />
      data.each_index {|index| data[index] = map_data[index]}<br />
      self.tileset_name = tileset_name<br />
      @subsets_mapping = subsets_mapping<br />
      create_textureset_from_data(textureset_data)<br />
    end<br />
    #-----------------------------<br />
    # * Retourne les données d'un tile par ses coordonées<br />
    # param x : integer ([0, width[)<br />
    # param y : integer ([0, height[)<br />
    # return Array[10]&lt;integer&gt; (map_Data)<br />
    #-----------------------------<br />
    def get_data(x, y)<br />
      ret = data[get_index(x, y)]<br />
      ret = [-1] unless ret<br />
      return ret<br />
    end<br />
    #-----------------------------<br />
    # * Retourne l'index d'un tile par ses coordonées<br />
    # param x : integer ([0, width[)<br />
    # param y : integer ([0, height[)<br />
    # return integer (&gt; 0)<br />
    #-----------------------------<br />
    def get_index(x, y)<br />
      return x + y * width<br />
    end<br />
    #-----------------------------<br />
    # * Retourne l'abscisse d'un tile par son index<br />
    # return integer ([0, width[)<br />
    #-----------------------------<br />
    def get_x(index)<br />
      return index - width * (index / width)<br />
    end<br />
    #-----------------------------<br />
    # * Retourne l'ordonnée d'un tile par son index<br />
    # return integer ([0, height[)<br />
    #-----------------------------<br />
    def get_y(index)<br />
      return index / width<br />
    end<br />
    #-----------------------------<br />
    # * Création du textureset<br />
    # param textureset_data : Array&lt;Array&gt; données de création du textureset<br />
    #-----------------------------<br />
        def get_texture_lazy(texture_id)<br />
      @texture_cache ||= {}<br />
      return @texture_cache[texture_id] if @texture_cache.has_key?(texture_id)<br />
    <br />
      # Only load texture if it will be used<br />
      if is_texture_id_valid?(texture_id)<br />
        @texture_cache[texture_id] = load_texture(texture_id)<br />
      else<br />
        @texture_cache[texture_id] = nil<br />
      end<br />
    <br />
      return @texture_cache[texture_id]<br />
    end<br />
  #-----------------------------<br />
    def create_textureset_from_data(textureset_data)<br />
      rect = Rect.new(0, 0, 32, 32)<br />
      textureset_height = 1 + (textureset_data.size &gt;&gt; 3) &lt;&lt; 5<br />
      self.textureset = Bitmap.new(256, textureset_height)<br />
      src = Cache.tileset(tileset_name)<br />
      textureset_data.each_index {|texture_id|<br />
        t_dat = textureset_data[texture_id]<br />
        if t_dat<br />
          x_trg = texture_id - (texture_id &gt;&gt; 3 &lt;&lt; 3) &lt;&lt; 5<br />
          y_trg = texture_id &gt;&gt; 3 &lt;&lt; 5<br />
          rect.x = t_dat[0]<br />
          rect.y = t_dat[1]<br />
          if t_dat[0] == 0 &amp;&amp; t_dat[1] == 0<br />
            @texture_id_nil = texture_id<br />
          end<br />
          textureset.blt(x_trg, y_trg, src, rect)<br />
        end<br />
      }<br />
      @texturesets = [textureset]<br />
      @texturesets_widths = [8]<br />
      @texturesets_mapping_ids = {}<br />
      subsets_names_list = []<br />
      if @subsets_mapping<br />
        @subsets_mapping.each {|texture_id, subset_name|<br />
          if subsets_names_list.include?(subset_name)<br />
            @texturesets_mapping_ids[texture_id] =<br />
            subsets_names_list.index(subset_name) + 1<br />
          else<br />
            subsets_names_list &lt;&lt; subset_name<br />
            subset = Cache.tileset(subset_name)<br />
            texturesets &lt;&lt; subset<br />
            for k in 5..9<br />
              if subset.width &gt;&gt; k == 1<br />
                @texturesets_widths &lt;&lt; k<br />
                break<br />
              end<br />
            end<br />
            @texturesets_mapping_ids[texture_id] = subsets_names_list.size<br />
          end<br />
        }<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Retourne l'index du textureset pour une texture<br />
    # param textureset_data : Integer<br />
    # return Integer<br />
    #-----------------------------<br />
    def get_textureset_id(texture_id)<br />
      if @texturesets_mapping_ids.has_key?(texture_id)<br />
        return @texturesets_mapping_ids[texture_id]<br />
      else<br />
        return 0<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Retourne la largeur du textureset pour une texture<br />
    # param textureset_data : Integer<br />
    # return Integer<br />
    #-----------------------------<br />
    def get_textureset_width(texture_id)<br />
      return @texturesets_widths[get_textureset_id(texture_id)]<br />
    end<br />
    #-----------------------------<br />
    # * Dispose<br />
    #-----------------------------<br />
    def dispose<br />
      if textureset then textureset.dispose end<br />
    end<br />
    #-----------------------------<br />
    # * Is texture valid<br />
    # param texture_id : Integer<br />
    # return Boolean<br />
    #-----------------------------<br />
    def is_texture_id_valid?(texture_id)<br />
      return texture_id &amp;&amp; texture_id != @texture_id_nil<br />
    end<br />
  end<br />
end<br />
#==============================<br />
# ** Spriteset_Weather<br />
#==============================<br />
class Spriteset_Weather<br />
  #-----------------------------<br />
  # * Modification of sprites coordinates when moving forward and backward<br />
  #-----------------------------<br />
  def update_fple<br />
    @sprites.each {|sprite|<br />
      if &#36;game_temp.movement_dir == 8<br />
        sprite.x += (sprite.x + @ox - 272) / 8<br />
        sprite.y += (sprite.y + @oy - 208) / 8<br />
        sprite.opacity += 8<br />
      elsif &#36;game_temp.movement_dir == 2<br />
        sprite.x -= (sprite.x + @ox - 272) / 8<br />
        sprite.y -= (sprite.y + @oy - 139) / 8<br />
        sprite.opacity -= 8<br />
      end<br />
    }<br />
  end<br />
end<br />
#==============================<br />
# ** FPLE::Spriteset_Map<br />
#==============================<br />
module FPLE<br />
  class Spriteset_Map &lt; ::Spriteset_Map<br />
    #-----------------------------<br />
    # * Public Instance Variables<br />
    #-----------------------------<br />
    attr_reader :character_surfaces # Array&lt;FPLE::Surface_Characters&gt;<br />
    attr_reader :viewport1 # Viewport<br />
    #-----------------------------<br />
    # * Create Tilemap<br />
    #-----------------------------<br />
    def create_tilemap<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Create Character Surfaces<br />
    #-----------------------------<br />
    def create_characters<br />
      @character_surfaces = []<br />
      &#36;game_map.events.values.each {|event|<br />
        character_surfaces &lt;&lt; FPLE::Surface_Character.new(self, event)<br />
      }<br />
      @map_id = &#36;game_map.map_id<br />
      initialize_fple_rendering<br />
    end<br />
    #-----------------------------<br />
    # * Create Airship Shadow Sprite<br />
    #-----------------------------<br />
    def create_shadow<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Initialize FPLE rendering<br />
    #-----------------------------<br />
    def initialize_fple_rendering<br />
      FPLE.initialize_fple(self, @viewport1)<br />
    end<br />
    #-----------------------------<br />
    # * Dispose<br />
    #-----------------------------<br />
    def dispose<br />
      dispose_fple_rendering<br />
      super<br />
    end<br />
    #-----------------------------<br />
    # * Dispose of FPLE rendering<br />
    #-----------------------------<br />
    def dispose_fple_rendering<br />
      FPLE.dispose<br />
    end<br />
    #-----------------------------<br />
    # * Free Tilemap<br />
    #-----------------------------<br />
    def dispose_tilemap<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Dispose of Character Surfaces<br />
    #-----------------------------<br />
    def dispose_characters<br />
      @character_surfaces.each {|surface| surface.dispose}<br />
    end<br />
    #-----------------------------<br />
    # * Free Airship Shadow Sprite<br />
    #-----------------------------<br />
    def dispose_shadow<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Update Tileset<br />
    #-----------------------------<br />
    def update_tileset<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Update Tilemap<br />
    #-----------------------------<br />
    def update_tilemap<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Update Parallax<br />
    #-----------------------------<br />
    def update_parallax<br />
      super<br />
      if @parallax.bitmap<br />
        @parallax.ox += (@parallax.bitmap.width * FPLE.angle) / 90<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Update Character Sprite<br />
    #-----------------------------<br />
    def update_characters<br />
      unless @map_id == &#36;game_map.map_id then refresh_characters end<br />
      character_surfaces.each {|surface| surface.update}<br />
      update_fple_rendering<br />
    end<br />
    #-----------------------------<br />
    # * Update FPLE Rendering<br />
    #-----------------------------<br />
    def update_fple_rendering<br />
      FPLE.update<br />
    end<br />
    #-----------------------------<br />
    # * Update Airship Shadow Sprite<br />
    #-----------------------------<br />
    def update_shadow<br />
      # do nothing<br />
    end<br />
    #-----------------------------<br />
    # * Update Weather<br />
    #-----------------------------<br />
    def update_weather<br />
      @weather.type = &#36;game_map.screen.weather_type<br />
      @weather.power = &#36;game_map.screen.weather_power<br />
      @weather.ox = &#36;game_map.display_x * 32 +<br />
      (Graphics.width * FPLE.angle) / 90 +<br />
      (Graphics.width * FPLE.offset_x &gt;&gt; 5)<br />
      @weather.oy = &#36;game_map.display_y * 32<br />
      @weather.update<br />
      if FPLE.offset_y &gt; 0 then @weather.update_fple end<br />
    end<br />
  end<br />
end<br />
#==============================<br />
# ** FPLE::Surface_Character<br />
#==============================<br />
module FPLE<br />
  class Surface_Character<br />
    #-----------------------------<br />
    # * Public Instance Variables<br />
    #-----------------------------<br />
    attr_accessor :character # Game_Event<br />
    attr_accessor :bitmap_set # Bitmap<br />
    attr_accessor :bitmap # Bitmap<br />
    attr_accessor :visible # Boolean<br />
    attr_accessor :opacity # Integer<br />
    attr_accessor :blend_type # Integer<br />
    attr_accessor :dx # Integer<br />
    attr_accessor :dy # Integer<br />
    attr_accessor :displayed # Boolean<br />
    attr_reader :spriteset # FPLE::Spriteset_Map<br />
    attr_reader :type # Integer<br />
    attr_reader :v_align # Integer<br />
    attr_reader :d_align # Integer<br />
    attr_reader :fit # Integer (0/1)<br />
    attr_reader :zoom # Integer (1024 &lt;=&gt; zoom = 1.0)<br />
    attr_reader :mirror # Integer (0/1) # [1.5]<br />
    #-----------------------------<br />
    # * Object Initialization<br />
    # param spriteset : FPLE::Spriteset_Map<br />
    # param character : Game_Event<br />
    #-----------------------------<br />
    def initialize(spriteset, character = nil)<br />
      @spriteset = spriteset<br />
      self.character = character<br />
      self.displayed = false<br />
      @need_refresh = false<br />
      @dx_old = 0<br />
      @dy_old = 0<br />
      @sx_old = -1<br />
      @sy_old = -1<br />
      @visible_old<br />
      @opacity_old<br />
      @blend_type_old<br />
      @sprite_temp = nil<br />
      @balloon_duration = 0<br />
      if character<br />
        @fit = character.fple_fit<br />
        @zoom = character.fple_zoom<br />
      else<br />
        @fit = 0<br />
        @zoom = 1024<br />
      end<br />
      @mirror = 0 # [1.5]<br />
      update<br />
    end<br />
    #-----------------------------<br />
    # * Dispose<br />
    #-----------------------------<br />
    def dispose<br />
      if @sprite_temp<br />
        @sprite_temp.dispose<br />
        @sprite_temp = nil<br />
      end<br />
      if bitmap_set then self.bitmap_set.dispose end<br />
      if bitmap then self.bitmap.dispose end<br />
    end<br />
    #-----------------------------<br />
    # * Get tile set image that includes the designated tile<br />
    # param tile_id : Integer<br />
    #-----------------------------<br />
    def tileset_bitmap(tile_id)<br />
      set_number = tile_id / 256<br />
      return Cache.system("TileB") if set_number == 0<br />
      return Cache.system("TileC") if set_number == 1<br />
      return Cache.system("TileD") if set_number == 2<br />
      return Cache.system("TileE") if set_number == 3<br />
      return nil<br />
    end<br />
    #-----------------------------<br />
    # * Frame Update<br />
    #-----------------------------<br />
    def update<br />
      update_bitmap<br />
      update_src_rect<br />
      update_position<br />
      update_other<br />
      update_balloon<br />
      setup_new_effect<br />
      if need_refresh? then force_render end<br />
    end<br />
    #-----------------------------<br />
    # * Update Transfer Origin Bitmap<br />
    #-----------------------------<br />
    def update_bitmap<br />
      if graphic_changed?<br />
        @tile_id = @character.tile_id<br />
        @character_name = @character.character_name<br />
        @character_index = @character.character_index<br />
        if @tile_id &gt; 0<br />
          set_tile_bitmap<br />
        else<br />
          set_character_bitmap<br />
        end<br />
        @need_refresh = true<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Determine if Graphic Changed<br />
    #-----------------------------<br />
    def graphic_changed?<br />
      @tile_id != character.tile_id ||<br />
      @character_name != character.character_name ||<br />
      @character_index != character.character_index<br />
    end<br />
    #-----------------------------<br />
    # * Set Tile Bitmap<br />
    #-----------------------------<br />
    def set_tile_bitmap<br />
      @sx = (@tile_id / 128 % 2 * 8 + @tile_id % 8) * 32;<br />
      @sy = @tile_id % 256 / 8 % 16 * 32;<br />
      self.bitmap_set = tileset_bitmap(@tile_id)<br />
      @cw = 32<br />
      @ch = 32<br />
      self.bitmap = Bitmap.new(@cw, @ch)<br />
    end<br />
    #-----------------------------<br />
    # * Set Character Bitmap<br />
    #-----------------------------<br />
    def set_character_bitmap<br />
      self.bitmap_set = Cache.character(@character_name)<br />
      sign = @character_name[/^[&#92;!&#92;&#36;]./]<br />
      if sign &amp;&amp; sign.include?('&#36;')<br />
        @cw = bitmap_set.width / 3<br />
        @ch = bitmap_set.height / 4<br />
      else<br />
        @cw = bitmap_set.width / 12<br />
        @ch = bitmap_set.height / 8<br />
      end<br />
      self.bitmap = Bitmap.new(@cw, @ch)<br />
    end<br />
    #-----------------------------<br />
    # * Update Transfer Origin Rectangle<br />
    #-----------------------------<br />
    def update_src_rect<br />
      if @tile_id == 0<br />
        index = character.character_index<br />
        pattern = character.pattern &lt; 3 ? character.pattern : 1<br />
        @sx = (index % 4 * 3 + pattern) * @cw<br />
        unless character.direction_fix<br />
          case &#36;game_player.direction<br />
          when 2<br />
            direction = 10 - character.direction<br />
          when 4<br />
            direction = 10 - FPLE::TURN_LEFT[(character.direction &gt;&gt; 1) - 1]<br />
          when 6<br />
            direction = FPLE::TURN_LEFT[(character.direction &gt;&gt; 1) - 1]<br />
          when 8<br />
            direction = character.direction<br />
          end<br />
        else<br />
          direction = character.direction<br />
        end<br />
        @sy = ((index &gt;&gt; 2 &lt;&lt; 2) + (direction - 2 &gt;&gt; 1)) * @ch<br />
      end<br />
      if @sx_old != @sx || @sy_old != @sy<br />
        return if @sx == @sx_old &amp;&amp; @sy == @sy_old &amp;&amp; !@bitmap_dirty<br />
        self.bitmap.clear<br />
        self.bitmap.blt(0, 0, bitmap_set, Rect.new(@sx, @sy, @cw, @ch))<br />
         @sx_old = @sx<br />
    @sy_old = @sy<br />
    @bitmap_dirty = false<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Update Position<br />
    #-----------------------------<br />
    def update_position<br />
      self.dx = (128 * character.real_x).to_i<br />
      self.dy = (128 * character.real_y).to_i<br />
    end<br />
    #-----------------------------<br />
    # * Update Other<br />
    #-----------------------------<br />
    def update_other<br />
      self.opacity = character.opacity<br />
      self.blend_type = character.blend_type<br />
      self.visible = !character.transparent<br />
    end<br />
    #-----------------------------<br />
    # * Set New Effect<br />
    #-----------------------------<br />
    def setup_new_effect<br />
      if character.animation_id &gt; 0<br />
        if displayed<br />
          unless @sprite_temp<br />
            # create a temporary sprite to launch animation<br />
            @sprite_temp = Sprite_Base.new(spriteset.viewport1)<br />
          end<br />
          coordinates = find_coordinates<br />
          if coordinates<br />
            @sprite_temp.x = coordinates[0]<br />
            @sprite_temp.y = coordinates[1]<br />
            animation = &#36;data_animations[character.animation_id]<br />
            @sprite_temp.start_animation(animation)<br />
          else<br />
            @sprite_temp.dispose<br />
            @sprite_temp = nil<br />
          end<br />
        end<br />
        character.animation_id = 0<br />
      end<br />
      if @sprite_temp<br />
        @sprite_temp.update<br />
        unless @sprite_temp.animation?<br />
          @sprite_temp.dispose<br />
          @sprite_temp = nil<br />
        end<br />
      end<br />
      if !@balloon_sprite &amp;&amp; character.balloon_id != 0<br />
        @balloon_id = character.balloon_id<br />
        start_balloon<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Determine if Changed<br />
    #-----------------------------<br />
    def need_refresh?<br />
      @need_refresh || @dx_old != dx || @dy_old != dy ||<br />
      @sx_old != @sx || @sy_old != @sy ||<br />
      @visible_old != visible || @opacity_old != opacity ||<br />
      @blend_type_old != blend_type<br />
    end<br />
    #-----------------------------<br />
    # * Force Render<br />
    #-----------------------------<br />
    def force_render<br />
      if displayed then &#36;game_temp.force_render = true end<br />
      @dx_old = dx<br />
      @dy_old = dy<br />
      @sx_old = @sx<br />
      @sy_old = @sy<br />
      @visible_old = visible<br />
      @opacity_old = opacity<br />
      @blend_type_old = blend_type<br />
      @need_refresh = false<br />
    end<br />
    #-----------------------------<br />
    # * Refresh FPLE attributes sepending on the relative frame of reference<br />
    # param direction : Integer<br />
    #-----------------------------<br />
def set_relative_attributes(direction)<br />
      # For 4-sided and 6-sided surfaces, we don't need to change attributes<br />
      # since all sides are rendered automatically<br />
      if character.fple_four_side<br />
        @type = 3 # Special identifier for 4-sided<br />
        @d_align = character.fple_d_align<br />
        @v_align = character.fple_v_align<br />
        @mirror = 0 # Could add logic for different mirror states per side if needed<br />
        return<br />
      elsif character.fple_six_side<br />
        @type = 4 # Special identifier for 6-sided<br />
        @d_align = character.fple_d_align<br />
        @v_align = character.fple_v_align<br />
        @mirror = 0 # Could add logic for different mirror states per side if needed<br />
        return<br />
      end<br />
      # Original logic for single surfaces<br />
      case direction<br />
      when 2<br />
        @type = character.fple_type<br />
        @d_align = 2 - character.fple_d_align<br />
        if character.fple_one_side<br />
          @mirror = 1<br />
          if type == 2 &amp;&amp; (&#36;game_player.x &lt;&lt; 7) - dx &lt;= 0<br />
            @mirror = 0<br />
          end<br />
        end<br />
      when 4<br />
        if character.fple_type &gt; 0<br />
          @type = 3 - character.fple_type<br />
        else<br />
          @type = 0<br />
        end<br />
        if character.fple_type &lt; 2<br />
          @d_align = character.fple_d_align<br />
        elsif character.fple_type == 2<br />
          @d_align = 2 - character.fple_d_align<br />
        end<br />
        if character.fple_one_side<br />
          @mirror = 1<br />
          if type == 2 &amp;&amp; (&#36;game_player.y &lt;&lt; 7) - dy &gt; 0<br />
            @mirror = 0<br />
          end<br />
        end<br />
      when 6<br />
        if character.fple_type &gt; 0<br />
          @type = 3 - character.fple_type<br />
        else<br />
          @type = 0<br />
        end<br />
        if character.fple_type &lt; 2<br />
          @d_align = 2 - character.fple_d_align<br />
        elsif character.fple_type == 2<br />
          @d_align = character.fple_d_align<br />
        end<br />
        if character.fple_one_side<br />
          @mirror = 0<br />
          if type == 2 &amp;&amp; (&#36;game_player.y &lt;&lt; 7) - dy &lt; 0<br />
            @mirror = 1<br />
          end<br />
        end<br />
      when 8<br />
        @type = character.fple_type<br />
        @d_align = character.fple_d_align<br />
        if character.fple_one_side<br />
          @mirror = 0<br />
          if type == 2 &amp;&amp; (&#36;game_player.x &lt;&lt; 7) - dx &gt;= 0<br />
            @mirror = 1<br />
          end<br />
        end<br />
      end<br />
      @v_align = character.fple_v_align<br />
    end<br />
    #-----------------------------<br />
    # * Calculate screen coordinates to display animations<br />
    # return Array[2]&lt;Integer&gt;<br />
    #-----------------------------<br />
  def find_coordinates<br />
      direction = &#36;game_player.direction<br />
      case direction<br />
      when 2<br />
        y = dy - (&#36;game_player.y &lt;&lt; 7)<br />
        x = (&#36;game_player.x &lt;&lt; 7) - dx<br />
      when 4<br />
        y = (&#36;game_player.x &lt;&lt; 7) - dx<br />
        x = (&#36;game_player.y &lt;&lt; 7) - dy<br />
      when 6<br />
        y = dx - (&#36;game_player.x &lt;&lt; 7)<br />
        x = dy - (&#36;game_player.y &lt;&lt; 7)<br />
      when 8<br />
        y = (&#36;game_player.y &lt;&lt; 7) - dy<br />
        x = dx - (&#36;game_player.x &lt;&lt; 7)<br />
      end<br />
      if y == 0 then return nil end<br />
      offset_x = 0<br />
      offset_y = 0<br />
      if character.fple_v_align != 1<br />
        x1_proj = 272 + (272 * x - (136 &lt;&lt; 7)) / y<br />
        x2_proj = 272 + (272 * x + (136 &lt;&lt; 7)) / y<br />
        offset_x = x2_proj - x1_proj &gt;&gt; 1<br />
        offset_y = offset_x<br />
        if bitmap<br />
          offset_x -= (bitmap.width &gt;&gt; 1)<br />
          offset_y -= (bitmap.height &gt;&gt; 1)<br />
        end<br />
      end<br />
      x_proj = 272 + (272 * x) / y<br />
      y_proj = ((544 * y) - (272 &lt;&lt; 7)) / (y &lt;&lt; 1)<br />
      if character.fple_v_align == 0<br />
        y_proj -= offset_y<br />
      elsif character.fple_v_align == 2<br />
        y_proj += offset_y<br />
      end<br />
      return [x_proj, y_proj]<br />
    end<br />
    #-----------------------------<br />
    # * Start Balloon Icon Display<br />
    #-----------------------------<br />
    def start_balloon<br />
      dispose_balloon<br />
      @balloon_duration = 8 * balloon_speed + balloon_wait<br />
      @balloon_sprite = ::Sprite.new(spriteset.viewport1)<br />
      @balloon_sprite.bitmap = Cache.system("Balloon")<br />
      @balloon_sprite.ox = -16<br />
      @balloon_sprite.oy = +128<br />
      update_balloon<br />
    end<br />
    #-----------------------------<br />
    # * Dispose of Balloon Icon<br />
    #-----------------------------<br />
    def dispose_balloon<br />
      if @balloon_sprite<br />
        @balloon_sprite.dispose<br />
        @balloon_sprite = nil<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * Update Balloon Icon<br />
    #-----------------------------<br />
    def update_balloon<br />
      if @balloon_duration &gt; 0<br />
        @balloon_duration -= 1<br />
        if @balloon_duration &gt; 0<br />
          coordinates = find_coordinates<br />
          if coordinates<br />
            @balloon_sprite.x = coordinates[0]<br />
            @balloon_sprite.y = coordinates[1]<br />
            @balloon_sprite.z = 9999<br />
            sx = balloon_frame_index * 32<br />
            sy = (@balloon_id - 1) * 32<br />
            @balloon_sprite.src_rect.set(sx, sy, 32, 32)<br />
          else<br />
            end_balloon<br />
          end<br />
        else<br />
          end_balloon<br />
        end<br />
      end<br />
    end<br />
    #-----------------------------<br />
    # * End Balloon Icon<br />
    #-----------------------------<br />
    def end_balloon<br />
      dispose_balloon<br />
      character.balloon_id = 0<br />
    end<br />
    #-----------------------------<br />
    # * Balloon Icon Display Speed<br />
    #-----------------------------<br />
    def balloon_speed<br />
      return 8<br />
    end<br />
    #-----------------------------<br />
    # * Wait Time for Last Frame of Balloon<br />
    #-----------------------------<br />
    def balloon_wait<br />
      return 12<br />
    end<br />
    #-----------------------------<br />
    # * Frame Number of Balloon Icon<br />
    #-----------------------------<br />
    def balloon_frame_index<br />
      return 7 - [(@balloon_duration - balloon_wait) / balloon_speed, 0].max<br />
    end<br />
  end<br />
end<br />
<br />
#==============================<br />
# ** Scene_Map<br />
#==============================<br />
class Scene_Map &lt; Scene_Base<br />
  #-----------------------------<br />
  # * Aliased methods (F12 compatibility)<br />
  #-----------------------------<br />
  unless @already_aliased_fple<br />
    alias create_spriteset_fple create_spriteset<br />
    alias perform_transfer_fple perform_transfer<br />
    alias post_transfer_fple post_transfer<br />
    @already_aliased_fple = true<br />
  end<br />
  #-----------------------------<br />
  # * Create Sprite Set<br />
  #-----------------------------<br />
  def create_spriteset<br />
    if &#36;game_system.fple<br />
      @spriteset = FPLE::Spriteset_Map.new<br />
    else<br />
      create_spriteset_fple<br />
    end<br />
  end<br />
  #-----------------------------<br />
  # * Player Transfer Processing<br />
  #-----------------------------<br />
  def perform_transfer<br />
    @exec_transfer = &#36;game_player.transfer?<br />
    @fple_old = &#36;game_system.fple<br />
    perform_transfer_fple<br />
  end<br />
  #-----------------------------<br />
  # * Post Processing for Transferring Player<br />
  #-----------------------------<br />
  def post_transfer<br />
    if @exec_transfer &amp;&amp; @fple_old != &#36;game_system.fple<br />
      @spriteset.dispose<br />
      create_spriteset<br />
    end<br />
    if &#36;game_system.fple<br />
      &#36;game_temp.force_render = true<br />
    end<br />
    post_transfer_fple<br />
  end<br />
end</code></div></div><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** FPLE Background Picture Addon - Enhanced<br />
#v.1.5 old, now upgraded to v.1.8 using Claude.AI by 5Brainplay.<br />
#==============================================================================<br />
# This addon creates a background picture that renders behind all FPLE surfaces<br />
# but in front of the engine's default background to prevent color bleeding.<br />
# The background now positions itself at VIEW_DISTANCE + 1 for proper depth.<br />
#==============================================================================<br />
<br />
module FPLE<br />
  #--------------------------------------------------------------------------<br />
  # * Background Picture Configuration<br />
  #--------------------------------------------------------------------------<br />
  BACKGROUND_ENABLED = false      # Enable/disable background picture<br />
  BACKGROUND_COLOR = Color.new(115, 190, 215, 255)  # Default color (R,G,B,A)<br />
  BACKGROUND_PICTURE_FILE = nil  # Optional: use "filename" for custom image<br />
  BACKGROUND_Z_DEPTH = -999    # Z-depth (negative = behind everything)<br />
end<br />
<br />
#==============================================================================<br />
# ** FPLE Core - Modified<br />
#==============================================================================<br />
module FPLE<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased initialization method<br />
  #--------------------------------------------------------------------------<br />
  class &lt;&lt; self<br />
    unless @background_addon_aliased<br />
      alias initialize_fple_background initialize_fple<br />
      @background_addon_aliased = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Initialize with background<br />
  #--------------------------------------------------------------------------<br />
  def self.initialize_fple(spriteset, viewport)<br />
    initialize_fple_background(spriteset, viewport)<br />
    if BACKGROUND_ENABLED<br />
      create_background_picture(viewport)<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create background picture with view distance integration<br />
  #--------------------------------------------------------------------------<br />
  def self.create_background_picture(viewport)<br />
    @background_sprite = Sprite.new(viewport)<br />
    @background_sprite.z = BACKGROUND_Z_DEPTH<br />
    <br />
    if BACKGROUND_PICTURE_FILE &amp;&amp; FileTest.exist?("Graphics/Pictures/#{BACKGROUND_PICTURE_FILE}.png")<br />
      # Use custom image file<br />
      @background_sprite.bitmap = Cache.picture(BACKGROUND_PICTURE_FILE)<br />
    else<br />
      # Create solid color background<br />
      @background_sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height)<br />
      @background_sprite.bitmap.fill_rect(0, 0, Graphics.width, Graphics.height, BACKGROUND_COLOR)<br />
    end<br />
    <br />
    # Position behind everything but visible<br />
    @background_sprite.x = 0<br />
    @background_sprite.y = 0<br />
    <br />
    # Add background surface to the surfaces array for proper depth rendering<br />
    create_background_surface<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create background surface at VIEW_DISTANCE + 1<br />
  #--------------------------------------------------------------------------<br />
  def self.create_background_surface<br />
    # Calculate the distance to render the background at (VIEW_DISTANCE + 1)<br />
    background_distance = (&#36;game_system.fple_view_distance + 1) &lt;&lt; 7<br />
    <br />
    # Create a background surface that will be processed by the 3D engine<br />
    @background_surface = [<br />
      0,                          # texture_id (0 = no texture, use solid color)<br />
      background_distance,        # dy (depth distance)<br />
      0,                          # dx (horizontal offset)<br />
      6,                          # type (6 = background plane, custom type)<br />
      0,                          # secondary texture<br />
      0,                          # z-order placeholder<br />
      0,                          # textureset_id<br />
      8,                          # textureset_width<br />
      BACKGROUND_COLOR.red,       # red component<br />
      BACKGROUND_COLOR.green,     # green component<br />
      BACKGROUND_COLOR.blue,      # blue component<br />
      BACKGROUND_COLOR.alpha      # alpha component<br />
    ]<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Add background surface to game map surfaces<br />
  #--------------------------------------------------------------------------<br />
  def self.add_background_to_surfaces<br />
    return unless BACKGROUND_ENABLED &amp;&amp; @background_surface<br />
    <br />
    # Calculate proper z-depth for background<br />
    distance = (&#36;game_system.fple_view_distance) &lt;&lt; 1<br />
    @background_surface[5] = distance &lt;&lt; 5  # Set z-order<br />
    <br />
    # Add background surface to the main surfaces array if not already present<br />
    unless &#36;game_map.surfaces.any? { |surface| surface[3] == 6 }<br />
      &#36;game_map.surfaces.push(@background_surface.dup)<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Aliased dispose method<br />
  #--------------------------------------------------------------------------<br />
  class &lt;&lt; self<br />
    unless @dispose_background_aliased<br />
      alias dispose_background dispose<br />
      @dispose_background_aliased = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Dispose with background cleanup<br />
  #--------------------------------------------------------------------------<br />
  def self.dispose<br />
    dispose_background<br />
    if @background_sprite<br />
      @background_sprite.dispose<br />
      @background_sprite = nil<br />
    end<br />
    @background_surface = nil<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Update background (called during movement/rotation)<br />
  #--------------------------------------------------------------------------<br />
  def self.update_background<br />
    return unless @background_surface &amp;&amp; BACKGROUND_ENABLED<br />
    <br />
    # Update the background distance based on current view distance<br />
    background_distance = (&#36;game_system.fple_view_distance) &lt;&lt; 7<br />
    @background_surface[1] = background_distance<br />
    <br />
    # Update z-order<br />
    distance = (&#36;game_system.fple_view_distance) &lt;&lt; 1<br />
    @background_surface[5] = distance &lt;&lt; 5<br />
    <br />
    # Add parallax effects if desired<br />
    if @angle != 0<br />
      # Slight horizontal shift based on rotation<br />
      @background_surface[2] = (@angle * 2)  # Adjust multiplier as needed<br />
    else<br />
      @background_surface[2] = 0<br />
    end<br />
    <br />
    # Adjust for movement offsets if desired (subtle parallax)<br />
    # @background_surface[2] += @offset_x / 8<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Aliased update method<br />
  #--------------------------------------------------------------------------<br />
  class &lt;&lt; self<br />
    unless @update_background_aliased<br />
      alias update_fple_background update<br />
      @update_background_aliased = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Update with background<br />
  #--------------------------------------------------------------------------<br />
  def self.update<br />
    update_fple_background<br />
    if BACKGROUND_ENABLED<br />
      update_background<br />
      add_background_to_surfaces<br />
    end<br />
  end<br />
end<br />
<br />
#==============================================================================<br />
# ** Game_Map - Background Integration<br />
#==============================================================================<br />
class Game_Map<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased refresh_surfaces method<br />
  #--------------------------------------------------------------------------<br />
  unless @background_surfaces_aliased<br />
    alias refresh_surfaces_background refresh_surfaces<br />
    @background_surfaces_aliased = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Refresh surfaces with background integration<br />
  #--------------------------------------------------------------------------<br />
  def refresh_surfaces<br />
    refresh_surfaces_background<br />
      surfaces.sort! { |a, b| b[5] - a[5] } if surfaces.any? { |s| s[3] == 6 }<br />
  end<br />
end<br />
<br />
#==============================================================================<br />
# ** Game_Interpreter - Script Commands<br />
#==============================================================================<br />
class Game_Interpreter<br />
  #--------------------------------------------------------------------------<br />
  # * Change FPLE Background Color<br />
  #--------------------------------------------------------------------------<br />
  def change_fple_background_color(red, green, blue, alpha = 255)<br />
    return unless &#36;game_system.fple &amp;&amp; FPLE::BACKGROUND_ENABLED<br />
    <br />
    # Update the background surface color<br />
    if FPLE.instance_variable_get(:@background_surface)<br />
      surface = FPLE.instance_variable_get(:@background_surface)<br />
      surface[8] = red<br />
      surface[9] = green<br />
      surface[10] = blue<br />
      surface[11] = alpha<br />
    end<br />
    <br />
    # Also update the sprite for immediate visual feedback<br />
    if FPLE.instance_variable_get(:@background_sprite)<br />
      sprite = FPLE.instance_variable_get(:@background_sprite)<br />
      color = Color.new(red, green, blue, alpha)<br />
      sprite.bitmap.fill_rect(0, 0, Graphics.width, Graphics.height, color)<br />
    end<br />
    <br />
    &#36;game_temp.force_render = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Change FPLE Background Picture<br />
  #--------------------------------------------------------------------------<br />
  def change_fple_background_picture(filename)<br />
    return unless &#36;game_system.fple &amp;&amp; FPLE::BACKGROUND_ENABLED<br />
    <br />
    if FPLE.instance_variable_get(:@background_sprite)<br />
      sprite = FPLE.instance_variable_get(:@background_sprite)<br />
      sprite.bitmap.dispose if sprite.bitmap<br />
      <br />
      if filename &amp;&amp; FileTest.exist?("Graphics/Pictures/#{filename}.png")<br />
        sprite.bitmap = Cache.picture(filename)<br />
        # When using a picture, set surface type to use texture instead of color<br />
        if FPLE.instance_variable_get(:@background_surface)<br />
          surface = FPLE.instance_variable_get(:@background_surface)<br />
          surface[0] = 1  # Enable texture rendering<br />
        end<br />
      else<br />
        # Fallback to solid color<br />
        sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height)<br />
        sprite.bitmap.fill_rect(0, 0, Graphics.width, Graphics.height, FPLE::BACKGROUND_COLOR)<br />
        # Reset to color mode<br />
        if FPLE.instance_variable_get(:@background_surface)<br />
          surface = FPLE.instance_variable_get(:@background_surface)<br />
          surface[0] = 0  # Disable texture, use color<br />
        end<br />
      end<br />
    end<br />
    <br />
    &#36;game_temp.force_render = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Toggle FPLE Background<br />
  #--------------------------------------------------------------------------<br />
  def toggle_fple_background(enabled)<br />
    return unless &#36;game_system.fple<br />
    <br />
    if FPLE.instance_variable_get(:@background_sprite)<br />
      sprite = FPLE.instance_variable_get(:@background_sprite)<br />
      sprite.visible = enabled<br />
    end<br />
    <br />
    # Remove or add background surface based on enabled state<br />
    if enabled<br />
      FPLE.add_background_to_surfaces<br />
    else<br />
      &#36;game_map.surfaces.reject! { |surface| surface[3] == 6 }<br />
    end<br />
    <br />
    &#36;game_temp.force_render = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Update Background Distance (call when VIEW_DISTANCE changes)<br />
  #--------------------------------------------------------------------------<br />
  def update_background_distance<br />
    return unless &#36;game_system.fple &amp;&amp; FPLE::BACKGROUND_ENABLED<br />
    <br />
    if FPLE.instance_variable_get(:@background_surface)<br />
      FPLE.update_background<br />
      &#36;game_temp.force_render = true<br />
    end<br />
  end<br />
end<br />
<br />
#==============================================================================<br />
# ** Game_Temp - Background Integration<br />
#==============================================================================<br />
class Game_Temp<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased set_view method to update background distance<br />
  #--------------------------------------------------------------------------<br />
  unless @background_view_aliased<br />
    alias set_view_background set_view<br />
    @background_view_aliased = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Set view distance with background update<br />
  #--------------------------------------------------------------------------<br />
  def set_view(distance)<br />
    set_view_background(distance)<br />
    <br />
    # Update background distance when view distance changes<br />
    if &#36;game_system.fple &amp;&amp; FPLE::BACKGROUND_ENABLED<br />
      FPLE.update_background<br />
    end<br />
  end<br />
end<br />
<br />
#==============================================================================<br />
# ** Usage Instructions<br />
#==============================================================================<br />
# Place this script below the main FPLE script but above Main.<br />
#<br />
# Configuration:<br />
# - BACKGROUND_ENABLED: Set to true/false to enable/disable<br />
# - BACKGROUND_COLOR: Set the RGB color (0-255 for each value)  <br />
# - BACKGROUND_PICTURE_FILE: Optional - use a picture file instead of solid color<br />
# - BACKGROUND_Z_DEPTH: Z-depth value (negative = behind surfaces)<br />
#<br />
# The background will automatically render at VIEW_DISTANCE + 1, providing<br />
# a backdrop that appears behind all game surfaces but maintains proper depth.<br />
#<br />
# Script Commands (use in events):<br />
# - change_fple_background_color(255, 0, 0)    # Change to red<br />
# - change_fple_background_picture("sunset")   # Use Graphics/Pictures/sunset.png  <br />
# - toggle_fple_background(false)              # Hide background<br />
# - toggle_fple_background(true)               # Show background<br />
# - update_background_distance                 # Refresh after VIEW_DISTANCE changes<br />
#==============================================================================</code></div></div><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#===============================================================================<br />
# FPLE Ground Tile Swap Addon v1.1<br />
# v.1.5 old, now upgraded to v.1.8 using Claude.AI by 5Brainplay.<br />
# Author: Assistant<br />
#===============================================================================<br />
# This addon allows swapping ground tiles in FPLE maps during gameplay.<br />
# Place this script below the main FPLE script but above "Main"<br />
#<br />
# Features:<br />
# - Swap ground tiles at specific coordinates<br />
# - Batch swap multiple tiles<br />
# - Restore original tiles<br />
# - Event-based tile swapping<br />
# - Animated tile transitions (optional)<br />
# - Region-based ground tile swapping<br />
# - Animated region tiles<br />
#<br />
# Usage Examples:<br />
# &#36;game_map.swap_ground_tile(x, y, new_texture_id)<br />
# &#36;game_map.restore_ground_tile(x, y)<br />
# &#36;game_map.batch_swap_ground_tiles([[x1, y1, texture1], [x2, y2, texture2]])<br />
# &#36;game_map.swap_region_ground_tiles(region_id, texture_id)<br />
#<br />
# Event Commands:<br />
# In event "Script..." command:<br />
# swap_ground(x, y, texture_id)<br />
# restore_ground(x, y)<br />
# swap_region_ground(region_id, texture_id)<br />
# animate_region_ground(region_id, base_texture_id)<br />
#===============================================================================<br />
#==============================================================================<br />
# ** Game_Map - Ground Tile Swapping Extensions<br />
#==============================================================================<br />
class Game_Map<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased methods<br />
  #--------------------------------------------------------------------------<br />
  unless @already_aliased_ground_swap<br />
    alias initialize_ground_swap initialize<br />
    alias setup_ground_swap setup<br />
    @already_aliased_ground_swap = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Public Instance Variables<br />
  #--------------------------------------------------------------------------<br />
  attr_accessor :original_ground_tiles  # Hash to store original tile data<br />
  attr_accessor :swapped_ground_tiles   # Hash to track swapped tiles<br />
  attr_accessor :animated_ground_tiles  # Hash to store animation data<br />
  attr_accessor :ground_animation_timer # Integer for frame counting<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Object Initialization<br />
  #--------------------------------------------------------------------------<br />
  def initialize<br />
    initialize_ground_swap<br />
    @original_ground_tiles = {}<br />
    @swapped_ground_tiles = {}<br />
    @animated_ground_tiles = {}<br />
    @ground_animation_timer = 0<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Setup<br />
  #--------------------------------------------------------------------------<br />
  def setup(map_id)<br />
    setup_ground_swap(map_id)<br />
    @original_ground_tiles = {}<br />
    @swapped_ground_tiles = {}<br />
    @animated_ground_tiles = {}<br />
    @ground_animation_timer = 0<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Swap Ground Tile at Specific Coordinates<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate  <br />
  # param new_texture_id : Integer - New ground texture ID<br />
  # param animate : Boolean - Whether to animate the transition (optional)<br />
  #--------------------------------------------------------------------------<br />
  def swap_ground_tile(x, y, new_texture_id, animate = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless valid_coordinates?(x, y)<br />
    <br />
    key = [x, y]<br />
    <br />
    # Store original tile data if not already stored<br />
    unless @original_ground_tiles.has_key?(key)<br />
      original_data = @fple_map.get_data(x, y).dup<br />
      @original_ground_tiles[key] = original_data<br />
    end<br />
    <br />
    # Use FPLE's proper method to change ground texture<br />
    if @fple_map.respond_to?(:change_ground)<br />
      @fple_map.change_ground(x, y, new_texture_id)<br />
    elsif @fple_map.respond_to?(:set_ground_tile)<br />
      @fple_map.set_ground_tile(x, y, new_texture_id)<br />
    else<br />
      # Fallback: try to modify the data structure directly<br />
      current_data = @fple_map.get_data(x, y)<br />
      if current_data &amp;&amp; current_data.size &gt; 1<br />
        current_data[1] = new_texture_id<br />
      else<br />
        return false<br />
      end<br />
    end<br />
    <br />
    @swapped_ground_tiles[key] = new_texture_id<br />
    <br />
    # Remove from animated tiles when doing a simple swap<br />
    @animated_ground_tiles.delete(key)<br />
    <br />
    # Trigger visual update<br />
    if animate<br />
      animate_tile_swap(x, y)<br />
    else<br />
      force_surface_refresh<br />
    end<br />
    <br />
    return true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Animated Ground Tile (cycles through next 3 tiles)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate  <br />
  # param base_texture_id : Integer - Base texture ID (will use this +1, +2, +3)<br />
  # param frame_duration : Integer - Frames to wait between texture changes<br />
  # param animate : Boolean - Whether to animate the initial transition<br />
  #--------------------------------------------------------------------------<br />
  def create_animated_ground_tile(x, y, base_texture_id, frame_duration = 30, animate = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless valid_coordinates?(x, y)<br />
    <br />
    key = [x, y]<br />
    <br />
    # Store original tile data if not already stored<br />
    unless @original_ground_tiles.has_key?(key)<br />
      original_data = @fple_map.get_data(x, y).dup<br />
      @original_ground_tiles[key] = original_data<br />
    end<br />
    <br />
    # Setup animation data<br />
    animation_data = {<br />
      :frames =&gt; [base_texture_id, base_texture_id + 1, base_texture_id + 2],<br />
      :current_frame =&gt; 0,<br />
      :frame_duration =&gt; frame_duration,<br />
      :frame_counter =&gt; 0<br />
    }<br />
    <br />
    @animated_ground_tiles[key] = animation_data<br />
    @swapped_ground_tiles[key] = base_texture_id<br />
    <br />
    # Set initial texture<br />
    current_data = @fple_map.get_data(x, y)<br />
    if current_data &amp;&amp; current_data.size &gt; 1<br />
      current_data[1] = base_texture_id<br />
      <br />
      # Trigger visual update<br />
      if animate<br />
        animate_tile_swap(x, y)<br />
      else<br />
        force_surface_refresh<br />
      end<br />
      <br />
      return true<br />
    end<br />
    <br />
    return false<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore Original Ground Tile<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  #--------------------------------------------------------------------------<br />
  def restore_ground_tile(x, y)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless valid_coordinates?(x, y)<br />
    <br />
    key = [x, y]<br />
    <br />
    if @original_ground_tiles.has_key?(key)<br />
      # Restore original data<br />
      original_data = @original_ground_tiles[key]<br />
      current_data = @fple_map.get_data(x, y)<br />
      <br />
      if current_data &amp;&amp; original_data<br />
        current_data[1] = original_data[1]  # Restore ground texture<br />
        @swapped_ground_tiles.delete(key)<br />
        @animated_ground_tiles.delete(key)  # Remove animation data<br />
        <br />
        force_surface_refresh<br />
        return true<br />
      end<br />
    end<br />
    <br />
    return false<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Batch Swap Multiple Ground Tiles<br />
  # param tile_data : Array&lt;Array&gt; - [[x, y, texture_id], ...]<br />
  #--------------------------------------------------------------------------<br />
  def batch_swap_ground_tiles(tile_data)<br />
    return unless is_fple? &amp;&amp; tile_data.is_a?(Array)<br />
    <br />
    success_count = 0<br />
    tile_data.each do |data|<br />
      next unless data.is_a?(Array) &amp;&amp; data.size &gt;= 3<br />
      x, y, texture_id = data[0], data[1], data[2]<br />
      success_count += 1 if swap_ground_tile(x, y, texture_id, false)<br />
    end<br />
    <br />
    force_surface_refresh if success_count &gt; 0<br />
    return success_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore All Swapped Ground Tiles<br />
  #--------------------------------------------------------------------------<br />
  def restore_all_ground_tiles<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    <br />
    restored_count = 0<br />
    @swapped_ground_tiles.keys.each do |key|<br />
      x, y = key[0], key[1]<br />
      restored_count += 1 if restore_ground_tile(x, y)<br />
    end<br />
    <br />
    force_surface_refresh if restored_count &gt; 0<br />
    return restored_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Swap All Ground Tiles in a Specific Region<br />
  # param region_id : Integer - Region ID to target (1-63, or 0 for no region)<br />
  # param new_texture_id : Integer - New ground texture ID for all tiles in region<br />
  # param animate : Boolean - Whether to animate the transitions (optional)<br />
  # param exclude_events : Boolean - Whether to skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def swap_region_ground_tiles(region_id, new_texture_id, animate = false, exclude_events = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless region_id &gt;= 0 &amp;&amp; region_id &lt;= 63<br />
    <br />
    success_count = 0<br />
    <br />
    # Loop through all tiles in the map<br />
    (0...width).each do |x|<br />
      (0...height).each do |y|<br />
        # Check if this tile has the target region ID<br />
        if region_id(x, y) == region_id<br />
          # Skip tiles with events if requested<br />
          if exclude_events &amp;&amp; events_xy(x, y).any?<br />
            next<br />
          end<br />
          <br />
          # Swap the ground tile<br />
          if swap_ground_tile(x, y, new_texture_id, false)<br />
            success_count += 1<br />
          end<br />
        end<br />
      end<br />
    end<br />
    <br />
    # Handle animation/refresh after all swaps are done<br />
    if success_count &gt; 0<br />
      if animate<br />
        # Create a region-wide flash effect<br />
        &#36;game_map.screen.start_flash(Color.new(255, 255, 255, 80), 15)<br />
      end<br />
      force_surface_refresh<br />
    end<br />
    <br />
    return success_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Animated Ground Tiles for Entire Region<br />
  # param region_id : Integer - Region ID to target (1-63, or 0 for no region)<br />
  # param base_texture_id : Integer - Base texture ID (will use this +1, +2)<br />
  # param frame_duration : Integer - Frames to wait between texture changes<br />
  # param animate : Boolean - Whether to animate the initial transition<br />
  # param exclude_events : Boolean - Whether to skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def animate_region_ground_tiles(region_id, base_texture_id, frame_duration = 30, animate = false, exclude_events = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless region_id &gt;= 0 &amp;&amp; region_id &lt;= 63<br />
    <br />
    success_count = 0<br />
    <br />
    # Loop through all tiles in the map<br />
    (0...width).each do |x|<br />
      (0...height).each do |y|<br />
        # Check if this tile has the target region ID<br />
        if region_id(x, y) == region_id<br />
          # Skip tiles with events if requested<br />
          if exclude_events &amp;&amp; events_xy(x, y).any?<br />
            next<br />
          end<br />
          <br />
          # Create animated ground tile<br />
          if create_animated_ground_tile(x, y, base_texture_id, frame_duration, false)<br />
            success_count += 1<br />
          end<br />
        end<br />
      end<br />
    end<br />
    <br />
    # Handle animation/refresh after all animations are set up<br />
    if success_count &gt; 0<br />
      if animate<br />
        # Create a region-wide flash effect<br />
        &#36;game_map.screen.start_flash(Color.new(200, 255, 200, 100), 20)<br />
      end<br />
      force_surface_refresh<br />
    end<br />
    <br />
    return success_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore All Ground Tiles in a Specific Region<br />
  # param region_id : Integer - Region ID to target (1-63, or 0 for no region)<br />
  # param exclude_events : Boolean - Whether to skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def restore_region_ground_tiles(region_id, exclude_events = false)<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return unless region_id &gt;= 0 &amp;&amp; region_id &lt;= 63<br />
    <br />
    restored_count = 0<br />
    <br />
    # Loop through all swapped tiles and restore those in the target region<br />
    @swapped_ground_tiles.keys.each do |key|<br />
      x, y = key[0], key[1]<br />
      <br />
      # Check if this tile is in the target region<br />
      if region_id(x, y) == region_id<br />
        # Skip tiles with events if requested<br />
        if exclude_events &amp;&amp; events_xy(x, y).any?<br />
          next<br />
        end<br />
        <br />
        # Restore the ground tile<br />
        if restore_ground_tile(x, y)<br />
          restored_count += 1<br />
        end<br />
      end<br />
    end<br />
    <br />
    force_surface_refresh if restored_count &gt; 0<br />
    return restored_count<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Check if Ground Tile is Swapped<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def ground_tile_swapped?(x, y)<br />
    return @swapped_ground_tiles.has_key?([x, y])<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Check if Ground Tile is Animated<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def ground_tile_animated?(x, y)<br />
    return @animated_ground_tiles.has_key?([x, y])<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Update Ground Tile Animations (call this from Scene_Map update)<br />
  #--------------------------------------------------------------------------<br />
  def update_ground_animations<br />
    return unless is_fple? &amp;&amp; @fple_map<br />
    return if @animated_ground_tiles.empty?<br />
    <br />
    @ground_animation_timer += 1<br />
    needs_refresh = false<br />
    <br />
    @animated_ground_tiles.each do |key, animation_data|<br />
      animation_data[:frame_counter] += 1<br />
      <br />
      if animation_data[:frame_counter] &gt;= animation_data[:frame_duration]<br />
        # Reset counter and advance frame<br />
        animation_data[:frame_counter] = 0<br />
        animation_data[:current_frame] = (animation_data[:current_frame] + 1) % animation_data[:frames].size<br />
        <br />
        # Update the tile texture using proper FPLE methods<br />
        x, y = key[0], key[1]<br />
        new_texture_id = animation_data[:frames][animation_data[:current_frame]]<br />
        <br />
        # Use FPLE's proper method to change ground texture<br />
        success = false<br />
        if @fple_map.respond_to?(:change_ground)<br />
          @fple_map.change_ground(x, y, new_texture_id)<br />
          success = true<br />
        elsif @fple_map.respond_to?(:set_ground_tile)<br />
          @fple_map.set_ground_tile(x, y, new_texture_id)<br />
          success = true<br />
        else<br />
          # Fallback: try to modify the data structure directly<br />
          current_data = @fple_map.get_data(x, y)<br />
          if current_data &amp;&amp; current_data.is_a?(Array) &amp;&amp; current_data.size &gt; 1<br />
            current_data[1] = new_texture_id<br />
            success = true<br />
          end<br />
        end<br />
        <br />
        if success<br />
          @swapped_ground_tiles[key] = new_texture_id<br />
          needs_refresh = true<br />
        end<br />
      end<br />
    end<br />
    <br />
    force_surface_refresh if needs_refresh<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Get Current Ground Texture ID<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Integer<br />
  #--------------------------------------------------------------------------<br />
  def get_ground_texture_id(x, y)<br />
    return nil unless valid_coordinates?(x, y) &amp;&amp; @fple_map<br />
    <br />
    tile_data = @fple_map.get_data(x, y)<br />
    return tile_data ? tile_data[1] : nil<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Get Original Ground Texture ID<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Integer<br />
  #--------------------------------------------------------------------------<br />
  def get_original_ground_texture_id(x, y)<br />
    key = [x, y]<br />
    if @original_ground_tiles.has_key?(key)<br />
      return @original_ground_tiles[key][1]<br />
    else<br />
      return get_ground_texture_id(x, y)<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Animate Tile Swap (Simple fade effect)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  #--------------------------------------------------------------------------<br />
  def animate_tile_swap(x, y)<br />
    # This is a placeholder for animation<br />
    # In a full implementation, you might want to:<br />
    # - Create temporary sprites for transition effects<br />
    # - Use screen flashes or particle effects<br />
    # - Gradually fade between old and new textures<br />
    <br />
    &#36;game_map.screen.start_flash(Color.new(255, 255, 255, 60), 10)<br />
    force_surface_refresh<br />
  end<br />
  <br />
  private<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Validate Coordinates<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def valid_coordinates?(x, y)<br />
    return x &gt;= 0 &amp;&amp; x &lt; width &amp;&amp; y &gt;= 0 &amp;&amp; y &lt; height<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Force Surface Refresh<br />
  #--------------------------------------------------------------------------<br />
  def force_surface_refresh<br />
    &#36;game_temp.force_render = true if &#36;game_temp<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Game_Interpreter - Event Commands for Ground Swapping<br />
#==============================================================================<br />
class Game_Interpreter<br />
  #--------------------------------------------------------------------------<br />
  # * Swap Ground Tile (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # param texture_id : Integer - New ground texture ID<br />
  #--------------------------------------------------------------------------<br />
  def swap_ground(x, y, texture_id)<br />
    &#36;game_map.swap_ground_tile(x, y, texture_id, true)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Animated Ground Tile (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # param base_texture_id : Integer - Base texture ID (uses this +1, +2)<br />
  # param frame_duration : Integer - Frames between animation changes (default: 30)<br />
  #--------------------------------------------------------------------------<br />
  def animate_ground(x, y, base_texture_id, frame_duration = 30)<br />
    &#36;game_map.create_animated_ground_tile(x, y, base_texture_id, frame_duration, true)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore Ground Tile (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  #--------------------------------------------------------------------------<br />
  def restore_ground(x, y)<br />
    &#36;game_map.restore_ground_tile(x, y)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Batch Swap Ground Tiles (Event Command)<br />
  # param tile_array : Array&lt;Array&gt; - [[x, y, texture_id], ...]<br />
  #--------------------------------------------------------------------------<br />
  def batch_swap_ground(tile_array)<br />
    &#36;game_map.batch_swap_ground_tiles(tile_array)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore All Ground Tiles (Event Command)<br />
  #--------------------------------------------------------------------------<br />
  def restore_all_ground<br />
    &#36;game_map.restore_all_ground_tiles<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Swap All Ground Tiles in Region (Event Command)<br />
  # param region_id : Integer - Region ID to target (1-63, or 0 for no region)<br />
  # param texture_id : Integer - New ground texture ID<br />
  # param exclude_events : Boolean - Skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def swap_region_ground(region_id, texture_id, exclude_events = false)<br />
    &#36;game_map.swap_region_ground_tiles(region_id, texture_id, true, exclude_events)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Animated Ground Tiles for Region (Event Command)<br />
  # param region_id : Integer - Region ID to target<br />
  # param base_texture_id : Integer - Base texture ID (uses this +1, +2)<br />
  # param frame_duration : Integer - Frames between animation changes (default: 30)<br />
  # param exclude_events : Boolean - Skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def animate_region_ground(region_id, base_texture_id, frame_duration = 30, exclude_events = false)<br />
    &#36;game_map.animate_region_ground_tiles(region_id, base_texture_id, frame_duration, true, exclude_events)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Restore All Ground Tiles in Region (Event Command)<br />
  # param region_id : Integer - Region ID to target<br />
  # param exclude_events : Boolean - Skip tiles with events (optional)<br />
  #--------------------------------------------------------------------------<br />
  def restore_region_ground(region_id, exclude_events = false)<br />
    &#36;game_map.restore_region_ground_tiles(region_id, exclude_events)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Check if Ground Tile is Swapped (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def ground_swapped?(x, y)<br />
    return &#36;game_map.ground_tile_swapped?(x, y)<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Check if Ground Tile is Animated (Event Command)<br />
  # param x : Integer - X coordinate<br />
  # param y : Integer - Y coordinate<br />
  # return Boolean<br />
  #--------------------------------------------------------------------------<br />
  def ground_animated?(x, y)<br />
    return &#36;game_map.ground_tile_animated?(x, y)<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Game_Temp - Additional Switches and Variables<br />
#==============================================================================<br />
class Game_Temp<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased methods<br />
  #--------------------------------------------------------------------------<br />
  unless @already_aliased_ground_swap_temp<br />
    alias initialize_ground_swap_temp initialize<br />
    @already_aliased_ground_swap_temp = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Public Instance Variables<br />
  #--------------------------------------------------------------------------<br />
  attr_accessor :ground_swap_animation  # Boolean - Enable swap animations<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Object Initialization<br />
  #--------------------------------------------------------------------------<br />
  def initialize<br />
    initialize_ground_swap_temp<br />
    @ground_swap_animation = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Enable/Disable Ground Swap Animations<br />
  # param enabled : Boolean<br />
  #--------------------------------------------------------------------------<br />
  def set_ground_swap_animation(enabled)<br />
    @ground_swap_animation = enabled<br />
  end<br />
end<br />
#==============================================================================<br />
# ** DataManager - Save/Load Support<br />
#==============================================================================<br />
module DataManager<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased methods<br />
  #--------------------------------------------------------------------------<br />
  class &lt;&lt; self<br />
    unless @already_aliased_ground_swap_data<br />
      alias make_save_contents_ground_swap make_save_contents<br />
      alias extract_save_contents_ground_swap extract_save_contents<br />
      @already_aliased_ground_swap_data = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Create Save Contents<br />
  #--------------------------------------------------------------------------<br />
  def self.make_save_contents<br />
    contents = make_save_contents_ground_swap<br />
    contents[:ground_swaps] = {<br />
      :original_tiles =&gt; &#36;game_map.original_ground_tiles,<br />
      :swapped_tiles =&gt; &#36;game_map.swapped_ground_tiles,<br />
      :animated_tiles =&gt; &#36;game_map.animated_ground_tiles<br />
    }<br />
    contents<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Extract Save Contents<br />
  #--------------------------------------------------------------------------<br />
  def self.extract_save_contents(contents)<br />
    extract_save_contents_ground_swap(contents)<br />
    if contents[:ground_swaps]<br />
      &#36;game_map.original_ground_tiles = contents[:ground_swaps][:original_tiles] || {}<br />
      &#36;game_map.swapped_ground_tiles = contents[:ground_swaps][:swapped_tiles] || {}<br />
      &#36;game_map.animated_ground_tiles = contents[:ground_swaps][:animated_tiles] || {}<br />
    end<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Scene_Map - Animation Updates<br />
#==============================================================================<br />
class Scene_Map &lt; Scene_Base<br />
  #--------------------------------------------------------------------------<br />
  # * Aliased methods<br />
  #--------------------------------------------------------------------------<br />
  unless @already_aliased_ground_swap_scene<br />
    alias update_ground_swap_scene update<br />
    @already_aliased_ground_swap_scene = true<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Frame Update<br />
  #--------------------------------------------------------------------------<br />
  def update<br />
    update_ground_swap_scene<br />
    &#36;game_map.update_ground_animations if &#36;game_system.fple<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Usage Examples and Helper Methods<br />
#==============================================================================<br />
# Example usage in events:<br />
#<br />
# Script Command Examples:<br />
# swap_ground(5, 3, 10)                         # Swap tile at (5,3) to texture 10<br />
# animate_ground(5, 3, 15, 60)                  # Animate tile at (5,3) using textures 15,16,17 with 60-frame delays<br />
# animate_ground(2, 4, 20)                      # Animate tile at (2,4) using textures 20,21,22 with default 30-frame delays<br />
# restore_ground(5, 3)                          # Restore original tile at (5,3)<br />
# batch_swap_ground([[1,1,5], [1,2,5]])        # Swap multiple tiles at once<br />
# restore_all_ground                            # Restore all swapped tiles<br />
# swap_region_ground(5, 10)                     # Swap all tiles in region 5 to texture 10<br />
# swap_region_ground(3, 15, true)               # Swap region 3, skip tiles with events<br />
# animate_region_ground(2, 20)                  # Animate all tiles in region 2 using textures 20,21,22<br />
# animate_region_ground(4, 25, 60, true)        # Animate region 4 with 60-frame delays, skip events<br />
# restore_region_ground(5)                      # Restore all tiles in region 5 to original<br />
# restore_region_ground(3, true)                # Restore region 3, skip tiles with events<br />
#<br />
# Conditional Branch Examples:<br />
# if ground_swapped?(5, 3)<br />
#   # Do something if tile is swapped<br />
# end<br />
#<br />
# if ground_animated?(5, 3)<br />
#   # Do something if tile is animated<br />
# end<br />
#<br />
# Advanced Script Examples:<br />
# &#36;game_map.create_animated_ground_tile(&#36;game_player.x, &#36;game_player.y, 15, 45)<br />
# &#36;game_map.swap_ground_tile(&#36;game_player.x, &#36;game_player.y, 15)<br />
# texture_id = &#36;game_map.get_ground_texture_id(5, 3)<br />
# original_id = &#36;game_map.get_original_ground_texture_id(5, 3)<br />
# count = &#36;game_map.swap_region_ground_tiles(1, 12, false, true)<br />
# &#36;game_map.animate_region_ground_tiles(7, 30, 45)<br />
# Global helper methods for easier access<br />
def swap_ground_tile(x, y, texture_id, animate = true)<br />
  &#36;game_map.swap_ground_tile(x, y, texture_id, animate)<br />
end<br />
def create_animated_ground_tile(x, y, base_texture_id, frame_duration = 30, animate = true)<br />
  &#36;game_map.create_animated_ground_tile(x, y, base_texture_id, frame_duration, animate)<br />
end<br />
def restore_ground_tile(x, y)<br />
  &#36;game_map.restore_ground_tile(x, y)<br />
end<br />
def ground_tile_swapped?(x, y)<br />
  &#36;game_map.ground_tile_swapped?(x, y)<br />
end<br />
def ground_tile_animated?(x, y)<br />
  &#36;game_map.ground_tile_animated?(x, y)<br />
end<br />
def swap_region_ground_tiles(region_id, texture_id, animate = true, exclude_events = false)<br />
  &#36;game_map.swap_region_ground_tiles(region_id, texture_id, animate, exclude_events)<br />
end<br />
def animate_region_ground_tiles(region_id, base_texture_id, frame_duration = 30, animate = true, exclude_events = false)<br />
  &#36;game_map.animate_region_ground_tiles(region_id, base_texture_id, frame_duration, animate, exclude_events)<br />
end<br />
def restore_region_ground_tiles(region_id, exclude_events = false)<br />
  &#36;game_map.restore_region_ground_tiles(region_id, exclude_events)<br />
end</code></div></div><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** FPLE Third Person Player Sprite<br />
# v.1.5 old, now upgraded to v.1.8 using Claude.AI by 5Brainplay. <br />
#==============================================================================<br />
# This script adds a third-person view sprite of the player character that<br />
# appears on screen during FPLE mode. The sprite can be positioned, scaled,<br />
# and configured to show the player's current state.<br />
#==============================================================================<br />
module FPLE<br />
  #--------------------------------------------------------------------------<br />
  # * Player Sprite Configuration<br />
  #--------------------------------------------------------------------------<br />
  PLAYER_SPRITE_DEFAULT_X = 300              # Default X position on screen<br />
  PLAYER_SPRITE_DEFAULT_Y = 450             # Default Y position on screen<br />
  PLAYER_SPRITE_DEFAULT_SCALE = 3.0         # Default scale multiplier<br />
  PLAYER_SPRITE_DEFAULT_OPACITY = 255       # Default opacity (0-255)<br />
  PLAYER_SPRITE_Z = 1000                    # Z-order (higher = in front)<br />
  PLAYER_SPRITE_DEFAULT_ANIMATE = true      # Default enable walking animation<br />
  PLAYER_SPRITE_UPDATE_DIRECTION = false     # Update sprite direction based on player facing<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Player Sprite Settings (Dynamic)<br />
  #--------------------------------------------------------------------------<br />
  @@player_sprite_enabled = true<br />
  @@player_sprite_animate = PLAYER_SPRITE_DEFAULT_ANIMATE<br />
  <br />
  def self.player_sprite_enabled<br />
    @@player_sprite_enabled<br />
  end<br />
  <br />
  def self.player_sprite_enabled=(value)<br />
    @@player_sprite_enabled = value<br />
  end<br />
  <br />
  def self.player_sprite_animate<br />
    @@player_sprite_animate<br />
  end<br />
  <br />
  def self.player_sprite_animate=(value)<br />
    @@player_sprite_animate = value<br />
  end<br />
end<br />
#==============================================================================<br />
# ** FPLE::Player_Sprite<br />
#==============================================================================<br />
module FPLE<br />
  class Player_Sprite &lt; Sprite<br />
    #--------------------------------------------------------------------------<br />
    # * Object Initialization<br />
    #--------------------------------------------------------------------------<br />
    def initialize(viewport = nil)<br />
      super(viewport)<br />
      @character = &#36;game_player<br />
      @tile_id = 0<br />
      @character_name = ""<br />
      @character_index = 0<br />
      @pattern = 0<br />
      @direction = 8<br />
      @animation_count = 0<br />
      @stop_count = 0<br />
      @jump_count = 0<br />
      <br />
      # Set initial position and properties<br />
      self.x = FPLE::PLAYER_SPRITE_DEFAULT_X<br />
      self.y = FPLE::PLAYER_SPRITE_DEFAULT_Y<br />
      self.z = FPLE::PLAYER_SPRITE_Z<br />
      self.zoom_x = FPLE::PLAYER_SPRITE_DEFAULT_SCALE<br />
      self.zoom_y = FPLE::PLAYER_SPRITE_DEFAULT_SCALE<br />
      self.opacity = FPLE::PLAYER_SPRITE_DEFAULT_OPACITY<br />
      <br />
      update<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Frame Update<br />
    #--------------------------------------------------------------------------<br />
    def update<br />
      super<br />
      if FPLE.player_sprite_enabled<br />
        update_bitmap<br />
        update_src_rect<br />
        update_visibility<br />
        update_animation if FPLE.player_sprite_animate<br />
      else<br />
        self.visible = false<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Transfer Origin Bitmap<br />
    #--------------------------------------------------------------------------<br />
    def update_bitmap<br />
      if graphic_changed?<br />
        @tile_id = @character.tile_id<br />
        @character_name = @character.character_name<br />
        @character_index = @character.character_index<br />
        if @tile_id &gt; 0<br />
          set_tile_bitmap<br />
        else<br />
          set_character_bitmap<br />
        end<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Determine if Graphic Changed<br />
    #--------------------------------------------------------------------------<br />
    def graphic_changed?<br />
      @tile_id != @character.tile_id ||<br />
      @character_name != @character.character_name ||<br />
      @character_index != @character.character_index<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Tile Bitmap<br />
    #--------------------------------------------------------------------------<br />
    def set_tile_bitmap<br />
      sx = (@tile_id / 128 % 2 * 8 + @tile_id % 8) * 32<br />
      sy = @tile_id % 256 / 8 % 16 * 32<br />
      self.bitmap = tileset_bitmap(@tile_id)<br />
      self.src_rect.set(sx, sy, 32, 32)<br />
      self.ox = 16<br />
      self.oy = 32<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Character Bitmap<br />
    #--------------------------------------------------------------------------<br />
    def set_character_bitmap<br />
      self.bitmap = Cache.character(@character_name)<br />
      sign = @character_name[/^[&#92;!&#92;&#36;]./]<br />
      if sign &amp;&amp; sign.include?('&#36;')<br />
        @cw = bitmap.width / 3<br />
        @ch = bitmap.height / 4<br />
      else<br />
        @cw = bitmap.width / 12<br />
        @ch = bitmap.height / 8<br />
      end<br />
      self.ox = @cw / 2<br />
      self.oy = @ch<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Get Tileset Bitmap<br />
    #--------------------------------------------------------------------------<br />
    def tileset_bitmap(tile_id)<br />
      set_number = tile_id / 256<br />
      return Cache.system("TileB") if set_number == 0<br />
      return Cache.system("TileC") if set_number == 1<br />
      return Cache.system("TileD") if set_number == 2<br />
      return Cache.system("TileE") if set_number == 3<br />
      return nil<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Transfer Origin Rectangle<br />
    #--------------------------------------------------------------------------<br />
    def update_src_rect<br />
      if @tile_id == 0<br />
        index = @character.character_index<br />
        pattern = @pattern &lt; 3 ? @pattern : 1<br />
        sx = (index % 4 * 3 + pattern) * @cw<br />
        <br />
        # Update direction based on player facing if enabled<br />
        if FPLE::PLAYER_SPRITE_UPDATE_DIRECTION<br />
          @direction = @character.direction<br />
        end<br />
        <br />
        sy = (index / 4 * 4 + (@direction - 2) / 2) * @ch<br />
        self.src_rect.set(sx, sy, @cw, @ch)<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Visibility<br />
    #--------------------------------------------------------------------------<br />
    def update_visibility<br />
      self.opacity = @character.opacity<br />
      self.blend_type = @character.blend_type<br />
      self.visible = !@character.transparent &amp;&amp; FPLE.player_sprite_enabled<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Animation<br />
    #--------------------------------------------------------------------------<br />
    def update_animation<br />
      if &#36;game_temp.movement<br />
        # Player is moving, animate the sprite<br />
        @stop_count = 0<br />
        update_animation_pattern<br />
      else<br />
        # Player is stationary<br />
        @stop_count += 1<br />
        if @stop_count &gt; 20  # Stop animation after standing still<br />
          @pattern = 1  # Default standing pattern<br />
          @animation_count = 0<br />
        end<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Animation Pattern<br />
    #--------------------------------------------------------------------------<br />
    def update_animation_pattern<br />
      @animation_count += 1.5<br />
      if @animation_count &gt; 18<br />
        if @pattern == 0<br />
          @pattern = 1<br />
        elsif @pattern == 1<br />
          @pattern = 2<br />
        elsif @pattern == 2<br />
          @pattern = 1<br />
        end<br />
        @animation_count = 0<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Position<br />
    #--------------------------------------------------------------------------<br />
    def set_position(x, y)<br />
      self.x = x<br />
      self.y = y<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Scale<br />
    #--------------------------------------------------------------------------<br />
    def set_scale(scale_x, scale_y = nil)<br />
      scale_y = scale_x if scale_y.nil?<br />
      self.zoom_x = scale_x<br />
      self.zoom_y = scale_y<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Set Direction (for manual control)<br />
    #--------------------------------------------------------------------------<br />
    def set_direction(direction)<br />
      @direction = direction<br />
    end<br />
  end<br />
end<br />
#==============================================================================<br />
# ** FPLE::Spriteset_Map - Modified<br />
#==============================================================================<br />
# Add player sprite support to the existing FPLE spriteset<br />
module FPLE<br />
  class Spriteset_Map &lt; ::Spriteset_Map<br />
    #--------------------------------------------------------------------------<br />
    # * Aliased methods for player sprite<br />
    #--------------------------------------------------------------------------<br />
    unless @already_aliased_player_sprite<br />
      alias create_characters_with_player_sprite create_characters<br />
      alias dispose_characters_with_player_sprite dispose_characters<br />
      alias update_characters_with_player_sprite update_characters<br />
      @already_aliased_player_sprite = true<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Create Characters (with player sprite)<br />
    #--------------------------------------------------------------------------<br />
    def create_characters<br />
      create_characters_with_player_sprite<br />
      create_player_sprite<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Create Player Sprite<br />
    #--------------------------------------------------------------------------<br />
    def create_player_sprite<br />
      if FPLE.player_sprite_enabled<br />
        @player_sprite = FPLE::Player_Sprite.new(@viewport1)<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Dispose of Characters (with player sprite)<br />
    #--------------------------------------------------------------------------<br />
    def dispose_characters<br />
      dispose_player_sprite<br />
      dispose_characters_with_player_sprite<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Dispose of Player Sprite<br />
    #--------------------------------------------------------------------------<br />
    def dispose_player_sprite<br />
      if @player_sprite<br />
        @player_sprite.dispose<br />
        @player_sprite = nil<br />
      end<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Characters (with player sprite)<br />
    #--------------------------------------------------------------------------<br />
    def update_characters<br />
      update_characters_with_player_sprite<br />
      update_player_sprite<br />
    end<br />
    <br />
    #--------------------------------------------------------------------------<br />
    # * Update Player Sprite<br />
    #--------------------------------------------------------------------------<br />
    def update_player_sprite<br />
      if @player_sprite<br />
        @player_sprite.update<br />
      end<br />
    end<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Game_Temp - Player Sprite Commands<br />
#==============================================================================<br />
class Game_Temp<br />
  #--------------------------------------------------------------------------<br />
  # * Show Player Sprite<br />
  #--------------------------------------------------------------------------<br />
  def show_player_sprite<br />
    if &#36;game_system.fple<br />
      FPLE.player_sprite_enabled = true<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Hide Player Sprite<br />
  #--------------------------------------------------------------------------<br />
  def hide_player_sprite<br />
    if &#36;game_system.fple<br />
      FPLE.player_sprite_enabled = false<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Set Player Sprite Position<br />
  #--------------------------------------------------------------------------<br />
  def set_player_sprite_position(x, y)<br />
    if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
      spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
      if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
        spriteset.instance_variable_get(:@player_sprite).set_position(x, y)<br />
      end<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Set Player Sprite Scale<br />
  #--------------------------------------------------------------------------<br />
  def set_player_sprite_scale(scale_x, scale_y = nil)<br />
    if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
      spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
      if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
        spriteset.instance_variable_get(:@player_sprite).set_scale(scale_x, scale_y)<br />
      end<br />
    end<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Get Player Sprite Position<br />
  #--------------------------------------------------------------------------<br />
  def get_player_sprite_position<br />
    if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
      spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
      if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
        sprite = spriteset.instance_variable_get(:@player_sprite)<br />
        return [sprite.x, sprite.y]<br />
      end<br />
    end<br />
    return [0, 0]<br />
  end<br />
  <br />
  #--------------------------------------------------------------------------<br />
  # * Reset Player Sprite to Default Position<br />
  #--------------------------------------------------------------------------<br />
  def reset_player_sprite_position<br />
    set_player_sprite_position(FPLE::PLAYER_SPRITE_DEFAULT_X, FPLE::PLAYER_SPRITE_DEFAULT_Y)<br />
  end<br />
end<br />
#==============================================================================<br />
# ** Script Call Methods - Global functions for easier access<br />
#==============================================================================<br />
#--------------------------------------------------------------------------<br />
# * Simple script call to set player sprite position<br />
# Usage in script call: set_player_sprite_xy(300, 450)<br />
#--------------------------------------------------------------------------<br />
def set_player_sprite_xy(x, y)<br />
  if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
    spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
    if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
      spriteset.instance_variable_get(:@player_sprite).set_position(x, y)<br />
    end<br />
  end<br />
end<br />
#--------------------------------------------------------------------------<br />
# * Alternative: More direct access to the player sprite<br />
# Usage in script call: player_sprite_position(100, 200)<br />
#--------------------------------------------------------------------------<br />
def player_sprite_position(x, y)<br />
  &#36;game_temp.set_player_sprite_position(x, y)<br />
end<br />
#--------------------------------------------------------------------------<br />
# * Set individual coordinates<br />
# Usage: set_player_sprite_x(150) or set_player_sprite_y(300)<br />
#--------------------------------------------------------------------------<br />
def set_player_sprite_x(x)<br />
  if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
    spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
    if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
      sprite = spriteset.instance_variable_get(:@player_sprite)<br />
      sprite.set_position(x, sprite.y)<br />
    end<br />
  end<br />
end<br />
def set_player_sprite_y(y)<br />
  if &#36;game_system.fple &amp;&amp; SceneManager.scene.is_a?(Scene_Map)<br />
    spriteset = SceneManager.scene.instance_variable_get(:@spriteset)<br />
    if spriteset.is_a?(FPLE::Spriteset_Map) &amp;&amp; spriteset.instance_variable_get(:@player_sprite)<br />
      sprite = spriteset.instance_variable_get(:@player_sprite)<br />
      sprite.set_position(sprite.x, y)<br />
    end<br />
  end<br />
end</code></div></div>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Super Skill Nerf VX]]></title>
			<link>https://www.save-point.org/thread-12790.html</link>
			<pubDate>Sat, 06 Sep 2025 20:25:31 +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-12790.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">Super Skill Nerf VX</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 />
Nerf! Nerf! Nerf your favorite super duper skills!<br />
Yes, even up to the point where your heroes can only use them once per battle!<br />
<br />
Mandatory Notes:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&lt;cast_only_once&gt;<br />
&lt;cast_only_twice&gt;</code></div></div><br />
Or Cool Them Down!<br />
<br />
Mandatory Note:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&lt;cooldown 1&gt;<br />
&lt;cooldown 4&gt;</code></div></div>Any positive number will be fine.<br />
<br />
And just in case you want to clear this skill use limit once per call:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;game_party.clear_used_skills!</code></div></div><br />
Or if you prefer to clear the cooldowns altogether:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;game_party.clear_skill_cooldowns!</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">VX Scripts</span></span><br />
<hr class="mycode_hr" />
<br />
<span style="font-weight: bold;" class="mycode_b">Version 1.3.x</span><br />
<br />
This release includes the ability to change the color of the skill name &amp; its cost based on how many turns are left.<br />
This feature can be modified by editing the constants found in the <span style="font-weight: bold;" class="mycode_b">SkillColor</span> module.<br />
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: x-large;" class="mycode_size"><a href="https://www.mediafire.com/folder/ikqb7ktqumv2p/SuperSkillNerf" target="_blank" rel="noopener" class="mycode_url">DOWNLOAD DEMOS NOW!</a></span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
<div style="text-align: left;" class="mycode_align">Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer for non commercial games. <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /></div>
<div style="text-align: left;" class="mycode_align">Include my nickname in your game credits.</div>
<div style="text-align: left;" class="mycode_align">Thank Opozorilo for making the script request. (Optional aka a Joke)</div>
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">Super Skill Nerf VX</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 />
Nerf! Nerf! Nerf your favorite super duper skills!<br />
Yes, even up to the point where your heroes can only use them once per battle!<br />
<br />
Mandatory Notes:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&lt;cast_only_once&gt;<br />
&lt;cast_only_twice&gt;</code></div></div><br />
Or Cool Them Down!<br />
<br />
Mandatory Note:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&lt;cooldown 1&gt;<br />
&lt;cooldown 4&gt;</code></div></div>Any positive number will be fine.<br />
<br />
And just in case you want to clear this skill use limit once per call:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;game_party.clear_used_skills!</code></div></div><br />
Or if you prefer to clear the cooldowns altogether:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;game_party.clear_skill_cooldowns!</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: medium;" class="mycode_size">VX Scripts</span></span><br />
<hr class="mycode_hr" />
<br />
<span style="font-weight: bold;" class="mycode_b">Version 1.3.x</span><br />
<br />
This release includes the ability to change the color of the skill name &amp; its cost based on how many turns are left.<br />
This feature can be modified by editing the constants found in the <span style="font-weight: bold;" class="mycode_b">SkillColor</span> module.<br />
<br />
<div style="text-align: center;" class="mycode_align"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: x-large;" class="mycode_size"><a href="https://www.mediafire.com/folder/ikqb7ktqumv2p/SuperSkillNerf" target="_blank" rel="noopener" class="mycode_url">DOWNLOAD DEMOS NOW!</a></span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
<div style="text-align: left;" class="mycode_align">Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer for non commercial games. <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /></div>
<div style="text-align: left;" class="mycode_align">Include my nickname in your game credits.</div>
<div style="text-align: left;" class="mycode_align">Thank Opozorilo for making the script request. (Optional aka a Joke)</div>
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[KursedVictory VX + ACE]]></title>
			<link>https://www.save-point.org/thread-12770.html</link>
			<pubDate>Sat, 06 Sep 2025 05:19:51 +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-12770.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">KursedVictory VX + ACE</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 />
You will either love this scriptlet or just hate it. <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /><br />
Sometimes the heroes cannot simply obtain a flawless victory. That would be inconceivable! <img src="https://www.save-point.org/images/smilies/ejlol/credible.gif" alt="Incredible" title="Incredible" class="smilie smilie_232" /> <br />
Thus, they need some final punishment to make sure they learn their lesson! <img src="https://www.save-point.org/images/smilies/ejlol/serious.gif" alt="Serious" title="Serious" class="smilie smilie_50" /> <br />
<br />
Just add enemy ID's to the <span style="font-weight: bold;" class="mycode_b">ENEMY_IDS</span> constant to make this happen! <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
<br />
Or leave this note tag in the enemy's notebox: <span style="font-weight: bold;" class="mycode_b">curse_victory</span><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/qMCxdDLp/kursedvictory-vx01.jpg" loading="lazy"  alt="[Image: kursedvictory-vx01.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/xjZ3hVLs/kursedvictory-vx02.jpg" loading="lazy"  alt="[Image: kursedvictory-vx02.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/vZS2bRBh/kursedvictory-vx003.jpg" loading="lazy"  alt="[Image: kursedvictory-vx003.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/Bnv7rZqt/kursedvictory-vx004.jpg" loading="lazy"  alt="[Image: kursedvictory-vx004.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/QxdPc0Cr/kursedvictory-ace01.jpg" loading="lazy"  alt="[Image: kursedvictory-ace01.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/xTpZ5MNN/kursedvictory-ace02.jpg" loading="lazy"  alt="[Image: kursedvictory-ace02.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">VX Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KursedVictory VX * #<br />
#   Scripter : Kyonides<br />
#   v1.2.0 - 2025-09-09<br />
<br />
# Sometimes the heroes cannot simply obtain a flawless victory. Thus, they need<br />
# some final punishment to make sure they learn their lesson!<br />
# - Method #1<br />
# Just add enemy ID's to the ENEMY_IDS constant to make this happen!<br />
# - Method #2<br />
# Leave a note tag in the enemy's notebox: curse_victory<br />
<br />
# Warning: If you refuse to comply, you might have to fight another troop...<br />
<br />
module KursedVictory<br />
  BGS = "Darkness"<br />
  CURSOR = "sword0132"<br />
  CURSOR_OY = 4<br />
  OPTION_BACKDROP = "box240"<br />
  MESSAGE = ["Flawless Victory!", "Now choose a curse victim!"]<br />
  OPTIONS = ["Comply", "Refuse"]<br />
  OUTCOME = ["You complied with the %s's demand.",<br />
             "You refused to listen to %s."]<br />
  CURSE_CHANCE = 100<br />
  WAIT_FRAMES = 40<br />
  ENEMY_NOTE_TAG = /curse_victory/i<br />
  ENEMY_IDS = []<br />
  ROUND2_ENEMY_IDS = {}<br />
  ROUND2_ENEMY_IDS[1] = { :name =&gt; "Basilisk", :troop_id =&gt; 2 }<br />
end<br />
<br />
class Game_Enemy<br />
  def cursed_victory_note<br />
    @cursed_victory ||= enemy.note[KursedVictory::ENEMY_NOTE_TAG]<br />
  end<br />
<br />
  def curse_victory?<br />
    return true if KursedVictory::ENEMY_IDS.include?(@enemy_id)<br />
    cursed_victory_note != nil<br />
  end<br />
end<br />
<br />
class Game_Party<br />
  def dead_members<br />
    members.select {|member| member.dead? }<br />
  end<br />
<br />
  def all_dead_now?<br />
    dead_members.size == @actors.size<br />
  end<br />
end<br />
<br />
class Game_Troop<br />
  def curse_flawless_victory?<br />
    enemy = @enemies.find {|enemy| enemy.curse_victory? }<br />
    enemy != nil<br />
  end<br />
  attr_reader :troop_id<br />
end<br />
<br />
class CursedMessageWindow &lt; Window_Base<br />
  def initialize(wx, wy)<br />
    super(wx, wy, 280, 80)<br />
    refresh<br />
  end<br />
<br />
  def refresh<br />
    line1, line2 = KursedVictory::MESSAGE<br />
    font = self.contents.font<br />
    font.bold = true<br />
    font.color.set(220, 80, 0)<br />
    self.contents.draw_text(0, 0, width - 32, 24, line1, 1)<br />
    font.bold = false<br />
    font.color.set(255, 255, 255)<br />
    self.contents.draw_text(0, 24, width - 32, 24, line2, 1)<br />
  end<br />
end<br />
<br />
module KursedVictory<br />
  class TextBox<br />
    def initialize(pos, total, vp=nil)<br />
      @index = pos<br />
      @max = total<br />
      @row_max = 2<br />
      @col_max = 1<br />
      @viewport = vp<br />
      @backdrop = Sprite.new(vp)<br />
      @label = Sprite.new(vp)<br />
      @label.z = 50<br />
    end<br />
<br />
    def set_image(filename)<br />
      @filename = filename<br />
      set_bitmap<br />
      set_text_bitmap<br />
      reset_alignment<br />
    end<br />
<br />
    def set_bitmap<br />
      bitmap = Cache.picture(@filename)<br />
      @width = bitmap.width<br />
      @height = bitmap.height<br />
      @rect = bitmap.rect<br />
      @col_width = Graphics.width<br />
      @center_x = (@col_width - @width) / 2<br />
      @backdrop.bitmap = bitmap<br />
    end<br />
<br />
    def set_text_bitmap<br />
      @align_x = 1<br />
      @label.bitmap = Bitmap.new(@width, @height)<br />
    end<br />
<br />
    def set_align_xy<br />
      h = @height + 24<br />
      @backdrop.x = @center_x<br />
      @backdrop.y = 140 + @index * h<br />
    end<br />
<br />
    def reset_alignment<br />
      set_align_xy<br />
      @label.x = @backdrop.x<br />
      @label.y = @backdrop.y<br />
    end<br />
<br />
    def x<br />
      @backdrop.x<br />
    end<br />
<br />
    def y<br />
      @backdrop.y<br />
    end<br />
<br />
    def set_text(text)<br />
      @text = text<br />
      bit = @label.bitmap<br />
      bit.clear<br />
      bit.draw_text(@rect, text, @align_x)<br />
    end<br />
<br />
    def dispose<br />
      @label.bitmap.dispose<br />
      @label.dispose<br />
      @backdrop.bitmap.dispose<br />
      @backdrop.dispose<br />
    end<br />
    attr_reader :text<br />
  end<br />
<br />
  class Spriteset<br />
    def initialize<br />
      @curse_viewport = Viewport.new(0, 0, 640, 480)<br />
      @curse_viewport.z = 500<br />
      @curse_boxes = []<br />
      @curse_x = []<br />
      @curse_y = []<br />
      filename = KursedVictory::OPTION_BACKDROP<br />
      options = KursedVictory::OPTIONS<br />
      options.each_with_index do |choice, n|<br />
        box = KursedVictory::TextBox.new(n, options.size, @curse_viewport)<br />
        box.set_image(filename)<br />
        box.set_text(choice)<br />
        @curse_x &lt;&lt; box.x<br />
        @curse_y &lt;&lt; box.y + KursedVictory::CURSOR_OY<br />
        @curse_boxes &lt;&lt; box<br />
      end<br />
      @cursed_cursor = Sprite.new(@curse_viewport)<br />
      @cursed_cursor.x = @curse_x[0]<br />
      @cursed_cursor.y = @curse_y[0]<br />
      @cursed_cursor.z = 100<br />
      @cursed_cursor.bitmap = Cache.picture(KursedVictory::CURSOR)<br />
    end<br />
<br />
    def move_cursor(index)<br />
      @cursed_cursor.y = @curse_y[index]<br />
    end<br />
<br />
    def dispose<br />
      @curse_boxes.each {|box| box.dispose }<br />
      @cursed_cursor.bitmap.dispose<br />
      @cursed_cursor.dispose<br />
      @curse_viewport.dispose<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Battle<br />
  alias :kyon_kurvic_scn_btl_proc_victor :process_victory<br />
  def process_victory<br />
    process_cursed_victory<br />
    if @cursed_victory and &#36;game_party.all_dead_now?<br />
      process_defeat<br />
      return<br />
    end<br />
    kyon_kurvic_scn_btl_proc_victor<br />
    start_anti_curse_battle if @curse_lifted<br />
  end<br />
<br />
  def start_anti_curse_battle<br />
    RPG::BGM.stop<br />
    RPG::BGS.stop<br />
    &#36;game_party.clear_actions<br />
    &#36;game_troop.clear<br />
    &#36;game_troop.setup(@round2_data[:troop_id])<br />
    Sound.play_battle_start<br />
    &#36;game_system.battle_bgm.play<br />
    &#36;scene = Scene_Battle.new<br />
  end<br />
<br />
  def process_cursed_victory<br />
    return if KursedVictory::CURSE_CHANCE &lt; rand(100)<br />
    return unless &#36;game_troop.curse_flawless_victory?<br />
    return if &#36;game_party.dead_members.size &gt; 0<br />
    RPG::BGM.stop<br />
    @bgs = RPG::BGS.new(KursedVictory::BGS)<br />
    @bgs.play<br />
    wx = (Graphics.width - 280) / 2<br />
    @cursed_message = CursedMessageWindow.new(wx, 40)<br />
    troop_id = &#36;game_troop.troop_id<br />
    @round2_data = KursedVictory::ROUND2_ENEMY_IDS[troop_id]<br />
    if @round2_data<br />
      process_cursed_victory_options<br />
      return if @curse_lifted<br />
    end<br />
    process_cursed_victory_execution<br />
  end<br />
<br />
  def process_cursed_victory_options<br />
    @cursed_spriteset = KursedVictory::Spriteset.new<br />
    @curse_stage = 0<br />
    @curse_index = 0<br />
    @cursed_options = true<br />
    while @cursed_options<br />
      Graphics.update<br />
      Input.update<br />
      update_cursed_victory<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory<br />
    case @curse_stage<br />
    when 0<br />
      update_cursed_victory_options<br />
    when 1<br />
      update_cursed_victory_decision<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory_options<br />
    if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)<br />
      Sound.play_cursor<br />
      @curse_index = (@curse_index + 1) % 2<br />
      @cursed_spriteset.move_cursor(@curse_index)<br />
      return<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      name = @round2_data[:name]<br />
      if name<br />
        text = KursedVictory::OUTCOME[@curse_index]<br />
        text = sprintf(text, name)<br />
      end<br />
      @cursed_spriteset.dispose<br />
      if @curse_index == 1<br />
        RPG::BGS.stop<br />
        @cursed_message.dispose<br />
        @curse_lifted = true<br />
      end<br />
      if name<br />
        ow = 460<br />
        &#36;game_message.texts &lt;&lt; text<br />
        @curse_stage = 1<br />
      else<br />
        @cursed_options = @curse_stage = nil<br />
      end<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory_decision<br />
    @message_window.update<br />
    if Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      @cursed_options = @curse_stage = nil<br />
    end<br />
  end<br />
<br />
  def process_cursed_victory_execution<br />
    @info_viewport.visible = true<br />
    @party_command_window.contents.clear<br />
    @party_command_window.index = -1<br />
    @message_window.visible = false<br />
    @status_window.index = 0<br />
    @status_window.active = true<br />
    @cursed_victory = true<br />
    while @cursed_victory<br />
      Graphics.update<br />
      Input.update<br />
      update_cursed_victory_execution<br />
    end<br />
    KursedVictory::WAIT_FRAMES.times { Graphics.update }<br />
    @cursed_message.dispose<br />
    @info_viewport.visible = false<br />
    @cursed_victory = true<br />
  end<br />
<br />
  def update_cursed_victory_execution<br />
    @status_window.update<br />
    if Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      n = @status_window.index<br />
      &#36;game_party.members[n].add_state(1)<br />
      @status_window.refresh<br />
      @status_window.active = false<br />
      @cursed_victory = nil<br />
    end<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">VX ACE Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KursedVictory ACE * #<br />
#   Scripter : Kyonides<br />
#   v1.2.0 - 2025-09-09<br />
<br />
# Sometimes the heroes cannot simply obtain a flawless victory. Thus, they need<br />
# some final punishment to make sure they learn their lesson!<br />
# - Method #1<br />
# Just add enemy ID's to the ENEMY_IDS constant to make this happen!<br />
# - Method #2<br />
# Leave a note tag in the enemy's notebox: curse_victory<br />
<br />
# Warning: If you refuse to comply, you might have to fight another troop...<br />
<br />
module KursedVictory<br />
  BGS = "Darkness"<br />
  CURSOR = "sword0132"<br />
  CURSOR_OY = 4<br />
  OPTION_BACKDROP = "box240"<br />
  MESSAGE = ["Flawless Victory!", "Now choose a curse victim!"]<br />
  OPTIONS = ["Comply", "Refuse"]<br />
  OUTCOME = ["You complied with the %s's demand.",<br />
             "You refused to listen to %s."]<br />
  CURSE_CHANCE = 100<br />
  WAIT_FRAMES = 40<br />
  ENEMY_NOTE_TAG = /curse_victory/i<br />
  ENEMY_IDS = []<br />
  ROUND2_ENEMY_IDS = {}<br />
  ROUND2_ENEMY_IDS[1] = { :name =&gt; "Basilisk", :troop_id =&gt; 2 }<br />
end<br />
<br />
class Game_Enemy<br />
  def cursed_victory_note<br />
    @cursed_victory ||= enemy.note[KursedVictory::ENEMY_NOTE_TAG]<br />
  end<br />
<br />
  def curse_victory?<br />
    return true if KursedVictory::ENEMY_IDS.include?(@enemy_id)<br />
    cursed_victory_note != nil<br />
  end<br />
end<br />
<br />
class Game_Party<br />
  def dead_members<br />
    members.select {|member| member.dead? }<br />
  end<br />
<br />
  def all_dead_now?<br />
    dead_members.size == @actors.size<br />
  end<br />
end<br />
<br />
class Game_Troop<br />
  def curse_flawless_victory?<br />
    enemy = @enemies.find {|enemy| enemy.curse_victory? }<br />
    enemy != nil<br />
  end<br />
  attr_reader :troop_id<br />
end<br />
<br />
class CursedMessageWindow &lt; Window_Base<br />
  def initialize(wx, wy)<br />
    super(wx, wy, 280, 76)<br />
    refresh<br />
  end<br />
<br />
  def refresh<br />
    line1, line2 = KursedVictory::MESSAGE<br />
    font = self.contents.font<br />
    font.bold = true<br />
    font.color.set(220, 80, 0)<br />
    self.contents.draw_text(0, 0, width - 32, 24, line1, 1)<br />
    font.bold = false<br />
    font.color.set(255, 255, 255)<br />
    self.contents.draw_text(0, 26, width - 32, 24, line2, 1)<br />
  end<br />
end<br />
<br />
module KursedVictory<br />
  class Message &lt; Window_Base<br />
    def set_text(text)<br />
      contents.clear<br />
      contents.draw_text(0, 0, contents.width, 24, text)<br />
      self.visible = true<br />
      self.pause = true<br />
    end<br />
  end<br />
<br />
  class TextBox<br />
    def initialize(pos, total, vp=nil)<br />
      @index = pos<br />
      @max = total<br />
      @row_max = 2<br />
      @col_max = 1<br />
      @viewport = vp<br />
      @backdrop = Sprite.new(vp)<br />
      @label = Sprite.new(vp)<br />
      @label.z = 50<br />
    end<br />
<br />
    def set_image(filename)<br />
      @filename = filename<br />
      set_bitmap<br />
      set_text_bitmap<br />
      reset_alignment<br />
    end<br />
<br />
    def set_bitmap<br />
      bitmap = Cache.picture(@filename)<br />
      @width = bitmap.width<br />
      @height = bitmap.height<br />
      @rect = bitmap.rect<br />
      @col_width = Graphics.width<br />
      @center_x = (@col_width - @width) / 2<br />
      @backdrop.bitmap = bitmap<br />
    end<br />
<br />
    def set_text_bitmap<br />
      @align_x = 1<br />
      @label.bitmap = Bitmap.new(@width, @height)<br />
    end<br />
<br />
    def set_align_xy<br />
      h = @height + 24<br />
      @backdrop.x = @center_x<br />
      @backdrop.y = 140 + @index * h<br />
    end<br />
<br />
    def reset_alignment<br />
      set_align_xy<br />
      @label.x = @backdrop.x<br />
      @label.y = @backdrop.y<br />
    end<br />
<br />
    def x<br />
      @backdrop.x<br />
    end<br />
<br />
    def y<br />
      @backdrop.y<br />
    end<br />
<br />
    def set_text(text)<br />
      @text = text<br />
      bit = @label.bitmap<br />
      bit.clear<br />
      bit.draw_text(@rect, text, @align_x)<br />
    end<br />
<br />
    def dispose<br />
      @label.bitmap.dispose<br />
      @label.dispose<br />
      @backdrop.bitmap.dispose<br />
      @backdrop.dispose<br />
    end<br />
    attr_reader :text<br />
  end<br />
<br />
  class Spriteset<br />
    def initialize<br />
      @curse_viewport = Viewport.new<br />
      @curse_viewport.z = 500<br />
      @curse_boxes = []<br />
      @curse_x = []<br />
      @curse_y = []<br />
      filename = KursedVictory::OPTION_BACKDROP<br />
      options = KursedVictory::OPTIONS<br />
      options.each_with_index do |choice, n|<br />
        box = KursedVictory::TextBox.new(n, options.size, @curse_viewport)<br />
        box.set_image(filename)<br />
        box.set_text(choice)<br />
        @curse_x &lt;&lt; box.x<br />
        @curse_y &lt;&lt; box.y + KursedVictory::CURSOR_OY<br />
        @curse_boxes &lt;&lt; box<br />
      end<br />
      @cursed_cursor = Sprite.new(@curse_viewport)<br />
      @cursed_cursor.x = @curse_x[0]<br />
      @cursed_cursor.y = @curse_y[0]<br />
      @cursed_cursor.z = 100<br />
      @cursed_cursor.bitmap = Cache.picture(KursedVictory::CURSOR)<br />
    end<br />
<br />
    def move_cursor(index)<br />
      @cursed_cursor.y = @curse_y[index]<br />
    end<br />
<br />
    def dispose<br />
      @curse_boxes.each {|box| box.dispose }<br />
      @cursed_cursor.bitmap.dispose<br />
      @cursed_cursor.dispose<br />
      @curse_viewport.dispose<br />
    end<br />
  end<br />
end<br />
<br />
class &lt;&lt; BattleManager<br />
  alias :kyon_kurvic_btlman_proc_victor :process_victory<br />
  def process_victory<br />
    process_cursed_victory<br />
    if @cursed_victory and &#36;game_party.all_dead_now?<br />
      process_defeat<br />
      return true<br />
    end<br />
    kyon_kurvic_btlman_proc_victor<br />
    start_anti_curse_battle if @curse_lifted<br />
    @curse_lifted = nil<br />
    true<br />
  end<br />
<br />
  def process_cursed_victory<br />
    return if KursedVictory::CURSE_CHANCE &lt; rand(100)<br />
    return unless &#36;game_troop.curse_flawless_victory?<br />
    return if &#36;game_party.dead_members.size &gt; 0<br />
    RPG::BGM.stop<br />
    @bgs = RPG::BGS.new(KursedVictory::BGS)<br />
    @bgs.play<br />
    @scene = SceneManager.scene<br />
    @scene.create_cursed_message<br />
    @scene.start_cursed_victory<br />
  end<br />
<br />
  def start_anti_curse_battle<br />
    RPG::BGM.stop<br />
    RPG::BGS.stop<br />
    &#36;game_party.clear_actions<br />
    &#36;game_troop.clear<br />
    &#36;game_troop.setup(@next_troop_id)<br />
    @next_troop_id = nil<br />
    Sound.play_battle_start<br />
    BattleManager.play_battle_bgm<br />
    SceneManager.call(Scene_Battle)<br />
  end<br />
  attr_writer :cursed_victory, :next_troop_id<br />
  attr_accessor :curse_lifted<br />
end<br />
<br />
class Scene_Battle<br />
  def create_cursed_message<br />
    wx = (Graphics.width - 280) / 2<br />
    @cursed_message = CursedMessageWindow.new(wx, 40)<br />
    @info_viewport.visible = true<br />
    @party_command_window.contents.clear<br />
    @party_command_window.index = -1<br />
    @message_window.visible = false<br />
    @status_window.index = 0<br />
    @status_window.active = true<br />
    @outcome_window = KursedVictory::Message.new(0, 288, 544, 128)<br />
    @outcome_window.visible = false<br />
  end<br />
<br />
  def start_cursed_victory<br />
    troop_id = &#36;game_troop.troop_id<br />
    @round2_data = KursedVictory::ROUND2_ENEMY_IDS[troop_id]<br />
    if @round2_data<br />
      process_cursed_victory_options<br />
      return if BattleManager.curse_lifted<br />
    end<br />
    process_cursed_victory_execution<br />
  end<br />
<br />
  def process_cursed_victory_options<br />
    @cursed_spriteset = KursedVictory::Spriteset.new<br />
    @curse_stage = 0<br />
    @curse_index = 0<br />
    while @curse_stage<br />
      Graphics.update<br />
      Input.update<br />
      update_cursed_victory<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory<br />
    case @curse_stage<br />
    when 0<br />
      update_cursed_victory_options<br />
    when 1<br />
      update_cursed_victory_decision<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory_options<br />
    if Input.trigger?(:UP) or Input.trigger?(:DOWN)<br />
      Sound.play_cursor<br />
      @curse_index = (@curse_index + 1) % 2<br />
      @cursed_spriteset.move_cursor(@curse_index)<br />
      return<br />
    elsif Input.trigger?(:C)<br />
      Sound.play_ok<br />
      name = @round2_data[:name]<br />
      if name<br />
        text = KursedVictory::OUTCOME[@curse_index]<br />
        text = sprintf(text, name)<br />
      end<br />
      @cursed_spriteset.dispose<br />
      if @curse_index == 1<br />
        RPG::BGS.stop<br />
        BattleManager.curse_lifted = true<br />
        BattleManager.next_troop_id = @round2_data[:troop_id]<br />
        @cursed_message.dispose<br />
        @cursed_message = nil<br />
      end<br />
      if name<br />
        @outcome_window.set_text(text)<br />
        @status_window.visible = false<br />
        @curse_stage = 1<br />
      else<br />
        @curse_stage = nil<br />
      end<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory_decision<br />
    @outcome_window.update<br />
    if Input.trigger?(:C)<br />
      Sound.play_ok<br />
      state = @curse_index == 0<br />
      BattleManager.cursed_victory = state<br />
      @status_window.visible = state<br />
      @message_window.visible = !state<br />
      @outcome_window.dispose<br />
      @outcome_window = @curse_stage = nil<br />
    end<br />
  end<br />
<br />
  def process_cursed_victory_execution<br />
    while @curse_index<br />
      Graphics.update<br />
      Input.update<br />
      update_cursed_victory_execution<br />
    end<br />
    KursedVictory::WAIT_FRAMES.times { Graphics.update }<br />
    @message_window.visible = true<br />
    @cursed_message.dispose<br />
    @cursed_message = nil<br />
  end<br />
<br />
  def update_cursed_victory_execution<br />
    @status_window.update<br />
    if Input.trigger?(:C)<br />
      Sound.play_ok<br />
      n = @status_window.index<br />
      &#36;game_party.members[n].add_state(1)<br />
      BattleManager.cursed_victory = nil<br />
      @status_window.refresh<br />
      @status_window.active = false<br />
      @curse_index = nil<br />
    end<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer for non commercial games. <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /><br />
Include my nickname in your game credits.<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">KursedVictory VX + ACE</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 />
You will either love this scriptlet or just hate it. <img src="https://www.save-point.org/images/smilies/ejlol/laughing.gif" alt="Laughing" title="Laughing" class="smilie smilie_23" /><br />
Sometimes the heroes cannot simply obtain a flawless victory. That would be inconceivable! <img src="https://www.save-point.org/images/smilies/ejlol/credible.gif" alt="Incredible" title="Incredible" class="smilie smilie_232" /> <br />
Thus, they need some final punishment to make sure they learn their lesson! <img src="https://www.save-point.org/images/smilies/ejlol/serious.gif" alt="Serious" title="Serious" class="smilie smilie_50" /> <br />
<br />
Just add enemy ID's to the <span style="font-weight: bold;" class="mycode_b">ENEMY_IDS</span> constant to make this happen! <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /> <br />
<br />
Or leave this note tag in the enemy's notebox: <span style="font-weight: bold;" class="mycode_b">curse_victory</span><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/qMCxdDLp/kursedvictory-vx01.jpg" loading="lazy"  alt="[Image: kursedvictory-vx01.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/xjZ3hVLs/kursedvictory-vx02.jpg" loading="lazy"  alt="[Image: kursedvictory-vx02.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/vZS2bRBh/kursedvictory-vx003.jpg" loading="lazy"  alt="[Image: kursedvictory-vx003.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/Bnv7rZqt/kursedvictory-vx004.jpg" loading="lazy"  alt="[Image: kursedvictory-vx004.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/QxdPc0Cr/kursedvictory-ace01.jpg" loading="lazy"  alt="[Image: kursedvictory-ace01.jpg]" class="mycode_img" /><br />
<img src="https://i.postimg.cc/xTpZ5MNN/kursedvictory-ace02.jpg" loading="lazy"  alt="[Image: kursedvictory-ace02.jpg]" class="mycode_img" /><br />
</div>
		</div>
<br />
<span style="font-weight: bold;" class="mycode_b">VX Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KursedVictory VX * #<br />
#   Scripter : Kyonides<br />
#   v1.2.0 - 2025-09-09<br />
<br />
# Sometimes the heroes cannot simply obtain a flawless victory. Thus, they need<br />
# some final punishment to make sure they learn their lesson!<br />
# - Method #1<br />
# Just add enemy ID's to the ENEMY_IDS constant to make this happen!<br />
# - Method #2<br />
# Leave a note tag in the enemy's notebox: curse_victory<br />
<br />
# Warning: If you refuse to comply, you might have to fight another troop...<br />
<br />
module KursedVictory<br />
  BGS = "Darkness"<br />
  CURSOR = "sword0132"<br />
  CURSOR_OY = 4<br />
  OPTION_BACKDROP = "box240"<br />
  MESSAGE = ["Flawless Victory!", "Now choose a curse victim!"]<br />
  OPTIONS = ["Comply", "Refuse"]<br />
  OUTCOME = ["You complied with the %s's demand.",<br />
             "You refused to listen to %s."]<br />
  CURSE_CHANCE = 100<br />
  WAIT_FRAMES = 40<br />
  ENEMY_NOTE_TAG = /curse_victory/i<br />
  ENEMY_IDS = []<br />
  ROUND2_ENEMY_IDS = {}<br />
  ROUND2_ENEMY_IDS[1] = { :name =&gt; "Basilisk", :troop_id =&gt; 2 }<br />
end<br />
<br />
class Game_Enemy<br />
  def cursed_victory_note<br />
    @cursed_victory ||= enemy.note[KursedVictory::ENEMY_NOTE_TAG]<br />
  end<br />
<br />
  def curse_victory?<br />
    return true if KursedVictory::ENEMY_IDS.include?(@enemy_id)<br />
    cursed_victory_note != nil<br />
  end<br />
end<br />
<br />
class Game_Party<br />
  def dead_members<br />
    members.select {|member| member.dead? }<br />
  end<br />
<br />
  def all_dead_now?<br />
    dead_members.size == @actors.size<br />
  end<br />
end<br />
<br />
class Game_Troop<br />
  def curse_flawless_victory?<br />
    enemy = @enemies.find {|enemy| enemy.curse_victory? }<br />
    enemy != nil<br />
  end<br />
  attr_reader :troop_id<br />
end<br />
<br />
class CursedMessageWindow &lt; Window_Base<br />
  def initialize(wx, wy)<br />
    super(wx, wy, 280, 80)<br />
    refresh<br />
  end<br />
<br />
  def refresh<br />
    line1, line2 = KursedVictory::MESSAGE<br />
    font = self.contents.font<br />
    font.bold = true<br />
    font.color.set(220, 80, 0)<br />
    self.contents.draw_text(0, 0, width - 32, 24, line1, 1)<br />
    font.bold = false<br />
    font.color.set(255, 255, 255)<br />
    self.contents.draw_text(0, 24, width - 32, 24, line2, 1)<br />
  end<br />
end<br />
<br />
module KursedVictory<br />
  class TextBox<br />
    def initialize(pos, total, vp=nil)<br />
      @index = pos<br />
      @max = total<br />
      @row_max = 2<br />
      @col_max = 1<br />
      @viewport = vp<br />
      @backdrop = Sprite.new(vp)<br />
      @label = Sprite.new(vp)<br />
      @label.z = 50<br />
    end<br />
<br />
    def set_image(filename)<br />
      @filename = filename<br />
      set_bitmap<br />
      set_text_bitmap<br />
      reset_alignment<br />
    end<br />
<br />
    def set_bitmap<br />
      bitmap = Cache.picture(@filename)<br />
      @width = bitmap.width<br />
      @height = bitmap.height<br />
      @rect = bitmap.rect<br />
      @col_width = Graphics.width<br />
      @center_x = (@col_width - @width) / 2<br />
      @backdrop.bitmap = bitmap<br />
    end<br />
<br />
    def set_text_bitmap<br />
      @align_x = 1<br />
      @label.bitmap = Bitmap.new(@width, @height)<br />
    end<br />
<br />
    def set_align_xy<br />
      h = @height + 24<br />
      @backdrop.x = @center_x<br />
      @backdrop.y = 140 + @index * h<br />
    end<br />
<br />
    def reset_alignment<br />
      set_align_xy<br />
      @label.x = @backdrop.x<br />
      @label.y = @backdrop.y<br />
    end<br />
<br />
    def x<br />
      @backdrop.x<br />
    end<br />
<br />
    def y<br />
      @backdrop.y<br />
    end<br />
<br />
    def set_text(text)<br />
      @text = text<br />
      bit = @label.bitmap<br />
      bit.clear<br />
      bit.draw_text(@rect, text, @align_x)<br />
    end<br />
<br />
    def dispose<br />
      @label.bitmap.dispose<br />
      @label.dispose<br />
      @backdrop.bitmap.dispose<br />
      @backdrop.dispose<br />
    end<br />
    attr_reader :text<br />
  end<br />
<br />
  class Spriteset<br />
    def initialize<br />
      @curse_viewport = Viewport.new(0, 0, 640, 480)<br />
      @curse_viewport.z = 500<br />
      @curse_boxes = []<br />
      @curse_x = []<br />
      @curse_y = []<br />
      filename = KursedVictory::OPTION_BACKDROP<br />
      options = KursedVictory::OPTIONS<br />
      options.each_with_index do |choice, n|<br />
        box = KursedVictory::TextBox.new(n, options.size, @curse_viewport)<br />
        box.set_image(filename)<br />
        box.set_text(choice)<br />
        @curse_x &lt;&lt; box.x<br />
        @curse_y &lt;&lt; box.y + KursedVictory::CURSOR_OY<br />
        @curse_boxes &lt;&lt; box<br />
      end<br />
      @cursed_cursor = Sprite.new(@curse_viewport)<br />
      @cursed_cursor.x = @curse_x[0]<br />
      @cursed_cursor.y = @curse_y[0]<br />
      @cursed_cursor.z = 100<br />
      @cursed_cursor.bitmap = Cache.picture(KursedVictory::CURSOR)<br />
    end<br />
<br />
    def move_cursor(index)<br />
      @cursed_cursor.y = @curse_y[index]<br />
    end<br />
<br />
    def dispose<br />
      @curse_boxes.each {|box| box.dispose }<br />
      @cursed_cursor.bitmap.dispose<br />
      @cursed_cursor.dispose<br />
      @curse_viewport.dispose<br />
    end<br />
  end<br />
end<br />
<br />
class Scene_Battle<br />
  alias :kyon_kurvic_scn_btl_proc_victor :process_victory<br />
  def process_victory<br />
    process_cursed_victory<br />
    if @cursed_victory and &#36;game_party.all_dead_now?<br />
      process_defeat<br />
      return<br />
    end<br />
    kyon_kurvic_scn_btl_proc_victor<br />
    start_anti_curse_battle if @curse_lifted<br />
  end<br />
<br />
  def start_anti_curse_battle<br />
    RPG::BGM.stop<br />
    RPG::BGS.stop<br />
    &#36;game_party.clear_actions<br />
    &#36;game_troop.clear<br />
    &#36;game_troop.setup(@round2_data[:troop_id])<br />
    Sound.play_battle_start<br />
    &#36;game_system.battle_bgm.play<br />
    &#36;scene = Scene_Battle.new<br />
  end<br />
<br />
  def process_cursed_victory<br />
    return if KursedVictory::CURSE_CHANCE &lt; rand(100)<br />
    return unless &#36;game_troop.curse_flawless_victory?<br />
    return if &#36;game_party.dead_members.size &gt; 0<br />
    RPG::BGM.stop<br />
    @bgs = RPG::BGS.new(KursedVictory::BGS)<br />
    @bgs.play<br />
    wx = (Graphics.width - 280) / 2<br />
    @cursed_message = CursedMessageWindow.new(wx, 40)<br />
    troop_id = &#36;game_troop.troop_id<br />
    @round2_data = KursedVictory::ROUND2_ENEMY_IDS[troop_id]<br />
    if @round2_data<br />
      process_cursed_victory_options<br />
      return if @curse_lifted<br />
    end<br />
    process_cursed_victory_execution<br />
  end<br />
<br />
  def process_cursed_victory_options<br />
    @cursed_spriteset = KursedVictory::Spriteset.new<br />
    @curse_stage = 0<br />
    @curse_index = 0<br />
    @cursed_options = true<br />
    while @cursed_options<br />
      Graphics.update<br />
      Input.update<br />
      update_cursed_victory<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory<br />
    case @curse_stage<br />
    when 0<br />
      update_cursed_victory_options<br />
    when 1<br />
      update_cursed_victory_decision<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory_options<br />
    if Input.trigger?(Input::UP) or Input.trigger?(Input::DOWN)<br />
      Sound.play_cursor<br />
      @curse_index = (@curse_index + 1) % 2<br />
      @cursed_spriteset.move_cursor(@curse_index)<br />
      return<br />
    elsif Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      name = @round2_data[:name]<br />
      if name<br />
        text = KursedVictory::OUTCOME[@curse_index]<br />
        text = sprintf(text, name)<br />
      end<br />
      @cursed_spriteset.dispose<br />
      if @curse_index == 1<br />
        RPG::BGS.stop<br />
        @cursed_message.dispose<br />
        @curse_lifted = true<br />
      end<br />
      if name<br />
        ow = 460<br />
        &#36;game_message.texts &lt;&lt; text<br />
        @curse_stage = 1<br />
      else<br />
        @cursed_options = @curse_stage = nil<br />
      end<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory_decision<br />
    @message_window.update<br />
    if Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      @cursed_options = @curse_stage = nil<br />
    end<br />
  end<br />
<br />
  def process_cursed_victory_execution<br />
    @info_viewport.visible = true<br />
    @party_command_window.contents.clear<br />
    @party_command_window.index = -1<br />
    @message_window.visible = false<br />
    @status_window.index = 0<br />
    @status_window.active = true<br />
    @cursed_victory = true<br />
    while @cursed_victory<br />
      Graphics.update<br />
      Input.update<br />
      update_cursed_victory_execution<br />
    end<br />
    KursedVictory::WAIT_FRAMES.times { Graphics.update }<br />
    @cursed_message.dispose<br />
    @info_viewport.visible = false<br />
    @cursed_victory = true<br />
  end<br />
<br />
  def update_cursed_victory_execution<br />
    @status_window.update<br />
    if Input.trigger?(Input::C)<br />
      Sound.play_decision<br />
      n = @status_window.index<br />
      &#36;game_party.members[n].add_state(1)<br />
      @status_window.refresh<br />
      @status_window.active = false<br />
      @cursed_victory = nil<br />
    end<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">VX ACE Script</span><br />
<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KursedVictory ACE * #<br />
#   Scripter : Kyonides<br />
#   v1.2.0 - 2025-09-09<br />
<br />
# Sometimes the heroes cannot simply obtain a flawless victory. Thus, they need<br />
# some final punishment to make sure they learn their lesson!<br />
# - Method #1<br />
# Just add enemy ID's to the ENEMY_IDS constant to make this happen!<br />
# - Method #2<br />
# Leave a note tag in the enemy's notebox: curse_victory<br />
<br />
# Warning: If you refuse to comply, you might have to fight another troop...<br />
<br />
module KursedVictory<br />
  BGS = "Darkness"<br />
  CURSOR = "sword0132"<br />
  CURSOR_OY = 4<br />
  OPTION_BACKDROP = "box240"<br />
  MESSAGE = ["Flawless Victory!", "Now choose a curse victim!"]<br />
  OPTIONS = ["Comply", "Refuse"]<br />
  OUTCOME = ["You complied with the %s's demand.",<br />
             "You refused to listen to %s."]<br />
  CURSE_CHANCE = 100<br />
  WAIT_FRAMES = 40<br />
  ENEMY_NOTE_TAG = /curse_victory/i<br />
  ENEMY_IDS = []<br />
  ROUND2_ENEMY_IDS = {}<br />
  ROUND2_ENEMY_IDS[1] = { :name =&gt; "Basilisk", :troop_id =&gt; 2 }<br />
end<br />
<br />
class Game_Enemy<br />
  def cursed_victory_note<br />
    @cursed_victory ||= enemy.note[KursedVictory::ENEMY_NOTE_TAG]<br />
  end<br />
<br />
  def curse_victory?<br />
    return true if KursedVictory::ENEMY_IDS.include?(@enemy_id)<br />
    cursed_victory_note != nil<br />
  end<br />
end<br />
<br />
class Game_Party<br />
  def dead_members<br />
    members.select {|member| member.dead? }<br />
  end<br />
<br />
  def all_dead_now?<br />
    dead_members.size == @actors.size<br />
  end<br />
end<br />
<br />
class Game_Troop<br />
  def curse_flawless_victory?<br />
    enemy = @enemies.find {|enemy| enemy.curse_victory? }<br />
    enemy != nil<br />
  end<br />
  attr_reader :troop_id<br />
end<br />
<br />
class CursedMessageWindow &lt; Window_Base<br />
  def initialize(wx, wy)<br />
    super(wx, wy, 280, 76)<br />
    refresh<br />
  end<br />
<br />
  def refresh<br />
    line1, line2 = KursedVictory::MESSAGE<br />
    font = self.contents.font<br />
    font.bold = true<br />
    font.color.set(220, 80, 0)<br />
    self.contents.draw_text(0, 0, width - 32, 24, line1, 1)<br />
    font.bold = false<br />
    font.color.set(255, 255, 255)<br />
    self.contents.draw_text(0, 26, width - 32, 24, line2, 1)<br />
  end<br />
end<br />
<br />
module KursedVictory<br />
  class Message &lt; Window_Base<br />
    def set_text(text)<br />
      contents.clear<br />
      contents.draw_text(0, 0, contents.width, 24, text)<br />
      self.visible = true<br />
      self.pause = true<br />
    end<br />
  end<br />
<br />
  class TextBox<br />
    def initialize(pos, total, vp=nil)<br />
      @index = pos<br />
      @max = total<br />
      @row_max = 2<br />
      @col_max = 1<br />
      @viewport = vp<br />
      @backdrop = Sprite.new(vp)<br />
      @label = Sprite.new(vp)<br />
      @label.z = 50<br />
    end<br />
<br />
    def set_image(filename)<br />
      @filename = filename<br />
      set_bitmap<br />
      set_text_bitmap<br />
      reset_alignment<br />
    end<br />
<br />
    def set_bitmap<br />
      bitmap = Cache.picture(@filename)<br />
      @width = bitmap.width<br />
      @height = bitmap.height<br />
      @rect = bitmap.rect<br />
      @col_width = Graphics.width<br />
      @center_x = (@col_width - @width) / 2<br />
      @backdrop.bitmap = bitmap<br />
    end<br />
<br />
    def set_text_bitmap<br />
      @align_x = 1<br />
      @label.bitmap = Bitmap.new(@width, @height)<br />
    end<br />
<br />
    def set_align_xy<br />
      h = @height + 24<br />
      @backdrop.x = @center_x<br />
      @backdrop.y = 140 + @index * h<br />
    end<br />
<br />
    def reset_alignment<br />
      set_align_xy<br />
      @label.x = @backdrop.x<br />
      @label.y = @backdrop.y<br />
    end<br />
<br />
    def x<br />
      @backdrop.x<br />
    end<br />
<br />
    def y<br />
      @backdrop.y<br />
    end<br />
<br />
    def set_text(text)<br />
      @text = text<br />
      bit = @label.bitmap<br />
      bit.clear<br />
      bit.draw_text(@rect, text, @align_x)<br />
    end<br />
<br />
    def dispose<br />
      @label.bitmap.dispose<br />
      @label.dispose<br />
      @backdrop.bitmap.dispose<br />
      @backdrop.dispose<br />
    end<br />
    attr_reader :text<br />
  end<br />
<br />
  class Spriteset<br />
    def initialize<br />
      @curse_viewport = Viewport.new<br />
      @curse_viewport.z = 500<br />
      @curse_boxes = []<br />
      @curse_x = []<br />
      @curse_y = []<br />
      filename = KursedVictory::OPTION_BACKDROP<br />
      options = KursedVictory::OPTIONS<br />
      options.each_with_index do |choice, n|<br />
        box = KursedVictory::TextBox.new(n, options.size, @curse_viewport)<br />
        box.set_image(filename)<br />
        box.set_text(choice)<br />
        @curse_x &lt;&lt; box.x<br />
        @curse_y &lt;&lt; box.y + KursedVictory::CURSOR_OY<br />
        @curse_boxes &lt;&lt; box<br />
      end<br />
      @cursed_cursor = Sprite.new(@curse_viewport)<br />
      @cursed_cursor.x = @curse_x[0]<br />
      @cursed_cursor.y = @curse_y[0]<br />
      @cursed_cursor.z = 100<br />
      @cursed_cursor.bitmap = Cache.picture(KursedVictory::CURSOR)<br />
    end<br />
<br />
    def move_cursor(index)<br />
      @cursed_cursor.y = @curse_y[index]<br />
    end<br />
<br />
    def dispose<br />
      @curse_boxes.each {|box| box.dispose }<br />
      @cursed_cursor.bitmap.dispose<br />
      @cursed_cursor.dispose<br />
      @curse_viewport.dispose<br />
    end<br />
  end<br />
end<br />
<br />
class &lt;&lt; BattleManager<br />
  alias :kyon_kurvic_btlman_proc_victor :process_victory<br />
  def process_victory<br />
    process_cursed_victory<br />
    if @cursed_victory and &#36;game_party.all_dead_now?<br />
      process_defeat<br />
      return true<br />
    end<br />
    kyon_kurvic_btlman_proc_victor<br />
    start_anti_curse_battle if @curse_lifted<br />
    @curse_lifted = nil<br />
    true<br />
  end<br />
<br />
  def process_cursed_victory<br />
    return if KursedVictory::CURSE_CHANCE &lt; rand(100)<br />
    return unless &#36;game_troop.curse_flawless_victory?<br />
    return if &#36;game_party.dead_members.size &gt; 0<br />
    RPG::BGM.stop<br />
    @bgs = RPG::BGS.new(KursedVictory::BGS)<br />
    @bgs.play<br />
    @scene = SceneManager.scene<br />
    @scene.create_cursed_message<br />
    @scene.start_cursed_victory<br />
  end<br />
<br />
  def start_anti_curse_battle<br />
    RPG::BGM.stop<br />
    RPG::BGS.stop<br />
    &#36;game_party.clear_actions<br />
    &#36;game_troop.clear<br />
    &#36;game_troop.setup(@next_troop_id)<br />
    @next_troop_id = nil<br />
    Sound.play_battle_start<br />
    BattleManager.play_battle_bgm<br />
    SceneManager.call(Scene_Battle)<br />
  end<br />
  attr_writer :cursed_victory, :next_troop_id<br />
  attr_accessor :curse_lifted<br />
end<br />
<br />
class Scene_Battle<br />
  def create_cursed_message<br />
    wx = (Graphics.width - 280) / 2<br />
    @cursed_message = CursedMessageWindow.new(wx, 40)<br />
    @info_viewport.visible = true<br />
    @party_command_window.contents.clear<br />
    @party_command_window.index = -1<br />
    @message_window.visible = false<br />
    @status_window.index = 0<br />
    @status_window.active = true<br />
    @outcome_window = KursedVictory::Message.new(0, 288, 544, 128)<br />
    @outcome_window.visible = false<br />
  end<br />
<br />
  def start_cursed_victory<br />
    troop_id = &#36;game_troop.troop_id<br />
    @round2_data = KursedVictory::ROUND2_ENEMY_IDS[troop_id]<br />
    if @round2_data<br />
      process_cursed_victory_options<br />
      return if BattleManager.curse_lifted<br />
    end<br />
    process_cursed_victory_execution<br />
  end<br />
<br />
  def process_cursed_victory_options<br />
    @cursed_spriteset = KursedVictory::Spriteset.new<br />
    @curse_stage = 0<br />
    @curse_index = 0<br />
    while @curse_stage<br />
      Graphics.update<br />
      Input.update<br />
      update_cursed_victory<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory<br />
    case @curse_stage<br />
    when 0<br />
      update_cursed_victory_options<br />
    when 1<br />
      update_cursed_victory_decision<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory_options<br />
    if Input.trigger?(:UP) or Input.trigger?(:DOWN)<br />
      Sound.play_cursor<br />
      @curse_index = (@curse_index + 1) % 2<br />
      @cursed_spriteset.move_cursor(@curse_index)<br />
      return<br />
    elsif Input.trigger?(:C)<br />
      Sound.play_ok<br />
      name = @round2_data[:name]<br />
      if name<br />
        text = KursedVictory::OUTCOME[@curse_index]<br />
        text = sprintf(text, name)<br />
      end<br />
      @cursed_spriteset.dispose<br />
      if @curse_index == 1<br />
        RPG::BGS.stop<br />
        BattleManager.curse_lifted = true<br />
        BattleManager.next_troop_id = @round2_data[:troop_id]<br />
        @cursed_message.dispose<br />
        @cursed_message = nil<br />
      end<br />
      if name<br />
        @outcome_window.set_text(text)<br />
        @status_window.visible = false<br />
        @curse_stage = 1<br />
      else<br />
        @curse_stage = nil<br />
      end<br />
    end<br />
  end<br />
<br />
  def update_cursed_victory_decision<br />
    @outcome_window.update<br />
    if Input.trigger?(:C)<br />
      Sound.play_ok<br />
      state = @curse_index == 0<br />
      BattleManager.cursed_victory = state<br />
      @status_window.visible = state<br />
      @message_window.visible = !state<br />
      @outcome_window.dispose<br />
      @outcome_window = @curse_stage = nil<br />
    end<br />
  end<br />
<br />
  def process_cursed_victory_execution<br />
    while @curse_index<br />
      Graphics.update<br />
      Input.update<br />
      update_cursed_victory_execution<br />
    end<br />
    KursedVictory::WAIT_FRAMES.times { Graphics.update }<br />
    @message_window.visible = true<br />
    @cursed_message.dispose<br />
    @cursed_message = nil<br />
  end<br />
<br />
  def update_cursed_victory_execution<br />
    @status_window.update<br />
    if Input.trigger?(:C)<br />
      Sound.play_ok<br />
      n = @status_window.index<br />
      &#36;game_party.members[n].add_state(1)<br />
      BattleManager.cursed_victory = nil<br />
      @status_window.refresh<br />
      @status_window.active = false<br />
      @curse_index = nil<br />
    end<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer for non commercial games. <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" alt="Gamer" title="Gamer" class="smilie smilie_183" /><br />
Include my nickname in your game credits.<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[KMustDie VX + ACE]]></title>
			<link>https://www.save-point.org/thread-12743.html</link>
			<pubDate>Wed, 03 Sep 2025 05:47:42 +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-12743.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">KMustDie VX + ACE</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 />
<img src="https://www.save-point.org/images/smilies/ejlol/up.gif" loading="lazy"  alt="[Image: up.gif]" class="mycode_img" /> Imagine a game world where certain battles won't force you to kill ALL of the enemy troops on screen.<br />
<img src="https://www.save-point.org/images/smilies/ejlol/sweathappy.gif" loading="lazy"  alt="[Image: sweathappy.gif]" class="mycode_img" /> Well, you can stop doing that right away because now you can make your battle dream come true! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" loading="lazy"  alt="[Image: shocked.gif]" class="mycode_img" /><br />
Just set which troops are mandatory to kill via a script call and that's it! <img src="https://www.save-point.org/images/smilies/ejlol/thumbs.gif" loading="lazy"  alt="[Image: thumbs.gif]" class="mycode_img" /> <br />
You won't have to depend on a tough negotiator to deal with tyrants looking for free lands up for the grabs. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Script Call</span> - Use natural index values like 1 upto 8 here:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;game_troop.must_die(EnemyIndex1, etc.)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">VX Script</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KMustDie VX * #<br />
# &nbsp;&nbsp;Scripter : Kyonides<br />
# &nbsp;&nbsp;v1.0.1 - 2025-09-06<br />
<br />
# This scriptlet allows you to set a given number of enemies that must die in<br />
# battle before the player can be proclaimed as the victor there.<br />
<br />
# * Script Call * #<br />
# - Enter 1+ Enemy Indexes to set which enemies should die before battle ends.<br />
#&nbsp;&nbsp; You should use number 1 as the first position available there.<br />
# &#36;game_troop.must_die(EnemyIndex1, etc.)<br />
<br />
class Game_Troop<br />
  alias :kyon_must_die_gm_trp_init :initialize<br />
  attr_reader :hunt_targets<br />
  def initialize<br />
    kyon_must_die_gm_trp_init<br />
    @hunt_targets = [] <br />
  end<br />
<br />
  def dead_now<br />
    @enemies.select {|e| e.dead? }<br />
  end<br />
<br />
  def hunt_targets_dead?<br />
    targets = dead_now.map {|e| e.index + 1 }<br />
    @hunt_targets.any? and targets.sort == @hunt_targets<br />
  end<br />
<br />
  def must_die(*targets)<br />
    @hunt_targets = targets.sort<br />
  end<br />
end<br />
<br />
class Scene_Battle<br />
  alias :kyon_must_die_scn_btl_judge :judge_win_loss<br />
  alias :kyon_must_die_scn_btl_blt_end :battle_end<br />
  def judge_win_loss<br />
    if &#36;game_troop.hunt_targets_dead?<br />
      process_victory<br />
      return true<br />
    else<br />
      kyon_must_die_scn_btl_judge<br />
    end<br />
  end<br />
<br />
  def battle_end(result)<br />
    &#36;game_troop.hunt_targets.clear<br />
    kyon_must_die_scn_btl_blt_end(result)<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">VX ACE Script</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KMustDie ACE * #<br />
#&nbsp;&nbsp; Scripter : Kyonides Arkanthes<br />
#&nbsp;&nbsp; v1.0.1 - 2025-09-06<br />
<br />
# This scriptlet allows you to set a given number of enemies that must die in<br />
# battle before the player can be proclaimed as the victor there.<br />
<br />
# * Script Call * #<br />
# - Enter 1+ Enemy Indexes to set which enemies should die before battle ends.<br />
#&nbsp;&nbsp; You should use number 1 as the first position available there.<br />
# &#36;game_troop.must_die(EnemyIndex1, etc.)<br />
<br />
class Game_Troop<br />
&nbsp;&nbsp;alias :kyon_must_die_gm_trp_init :initialize<br />
&nbsp;&nbsp;attr_reader :hunt_targets<br />
&nbsp;&nbsp;def initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_must_die_gm_trp_init<br />
&nbsp;&nbsp;&nbsp;&nbsp;@hunt_targets = [] <br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def dead_now<br />
&nbsp;&nbsp;&nbsp;&nbsp;members.select {|e| e.dead? }<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def hunt_targets_dead?<br />
&nbsp;&nbsp;&nbsp;&nbsp;targets = dead_now.map {|e| e.index + 1 }<br />
&nbsp;&nbsp;&nbsp;&nbsp;@hunt_targets.any? and targets.sort == @hunt_targets<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def must_die(*targets)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@hunt_targets = targets.sort<br />
&nbsp;&nbsp;end<br />
end<br />
<br />
class &lt;&lt; BattleManager<br />
&nbsp;&nbsp;alias :kyon_must_die_btlman_judge :judge_win_loss<br />
&nbsp;&nbsp;alias :kyon_must_die_btlman_blt_end :battle_end<br />
&nbsp;&nbsp;def judge_win_loss<br />
&nbsp;&nbsp;&nbsp;&nbsp;if &#36;game_troop.hunt_targets_dead?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process_victory<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kyon_must_die_btlman_judge<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def battle_end(result)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_troop.hunt_targets.clear<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_must_die_btlman_blt_end(result)<br />
&nbsp;&nbsp;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: x-large;" class="mycode_size"><a href="https://www.mediafire.com/folder/dnnotqzr55fgm/KMustDie" target="_blank" rel="noopener" class="mycode_url">DOWNLOAD DEMOS!</a></span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" loading="lazy"  alt="[Image: beer.gif]" class="mycode_img" /> beer for non-commercial games. <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" loading="lazy"  alt="[Image: gamer.gif]" class="mycode_img" /><br />
Include my nickname in your game credits.<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-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KMustDie VX + ACE</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 />
<img src="https://www.save-point.org/images/smilies/ejlol/up.gif" loading="lazy"  alt="[Image: up.gif]" class="mycode_img" /> Imagine a game world where certain battles won't force you to kill ALL of the enemy troops on screen.<br />
<img src="https://www.save-point.org/images/smilies/ejlol/sweathappy.gif" loading="lazy"  alt="[Image: sweathappy.gif]" class="mycode_img" /> Well, you can stop doing that right away because now you can make your battle dream come true! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" loading="lazy"  alt="[Image: shocked.gif]" class="mycode_img" /><br />
Just set which troops are mandatory to kill via a script call and that's it! <img src="https://www.save-point.org/images/smilies/ejlol/thumbs.gif" loading="lazy"  alt="[Image: thumbs.gif]" class="mycode_img" /> <br />
You won't have to depend on a tough negotiator to deal with tyrants looking for free lands up for the grabs. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Script Call</span> - Use natural index values like 1 upto 8 here:<br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>&#36;game_troop.must_die(EnemyIndex1, etc.)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">VX Script</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KMustDie VX * #<br />
# &nbsp;&nbsp;Scripter : Kyonides<br />
# &nbsp;&nbsp;v1.0.1 - 2025-09-06<br />
<br />
# This scriptlet allows you to set a given number of enemies that must die in<br />
# battle before the player can be proclaimed as the victor there.<br />
<br />
# * Script Call * #<br />
# - Enter 1+ Enemy Indexes to set which enemies should die before battle ends.<br />
#&nbsp;&nbsp; You should use number 1 as the first position available there.<br />
# &#36;game_troop.must_die(EnemyIndex1, etc.)<br />
<br />
class Game_Troop<br />
  alias :kyon_must_die_gm_trp_init :initialize<br />
  attr_reader :hunt_targets<br />
  def initialize<br />
    kyon_must_die_gm_trp_init<br />
    @hunt_targets = [] <br />
  end<br />
<br />
  def dead_now<br />
    @enemies.select {|e| e.dead? }<br />
  end<br />
<br />
  def hunt_targets_dead?<br />
    targets = dead_now.map {|e| e.index + 1 }<br />
    @hunt_targets.any? and targets.sort == @hunt_targets<br />
  end<br />
<br />
  def must_die(*targets)<br />
    @hunt_targets = targets.sort<br />
  end<br />
end<br />
<br />
class Scene_Battle<br />
  alias :kyon_must_die_scn_btl_judge :judge_win_loss<br />
  alias :kyon_must_die_scn_btl_blt_end :battle_end<br />
  def judge_win_loss<br />
    if &#36;game_troop.hunt_targets_dead?<br />
      process_victory<br />
      return true<br />
    else<br />
      kyon_must_die_scn_btl_judge<br />
    end<br />
  end<br />
<br />
  def battle_end(result)<br />
    &#36;game_troop.hunt_targets.clear<br />
    kyon_must_die_scn_btl_blt_end(result)<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">VX ACE Script</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * KMustDie ACE * #<br />
#&nbsp;&nbsp; Scripter : Kyonides Arkanthes<br />
#&nbsp;&nbsp; v1.0.1 - 2025-09-06<br />
<br />
# This scriptlet allows you to set a given number of enemies that must die in<br />
# battle before the player can be proclaimed as the victor there.<br />
<br />
# * Script Call * #<br />
# - Enter 1+ Enemy Indexes to set which enemies should die before battle ends.<br />
#&nbsp;&nbsp; You should use number 1 as the first position available there.<br />
# &#36;game_troop.must_die(EnemyIndex1, etc.)<br />
<br />
class Game_Troop<br />
&nbsp;&nbsp;alias :kyon_must_die_gm_trp_init :initialize<br />
&nbsp;&nbsp;attr_reader :hunt_targets<br />
&nbsp;&nbsp;def initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_must_die_gm_trp_init<br />
&nbsp;&nbsp;&nbsp;&nbsp;@hunt_targets = [] <br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def dead_now<br />
&nbsp;&nbsp;&nbsp;&nbsp;members.select {|e| e.dead? }<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def hunt_targets_dead?<br />
&nbsp;&nbsp;&nbsp;&nbsp;targets = dead_now.map {|e| e.index + 1 }<br />
&nbsp;&nbsp;&nbsp;&nbsp;@hunt_targets.any? and targets.sort == @hunt_targets<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def must_die(*targets)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@hunt_targets = targets.sort<br />
&nbsp;&nbsp;end<br />
end<br />
<br />
class &lt;&lt; BattleManager<br />
&nbsp;&nbsp;alias :kyon_must_die_btlman_judge :judge_win_loss<br />
&nbsp;&nbsp;alias :kyon_must_die_btlman_blt_end :battle_end<br />
&nbsp;&nbsp;def judge_win_loss<br />
&nbsp;&nbsp;&nbsp;&nbsp;if &#36;game_troop.hunt_targets_dead?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process_victory<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true<br />
&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kyon_must_die_btlman_judge<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def battle_end(result)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_troop.hunt_targets.clear<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_must_die_btlman_blt_end(result)<br />
&nbsp;&nbsp;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: x-large;" class="mycode_size"><a href="https://www.mediafire.com/folder/dnnotqzr55fgm/KMustDie" target="_blank" rel="noopener" class="mycode_url">DOWNLOAD DEMOS!</a></span></span></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" loading="lazy"  alt="[Image: beer.gif]" class="mycode_img" /> beer for non-commercial games. <img src="https://www.save-point.org/images/smilies/ejlol/gamer.gif" loading="lazy"  alt="[Image: gamer.gif]" class="mycode_img" /><br />
Include my nickname in your game credits.<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[KChangeCmdMsg VX + ACE]]></title>
			<link>https://www.save-point.org/thread-11617.html</link>
			<pubDate>Wed, 23 Jul 2025 01:31:47 +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-11617.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">KChangeCmdMsg VX + ACE</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 is very practical. It allows you to predefine a message that will include both the object's name and the total amount of things the party has gain or lost just a split second ago. You will <span style="font-weight: bold;" class="mycode_b">no longer need</span> to click on the <span style="font-weight: bold;" class="mycode_b"><span style="font-style: italic;" class="mycode_i">Show Text</span></span> event command ever again to inform the player about those changes.<br />
<br />
That's laziness at its best! <img src="https://www.save-point.org/images/smilies/ejlol/thumbs.gif" loading="lazy"  alt="[Image: thumbs.gif]" class="mycode_img" /> <br />
<br />
<span style="font-weight: bold;" class="mycode_b">NOTES:</span><br />
<br />
The <span style="font-weight: bold;" class="mycode_b">FOUND_MSG</span> &amp; <span style="font-weight: bold;" class="mycode_b">LOST_MSG</span> constants contain the automated earn &amp; lost messages. Feel free to change them at will.<br />
Yet, you can also customize both <span style="font-weight: bold;" class="mycode_b">JOIN_MSG</span> and <span style="font-weight: bold;" class="mycode_b">LEAVE_MSG</span> if you want to add your personal touch to this new automated message.<br />
<br />
I know VX &amp; VX ACE already offer a way to quickly create a automated message, yet, this one allows you to find several items in a row at the same spot without any complications. And you can still add any other event commands to your event command list.<br />
<br />
<div style="text-align: center;" class="mycode_align"><a href="https://www.mediafire.com/folder/vunf8jgs0qw2w/KChangeCmdMsg" target="_blank" rel="noopener" class="mycode_url"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: x-large;" class="mycode_size">DOWNLOAD DEMOS</span></span></a></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
If you know how to use the engine, that's enough for me! <img src="https://www.save-point.org/images/smilies/ejlol/grin.gif" loading="lazy"  alt="[Image: grin.gif]" class="mycode_img" /><br />
Of course, I wouldn't mind if you include me in your game credits. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><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-weight: bold;" class="mycode_b"><span style="font-size: large;" class="mycode_size">KChangeCmdMsg VX + ACE</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 is very practical. It allows you to predefine a message that will include both the object's name and the total amount of things the party has gain or lost just a split second ago. You will <span style="font-weight: bold;" class="mycode_b">no longer need</span> to click on the <span style="font-weight: bold;" class="mycode_b"><span style="font-style: italic;" class="mycode_i">Show Text</span></span> event command ever again to inform the player about those changes.<br />
<br />
That's laziness at its best! <img src="https://www.save-point.org/images/smilies/ejlol/thumbs.gif" loading="lazy"  alt="[Image: thumbs.gif]" class="mycode_img" /> <br />
<br />
<span style="font-weight: bold;" class="mycode_b">NOTES:</span><br />
<br />
The <span style="font-weight: bold;" class="mycode_b">FOUND_MSG</span> &amp; <span style="font-weight: bold;" class="mycode_b">LOST_MSG</span> constants contain the automated earn &amp; lost messages. Feel free to change them at will.<br />
Yet, you can also customize both <span style="font-weight: bold;" class="mycode_b">JOIN_MSG</span> and <span style="font-weight: bold;" class="mycode_b">LEAVE_MSG</span> if you want to add your personal touch to this new automated message.<br />
<br />
I know VX &amp; VX ACE already offer a way to quickly create a automated message, yet, this one allows you to find several items in a row at the same spot without any complications. And you can still add any other event commands to your event command list.<br />
<br />
<div style="text-align: center;" class="mycode_align"><a href="https://www.mediafire.com/folder/vunf8jgs0qw2w/KChangeCmdMsg" target="_blank" rel="noopener" class="mycode_url"><span style="font-weight: bold;" class="mycode_b"><span style="font-size: x-large;" class="mycode_size">DOWNLOAD DEMOS</span></span></a></div>
<br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
If you know how to use the engine, that's enough for me! <img src="https://www.save-point.org/images/smilies/ejlol/grin.gif" loading="lazy"  alt="[Image: grin.gif]" class="mycode_img" /><br />
Of course, I wouldn't mind if you include me in your game credits. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" loading="lazy"  alt="[Image: wink.gif]" class="mycode_img" /><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[Command Color VX + ACE]]></title>
			<link>https://www.save-point.org/thread-11591.html</link>
			<pubDate>Mon, 16 Jun 2025 02:29:20 +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-11591.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">Command Color VX + ACE</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 />
Did you ever want to change your command window's currently selected command a little bit? <img src="https://www.save-point.org/images/smilies/ejlol/think.gif" alt="Thinking" title="Thinking" class="smilie smilie_49" /><br />
Now you can do it! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
This scriptlet lets you alter its color! <img src="https://www.save-point.org/images/smilies/ejlol/painter.gif" alt="Painter" title="Painter" class="smilie smilie_223" /><br />
<br />
Just configure the SELECT_COLOR constant accordingly and that's 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 />
<span style="font-weight: bold;" class="mycode_b">VX Script</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * Command Color VX * #<br />
#&nbsp;&nbsp; Scripter : Kyonides<br />
#&nbsp;&nbsp; v0.5.0 - 2025-06-15<br />
<br />
# The SELECT_COLOR Constant lets you configure your custom color following<br />
# the usual (R,G,B) or (R,G,B,A) color format.<br />
<br />
class Window_Command<br />
&nbsp;&nbsp;SELECT_COLOR = Color.new(255, 255, 0)<br />
&nbsp;&nbsp;DISABLED_ALPHA = 100<br />
&nbsp;&nbsp;alias :kyon_cmd_clr_win_comm_init :initialize<br />
&nbsp;&nbsp;alias :kyon_cmd_clr_win_comm_set_index :index=<br />
&nbsp;&nbsp;alias :kyon_cmd_clr_win_comm_draw_item :draw_item<br />
&nbsp;&nbsp;alias :kyon_cmd_clr_win_comm_up :update<br />
&nbsp;&nbsp;def initialize(width, commands)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@disabled = []<br />
&nbsp;&nbsp;&nbsp;&nbsp;@last_pos = -1<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_cmd_clr_win_comm_init(width, commands)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def disable_item(index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@disabled &lt;&lt; index<br />
&nbsp;&nbsp;&nbsp;&nbsp;@disabled = @disabled.sort.uniq<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def draw_item(index, enabled = true)<br />
&nbsp;&nbsp;&nbsp;&nbsp;disable_item(index) unless enabled<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_cmd_clr_win_comm_draw_item(index, enabled)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def draw_item_color(n, current)<br />
&nbsp;&nbsp;&nbsp;&nbsp;rect = item_rect(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;rect.x += 4<br />
&nbsp;&nbsp;&nbsp;&nbsp;rect.width -= 8<br />
&nbsp;&nbsp;&nbsp;&nbsp;b = self.contents<br />
&nbsp;&nbsp;&nbsp;&nbsp;b.clear_rect(rect)<br />
&nbsp;&nbsp;&nbsp;&nbsp;new_color = current ? SELECT_COLOR.dup : normal_color.dup<br />
&nbsp;&nbsp;&nbsp;&nbsp;new_color.alpha = DISABLED_ALPHA if @disabled.include?(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;b.font.color = new_color<br />
&nbsp;&nbsp;&nbsp;&nbsp;b.draw_text(rect, @commands[n])<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def index=(new_index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @index == new_index<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @index &gt;= 0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;draw_item_color(@index, nil)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@last_pos = @index<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_cmd_clr_win_comm_set_index(new_index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_item_color(@index, true)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def update_command<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @last_pos == @index<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_item_color(@last_pos, nil) if @last_pos &gt;= 0<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_item_color(@index, true)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@last_pos = @index<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def update<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_cmd_clr_win_comm_up<br />
&nbsp;&nbsp;&nbsp;&nbsp;update_command<br />
&nbsp;&nbsp;end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">VX ACE Script</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * Command Color ACE * #<br />
#&nbsp;&nbsp; Scripter : Kyonides<br />
#&nbsp;&nbsp; v0.5.1 - 2025-09-10<br />
<br />
# The SELECT_COLOR Constant lets you configure your custom color following<br />
# the usual (R,G,B) or (R,G,B,A) color format.<br />
<br />
class Window_Command<br />
&nbsp;&nbsp;SELECT_COLOR = Color.new(255, 255, 0)<br />
&nbsp;&nbsp;def no_commands?<br />
&nbsp;&nbsp;&nbsp;&nbsp;@list.empty?<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def clear_old_item(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @index == n<br />
&nbsp;&nbsp;&nbsp;&nbsp;clear_item(@index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_item(@index)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def draw_new_item(index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;change_color(SELECT_COLOR, command_enabled?(index))<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_text(item_rect_for_text(index), command_name(index), alignment)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def select(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;if no_commands?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.index = n if n<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;clear_old_item(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.index = n if n<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_new_item(@index) if @index == n<br />
&nbsp;&nbsp;end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Use</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer.<br />
Crediting me as the author is optional. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><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">Command Color VX + ACE</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 />
Did you ever want to change your command window's currently selected command a little bit? <img src="https://www.save-point.org/images/smilies/ejlol/think.gif" alt="Thinking" title="Thinking" class="smilie smilie_49" /><br />
Now you can do it! <img src="https://www.save-point.org/images/smilies/ejlol/shocked.gif" alt="Shocked" title="Shocked" class="smilie smilie_22" /><br />
This scriptlet lets you alter its color! <img src="https://www.save-point.org/images/smilies/ejlol/painter.gif" alt="Painter" title="Painter" class="smilie smilie_223" /><br />
<br />
Just configure the SELECT_COLOR constant accordingly and that's 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 />
<span style="font-weight: bold;" class="mycode_b">VX Script</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * Command Color VX * #<br />
#&nbsp;&nbsp; Scripter : Kyonides<br />
#&nbsp;&nbsp; v0.5.0 - 2025-06-15<br />
<br />
# The SELECT_COLOR Constant lets you configure your custom color following<br />
# the usual (R,G,B) or (R,G,B,A) color format.<br />
<br />
class Window_Command<br />
&nbsp;&nbsp;SELECT_COLOR = Color.new(255, 255, 0)<br />
&nbsp;&nbsp;DISABLED_ALPHA = 100<br />
&nbsp;&nbsp;alias :kyon_cmd_clr_win_comm_init :initialize<br />
&nbsp;&nbsp;alias :kyon_cmd_clr_win_comm_set_index :index=<br />
&nbsp;&nbsp;alias :kyon_cmd_clr_win_comm_draw_item :draw_item<br />
&nbsp;&nbsp;alias :kyon_cmd_clr_win_comm_up :update<br />
&nbsp;&nbsp;def initialize(width, commands)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@disabled = []<br />
&nbsp;&nbsp;&nbsp;&nbsp;@last_pos = -1<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_cmd_clr_win_comm_init(width, commands)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def disable_item(index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@disabled &lt;&lt; index<br />
&nbsp;&nbsp;&nbsp;&nbsp;@disabled = @disabled.sort.uniq<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def draw_item(index, enabled = true)<br />
&nbsp;&nbsp;&nbsp;&nbsp;disable_item(index) unless enabled<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_cmd_clr_win_comm_draw_item(index, enabled)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def draw_item_color(n, current)<br />
&nbsp;&nbsp;&nbsp;&nbsp;rect = item_rect(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;rect.x += 4<br />
&nbsp;&nbsp;&nbsp;&nbsp;rect.width -= 8<br />
&nbsp;&nbsp;&nbsp;&nbsp;b = self.contents<br />
&nbsp;&nbsp;&nbsp;&nbsp;b.clear_rect(rect)<br />
&nbsp;&nbsp;&nbsp;&nbsp;new_color = current ? SELECT_COLOR.dup : normal_color.dup<br />
&nbsp;&nbsp;&nbsp;&nbsp;new_color.alpha = DISABLED_ALPHA if @disabled.include?(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;b.font.color = new_color<br />
&nbsp;&nbsp;&nbsp;&nbsp;b.draw_text(rect, @commands[n])<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def index=(new_index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @index == new_index<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @index &gt;= 0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;draw_item_color(@index, nil)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@last_pos = @index<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_cmd_clr_win_comm_set_index(new_index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_item_color(@index, true)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def update_command<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @last_pos == @index<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_item_color(@last_pos, nil) if @last_pos &gt;= 0<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_item_color(@index, true)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@last_pos = @index<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def update<br />
&nbsp;&nbsp;&nbsp;&nbsp;kyon_cmd_clr_win_comm_up<br />
&nbsp;&nbsp;&nbsp;&nbsp;update_command<br />
&nbsp;&nbsp;end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">VX ACE Script</span><br />
<div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code># * Command Color ACE * #<br />
#&nbsp;&nbsp; Scripter : Kyonides<br />
#&nbsp;&nbsp; v0.5.1 - 2025-09-10<br />
<br />
# The SELECT_COLOR Constant lets you configure your custom color following<br />
# the usual (R,G,B) or (R,G,B,A) color format.<br />
<br />
class Window_Command<br />
&nbsp;&nbsp;SELECT_COLOR = Color.new(255, 255, 0)<br />
&nbsp;&nbsp;def no_commands?<br />
&nbsp;&nbsp;&nbsp;&nbsp;@list.empty?<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def clear_old_item(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @index == n<br />
&nbsp;&nbsp;&nbsp;&nbsp;clear_item(@index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_item(@index)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def draw_new_item(index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;change_color(SELECT_COLOR, command_enabled?(index))<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_text(item_rect_for_text(index), command_name(index), alignment)<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;def select(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;if no_commands?<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.index = n if n<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;clear_old_item(n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.index = n if n<br />
&nbsp;&nbsp;&nbsp;&nbsp;draw_new_item(@index) if @index == n<br />
&nbsp;&nbsp;end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Use</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer.<br />
Crediting me as the author is optional. <img src="https://www.save-point.org/images/smilies/ejlol/wink.gif" alt="Winking" title="Winking" class="smilie smilie_33" /><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[Animated Message Profiles VX]]></title>
			<link>https://www.save-point.org/thread-11587.html</link>
			<pubDate>Mon, 09 Jun 2025 20:16:16 +0000</pubDate>
			<dc:creator><![CDATA[<a href="https://www.save-point.org/member.php?action=profile&uid=5">DerVVulfman</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.save-point.org/thread-11587.html</guid>
			<description><![CDATA[<div align="center"><span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Animated Message Profiles VX</span></span><br />
<span style="font-size: medium;" class="mycode_size">Version: 1.1</span></div>
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Introduction</span></span><br />
<br />
This is an add-on for the default message systems, or for those custom message systems that are compliant.  It permits the game developer to present  an image behind the default message window, and even allow for the image to display cel animation properties.<br />
<br />
Essentially, one can present characters that appear to be talking.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Script</span></span><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='+';}"/> Instructions/Configuration</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;"><div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** Animated Message Profiles VX<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;&nbsp;&nbsp;by DerVVulfman<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Version 1.1<br />
#&nbsp;&nbsp;&nbsp;&nbsp;06-14-2025 (MM/DD/YYYY)<br />
#&nbsp;&nbsp;&nbsp;&nbsp;RGSS2 / RPGMaker VX<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt; INSTRUCTION / CONFIGURATION PAGE &lt;<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;INTRODUCTION:<br />
#&nbsp;&nbsp;=============<br />
#<br />
#&nbsp;&nbsp;This is an add-on for the default message systems, or for those custom mes-<br />
#&nbsp;&nbsp;sage systems that are compliant.&nbsp;&nbsp;It permits the game developer&nbsp;&nbsp;to present&nbsp;&nbsp;<br />
#&nbsp;&nbsp;an image behind the default message window, and even allow for the image to<br />
#&nbsp;&nbsp;display cel animation properties.<br />
#<br />
#&nbsp;&nbsp;Essentially, one can present characters that appear to be talking.<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;INSTALLATION:<br />
#&nbsp;&nbsp;=============<br />
#<br />
#&nbsp;&nbsp;At bare minimum,&nbsp;&nbsp;place both the Instruction / Configuration and the Engine<br />
#&nbsp;&nbsp;scripts below Scene_Debug and above Main.&nbsp;&nbsp;<br />
#<br />
#&nbsp;&nbsp;The configuration page defines the actual profiles that are displayed,&nbsp;&nbsp;the<br />
#&nbsp;&nbsp;location where they are shown, and if they are indeed animated.<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;CONFIGURATION SETTINGS:<br />
#&nbsp;&nbsp;=======================<br />
#<br />
#&nbsp;&nbsp;The configuration section has two areas to adjust, the first is the setting<br />
#&nbsp;&nbsp;that determines&nbsp;&nbsp;if the profile shows&nbsp;&nbsp;when the message 'begins' to show or <br />
#&nbsp;&nbsp;waits until the message display is complete,&nbsp;&nbsp;and the second is the list of<br />
#&nbsp;&nbsp;profiles themselves.&nbsp;&nbsp;These profiles are the images or renders of the char-<br />
#&nbsp;&nbsp;acters that appear beind the message window, whether animated or not.<br />
#<br />
#&nbsp;&nbsp;Profiles are defined within a hash array.&nbsp;&nbsp;Each of these profiles are iden-<br />
#&nbsp;&nbsp;tified by a key,&nbsp;&nbsp;a string value that can be easily referenced. And each of<br />
#&nbsp;&nbsp;these profiles points to an array indicating where the profiles are placed,<br />
#&nbsp;&nbsp;the speed in which the profiles circulate between animated frames,&nbsp;&nbsp;and the<br />
#&nbsp;&nbsp;list of one (or more) profile animation frames.<br />
#&nbsp;&nbsp;<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Syntax:&nbsp;&nbsp;DATA[key]&nbsp;&nbsp;= [ xpos, ypos, speed, repeat img, img, img... img ]<br />
#&nbsp;&nbsp;&nbsp;&nbsp;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* key:&nbsp;&nbsp;&nbsp;&nbsp;A string (in quotes) that separates it from other profiles.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* xpos:&nbsp;&nbsp; X-Position or Coordinates where the sprite(s) will draw.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* ypos:&nbsp;&nbsp; Y-Position or Coordinates where the sprite(s) will draw.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* speed:&nbsp;&nbsp;(in frames per second) The number of frames between each image.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* repeat: (a true/false value) Indicating if multiple images repeat<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* img:&nbsp;&nbsp;&nbsp;&nbsp;An image file (or set of file) in the Graphics&#92;Pictures folder.<br />
#<br />
#&nbsp;&nbsp;You can show one single image behind the message box with the following<br />
#&nbsp;&nbsp;example:<br />
#&nbsp;&nbsp;DATA["LunarSmile"]&nbsp;&nbsp;=&nbsp;&nbsp; [50,120,4,true'actor1']<br />
#&nbsp;&nbsp;-- or --<br />
#&nbsp;&nbsp;DATA["LunarSmile"]&nbsp;&nbsp;=&nbsp;&nbsp; [50,120,4,true'actor1']<br />
#<br />
#&nbsp;&nbsp;Or, you can render a profile that draws three images in the pictures folder<br />
#&nbsp;&nbsp;in rapid succession like so:<br />
#<br />
#&nbsp;&nbsp;DATA["ZeldaIsLaughing"]&nbsp;&nbsp;= [50,120,4, true 'actor1','actor1a','actor1b']<br />
#&nbsp;&nbsp;-- if the animation continues until closed --<br />
#&nbsp;&nbsp;DATA["ZeldaIsLaughing"]&nbsp;&nbsp;= [50,120,4, false 'actor1','actor1a','actor1b']<br />
#&nbsp;&nbsp;-- if the animation ends after all three images have been shown --<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;MESSAGE WINDOW COMMANDS:<br />
#&nbsp;&nbsp;========================<br />
#<br />
#&nbsp;&nbsp;DISPLAYING THE PROFILE:<br />
#<br />
#&nbsp;&nbsp;You may display a profile by using the Message Code:&nbsp;&nbsp;&#92;AB[key].<br />
#<br />
#&nbsp;&nbsp;While the key must have quotes when defined in the module, the message<br />
#&nbsp;&nbsp;code's key value does not use quotes.<br />
#&nbsp;&nbsp;<br />
#&nbsp;&nbsp;EX:&nbsp;&nbsp;&#92;ab[ZeldaIsLaughing]That is so funny!!!<br />
#<br />
#&nbsp;&nbsp;The above example would display an animated profile with the defined<br />
#&nbsp;&nbsp;profile name of 'ZeldaIsLaughing' with text following immediately.<br />
#<br />
#&nbsp;&nbsp;Alternately, you may use a script call prior to the display of the <br />
#&nbsp;&nbsp;message with the 'set_profile' command like so:<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("ZeldaIsLaughing")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: That is so funny!!!!"<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-<br />
#<br />
#&nbsp;&nbsp;HOLDING A PROFILE PRESENT<br />
#<br />
#&nbsp;&nbsp;Normally, the image vanishes when you close a window. However, there may be<br />
#&nbsp;&nbsp;instances where a character is delivering multiple message windows of text<br />
#&nbsp;&nbsp;and you want the image to remain for the very next message.<br />
#<br />
#&nbsp;&nbsp;For this, you need to apply the 'hold_profile' script call on the message<br />
#&nbsp;&nbsp;the contains the current profile.&nbsp;&nbsp;This is to prevent it from erasing the<br />
#&nbsp;&nbsp;profile before the message ends.&nbsp;&nbsp;This may appear like so:<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("ZeldaIsLaughing")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: hold_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: That is so funny!!!!"<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: I am just laughing uncontrollably!!!!"<br />
#<br />
#&nbsp;&nbsp;This example would use the same profile image for both messages.&nbsp;&nbsp;However,<br />
#&nbsp;&nbsp;the below exaple would have its third message window without the profile.<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("ZeldaIsLaughing")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: hold_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: That is so funny!!!!"<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: I am just laughing uncontrollably!!!!"<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: Okay, I'm done now."<br />
#<br />
#&nbsp;&nbsp;To continue with the image remaining in place, you must use the hold_profile<br />
#&nbsp;&nbsp;command before each message that you want to PREVENT the profile's erasure.<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-<br />
#<br />
#&nbsp;&nbsp;SWAPPING A PROFILE PRESENT<br />
#<br />
#&nbsp;&nbsp;For use in tandem with the above&nbsp;&nbsp;'hold_profile' call,&nbsp;&nbsp;this is a special<br />
#&nbsp;&nbsp;command that lets you switch&nbsp;&nbsp;from one profile set to another without the<br />
#&nbsp;&nbsp;profile sprite erasing.&nbsp;&nbsp;Unlike the hold_profile call, the 'swap_profile'<br />
#&nbsp;&nbsp;is run right before the new message is shown, and used in tandem with the<br />
#&nbsp;&nbsp;application of a new profile like so:<br />
#&nbsp;&nbsp; <br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("ZeldaIsLaughing")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: hold_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: That is so funny!!!!"<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: swap_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: &#92;AB[ZeldaCry]Waaahhh!"<br />
#<br />
#&nbsp;&nbsp;This would provide a more seamless change in character behavior between<br />
#&nbsp;&nbsp;messages without the character needing to vanish and be redrawn.<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;PAPERDOLL/BITMAP COMPATABILITY:<br />
#&nbsp;&nbsp;===============================<br />
#<br />
#&nbsp;&nbsp;paper doll (noun)<br />
#&nbsp;&nbsp; 1. A paper or cardboard representation of a person usually in two dimen-<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sions for children to play with. <br />
#&nbsp;&nbsp; 2. Figures cut out of paper or thin card, with separate clothes, also made<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of paper, that are usually held onto the dolls by paper folding tabs.<br />
#<br />
#&nbsp;&nbsp;Sometimes called a Visual Equipment script,&nbsp;&nbsp;a paperdoll system is one that<br />
#&nbsp;&nbsp;can change a character's appearance based on the gear attached.<br />
#<br />
#&nbsp;&nbsp;While Animated Message Profiles does not have&nbsp;&nbsp;a built-in paperdoll system,<br />
#&nbsp;&nbsp;it contains an area where changes to a profile's appearance may be made. It<br />
#&nbsp;&nbsp;is within the Window_Message class, and is a specifically defined method to<br />
#&nbsp;&nbsp;grant a would-be scripter access to the bitmaps to adjust.<br />
#<br />
#&nbsp;&nbsp;In short, I made a method a scripter can mess with. ^_^&nbsp;&nbsp; <br />
#<br />
#&nbsp;&nbsp;Line # 331:&nbsp;&nbsp;update_profile_reader<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;NOTES ON THE EXAMPLE CONFIG:<br />
#&nbsp;&nbsp;============================<br />
#<br />
#&nbsp;&nbsp;The two profiles are using images found in the 'Graphics&#92;Profiles' folder.<br />
#&nbsp;&nbsp;And in that folder, there are only two files, "Ikuno1.png" &amp; "Ikuno2.png".<br />
#&nbsp;&nbsp;<br />
#&nbsp;&nbsp;You use multiple image files to creat an animation, and at least one file<br />
#&nbsp;&nbsp;to create a portrait if static and not animated.<br />
#<br />
#&nbsp;&nbsp;The first profile is that of "Ikuno".&nbsp;&nbsp;The profile will appear&nbsp;&nbsp;at coordi-<br />
#&nbsp;&nbsp;nates&nbsp;&nbsp;80,140&nbsp;&nbsp;which would line up nice with the default message window if<br />
#&nbsp;&nbsp;it is at the bottom of the screen.&nbsp;&nbsp;The speed is set to 4, which means the<br />
#&nbsp;&nbsp;individual cels change after 4 frames (in framerate).&nbsp;&nbsp;It is set to false,<br />
#&nbsp;&nbsp;this indicates it will only cycle through all the animation cels once. And<br />
#&nbsp;&nbsp;it only has two images:&nbsp;&nbsp;"Ikuno1.png" and "Ikuno2.png". This means that it<br />
#&nbsp;&nbsp;only plays the two images in sequence once... and stops.<br />
#<br />
#&nbsp;&nbsp;The second profile is that of "Ikuno2". The profile will appear&nbsp;&nbsp;at coordi-<br />
#&nbsp;&nbsp;nates&nbsp;&nbsp;80,140&nbsp;&nbsp;the same as the first. The speed is set to 0, however, this<br />
#&nbsp;&nbsp;is an illegal value&nbsp;&nbsp;as the animation speed rate cannot go below '1'.&nbsp;&nbsp;The<br />
#&nbsp;&nbsp;repeat value is set to 'true' so it will play every animation frame in its<br />
#&nbsp;&nbsp;set over and over aggain.&nbsp;&nbsp;And it lists "Ikuno1", "Ikuno2" and "Ikuno1".<br />
#<br />
#&nbsp;&nbsp;The third profile is that of "Ikuno3".&nbsp;&nbsp;And this one is merely a static,<br />
#&nbsp;&nbsp;one frame/image profile.&nbsp;&nbsp;Ergo, it will not appear animated.<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-<br />
#<br />
#&nbsp;&nbsp;Example I used with the three profile settings:<br />
#<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: hold_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: &#92;AB[Ikuno]What? Yeah, my mouth isn't moving.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: swap_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: &#92;AB[Ikuno2]Yap Yap Yap!<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: Peekaboo... you don't see me<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("Ikuno3")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: Now you do.<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;VERSION HISTORY:<br />
#&nbsp;&nbsp;================<br />
#&nbsp;&nbsp;YYYY MM DD<br />
#&nbsp;&nbsp;2025-06-09 - Original release<br />
#&nbsp;&nbsp;2025-06-14 - Fix: Disposed portrait sprite issue and increased z-depth<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;COMPATABILITY:<br />
#&nbsp;&nbsp;==============<br />
#<br />
#&nbsp;&nbsp;Designed for message systems compliant with RPGMaker VX's default system.<br />
#&nbsp;&nbsp;All default scripts aliased.<br />
#<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;TERMS AND CONDITIONS:<br />
#&nbsp;&nbsp;=====================<br />
#<br />
#&nbsp;&nbsp;Free to use,&nbsp;&nbsp;even in commercial projects.&nbsp;&nbsp;However, I will need some form<br />
#&nbsp;&nbsp;of due credit.<br />
#<br />
#<br />
#==============================================================================<br />
<br />
<br />
<br />
module Profiles<br />
<br />
&nbsp;&nbsp;# --------------------------------------------------------------------------<br />
&nbsp;&nbsp;DATA = {} # Do Not Touch<br />
&nbsp;&nbsp;# --------------------------------------------------------------------------<br />
<br />
<br />
&nbsp;&nbsp;# Do profiles show when beginning to render?<br />
&nbsp;&nbsp;# ==========================================<br />
&nbsp;&nbsp;SHOW_ON_OPENING = false<br />
<br />
<br />
&nbsp;&nbsp;# PROFILE LIST<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# Profile w Key&nbsp;&nbsp;&nbsp;&nbsp; X&nbsp;&nbsp;&nbsp;&nbsp; Y&nbsp;&nbsp;&nbsp;&nbsp; Spd&nbsp;&nbsp; Repeat&nbsp;&nbsp;Animation frames...<br />
&nbsp;&nbsp;# ===============&nbsp;&nbsp; ====&nbsp;&nbsp;====&nbsp;&nbsp;====&nbsp;&nbsp;======&nbsp;&nbsp;=============================<br />
&nbsp;&nbsp;DATA["Ikuno"]&nbsp;&nbsp; = [ 80,&nbsp;&nbsp; 140,&nbsp;&nbsp;4,&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;'Ikuno1', 'Ikuno2' ]<br />
&nbsp;&nbsp;DATA["Ikuno2"]&nbsp;&nbsp;= [ 80,&nbsp;&nbsp; 140,&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;true,&nbsp;&nbsp; 'Ikuno1', 'Ikuno2', 'Ikuno1' ]<br />
&nbsp;&nbsp;DATA["Ikuno3"]&nbsp;&nbsp;= [ 80,&nbsp;&nbsp; 140,&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;'Ikuno2' ]<br />
<br />
<br />
end</code></div></div></div>
		</div>
<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='+';}"/> Main Code</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;"><div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** Animated Message Profiles VX<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;&nbsp;&nbsp;by DerVVulfman<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Version 1.1<br />
#&nbsp;&nbsp;&nbsp;&nbsp;06-14-2025 (MM/DD/YYYY)<br />
#&nbsp;&nbsp;&nbsp;&nbsp;RGSS2 / RPGMaker VX<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt; MAIN SYSTEM PAGE &lt;<br />
#<br />
#==============================================================================<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** Cache<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This module loads each of graphics, creates a Bitmap object, and retains it.<br />
# To speed up load times and conserve memory, this module holds the created<br />
# Bitmap object in the internal hash, allowing the program to return<br />
# preexisting objects when the same bitmap is requested again.<br />
#==============================================================================<br />
<br />
module Cache<br />
<br />
&nbsp;&nbsp;#------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Profile image<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp; filename : filename of the cached bitmap<br />
&nbsp;&nbsp;#------------------------------------------------------------------------<br />
&nbsp;&nbsp;def self.profiles(filename)<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;begin<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.load_bitmap("Graphics/Profiles/", filename)<br />
&nbsp;&nbsp;&nbsp;&nbsp;rescue <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.load_bitmap("Graphics/Profiles/", "")<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** Game_System<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This class handles system-related data. Also manages vehicles and BGM, etc.<br />
# The instance of this class is referenced by &#36;game_system.<br />
#==============================================================================<br />
<br />
class Game_System<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Public Instance Variables<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;attr_accessor :profile_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Name of profile image data<br />
&nbsp;&nbsp;attr_accessor :profile_hold&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Profile do not erase flag<br />
&nbsp;&nbsp;attr_accessor :profile_swap <br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Alias Listings<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;alias msg_profiles_game_system_initialize initialize<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Object Initialization<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_game_system_initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = nil<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile_hold&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = false<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile_swap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = false<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** Game_Interpreter<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;An interpreter for executing event commands. This class is used within the<br />
# Game_Map, Game_Troop, and Game_Event classes.<br />
#==============================================================================<br />
<br />
class Game_Interpreter<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Set Message Profile outside of Show Text box<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp; key : key as defined in the Profiles Module<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def set_profile(key=nil)<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if key.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If no valid key supplied<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..set erased profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..and exit method.<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless Profiles::DATA.has_key?(key)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If no valid profile given<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..set erased profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..and exit method.<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = key&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set the profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Set image hold/freeze to use in next message<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def hold_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_hold = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set the profile hold flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Set sprite frozent to allow profile image and animation swapping<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def swap_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_swap = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set the profile swap flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** Window_Message<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This message window is used to display text.<br />
#==============================================================================<br />
<br />
class Window_Message &lt; Window_Selectable<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Alias Listings<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;alias msg_profiles_windows_initialize initialize<br />
&nbsp;&nbsp;alias msg_profiles_windows_dispose dispose<br />
&nbsp;&nbsp;alias msg_profiles_windows_update update<br />
&nbsp;&nbsp;alias msg_profiles_windows_csc convert_special_characters<br />
&nbsp;&nbsp;alias msg_profiles_windows_terminate_message terminate_message<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Original methods Aliased<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Object Initialization<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_initialize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;initialize_message_profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create profile data<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Dispose<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def dispose<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.dispose&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Dispose of profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_dispose&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Frame Update<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;deny_flag = @closing&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set deny flag on closing <br />
&nbsp;&nbsp;&nbsp;&nbsp;unless Profiles::SHOW_ON_OPENING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If opening is denied<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deny_flag = true if @opening&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ...set flag if also opening<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless deny_flag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Unless denied from showing&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update_message_profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Perform update if showing<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_update&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Convert Special Characters<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def convert_special_characters<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;convert_special_characters_profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Perform profile refresh<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_csc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Terminate Message<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def terminate_message<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_terminate_message&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;terminate_message_profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Terminate profile data<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * New Content<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Object Initialization : Creation of clear profile data variables<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def initialize_message_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Sprite.new&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create the profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= self.z - 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set it behind the message<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgprofile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = []&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create empty filename array<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgwait_count&nbsp;&nbsp;&nbsp;&nbsp;= 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Reset the wait count<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profilerepeat&nbsp;&nbsp;&nbsp;&nbsp;= true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Reset repeat function<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Frame Update:&nbsp;&nbsp;Profile display and animation<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update_message_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless &#36;game_system.profile_swap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Unless swapping profiles<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return if @profilerepeat == false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Exit method on no repeat<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @msgwait_count &gt; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If a wait count exists<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@msgwait_count -= 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..reduce the wait count<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..and exit the method <br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;update_profile_generator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Run the profile generator<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @bitmap.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if not valid bitmap <br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @profile.bitmap.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no profile bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @pattern.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Exit if no defined pattern<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @sprite_numbers.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no sprite number set<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @msgprofile.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no configed profile <br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@pattern = (@pattern + 1) % @sprite_numbers&nbsp;&nbsp; # Set animation pattern<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @pattern == (@sprite_numbers-1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# If at end of loop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@profilerepeat = @msg_repeat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# .. determine if repeating<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;sx = @pattern * @cw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Define which image to use<br />
&nbsp;&nbsp;&nbsp;&nbsp;src_rect = Rect.new(sx, 0, @cw, @ch)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Acquire the sprite image<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap.clear&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Clear the sprite bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap.blt(0, 0, @bitmap, src_rect)&nbsp;&nbsp;# Apply the new bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgwait_count&nbsp;&nbsp;= @msg_count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Reset the wait count <br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.visible = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Show the provile sprite <br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Update:&nbsp;&nbsp;Generate the Profile Animation Strip<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update_profile_generator<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if &#36;game_system.profile_name.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Exit if no profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if &#36;game_system.profile_name == ""&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if profile name empty<br />
&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;&nbsp; = &#36;game_system.profile_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get the profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return unless update_profile_empty?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if exist or is to swap<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if Profiles::DATA.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no configured data<br />
&nbsp;&nbsp;&nbsp;&nbsp;return unless Profiles::DATA.has_key?(name)&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no profile configed<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if &#36;game_system.profile_swap == true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If profiles are swapped<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@profilerepeat = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Ensure repeat at restart<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless &#36;game_system.profile_swap == true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# If profiles are not swapped<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Sprite.new&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..make a new profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgprofile&nbsp;&nbsp;&nbsp;&nbsp; = Profiles::DATA[name]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Acquire configured profile <br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= self.z - 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set profile behind message<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= @msgprofile[0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set x-coordinate of profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= @msgprofile[1]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set y-coordinate of profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msg_count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= @msgprofile[2]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set Message wait count<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msg_repeat&nbsp;&nbsp;&nbsp;&nbsp; = @msgprofile[3]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set Message repeat flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;files&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = @msgprofile[4]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set first file in list<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msg_count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 if @msg_count &lt; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set wait count minimum<br />
&nbsp;&nbsp;&nbsp;&nbsp;@pattern&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Reset profile pattern<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@sprite_numbers = @msgprofile.size-4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Get size of configed profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;bitmap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Cache.profiles(files)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set first bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@cw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = bitmap.width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Get profile strip width<br />
&nbsp;&nbsp;&nbsp;&nbsp;@ch&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = bitmap.height&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get character height<br />
&nbsp;&nbsp;&nbsp;&nbsp;width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = @cw * @sprite_numbers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get single-image width<br />
&nbsp;&nbsp;&nbsp;&nbsp;@bitmap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = Bitmap.new(width, @ch)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create simgle-image bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;for i in 0...@sprite_numbers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Cycle through sprites<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src = update_profile_reader(@msgprofile,i)&nbsp;&nbsp;# Acquire individual sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src_rect&nbsp;&nbsp;&nbsp;&nbsp;= Rect.new(0, 0, @cw, @ch)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Acquire sprite rectangle<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@bitmap.blt(@cw*i, 0, src, src_rect)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Blit sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap&nbsp;&nbsp;= Bitmap.new(@cw, @ch)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Create clean profile bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.visible = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Make visible<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_swap = false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # And clear swap flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Update:&nbsp;&nbsp;Testing if there is no image, or if image is to be replaced.<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update_profile_empty?<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if &#36;game_system.profile_swap == true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# If swapping profiles set<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..Exit method true<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @profile.bitmap.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If there is no bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..Exit method true<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;return false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit method false<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Update:&nbsp;&nbsp;Acquire each Profile from the Animation Strip<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp; name&nbsp;&nbsp;: used to identify the profile for possible editing<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp; index : index within the animation strip<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update_profile_reader(name, index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Acquire the cached bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;src_bitmap&nbsp;&nbsp;= Cache.profiles(@msgprofile[index+4])<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Possible edits to the bitmap may go here... before the returned bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;return src_bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Convert Special Characters : Setting profile data name and message<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def convert_special_characters_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@text.gsub!(/&#92;&#92;[Aa][Bb]&#92;[(.*?)&#92;]/) do&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Substitute the &#92;ab code<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = &#36;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..and set the profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;""<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Terminate Message : Resetting of profile<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def terminate_message_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;terminate_message_profile_erase&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Clear profile image<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_hold = false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Clear profile hold flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Terminate Message : Erasing of profile image and data<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def terminate_message_profile_erase<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if &#36;game_system.profile_hold&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Clear profile hold<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @profile.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Exit if no profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @profile.disposed?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.visible = false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Make profile sprite hidden<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless @profile.bitmap.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Only if there is a bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap.dispose&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..dispose of the bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap = nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Nil out the profile bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgprofile = []&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Clear the filename array<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Erase the profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profilerepeat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= true<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
end</code></div></div></div>
		</div>
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Instructions</span></span><br />
<br />
Within the main header page / configuration page<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Compatibility</span></span><br />
<br />
Designed to work with the default message system, but should be compliant with most that are structurally similar.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Terms and Conditions</span></span><br />
<br />
Free to use,  even in commercial projects.  However, I will need some form of due credit.]]></description>
			<content:encoded><![CDATA[<div align="center"><span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Animated Message Profiles VX</span></span><br />
<span style="font-size: medium;" class="mycode_size">Version: 1.1</span></div>
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Introduction</span></span><br />
<br />
This is an add-on for the default message systems, or for those custom message systems that are compliant.  It permits the game developer to present  an image behind the default message window, and even allow for the image to display cel animation properties.<br />
<br />
Essentially, one can present characters that appear to be talking.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Script</span></span><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='+';}"/> Instructions/Configuration</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;"><div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** Animated Message Profiles VX<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;&nbsp;&nbsp;by DerVVulfman<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Version 1.1<br />
#&nbsp;&nbsp;&nbsp;&nbsp;06-14-2025 (MM/DD/YYYY)<br />
#&nbsp;&nbsp;&nbsp;&nbsp;RGSS2 / RPGMaker VX<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt; INSTRUCTION / CONFIGURATION PAGE &lt;<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;INTRODUCTION:<br />
#&nbsp;&nbsp;=============<br />
#<br />
#&nbsp;&nbsp;This is an add-on for the default message systems, or for those custom mes-<br />
#&nbsp;&nbsp;sage systems that are compliant.&nbsp;&nbsp;It permits the game developer&nbsp;&nbsp;to present&nbsp;&nbsp;<br />
#&nbsp;&nbsp;an image behind the default message window, and even allow for the image to<br />
#&nbsp;&nbsp;display cel animation properties.<br />
#<br />
#&nbsp;&nbsp;Essentially, one can present characters that appear to be talking.<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;INSTALLATION:<br />
#&nbsp;&nbsp;=============<br />
#<br />
#&nbsp;&nbsp;At bare minimum,&nbsp;&nbsp;place both the Instruction / Configuration and the Engine<br />
#&nbsp;&nbsp;scripts below Scene_Debug and above Main.&nbsp;&nbsp;<br />
#<br />
#&nbsp;&nbsp;The configuration page defines the actual profiles that are displayed,&nbsp;&nbsp;the<br />
#&nbsp;&nbsp;location where they are shown, and if they are indeed animated.<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;CONFIGURATION SETTINGS:<br />
#&nbsp;&nbsp;=======================<br />
#<br />
#&nbsp;&nbsp;The configuration section has two areas to adjust, the first is the setting<br />
#&nbsp;&nbsp;that determines&nbsp;&nbsp;if the profile shows&nbsp;&nbsp;when the message 'begins' to show or <br />
#&nbsp;&nbsp;waits until the message display is complete,&nbsp;&nbsp;and the second is the list of<br />
#&nbsp;&nbsp;profiles themselves.&nbsp;&nbsp;These profiles are the images or renders of the char-<br />
#&nbsp;&nbsp;acters that appear beind the message window, whether animated or not.<br />
#<br />
#&nbsp;&nbsp;Profiles are defined within a hash array.&nbsp;&nbsp;Each of these profiles are iden-<br />
#&nbsp;&nbsp;tified by a key,&nbsp;&nbsp;a string value that can be easily referenced. And each of<br />
#&nbsp;&nbsp;these profiles points to an array indicating where the profiles are placed,<br />
#&nbsp;&nbsp;the speed in which the profiles circulate between animated frames,&nbsp;&nbsp;and the<br />
#&nbsp;&nbsp;list of one (or more) profile animation frames.<br />
#&nbsp;&nbsp;<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Syntax:&nbsp;&nbsp;DATA[key]&nbsp;&nbsp;= [ xpos, ypos, speed, repeat img, img, img... img ]<br />
#&nbsp;&nbsp;&nbsp;&nbsp;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* key:&nbsp;&nbsp;&nbsp;&nbsp;A string (in quotes) that separates it from other profiles.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* xpos:&nbsp;&nbsp; X-Position or Coordinates where the sprite(s) will draw.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* ypos:&nbsp;&nbsp; Y-Position or Coordinates where the sprite(s) will draw.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* speed:&nbsp;&nbsp;(in frames per second) The number of frames between each image.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* repeat: (a true/false value) Indicating if multiple images repeat<br />
#&nbsp;&nbsp;&nbsp;&nbsp;* img:&nbsp;&nbsp;&nbsp;&nbsp;An image file (or set of file) in the Graphics&#92;Pictures folder.<br />
#<br />
#&nbsp;&nbsp;You can show one single image behind the message box with the following<br />
#&nbsp;&nbsp;example:<br />
#&nbsp;&nbsp;DATA["LunarSmile"]&nbsp;&nbsp;=&nbsp;&nbsp; [50,120,4,true'actor1']<br />
#&nbsp;&nbsp;-- or --<br />
#&nbsp;&nbsp;DATA["LunarSmile"]&nbsp;&nbsp;=&nbsp;&nbsp; [50,120,4,true'actor1']<br />
#<br />
#&nbsp;&nbsp;Or, you can render a profile that draws three images in the pictures folder<br />
#&nbsp;&nbsp;in rapid succession like so:<br />
#<br />
#&nbsp;&nbsp;DATA["ZeldaIsLaughing"]&nbsp;&nbsp;= [50,120,4, true 'actor1','actor1a','actor1b']<br />
#&nbsp;&nbsp;-- if the animation continues until closed --<br />
#&nbsp;&nbsp;DATA["ZeldaIsLaughing"]&nbsp;&nbsp;= [50,120,4, false 'actor1','actor1a','actor1b']<br />
#&nbsp;&nbsp;-- if the animation ends after all three images have been shown --<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;MESSAGE WINDOW COMMANDS:<br />
#&nbsp;&nbsp;========================<br />
#<br />
#&nbsp;&nbsp;DISPLAYING THE PROFILE:<br />
#<br />
#&nbsp;&nbsp;You may display a profile by using the Message Code:&nbsp;&nbsp;&#92;AB[key].<br />
#<br />
#&nbsp;&nbsp;While the key must have quotes when defined in the module, the message<br />
#&nbsp;&nbsp;code's key value does not use quotes.<br />
#&nbsp;&nbsp;<br />
#&nbsp;&nbsp;EX:&nbsp;&nbsp;&#92;ab[ZeldaIsLaughing]That is so funny!!!<br />
#<br />
#&nbsp;&nbsp;The above example would display an animated profile with the defined<br />
#&nbsp;&nbsp;profile name of 'ZeldaIsLaughing' with text following immediately.<br />
#<br />
#&nbsp;&nbsp;Alternately, you may use a script call prior to the display of the <br />
#&nbsp;&nbsp;message with the 'set_profile' command like so:<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("ZeldaIsLaughing")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: That is so funny!!!!"<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-<br />
#<br />
#&nbsp;&nbsp;HOLDING A PROFILE PRESENT<br />
#<br />
#&nbsp;&nbsp;Normally, the image vanishes when you close a window. However, there may be<br />
#&nbsp;&nbsp;instances where a character is delivering multiple message windows of text<br />
#&nbsp;&nbsp;and you want the image to remain for the very next message.<br />
#<br />
#&nbsp;&nbsp;For this, you need to apply the 'hold_profile' script call on the message<br />
#&nbsp;&nbsp;the contains the current profile.&nbsp;&nbsp;This is to prevent it from erasing the<br />
#&nbsp;&nbsp;profile before the message ends.&nbsp;&nbsp;This may appear like so:<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("ZeldaIsLaughing")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: hold_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: That is so funny!!!!"<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: I am just laughing uncontrollably!!!!"<br />
#<br />
#&nbsp;&nbsp;This example would use the same profile image for both messages.&nbsp;&nbsp;However,<br />
#&nbsp;&nbsp;the below exaple would have its third message window without the profile.<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("ZeldaIsLaughing")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: hold_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: That is so funny!!!!"<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: I am just laughing uncontrollably!!!!"<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: Okay, I'm done now."<br />
#<br />
#&nbsp;&nbsp;To continue with the image remaining in place, you must use the hold_profile<br />
#&nbsp;&nbsp;command before each message that you want to PREVENT the profile's erasure.<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-<br />
#<br />
#&nbsp;&nbsp;SWAPPING A PROFILE PRESENT<br />
#<br />
#&nbsp;&nbsp;For use in tandem with the above&nbsp;&nbsp;'hold_profile' call,&nbsp;&nbsp;this is a special<br />
#&nbsp;&nbsp;command that lets you switch&nbsp;&nbsp;from one profile set to another without the<br />
#&nbsp;&nbsp;profile sprite erasing.&nbsp;&nbsp;Unlike the hold_profile call, the 'swap_profile'<br />
#&nbsp;&nbsp;is run right before the new message is shown, and used in tandem with the<br />
#&nbsp;&nbsp;application of a new profile like so:<br />
#&nbsp;&nbsp; <br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("ZeldaIsLaughing")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: hold_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: That is so funny!!!!"<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: swap_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: &#92;AB[ZeldaCry]Waaahhh!"<br />
#<br />
#&nbsp;&nbsp;This would provide a more seamless change in character behavior between<br />
#&nbsp;&nbsp;messages without the character needing to vanish and be redrawn.<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;PAPERDOLL/BITMAP COMPATABILITY:<br />
#&nbsp;&nbsp;===============================<br />
#<br />
#&nbsp;&nbsp;paper doll (noun)<br />
#&nbsp;&nbsp; 1. A paper or cardboard representation of a person usually in two dimen-<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sions for children to play with. <br />
#&nbsp;&nbsp; 2. Figures cut out of paper or thin card, with separate clothes, also made<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of paper, that are usually held onto the dolls by paper folding tabs.<br />
#<br />
#&nbsp;&nbsp;Sometimes called a Visual Equipment script,&nbsp;&nbsp;a paperdoll system is one that<br />
#&nbsp;&nbsp;can change a character's appearance based on the gear attached.<br />
#<br />
#&nbsp;&nbsp;While Animated Message Profiles does not have&nbsp;&nbsp;a built-in paperdoll system,<br />
#&nbsp;&nbsp;it contains an area where changes to a profile's appearance may be made. It<br />
#&nbsp;&nbsp;is within the Window_Message class, and is a specifically defined method to<br />
#&nbsp;&nbsp;grant a would-be scripter access to the bitmaps to adjust.<br />
#<br />
#&nbsp;&nbsp;In short, I made a method a scripter can mess with. ^_^&nbsp;&nbsp; <br />
#<br />
#&nbsp;&nbsp;Line # 331:&nbsp;&nbsp;update_profile_reader<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;NOTES ON THE EXAMPLE CONFIG:<br />
#&nbsp;&nbsp;============================<br />
#<br />
#&nbsp;&nbsp;The two profiles are using images found in the 'Graphics&#92;Profiles' folder.<br />
#&nbsp;&nbsp;And in that folder, there are only two files, "Ikuno1.png" &amp; "Ikuno2.png".<br />
#&nbsp;&nbsp;<br />
#&nbsp;&nbsp;You use multiple image files to creat an animation, and at least one file<br />
#&nbsp;&nbsp;to create a portrait if static and not animated.<br />
#<br />
#&nbsp;&nbsp;The first profile is that of "Ikuno".&nbsp;&nbsp;The profile will appear&nbsp;&nbsp;at coordi-<br />
#&nbsp;&nbsp;nates&nbsp;&nbsp;80,140&nbsp;&nbsp;which would line up nice with the default message window if<br />
#&nbsp;&nbsp;it is at the bottom of the screen.&nbsp;&nbsp;The speed is set to 4, which means the<br />
#&nbsp;&nbsp;individual cels change after 4 frames (in framerate).&nbsp;&nbsp;It is set to false,<br />
#&nbsp;&nbsp;this indicates it will only cycle through all the animation cels once. And<br />
#&nbsp;&nbsp;it only has two images:&nbsp;&nbsp;"Ikuno1.png" and "Ikuno2.png". This means that it<br />
#&nbsp;&nbsp;only plays the two images in sequence once... and stops.<br />
#<br />
#&nbsp;&nbsp;The second profile is that of "Ikuno2". The profile will appear&nbsp;&nbsp;at coordi-<br />
#&nbsp;&nbsp;nates&nbsp;&nbsp;80,140&nbsp;&nbsp;the same as the first. The speed is set to 0, however, this<br />
#&nbsp;&nbsp;is an illegal value&nbsp;&nbsp;as the animation speed rate cannot go below '1'.&nbsp;&nbsp;The<br />
#&nbsp;&nbsp;repeat value is set to 'true' so it will play every animation frame in its<br />
#&nbsp;&nbsp;set over and over aggain.&nbsp;&nbsp;And it lists "Ikuno1", "Ikuno2" and "Ikuno1".<br />
#<br />
#&nbsp;&nbsp;The third profile is that of "Ikuno3".&nbsp;&nbsp;And this one is merely a static,<br />
#&nbsp;&nbsp;one frame/image profile.&nbsp;&nbsp;Ergo, it will not appear animated.<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;-<br />
#<br />
#&nbsp;&nbsp;Example I used with the three profile settings:<br />
#<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: hold_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: &#92;AB[Ikuno]What? Yeah, my mouth isn't moving.<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: swap_profile<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: &#92;AB[Ikuno2]Yap Yap Yap!<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: Peekaboo... you don't see me<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Script: set_profile("Ikuno3")<br />
#&nbsp;&nbsp;&nbsp;&nbsp;@&gt;Text: Now you do.<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;VERSION HISTORY:<br />
#&nbsp;&nbsp;================<br />
#&nbsp;&nbsp;YYYY MM DD<br />
#&nbsp;&nbsp;2025-06-09 - Original release<br />
#&nbsp;&nbsp;2025-06-14 - Fix: Disposed portrait sprite issue and increased z-depth<br />
#<br />
#<br />
#------------------------------------------------------------------------------<br />
#<br />
#&nbsp;&nbsp;COMPATABILITY:<br />
#&nbsp;&nbsp;==============<br />
#<br />
#&nbsp;&nbsp;Designed for message systems compliant with RPGMaker VX's default system.<br />
#&nbsp;&nbsp;All default scripts aliased.<br />
#<br />
#<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;TERMS AND CONDITIONS:<br />
#&nbsp;&nbsp;=====================<br />
#<br />
#&nbsp;&nbsp;Free to use,&nbsp;&nbsp;even in commercial projects.&nbsp;&nbsp;However, I will need some form<br />
#&nbsp;&nbsp;of due credit.<br />
#<br />
#<br />
#==============================================================================<br />
<br />
<br />
<br />
module Profiles<br />
<br />
&nbsp;&nbsp;# --------------------------------------------------------------------------<br />
&nbsp;&nbsp;DATA = {} # Do Not Touch<br />
&nbsp;&nbsp;# --------------------------------------------------------------------------<br />
<br />
<br />
&nbsp;&nbsp;# Do profiles show when beginning to render?<br />
&nbsp;&nbsp;# ==========================================<br />
&nbsp;&nbsp;SHOW_ON_OPENING = false<br />
<br />
<br />
&nbsp;&nbsp;# PROFILE LIST<br />
&nbsp;&nbsp;#<br />
&nbsp;&nbsp;# Profile w Key&nbsp;&nbsp;&nbsp;&nbsp; X&nbsp;&nbsp;&nbsp;&nbsp; Y&nbsp;&nbsp;&nbsp;&nbsp; Spd&nbsp;&nbsp; Repeat&nbsp;&nbsp;Animation frames...<br />
&nbsp;&nbsp;# ===============&nbsp;&nbsp; ====&nbsp;&nbsp;====&nbsp;&nbsp;====&nbsp;&nbsp;======&nbsp;&nbsp;=============================<br />
&nbsp;&nbsp;DATA["Ikuno"]&nbsp;&nbsp; = [ 80,&nbsp;&nbsp; 140,&nbsp;&nbsp;4,&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;'Ikuno1', 'Ikuno2' ]<br />
&nbsp;&nbsp;DATA["Ikuno2"]&nbsp;&nbsp;= [ 80,&nbsp;&nbsp; 140,&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;true,&nbsp;&nbsp; 'Ikuno1', 'Ikuno2', 'Ikuno1' ]<br />
&nbsp;&nbsp;DATA["Ikuno3"]&nbsp;&nbsp;= [ 80,&nbsp;&nbsp; 140,&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;false,&nbsp;&nbsp;'Ikuno2' ]<br />
<br />
<br />
end</code></div></div></div>
		</div>
<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='+';}"/> Main Code</div>
  			<div class="trow2" style="display:none; padding:4px; margin:1px;"><div class="codeblock"><div class="title">Code:</div><div class="body" dir="ltr"><code>#==============================================================================<br />
# ** Animated Message Profiles VX<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;&nbsp;&nbsp;by DerVVulfman<br />
#&nbsp;&nbsp;&nbsp;&nbsp;Version 1.1<br />
#&nbsp;&nbsp;&nbsp;&nbsp;06-14-2025 (MM/DD/YYYY)<br />
#&nbsp;&nbsp;&nbsp;&nbsp;RGSS2 / RPGMaker VX<br />
#==============================================================================<br />
#<br />
#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt; MAIN SYSTEM PAGE &lt;<br />
#<br />
#==============================================================================<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** Cache<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This module loads each of graphics, creates a Bitmap object, and retains it.<br />
# To speed up load times and conserve memory, this module holds the created<br />
# Bitmap object in the internal hash, allowing the program to return<br />
# preexisting objects when the same bitmap is requested again.<br />
#==============================================================================<br />
<br />
module Cache<br />
<br />
&nbsp;&nbsp;#------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Profile image<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp; filename : filename of the cached bitmap<br />
&nbsp;&nbsp;#------------------------------------------------------------------------<br />
&nbsp;&nbsp;def self.profiles(filename)<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;begin<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.load_bitmap("Graphics/Profiles/", filename)<br />
&nbsp;&nbsp;&nbsp;&nbsp;rescue <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.load_bitmap("Graphics/Profiles/", "")<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** Game_System<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This class handles system-related data. Also manages vehicles and BGM, etc.<br />
# The instance of this class is referenced by &#36;game_system.<br />
#==============================================================================<br />
<br />
class Game_System<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Public Instance Variables<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;attr_accessor :profile_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Name of profile image data<br />
&nbsp;&nbsp;attr_accessor :profile_hold&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Profile do not erase flag<br />
&nbsp;&nbsp;attr_accessor :profile_swap <br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Alias Listings<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;alias msg_profiles_game_system_initialize initialize<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Object Initialization<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_game_system_initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = nil<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile_hold&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = false<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile_swap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = false<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** Game_Interpreter<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;An interpreter for executing event commands. This class is used within the<br />
# Game_Map, Game_Troop, and Game_Event classes.<br />
#==============================================================================<br />
<br />
class Game_Interpreter<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Set Message Profile outside of Show Text box<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp; key : key as defined in the Profiles Module<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def set_profile(key=nil)<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if key.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If no valid key supplied<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..set erased profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..and exit method.<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless Profiles::DATA.has_key?(key)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If no valid profile given<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..set erased profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..and exit method.<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = key&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set the profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Set image hold/freeze to use in next message<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def hold_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_hold = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set the profile hold flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Set sprite frozent to allow profile image and animation swapping<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def swap_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_swap = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set the profile swap flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
end<br />
<br />
<br />
<br />
#==============================================================================<br />
# ** Window_Message<br />
#------------------------------------------------------------------------------<br />
#&nbsp;&nbsp;This message window is used to display text.<br />
#==============================================================================<br />
<br />
class Window_Message &lt; Window_Selectable<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Alias Listings<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;alias msg_profiles_windows_initialize initialize<br />
&nbsp;&nbsp;alias msg_profiles_windows_dispose dispose<br />
&nbsp;&nbsp;alias msg_profiles_windows_update update<br />
&nbsp;&nbsp;alias msg_profiles_windows_csc convert_special_characters<br />
&nbsp;&nbsp;alias msg_profiles_windows_terminate_message terminate_message<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Original methods Aliased<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Object Initialization<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def initialize<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_initialize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;initialize_message_profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create profile data<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Dispose<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def dispose<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.dispose&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Dispose of profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_dispose&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Frame Update<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;deny_flag = @closing&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set deny flag on closing <br />
&nbsp;&nbsp;&nbsp;&nbsp;unless Profiles::SHOW_ON_OPENING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If opening is denied<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deny_flag = true if @opening&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ...set flag if also opening<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless deny_flag&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Unless denied from showing&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update_message_profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Perform update if showing<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_update&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Convert Special Characters<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def convert_special_characters<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;convert_special_characters_profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Perform profile refresh<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_csc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Terminate Message<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def terminate_message<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;msg_profiles_windows_terminate_message&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Run the original method<br />
&nbsp;&nbsp;&nbsp;&nbsp;terminate_message_profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Terminate profile data<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * New Content<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Object Initialization : Creation of clear profile data variables<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def initialize_message_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Sprite.new&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create the profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= self.z - 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set it behind the message<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgprofile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = []&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create empty filename array<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgwait_count&nbsp;&nbsp;&nbsp;&nbsp;= 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Reset the wait count<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profilerepeat&nbsp;&nbsp;&nbsp;&nbsp;= true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Reset repeat function<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Frame Update:&nbsp;&nbsp;Profile display and animation<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update_message_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless &#36;game_system.profile_swap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Unless swapping profiles<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return if @profilerepeat == false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Exit method on no repeat<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @msgwait_count &gt; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If a wait count exists<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@msgwait_count -= 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..reduce the wait count<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..and exit the method <br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;update_profile_generator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Run the profile generator<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @bitmap.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if not valid bitmap <br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @profile.bitmap.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no profile bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @pattern.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Exit if no defined pattern<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @sprite_numbers.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no sprite number set<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @msgprofile.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no configed profile <br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@pattern = (@pattern + 1) % @sprite_numbers&nbsp;&nbsp; # Set animation pattern<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @pattern == (@sprite_numbers-1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# If at end of loop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@profilerepeat = @msg_repeat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# .. determine if repeating<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;sx = @pattern * @cw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Define which image to use<br />
&nbsp;&nbsp;&nbsp;&nbsp;src_rect = Rect.new(sx, 0, @cw, @ch)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Acquire the sprite image<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap.clear&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Clear the sprite bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap.blt(0, 0, @bitmap, src_rect)&nbsp;&nbsp;# Apply the new bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgwait_count&nbsp;&nbsp;= @msg_count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Reset the wait count <br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.visible = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Show the provile sprite <br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Update:&nbsp;&nbsp;Generate the Profile Animation Strip<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update_profile_generator<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if &#36;game_system.profile_name.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Exit if no profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if &#36;game_system.profile_name == ""&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if profile name empty<br />
&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;&nbsp; = &#36;game_system.profile_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get the profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return unless update_profile_empty?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if exist or is to swap<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if Profiles::DATA.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no configured data<br />
&nbsp;&nbsp;&nbsp;&nbsp;return unless Profiles::DATA.has_key?(name)&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no profile configed<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if &#36;game_system.profile_swap == true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If profiles are swapped<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@profilerepeat = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Ensure repeat at restart<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless &#36;game_system.profile_swap == true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# If profiles are not swapped<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@profile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Sprite.new&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..make a new profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgprofile&nbsp;&nbsp;&nbsp;&nbsp; = Profiles::DATA[name]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Acquire configured profile <br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= self.z - 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set profile behind message<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= @msgprofile[0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set x-coordinate of profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= @msgprofile[1]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set y-coordinate of profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msg_count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= @msgprofile[2]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set Message wait count<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msg_repeat&nbsp;&nbsp;&nbsp;&nbsp; = @msgprofile[3]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set Message repeat flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;files&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = @msgprofile[4]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Set first file in list<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msg_count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1 if @msg_count &lt; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set wait count minimum<br />
&nbsp;&nbsp;&nbsp;&nbsp;@pattern&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Reset profile pattern<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@sprite_numbers = @msgprofile.size-4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Get size of configed profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;bitmap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= Cache.profiles(files)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Set first bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@cw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = bitmap.width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Get profile strip width<br />
&nbsp;&nbsp;&nbsp;&nbsp;@ch&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = bitmap.height&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get character height<br />
&nbsp;&nbsp;&nbsp;&nbsp;width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = @cw * @sprite_numbers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Get single-image width<br />
&nbsp;&nbsp;&nbsp;&nbsp;@bitmap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = Bitmap.new(width, @ch)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create simgle-image bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;for i in 0...@sprite_numbers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Cycle through sprites<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src = update_profile_reader(@msgprofile,i)&nbsp;&nbsp;# Acquire individual sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src_rect&nbsp;&nbsp;&nbsp;&nbsp;= Rect.new(0, 0, @cw, @ch)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Acquire sprite rectangle<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@bitmap.blt(@cw*i, 0, src, src_rect)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Blit sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap&nbsp;&nbsp;= Bitmap.new(@cw, @ch)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Create clean profile bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.visible = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Make visible<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_swap = false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # And clear swap flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Update:&nbsp;&nbsp;Testing if there is no image, or if image is to be replaced.<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update_profile_empty?<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;if &#36;game_system.profile_swap == true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# If swapping profiles set<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..Exit method true<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;if @profile.bitmap.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # If there is no bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..Exit method true<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;return false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit method false<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Update:&nbsp;&nbsp;Acquire each Profile from the Animation Strip<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp; name&nbsp;&nbsp;: used to identify the profile for possible editing<br />
&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp; index : index within the animation strip<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def update_profile_reader(name, index)<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Acquire the cached bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;src_bitmap&nbsp;&nbsp;= Cache.profiles(@msgprofile[index+4])<br />
&nbsp;&nbsp;&nbsp;&nbsp;# Possible edits to the bitmap may go here... before the returned bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;return src_bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Convert Special Characters : Setting profile data name and message<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def convert_special_characters_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;@text.gsub!(/&#92;&#92;[Aa][Bb]&#92;[(.*?)&#92;]/) do&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Substitute the &#92;ab code<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = &#36;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ..and set the profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;""<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Terminate Message : Resetting of profile<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def terminate_message_profile<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;terminate_message_profile_erase&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Clear profile image<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_hold = false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Clear profile hold flag<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;# * Terminate Message : Erasing of profile image and data<br />
&nbsp;&nbsp;#--------------------------------------------------------------------------<br />
&nbsp;&nbsp;def terminate_message_profile_erase<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if &#36;game_system.profile_hold&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Clear profile hold<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @profile.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Exit if no profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;return if @profile.disposed?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Exit if no profile sprite<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.visible = false&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Make profile sprite hidden<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless @profile.bitmap.nil?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Only if there is a bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap.dispose&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ..dispose of the bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profile.bitmap = nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Nil out the profile bitmap<br />
&nbsp;&nbsp;&nbsp;&nbsp;@msgprofile = []&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Clear the filename array<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#36;game_system.profile_name = nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Erase the profile name<br />
&nbsp;&nbsp;&nbsp;&nbsp;@profilerepeat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= true<br />
&nbsp;&nbsp;&nbsp;&nbsp;#<br />
&nbsp;&nbsp;end<br />
<br />
end</code></div></div></div>
		</div>
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Instructions</span></span><br />
<br />
Within the main header page / configuration page<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Compatibility</span></span><br />
<br />
Designed to work with the default message system, but should be compliant with most that are structurally similar.<br />
<br />
<br />
<br />
<span style="font-size: medium;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Terms and Conditions</span></span><br />
<br />
Free to use,  even in commercial projects.  However, I will need some form of due credit.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[KSingleItemShop ACE]]></title>
			<link>https://www.save-point.org/thread-11564.html</link>
			<pubDate>Mon, 28 Apr 2025 01:58:59 +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-11564.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">KSingleItemShop ACE</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 />
Normally, you would open the store menu and buy n amount of potions or rings, etc.<br />
<img src="https://www.save-point.org/images/smilies/ejlol/think.gif" alt="Thinking" title="Thinking" class="smilie smilie_49" /> What would happen if some items were so unique that you could not ever find more than a single potion or ring there?<br />
This script lets you setup such a custom shop with ease! <img src="https://www.save-point.org/images/smilies/ejlol/grin.gif" alt="Grinning" title="Grinning" class="smilie smilie_25" /><br />
<br />
Setup Steps:<br />
<ul class="mycode_list"><li>Turn on a specific switch.<br />
</li>
<li>Set the shop's ID via a game variable.<br />
</li>
<li>Use a custom backdrop instead of a snapshot of the current map.<br />
</li>
<li>Add items to the list of goods as usual.<br />
</li>
</ul>
The scriptlet will take care of deactivating it after exiting the custom menu.<br />
<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># * KSingleItemShop ACE * #<br />
# &nbsp;&nbsp;Scripter : Kyonides<br />
# &nbsp;&nbsp;v0.6.0 - 2025-04-27<br />
<br />
# Create a special shop that only offers single items on its shelves.<br />
# To keep them separate from normal shops, turn on a specific switch and set<br />
# the shop's ID via a specific variable. The rest is taken care by the script.<br />
# It also allows you to set a backdrop as well instead of the current map.<br />
<br />
module KSingleItem<br />
  SHOP_SWITCH = 10<br />
  SHOP_ID_VAR = 10<br />
  DEFAULT_BACKDROPS = ["Wood2", "Room2"]<br />
<br />
  class Shop<br />
    attr_accessor :goods<br />
  end<br />
end<br />
<br />
class Game_Party<br />
  alias :kyon_single_item_gm_pty_init :initialize<br />
  def initialize<br />
    kyon_single_item_gm_pty_init<br />
    @single_shops = {}<br />
  end<br />
<br />
  def setup_single_shop(shop_id, new_goods)<br />
    shop = @single_shops[shop_id] || KSingleItem::Shop.new<br />
    shop.goods = new_goods<br />
  end<br />
  attr_reader :single_shops<br />
end<br />
<br />
class Game_Interpreter<br />
  def command_302<br />
    return if &#36;game_party.in_battle<br />
    goods = [@params]<br />
    while next_event_code == 605<br />
      @index += 1<br />
      goods.push(@list[@index].parameters)<br />
    end<br />
    if &#36;game_switches[KSingleItem::SHOP_SWITCH]<br />
      SceneManager.call(SingleShopScene)<br />
    else<br />
      SceneManager.call(Scene_Shop)<br />
    end<br />
    SceneManager.scene.prepare(goods, @params[4])<br />
    Fiber.yield<br />
  end<br />
end<br />
<br />
class Window_ShopBuy<br />
  alias :kyon_single_item_win_shopbuy_draw_item :draw_item<br />
  attr_reader :shop_goods<br />
  def initialize(x, y, height, shop_goods, stretch=nil)<br />
    @stretch = stretch<br />
    super(x, y, window_width, height)<br />
    @shop_goods = shop_goods.dup<br />
    @money = 0<br />
    @no_item = RPG::Item.new<br />
    @symbol_color = Color.new(255, 255, 80)<br />
    @symbol = &#36;data_system.currency_unit<br />
    refresh<br />
    select(0)<br />
  end<br />
<br />
  def window_width<br />
    @stretch ? 384 : 304<br />
  end<br />
<br />
  def item<br />
    @data[@index] || @no_item<br />
  end<br />
<br />
  def money=(money)<br />
    @money = money<br />
    refresh<br />
  end<br />
<br />
  def price(item)<br />
    @price[item.id]<br />
  end<br />
<br />
  def enable?(item)<br />
    item &amp;&amp; price(item) &lt;= @money &amp;&amp; !&#36;game_party.item_max?(item)<br />
  end<br />
<br />
  def set_goods(type, gid)<br />
    case type<br />
    when 0<br />
      &#36;data_items[gid]<br />
    when 1<br />
      &#36;data_weapons[gid]<br />
    when 2<br />
      &#36;data_armors[gid]<br />
    end<br />
  end<br />
<br />
  def make_item_list<br />
    @data = []<br />
    @price = {}<br />
    @shop_goods.each do |goods|<br />
      item = set_goods(goods[0], goods[1])<br />
      next unless item<br />
      @data &lt;&lt; item<br />
      @price[item.id] = goods[2] == 0 ? item.price : goods[3]<br />
    end<br />
  end<br />
<br />
  def draw_item_data(item, rx, ry, enabled=true, w=240)<br />
    return unless item<br />
    draw_icon(item.icon_index, 28, ry, enabled)<br />
    change_color(normal_color, enabled)<br />
    draw_text(56, ry, w - 56, 24, item.name)<br />
    draw_text(w, ry, 100, 24, price(item), 2)<br />
    change_color(@symbol_color, enabled)<br />
    draw_text(w + 100, ry, 16, 24, @symbol, 2)<br />
  end<br />
<br />
  def draw_item(n)<br />
    unless @stretch<br />
      kyon_single_item_win_shopbuy_draw_item(n)<br />
    else<br />
      item = @data[n]<br />
      rect = item_rect(n)<br />
      draw_item_data(item, rect.x, rect.y, enable?(item))<br />
    end<br />
  end<br />
<br />
  def delete_item<br />
    @shop_goods.delete(@index)<br />
    item = @data.delete(@index)<br />
    @price.delete(item.id)<br />
    create_contents<br />
    draw_all_items<br />
  end<br />
end<br />
<br />
class SingleShopScene &lt; Scene_Shop<br />
  def find_shop_id<br />
    &#36;game_variables[KSingleItem::SHOP_ID_VAR]<br />
  end<br />
<br />
  def prepare(goods, purchase_only)<br />
    shop_id = find_shop_id<br />
    shop = &#36;game_party.single_shops[shop_id]<br />
    @goods = shop ? shop.goods : goods<br />
    @purchase_only = purchase_only<br />
  end<br />
<br />
  def start<br />
    create_main_viewport<br />
    create_background<br />
    @actor = &#36;game_party.menu_actor<br />
    create_help_window<br />
    create_gold_window<br />
    create_command_window<br />
    create_buy_window<br />
    create_status_window<br />
    create_category_window<br />
    create_sell_window<br />
  end<br />
<br />
  def create_background<br />
    drop1, drop2 = KSingleItem::DEFAULT_BACKDROPS<br />
    @backdrops = [Sprite.new, Sprite.new]<br />
    @backdrops[0].bitmap = Cache.battleback1(drop1)<br />
    @backdrops[1].bitmap = Cache.battleback2(drop2)<br />
  end<br />
<br />
  def create_buy_window<br />
    @buy_window = Window_ShopBuy.new(0, 252, 24 * 7, @goods, true)<br />
    @buy_window.viewport = @viewport<br />
    @buy_window.help_window = @help_window<br />
    @buy_window.hide<br />
    @buy_window.set_handler(:ok,   &nbsp;&nbsp;method(:on_buy_ok))<br />
    @buy_window.set_handler(:cancel, method(:on_buy_cancel))<br />
  end<br />
<br />
  def create_status_window<br />
    wx = @buy_window.width<br />
    wy = @buy_window.y<br />
    ww = Graphics.width - wx<br />
    @status_window = Window_ShopStatus.new(wx, wy, ww, @buy_window.height)<br />
    @status_window.viewport = @viewport<br />
    @status_window.hide<br />
    @buy_window.status_window = @status_window<br />
  end<br />
<br />
  def create_category_window<br />
    @category_window = Window_ItemCategory.new<br />
    @category_window.viewport = @viewport<br />
    @category_window.help_window = @help_window<br />
    @category_window.hide.deactivate<br />
    @category_window.set_handler(:ok,   &nbsp;&nbsp;method(:on_category_ok))<br />
    @category_window.set_handler(:cancel, method(:on_category_cancel))<br />
  end<br />
<br />
  def command_buy<br />
    activate_buy_window<br />
  end<br />
<br />
  def command_sell<br />
    @category_window.show.activate<br />
    @sell_window.show<br />
    @sell_window.unselect<br />
    @sell_window.refresh<br />
  end<br />
<br />
  def on_buy_ok<br />
    @item = @buy_window.item<br />
    @buy_window.hide<br />
    Sound.play_shop<br />
    do_buy(1)<br />
    @gold_window.refresh<br />
    @status_window.refresh<br />
    @buy_window.delete_item<br />
  end<br />
<br />
  def on_buy_cancel<br />
    @command_window.activate<br />
    @buy_window.hide<br />
    @status_window.hide<br />
    @status_window.item = nil<br />
    @help_window.clear<br />
  end<br />
<br />
  def dispose_background<br />
    @backdrops.each do |sprite|<br />
      sprite.bitmap.dispose<br />
      sprite.dispose<br />
    end<br />
  end<br />
<br />
  def terminate<br />
    super<br />
    reset_single_shop<br />
  end<br />
<br />
  def reset_single_shop<br />
    list = @buy_window.shop_goods<br />
    return list.size == @goods.size<br />
    shop_id = find_shop_id<br />
    return if shop_id == 0<br />
    &#36;game_party.setup_single_shop(shop_id, @buy_window.shop_goods)<br />
    &#36;game_variables[KSingleItem::SHOP_ID_VAR] = 0<br />
    &#36;game_switches[KSingleItem::SHOP_SWITCH] = false<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer.<br />
Mention me in your game credits.<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">KSingleItemShop ACE</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 />
Normally, you would open the store menu and buy n amount of potions or rings, etc.<br />
<img src="https://www.save-point.org/images/smilies/ejlol/think.gif" alt="Thinking" title="Thinking" class="smilie smilie_49" /> What would happen if some items were so unique that you could not ever find more than a single potion or ring there?<br />
This script lets you setup such a custom shop with ease! <img src="https://www.save-point.org/images/smilies/ejlol/grin.gif" alt="Grinning" title="Grinning" class="smilie smilie_25" /><br />
<br />
Setup Steps:<br />
<ul class="mycode_list"><li>Turn on a specific switch.<br />
</li>
<li>Set the shop's ID via a game variable.<br />
</li>
<li>Use a custom backdrop instead of a snapshot of the current map.<br />
</li>
<li>Add items to the list of goods as usual.<br />
</li>
</ul>
The scriptlet will take care of deactivating it after exiting the custom menu.<br />
<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># * KSingleItemShop ACE * #<br />
# &nbsp;&nbsp;Scripter : Kyonides<br />
# &nbsp;&nbsp;v0.6.0 - 2025-04-27<br />
<br />
# Create a special shop that only offers single items on its shelves.<br />
# To keep them separate from normal shops, turn on a specific switch and set<br />
# the shop's ID via a specific variable. The rest is taken care by the script.<br />
# It also allows you to set a backdrop as well instead of the current map.<br />
<br />
module KSingleItem<br />
  SHOP_SWITCH = 10<br />
  SHOP_ID_VAR = 10<br />
  DEFAULT_BACKDROPS = ["Wood2", "Room2"]<br />
<br />
  class Shop<br />
    attr_accessor :goods<br />
  end<br />
end<br />
<br />
class Game_Party<br />
  alias :kyon_single_item_gm_pty_init :initialize<br />
  def initialize<br />
    kyon_single_item_gm_pty_init<br />
    @single_shops = {}<br />
  end<br />
<br />
  def setup_single_shop(shop_id, new_goods)<br />
    shop = @single_shops[shop_id] || KSingleItem::Shop.new<br />
    shop.goods = new_goods<br />
  end<br />
  attr_reader :single_shops<br />
end<br />
<br />
class Game_Interpreter<br />
  def command_302<br />
    return if &#36;game_party.in_battle<br />
    goods = [@params]<br />
    while next_event_code == 605<br />
      @index += 1<br />
      goods.push(@list[@index].parameters)<br />
    end<br />
    if &#36;game_switches[KSingleItem::SHOP_SWITCH]<br />
      SceneManager.call(SingleShopScene)<br />
    else<br />
      SceneManager.call(Scene_Shop)<br />
    end<br />
    SceneManager.scene.prepare(goods, @params[4])<br />
    Fiber.yield<br />
  end<br />
end<br />
<br />
class Window_ShopBuy<br />
  alias :kyon_single_item_win_shopbuy_draw_item :draw_item<br />
  attr_reader :shop_goods<br />
  def initialize(x, y, height, shop_goods, stretch=nil)<br />
    @stretch = stretch<br />
    super(x, y, window_width, height)<br />
    @shop_goods = shop_goods.dup<br />
    @money = 0<br />
    @no_item = RPG::Item.new<br />
    @symbol_color = Color.new(255, 255, 80)<br />
    @symbol = &#36;data_system.currency_unit<br />
    refresh<br />
    select(0)<br />
  end<br />
<br />
  def window_width<br />
    @stretch ? 384 : 304<br />
  end<br />
<br />
  def item<br />
    @data[@index] || @no_item<br />
  end<br />
<br />
  def money=(money)<br />
    @money = money<br />
    refresh<br />
  end<br />
<br />
  def price(item)<br />
    @price[item.id]<br />
  end<br />
<br />
  def enable?(item)<br />
    item &amp;&amp; price(item) &lt;= @money &amp;&amp; !&#36;game_party.item_max?(item)<br />
  end<br />
<br />
  def set_goods(type, gid)<br />
    case type<br />
    when 0<br />
      &#36;data_items[gid]<br />
    when 1<br />
      &#36;data_weapons[gid]<br />
    when 2<br />
      &#36;data_armors[gid]<br />
    end<br />
  end<br />
<br />
  def make_item_list<br />
    @data = []<br />
    @price = {}<br />
    @shop_goods.each do |goods|<br />
      item = set_goods(goods[0], goods[1])<br />
      next unless item<br />
      @data &lt;&lt; item<br />
      @price[item.id] = goods[2] == 0 ? item.price : goods[3]<br />
    end<br />
  end<br />
<br />
  def draw_item_data(item, rx, ry, enabled=true, w=240)<br />
    return unless item<br />
    draw_icon(item.icon_index, 28, ry, enabled)<br />
    change_color(normal_color, enabled)<br />
    draw_text(56, ry, w - 56, 24, item.name)<br />
    draw_text(w, ry, 100, 24, price(item), 2)<br />
    change_color(@symbol_color, enabled)<br />
    draw_text(w + 100, ry, 16, 24, @symbol, 2)<br />
  end<br />
<br />
  def draw_item(n)<br />
    unless @stretch<br />
      kyon_single_item_win_shopbuy_draw_item(n)<br />
    else<br />
      item = @data[n]<br />
      rect = item_rect(n)<br />
      draw_item_data(item, rect.x, rect.y, enable?(item))<br />
    end<br />
  end<br />
<br />
  def delete_item<br />
    @shop_goods.delete(@index)<br />
    item = @data.delete(@index)<br />
    @price.delete(item.id)<br />
    create_contents<br />
    draw_all_items<br />
  end<br />
end<br />
<br />
class SingleShopScene &lt; Scene_Shop<br />
  def find_shop_id<br />
    &#36;game_variables[KSingleItem::SHOP_ID_VAR]<br />
  end<br />
<br />
  def prepare(goods, purchase_only)<br />
    shop_id = find_shop_id<br />
    shop = &#36;game_party.single_shops[shop_id]<br />
    @goods = shop ? shop.goods : goods<br />
    @purchase_only = purchase_only<br />
  end<br />
<br />
  def start<br />
    create_main_viewport<br />
    create_background<br />
    @actor = &#36;game_party.menu_actor<br />
    create_help_window<br />
    create_gold_window<br />
    create_command_window<br />
    create_buy_window<br />
    create_status_window<br />
    create_category_window<br />
    create_sell_window<br />
  end<br />
<br />
  def create_background<br />
    drop1, drop2 = KSingleItem::DEFAULT_BACKDROPS<br />
    @backdrops = [Sprite.new, Sprite.new]<br />
    @backdrops[0].bitmap = Cache.battleback1(drop1)<br />
    @backdrops[1].bitmap = Cache.battleback2(drop2)<br />
  end<br />
<br />
  def create_buy_window<br />
    @buy_window = Window_ShopBuy.new(0, 252, 24 * 7, @goods, true)<br />
    @buy_window.viewport = @viewport<br />
    @buy_window.help_window = @help_window<br />
    @buy_window.hide<br />
    @buy_window.set_handler(:ok,   &nbsp;&nbsp;method(:on_buy_ok))<br />
    @buy_window.set_handler(:cancel, method(:on_buy_cancel))<br />
  end<br />
<br />
  def create_status_window<br />
    wx = @buy_window.width<br />
    wy = @buy_window.y<br />
    ww = Graphics.width - wx<br />
    @status_window = Window_ShopStatus.new(wx, wy, ww, @buy_window.height)<br />
    @status_window.viewport = @viewport<br />
    @status_window.hide<br />
    @buy_window.status_window = @status_window<br />
  end<br />
<br />
  def create_category_window<br />
    @category_window = Window_ItemCategory.new<br />
    @category_window.viewport = @viewport<br />
    @category_window.help_window = @help_window<br />
    @category_window.hide.deactivate<br />
    @category_window.set_handler(:ok,   &nbsp;&nbsp;method(:on_category_ok))<br />
    @category_window.set_handler(:cancel, method(:on_category_cancel))<br />
  end<br />
<br />
  def command_buy<br />
    activate_buy_window<br />
  end<br />
<br />
  def command_sell<br />
    @category_window.show.activate<br />
    @sell_window.show<br />
    @sell_window.unselect<br />
    @sell_window.refresh<br />
  end<br />
<br />
  def on_buy_ok<br />
    @item = @buy_window.item<br />
    @buy_window.hide<br />
    Sound.play_shop<br />
    do_buy(1)<br />
    @gold_window.refresh<br />
    @status_window.refresh<br />
    @buy_window.delete_item<br />
  end<br />
<br />
  def on_buy_cancel<br />
    @command_window.activate<br />
    @buy_window.hide<br />
    @status_window.hide<br />
    @status_window.item = nil<br />
    @help_window.clear<br />
  end<br />
<br />
  def dispose_background<br />
    @backdrops.each do |sprite|<br />
      sprite.bitmap.dispose<br />
      sprite.dispose<br />
    end<br />
  end<br />
<br />
  def terminate<br />
    super<br />
    reset_single_shop<br />
  end<br />
<br />
  def reset_single_shop<br />
    list = @buy_window.shop_goods<br />
    return list.size == @goods.size<br />
    shop_id = find_shop_id<br />
    return if shop_id == 0<br />
    &#36;game_party.setup_single_shop(shop_id, @buy_window.shop_goods)<br />
    &#36;game_variables[KSingleItem::SHOP_ID_VAR] = 0<br />
    &#36;game_switches[KSingleItem::SHOP_SWITCH] = false<br />
  end<br />
end</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Terms &amp; Conditions</span><br />
<br />
Free as in <img src="https://www.save-point.org/images/smilies/ejlol/beer.gif" alt="Beer" title="Beer" class="smilie smilie_189" /> beer.<br />
Mention me in your game credits.<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>
	</channel>
</rss>