mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Rewrote Move Reminder screen
This commit is contained in:
@@ -363,16 +363,36 @@ module UI
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def set_viewport_color(new_color)
|
||||
@viewport.color = new_color
|
||||
end
|
||||
|
||||
def fade_in
|
||||
# TODO: pbFadeInAndShow changes the colour of all sprites. Make it instead
|
||||
# change the opacity of @viewport like def pbFadeOutIn.
|
||||
pbFadeInAndShow(@sprites)
|
||||
duration = 0.4 # In seconds
|
||||
col = Color.new(0, 0, 0, 0)
|
||||
timer_start = System.uptime
|
||||
loop do
|
||||
col.set(0, 0, 0, lerp(255, 0, duration, timer_start, System.uptime))
|
||||
set_viewport_color(col)
|
||||
Graphics.update
|
||||
Input.update
|
||||
update_visuals
|
||||
break if col.alpha == 0
|
||||
end
|
||||
end
|
||||
|
||||
def fade_out
|
||||
# TODO: pbFadeOutAndHide changes the colour of all sprites. Make it
|
||||
# instead change the opacity of @viewport like def pbFadeOutIn.
|
||||
pbFadeOutAndHide(@sprites)
|
||||
duration = 0.4 # In seconds
|
||||
col = Color.new(0, 0, 0, 0)
|
||||
timer_start = System.uptime
|
||||
loop do
|
||||
col.set(0, 0, 0, lerp(0, 255, duration, timer_start, System.uptime))
|
||||
set_viewport_color(col)
|
||||
Graphics.update
|
||||
Input.update
|
||||
update_visuals
|
||||
break if col.alpha == 255
|
||||
end
|
||||
end
|
||||
|
||||
def dispose
|
||||
|
||||
@@ -27,7 +27,6 @@ class UI::PokemonSummaryMoveCursor < ChangelingSprite
|
||||
self.visible = (@index >= 0)
|
||||
end
|
||||
|
||||
|
||||
def refresh_position
|
||||
return if @index < 0
|
||||
self.x = UI::PokemonSummaryVisuals::MOVE_LIST_X_DETAILED - CURSOR_THICKNESS
|
||||
|
||||
364
Data/Scripts/016b_UI redesign/022_UI_MoveReminder.rb
Normal file
364
Data/Scripts/016b_UI redesign/022_UI_MoveReminder.rb
Normal file
@@ -0,0 +1,364 @@
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class UI::MoveReminderCursor < IconSprite
|
||||
attr_accessor :top_index
|
||||
|
||||
CURSOR_WIDTH = 258
|
||||
CURSOR_HEIGHT = 72
|
||||
CURSOR_THICKNESS = 6
|
||||
|
||||
def initialize(viewport = nil)
|
||||
super(0, 0, viewport)
|
||||
setBitmap("Graphics/UI/Move Reminder/cursor")
|
||||
self.src_rect = Rect.new(0, 0, CURSOR_WIDTH, CURSOR_HEIGHT)
|
||||
self.z = 1600
|
||||
@bg_sprite = IconSprite.new(x, y, viewport)
|
||||
@bg_sprite.setBitmap("Graphics/UI/Move Reminder/cursor")
|
||||
@bg_sprite.src_rect = Rect.new(0, CURSOR_HEIGHT, CURSOR_WIDTH, CURSOR_HEIGHT)
|
||||
@top_index = 0
|
||||
self.index = 0
|
||||
end
|
||||
|
||||
def dispose
|
||||
@bg_sprite.dispose
|
||||
@bg_sprite = nil
|
||||
super
|
||||
end
|
||||
|
||||
def index=(value)
|
||||
@index = value
|
||||
refresh_position
|
||||
end
|
||||
|
||||
def visible=(value)
|
||||
super
|
||||
@bg_sprite.visible = value
|
||||
end
|
||||
|
||||
def refresh_position
|
||||
return if @index < 0
|
||||
self.x = UI::MoveReminderVisuals::MOVE_LIST_X
|
||||
self.y = UI::MoveReminderVisuals::MOVE_LIST_Y - CURSOR_THICKNESS
|
||||
self.y += (@index - @top_index) * UI::MoveReminderVisuals::MOVE_LIST_SPACING
|
||||
@bg_sprite.x = self.x
|
||||
@bg_sprite.y = self.y
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class UI::MoveReminderVisuals < UI::BaseVisuals
|
||||
attr_reader :index
|
||||
|
||||
GRAPHICS_FOLDER = "Move Reminder/" # Subfolder in Graphics/UI
|
||||
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
||||
:default => [Color.new(248, 248, 248), Color.new(0, 0, 0)], # Base and shadow colour
|
||||
:white => [Color.new(248, 248, 248), Color.new(0, 0, 0)],
|
||||
:black => [Color.new(64, 64, 64), Color.new(176, 176, 176)],
|
||||
:header => [Color.new(88, 88, 80), Color.new(168, 184, 184)]
|
||||
}
|
||||
MOVE_LIST_X = 0
|
||||
MOVE_LIST_Y = 84
|
||||
MOVE_LIST_SPACING = 64 # Y distance between top of two adjacent move areas
|
||||
VISIBLE_MOVES = 4
|
||||
|
||||
def initialize(pokemon, moves)
|
||||
@pokemon = pokemon
|
||||
@moves = moves
|
||||
@top_index = 0
|
||||
@index = 0
|
||||
super()
|
||||
refresh_cursor
|
||||
end
|
||||
|
||||
def initialize_bitmaps
|
||||
@bitmaps[:types] = AnimatedBitmap.new(UI_FOLDER + _INTL("types"))
|
||||
@bitmaps[:buttons] = AnimatedBitmap.new(graphics_folder + "buttons")
|
||||
end
|
||||
|
||||
def initialize_sprites
|
||||
# Pokémon icon
|
||||
@sprites[:pokemon_icon] = PokemonIconSprite.new(@pokemon, @viewport)
|
||||
@sprites[:pokemon_icon].setOffset(PictureOrigin::CENTER)
|
||||
@sprites[:pokemon_icon].x = 314
|
||||
@sprites[:pokemon_icon].y = 84
|
||||
@sprites[:pokemon_icon].z = 200
|
||||
# Cursor
|
||||
@sprites[:cursor] = UI::MoveReminderCursor.new(@viewport)
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def moves=(move_list)
|
||||
@moves = move_list
|
||||
@index = @moves.length - 1 if @index >= @moves.length
|
||||
refresh_on_index_changed(@index)
|
||||
@cursor.visible = false if @moves.empty?
|
||||
refresh
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def refresh_overlay
|
||||
super
|
||||
draw_header
|
||||
draw_pokemon_type_icons(396, 70, 6)
|
||||
draw_moves_list
|
||||
draw_move_properties
|
||||
draw_buttons
|
||||
end
|
||||
|
||||
def draw_header
|
||||
draw_text(_INTL("Teach which move?"), 16, 14, theme: :header)
|
||||
end
|
||||
|
||||
# x and y are the top left corner of the type icon if there is only one type.
|
||||
def draw_pokemon_type_icons(x, y, spacing)
|
||||
@pokemon.types.each_with_index do |type, i|
|
||||
type_number = GameData::Type.get(type).icon_position
|
||||
offset = ((@pokemon.types.length - 1) * (GameData::Type::ICON_SIZE[0] + spacing) / 2)
|
||||
offset = (offset / 2) * 2
|
||||
type_x = x - offset + ((GameData::Type::ICON_SIZE[0] + spacing) * i)
|
||||
draw_image(@bitmaps[:types], type_x, y,
|
||||
0, type_number * GameData::Type::ICON_SIZE[1], *GameData::Type::ICON_SIZE)
|
||||
end
|
||||
end
|
||||
|
||||
def draw_moves_list
|
||||
VISIBLE_MOVES.times do |i|
|
||||
move = @moves[@top_index + i]
|
||||
next if move.nil?
|
||||
move_data = GameData::Move.get(move)
|
||||
draw_move_in_list(move_data, MOVE_LIST_X, MOVE_LIST_Y + (i * MOVE_LIST_SPACING))
|
||||
end
|
||||
end
|
||||
|
||||
def draw_move_in_list(move_data, x, y)
|
||||
# Draw move name
|
||||
move_name = move_data.name
|
||||
move_name = crop_text(move_name, 230)
|
||||
draw_text(move_name, x + 10, y + 6)
|
||||
# Draw move type icon
|
||||
type_number = GameData::Type.get(move_data.display_type(@pokemon)).icon_position
|
||||
draw_image(@bitmaps[:types], x + 10, y + 32,
|
||||
0, type_number * GameData::Type::ICON_SIZE[1], *GameData::Type::ICON_SIZE)
|
||||
# Draw move category
|
||||
draw_image(UI_FOLDER + "category", x + 76, y + 32,
|
||||
0, move_data.display_category(@pokemon) * GameData::Move::CATEGORY_ICON_SIZE[1], *GameData::Move::CATEGORY_ICON_SIZE)
|
||||
# Draw PP text
|
||||
if move_data.total_pp > 0
|
||||
draw_text(_INTL("PP"), x + 150, y + 38, theme: :black)
|
||||
draw_text(sprintf("%d/%d", move_data.total_pp, move_data.total_pp), x + 240, y + 38, align: :right, theme: :black)
|
||||
end
|
||||
end
|
||||
|
||||
def draw_move_properties
|
||||
move = @moves[@index]
|
||||
move_data = GameData::Move.get(move)
|
||||
# Power
|
||||
draw_text(_INTL("POWER"), 278, 120)
|
||||
power_text = move_data.display_power(@pokemon)
|
||||
power_text = "---" if power_text == 0 # Status move
|
||||
power_text = "???" if power_text == 1 # Variable power move
|
||||
draw_text(power_text, 480, 120, align: :right, theme: :black)
|
||||
# Accuracy
|
||||
draw_text(_INTL("ACCURACY"), 278, 152)
|
||||
accuracy = move_data.display_accuracy(@pokemon)
|
||||
if accuracy == 0
|
||||
draw_text("---", 480, 152, align: :right, theme: :black)
|
||||
else
|
||||
draw_text(accuracy, 480, 152, align: :right, theme: :black)
|
||||
draw_text("%", 480, 152, theme: :black)
|
||||
end
|
||||
# Description
|
||||
draw_paragraph_text(move_data.description, 262, 184, 246, 6, theme: :black)
|
||||
end
|
||||
|
||||
def draw_buttons
|
||||
draw_image(@bitmaps[:buttons], 44, 350, 0, 0, 76, 32) if @top_index < @moves.length - VISIBLE_MOVES
|
||||
draw_image(@bitmaps[:buttons], 132, 350, 76, 0, 76, 32) if @top_index > 0
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def refresh_cursor
|
||||
@sprites[:cursor].top_index = @top_index
|
||||
@sprites[:cursor].index = @index
|
||||
end
|
||||
|
||||
def refresh_on_index_changed(old_index)
|
||||
pbPlayCursorSE
|
||||
# Change @top_index to keep @index in the middle of the visible list (or as
|
||||
# close to it as possible)
|
||||
middle_range_top = (VISIBLE_MOVES / 2) - ((VISIBLE_MOVES + 1) % 2)
|
||||
middle_range_bottom = VISIBLE_MOVES / 2
|
||||
if @index < @top_index + middle_range_top
|
||||
@top_index = @index - middle_range_top
|
||||
elsif @index > @top_index + middle_range_bottom
|
||||
@top_index = @index - middle_range_bottom
|
||||
end
|
||||
@top_index = @top_index.clamp(0, [@moves.length - VISIBLE_MOVES, 0].max)
|
||||
refresh_cursor
|
||||
refresh
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def update_input
|
||||
# Check for movement to a new move
|
||||
update_cursor_movement
|
||||
# Check for interaction
|
||||
if Input.trigger?(Input::USE)
|
||||
return update_interaction(Input::USE)
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
return update_interaction(Input::BACK)
|
||||
elsif Input.trigger?(Input::ACTION)
|
||||
return update_interaction(Input::ACTION)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def update_cursor_movement
|
||||
# Check for movement to a new move
|
||||
if Input.repeat?(Input::UP)
|
||||
@index -= 1
|
||||
if Input.trigger?(Input::UP)
|
||||
@index = @moves.length - 1 if @index < 0 # Wrap around
|
||||
else
|
||||
@index = 0 if @index < 0
|
||||
end
|
||||
elsif Input.repeat?(Input::DOWN)
|
||||
@index += 1
|
||||
if Input.trigger?(Input::DOWN)
|
||||
@index = 0 if @index >= @moves.length # Wrap around
|
||||
else
|
||||
@index = @moves.length - 1 if @index >= @moves.length
|
||||
end
|
||||
elsif Input.repeat?(Input::JUMPUP)
|
||||
@index -= VISIBLE_MOVES
|
||||
@index = 0 if @index < 0
|
||||
elsif Input.repeat?(Input::JUMPDOWN)
|
||||
@index += VISIBLE_MOVES
|
||||
@index = @moves.length - 1 if @index >= @moves.length
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def update_interaction(input)
|
||||
case input
|
||||
when Input::USE
|
||||
pbPlayDecisionSE
|
||||
return :learn
|
||||
when Input::BACK
|
||||
pbPlayCloseMenuSE
|
||||
return :quit
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class UI::MoveReminder < UI::BaseScreen
|
||||
attr_reader :pokemon, :mode
|
||||
|
||||
SCREEN_ID = :move_reminder_screen
|
||||
|
||||
# mode is either :normal or :single.
|
||||
def initialize(pokemon, mode: :normal)
|
||||
@pokemon = pokemon
|
||||
@mode = mode
|
||||
generate_move_list
|
||||
super()
|
||||
end
|
||||
|
||||
def initialize_visuals
|
||||
@visuals = UI::MoveReminderVisuals.new(@pokemon, @moves)
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def generate_move_list
|
||||
@moves = []
|
||||
return if !@pokemon || @pokemon.egg? || @pokemon.shadowPokemon?
|
||||
@pokemon.getMoveList.each do |move|
|
||||
next if move[0] > @pokemon.level || @pokemon.hasMove?(move[1])
|
||||
@moves.push(move[1]) if !@moves.include?(move[1])
|
||||
end
|
||||
if Settings::MOVE_RELEARNER_CAN_TEACH_MORE_MOVES && @pokemon.first_moves
|
||||
first_moves = []
|
||||
@pokemon.first_moves.each do |move|
|
||||
first_moves.push(move) if !@moves.include?(move) && !@pokemon.hasMove?(move)
|
||||
end
|
||||
@moves = first_moves + @moves # List first moves before level-up moves
|
||||
end
|
||||
@moves = @moves | [] # remove duplicates
|
||||
end
|
||||
|
||||
def refresh_move_list
|
||||
generate_move_list
|
||||
@visuals.moves = @moves
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def move
|
||||
return @moves[self.index]
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def main
|
||||
return if @disposed
|
||||
start_screen
|
||||
loop do
|
||||
on_start_main_loop
|
||||
command = @visuals.navigate
|
||||
break if command == :quit && (@mode == @normal ||
|
||||
show_confirm_message(_INTL("Give up trying to teach a new move to {1}?", @pokemon.name)))
|
||||
perform_action(command)
|
||||
if @moves.empty?
|
||||
show_message(_INTL("There are no more moves for {1} to learn.", @pokemon.name))
|
||||
break
|
||||
end
|
||||
if @disposed
|
||||
@result = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end_screen
|
||||
return @result
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Actions that can be triggered in the Move Reminder screen.
|
||||
#===============================================================================
|
||||
UIActionHandlers.add(UI::MoveReminder::SCREEN_ID, :learn, {
|
||||
:effect => proc { |screen|
|
||||
if screen.show_confirm_message(_INTL("Teach {1}?", GameData::Move.get(screen.move).name))
|
||||
if pbLearnMove(screen.pokemon, screen.move, false, false, screen)
|
||||
$stats.moves_taught_by_reminder += 1
|
||||
if screen.mode == :normal
|
||||
screen.refresh_move_list
|
||||
else
|
||||
screen.end_screen
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
})
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
def pbRelearnMoveScreen(pkmn)
|
||||
ret = true
|
||||
pbFadeOutIn do
|
||||
ret = UI::MoveReminder.new(pkmn, mode: :single).main
|
||||
end
|
||||
return ret
|
||||
end
|
||||
@@ -1,3 +1,4 @@
|
||||
=begin
|
||||
#===============================================================================
|
||||
# Scene class for handling appearance of the screen.
|
||||
#===============================================================================
|
||||
@@ -197,3 +198,4 @@ def pbRelearnMoveScreen(pkmn)
|
||||
end
|
||||
return retval
|
||||
end
|
||||
=end
|
||||
Reference in New Issue
Block a user