Files
infinitefusion-e18/Data/Scripts/016_UI/015_UI_Options.rb
2025-06-07 10:22:50 -04:00

534 lines
16 KiB
Ruby

#===============================================================================
#
#===============================================================================
class PokemonSystem
attr_accessor :textspeed
attr_accessor :battlescene
attr_accessor :battlestyle
attr_accessor :frame
attr_accessor :textskin
attr_accessor :screensize
attr_accessor :language
attr_accessor :runstyle
attr_accessor :bgmvolume
attr_accessor :sevolume
attr_accessor :textinput
attr_accessor :quicksurf
attr_accessor :level_caps
attr_accessor :battle_type
attr_accessor :download_sprites
attr_accessor :speedup
attr_accessor :speedup_speed
attr_accessor :max_nb_sprites_download
attr_accessor :on_mobile
attr_accessor :type_icons
attr_accessor :use_generated_dex_entries
attr_accessor :use_custom_eggs
attr_accessor :include_alt_sprites_in_random
def initialize
@textspeed = 1 # Text speed (0=slow, 1=normal, 2=fast)
@battlescene = 0 # Battle effects (animations) (0=on, 1=off)
@battlestyle = 0 # Battle style (0=switch, 1=set)
@frame = 0 # Default window frame (see also Settings::MENU_WINDOWSKINS)
@textskin = 0 # Speech frame
@screensize = (Settings::SCREEN_SCALE * 2).floor - 1 # 0=half size, 1=full size, 2=full-and-a-half size, 3=double size
@language = 0 # Language (see also Settings::LANGUAGES in script PokemonSystem)
@runstyle = 0 # Default movement speed (0=walk, 1=run)
@bgmvolume = 40 # Volume of background music and ME
@sevolume = 40 # Volume of sound effects
@textinput = 1 # Text input mode (0=cursor, 1=keyboard)
@quicksurf = 0
@battle_type = 0
@speedup = 0 #0= hold, 1=toggle
@speedup_speed = 3 #for hold only
@download_sprites = 0
@max_nb_sprites_download = 5
@on_mobile = false
@type_icons = true
@use_generated_dex_entries = true
@use_custom_eggs = true
@include_alt_sprites_in_random = false
end
end
#===============================================================================
#
#===============================================================================
module PropertyMixin
def get
(@getProc) ? @getProc.call : nil
end
def set(value)
@setProc.call(value) if @setProc
end
end
class Option
attr_reader :description
def initialize(description)
@description = description
end
end
#===============================================================================
#
#===============================================================================
class EnumOption < Option
include PropertyMixin
attr_reader :values
attr_reader :name
def initialize(name, options, getProc, setProc, description = "")
super(description)
@name = name
@values = options
@getProc = getProc
@setProc = setProc
end
def next(current)
index = current + 1
index = @values.length - 1 if index > @values.length - 1
return index
end
def prev(current)
index = current - 1
index = 0 if index < 0
return index
end
end
#===============================================================================
#
#===============================================================================
class EnumOption2
include PropertyMixin
attr_reader :values
attr_reader :name
def initialize(name, options, getProc, setProc)
@name = name
@values = options
@getProc = getProc
@setProc = setProc
end
def next(current)
index = current + 1
index = @values.length - 1 if index > @values.length - 1
return index
end
def prev(current)
index = current - 1
index = 0 if index < 0
return index
end
end
#===============================================================================
#
#===============================================================================
class NumberOption < Option
include PropertyMixin
attr_reader :name
attr_reader :optstart
attr_reader :optend
def initialize(name, optstart, optend, getProc, setProc, description="")
super(description)
@name = name
@optstart = optstart
@optend = optend
@getProc = getProc
@setProc = setProc
end
def next(current)
index = current + @optstart
index += 1
index = @optstart if index > @optend
return index - @optstart
end
def prev(current)
index = current + @optstart
index -= 1
index = @optend if index < @optstart
return index - @optstart
end
end
#===============================================================================
#
#===============================================================================
class SliderOption < Option
include PropertyMixin
attr_reader :name
attr_reader :optstart
attr_reader :optend
def initialize(name, optstart, optend, optinterval, getProc, setProc, description = "")
super(description)
@name = name
@optstart = optstart
@optend = optend
@optinterval = optinterval
@getProc = getProc
@setProc = setProc
end
def next(current)
index = current + @optstart
index += @optinterval
index = @optend if index > @optend
return index - @optstart
end
def prev(current)
index = current + @optstart
index -= @optinterval
index = @optstart if index < @optstart
return index - @optstart
end
end
#===============================================================================
# Main options list
#===============================================================================
class Window_PokemonOption < Window_DrawableCommand
attr_reader :mustUpdateOptions
attr_reader :mustUpdateDescription
attr_reader :selected_position
def initialize(options, x, y, width, height)
@previous_Index = 0
@options = options
@nameBaseColor = Color.new(24 * 8, 15 * 8, 0)
@nameShadowColor = Color.new(31 * 8, 22 * 8, 10 * 8)
@selBaseColor = Color.new(31 * 8, 6 * 8, 3 * 8)
@selShadowColor = Color.new(31 * 8, 17 * 8, 16 * 8)
@optvalues = []
@mustUpdateOptions = false
@mustUpdateDescription = false
@selected_position = 0
@allow_arrows_jump = false
@is_first_update = true
for i in 0...@options.length
@optvalues[i] = 0
end
super(x, y, width, height)
end
def changedPosition
@mustUpdateDescription = true
super
end
def descriptionUpdated
@mustUpdateDescription = false
end
def nameBaseColor=(value)
@nameBaseColor = value
end
def nameShadowColor=(value)
@nameShadowColor = value
end
def [](i)
return @optvalues[i]
end
def []=(i, value)
@optvalues[i] = value
refresh
end
def setValueNoRefresh(i, value)
@optvalues[i] = value
end
def itemCount
return @options.length + 1
end
def dont_draw_item(index)
return false
end
def drawItem(index, _count, rect)
return if dont_draw_item(index)
rect = drawCursor(index, rect)
optionname = (index == @options.length) ? _INTL("Confirm") : @options[index].name
optionwidth = rect.width * 9 / 20
pbDrawShadowText(self.contents, rect.x, rect.y, optionwidth, rect.height, optionname,
@nameBaseColor, @nameShadowColor)
return if index == @options.length
if @options[index].is_a?(EnumOption)
if @options[index].values.length > 1
totalwidth = 0
for value in @options[index].values
totalwidth += self.contents.text_size(value).width
end
spacing = (optionwidth - totalwidth) / (@options[index].values.length - 1)
spacing = 0 if spacing < 0
xpos = optionwidth + rect.x
ivalue = 0
for value in @options[index].values
pbDrawShadowText(self.contents, xpos, rect.y, optionwidth, rect.height, value,
(ivalue == self[index]) ? @selBaseColor : self.baseColor,
(ivalue == self[index]) ? @selShadowColor : self.shadowColor
)
xpos += self.contents.text_size(value).width
xpos += spacing
ivalue += 1
end
else
pbDrawShadowText(self.contents, rect.x + optionwidth, rect.y, optionwidth, rect.height,
optionname, self.baseColor, self.shadowColor)
end
elsif @options[index].is_a?(NumberOption)
value = _INTL("Type {1}/{2}", @options[index].optstart + self[index],
@options[index].optend - @options[index].optstart + 1)
xpos = optionwidth + rect.x
pbDrawShadowText(self.contents, xpos, rect.y, optionwidth, rect.height, value,
@selBaseColor, @selShadowColor)
elsif @options[index].is_a?(SliderOption)
value = sprintf(" %d", @options[index].optend)
sliderlength = optionwidth - self.contents.text_size(value).width
xpos = optionwidth + rect.x
self.contents.fill_rect(xpos, rect.y - 2 + rect.height / 2,
optionwidth - self.contents.text_size(value).width, 4, self.baseColor)
self.contents.fill_rect(
xpos + (sliderlength - 8) * (@options[index].optstart + self[index]) / @options[index].optend,
rect.y - 8 + rect.height / 2,
8, 16, @selBaseColor)
value = sprintf("%d", @options[index].optstart + self[index])
xpos += optionwidth - self.contents.text_size(value).width
pbDrawShadowText(self.contents, xpos, rect.y, optionwidth, rect.height, value,
@selBaseColor, @selShadowColor)
else
value = @options[index].values[self[index]]
xpos = optionwidth + rect.x
pbDrawShadowText(self.contents, xpos, rect.y, optionwidth, rect.height, value,
@selBaseColor, @selShadowColor)
end
end
def update
oldindex = self.index
@mustUpdateOptions = false
super
if @is_first_update
# Needed for displaying the description of the initially selected option correctly
@selected_position = self[self.index]
@mustUpdateOptions = true
@mustUpdateDescription = true
@is_first_update = false
refresh
return
end
if self.active && self.index < @options.length
if Input.repeat?(Input::LEFT)
self[self.index] = @options[self.index].prev(self[self.index])
@selected_position = self[self.index]
@mustUpdateOptions = true
@mustUpdateDescription = true
refresh if self[self.index]
return
end
if Input.repeat?(Input::RIGHT)
self[self.index] = @options[self.index].next(self[self.index])
@selected_position = self[self.index]
@mustUpdateOptions = true
@mustUpdateDescription = true
refresh
return
end
if Input.repeat?(Input::UP) || Input.repeat?(Input::DOWN)
@selected_position = self[self.index]
@mustUpdateOptions = true
@mustUpdateDescription = true
refresh
return
end
end
refresh if (self.index != oldindex)
end
end
#===============================================================================
# Options main screen
#===============================================================================
class PokemonOption_Scene
def getDefaultDescription
return _INTL("Speech frame {1}.", 1 + $PokemonSystem.textskin)
end
def pbUpdate
pbUpdateSpriteHash(@sprites)
if @sprites["option"].mustUpdateDescription
updateDescription(@sprites["option"].index)
@sprites["option"].descriptionUpdated
end
end
def initialize
@autosave_menu = false
@manually_changed_difficulty=false
end
def initUIElements
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(
_INTL("Options"), 0, 0, Graphics.width, 64, @viewport)
@sprites["textbox"] = pbCreateMessageWindow
@sprites["textbox"].text = _INTL("Speech frame {1}.", 1 + $PokemonSystem.textskin)
@sprites["textbox"].letterbyletter = false
pbSetSystemFont(@sprites["textbox"].contents)
end
def pbStartScene(inloadscreen = false)
@sprites = {}
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999
initUIElements
# These are the different options in the game. To add an option, define a
# setter and a getter for that option. To delete an option, comment it out
# or delete it. The game's options may be placed in any order.
@PokemonOptions = pbGetOptions(inloadscreen)
@PokemonOptions = pbAddOnOptions(@PokemonOptions)
@sprites["option"] = initOptionsWindow
# Get the values of each option
for i in 0...@PokemonOptions.length
@sprites["option"].setValueNoRefresh(i, (@PokemonOptions[i].get || 0))
end
@sprites["option"].refresh
pbDeactivateWindows(@sprites)
pbFadeInAndShow(@sprites) { pbUpdate }
end
def initOptionsWindow
optionsWindow = Window_PokemonOption.new(@PokemonOptions, 0,
@sprites["title"].height, Graphics.width,
Graphics.height - @sprites["title"].height - @sprites["textbox"].height)
optionsWindow.viewport = @viewport
optionsWindow.visible = true
return optionsWindow
end
def updateDescription(index)
index = 0 if !index
begin
horizontal_position = @sprites["option"].selected_position
optionDescription = @PokemonOptions[index].description
if optionDescription.is_a?(Array)
if horizontal_position < optionDescription.size
new_description = optionDescription[horizontal_position]
else
new_description = getDefaultDescription
end
else
new_description = optionDescription
end
new_description = getDefaultDescription if new_description == ""
@sprites["textbox"].text = _INTL(new_description)
rescue
@sprites["textbox"].text = getDefaultDescription
end
end
#IMPLEMENT IN INHERITED CLASSES
def pbGetOptions(inloadscreen = false)
options = []
return options
end
def pbAddOnOptions(options)
return options
end
def openAutosaveMenu()
return if !@autosave_menu
pbFadeOutIn {
scene = AutosaveOptionsScene.new
screen = PokemonOptionScreen.new(scene)
screen.pbStartScreen
}
@autosave_menu = false
end
def pbOptions
oldSystemSkin = $PokemonSystem.frame # Menu
oldTextSkin = $PokemonSystem.textskin # Speech
pbActivateWindow(@sprites, "option") {
loop do
Graphics.update
Input.update
pbUpdate
if @sprites["option"].mustUpdateOptions
# Set the values of each option
for i in 0...@PokemonOptions.length
@PokemonOptions[i].set(@sprites["option"][i])
end
if $PokemonSystem.textskin != oldTextSkin
@sprites["textbox"].setSkin(MessageConfig.pbGetSpeechFrame())
@sprites["textbox"].text = _INTL("Speech frame {1}.", 1 + $PokemonSystem.textskin)
oldTextSkin = $PokemonSystem.textskin
end
if $PokemonSystem.frame != oldSystemSkin
@sprites["title"].setSkin(MessageConfig.pbGetSystemFrame())
@sprites["option"].setSkin(MessageConfig.pbGetSystemFrame())
oldSystemSkin = $PokemonSystem.frame
end
end
if Input.trigger?(Input::BACK)
break
elsif Input.trigger?(Input::USE)
break if isConfirmedOnKeyPress
end
end
}
end
def isConfirmedOnKeyPress
return @sprites["option"].index == @PokemonOptions.length
end
def pbEndScene
pbPlayCloseMenuSE
pbFadeOutAndHide(@sprites) { pbUpdate }
# Set the values of each option
for i in 0...@PokemonOptions.length
@PokemonOptions[i].set(@sprites["option"][i])
end
pbDisposeMessageWindow(@sprites["textbox"])
pbDisposeSpriteHash(@sprites)
pbRefreshSceneMap
@viewport.dispose
end
end
#===============================================================================
#
#===============================================================================
class PokemonOptionScreen
def initialize(scene)
@scene = scene
end
def pbStartScreen(inloadscreen = false)
@scene.pbStartScene(inloadscreen)
@scene.pbOptions
@scene.pbEndScene
end
end