Update 6.8

This commit is contained in:
chardub
2026-07-10 15:42:06 -04:00
parent 5b85e72cb2
commit 6a6f126a18
7871 changed files with 493194 additions and 224826 deletions
@@ -0,0 +1,385 @@
################
#### AQUA ##
################
def build_aqua_song(event_id1, event_id2)
chorus = _INTL("Oh! \\wt[10]Hey!\\wt[10]\\wt[10] Aqua!\\wt[10] We're Team Aqua!")
add_aqua_song_segment(chorus)
segment1 = build_aqua_song_pt1(event_id1, event_id2, chorus)
build_aqua_song_pt2(event_id1, event_id2)
add_aqua_song_segment(chorus)
# add_aqua_song_segment(segment1)
build_aqua_song_pt3(event_id1, event_id2)
end
def build_aqua_song_pt1(event_id1, event_id2, chorus)
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Let's see, this is what we have so far."))
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("The start of the song goes like this..."))
#~~~~~ Singing ~~~~~~
segment_1_incomplete = _INTL("Cool as...\\wt[20]\\ts[1]Something...\\n\\ts[4]\\wt[10]Graceful like... \\wt[20]\\ts[1]Something else...")
add_aqua_song_segment(segment_1_incomplete)
sing_aqua_song
pbWait(10)
#~~~~~~~~~~~
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Yeah... That's all we have so far."))
confirmed = false
while !confirmed
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("So uh... What's something that's icy cool?"))
helpText = _INTL("Cool as...")
word1 = pbEnterText(helpText, 2, 16)
pbCallBubDown(2, event_id1) # Left
commands = [_INTL("That's right!"), _INTL("Maybe not...")]
confirmed = pbMessage(_INTL("Cool as {1}...?", word1), commands) == 0
end
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Hmmm..."))
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Not bad! That might be the one."))
pbWait(10)
#~~~~~ Singing ~~~~~~
pbSet(VAR_AQUA_SONG, [])
add_aqua_song_segment(chorus)
segment_1_incomplete2 = _INTL("Cool as {1}!\\wt[10]\\nGraceful like...\\wt[20]\\ts[1]Something...", word1)
add_aqua_song_segment(segment_1_incomplete2)
sing_aqua_song
pbWait(10)
#~~~~~~~~~~~
confirmed = false
while !confirmed
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Uh... Graceful like what?"))
helpText = _INTL("Graceful like...")
word2 = pbEnterText(helpText, 2, 16)
pbCallBubUp(2, event_id2) # Right
commands = [_INTL("That's right!"), _INTL("Maybe not...")]
confirmed = pbMessage(_INTL("Cool as {1}!\\nGraceful like {2}!", word1, word2), commands) == 0
end
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("That sounds pretty good, right?"))
pbSet(VAR_AQUA_SONG, [])
add_aqua_song_segment(chorus)
segment_1_complete = _INTL("Cool as {1}!\\n\\wt[10]Graceful like {2}!", word1, word2)
add_aqua_song_segment(segment_1_complete)
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Okay... On to the next part!"))
return segment_1_complete
end
def build_aqua_song_pt2(event_id1, event_id2)
cmd_goals = _INTL("Our goals")
cmd_style = _INTL("Our style")
cmd_strength = _INTL("Our strength")
commands = [cmd_goals, cmd_style, cmd_strength]
confirmed = false
while !confirmed
pbCallBubDown(2, event_id1) # Left
choice = pbMessage(_INTL("So... What should the next line of the song be about?"), commands)
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Okay... What do you think of this?"))
case commands[choice]
when cmd_goals
segment1 = _INTL("\\ts[4]\\C[1]Life depends on the sea, ya see\\n\\wt[5]We gotta ex\\wt[2]pand \\wt[2]it \\wt[2]to be free")
when cmd_style
segment1 = _INTL("\\ts[4]\\C[1]With our cool bandanas, we rule\\n\\wt[5]Our style will \\wt[6]make you drool")
when cmd_strength
segment1 = _INTL("\\ts[4]\\C[1]Our power is deep as the blue\\n\\wt[5]There's nothing\\wt[5] Team Aqua can't do")
end
commands_confirm = [_INTL("Perfect"), _INTL("Let's try something else...")]
pbCallBubDown(2, event_id1) # Left
confirmed = pbMessage(segment1, commands_confirm) == 0
end
add_aqua_song_segment(segment1)
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Yeah, this rules!"))
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("The next line should talk about something that inspires us."))
cmd_leader = _INTL("Archie")
cmd_land = _INTL("The ocean")
cmd_pokemon = _INTL("Pokémon")
commands = [cmd_leader, cmd_land, cmd_pokemon]
confirmed = false
while !confirmed
pbCallBubDown(2, event_id1) # Left
choice = pbMessage(_INTL("What should we sing about?"), commands)
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Hmm... How about this?"))
case commands[choice]
when cmd_leader
segment2 = _INTL("\\ts[4]\\C[1]Archie's a captain bold\\n\\wt[5]His legend is \\ts[2]yet un\\wt[5]told")
when cmd_land
segment2 = _INTL("\\ts[4]\\C[1]The ocean is our home\\n\\wt[5]We sail through \\ts[2]salt and \\wt[5]foam")
when cmd_pokemon
segment2 = _INTL("\\ts[4]\\C[1]Water Pokémon by our side\\n\\wt[5]We always surf the \\ts[2]\\wt[5]tide")
end
commands_confirm = [_INTL("Perfect"), _INTL("Let's try something else...")]
pbCallBubDown(2, event_id1) # Left
confirmed = pbMessage(segment2, commands_confirm) == 0
end
add_aqua_song_segment(segment2)
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("I'm feeling it!"))
end
def build_aqua_song_pt3(event_id1, event_id2)
confirmed = false
while !confirmed
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Now we only need an ending line. Do you have something in mind?"))
helpText = _INTL("The song's final line...")
line = pbEnterText(helpText, 2, 50)
pbCallBubUp(2, event_id2) # Right
commands = [_INTL("That's right!"), _INTL("Maybe not...")]
confirmed = pbMessage(_INTL("{1}... ?", line), commands) == 0
end
add_aqua_song_segment(line)
end
def sing_aqua_song
pbMEPlay("aqua_theme_song")
pbWait(160) # Wait for intro
lyrics = pbGet(VAR_AQUA_SONG)
lyrics = [] unless lyrics.is_a?(Array)
for line in lyrics
pbMEPlay("aqua_theme_song")
line = "\\ts[2]\\C[1]#{line}\\wtnp[12]"
pbCallBub(3)
pbMessage(line)
end
pbMEStop
end
def add_aqua_song_segment(text)
current_song = pbGet(VAR_AQUA_SONG)
current_song = [] unless current_song.is_a?(Array)
current_song << text
pbSet(VAR_AQUA_SONG, current_song)
end
################
#### MAGMA ##
################
def build_magma_song(event_id1, event_id2)
chorus = _INTL("Ma\\wt[10]gma!\\n\\wt[5]Team Ma\\wt[10]gma!")
add_magma_song_segment(chorus)
segment1 = build_magma_song_pt1(event_id1, event_id2, chorus)
build_magma_song_pt2(event_id1, event_id2)
add_magma_song_segment(chorus)
# add_magma_song_segment(segment1)
build_magma_song_pt3(event_id1, event_id2)
end
def build_magma_song_pt1(event_id1, event_id2, chorus)
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Let's see, this is what we have so far."))
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("The start of the song goes like this..."))
#~~~~~ Singing ~~~~~~
segment_1_incomplete = _INTL("Hot as...\\wt[20]\\ts[1]Something...\\ts[4]\\wt[10]\\nFierce like...\\wt[20]\\ts[1]Something else...")
add_magma_song_segment(segment_1_incomplete)
sing_magma_song
pbWait(10)
#~~~~~~~~~~~
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Yeah... That's all we have so far."))
confirmed = false
while !confirmed
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("So uh... What's something that's burning hot?"))
helpText = _INTL("Hot as...")
word1 = pbEnterText(helpText, 2, 16)
pbCallBubDown(2, event_id1) # Left
commands = [_INTL("That's right!"), _INTL("Maybe not...")]
confirmed = pbMessage(_INTL("Hot as {1}...?", word1), commands) == 0
end
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Hmmm..."))
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("I like it! Let's go with this!"))
pbWait(10)
#~~~~~ Singing ~~~~~~
pbSet(VAR_MAGMA_SONG, [])
add_magma_song_segment(chorus)
segment_1_incomplete2 = _INTL("Hot as {1}!\\wt[10]\\nFierce like...\\wt[20]\\ts[1]Something...", word1)
add_magma_song_segment(segment_1_incomplete2)
sing_magma_song
pbWait(10)
#~~~~~~~~~~~
confirmed = false
while !confirmed
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Uh... Fierce like what?"))
helpText = _INTL("Fierce like...")
word2 = pbEnterText(helpText, 2, 16)
pbCallBubUp(2, event_id2) # Right
commands = [_INTL("That's right!"), _INTL("Maybe not...")]
confirmed = pbMessage(_INTL("Hot as {1}! Fierce like {2}!", word1, word2), commands) == 0
end
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("It has a nice ring to it, don't you think?"))
pbSet(VAR_MAGMA_SONG, [])
add_magma_song_segment(chorus)
segment_1_complete = _INTL("Hot as {1}!\\wt[10]\\nFierce like {2}!", word1, word2)
add_magma_song_segment(segment_1_complete)
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Okay... On to the next part!"))
return segment_1_complete
end
def build_magma_song_pt2(event_id1, event_id2)
cmd_goals = _INTL("Our goals")
cmd_style = _INTL("Our style")
cmd_strength = _INTL("Our strength")
commands = [cmd_goals, cmd_style, cmd_strength]
confirmed = false
while !confirmed
pbCallBubDown(2, event_id1) # Left
choice = pbMessage(_INTL("So... What should the next line of the song be about?"), commands)
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Okay... How's this?"))
case commands[choice]
when cmd_goals
segment1 = _INTL("\\ts[4]\\C[2]Land is the cradle of all\\n\\wt[5]We must ex\\wt[2]pand \\wt[2]its \\wt[2]sprawl")
when cmd_style
segment1 = _INTL("\\ts[4]\\C[2]Our uniforms are sleek\\n\\wt[5]Our style is \\wt[6]unique")
when cmd_strength
segment1 = _INTL("\\ts[4]\\C[2]No one can match our power\\n\\wt[5]We grow stronger \\wt[2]by \\wt[2]the \\wt[2]hour")
end
commands_confirm = [_INTL("Perfect"), _INTL("Let's try something else...")]
pbCallBubDown(2, event_id1) # Left
confirmed = pbMessage(segment1, commands_confirm) == 0
end
add_magma_song_segment(segment1)
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("That's pretty good!"))
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("The next line should talk about something that inspires us."))
cmd_leader = _INTL("Maxie")
cmd_land = _INTL("The land")
cmd_pokemon = _INTL("Pokémon")
commands = [cmd_leader, cmd_land, cmd_pokemon]
confirmed = false
while !confirmed
pbCallBubDown(2, event_id1) # Left
choice = pbMessage(_INTL("What should we sing about?"), commands)
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Hmm... How about this?"))
case commands[choice]
when cmd_leader
segment2 = _INTL("\\ts[4]\\C[2]Ma\\wt[2]xie's a visionary \\wt[5]\\nHis \\ts[2]intellect is \\wt[5]le\\wt[2]gen\\wt[2]da\\wt[4]ry")
when cmd_land
segment2 = _INTL("\\ts[4]\\C[2]The land is our domain\\wt[5]\\n\\ts[2]Magma flows \\wt[2]through \\wt[2]our \\wt[2]veins")
when cmd_pokemon
segment2 = _INTL("\\ts[4]\\C[2]Land Po\\wt[2]ké\\wt[2]mon by our side\\wt[5]\\nThe oceans \\ts[2]will soon sub\\wt[5]side")
end
commands_confirm = [_INTL("Perfect"), _INTL("Let's try something else...")]
pbCallBubDown(2, event_id1) # Left
confirmed = pbMessage(segment2, commands_confirm) == 0
end
add_magma_song_segment(segment2)
pbCallBubDown(2, event_id1) # Left
pbMessage(_INTL("Oh yeah that's pretty good."))
end
def build_magma_song_pt3(event_id1, event_id2)
confirmed = false
while !confirmed
pbCallBubUp(2, event_id2) # Right
pbMessage(_INTL("Now we only need an ending line. Do you have something in mind?"))
helpText = _INTL("The song's final line...")
line = pbEnterText(helpText, 2, 50)
pbCallBubUp(2, event_id2) # Right
commands = [_INTL("That's right!"), _INTL("Maybe not...")]
confirmed = pbMessage(_INTL("{1}... ?", line), commands) == 0
end
add_magma_song_segment(line)
end
def sing_magma_song
pbMEPlay("magma_theme_song")
lyrics = pbGet(VAR_MAGMA_SONG)
lyrics = [] unless lyrics.is_a?(Array)
for line in lyrics
pbMEPlay("magma_theme_song")
line = "\\ts[3]\\C[2]#{line}\\wtnp[20]"
pbCallBub(3)
pbMessage(line)
end
pbMEStop
end
def add_magma_song_segment(text)
current_song = pbGet(VAR_MAGMA_SONG)
current_song = [] unless current_song.is_a?(Array)
current_song << text
pbSet(VAR_MAGMA_SONG, current_song)
end
################################
def aquaCarvanhaQuestValidPokemon?(pokemon)
valid_species = isPartPokemon(pokemon, :ZUBAT) || isPartPokemon(pokemon, :GOLBAT) || isPartPokemon(pokemon, :CROBAT) ||
isPartPokemon(pokemon, :GEODUDE) || isPartPokemon(pokemon, :GRAVELER) || isPartPokemon(pokemon, :GOLEM)
is_water_type = pokemon.hasType?(:WATER)
echoln "#{pokemon.species}: valid species: #{valid_species}, waterType: #{is_water_type}"
return valid_species && is_water_type
end
# Check that there's 2 ZUBAT and 1 GEODUDE in party
def aquaCarvanhaPostValidation()
echoln pbGet(5)
nb_zubat = 0
nb_geodude = 0
target_nb_zubat = 2
target_nb_geodude = 1
$Trainer.party.each do |pokemon|
nb_zubat += 1 if isPartPokemon(pokemon, :ZUBAT) || isPartPokemon(pokemon, :GOLBAT) || isPartPokemon(pokemon, :CROBAT)
nb_geodude += 1 if isPartPokemon(pokemon, :GEODUDE) || isPartPokemon(pokemon, :GRAVELER) || isPartPokemon(pokemon, :GOLEM)
end
return nb_zubat == target_nb_zubat && nb_geodude == target_nb_geodude
end
@@ -0,0 +1,278 @@
#==============================================================================
# QuestMapPopup - Side panel listing quests at a map location
#==============================================================================
class QuestMapPopup
attr_reader :quests
attr_reader :panel_active
attr_reader :disposed
PANEL_WIDTH = 260 #220
PANEL_HEIGHT = 320
ITEM_HEIGHT = 52
MAX_VISIBLE = 5
FADE_SPEED = 40
OPACITY_SELECTED = 255
OPACITY_UNSELECTED=200
def initialize(quests, on_left, viewport, location_name = _INTL("Unknown Location"))
@quests = quests.sort_by { |q| q.type == :MAIN_QUEST ? 0 : 1 }
@on_left = on_left
@viewport = viewport
@index = 0
@scroll = 0 # index of topmost visible quest
@scroll_timer = 0
@scroll_delay = 6
@sprites = {}
@location_name = location_name
create_sprites
animate_in
end
def selected_quest
@quests[@index]
end
def run
set_selected(true)
refresh
loop do
break if @disposed
Graphics.update
Input.update
animate_arrows
if Input.trigger?(Input::B)
animate_out
dispose
set_selected(false)
Input.update
return nil
end
if Input.trigger?(Input::C)
animate_out
dispose
return @quests[@index]
end
if @scroll_timer > 0
@scroll_timer -= 1
else
if Input.press?(Input::DOWN)
move(:DOWN)
@scroll_timer = @scroll_delay
elsif Input.press?(Input::UP)
move(:UP)
@scroll_timer = @scroll_delay
end
end
end
end
def panel_x
@on_left ? 8 : (Graphics.width - PANEL_WIDTH - 8)
end
def create_sprites
@sprites["panel"] = IconSprite.new(0, 0, @viewport)
@sprites["panel"].setBitmap("Graphics/Pictures/map/quests_panel")
@sprites["panel"].x = panel_x
@sprites["panel"].y = (Graphics.height - PANEL_HEIGHT) / 2
@sprites["panel"].z = 110000
@sprites["panel"].opacity = 0
# Overlay bitmap for text
@sprites["text"] = BitmapSprite.new(PANEL_WIDTH, PANEL_HEIGHT, @viewport)
@sprites["text"].x = panel_x
@sprites["text"].y = (Graphics.height - PANEL_HEIGHT) / 2
@sprites["text"].z = 110001
@sprites["text"].opacity = 0
pbSetSystemFont(@sprites["text"].bitmap)
# Quest row sprites (buttons)
MAX_VISIBLE.times do |i|
# Background image sprite (selected / unselected)
bg = IconSprite.new(0, 0, @viewport)
bg.x = panel_x + 6
bg.y = (Graphics.height - PANEL_HEIGHT) / 2 + 36 + i * ITEM_HEIGHT
bg.z = 110002
bg.opacity = 0
@sprites["rowbg#{i}"] = bg
# Text/icon overlay bitmap
s = BitmapSprite.new(PANEL_WIDTH - 12, ITEM_HEIGHT - 4, @viewport)
pbSetSystemFont(s.bitmap)
s.x = panel_x + 6
s.y = (Graphics.height - PANEL_HEIGHT) / 2 + 36 + i * ITEM_HEIGHT
s.z = 110003
s.opacity = 0
@sprites["row#{i}"] = s
end
# Character icon sprites for each visible row
MAX_VISIBLE.times do |i|
ic = IconSprite.new(0, 0, @viewport)
ic.z = 110003
ic.opacity = 0
@sprites["icon#{i}"] = ic
end
# Up/down arrows
panel_top_y = (Graphics.height - PANEL_HEIGHT) / 2
create_arrow("uparrow",panel_top_y - 30)
create_arrow("downarrow",panel_top_y + PANEL_HEIGHT - 46)
refresh
end
def create_arrow(arrow_filename, y_position)
panel_center_x = panel_x + PANEL_WIDTH / 2
@sprites[arrow_filename] = AnimatedSprite.new("Graphics/Pictures/#{arrow_filename}", 8, 28, 40, 2, @viewport)
@sprites[arrow_filename].x = panel_center_x - 8
@sprites[arrow_filename].y = y_position
@sprites[arrow_filename].visible = false
@sprites[arrow_filename].z = @sprites["panel"].z+1
end
def refresh
return unless @sprites["text"]
text_bmp = @sprites["text"].bitmap
text_bmp.clear
pbDrawOutlineText(text_bmp, 0, 6, PANEL_WIDTH, 32, _INTL("{1} Quests", @location_name),
Color.new(255, 220, 100), Color.new(0, 0, 0), 1)
MAX_VISIBLE.times do |i|
qi = @scroll + i
row_bmp = @sprites["row#{i}"].bitmap
row_bmp.clear
if qi < @quests.size
quest = @quests[qi]
selected = (qi == @index) && @panel_active
if quest.type == :MAIN_QUEST
bg_path = "Graphics/Pictures/map/quests_row_main"
else
bg_path = "Graphics/Pictures/map/quests_row"
end
bg_path = selected \
? "#{bg_path}_selected"
: "#{bg_path}_unselected"
@sprites["rowbg#{i}"].setBitmap(bg_path)
@sprites["rowbg#{i}"].visible = true
# Quest name text (no background drawing needed here anymore)
pbDrawOutlineText(row_bmp, 44, 8, row_bmp.width - 44, row_bmp.height,
quest.name, quest.default_color, Color.new(0, 0, 0))
# Character icon
icon = @sprites["icon#{i}"]
begin
icon.setBitmap("Graphics/Characters/#{quest.sprite}")
icon.src_rect.width = (icon.bitmap.width / 4).round
icon.src_rect.height = (icon.bitmap.height / 4).round - 16
icon.src_rect.x = 0
icon.src_rect.y = 0
icon.x = panel_x - 16
icon.y = (Graphics.height - PANEL_HEIGHT) / 2 + 16 + i * ITEM_HEIGHT
icon.visible = true
rescue
icon.visible = false
end
else
@sprites["rowbg#{i}"].visible = false
@sprites["icon#{i}"].visible = false
end
end
@sprites["uparrow"].visible = @scroll > 0 if @sprites["uparrow"]
@sprites["downarrow"].visible = (@scroll + MAX_VISIBLE) < @quests.size if @sprites["downarrow"]
end
def move(dir)
if dir == :DOWN
return if @index >= @quests.size - 1
@index += 1
if @index >= @scroll + MAX_VISIBLE
@scroll += 1
end
else
return if @index <= 0
@index -= 1
if @index < @scroll
@scroll -= 1
end
end
refresh
end
def animate_in
@sprites["panel"].opacity = OPACITY_UNSELECTED
MAX_VISIBLE.times do |j|
@sprites["rowbg#{j}"].opacity = OPACITY_UNSELECTED
@sprites["row#{j}"].opacity = OPACITY_UNSELECTED
@sprites["icon#{j}"].opacity = OPACITY_UNSELECTED
end
# 12.times do |i|
# Graphics.update
# alpha_step = FADE_SPEED
# if i < 8
# @sprites["panel"].opacity = [@sprites["panel"].opacity + alpha_step, OPACITY_UNSELECTED].min
# end
# if i > 2
# @sprites["text"].opacity = [@sprites["text"].opacity + alpha_step, OPACITY_UNSELECTED].min
# MAX_VISIBLE.times do |j|
# @sprites["rowbg#{j}"].opacity = [@sprites["rowbg#{j}"].opacity + alpha_step, OPACITY_UNSELECTED].min
# @sprites["row#{j}"].opacity = [@sprites["row#{j}"].opacity + alpha_step, OPACITY_UNSELECTED].min
# @sprites["icon#{j}"].opacity = [@sprites["icon#{j}"].opacity + alpha_step, OPACITY_UNSELECTED].min
# end
# end
# end
end
def set_selected(selected)
@panel_active = selected
target = selected ? OPACITY_SELECTED : OPACITY_UNSELECTED
@sprites["panel"]&.opacity = target
@sprites["text"]&.opacity = target
MAX_VISIBLE.times do |j|
@sprites["rowbg#{j}"]&.opacity = target
@sprites["row#{j}"]&.opacity = target
@sprites["icon#{j}"]&.opacity = target
end
@sprites["uparrow"]&.visible = true
@sprites["downarrow"]&.visible = true
end
def animate_out
@disposed = true
@sprites["uparrow"]&.visible = false
@sprites["downarrow"]&.visible = false
8.times do
Graphics.update
@sprites["panel"]&.opacity -= FADE_SPEED
@sprites["text"]&.opacity -= FADE_SPEED
MAX_VISIBLE.times do |j|
@sprites["rowbg#{j}"]&.opacity -= FADE_SPEED
@sprites["row#{j}"]&.opacity -= FADE_SPEED
@sprites["icon#{j}"]&.opacity -= FADE_SPEED
end
end
end
@arrow_frame = 0
def animate_arrows
@sprites["uparrow"].visible=true
@sprites["downarrow"].visible=true
@sprites["uparrow"].play
@sprites["downarrow"].play
end
def dispose
@sprites.each_value { |s| s.dispose rescue nil }
@sprites.clear
end
end
@@ -0,0 +1,324 @@
def showQuestMap
QuestMap.new
end
class QuestMap < BetterRegionMap
attr_reader :reopen_map
QUEST_SIDE_ICON_PATH = "Graphics/Pictures/map/quest_icon"
QUEST_MAIN_ICON_PATH = "Graphics/Pictures/map/quest_icon_main"
QUEST_AQUA_ICON_PATH = "Graphics/Pictures/map/quest_icon_aqua"
QUEST_MAGMA_ICON_PATH = "Graphics/Pictures/map/quest_icon_magma"
QUEST_ROCKET_ICON_PATH = "Graphics/Pictures/map/quest_icon_rocket"
QUEST_COMPLETED_ICON_PATH = "Graphics/Pictures/map/quest_icon_completed"
def initialize
@quests = {}
@spots = {}
@popup = nil
@snapping = false
@previous_position = [0, 0]
@show_completed=false
@show_in_progress =true
super(nil, false, false, false, nil, nil, false)
end
def after_init_graphics
@window["player"].visible = false
end
def init_cursor_position(x, y)
super(x, y)
on_hover(*getPlayerPosition)
end
def initialize_quests_locations(show_in_progress, show_completed)
$Trainer.quests.each do |quest|
next if quest.completed && !show_completed
next if !quest.completed && !show_in_progress
position = [0, 0] # default
if quest.location_map_id
position = getTownMapFlyCoordinates(quest.location_map_id)
else
if DEFAULT_QUEST_MAP_LOCATIONS.include?(quest.id)
position = getTownMapFlyCoordinates(DEFAULT_QUEST_MAP_LOCATIONS[quest.id])
end
end
quests_at_location = @quests[position]
quests_at_location = [] if quests_at_location.nil?
quests_at_location << quest
@quests[position] = quests_at_location
@spots[position] = quests_at_location # Unused, but the map checks positions in there to see if it should snap to a new location
end
end
def add_map_icons
initialize_quests_locations(true, false)
@quests.each_key do |position|
quests_list = @quests[position]
if quests_list.all?(&:completed)
add_map_icon_at_position(position, position, QUEST_COMPLETED_ICON_PATH)
next
end
icon_path = QUEST_SIDE_ICON_PATH
has_rocket = false
has_magma = false
has_aqua = false
quests_list.each do |quest|
case quest.type
when :MAIN_QUEST
icon_path = QUEST_MAIN_ICON_PATH
break
when :ROCKET_QUEST then has_rocket = true
when :MAGMA_QUEST then has_magma = true
when :AQUA_QUEST then has_aqua = true
end
end
unless icon_path == QUEST_MAIN_ICON_PATH
if has_rocket then icon_path = QUEST_ROCKET_ICON_PATH
elsif has_magma then icon_path = QUEST_MAGMA_ICON_PATH
elsif has_aqua then icon_path = QUEST_AQUA_ICON_PATH
end
end
add_map_icon_at_position(position, position, icon_path)
end
end
def on_hover(x, y)
quests_at_pos = @quests[[x, y]]
if quests_at_pos && !quests_at_pos.empty?
snap_to_position(x, y)
show_popup(quests_at_pos)
else
hide_popup
end
end
def on_start_moving
end
def on_stop_moving
return if @snapping
x = $PokemonGlobal.regionMapSel[0]
y = $PokemonGlobal.regionMapSel[1]
if @quests.has_key?([x, y])
on_hover(x, y)
return
end
nearby_quest = find_quest_near_coordinates(x, y, 2)
if nearby_quest
@snapping = true
new_x, new_y = nearby_quest
if [new_x, new_y] != @position_before_moving
snap_to_position(new_x, new_y)
on_hover(new_x, new_y)
end
@snapping = false
end
end
def find_quest_near_coordinates(current_x, current_y, radius)
closest = nil
min_distance = Float::INFINITY
for new_x in current_x - radius..current_x + radius
for new_y in current_y - radius..current_y + radius
if @quests.has_key?([new_x, new_y])
distance = Math.sqrt((new_x - current_x) ** 2 + (new_y - current_y) ** 2)
if distance < min_distance
min_distance = distance
closest = [new_x, new_y]
end
end
end
end
return closest
end
def on_click(x, y)
return unless @popup
quest = @popup.run
if quest
@popup = nil
@sprites.visible = false
@window.visible = false
Questlog.new(open_quest: quest, from_map: true)
@sprites.visible = true
@window.visible = true
@viewport.visible = true
@viewport2.visible = true
@mapvp.visible = true
@mapoverlayvp.visible = true
Graphics.update
x, y = $PokemonGlobal.regionMapSel[0], $PokemonGlobal.regionMapSel[1]
on_hover(x, y)
#@popup&.set_selected(true)
@popup&.refresh
end
end
def show_popup(quests)
return unless @sprites["cursor"]
return if @popup&.quests == quests #popup already active
return if @popup && @popup.panel_active
location_name = get_current_location_name
hide_popup
on_right_half = @sprites["cursor"].x > (Graphics.width / 2)
@popup = QuestMapPopup.new(quests, on_right_half, @viewport2, location_name)
pbWait(4)
end
def should_exit_confirm?
return false
end
def on_exit_main
@reopen_map = false
if @switch_to_questlog
@switch_to_questlog = false
@reopen_map = true
end
end
def should_exit_cancel?
return true if @switch_to_questlog
return false if @popup && @popup.panel_active
return Input.trigger?(Input::B)
end
def on_update
if Input.trigger?(Input::L) || Input.trigger?(Input::R)
pbSEPlay("GUI storage show party panel")
$Trainer.pokenav.last_opened_quest_mode = :LIST
@switch_to_questlog = true
end
end
def hide_popup
return unless @popup
@popup.animate_out
@popup.dispose
@popup = nil
end
def dispose
hide_popup
super
end
def update_text_at_location(location)
current_position = [$PokemonGlobal.regionMapSel[0], $PokemonGlobal.regionMapSel[1]]
quests_at_location = @quests[current_position]
nb_quests_at_position = 0
nb_quests_at_position = @quests[current_position].length if quests_at_location
text = ""
text = pbGetMessageFromHash(MessageTypes::PlaceNames, location[2]) if location
nb_quests_text = ""
if nb_quests_at_position > 1
nb_quests_text = _INTL("{1} quests in progress", nb_quests_at_position)
elsif nb_quests_at_position > 0
nb_quests_text = _INTL("{1} quest in progress", nb_quests_at_position)
end
@sprites["txt"].draw([
[_INTL("Quest Log"), 24, -8, 0, Color.new(255, 255, 255), Color.new(0, 0, 0)],
[_INTL("L/R : LIST"), 360, -8, 0, Color.new(255, 255, 255), Color.new(0, 0, 0)],
[text, 16, 344, 0, Color.new(255, 255, 255), Color.new(0, 0, 0)],
[nb_quests_text, 496, 344, 1, Color.new(255, 255, 255), Color.new(0, 0, 0)],
], true)
end
def open_quest_detail(quest)
dispose
Questlog.new(open_quest: quest)
end
end
#For quests recorded before QuestMap existed, so that they don't show up at [0,0]
DEFAULT_QUEST_MAP_LOCATIONS = {
# Main quests
"main_dad" => MAP_PETALBURG,
"main_wally" => MAP_PETALBURG,
"main_gym_1" => MAP_RUSTBORO,
"main_gym_2" => MAP_DEWFORD,
"main_gym_3" => MAP_MAUVILLE,
"main_gym_4" => MAP_LAVARIDGE,
"main_gym_5" => MAP_PETALBURG,
"main_gym_6" => MAP_FORTREE,
"main_gym_7" => MAP_MOSSDEEP,
"main_gym_8" => MAP_SOOTOPOLIS,
"main_league" => MAP_LEAGUE,
"main_stolen_parts" => MAP_RUSTBORO,
"main_steven_letter" => MAP_DEWFORD,
"main_devon_parts" => MAP_SLATEPORT,
"slateport_team_aqua" => MAP_AQUA_CAMP,
"slateport_team_magma"=> MAP_MAGMA_CAMP,
"evergrande_trumpet" => MAP_EVERGRANDE,
"route_102_rematch" => MAP_ROUTE_102,
"route104_rivalWeather" => MAP_ROUTE_104,
"route104_oricorio" => MAP_ROUTE_104,
"route104_oricorio_forms" => MAP_ROUTE_104,
"route104_allergic" => MAP_ROUTE_104,
"route109_tanning" => MAP_ROUTE_109,
"route109_seahouse" => MAP_ROUTE_109,
"route109_beachball" => MAP_ROUTE_109,
"route110_bike" => MAP_ROUTE_110,
"route111_winstrate" => MAP_ROUTE_111,
"route115_secretBase" => MAP_ROUTE_115,
"route116_glasses" => MAP_ROUTE_116,
# Town/City quests
"petalburg_berry" => MAP_PETALBURG,
"rustboro_whismur" => MAP_RUSTBORO,
"rustboro_shiny" => MAP_RUSTBORO,
"rustboro_trash" => MAP_RUSTBORO,
"rustboro_fusion" => MAP_RUSTBORO,
"dewford_fishing" => MAP_DEWFORD,
"mauville_quests_1" => MAP_MAUVILLE,
"mauville_quests_2" => MAP_MAUVILLE,
"mauville_quests_3" => MAP_MAUVILLE,
"mauville_quests_4" => MAP_MAUVILLE,
"mauville_quests_5" => MAP_MAUVILLE,
"mauville_quests_6" => MAP_MAUVILLE,
"mauville_quests_7" => MAP_MAUVILLE,
"verdanturf_shroomish" => MAP_VERDANTURF,
"verdanturf_nurse" => MAP_VERDANTURF,
# Dungeon/Area quests
"petalburgwoods_spores" => MAP_PETALBURG_WOODS,
"rusturf_trumpet" => MAP_RUSTURF_TUNNEL,
# Team Magma quests
"magma_camp_attack" => MAP_MAGMA_CAMP,
"magma_slugma_eggs" => MAP_MAGMA_CAMP,
"magma_help_grunts" => MAP_MAGMA_CAMP,
"magma_numel" => MAP_MAGMA_CAMP,
"magma_graffiti" => MAP_MAGMA_CAMP,
"magma_song" => MAP_MAGMA_CAMP,
# Team Aqua quests
"aqua_camp_attack" => MAP_AQUA_CAMP,
"aqua_wailmer_eggs" => MAP_AQUA_CAMP,
"aqua_help_grunts" => MAP_AQUA_CAMP,
"aqua_carvanha" => MAP_AQUA_CAMP,
"aqua_graffiti" => MAP_AQUA_CAMP,
"aqua_song" => MAP_AQUA_CAMP,
# Mauville team quests
"mauville_magma" => MAP_MAUVILLE,
"mauville_aqua" => MAP_MAUVILLE,
}