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
@@ -41,9 +41,15 @@ def Kernel.getItemNamesAsString(list)
end
def getCurrentLevelCap()
current_max_level = Settings::LEVEL_CAPS[$Trainer.badge_count]
if Settings::KANTO
current_max_level = Settings::LEVEL_CAPS_KANTO[$Trainer.badge_count]
else
current_max_level = Settings::LEVEL_CAPS_HOENN[$Trainer.badge_count]
end
current_max_level *= Settings::HARD_MODE_LEVEL_MODIFIER if $game_switches[SWITCH_GAME_DIFFICULTY_HARD]
return current_max_level.floor
current_max_level *= Settings::EASY_MODE_LEVEL_MODIFIER if $game_switches[SWITCH_GAME_DIFFICULTY_EASY] && Settings::HOENN
return current_max_level&.floor || 100
end
def pokemonExceedsLevelCap(pokemon)
@@ -52,13 +58,8 @@ def pokemonExceedsLevelCap(pokemon)
return pokemon.level >= current_max_level
end
def get_spritecharacter_for_event(event_id)
for sprite in $scene.spriteset.character_sprites
if sprite.character.id == event_id
return sprite
end
end
end
def setForcedAltSprites(forcedSprites_map)
$PokemonTemp.forced_alt_sprites = forcedSprites_map
@@ -17,9 +17,14 @@ def pbCheckPokemonIconFiles(speciesID, egg = false, dna = false)
return pbResolveBitmap("Graphics/Icons/iconDNA.png")
end
def addShinyStarsToGraphicsArray(imageArray, xPos, yPos, shinyBody, shinyHead, debugShiny, srcx = nil, srcy = nil, width = nil, height = nil,
def addShinyStarsToGraphicsArray(imageArray, xPos, yPos, shinyBody, shinyHead, debugShiny, radarShiny, srcx = nil, srcy = nil, width = nil, height = nil,
showSecondStarUnder = false, showSecondStarAbove = false)
color = debugShiny ? Color.new(0, 0, 0, 255) : nil
if debugShiny == true
color = debugShiny ? Color.new(0, 0, 0, 255) : nil
end
if radarShiny == true
color = radarShiny ? Color.new(0, 0, 255, 255) : nil
end
imageArray.push(["Graphics/Pictures/shiny", xPos, yPos, srcx, srcy, width, height, color])
if shinyBody && shinyHead
if showSecondStarUnder
@@ -38,9 +43,10 @@ def addShinyStarsToGraphicsArray(imageArray, xPos, yPos, shinyBody, shinyHead, d
end
def pbBitmap(path)
if !pbResolveBitmap(path).nil?
bmp = RPG::Cache.load_bitmap_path(path)
bmp.storedPath = path
resolved_path = pbResolveBitmap(path)
if !resolved_path.nil?
bmp = RPG::Cache.load_bitmap_path(resolved_path)
bmp.storedPath = resolved_path
else
p "Image located at '#{path}' was not found!" if $DEBUG
bmp = Bitmap.new(1, 1)
@@ -48,8 +54,6 @@ def pbBitmap(path)
return bmp
end
# if need to play animation from event route
def playAnimation(animationId, x = nil, y = nil)
return if !$scene.is_a?(Scene_Map)
@@ -76,4 +80,4 @@ def showPicture(path,x,y,viewport_x=(Graphics.width / 4), viewport_y=0)
return viewport
rescue
end
end
end
@@ -81,4 +81,21 @@ def getArceusPlateType(heldItem)
else
return :NORMAL
end
end
def hasFishingRod()
return hasItem?(:OLDROD) || hasItem?(:GOODROD) || hasItem?(:SUPERROD)
end
def list_all_item_names()
names = []
GameData::Item.list_all.each do |item|
names << item[1].name
end
return names
end
def hasItem?(item)
return $PokemonBag.pbQuantity(item) >= 1
end
@@ -0,0 +1,422 @@
def obtainBadgeMessage(badgeName)
Kernel.pbMessage(_INTL("\\me[Badge get]{1} obtained the {2}!", $Trainer.name, badgeName))
end
def pbSpendMoney(amount,showMessage=false,msgwindow=nil, goldwindow=nil)
pbReceiveMoney(0- amount,showMessage,msgwindow,goldwindow,)
end
def pbReceiveMoney(amount, showMessage=true, msgwindow=nil, goldwindow=nil)
msgwindow = pbCreateMessageWindow(nil) unless msgwindow
goldwindow = pbDisplayGoldWindow(msgwindow) unless goldwindow
if showMessage
if amount >= 0
pbMessage(_INTL("{1} received ${2}!", $Trainer.name, amount.to_s_formatted))
else
pbMessage(_INTL("{1} spent ${2}!", $Trainer.name, amount.abs.to_s_formatted))
end
end
# Show current money initial pause
15.times do
Graphics.update
Input.update
pbUpdateSceneMap
msgwindow.update
goldwindow.update
end
oldMoney = $Trainer.money
targetMoney = oldMoney + amount
step = [(amount.abs / 15), 1].max
current = oldMoney
# Count up/down animation
while (amount >= 0 ? current < targetMoney : current > targetMoney)
current += (amount >= 0 ? step : -step)
current = targetMoney if (amount >= 0 ? current > targetMoney : current < targetMoney)
color = amount >= 0 ? "00FF00" : "FF0000"
sign = amount >= 0 ? "+" : "-"
goldwindow.text = "Money:\n<ar>$#{current.to_s_formatted}</ar>\n<ar><c3=#{color}>#{sign}$#{amount.abs.to_s_formatted}</c3></ar>"
goldwindow.text = "Money:\n<ar>$#{current.to_s_formatted}</ar>\n<ar><c3=#{color}>#{sign}$#{amount.abs.to_s_formatted}</c3></ar>"
goldwindow.resizeToFit(goldwindow.text, Graphics.width)
goldwindow.width = 160 if goldwindow.width <= 160
pbSEPlay("Mart buy item") if (amount >= 0 ? current < targetMoney : current > targetMoney)
Graphics.update
Input.update
pbUpdateSceneMap
msgwindow.update
goldwindow.update
end
$Trainer.money = targetMoney
# Final display text
goldwindow.text = "Money:\n<ar>$#{targetMoney.to_s_formatted}</ar>"
goldwindow.resizeToFit(goldwindow.text, Graphics.width)
goldwindow.width = 160 if goldwindow.width <= 160
# Show final balance pause
20.times do
Graphics.update
Input.update
pbUpdateSceneMap
msgwindow.update
goldwindow.update
end
goldwindow.dispose
pbDisposeMessageWindow(msgwindow)
end
def pbSpendCosmeticMoney(amount,showMessage=false,msgwindow=nil, goldwindow=nil)
pbReceiveCosmeticsMoney(0- amount,showMessage,msgwindow,goldwindow,)
end
def pbReceiveCosmeticsMoney(amount, showMessage=true, msgwindow=nil, goldwindow=nil)
msgwindow = pbCreateMessageWindow(nil) unless msgwindow
goldwindow = pbDisplayCosmeticsMoneyWindow(msgwindow) unless goldwindow
if showMessage
if amount >= 0
pbMessage(_INTL("{1} received {2} {3}!", $Trainer.name, amount.to_s_formatted, COSMETIC_CURRENCY_NAME))
else
pbMessage(_INTL("{1} spent {2} {3}!", $Trainer.name, amount.abs.to_s_formatted, COSMETIC_CURRENCY_NAME))
end
end
# Show current cosmetic money initial pause
15.times do
Graphics.update
Input.update
pbUpdateSceneMap
msgwindow.update
goldwindow.update
end
oldMoney = $Trainer.cosmetics_money || 0
targetMoney = oldMoney + amount
step = [(amount.abs / 15), 1].max
current = oldMoney
# Count up/down animation
while (amount >= 0 ? current < targetMoney : current > targetMoney)
current += (amount >= 0 ? step : -step)
current = targetMoney if (amount >= 0 ? current > targetMoney : current < targetMoney)
color = amount >= 0 ? "00FF00" : "FF0000"
sign = amount >= 0 ? "+" : "-"
goldwindow.text = _INTL(
"{1}:\n<ar>{2}</ar>\n<ar><c3={3}>{4} {5}</c3></ar>",
COSMETIC_CURRENCY_NAME,
current.to_s_formatted,
color,
sign,
amount.abs.to_s_formatted
)
pbSEPlay("Mart buy item") if amount >= 0 ? current < targetMoney : current > targetMoney
Graphics.update
Input.update
pbUpdateSceneMap
msgwindow.update
goldwindow.update
end
$Trainer.cosmetics_money = targetMoney
# Final display text
goldwindow.text = _INTL(
"{1}:\n<ar>{2}</ar>",
COSMETIC_CURRENCY_NAME,
targetMoney.to_s_formatted
)
goldwindow.resizeToFit(goldwindow.text, Graphics.width)
goldwindow.width = 160 if goldwindow.width <= 160
# Show final balance pause
20.times do
Graphics.update
Input.update
pbUpdateSceneMap
msgwindow.update
goldwindow.update
end
goldwindow.dispose
pbDisposeMessageWindow(msgwindow)
end
def promptCaughtPokemonAction(pokemon)
pickedOption = false
return pbStorePokemon(pokemon) if !$Trainer.party_full?
return promptKeepOrRelease(pokemon) if isOnPinkanIsland() && !$game_switches[SWITCH_PINKAN_FINISHED]
while !pickedOption
cmd_swap = _INTL("Add to your party")
cmd_fuse = _INTL("Fuse in party")
cmd_pc = _INTL("Store to PC")
options = []
options << cmd_swap
if !pokemon.isFusion? && playerHasFusionItems && hasUnfusedPokemonInParty(false)
options << cmd_fuse
end
options << cmd_pc
command = pbMessage(_INTL("\\ts[]Your team is full!"), options, options.length)
case options[command]
when cmd_swap
if swapCaughtPokemon(pokemon)
pickedOption = true
end
when cmd_fuse
if fuseCaughtPokemon(pokemon)
pickedOption = true
end
else
# STORE
pbStorePokemon(pokemon)
pickedOption = true
end
end
end
def promptKeepOrRelease(pokemon)
pickedOption = false
while !pickedOption
command = pbMessage(_INTL("\\ts[]Your team is full!"),
[_INTL("Release a party member"), _INTL("Release this {1}",pokemon.name),], 2)
case command
when 0 # SWAP
if swapReleaseCaughtPokemon(pokemon)
pickedOption = true
end
else
pickedOption = true
end
end
end
def fuseCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isFusion? rescue false) &&
poke.hp > 0
})
partyPosition = pbGet(1)
return false if partyPosition == -1
splicerItem = selectSplicer()
return unless splicerItem
selected = $Trainer.party[partyPosition].clone
selectedHead, fusion_pif_sprite = selectFusion(caughtPokemon,selected)
return false unless selectedHead && fusion_pif_sprite
if (pbConfirmMessage(_INTL("Fuse the newly obtained {1} with {2}?", caughtPokemon.name, selected.name)))
if selectedHead == caughtPokemon
pbRemovePokemonAt(partyPosition)
pbAddPokemonSilent(caughtPokemon)
pbFuse(caughtPokemon, selected, splicerItem, fusion_pif_sprite)
else
actualPartyPokemon = $Trainer.party[partyPosition] # real reference, not clone
pbFuse(actualPartyPokemon, caughtPokemon, splicerItem, fusion_pif_sprite)
end
$PokemonBag.pbDeleteItem(splicerItem) if splicerItem == :DNASPLICERS || splicerItem == :SUPERSPLICERS
return true
end
return false
end
# def pbChoosePokemon(variableNumber, nameVarNumber, ableProc = nil, allowIneligible = false)
def swapCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isShadow? rescue false)
})
index = pbGet(1)
return false if index == -1
$PokemonStorage.pbStoreCaught($Trainer.party[index])
pbRemovePokemonAt(index)
pbStorePokemon(caughtPokemon)
tmp = $Trainer.party[index]
$Trainer.party[index] = $Trainer.party[-1]
$Trainer.party[-1] = tmp
return true
end
def swapReleaseCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isShadow? rescue false)
})
index = pbGet(1)
return false if index == -1
releasedPokemon = $Trainer.party[index]
pbMessage(_INTL("{1} was released.",releasedPokemon.name))
pbRemovePokemonAt(index)
pbStorePokemon(caughtPokemon)
tmp = $Trainer.party[index]
$Trainer.party[index] = $Trainer.party[-1]
$Trainer.party[-1] = tmp
return true
end
def select_any_pokemon()
commands = []
for dex_num in 1..NB_POKEMON
species = getPokemon(dex_num)
commands.push([dex_num - 1, species.real_name, species.id])
end
return pbChooseList(commands, 0, nil, 1)
end
# chosen pokemon is returned with this format:
#[[boxID, boxPosition],pokemon]
def pbChoosePokemonPC(positionVariableNumber, pokemonVarNumber, ableProc = nil)
chosen = nil
pokemon = nil
pbFadeOutIn {
scene = PokemonStorageScene.new
screen = PokemonStorageScreen.new(scene, $PokemonStorage)
screen.setFilter(ableProc) if ableProc
chosen = screen.choosePokemon
pokemon = $PokemonStorage[chosen[0]][chosen[1]] if chosen
scene.pbCloseBox
}
pbSet(positionVariableNumber, chosen)
pbSet(pokemonVarNumber, pokemon)
end
def set_player_birthday
date = selectDate(_INTL("Your birthday is on"))
$Trainer.birth_day = date.day
$Trainer.birth_month = date.month
end
def selectDate(confirm_text = _INTL("You chose "))
months_nb_days = {
:JANUARY => 31,
:FEBRUARY => 29,
:MARCH => 31,
:APRIL => 30,
:MAY => 31,
:JUNE => 30,
:JULY => 31,
:AUGUST => 31,
:SEPTEMBER => 30,
:OCTOBER => 31,
:NOVEMBER => 30,
:DECEMBER => 31,
}
month_names = {
:JANUARY => _INTL("January"),
:FEBRUARY => _INTL("February"),
:MARCH => _INTL("March"),
:APRIL => _INTL("April"),
:MAY => _INTL("May"),
:JUNE => _INTL("June"),
:JULY => _INTL("July"),
:AUGUST => _INTL("August"),
:SEPTEMBER => _INTL("September"),
:OCTOBER => _INTL("October"),
:NOVEMBER => _INTL("November"),
:DECEMBER => _INTL("December"),
}
pbMessage(_INTL("Which month?"))
selected = false
while !selected
chosen_month_index = optionsMenu(month_names.values)
month = month_names.keys[chosen_month_index]
nb_days = months_nb_days[month]
numberParams = ChooseNumberParams.new
numberParams.setRange(1,nb_days)
numberParams.setDefaultValue(1)
chosen_day = pbMessageChooseNumber(_INTL("Which day?"),numberParams)
chosen_month_name = month_names[month]
if pbConfirmMessage(_INTL("{1} \\C[1]{2} {3}\\C[0]. Is that correct?",confirm_text, chosen_month_name,chosen_day))
birthday = Time.new(2000,chosen_month_index+1,chosen_day)
return birthday
end
end
end
# Helper method to wrap text into multiple lines
def wrap_text(text, bitmap, max_width)
words = text.split(" ")
lines = []
line = ""
words.each do |word|
test_line = line.empty? ? word : "#{line} #{word}"
if bitmap.text_size(test_line).width > max_width
lines << line
line = word
else
line = test_line
end
end
lines << line unless line.empty?
return lines
end
def pbColor(color)
# Mix your own colors: http://www.rapidtables.com/web/color/RGB_Color.htm
return Color.new(0, 0, 0) if color == :BLACK
return Color.new(255, 255, 255) if color == :WHITE
return Color.new(255, 115, 115) if color == :LIGHTRED
return Color.new(245, 11, 11) if color == :RED
return Color.new(164, 3, 3) if color == :DARKRED
return Color.new(47, 46, 46) if color == :DARKGREY
return Color.new(47, 46, 46) if color == :DARKGREY
return Color.new(100, 92, 92) if color == :LIGHTGREY
return Color.new(226, 104, 250) if color == :PINK
return Color.new(243, 154, 154) if color == :PINKTWO
return Color.new(255, 160, 50) if color == :GOLD
return Color.new(255, 186, 107) if color == :LIGHTORANGE
return Color.new(95, 54, 6) if color == :BROWN
return Color.new(122, 76, 24) if color == :LIGHTBROWN
return Color.new(255, 246, 152) if color == :LIGHTYELLOW
return Color.new(242, 222, 42) if color == :YELLOW
return Color.new(80, 111, 6) if color == :DARKGREEN
return Color.new(154, 216, 8) if color == :GREEN
return Color.new(197, 252, 70) if color == :LIGHTGREEN
return Color.new(74, 146, 91) if color == :FADEDGREEN
return Color.new(6, 128, 92) if color == :DARKLIGHTBLUE
return Color.new(18, 235, 170) if color == :LIGHTBLUE
return Color.new(139, 247, 215) if color == :SUPERLIGHTBLUE
return Color.new(35, 203, 255) if color == :BLUE
return Color.new(3, 44, 114) if color == :DARKBLUE
return Color.new(7, 3, 114) if color == :SUPERDARKBLUE
return Color.new(63, 6, 121) if color == :DARKPURPLE
return Color.new(113, 16, 209) if color == :PURPLE
return Color.new(130, 50, 200) if color == :LIGHTPURPLE
return Color.new(219, 183, 37) if color == :ORANGE
return Color.new(255, 255, 255, 0) if color == :INVISIBLE
return MessageConfig::LIGHT_TEXT_MAIN_COLOR if color == :LIGHT_TEXT_MAIN_COLOR
return MessageConfig::LIGHT_TEXT_SHADOW_COLOR if color == :LIGHT_TEXT_SHADOW_COLOR
return MessageConfig::DARK_TEXT_MAIN_COLOR if color == :DARK_TEXT_MAIN_COLOR
return MessageConfig::DARK_TEXT_SHADOW_COLOR if color == :DARK_TEXT_SHADOW_COLOR
return Color.new(255, 255, 255)
end
def isDarkMode
return $Trainer&.pokenav&.darkMode
end
@@ -11,9 +11,9 @@ end
def getPlayerDefaultName(gender)
if gender == GENDER_MALE
return Settings::GAME_ID == :IF_HOENN ? "Brendan" : "Red"
return Settings::GAME_ID == :IF_HOENN ? pbGetMessageFromHash(MessageTypes::TrainerNames, "Brendan") : _INTL("Red")
else
return Settings::GAME_ID == :IF_HOENN ? "May" : "Green"
return Settings::GAME_ID == :IF_HOENN ? pbGetMessageFromHash(MessageTypes::TrainerNames, "May") : _INTL("Green")
end
end
@@ -25,7 +25,7 @@ def getDefaultClothes(gender)
end
end
def getDefaultHat(gender)
def getDefaultHat(gender=getPlayerGenderId())
if gender == GENDER_MALE
return Settings::GAME_ID == :IF_HOENN ? HAT_BRENDAN : DEFAULT_OUTFIT_MALE
else
@@ -51,26 +51,28 @@ def setupStartingOutfit()
default_hair_male = getDefaultHair(GENDER_MALE)
default_hair_female = getDefaultHair(GENDER_FEMALE)
$Trainer.hat = nil
$Trainer.clothes = STARTING_OUTFIT
unlock_easter_egg_hats()
gender = pbGet(VAR_TRAINER_GENDER)
if gender == GENDER_FEMALE
$Trainer.unlock_clothes(default_clothes_female, true)
$Trainer.unlock_hat(default_hat_female, true)
$Trainer.unlock_hat(default_hat_female, true) unless Settings::HOENN
$Trainer.hair = "3_" + default_hair_female if !$Trainer.hair # when migrating old savefiles
$Trainer.clothes = default_clothes_female
elsif gender == GENDER_MALE
$Trainer.unlock_clothes(default_clothes_male, true)
$Trainer.unlock_hat(default_hat_male, true)
echoln $Trainer.hair
$Trainer.unlock_hat(default_hat_male, true) unless Settings::HOENN
$Trainer.hair = ("3_" + default_hair_male) if !$Trainer.hair # when migrating old savefiles
echoln $Trainer.hair
$Trainer.clothes = default_clothes_male
end
$Trainer.unlock_hair(default_hair_male, true)
$Trainer.unlock_hair(default_hair_female, true)
$Trainer.unlock_clothes(STARTING_OUTFIT, true)
$Trainer.hat = nil
if Settings::KANTO
$Trainer.clothes = STARTING_OUTFIT
end
end
def give_date_specific_hats()
@@ -94,6 +96,18 @@ def give_date_specific_hats()
end
end
def check_obtain_hat_after_battle(species)
hat_chance = 1
if rand(1..100) <= hat_chance
hat = getHatForPokemon(species)
if hat
obtainHat(hat)
end
end
end
def qmarkMaskCheck()
if $Trainer.seen_qmarks_sprite
unless hasHat?(HAT_QMARKS)
@@ -123,42 +137,83 @@ def purchaseDyeKitMenu(hats_kit_price = 0, clothes_kit_price = 0)
return
end
pbCallBub(2, @event_id)
pbMessage(_INTL("\\GWelcome! Are you interested in dyeing your outfits different colours?"))
pbMessage(_INTL("Welcome! Are you interested in dyeing your outfits different colors?"))
pbCallBub(2, @event_id)
pbMessage(_INTL("I make handy \\C[1]Dye Kits\\C[0] from my Smeargle's paint that can be used to dye your outfits any color you want!"))
pbCallBub(2, @event_id)
pbMessage(_INTL("\\GWhat's more is that it's reusable so you can go completely wild with it if you want! Are you interested?"))
pbMessage(_INTL("What's more is that it's reusable, so you can go completely wild with it if you want! Are you interested?"))
msgwindow = pbCreateMessageWindow(nil)
pbMessageDisplay(msgwindow, _INTL("Which dye kit would you like to purchase?"))
if Settings::HOENN
money = $Trainer.cosmetics_money
goldwindow = pbDisplayCosmeticsMoneyWindow(msgwindow,300)
else
money = $Trainer.money
goldwindow = pbDisplayGoldWindow(msgwindow,300)
end
choice = optionsMenu(commands, commands.length)
case commands[choice]
when command_hats
if $Trainer.money < hats_kit_price
if money < hats_kit_price
pbCallBub(2, @event_id)
pbMessage(_INTL("Oh, you don't have enough money..."))
goldwindow.dispose
return
end
pbMessage(_INTL("\\G\\PN purchased the dye kit."))
$Trainer.money -= hats_kit_price
pbSEPlay("SlotsCoin")
purchaseWindowAnimation(hats_kit_price,msgwindow,goldwindow)
Kernel.pbReceiveItem(:HATSDYEKIT)
pbCallBub(2, @event_id)
pbMessage(_INTL("\\GHere you go! Have fun dyeing your hats!"))
pbMessage(_INTL("Here you go! Have fun dyeing your hats!"))
when command_clothes
if $Trainer.money < clothes_kit_price
if money < clothes_kit_price
pbCallBub(2, @event_id)
pbMessage(_INTL("Oh, you don't have enough money..."))
goldwindow.dispose
return
end
pbMessage(_INTL("\\G\\PN purchased the dye kit."))
$Trainer.money -= clothes_kit_price
pbSEPlay("SlotsCoin")
#pbMessage(_INTL("\\PN purchased the dye kit."))
purchaseWindowAnimation(clothes_kit_price,msgwindow,goldwindow)
Kernel.pbReceiveItem(:CLOTHESDYEKIT)
pbCallBub(2, @event_id)
pbMessage(_INTL("\\GHere you go! Have fun dyeing your clothes!"))
pbMessage(_INTL("Here you go! Have fun dyeing your clothes!"))
end
pbCallBub(2, @event_id)
pbMessage(_INTL("You can use \\C[1]Dye Kits\\C[0] at any time when you change clothes."))
msgwindow.dispose
goldwindow.dispose
end
def purchaseWindowAnimation(price, msgwindow,goldwindow)
if Settings::HOENN
pbSpendCosmeticMoney(price,false,msgwindow,goldwindow)
else
pbSpendMoney(price,false,msgwindow,goldwindow)
end
msgwindow.dispose
goldwindow.dispose
end
def get_hat_contest_tags(hat_id)
hat = $PokemonGlobal.hats_data[hat_id]
return hat&.contest_condition
end
def get_clothes_contest_tags(clothes_id)
clothes = $PokemonGlobal.clothes_data[clothes_id]
return clothes&.contest_condition
end
def isWearingTeamAquaOutfit()
return false if !$game_switches[SWITCH_JOINED_TEAM_AQUA]
return isWearingClothes(CLOTHES_TEAM_AQUA_F) || isWearingClothes(CLOTHES_TEAM_AQUA_M)
end
def isWearingTeamMagmaOutfit()
return false if !$game_switches[SWITCH_JOINED_TEAM_MAGMA]
return isWearingClothes(CLOTHES_TEAM_MAGMA_M) || isWearingClothes(CLOTHES_TEAM_MAGMA_F)
end
@@ -1,6 +1,7 @@
def pbAddPokemonID(pokemon_id, level = 1, see_form = true, skip_randomize = false)
return false if !pokemon_id
skip_randomize = true if $game_switches[SWITCH_CHOOSING_STARTER] # when choosing starters
skip_randomize = true if $game_switches[SWITCH_DONT_RANDOMIZE]
if pbBoxesFull?
pbMessage(_INTL("There's no more room for Pokémon!\1"))
pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
@@ -165,7 +166,7 @@ def isKalosPokemon(species)
[327, 328, 329, 339, 371, 372, 417, 418,
425, 426, 438, 439, 440, 441, 444, 445, 446,
456, 461, 462, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487,
489, 490, 491, 492, 500,
489, 490, 491, 492, 500, 571, 572,
]
return list.include?(dexNum) || list.include?(head_dex) || list.include?(body_dex)
@@ -182,8 +183,9 @@ def isUnovaPokemon(species)
362, 363, 364, 365, 366, 367, 368, 369, 374, 375, 376, 377,
397, 398, 399, 406, 407, 408, 409, 410, 411, 412, 413, 414,
415, 416, 419, 420,
422, 423, 424, 434, 345,
422, 423, 424, 434, 435,
466, 467, 494, 493,
566, 567, 568, 569,570,
]
return list.include?(dexNum) || list.include?(head_dex) || list.include?(body_dex)
end
@@ -199,7 +201,7 @@ def isSinnohPokemon(species)
295, 296, 297, 298, 299, 305, 306, 307, 308, 315, 316, 317,
318, 319, 320, 321, 322, 323, 324, 326, 332, 343, 344, 345,
346, 347, 352, 353, 354, 358, 383, 384, 388, 389, 400, 402,
403, 429, 468]
403, 429, 468, 573, 574, 575, 576]
return list.include?(dexNum) || list.include?(head_dex) || list.include?(body_dex)
end
@@ -302,8 +304,9 @@ def getBasePokemonID(pokemon, body = true)
return head.to_i
end
def getGenericPokemonCryText(pokemonSpecies)
case pokemonSpecies
def getGenericPokemonCryText(dex_number)
return unless dex_number.is_a?(Integer)
case dex_number
when 25
return "Pika!"
when 16, 17, 18, 21, 22, 144, 145, 146, 227, 417, 418, 372 # birds
@@ -380,4 +383,26 @@ end
def has_species_or_fusion?(species, form = -1)
return $Trainer.pokemon_party.any? { |p| p && p.isSpecies?(species) || p.isFusionOf(species) }
end
def delete_party_pokemon_multi(indexes=[],safe=true)
indexes.sort.reverse_each do |i|
echoln "Deleting #{$Trainer.party[i].name} (index #{i})"
if safe
$Trainer.remove_pokemon_at_index(i)
else
#Doesn't check if the player has at least 1 pokemon left
$Trainer.party.delete_at(i)
end
end
end
def format_pokemon_names(species_list=[])
names_list = []
species_list.each do |species|
species_data = GameData::Species.get(species)
names_list << species_data.name
end
return names_list.join(", ")
end
@@ -228,4 +228,51 @@ def fix_missing_infinite_splicers
if obtained_upgraded_infinite_splicers && pbQuantity(:INFINITESPLICERS2) <= 0
pbReceiveItem(:INFINITESPLICERS2)
end
end
#Called from the fix game npc common event.
# Would be nice to migrate all the stuff in there over here
SWITCH_HOENN_GOT_POKEBALLS = 2018
SWITCH_HOENN_BEAT_RIVAL_RT_110 = 2116
def fixStuff
if Settings::HOENN
if $game_switches[SWITCH_HOENN_GOT_POKEBALLS]
$Trainer.install_app(:QUESTS) unless $Trainer.pokenav.has_app(:QUESTS)
$Trainer.install_app(:MAP) unless $Trainer.pokenav.has_app(:MAP)
$Trainer.install_app(:DAYNIGHT) unless $Trainer.pokenav.has_app(:DAYNIGHT)
$Trainer.install_app(:REARRANGE) unless $Trainer.pokenav.has_app(:REARRANGE)
$Trainer.install_app(:CONTACTS) unless $Trainer.pokenav.has_app(:CONTACTS)
end
if $game_switches[SWITCH_HOENN_BEAT_RIVAL_RT_110]
$Trainer.install_app(:POKERADAR) unless $Trainer.pokenav.has_app(:POKERADAR)
end
if $game_variables[1033].is_a?(String) #graffiti/trick house variable mixup
$game_variables[1033] = 0
end
end
$PokemonGlobal.sliding=false
$game_player.walk_anime=true
$game_player.direction_fix=false
PokemonSelection.restore
$game_system.menu_disabled=false
clear_all_images
Kernel.initRandomTypeArray
#fixMissedHMs
# todo: make a hoenn version of missed HMs
$game_switches[SWITCH_CANNOT_CATCH_POKEMON] = false
$game_switches[SWITCH_AQUA_CAMP] = false
restoreDefaultCharacterSprite
Graphics.update
Input.update
pbUpdateSceneMap
end
@@ -0,0 +1,214 @@
def splitSpriteCredits(name, bitmap, max_width)
return [name] if bitmap.text_size(name).width <= max_width
parts = name.split(" & ")
lines = []
parts.each_with_index do |part, i|
segment = part
segment += " &" if i < parts.length - 1 # keep & with the left segment
# If this segment fits, just add it
if bitmap.text_size(segment).width <= max_width
lines << segment
next
end
# Otherwise split inside the segment
current = segment.dup
while bitmap.text_size(current).width > max_width
# Try to break at last space within limit
break_pos = nil
j = 0
while j = current.index(" ", j)
if bitmap.text_size(current[0, j]).width <= max_width
break_pos = j
else
break
end
j += 1
end
if break_pos
# split at last valid space
lines << current[0, break_pos].strip
current = current[break_pos + 1..].strip
else
# no spaces at all: hard split by characters
# find max chars that fit
k = current.length - 1
k -= 1 while bitmap.text_size(current[0, k]).width > max_width
lines << current[0, k]
current = current[k..].strip
end
end
lines << current unless current.empty?
end
lines
end
def pbLoadPokemonBitmapSpecies(pokemon, species, back = false, scale = POKEMONSPRITESCALE)
ret = nil
pokemon = pokemon.pokemon if pokemon.respond_to?(:pokemon)
if pokemon.isEgg?
bitmapFileName = getEggBitmapPath(pokemon)
bitmapFileName = pbResolveBitmap(bitmapFileName)
elsif pokemon.species >= ZAPMOLCUNO_NB #zapmolcuno
bitmapFileName = getSpecialSpriteName(pokemon.species) #sprintf("Graphics/Battlers/special/144.145.146")
bitmapFileName = pbResolveBitmap(bitmapFileName)
else
#edited here
isFusion = species > NB_POKEMON
if isFusion
poke1 = getBodyID(species)
poke2 = getHeadID(species, poke1)
else
poke1 = species
poke2 = species
end
bitmapFileName = GetSpritePath(poke1, poke2, isFusion)
# Alter bitmap if supported
alterBitmap = (MultipleForms.getFunction(species, "alterBitmap") rescue nil)
end
if bitmapFileName && alterBitmap
animatedBitmap = AnimatedBitmap.new(bitmapFileName)
copiedBitmap = animatedBitmap.copy
animatedBitmap.dispose
copiedBitmap.each { |bitmap| alterBitmap.call(pokemon, bitmap) }
ret = copiedBitmap
elsif bitmapFileName
ret = AnimatedBitmap.new(bitmapFileName)
end
return ret
end
def pbPokemonBitmapFile(species)
# Used by the Pokédex
# Load normal bitmap
#get body and head num
isFused = species > NB_POKEMON
if isFused
if species >= ZAPMOLCUNO_NB
path = getSpecialSpriteName(species) + ".png"
else
poke1 = getBodyID(species) #getBasePokemonID(species,true)
poke2 = getHeadID(species, poke1) #getBasePokemonID(species,false)
path = GetSpritePath(poke1, poke2, isFused)
end
else
path = GetSpritePath(species, species, false)
end
ret = sprintf(path) rescue nil
if !pbResolveBitmap(ret)
ret = "Graphics/Battlers/000.png"
end
return ret
end
def pbLoadPokemonBitmap(pokemon, species, back = false)
#species est utilisé par elitebattle mais ca sert a rien
return pbLoadPokemonBitmapSpecies(pokemon, pokemon.species, back)
end
def getEggBitmapPath(pokemon)
return "Graphics/Battlers/Eggs/000" if $PokemonSystem.hide_custom_eggs
bitmapFileName = sprintf("Graphics/Battlers/Eggs/%s", getConstantName(PBSpecies, pokemon.species)) rescue nil
if !pbResolveBitmap(bitmapFileName)
if pokemon.species >= NUM_ZAPMOLCUNO
bitmapFileName = "Graphics/Battlers/Eggs/egg_base"
else
bitmapFileName = sprintf("Graphics/Battlers/Eggs/%03d", pokemon.species)
if !pbResolveBitmap(bitmapFileName)
bitmapFileName = sprintf("Graphics/Battlers/Eggs/000")
end
end
end
return bitmapFileName
end
def GetSpritePath(poke1, poke2, isFused)
#Check if custom exists
spritename = GetSpriteName(poke1, poke2, isFused)
pathCustom = sprintf("Graphics/%s/indexed/%s/%s.png", DOSSIERCUSTOMSPRITES,poke2, spritename)
pathReg = sprintf("Graphics/%s/%s/%s.png", BATTLERSPATH, poke2, spritename)
path = pbResolveBitmap(pathCustom) && $game_variables[196] == 0 ? pathCustom : pathReg
return path
end
def GetSpritePathForced(poke1, poke2, isFused)
#Check if custom exists
spritename = GetSpriteName(poke1, poke2, isFused)
pathCustom = sprintf("Graphics/%s/indexed/%s/%s.png", DOSSIERCUSTOMSPRITES, poke2, spritename)
pathReg = sprintf("Graphics/%s/%s/%s.png", BATTLERSPATH, poke2, spritename)
path = pbResolveBitmap(pathCustom) ? pathCustom : pathReg
return path
end
def GetSpriteName(poke1, poke2, isFused)
ret = isFused ? sprintf("%d.%d", poke2, poke1) : sprintf("%d", poke2) rescue nil
return ret
end
def initialize_species_blacklist(species)
black_list = []
main_sprite_letters = list_main_sprites_letters_species(species)
unless $PokemonSystem.include_alt_sprites_in_random
@available.each_with_index do |pif_sprite, index|
alt_letter = pif_sprite.alt_letter
unless main_sprite_letters.include?(@available[index].alt_letter)
black_list << alt_letter
end
end
end
$PokemonSystem.sprites_blacklist[species] = black_list
return black_list
end
def export_sprites_blacklist
export_file_name = "Data/sprites/sprite_preferences.json"
return unless $PokemonSystem.sprites_blacklist
json =JSON.generate(sanitize_string($PokemonSystem.sprites_blacklist))
File.write(export_file_name, json)
pbMessage(_INTL("Your sprites settings were exported to #{export_file_name}.",))
pbMessage(_INTL("You can share this file with your friends to have them use the same sprites preferences as you."))
pbMessage(_INTL("Place this it in their Data/sprites folder and talk to the Update Man NPC to import them in their game.",))
end
def import_sprites_blacklist
export_file_name = "Data/sprites/sprite_preferences.json"
if File.exist?(export_file_name)
json = File.read(export_file_name)
new_settings = JSON.parse(json)
if $PokemonSystem.sprites_blacklist && !$PokemonSystem.sprites_blacklist.empty?
pbMessage(_INTL("You already have some sprite preferences defined."))
pbMessage(_INTL("Would you like to merge your existing settings with the ones you're importing and completely replace them?",-1))
cmd_merge = _INTL("Merge")
cmd_replace = _INTL("Replace")
cmd_cancel = _INTL("Cancel")
options = [cmd_merge, cmd_replace, cmd_cancel]
choice = optionsMenu(options,-1)
case options[choice]
when cmd_merge
$PokemonSystem.sprites_blacklist = $PokemonSystem.sprites_blacklist.merge(new_settings) do |key, old_arr, new_arr|
(old_arr + new_arr).uniq
end
pbMessage(_INTL("Your sprite settings have been merged! Make sure to save the game."))
when cmd_replace
$PokemonSystem.sprites_blacklist = new_settings
pbMessage(_INTL("Your sprite settings have been replaced! Make sure to save the game."))
end
end
else
pbMessage(_INTL("The game couldn't find a \"sprite_preferences.json\" file in the Data/sprites folder."))
pbMessage(_INTL("Export the sprites settings from the Update Man NPC and place the file in this folder to import them."))
end
#$PokemonSystem.sprites_blacklist = JSON.parse(json)
end
@@ -86,9 +86,10 @@ def formatNumberToString(number)
end
def optionsMenu(options = [], cmdIfCancel = -1, startingOption = 0)
$game_temp.message_window_showing = true
cmdIfCancel = -1 if !cmdIfCancel
result = pbShowCommands(nil, options, cmdIfCancel, startingOption)
# echoln "menuResult :#{result}"
result = pbShowCommands(nil, options, cmdIfCancel+1, startingOption) #+1 parce que pbShowCommands fait un "-1" pour être "user friendly"...
$game_temp.message_window_showing = false
return result
end
@@ -112,4 +113,18 @@ end
def numeric_string?(str)
str.match?(/\A\d+\z/)
end
end
def timeDateGreaterThan(date1, date2)
return (
date1.year > date2.year ||
date1.month > date2.month && date1.year == date2.year ||
date1.day > date2.day && date1.month == date2.month && date1.year == date2.year
)
end
def transferBoxDisclaimer(event)
unless Settings::TRANSFER_BOX_DISCLAIMER_MESSAGE.empty?
pbMessage(_INTL(Settings::TRANSFER_BOX_DISCLAIMER_MESSAGE))
end
end
@@ -2,7 +2,7 @@
def pick_trainer_sprite(spriter_name)
possible_types = "abcd"
trainer_type_index = select_number_from_seed(spriter_name,0,3)
path = _INTL("Graphics/Trainers/trainer116{1}",possible_types[trainer_type_index].to_s)
path = "Graphics/Trainers/trainer116#{possible_types[trainer_type_index].to_s}"
return path
end
@@ -214,10 +214,10 @@ def fusionOf(head,body)
end
def getFusionSpeciesSymbol(body, head)
body_num = dexNum(body)
head_num = dexNum(head)
body_num = getDexNumberForSpecies(body)
head_num = getDexNumberForSpecies(head)
nb_pokemon = Settings::NB_POKEMON
id = body_num * nb_pokemon + head_num
id = (body_num * nb_pokemon) + head_num
if id > (nb_pokemon*nb_pokemon)+nb_pokemon
displayRandomizerErrorMessage()
return body
@@ -0,0 +1,149 @@
class Game_Temp
attr_accessor :choose_number_window
end
class ExpExtraction
attr_accessor :exp_to_extract
attr_accessor :nb_candies
attr_reader :valid_exp
attr_reader :max_value
attr_reader :full_price
BASE_PRICE = 1000
LOSS_PER_CANDY = 50
def initialize(pokemon, unit_price)
@pokemon = pokemon
@unit_price = unit_price
@exp_to_extract = 0
@nb_candies = (@exp_to_extract / 1000).floor
@full_price = BASE_PRICE + @unit_price * @nb_candies
@total_exp = pokemon.exp_gained_with_player
pokemon.exp_gained_with_player = 0 if !pokemon.exp_gained_with_player
@valid_exp = [pokemon.exp_gained_with_player,pokemon.exp].min
@max_value = @valid_exp / 1000.floor
update_text
end
def update(nb_candies)
return if nb_candies == @nb_candies
@nb_candies = nb_candies
@exp_to_extract = @nb_candies * 1000
@nb_candies = (@exp_to_extract / 1000).floor
@full_price = calculate_price
update_text
end
def calculate_price # todo: scale exponentially with bigger numbers
return BASE_PRICE + @unit_price * @nb_candies
end
def update_text
Kernel.pbClearNumber()
Kernel.pbClearText()
return if @max_value < 1
Kernel.pbDisplayText(_INTL("Exp to extract:"), 80, 100,)
Kernel.pbDisplayText("#{@exp_to_extract} / #{@valid_exp}", 120, 130,)
Kernel.pbDisplayText(_INTL("Price:"), 40, 170,)
Kernel.pbDisplayText("$#{@full_price}", 80, 200,)
end
def dispose
Kernel.pbClearText()
Kernel.pbClearNumber()
$game_temp.choose_number_window = nil
end
end
# nbCandiesVariable: variable in which to store the nb. of candies obtained.
# The event does a little animation before giving out the candies.
#
def extractExpFromPokemon(pokemon, unitPrice, nbCandiesVariable = 1)
expExtraction = ExpExtraction.new(pokemon, unitPrice)
if expExtraction.max_value < 1
pbCallBubDown(2, @event_id)
pbMessage(_INTL("Oh, I'm sorry, but this Pokémon does not have enough Exp. available for the procedure."))
pbCallBubDown(2, @event_id)
pbMessage(_INTL("Keep in mind that only the Exp. that was obtained with a Trainer can be safely extracted. Any Exp. it gained as a wild Pokémon is no good!"))
return false
end
update_proc = proc {
cmdwindow = $game_temp.choose_number_window
if cmdwindow
current_number = cmdwindow.number
expExtraction.update(current_number)
end
}
params = ChooseNumberParams.new
params.setRange(0, expExtraction.max_value)
params.setDefaultValue(1)
params.setCancelValue(0)
value = pbMessageChooseNumber(_INTL("\\GHow many \\C[1]Exp. Candies\\C[0] to extract?"), params, &update_proc)
new_exp = pokemon.exp - expExtraction.exp_to_extract
new_exp -= ExpExtraction::LOSS_PER_CANDY*expExtraction.nb_candies
new_exp -= expExtraction.nb_candies
new_exp = 0 if new_exp < 0
nb_candies = expExtraction.nb_candies
new_level = pokemon.calculate_level_at_exp(new_exp)
expExtraction.dispose
if expExtraction.nb_candies <= 0 || value <=0 #value:0 means that it was cancelled
return false
end
if $Trainer.money < expExtraction.full_price
pbCallBubDown(2, @event_id)
pbMessage(_INTL("Oh, I'm sorry, but you don't have enough money to afford the procedure. You might want to try a smaller extraction."))
return false
end
pbCallBubDown(2, @event_id)
if pbConfirmMessage(_INTL("Your {1} will go from \\C[1]Level {2}\\C[0] to \\C[1]Level {3}\\C[0] after all the Exp. Candies are extracted. Do you still want to continue?", pokemon.name, pokemon.level, new_level))
exp_to_extract = expExtraction.exp_to_extract + ExpExtraction::LOSS_PER_CANDY*expExtraction.nb_candies
removeExp(pokemon, exp_to_extract)
pbSet(nbCandiesVariable, nb_candies)
$Trainer.money -= expExtraction.full_price
else
return false
end
end
def removeExp(pokemon, exp_to_remove)
pokemon.exp_gained_with_player = 0 unless pokemon.exp_gained_with_player
pokemon.exp_gained_with_player -= exp_to_remove
pokemon.exp_gained_with_player = 0 if pokemon.exp_gained_with_player < 0
if pokemon.exp_gained_since_fused && pokemon.exp_gained_with_player > 0
pokemon.exp_gained_since_fused -= exp_to_remove
if pokemon.exp_gained_since_fused < 0
pokemon.exp_when_fused_head = 0 unless pokemon.exp_when_fused_head
pokemon.exp_when_fused_body = 0 unless pokemon.exp_when_fused_body
difference = pokemon.exp_gained_since_fused.abs
pokemon.exp_gained_since_fused = 0
pokemon.exp_when_fused_head -= difference / 2
pokemon.exp_when_fused_body -= difference / 2
pokemon.exp_when_fused_head = 0 if pokemon.exp_when_fused_head < 0
pokemon.exp_when_fused_body = 0 if pokemon.exp_when_fused_body < 0
end
pokemon.exp_gained_since_fused = 0 if pokemon.exp_gained_since_fused < 0
end
pokemon.exp -= exp_to_remove
pokemon.exp = 0 if pokemon.exp < 0
pokemon.calc_stats
end
@@ -110,7 +110,7 @@ CARD_BACKGROUND_UNLOCKABLES = {
"RUBY" => SWITCH_HOENN_HAIR_COLLECTION,
"SAPPHIRE" => SWITCH_HOENN_HAIR_COLLECTION,
"EMERALD" => SWITCH_HOENN_HAIR_COLLECTION,
"BARS_BOACH" => SWITCH_HOENN_HAIR_COLLECTION,
"BARS-BOACH" => SWITCH_HOENN_HAIR_COLLECTION,
"RIVALS" => SWITCH_HOENN_HAIR_COLLECTION,
@@ -179,7 +179,7 @@ end
def purchaseCardBackground(price = 1000)
$Trainer.unlocked_card_backgrounds = [] if ! $Trainer.unlocked_card_backgrounds
purchasable_cards = []
current_city = pbGet(VAR_CURRENT_MART)
current_city = pbGet(VAR_CURRENT_CITY)
current_city = :PEWTER if !current_city.is_a?(Symbol)
for card in CARD_BACKGROUND_CITY_EXCLUSIVES.keys
purchasable_cards << card if current_city == CARD_BACKGROUND_CITY_EXCLUSIVES[card] && !$Trainer.unlocked_card_backgrounds.include?(card)
@@ -219,7 +219,7 @@ def purchaseCardBackground(price = 1000)
pbSEPlay("Mart buy item")
$Trainer.money -= price
unlock_card_background(chosen)
pbSEPlay("Item get")
pbMEPlay("Item get")
pbMessage(_INTL("\\GYou purchased the {1} Trainer Card background!", name))
if pbConfirmMessage(_INTL("Would you like to swap your current Trainer Card for the newly purchased one?"))
pbSEPlay("GUI trainer card open")
@@ -305,4 +305,4 @@ class TrainerCardBackgroundLister
#sprite.ox = @sprite.bitmap.width/2 if @sprite.bitmap
#@sprite.oy = @sprite.bitmap.height/2 if @sprite
end
end
end
@@ -6,7 +6,7 @@ class PokemonStorage
commands = [cmd_play, cmd_info, cmd_cancel]
$Trainer.quest_points = initialize_quest_points unless $Trainer.quest_points
choice = pbMessage(_INTL("\\qpWould you like to play the Wallpaper Lottery? (Costs \\C[1]1 Quest point\\C[0])"),commands,2)
choice = pbMessage(_INTL("\\qpWould you like to play the Wallpaper Lottery? (Costs \\C[1]1 Quest point\\C[0])"), commands, 2)
case commands[choice]
when cmd_play
@@ -16,7 +16,7 @@ class PokemonStorage
end
locked_wallpapers = []
for i in BASICWALLPAPERQTY..allWallpapers.length-1
for i in BASICWALLPAPERQTY..allWallpapers.length - 1
locked_wallpapers << i unless isAvailableWallpaper?(i)
end
if locked_wallpapers.empty?
@@ -27,7 +27,6 @@ class PokemonStorage
unlocked_index = locked_wallpapers.sample
$Trainer.quest_points -= 1
$game_system.bgm_memorize
$game_system.bgm_stop
@@ -47,7 +46,7 @@ class PokemonStorage
wallpaper_name = allWallpapers[wallpaper_id]
pbUnlockWallpaper(wallpaper_id)
path = "Graphics/Pictures/Storage/Wallpapers/box_#{wallpaper_id}"
pictureViewport = showPicture(path, 50,-45)
pictureViewport = showPicture(path, 50, -45)
musical_effect = "Key item get"
pbMessage(_INTL("\\qp\\me[{1}]Obtained a new wallpaper: \\c[1]{2}\\c[0]!", musical_effect, wallpaper_name))
pictureViewport.dispose if pictureViewport
@@ -56,7 +55,12 @@ end
class WallpaperLotteryPC
def shouldShow?
return player_has_quest_journal?
if Settings::KANTO
return player_has_quest_journal?
end
if Settings::HOENN
return $game_switches[SWITCH_UNLOCKED_WALLPAPER_LOTTERY]
end
end
def name
@@ -0,0 +1,207 @@
# chosen pokemon is returned with this format:
#[[boxID, boxPosition],pokemon]
def pbChoosePokemonPC(positionVariableNumber, pokemonVarNumber, ableProc = nil)
chosen = nil
pokemon = nil
pbFadeOutIn {
scene = PokemonStorageScene.new
screen = PokemonStorageScreen.new(scene, $PokemonStorage)
screen.setFilter(ableProc) if ableProc
chosen = screen.choosePokemon
pokemon = $PokemonStorage[chosen[0]][chosen[1]] if chosen
scene.pbCloseBox
}
pbSet(positionVariableNumber, chosen)
pbSet(pokemonVarNumber, pokemon)
end
def npcTrade(npcPokemon_species, nickname, trainerName, playerPokemonProc)
chosen_pokemon = pbChoosePokemon(1, 2, playerPokemonProc)
chosen_position = pbGet(1)
return nil if chosen_position <= -1
pbStartTrade(chosen_position, npcPokemon_species, nickname, trainerName, 0)
end
def floorHole(mapBelow, frames_for_fall = 8, bikeOnly = true)
return unless mapBelow
return if $game_player.moving?
event = this_event()
event.instance_variable_set(:@idle_frames, 0) unless event.instance_variable_defined?(:@idle_frames)
event.instance_variable_set(:@idle_frames, event.instance_variable_get(:@idle_frames) + 1)
frames_for_fall = 0 if bikeOnly && !$PokemonGlobal.bicycle
if event.instance_variable_get(:@idle_frames) >= frames_for_fall
event.instance_variable_set(:@idle_frames, 0)
# Find a passable landing tile on the target map
target_x, target_y = findPassableLanding(mapBelow, $game_player.x, $game_player.y)
return unless target_x
pbSEPlay("Slash")
playAnimation(Settings::EXCLAMATION_ANIMATION_ID, $game_player.x, $game_player.y)
event.direction_fix = false
event.turn_left
pbWait(4)
pbFadeOutIn {
$game_temp.player_new_map_id = mapBelow
$game_temp.player_new_x = target_x
$game_temp.player_new_y = target_y
pbCancelVehicles
$scene.transfer_player
$game_map.autoplay
$game_map.refresh
}
pbWait(8)
end
end
# Loads the target map and spirals outward from (start_x, start_y)
# until a passable tile is found. Returns [x, y] or [nil, nil].
def findPassableLanding(map_id, start_x, start_y, max_radius = 10)
# Load the target map data without switching to it
map_data = load_data(sprintf("Data/Map%03d.rxdata", map_id))
target_map = Game_Map.new
target_map.setup(map_id)
# Check exact position first
if target_map.passableStrict?(start_x, start_y, 2)
return [start_x, start_y]
end
# Spiral outward: check ring by ring
1.upto(max_radius) do |radius|
(-radius..radius).each do |dx|
(-radius..radius).each do |dy|
next unless dx.abs == radius || dy.abs == radius # Only check the outer ring
x = start_x + dx
y = start_y + dy
next unless target_map.valid?(x, y)
return [x, y] if target_map.passableStrict?(x, y, 2)
end
end
end
return [nil, nil]
end
BASIC_SHIRTS = {
:GRASS => "basicgrass",
:FIRE => "basicfire",
:WATER => "basicwater",
:BUG => "basicbug",
:NORMAL => "basicnormal",
:ROCK => "basicrock",
:GROUND => "basicground",
:STEEL => "basicsteel",
:PSYCHIC => "basicpsychic",
:POISON => "basicpoison",
:ICE => "basicice",
:GHOST => "basicghost",
:FLYING => "basicflying",
:FIGHTING => "basicfight",
:FAIRY => "basicfairy",
:ELECTRIC => "basicelectric",
:DRAGON => "basicdragon",
:DARK => "basicdark",
}
def basicTypeShirts(event_id, nb_owned_for_reward = 5)
GameData::Type.each do |type|
nb_owned = 0
GameData::Species.each do |species|
if $Trainer.pokedex.owned?(species.species) && species.hasType?(type)
nb_owned += 1
end
end
if nb_owned >= nb_owned_for_reward
clothes_reward = BASIC_SHIRTS[type.id]
unless hasClothes?(clothes_reward)
pbCallBub(2, event_id)
pbMessage(_INTL("Let's see your Pokédex..."))
pbCallBub(2, event_id)
pbMessage(_INTL("Oh! You've caught {1} \\C[1]{2}-type\\C[0] Pokémon! You must be a huge {2} fan!", nb_owned, type.name))
pbCallBub(2, event_id)
pbMessage(_INTL("I have just the shirt for you. Here you go!"))
obtainClothes(clothes_reward)
return true
end
end
end
return false
end
def timeTrialStart
$game_temp.time_trial_bumps = 0
pbSet(VAR_TIME_TRIAL_START, Time.now)
end
def timeTrialStop
currentTime = Time.now
startTime = pbGet(VAR_TIME_TRIAL_START)
elapsed = (currentTime - startTime).to_f.truncate(3)
pbSet(VAR_TIME_TRIAL_SECONDS, elapsed)
end
def timeTrialApplyBumpsPenalty
nb_bumps = $game_temp.time_trial_bumps
current_time = pbGet(VAR_TIME_TRIAL_SECONDS)
current_time += (nb_bumps * 0.5)
pbSet(VAR_TIME_TRIAL_SECONDS, current_time.truncate(3))
end
def get_current_town_map_location
map_data = pbLoadTownMapData
all_maps = map_data[0][2]
map_id_position = find_position_for_map(all_maps, $game_map.map_id)
if map_id_position
return $game_map.map_id
else
return $Trainer.last_visited_town_map_location
end
end
def getNaturalPokemonList()
list = []
if Settings::KANTO
for i in 1..501
pokemon_species = GameData::Species.get(i)
list << pokemon_species.species
end
end
if Settings::HOENN
# Todo: Update and double check this!!!
return [
:PIDGEY, :PIDGEOTTO, :PIDGEOT, :RATTATA, :RATICATE, :SPEAROW, :FEAROW, :PIKACHU, :RAICHU, :CLEFAIRY, :CLEFABLE, :ZUBAT, :GOLBAT, :ODDISH, :GLOOM, :VILEPLUME, :PARAS, :PARASECT, :MEOWTH, :PERSIAN, :POLIWAG, :POLIWHIRL,
:POLIWRATH, :ABRA, :KADABRA, :ALAKAZAM, :MACHOP, :MACHOKE, :MACHAMP, :GEODUDE, :GRAVELER, :GOLEM, :PONYTA, :RAPIDASH, :MAGNEMITE, :MAGNETON, :DODUO, :DODRIO, :GRIMER, :MUK, :KRABBY, :KINGLER, :VOLTORB, :ELECTRODE,
:HITMONLEE, :HITMONCHAN, :HORSEA, :SEADRA, :GOLDEEN, :SEAKING, :STARYU, :STARMIE, :MAGIKARP, :GYARADOS, :DITTO, :EEVEE, :VAPOREON, :JOLTEON, :FLAREON, :PORYGON, :SNORLAX, :HOOTHOOT, :NOCTOWL, :CROBAT, :PICHU, :CLEFFA,
:IGGLYBUFF, :MAREEP, :FLAAFFY, :AMPHAROS, :BELLOSSOM, :MARILL, :AZUMARILL, :HOPPIP, :SKIPLOOM, :JUMPLUFF, :AIPOM, :SUNKERN, :SUNFLORA, :ESPEON, :UMBREON, :MURKROW, :MISDREAVUS, :PINECO, :FORRETRESS, :SHUCKLE,
:TEDDIURSA, :URSARING, :SLUGMA, :MAGCARGO, :REMORAID, :OCTILLERY, :MANTINE, :HOUNDOUR, :HOUNDOOM, :SMEARGLE, :TYROGUE, :HITMONTOP, :AZURILL, :WYNAUT, :AMBIPOM, :MISMAGIUS, :HONCHKROW, :MUNCHLAX, :MANTYKE,
:LEAFEON, :GLACEON, :TREECKO, :GROVYLE, :SCEPTILE, :TORCHIC, :COMBUSKEN, :BLAZIKEN, :MUDKIP, :MARSHTOMP, :SWAMPERT, :RALTS, :KIRLIA, :GARDEVOIR, :GALLADE, :SHEDINJA, :KECLEON, :MAWILE, :SLAKING, :NOSEPASS,
:LUXRAY, :AGGRON, :KLINKLANG, :ZOROARK, :SYLVEON, :ROSERADE, :DRIFBLIM, :NINJASK, :WHIMSICOTT, :TALONFLAME, :NINCADA, :RIOLU, :SLAKOTH, :VIGOROTH, :WAILMER, :SHINX, :LUXIO, :ARON, :LAIRON, :KLINK, :KLANG, :ZORUA,
:BUDEW, :ROSELIA, :DRIFLOON, :SHROOMISH, :COTTONEE, :FLETCHLING, :FLETCHINDER, :SABLEYE, :VENIPEDE, :WHIRLIPEDE, :SCOLIPEDE, :ORICORIO_1, :ORICORIO_2, :ORICORIO_3, :ORICORIO_4, :TRUBBISH, :GARBODOR, :CARVANHA, :SHARPEDO,
:PHANTUMP, :TREVENANT, :SANDYGAST, :PALOSSAND, :FOMANTIS, :LURANTIS, :CARBINK, :SCRAGGY, :SCRAFTY, :LOTAD, :LOMBRE, :LUDICOLO, :LUVDISC, :POOCHYENA, :MIGHTYENA, :ZIGZAGOON, :LINOONE, :WURMPLE, :SILCOON, :BEAUTIFLY,
:CASCOON, :DUSTOX, :SEEDOT, :NUZLEAF, :SHIFTRY, :TAILLOW, :SWELLOW, :WINGULL, :PELIPPER, :SURSKIT, :MASQUERAIN, :WHISMUR, :LOUDRED, :EXPLOUD, :MAKUHITA, :HARIYAMA, :SKITTY, :DELCATTY, :MEDITITE, :MEDICHAM,
:ELECTRIKE, :MANECTRIC, :PLUSLE, :MINUN, :VOLBEAT, :ILLUMISE, :GULPIN, :SWALOT, :NUMEL, :CAMERUPT, :SPOINK, :GRUMPIG, :CORPHISH, :CRAWDAUNT, :CHINGLING, :CHIMECHO, :SPHEAL, :SEALEO, :WALREIN, :CLAMPERL, :GOREBYSS, :HUNTAIL,
:WOOBAT, :SWOOBAT, :TYNAMO, :EELEKTRIK, :EELEKTROSS, :SKRELP, :DRAGALGE
]
end
return list
end
def pokedex_check
missing = []
natural_pokemon_list = getNaturalPokemonList
natural_pokemon_list.each do |species|
unless $Trainer.owned?(species)
missing.push(species)
end
end
return missing
end
@@ -1,32 +1,49 @@
HIDDEN_MAPS_STEPS = 1500
HIDDEN_MAP_ALWAYS = [178,655,570,356]
RANDOM_HIDDEN_MAP_LIST = [8,109,431,446,402,403,467,468,10,23,167,16,19,78,185,86,
491,90,40,342,490,102,103,104,105,106,1,12,413,445,484,485,486,140,350,146,
149,304,356,307,409,351,495,154,349,322,323,544,198,144,155,444,58,59,229,52,53,54,
55,98,173,174,181,187,95,159,162,437,440,438,57,171,528,265,288,364,329,
335,254,261,262,266,230,145,147,258,284,283,267,586,285,286,287,300,311,47,580,529,
635,638,646,560,559,526,600,564,594,566,562,619,563,603,561,597,633,640,641,621,312,
670,692,643,523,698,
602,642,623,569,588,573,362,645,651,376,762
HIDDEN_MAP_ALWAYS = [178, 655, 570, 356]
RANDOM_HIDDEN_MAP_LIST = [8, 109, 431, 446, 402, 403, 467, 468, 10, 23, 167, 16, 19, 78, 185, 86,
491, 90, 40, 342, 490, 102, 103, 104, 105, 106, 1, 12, 413, 445, 484, 485, 486, 140, 350, 146,
149, 304, 356, 307, 409, 351, 495, 154, 349, 322, 323, 544, 198, 144, 155, 444, 58, 59, 229, 52, 53, 54,
55, 98, 173, 174, 181, 187, 95, 159, 162, 437, 440, 438, 57, 171, 528, 265, 288, 364, 329,
335, 254, 261, 262, 266, 230, 145, 147, 258, 284, 283, 267, 586, 285, 286, 287, 300, 311, 47, 580, 529,
635, 638, 646, 560, 559, 526, 600, 564, 594, 566, 562, 619, 563, 603, 561, 597, 633, 640, 641, 621, 312,
670, 692, 643, 523, 698,
602, 642, 623, 569, 588, 573, 362, 645, 651, 376, 762
]
Events.onMapUpdate+=proc {|sender,e|
#next if !$game_switches[HIDDENMAPSWITCH]
RANDOM_HIDDEN_MAP_LIST_HOENN = [
5, 10, 11, 12, 20, 50, 49, 31, 65, 37, 38, 39, 71, 74, 76, 77, # Routes
30, 28, 32, 34, 35, # dungeons
69, 62, 97, # secret areas
7, 47, 51, 6, # cities (only those that have encounterable pokemon)
999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, # Placeholders (so that it's still rare in the demo lol)
]
Events.onMapUpdate += proc { |sender, e|
# next if !$game_switches[HIDDENMAPSWITCH]
if $PokemonGlobal.stepcount % HIDDEN_MAPS_STEPS == 0
changeHiddenMap()
end
}
def changeHiddenMap()
i = rand(RANDOM_HIDDEN_MAP_LIST.length-1)
pbSet(VAR_CURRENT_HIDDEN_MAP,RANDOM_HIDDEN_MAP_LIST[i])
maps_list = Settings::KANTO ? RANDOM_HIDDEN_MAP_LIST : RANDOM_HIDDEN_MAP_LIST_HOENN
i = rand(maps_list.length - 1)
pbSet(VAR_CURRENT_HIDDEN_MAP, maps_list[i])
setHiddenAbilityMapAnnouncement if Settings::HOENN
end
Events.onWildPokemonCreate+=proc {|sender,e|
def setHiddenAbilityMapAnnouncement
visitedMap = $PokemonGlobal.visitedMaps[pbGet(VAR_CURRENT_HIDDEN_MAP)]
if visitedMap
addTVAnnouncement(:hidden_ability)
else
removeTVAnnouncement(:hidden_ability)
end
end
Events.onWildPokemonCreate += proc { |sender, e|
if player_on_hidden_ability_map || isAlwaysHiddenAbilityMap($game_map.map_id)
pokemon=e[0]
chosenAbility = pokemon.getAbilityList.sample #format: [[:ABILITY, index],...]
pokemon = e[0]
chosenAbility = pokemon.getAbilityList.sample # format: [[:ABILITY, index],...]
pokemon.ability = chosenAbility[0]
pokemon.ability_index = chosenAbility[1]
end
@@ -37,10 +54,14 @@ def isAlwaysHiddenAbilityMap(mapId)
end
def player_on_hidden_ability_map
return $game_map.map_id== pbGet(226)
return $game_map.map_id == pbGet(VAR_CURRENT_HIDDEN_MAP)
end
def Kernel.getMapName(id)
def getCurrentHiddenAbilityMapName
return getMapName(pbGet(VAR_CURRENT_HIDDEN_MAP)).to_s
end
def getMapName(id)
mapinfos = pbLoadMapInfos
return _INTL("Unknown location") if !mapinfos[id]
return mapinfos[id].name
@@ -59,6 +59,8 @@ def rockSmashItem(isDark=false)
if rand(100)< chance
if rand(5) == 0 && !hatUnlocked?(HAT_AERODACTYL)
obtainHat(HAT_AERODACTYL)
elsif rand(5) == 0 && !hatUnlocked?(HAT_TYRUNT)
obtainHat(HAT_TYRUNT)
else
itemsList = getRockSmashItemList(isDark)
i = rand(itemsList.length)
@@ -228,8 +228,8 @@ ItemHandlers::UseOnPokemon.add(:INCUBATOR, proc { |item, pokemon, scene|
next false
else
scene.pbDisplay(_INTL("Incubating..."))
scene.pbDisplay(_INTL("..."))
scene.pbDisplay(_INTL("..."))
scene.pbDisplay("...")
scene.pbDisplay("...")
scene.pbDisplay(_INTL("Your egg is ready to hatch!"))
pokemon.eggsteps = 1
next true
@@ -255,7 +255,7 @@ ItemHandlers::UseFromBag.add(:DEBUGGER, proc { |item|
if Kernel.pbConfirmMessageSerious(_INTL("Innapropriate use of this item can lead to unwanted effects and make the game unplayable. Do you want to continue?"))
$game_player.cancelMoveRoute()
Kernel.pbStartOver(false)
pbCommonEvent(COMMON_EVENT_FIX_GAME)
fixStuff
Kernel.pbMessage(_INTL("Please report the glitch on the game's Discord, in the #bug-reports channel."))
openUrlInBrowser(Settings::DISCORD_URL)
next 1
@@ -264,6 +264,17 @@ ItemHandlers::UseFromBag.add(:DEBUGGER, proc { |item|
end
})
ItemHandlers::UseInField.add(:SPAWNER, proc { |item|
old_id = pbGet(1)
unless old_id.is_a?(Integer)
old_id =1
end
species = pbChooseSpeciesList(old_id,NB_POKEMON)
pbSet(1,species.id_number)
echoln species.species
spawn_ow_pokemon(species.species,5,1)
})
def useSleepingBag()
currentSecondsValue = pbGet(UnrealTime::EXTRA_SECONDS)
choices = [_INTL("1 hour"), _INTL("6 hours"), _INTL("12 hours"), _INTL("24 hours"), _INTL("Cancel")]
@@ -285,6 +296,13 @@ def useSleepingBag()
pbSet(UnrealTime::EXTRA_SECONDS, currentSecondsValue + timeAdded)
pbSEPlay("Sleep", 100)
pbFadeOutIn {
if $game_weather
mapId = $game_map.map_id
$game_weather.try_spawn_new_weather(mapId,
$game_weather.current_weather[mapId][0],
40)
$game_weather.update_weather
end
Kernel.pbMessage(_INTL("{1} slept for a while...", $Trainer.name))
}
time = pbGetTimeNow.strftime("%I:%M %p")
@@ -294,6 +312,7 @@ def useSleepingBag()
else
Kernel.pbMessage(_INTL("The current time is now {1}.", time))
end
$scene.spriteset.addUserSprite(WeatherIcon.new)
return 1
end
@@ -308,7 +327,17 @@ def useFieldSleepingBag()
pbSet(UnrealTime::EXTRA_SECONDS, currentSecondsValue + timeAdded)
pbSEPlay("Sleep", 100)
pbFadeOutIn {
$game_weather.update_weather
if $game_weather
mapId = $game_map.map_id
echoln $game_weather.current_weather[mapId]
if $game_weather.current_weather[mapId]
echoln "spawning...."
$game_weather.try_spawn_new_weather(mapId,
$game_weather.current_weather[mapId][0],
40)
end
$game_weather.update_weather
end
Kernel.pbMessage(_INTL("{1} slept for a while...", $Trainer.name))
$scene.reset_map(false)
}
@@ -319,6 +348,7 @@ def useFieldSleepingBag()
else
Kernel.pbMessage(_INTL("The current time is now {1}.", time))
end
$scene.spriteset.addUserSprite(WeatherIcon.new)
return 1
end
@@ -344,7 +374,7 @@ ItemHandlers::UseInField.add(:SLEEPINGBAG, proc { |item|
ItemHandlers::UseFromBag.add(:FIELDSLEEPINGBAG, proc { |item|
mapMetadata = GameData::MapMetadata.try_get($game_map.map_id)
if !mapMetadata || !mapMetadata.outdoor_map
if !mapMetadata || !mapMetadata.outdoor_map || $PokemonGlobal.surfing
Kernel.pbMessage(_INTL("Can't use that here..."))
next 0
end
@@ -353,7 +383,7 @@ ItemHandlers::UseFromBag.add(:FIELDSLEEPINGBAG, proc { |item|
ItemHandlers::UseInField.add(:FIELDSLEEPINGBAG, proc { |item|
mapMetadata = GameData::MapMetadata.try_get($game_map.map_id)
if !mapMetadata || !mapMetadata.outdoor_map
if !mapMetadata || !mapMetadata.outdoor_map || $PokemonGlobal.surfing
Kernel.pbMessage(_INTL("Can't use that here..."))
next 0
end
@@ -368,6 +398,24 @@ ItemHandlers::UseInField.add(:ROCKETUNIFORM, proc { |item|
next useRocketUniform()
})
ItemHandlers::UseFromBag.add(:MAGMAUNIFORM, proc { |item|
next useMagmaUniform()
})
ItemHandlers::UseInField.add(:MAGMAUNIFORM, proc { |item|
next useMagmaUniform()
})
ItemHandlers::UseFromBag.add(:AQUAUNIFORM, proc { |item|
next useAquaUniform()
})
ItemHandlers::UseInField.add(:AQUAUNIFORM, proc { |item|
next useAquaUniform()
})
ItemHandlers::UseFromBag.add(:FAVORITEOUTFIT, proc { |item|
next useFavoriteOutfit()
})
@@ -396,11 +444,30 @@ ItemHandlers::UseFromBag.add(:EMERGENCYWHISTLE, proc { |item|
next 0
})
ItemHandlers::UseFromBag.add(:PRESENT, proc { |item|
quantity = $PokemonBag.pbQuantity(item)
nb = 1
if quantity > 1
params = ChooseNumberParams.new
params.setRange(1, quantity)
params.setDefaultValue(1)
nb = pbMessageChooseNumber(_INTL("\How many would you like to open?<br>({1} in bag)", quantity), params)
end
if Settings::HOENN
pbReceiveCosmeticsMoney(600*nb)
else
pbReceiveMoney(400*nb)
end
$PokemonBag.pbDeleteItem(item, nb)
next 1
})
ItemHandlers::UseFromBag.add(:MUSHROOMSPORES, proc { |item|
if $game_switches[SWITCH_SPORES_REPEL]
if pbQuantity(:MUSHROOMSPORES) >= 2
if pbConfirmMessage(_INTL("Condense 2 spore samples into a Repel?"))
$PokemonBag.pbDeleteItem(:MUSHROOMSPORES,2)
$PokemonBag.pbDeleteItem(:MUSHROOMSPORES, 2)
pbReceiveItem(:REPEL)
next 1
else
@@ -415,7 +482,6 @@ ItemHandlers::UseFromBag.add(:MUSHROOMSPORES, proc { |item|
next 0
})
ItemHandlers::UseFromBag.add(:ODDKEYSTONE, proc { |item|
TOTAL_SPIRITS_NEEDED = 108
nbSpirits = pbGet(VAR_ODDKEYSTONE_NB)
@@ -449,9 +515,9 @@ def useFavoriteOutfit()
switchToFavoriteOutfit()
elsif options[choice] == cmd_mark_favorite
pbSEPlay("shiny", 80, 100)
$Trainer.favorite_clothes= $Trainer.clothes
$Trainer.favorite_clothes = $Trainer.clothes
$Trainer.favorite_hat = $Trainer.hat
$Trainer.favorite_hat2=$Trainer.hat2
$Trainer.favorite_hat2 = $Trainer.hat2
pbMessage(_INTL("Your favorite outfit was updated!"))
end
end
@@ -471,9 +537,9 @@ def switchToFavoriteOutfit()
$Trainer.last_worn_outfit = getDefaultClothes(getPlayerGenderId)
end
playOutfitChangeAnimation()
putOnClothes($Trainer.last_worn_outfit, true) #if $Trainer.favorite_clothes
putOnHat($Trainer.last_worn_hat, true,false) #if $Trainer.favorite_hat
putOnHat($Trainer.last_worn_hat2, true,true) #if $Trainer.favorite_hat2
putOnClothes($Trainer.last_worn_outfit, true) # if $Trainer.favorite_clothes
putOnHat($Trainer.last_worn_hat, true, false) # if $Trainer.favorite_hat
putOnHat($Trainer.last_worn_hat2, true, true) # if $Trainer.favorite_hat2
else
return 0
@@ -498,7 +564,7 @@ def useRocketUniform()
if isWearingTeamRocketOutfit()
if (Kernel.pbConfirmMessage(_INTL("Remove the Team Rocket uniform?")))
if ($Trainer.last_worn_outfit == CLOTHES_TEAM_ROCKET_MALE || $Trainer.last_worn_outfit == CLOTHES_TEAM_ROCKET_FEMALE) && $Trainer.last_worn_hat == HAT_TEAM_ROCKET
$Trainer.last_worn_outfit = getDefaultClothes(getPlayerGender)
$Trainer.last_worn_outfit = getDefaultClothes(getPlayerGenderId)
end
playOutfitChangeAnimation()
putOnClothes($Trainer.last_worn_outfit, true)
@@ -522,9 +588,71 @@ def useRocketUniform()
return 1
end
def useMagmaUniform()
return 0 if !$game_switches[SWITCH_JOINED_TEAM_MAGMA]
if isWearingTeamMagmaOutfit()
if (Kernel.pbConfirmMessage(_INTL("Remove the Team Magma uniform?")))
if ($Trainer.last_worn_outfit == CLOTHES_TEAM_MAGMA_M || $Trainer.last_worn_outfit == CLOTHES_TEAM_MAGMA_F) && $Trainer.last_worn_hat == HAT_TEAM_MAGMA
gender = pbGet(VAR_TRAINER_GENDER)
$Trainer.last_worn_outfit = getDefaultClothes(gender)
end
playOutfitChangeAnimation()
putOnClothes($Trainer.last_worn_outfit, true)
putOnHat($Trainer.last_worn_hat, true)
else
return 0
end
else
if (Kernel.pbConfirmMessage(_INTL("Put on the Team Magma uniform?")))
playOutfitChangeAnimation()
gender = pbGet(VAR_TRAINER_GENDER)
if gender == GENDER_MALE
putOnClothes(CLOTHES_TEAM_MAGMA_M, true)
else
putOnClothes(CLOTHES_TEAM_MAGMA_F, true)
end
putOnHat(HAT_TEAM_MAGMA, true)
end
end
return 1
end
def useAquaUniform()
return 0 if !$game_switches[SWITCH_JOINED_TEAM_AQUA]
if isWearingTeamAquaOutfit()
if (Kernel.pbConfirmMessage(_INTL("Remove the Team Aqua uniform?")))
if ($Trainer.last_worn_outfit == CLOTHES_TEAM_AQUA_M || $Trainer.last_worn_outfit == CLOTHES_TEAM_AQUA_F) && $Trainer.last_worn_hat == HAT_TEAM_AQUA
gender = pbGet(VAR_TRAINER_GENDER)
$Trainer.last_worn_outfit = getDefaultClothes(gender)
end
playOutfitChangeAnimation()
putOnClothes($Trainer.last_worn_outfit, true)
putOnHat($Trainer.last_worn_hat, true)
else
return 0
end
else
if (Kernel.pbConfirmMessage(_INTL("Put on the Team Aqua uniform?")))
playOutfitChangeAnimation()
gender = pbGet(VAR_TRAINER_GENDER)
if gender == GENDER_MALE
putOnClothes(CLOTHES_TEAM_AQUA_M, true)
else
putOnClothes(CLOTHES_TEAM_AQUA_F, true)
end
putOnHat(HAT_TEAM_AQUA, true)
end
end
return 1
end
def useDreamMirror
visitedMap = $PokemonGlobal.visitedMaps[pbGet(226)]
map_name = visitedMap ? Kernel.getMapName(pbGet(226)).to_s : _INTL("an unknown location")
map_name = visitedMap ? getMapName(pbGet(226)).to_s : _INTL("an unknown location")
Kernel.pbMessage(_INTL("You peeked into the Dream Mirror..."))
@@ -680,7 +808,7 @@ ItemHandlers::UseOnPokemon.add(:DNAREVERSER, proc { |item, pokemon, scene|
scene.pbDisplay(_INTL("It won't have any effect."))
next false
end
if Kernel.pbConfirmMessageSerious(_INTL("Should {1} be reversed?", pokemon.name))
if Kernel.pbConfirmMessage(_INTL("Should {1} be reversed?", pokemon.name))
reverseFusion(pokemon)
scene.pbRefreshAnnotations(proc { |p| pbCheckEvolution(p, item) > 0 })
scene.pbRefresh
@@ -691,7 +819,7 @@ ItemHandlers::UseOnPokemon.add(:DNAREVERSER, proc { |item, pokemon, scene|
})
def reverseFusion(pokemon)
if pokemon.owner.name == "RENTAL"
if pokemon.owner.name == "RENTAL"
pbMessage(_INTL("You cannot reverse a rental pokémon!"))
return
end
@@ -707,6 +835,7 @@ def reverseFusion(pokemon)
pokemon.exp_when_fused_head = body_exp
pokemon.head_shiny, pokemon.body_shiny = pokemon.body_shiny, pokemon.head_shiny
pokemon.original_body, pokemon.original_head = pokemon.original_head, pokemon.original_body
# play animation
pbFadeOutInWithMusic(99999) {
fus = PokemonEvolutionScene.new
@@ -721,7 +850,7 @@ ItemHandlers::UseOnPokemon.add(:INFINITEREVERSERS, proc { |item, pokemon, scene|
scene.pbDisplay(_INTL("It won't have any effect."))
next false
end
if Kernel.pbConfirmMessageSerious(_INTL("Should {1} be reversed?", pokemon.name))
if Kernel.pbConfirmMessage(_INTL("Should {1} be reversed?", pokemon.name))
body = getBasePokemonID(pokemon.species, true)
head = getBasePokemonID(pokemon.species, false)
newspecies = (head) * Settings::NB_POKEMON + body
@@ -898,7 +1027,7 @@ def drawPokemonType(pokemon_id, x_pos = 192, y_pos = 264)
overlay = BitmapSprite.new(Graphics.width, Graphics.height, viewport).bitmap
pokemon = GameData::Species.get(pokemon_id)
typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
typebitmap = AnimatedBitmap.new("Graphics/Pictures/types")
type1_number = GameData::Type.get(pokemon.type1).id_number
type2_number = GameData::Type.get(pokemon.type2).id_number
type1rect = Rect.new(0, type1_number * 28, 64, 28)
@@ -1047,7 +1176,6 @@ ItemHandlers::UseOnPokemon.add(:SLOWPOKETAIL, proc { |item, pokemon, scene|
next evolveSlowpokeTail(item, pokemon, scene)
})
def evolveSlowpokeTail(item, pokemon, scene)
if pokemon.species != :SHELLDER
pbMessage(_INTL("It won't have any effect."))
@@ -1065,6 +1193,7 @@ def evolveSlowpokeTail(item, pokemon, scene)
}
return true
end
#
# ItemHandlers::UseOnPokemon.add(:SHINYSTONE, proc { |item, pokemon, scene|
# if (pokemon.isShadow? rescue false)
@@ -1212,8 +1341,8 @@ ItemHandlers::UseFromBag.add(:EXPALLOFF, proc { |item|
next 1 # Continue
})
ItemHandlers::BattleUseOnPokemon.add(:BANANA,proc { |item,pokemon,battler,choices,scene|
pbBattleHPItem(pokemon,battler,30,scene)
ItemHandlers::BattleUseOnPokemon.add(:BANANA, proc { |item, pokemon, battler, choices, scene|
pbBattleHPItem(pokemon, battler, 30, scene)
})
ItemHandlers::UseOnPokemon.add(:BANANA, proc { |item, pokemon, scene|
@@ -1344,7 +1473,7 @@ ItemHandlers::UseOnPokemon.add(:COFFEE, proc { |item, pokemon, scene|
})
ItemHandlers::BattleUseOnPokemon.add(:COFFEE, proc { |item, pokemon, battler, choices, scene|
battler.pbRaiseStatStage(:SPEED,(Settings::X_STAT_ITEMS_RAISE_BY_TWO_STAGES) ? 2 : 1,battler) if battler
battler.pbRaiseStatStage(:SPEED, (Settings::X_STAT_ITEMS_RAISE_BY_TWO_STAGES) ? 2 : 1, battler) if battler
pbBattleHPItem(pokemon, battler, 50, scene)
})
@@ -1366,8 +1495,8 @@ ItemHandlers::UseOnPokemon.add(:INCUBATOR, proc { |item, pokemon, scene|
next false
else
scene.pbDisplay(_INTL("Incubating..."))
scene.pbDisplay(_INTL("..."))
scene.pbDisplay(_INTL("..."))
scene.pbDisplay("...")
scene.pbDisplay("...")
scene.pbDisplay(_INTL("Your egg is ready to hatch!"))
pokemon.steps_to_hatch = 1
next true
@@ -1389,8 +1518,8 @@ ItemHandlers::UseOnPokemon.add(:INCUBATOR_NORMAL, proc { |item, pokemon, scene|
pokemon.steps_to_hatch = steps
end
scene.pbDisplay(_INTL("Incubating..."))
scene.pbDisplay(_INTL("..."))
scene.pbDisplay(_INTL("..."))
scene.pbDisplay("...")
scene.pbDisplay("...")
scene.pbDisplay(_INTL("The egg is closer to hatching!"))
# if pokemon.steps_to_hatch <= 1
@@ -1432,7 +1561,7 @@ def pbForceEvo(pokemon)
return false if evolutions.empty?
# if multiple evolutions, pick a random one
#(format of returned value is [[speciesNum, level]])
newspecies = evolutions[rand(evolutions.length - 1)][0]
newspecies = evolutions[rand(evolutions.length)][0]
return false if newspecies == nil
evo = PokemonEvolutionScene.new
evo.pbStartScreen(pokemon, newspecies)
@@ -1500,7 +1629,7 @@ def getPokemonPositionInParty(pokemon)
end
# don't remember why there's two Supersplicers arguments.... probably a mistake
def pbDNASplicing(pokemon, scene, item = :DNASPLICERS)
def pbDNASplicing(pokemon, scene, item = :DNASPLICERS, partyPosition =nil)
is_supersplicer = isSuperSplicersMechanics(item)
playingBGM = $game_system.getPlayingBGM
@@ -1534,7 +1663,7 @@ def pbDNASplicing(pokemon, scene, item = :DNASPLICERS)
return false
end
selectedHead = selectFusion(pokemon, poke2, is_supersplicer)
selectedHead, selected_sprite = selectFusion(pokemon, poke2, is_supersplicer)
if selectedHead == -1 # cancelled
return false
end
@@ -1554,7 +1683,7 @@ def pbDNASplicing(pokemon, scene, item = :DNASPLICERS)
end
if (Kernel.pbConfirmMessage(_INTL("Fuse {1} and {2}?", selectedHead.name, selectedBase.name)))
pbFuse(selectedHead, selectedBase, item)
pbFuse(selectedHead, selectedBase, item, selected_sprite)
pbRemovePokemonAt(chosen)
scene.pbHardRefresh
pbBGMPlay(playingBGM)
@@ -1573,8 +1702,8 @@ def pbDNASplicing(pokemon, scene, item = :DNASPLICERS)
end
end
else
# UNFUSE
return true if pbUnfuse(pokemon, scene, is_supersplicer)
partyPosition = getPokemonPositionInParty(pokemon) unless partyPosition
return true if pbUnfuse(pokemon, scene, partyPosition, nil)
end
end
@@ -1584,8 +1713,9 @@ def selectFusion(pokemon, poke2, supersplicers = false)
selectorWindow = FusionPreviewScreen.new(poke2, pokemon, supersplicers) # PictureWindow.new(picturePath)
selectedHead = selectorWindow.getSelection
fusion_pif_sprite = selectorWindow.get_selected_sprite if selectedHead.is_a?(Pokemon)
selectorWindow.dispose
return selectedHead
return selectedHead, fusion_pif_sprite
end
# firstOptionSelected= selectedHead == pokemon
@@ -1612,28 +1742,40 @@ end
# end
# end
def pbFuse(pokemon_body, pokemon_head, splicer_item)
def pbFuse(pokemon_body, pokemon_head, splicer_item, fusion_pif_sprite=nil)
original_head = pokemon_head.clone
original_body = pokemon_body.clone
use_supersplicers_mechanics = isSuperSplicersMechanics(splicer_item)
newid = (pokemon_body.species_data.id_number) * NB_POKEMON + pokemon_head.species_data.id_number
fus = PokemonFusionScene.new
if (fus.pbStartScreen(pokemon_body, pokemon_head, newid, splicer_item))
if (fus.pbStartScreen(pokemon_body, pokemon_head, newid, splicer_item, fusion_pif_sprite))
returnItemsToBag(pokemon_body, pokemon_head)
fus.pbFusionScreen(false, use_supersplicers_mechanics)
$game_variables[VAR_FUSE_COUNTER] += 1 # fuse counter
fus.pbEndScreen
$PokemonTemp.fuse_count_today = 0 unless $PokemonTemp.fuse_count_today
$PokemonTemp.fuse_count_today += 1
checkFuseChallenges(original_head,original_body)
return true
end
end
# Todo: refactor this, this is a mess
def pbUnfuse(pokemon, scene, supersplicers, pcPosition = nil)
def unfusePokemonLegacy(pokemon, scene, supersplicers, pcPosition = nil)
if pokemon.species_data.id_number > (NB_POKEMON * NB_POKEMON) + NB_POKEMON # triple fusion
scene.pbDisplay(_INTL("{1} cannot be unfused.", pokemon.name))
return false
end
if pokemon.owner.name == "RENTAL"
if pokemon.owner.name == "RENTAL"
scene.pbDisplay(_INTL("You cannot unfuse a rental pokémon!"))
return
end
@@ -1665,9 +1807,9 @@ def pbUnfuse(pokemon, scene, supersplicers, pcPosition = nil)
end
end
scene.pbDisplay(_INTL("Unfusing ... "))
scene.pbDisplay(_INTL(" ... "))
scene.pbDisplay(_INTL(" ... "))
pbSEPlay("Minimize")
pbMessage(_INTL("Unfusing...\\....\\....\\....\\wtnp[5]"))
pbSEPlay("Voltorb Flip Point")
if pokemon.exp_when_fused_head == nil || pokemon.exp_when_fused_body == nil
new_level = calculateUnfuseLevelOldMethod(pokemon, supersplicers)
@@ -1691,6 +1833,11 @@ def pbUnfuse(pokemon, scene, supersplicers, pcPosition = nil)
pokemon.exp_when_fused_head = nil
pokemon.exp_when_fused_body = nil
pokemon.pif_sprite = nil
poke1.pif_sprite=nil
poke2.pif_sprite = nil
if pokemon.shiny?
pokemon.shiny = false
if pokemon.bodyShiny? && pokemon.headShiny?
@@ -1710,8 +1857,10 @@ def pbUnfuse(pokemon, scene, supersplicers, pcPosition = nil)
# shiny was obtained already fused
if rand(2) == 0
pokemon.shiny = true
pokemon.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
else
poke2.shiny = true
poke2.natural_shiny = true if pokemon.natural_shiny && !pokemon.debug_shiny
end
end
end
@@ -1729,11 +1878,6 @@ def pbUnfuse(pokemon, scene, supersplicers, pcPosition = nil)
pokemon.ability_index = pokemon.body_original_ability_index if pokemon.body_original_ability_index
poke2.ability_index = pokemon.head_original_ability_index if pokemon.head_original_ability_index
pokemon.ability2_index = nil
pokemon.ability2 = nil
poke2.ability2_index = nil
poke2.ability2 = nil
pokemon.debug_shiny = true if pokemon.debug_shiny && pokemon.body_shiny
poke2.debug_shiny = true if pokemon.debug_shiny && poke2.head_shiny
@@ -1801,7 +1945,7 @@ def pbUnfuse(pokemon, scene, supersplicers, pcPosition = nil)
# scene.pbDisplay(p1.to_s + " " + p2.to_s)
scene.pbHardRefresh
scene.pbDisplay(_INTL("Your Pokémon were successfully unfused!"))
pbMessage(_INTL("Your Pokémon were successfully unfused!"))
return true
end
end
@@ -2119,7 +2263,6 @@ ItemHandlers::UseFromBag.add(:EXPALLOFF, proc { |item|
next 1 # Continue
})
ItemHandlers::UseInField.add(:BOXLINK, proc { |item|
blacklisted_maps = [
315, 316, 317, 318, 328, 343, # Elite Four
@@ -2139,12 +2282,12 @@ ItemHandlers::UseInField.add(:BOXLINK, proc { |item|
next 1
})
def changeOricorioFormFromItem(pokemon,form_name,new_form)
def changeOricorioFormFromItem(pokemon, form_name, new_form)
if !(Kernel.isPartPokemon(pokemon, :ORICORIO_1) ||
Kernel.isPartPokemon(pokemon, :ORICORIO_2) ||
Kernel.isPartPokemon(pokemon, :ORICORIO_3) ||
Kernel.isPartPokemon(pokemon, :ORICORIO_4))
scene.pbDisplay(_INTL("It had no effect."))
pbMessage(_INTL("It had no effect."))
return false
end
if changeOricorioForm(pokemon, new_form)
@@ -2160,47 +2303,47 @@ end
ItemHandlers::UseOnPokemon.add(:REDNECTAR, proc { |item, poke, scene|
form_name = "Baile"
form = 1
next changeOricorioFormFromItem(poke,form_name,form)
next changeOricorioFormFromItem(poke, form_name, form)
})
ItemHandlers::BattleUseOnPokemon.add(:REDNECTAR, proc { |item, poke, scene|
form_name = "Baile"
form = 1
next changeOricorioFormFromItem(poke,form_name,form)
next changeOricorioFormFromItem(poke, form_name, form)
})
ItemHandlers::UseOnPokemon.add(:YELLOWNECTAR, proc { |item, poke, scene|
form_name = "Pom-Pom"
form = 2
next changeOricorioFormFromItem(poke,form_name,form)
next changeOricorioFormFromItem(poke, form_name, form)
})
ItemHandlers::BattleUseOnPokemon.add(:YELLOWNECTAR, proc { |item, poke, scene|
form_name = "Pom-Pom"
form = 1
next changeOricorioFormFromItem(poke,form_name,form)
form = 2
next changeOricorioFormFromItem(poke, form_name, form)
})
ItemHandlers::UseOnPokemon.add(:PINKNECTAR, proc { |item, poke, scene|
form_name = "Pa'u"
form = 3
next changeOricorioFormFromItem(poke,form_name,form)
next changeOricorioFormFromItem(poke, form_name, form)
})
ItemHandlers::BattleUseOnPokemon.add(:PINKNECTAR, proc { |item, poke, scene|
form_name = "Pa'u"
form = 3
next changeOricorioFormFromItem(poke,form_name,form)
next changeOricorioFormFromItem(poke, form_name, form)
})
ItemHandlers::UseOnPokemon.add(:BLUENECTAR, proc { |item, poke, scene|
form_name = "Sensu"
form = 4
next changeOricorioFormFromItem(poke,form_name,form)
next changeOricorioFormFromItem(poke, form_name, form)
})
ItemHandlers::BattleUseOnPokemon.add(:BLUENECTAR, proc { |item, poke, scene|
form_name = "Sensu"
form = 4
next changeOricorioFormFromItem(poke,form_name,form)
})
next changeOricorioFormFromItem(poke, form_name, form)
})
@@ -27,7 +27,7 @@ def pbVariablePokemonMart(stock,currencyVariable,currency_name="Points",speech=n
cmdSell = -1
cmdQuit = -1
commands[cmdBuy = commands.length] = _INTL("Buy")
commands[cmdSell = commands.length] = _INTL("Sell") if !cantsell
#commands[cmdSell = commands.length] = _INTL("Sell") if !cantsell
commands[cmdQuit = commands.length] = _INTL("Quit")
cmd = pbMessage(
speech ? speech : _INTL("Welcome! How may I serve you?"),
@@ -141,6 +141,7 @@ class FusionTutorService
#compatibleMoves << :ANCHORSHOT if (is_fusion_of([:EMPOLEON, :STEELIX, :BELDUM, :METANG, :METAGROSS, :KLINK, :KLINKLANG, :KLANG, :ARON, :LAIRON, :AGGRON]) && hasType(:WATER)) || (is_fusion_of([:LAPRAS, :WAILORD, :KYOGRE]) && hasType(:STEEL))
compatibleMoves << :SPARKLINGARIA if (is_fusion_of([:JYNX, :JIGGLYPUFF, :WIGGLYTUFF]) && hasType(:WATER)) || is_fusion_of([:LAPRAS])
#compatibleMoves << :WATERSHURIKEN if is_fusion_of([:NINJASK, :LUCARIO, :ZOROARK, :BISHARP]) && hasType(:WATER)
compatibleMoves << :DRAGONHAMMER if is_fusion_of([:TROPIUS, :EXEGGUTOR]) && hasType(:DRAGON)
end
if includeLegendaries
#legendary moves (only available after a certain trigger, maybe a different npc)
@@ -1,4 +1,8 @@
class FusionQuiz
attr_accessor :silhouette_color
attr_accessor :windowed
attr_accessor :picture_offset_x
attr_accessor :picture_offset_y
#
# Possible difficulties:
@@ -23,10 +27,21 @@ class FusionQuiz
@score = 0
@current_streak = 0
@streak_multiplier = 0.15
@silhouette_color = Color.new(255, 255, 255, 200)
@windowed=true
@picture_offset_x = 0
@picture_offset_y = 0
@score_viewport = nil
@score_sprite = nil
@streak_viewport = nil
@streak_sprite = nil
end
def start_quiz(nb_rounds = 3)
create_score_display
nb_games_played= pbGet(VAR_STAT_FUSION_QUIZ_NB_TIMES)
pbSet(VAR_STAT_FUSION_QUIZ_NB_TIMES,nb_games_played+1)
@@ -35,20 +50,20 @@ class FusionQuiz
for i in 1..nb_rounds
if i == nb_rounds
pbMessage(_INTL("Get ready! Here comes the final round!"))
pbMessage(_INTL("Get ready! Here comes the final round!\\wtnp[10]"))
elsif i == 1
pbMessage(_INTL("Get ready! Here comes the first round!"))
pbMessage(_INTL("Get ready! Here comes the first round!\\wtnp[10]"))
else
pbMessage(_INTL("Get ready! Here comes round {1}!", i))
pbMessage(_INTL("Get ready! Here comes round {1}!\\wtnp[10]", i))
end
start_quiz_new_round(round_multiplier)
rounds_left = nb_rounds - i
if rounds_left > 0
pbMessage(_INTL("That's it for round {1}. You've cumulated {2} points so far.", i, @score))
prompt_next_round = pbMessage(_INTL("Are you ready to move on to the next round?", i), ["Yes", "No"])
pbMessage(_INTL("That's it for round {1}. You've cumulated {2} points so far.\\wtnp[20]", i, @score))
prompt_next_round = pbMessage(_INTL("Are you ready to move on to the next round?", i), [_INTL("Yes"), _INTL("No")])
if prompt_next_round != 0
prompt_quit = pbMessage(_INTL("You still have {1} rounds to go. You'll only keep your points if you finish all {2} rounds. Do you really want to quit now?", rounds_left, nb_rounds), ["Yes", "No"])
prompt_quit = pbMessage(_INTL("You still have {1} rounds to go. You'll only keep your points if you finish all {2} rounds. Do you really want to quit now?", rounds_left, nb_rounds), [_INTL("Yes"), _INTL("No")])
if prompt_quit
@abandonned = true
break
@@ -57,13 +72,52 @@ class FusionQuiz
round_multiplier += round_multiplier_increase
else
pbMessage(_INTL("This concludes our quiz! You've cumulated {1} points in total.", @score))
pbMessage(_INTL("Thanks for playing with us today!"))
pbMessage(_INTL("Thanks for playing!\\wtnp[20]"))
end
end
end_quiz()
end
def create_score_display
@score_viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@score_viewport.z = 99999
@score_sprite = BitmapSprite.new(200, 32, @score_viewport)
@score_sprite.x = Graphics.width - 230
@score_sprite.y = 10
refresh_score_display
@streak_viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@streak_viewport.z = 99999
@streak_sprite = BitmapSprite.new(200, 32, @streak_viewport)
@streak_sprite.x = Graphics.width - 230
@streak_sprite.y = 42
refresh_streak_ui
end
def refresh_score_display
return unless @score_sprite
@score_sprite.bitmap.clear
pbSetSystemFont(@score_sprite.bitmap)
text = _INTL("{1}", @score)
@score_sprite.bitmap.font.color = Color.new(160, 160, 160)
@score_sprite.bitmap.draw_text(1, 1, 200, 32, text, 2)
@score_sprite.bitmap.font.color = Color.new(255, 255, 255)
@score_sprite.bitmap.draw_text(0, 0, 200, 32, text, 2)
end
def dispose_score_display
@score_sprite&.dispose
@score_viewport&.dispose
@score_sprite = nil
@score_viewport = nil
@streak_sprite&.dispose
@streak_viewport&.dispose
@streak_sprite = nil
@streak_viewport = nil
end
def end_quiz()
dispose_score_display
hide_fusion_picture
Kernel.pbClearText()
previous_highest = pbGet(VAR_STAT_FUSION_QUIZ_HIGHEST_SCORE)
@@ -90,33 +144,38 @@ class FusionQuiz
end
pick_random_pokemon()
sprite_loader = BattleSpriteLoader.new
@pif_sprite = sprite_loader.select_new_pif_fusion_sprite(@head_id,@body_id)
show_fusion_picture(true)
correct_answers = []
#OBSCURED
correct_answers << new_question(calculate_points_awarded(base_points_q1, round_multiplier), _INTL("Which Pokémon is this fusion's body?"), @body_id, nil, true, :BODY)
pbMessage(_INTL("Next question!"))
pbMessage(_INTL("Next question!\\wtnp[10]"))
correct_answers << new_question(calculate_points_awarded(base_points_q2, round_multiplier), _INTL("Which Pokémon is this fusion's head?"), @head_id, nil, true, :HEAD)
#NON-OBSCURED
if !correct_answers[0] || !correct_answers[1]
show_fusion_picture(false)
pbMessage(_INTL("Okay, now's your chance to make up for the points you missed!"))
pbMessage(_INTL("Okay, now's your chance to make up for the points you missed!\\wtnp[15]"))
if !correct_answers[0] #1st question redemption
new_question(calculate_points_awarded(base_points_q1_redemption, round_multiplier), "Which Pokémon is this fusion's body?", @body_id, @body_choices, false, :BODY)
new_question(calculate_points_awarded(base_points_q1_redemption, round_multiplier), _INTL("Which Pokémon is this fusion's body?"), @body_id, @body_choices, false, :BODY)
if !correct_answers[1]
pbMessage(_INTL("Next question!"))
pbMessage(_INTL("Next question!\\wtnp[10]"))
end
end
if !correct_answers[1] #2nd question redemption
new_question(calculate_points_awarded(base_points_q2_redemption, round_multiplier), "Which Pokémon is this fusion's head?", @head_id, @head_choices, false, :HEAD)
new_question(calculate_points_awarded(base_points_q2_redemption, round_multiplier), _INTL("Which Pokémon is this fusion's head?"), @head_id, @head_choices, false, :HEAD)
end
else
pbSEPlay("Applause", 80)
pbMessage(_INTL("Wow! A perfect round! You get {1} more points!", perfect_round_points))
show_fusion_picture(false, 100)
pbMessage(_INTL("Let's see what this Pokémon looked like!"))
pbMessage(_INTL("Wow! A perfect round! You get {1} more points!\\wtnp[15]", perfect_round_points))
pbMessage(_INTL("Let's see what this Pokémon looked like...\\wtnp[20]"))
show_fusion_picture(false)
fusion_name= GameData::Species.get(fusionOf(@head_id,@body_id)).name
pbMessage(_INTL("It's... \\C[1]{1}\\C[0]!",fusion_name))
end
current_streak_dialog()
hide_fusion_picture()
@@ -136,7 +195,7 @@ class FusionQuiz
def new_question(points_value, question, answer_id, choices, other_chance_later,question_type)
points_value = points_value.to_i
answer_name = getPokemon(answer_id).real_name
answer_name = getPokemon(answer_id).name
answered_correctly = give_answer(question, answer_id, choices,question_type)
award_points(points_value) if answered_correctly
question_answer_followup_dialog(answered_correctly, answer_name, points_value, other_chance_later)
@@ -153,42 +212,52 @@ class FusionQuiz
refresh_streak_ui()
end
def refresh_streak_ui()
shadow_color = Color.new(160,160,160)
base_color_low_streak = Color.new(72,72,72)
base_color_medium_streak = Color.new(213,254,205)
base_color_high_streak = Color.new(100,232,96)
streak_color= base_color_low_streak
def refresh_streak_ui
base_color_low_streak = Color.new(72, 72, 72)
base_color_medium_streak = Color.new(213, 254, 205)
base_color_high_streak = Color.new(100, 232, 96)
streak_color = base_color_low_streak
streak_color = base_color_medium_streak if @current_streak >= 2
streak_color = base_color_high_streak if @current_streak >= 4
streak_color = base_color_high_streak if @current_streak >= 4
message = _INTL("Streak: {1}",@current_streak)
Kernel.pbClearText()
Kernel.pbDisplayText(message,420,340,nil,streak_color)
# Update persistent sprite
if @streak_sprite
@streak_sprite.bitmap.clear
pbSetSystemFont(@streak_sprite.bitmap)
text = _INTL("Streak: {1}", @current_streak)
@streak_sprite.bitmap.font.color = Color.new(0, 0, 0)
@streak_sprite.bitmap.draw_text(1, 1, 200, 32, text, 2)
@streak_sprite.bitmap.font.color = streak_color
@streak_sprite.bitmap.draw_text(0, 0, 200, 32, text, 2)
end
end
def award_points(nb_points)
@score += nb_points
refresh_score_display
end
def question_answer_followup_dialog(answered_correctly, correct_answer, points_awarded_if_win, other_chance_later = false)
if !other_chance_later
pbMessage(_INTL("And the correct answer was..."))
pbMessage("...")
pbMessage("#{correct_answer}!")
pbMessage(_INTL("And the correct answer was...\\wtnp[10]"))
pbMessage(_INTL("...\\wtnp[10]"))
pbMessage(_INTL("{1}!", correct_answer))
end
if answered_correctly
pbSEPlay("itemlevel", 80)
increase_streak
pbMessage(_INTL("That's a correct answer!"))
pbMessage(_INTL("You're awarded {1} points for your answer. Your current score is {2}", points_awarded_if_win, @score.to_s))
pbMessage(_INTL("That's a correct answer!\\wtnp[10]"))
pbMessage(_INTL("You're awarded {1} points for your answer. Your current score is {2}.\\wtnp[20]", points_awarded_if_win, @score.to_s))
else
pbSEPlay("buzzer", 80)
break_streak
pbMessage(_INTL("Unfortunately, that was a wrong answer."))
pbMessage(_INTL("But you'll get another chance at it!")) if other_chance_later
pbMessage(_INTL("Unfortunately, that was a wrong answer.\\wtnp[10]"))
pbMessage(_INTL("But you'll get another chance at it!\\wtnp[15]")) if other_chance_later
end
end
@@ -198,11 +267,11 @@ class FusionQuiz
if @current_streak % 4 == 0
extra_points = (@current_streak/4)*streak_base_worth
if @current_streak >= 8
pbMessage(_INTL("That's {1} correct answers in a row. You're on a roll!", @current_streak))
pbMessage(_INTL("That's {1} correct answers in a row. You're on a roll!\\wtnp[20]", @current_streak))
else
pbMessage(_INTL("That's {1} correct answers in a row. You're doing great!", @current_streak))
pbMessage(_INTL("That's {1} correct answers in a row. You're doing great!\\wtnp[20]", @current_streak))
end
pbMessage(_INTL("Here's {1} extra points for maintaining a streak!",extra_points))
pbMessage(_INTL("Here's {1} extra points for maintaining a streak!\\wtnp[15]",extra_points))
award_points(extra_points)
end
end
@@ -210,14 +279,17 @@ class FusionQuiz
def show_fusion_picture(obscured = false, x = nil, y = nil)
hide_fusion_picture()
spriteLoader = BattleSpriteLoader.new
bitmap = spriteLoader.load_fusion_sprite(@head_id, @body_id)
bitmap = spriteLoader.load_pif_sprite_directly(@pif_sprite)
bitmap.scale_bitmap(Settings::FRONTSPRITE_SCALE)
@previewwindow = PictureWindow.new(bitmap)
@previewwindow.opacity = 0 unless @windowed
@previewwindow.y = y ? y : 30
@previewwindow.y += @picture_offset_y
@previewwindow.x = x ? x : (@difficulty == :ADVANCED ? 275 : 100)
@previewwindow.x += @picture_offset_x
@previewwindow.z = 100000
if obscured
@previewwindow.picture.pbSetColor(255, 255, 255, 200)
@previewwindow.picture.pbSetColorValue(@silhouette_color)
end
end
@@ -235,7 +307,8 @@ class FusionQuiz
def give_answer(prompt_message, answer_id, choices,question_type=:BODY)
question_answered = false
answer_pokemon_name = getPokemon(answer_id).real_name
answer_pokemon_name = getPokemon(answer_id).name
choices = generate_new_choices(answer_id,question_type) unless choices
while !question_answered
if @difficulty == :ADVANCED
player_answer = prompt_pick_answer_advanced(prompt_message, answer_id)
@@ -245,8 +318,6 @@ class FusionQuiz
confirmed = pbMessage(_INTL("Is this your final answer?"), [_INTL("Yes"), _INTL("No")])
if confirmed == 0
question_answered = true
else
should_generate_new_choices = false
end
end
return player_answer == answer_pokemon_name
@@ -258,7 +329,7 @@ class FusionQuiz
# Get a list all pokemon in the same egg group
matching_egg_group = []
for num in 1..NB_POKEMON
for num in 1..NB_POKEMON-4
next if pokemon.id_number == num
next if matching_egg_group.include?(num)
new_pokemon = ::GameData::Species.get(num)
@@ -272,7 +343,7 @@ class FusionQuiz
for index in 1..amount_required
if matching_egg_group[index].nil?
# If there's not enough pokemon in the list (e.g. for Ditto), get anything
new_pokemon = rand(1..NB_POKEMON) until !choices.include?(new_pokemon) && new_pokemon != pokemon.id_number
new_pokemon = rand(1..NB_POKEMON-4) until !choices.include?(new_pokemon) && new_pokemon != pokemon.id_number
choices << new_pokemon
else
choices << matching_egg_group[index]
@@ -283,6 +354,7 @@ class FusionQuiz
end
def prompt_pick_answer_regular(prompt_message, real_answer, choices, question_type=:BODY)
echoln choices
if choices && choices.is_a?(Array)
commands = choices.shuffle
else
@@ -300,7 +372,7 @@ class FusionQuiz
commands = []
choices.each do |dex_num, i|
species = getPokemon(dex_num)
commands.push(species.real_name)
commands.push(species.name)
end
if question_type == :BODY
@body_choices = commands
@@ -312,12 +384,12 @@ class FusionQuiz
def prompt_pick_answer_advanced(prompt_message, answer)
commands = []
for dex_num in 1..NB_POKEMON
for dex_num in 1..NB_POKEMON-4
species = getPokemon(dex_num)
commands.push([dex_num - 1, species.real_name, species.real_name])
commands.push([dex_num - 1, species.name, species.name])
end
pbMessage(prompt_message)
return pbChooseList(commands, 0, nil, 1)
return pbChooseListWithFilter(commands, 0, nil, 1,0,42,_INTL("Type with your keyboard"))
end
def get_score
@@ -0,0 +1,33 @@
def berryContest(map_id,plots_event_ids=[])
total_yield = 0
berry_types= []
plots_event_ids.each do |event_id|
berryData = $PokemonGlobal.eventvars[[map_id, event_id]]
if berryData
berry_type = berryData[1]
growth_stage= berryData[0]
if berry_type && growth_stage == 5
berry_types << berry_type unless berry_types.include?(berry_type)
berry_yield = calculateBerryYield(berryData)
total_yield += berry_yield
end
end
end
return total_yield + berry_types.length
end
def calculateBerryYield(berryData)
berryvalues = GameData::BerryPlant.get(berryData[1])
berrycount = [berryvalues.maximum_yield - berryData[6], berryvalues.minimum_yield].max
return berrycount
end
def berry_contest_results(player_score)
contestants = {"Evelyn" => rand(5..8),
"Martin" => rand(4..8),
"Sarah" => rand(3..5)}
contestants[$Trainer.name] = player_score
results = contestants.sort_by { |name, score| score }
return results
end
@@ -0,0 +1,29 @@
class Game_Event < Game_Character
#Detects if the event has a specific comment command at the top (can pass multiple comments to test for as an array)
def detectCommentCommand(comment_text,event)
comment_text = [comment_text] if comment_text.is_a?(String)
page = pbGetActiveEventPage(event)
return unless page
first_command = page.list[0]
return nil if !(first_command.code == 108 || first_command.code == 408)
comments = first_command.parameters
return comments.any? { |str| comment_text.include?(str) }
end
# def getCommentCommandAtTop
# page = pbGetActiveEventPage(event)
# first_command = page.list[0]
# return nil if !(first_command.code == 108 || first_command.code == 408)
# comments = first_command.parameters.first
# return comments
# end
end
@@ -1,4 +1,11 @@
def turnEventTowardsEvent(turning, turnedTowards)
if turnedTowards.is_a?(Integer)
turnedTowards = $game_map.events[turnedTowards]
end
if turning.is_a?(Integer)
turning = $game_map.events[turning]
end
event_x = turnedTowards.x
event_y = turnedTowards.y
if turning.x < event_x
@@ -12,6 +19,13 @@ def turnEventTowardsEvent(turning, turnedTowards)
end
end
def resetFrames(event)
if event.is_a?(Integer)
event = $game_map.events[event]
end
event.pattern=0
end
def turnPlayerTowardsEvent(event)
if event.is_a?(Integer)
event = $game_map.events[event]
@@ -55,14 +69,23 @@ end
# 1: wood
def sign(message, type = 0)
signId = "sign_#{type}"
formatted_message = "\\sign[#{signId}]#{message}"
translated = MessageTypes.getFromMapHash($game_map.map_id, message)
formatted_message = "\\sign[#{signId}]#{translated}"
pbMessage(formatted_message)
end
def setEventGraphicsToPokemon(species, eventId)
def setEventGraphicsToPokemon(species, eventId, shiny=false)
event = $game_map.events[eventId]
return if !event
event.character_name = "Followers/#{species.to_s}"
shiny_folder= shiny ? "Shiny/" : ""
path = "Followers/#{shiny_folder}#{species.to_s}"
echoln path
if pbResolveBitmap("Graphics/Characters/" +path)
event.character_name = path
else
path = "Followers/#{shiny_folder}#{species.to_s}_fly"
event.character_name = path
end
event.refresh
end
@@ -81,3 +104,591 @@ def idleHatEvent(hatId, time, switchToActivate = nil)
$game_switches[switchToActivate] = true if switchToActivate
obtainHat(hatId)
end
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
def kick_ball(eventId, obstacleName = nil, targetDestination = nil, targetSwitch = nil)
target_radius = 2
ball = $game_map.events[eventId]
return if !ball
dir = $game_player.direction
dx = (dir == DIRECTION_RIGHT ? 1 : dir == DIRECTION_LEFT ? -1 : 0)
dy = (dir == DIRECTION_DOWN ? 1 : dir == DIRECTION_UP ? -1 : 0)
# Shorter kick distance — scales gently with speed
player_speed = $game_player.move_speed
remaining_distance = [player_speed * 0.8, 1].max.floor
pbSEPlay("jump", 80, 100) rescue nil
pbWait(3)
current_dir = dir
total_bounces = 0
max_bounces = 3
will_pop = false
while remaining_distance > 0 && total_bounces < max_bounces
travel = 0
while travel < remaining_distance
test_x = ball.x + dx * (travel + 1)
test_y = ball.y + dy * (travel + 1)
event_at_test = $game_map.get_event_at_position(test_x, test_y)
if event_at_test && event_at_test.name == obstacleName && event_at_test.active?
ball.through = true
will_pop = true
else
break if !$game_map.passable?(test_x - dx, test_y - dy, current_dir) ||
!$game_map.passable?(test_x, test_y, current_dir)
end
travel += 1
end
if travel > 0
ball.jump(dx * travel, dy * travel)
pbWait(6)
end
if travel < remaining_distance
pbSEPlay("jump", 80, 80) rescue nil
total_bounces += 1
remaining_distance = [remaining_distance / 2.0, 1].max.floor
pbWait(6)
dx *= -1
dy *= -1
current_dir = case current_dir
when DIRECTION_UP then DIRECTION_DOWN
when DIRECTION_DOWN then DIRECTION_UP
when DIRECTION_LEFT then DIRECTION_RIGHT
when DIRECTION_RIGHT then DIRECTION_LEFT
end
bounce_dist = [remaining_distance / 2.0, 1].max.floor
ball.jump(dx * bounce_dist, dy * bounce_dist)
pbWait(8)
else
remaining_distance = 0
end
# After it lands
if will_pop
pbWait(24)
pbSetSelfSwitch(eventId, "A", true)
elsif targetDestination && targetSwitch
pbWait(24)
dist = (ball.x - targetDestination[0]).abs + (ball.y - targetDestination[1]).abs
if dist <= target_radius
$game_switches[targetSwitch] = true
$scene.reset_map(false)
end
end
end
end
def showTimeWindow
timeText = pbGetTimeNow.strftime(_INTL("%I:%M %p"))
window = LocationWindow.new(timeText)
window.set_close_automatically(false)
$scene.spriteset.addUserSprite(window)
return window
end
def updateTimeWindow(window)
return if !window || window.disposed?
window.text = pbGetTimeNow.strftime(_INTL("%I:%M %p"))
end
def update_weather(last_weather_hour)
now = pbGetTimeNow
current_hour = now.hour
if current_hour != last_weather_hour
if current_hour % 4 == 0 # Update every 4 hours
$game_weather.update_weather
end
last_weather_hour = current_hour
end
return if last_weather_hour
end
def sit_on_chair
pbSEPlay("jump", 80, 100)
max_faster_time = 20
# Enter sitting state
$game_temp.faster_time = 4
is_outdoor = isOutdoor()
time_window = showTimeWindow if is_outdoor
$game_player.through = true
$game_player.jump_forward
$game_player.turn_180
$game_player.through = false
last_weather_hour = pbGetTimeNow.hour
time_on_chair = 0
loop do
Graphics.update
Input.update
pbUpdateSceneMap
if is_outdoor
updateTimeWindow(time_window)
last_weather_hour = update_weather(last_weather_hour) if time_on_chair % 100 == 0
time_on_chair += 1
if time_on_chair % 100 == 0
$game_temp.faster_time += 1 if $game_temp.faster_time < max_faster_time
end
end
direction = checkInputDirection
next if !direction
facing_terrain = $game_player.pbFacingTerrainTag(direction)
if facing_terrain&.chair
pbSEPlay("jump", 80, 100)
$game_player.direction_fix = true
$game_player.jumpTowards(direction)
$game_player.direction_fix = false
else
passable = $game_map.passable?($game_player.x, $game_player.y, direction)
dest_x = $game_player.x + (direction == 6 ? 1 : direction == 4 ? -1 : 0)
dest_y = $game_player.y + (direction == 2 ? 1 : direction == 8 ? -1 : 0)
if passable #&& !$game_map.event_at_position(dest_x, dest_y) #todo Meant to make it so that you can't get stuck, but also prevents from interacting with
$game_player.turn_generic(direction)
$game_player.jump_forward
break
else
$game_player.turn_generic(direction)
$game_player.turn_180
end
end
pbWait(8)
end
ensure
# Always clean up
$game_temp.faster_time = nil
time_window.dispose if time_window && !time_window.disposed?
end
def checkInputDirection
return DIRECTION_UP if Input.trigger?(Input::UP)
return DIRECTION_DOWN if Input.trigger?(Input::DOWN)
return DIRECTION_LEFT if Input.trigger?(Input::LEFT)
return DIRECTION_RIGHT if Input.trigger?(Input::RIGHT)
return nil
end
def getOnBoat
set_player_graphics("boat_briney_peeko")
$PokemonTemp.prevent_ow_battles = true
$PokemonGlobal.boat = true
end
def getOffBoat
reset_player_graphics
$PokemonTemp.prevent_ow_battles = false
$PokemonGlobal.boat = false
$game_map.refresh
end
def check_beach_seashell
pbMessage(_INTL("{1} flipped the seashell over...", $Trainer.name))
pearl_chance = 2
heartscale_chance = 20
pokemon_chance = 40
roll = rand(1..100)
if roll <= pearl_chance
pbReceiveItem(:PEARL)
elsif roll <= pearl_chance + heartscale_chance
pbReceiveItem(:HEARTSCALE)
elsif roll <= pearl_chance + heartscale_chance + pokemon_chance
possible_pokemon = [:KRABBY] # if added to the game, also dwebble, binacle?
event = $game_map.events[@event_id]
# Spawn Pokémon
level = rand(8..16)
pbWait(4)
playAnimation(Settings::EXCLAMATION_ANIMATION_ID, $game_player.x, $game_player.y)
spawn_random_overworld_pokemon_group([possible_pokemon.sample, level], 1, 3, [event.x, event.y], :Cave)
else
# Nothing
pbMessage(_INTL("...There's nothing there."))
end
end
# shortcut for events
def spawn_near(species, level, group_size)
spawn_random_overworld_pokemon_group([species, level], 1, group_size)
end
def clefairy_minigame(length = 4, clefairy_event_id = nil)
if clefairy_event_id
event = $game_map.events[clefairy_event_id]
end
possible_elements = [_INTL("Left!"), _INTL("Up!"), _INTL("Right!"), _INTL("Down!")]
pbMessage(_INTL("Listen up and remember this!"))
sequence = []
message = ""
(0...length).each { |i|
element = possible_elements.sample
sequence << element
message += element
message += "\\wt[20]"
message += " "
}
message += "\\wtnp[40]"
pbWait(8)
pbMessage(message)
pbMessage(_INTL("Get ready... Press the buttons!\\wtnp[20]"))
player_input = []
loop do
if Input.trigger?(Input::LEFT)
player_input << possible_elements[0]
pbSEPlay("GUI save choice", 80, 100)
end
if Input.trigger?(Input::UP)
player_input << possible_elements[1]
pbSEPlay("GUI save choice", 80, 100)
end
if Input.trigger?(Input::RIGHT)
player_input << possible_elements[2]
pbSEPlay("GUI save choice", 80, 100)
end
if Input.trigger?(Input::DOWN)
player_input << possible_elements[3]
pbSEPlay("GUI save choice", 80, 100)
end
if Input.trigger?(Input::BACK)
pbSEPlay("GUI sel buzzer", 80, 100)
return false
end
Graphics.update
Input.update
break if player_input.size == sequence.size
end
pbWait(10)
if player_input == sequence
pbSEPlay("GUI naming confirm", 80, 100)
pbMEPlay("clefairy_correct",100)
pbMessage(_INTL("Correct!\\wtnp[40]"))
12.times do
event.turn_left_90 if event
pbWait(20)
end
return true
else
pbSEPlay("GUI sel buzzer", 80, 100)
pbMessage(_INTL("Incorrect!\\wtnp[40]"))
return false
end
end
# Switch 20
def isDebugMode()
return $DEBUG
end
def side_stairs_right
case $game_player.direction
when DIRECTION_RIGHT # Going up
destination_x = $game_player.x + 1
destination_y = $game_player.y - 1
if $game_player.destination_is_passable(destination_x, destination_y)
$game_player.move_upper_right
elsif $game_player.destination_is_passable(destination_x, $game_player.y)
$game_player.move_right
end
when DIRECTION_LEFT # Going down
destination_x = $game_player.x - 1
destination_y = $game_player.y + 1
if $game_player.destination_is_passable(destination_x, destination_y)
$game_player.move_lower_left
elsif $game_player.destination_is_passable(destination_x, $game_player.y)
$game_player.move_left
end
end
end
def side_stairs_left
case $game_player.direction
when DIRECTION_LEFT # Going up
destination_x = $game_player.x - 1
destination_y = $game_player.y - 1
if $game_player.destination_is_passable(destination_x, destination_y)
$game_player.move_upper_left
elsif $game_player.destination_is_passable(destination_x, $game_player.y)
$game_player.move_left
end
when DIRECTION_RIGHT # Going down
destination_x = $game_player.x + 1
destination_y = $game_player.y + 1
if $game_player.destination_is_passable(destination_x, destination_y)
$game_player.move_lower_right
elsif $game_player.destination_is_passable(destination_x, $game_player.y)
$game_player.move_right
end
end
end
def get_random_trend
items = list_all_item_names.reject { |name| name.include?("TM") || name.include?("HM") || name.include?("unknown_item") }
name1, name2 = items.sample(2)
word1 = name1.split.first
word2 = name2.split[1] || name2.split.first
"#{word1} #{word2}"
end
def trendSet(option1, option2)
choice = pbMessage(_INTL("What do you think? Do you think any of these have any potential?"), [_INTL("Not really..."), "#{option1} is pretty cool!", "I like #{option2}!"])
case choice
when 0
return false
when 1
pbSet(VAR_TRENDY_PHRASE, option1)
return true
when 2
pbSet(VAR_TRENDY_PHRASE, option2)
return true
end
return false
end
def vendingMachine(stock)
pbPokemonMart(stock, _INTL("It's a vending machine. What do you want to buy?"), true, _INTL(""), _INTL("Purchase anything else?"))
end
# Shiny egg of a random Pokemon (from a list)
def obtainBirthdayGift
possible_species =
[
:PICHU, :CLEFFA, :IGGLYBUFF, :TOGEPI, :EEVEE, :HAPPINY, :BUDEW, :CHINGLING, :MUNCHLAX, :RIOLU,
]
species = possible_species.sample
pokemon = Pokemon.new(species, Settings::EGG_LEVEL)
pokemon.shiny = true
pokemon.natural_shiny = true
pokemon.moves[0] = Pokemon::Move.new(:HOLDHANDS)
pbGenerateEgg(pokemon)
end
# Called from an event. The event's name must be the legendary Pokemon's species
# Returns true is it's not in $trainer.caught_legendaries or $trainer.encountered_legendaries
# Returns false if it is
def is_legendary_active?(species)
$Trainer.caught_legendaries = [] unless $Trainer.caught_legendaries
$Trainer.encountered_legendaries = [] unless $Trainer.encountered_legendaries
is_caught = $Trainer.caught_legendaries.include?(species)
is_encountered = $Trainer.encountered_legendaries.include?(species)
return !is_caught && !is_encountered
end
def setEventGraphicPokemon(species, event_id)
species_data = GameData::Species.get(species)
event = $game_map.events[event_id]
return unless event
if event
echoln event.get_page(1)
event.get_page(1).graphic.character_name = getOverworldLandPath(species_data)
# event.character_name= #"Graphics/Characters/#{getOverworldLandPath(species_data)}"
event.refresh
end
end
# ZORUA FOREST
#
ZORUA_FOLLOWED_VARIABLE = 1031
def shapeshift_zorua
zorua_events = [32, 36, 38, 34, 37, 61, 41]
nb_active = $game_variables[ZORUA_FOLLOWED_VARIABLE]
for i in 0..nb_active
event_id = zorua_events[i]
event = $game_map.events[event_id]
next unless event
next if event.erased
encounter_type = getTimeBasedEncounter(:Land)
disguise_species = getRandomPokemonFromRoute(:ZORUA, encounter_type)
species_data = GameData::Species.get(disguise_species)
event.character_name = getOverworldLandPath(species_data)
event.refresh
end
end
def transfer_subtle(new_x, new_y)
return if isWearingHat(HAT_ZOROARK)
map = $game_map.map_id
$game_temp.player_new_map_id = map
$game_temp.player_new_x = new_x
$game_temp.player_new_y = new_y
pbFadeOutIn {
$scene.transfer_player(false)
shapeshift_zorua
}
end
def this_event()
return $game_map.events[@event_id]
end
def get_event(id)
return $game_map.events[id]
end
def select_tv_show_quests(episode = 0)
all_episodes = [
[],
[:main_stolen_parts, :route_102_rematch, :petalburg_berry, :route104_rivalWeather, :petalburgwoods_spores],
[:main_steven_letter, :route104_oricorio, :route104_oricorio_forms, :rustboro_whismur, :rustboro_shiny],
[:main_devon_parts, :dewford_fishing, :route109_tanning, :route109_seahouse, :route109_beachball],
[:magma_help_grunts, :aqua_help_grunts],
[:mauville_quests_1]
]
episode_quests = all_episodes[episode] || []
completed_ids = get_completed_quests.map { |q| q.id.to_s }
filtered = episode_quests.select { |q| completed_ids.include?(q.to_s) }
#filtered = episode_quests # For debugging with all quests
filtered.sample(2)
end
def get_show_dialog(quest_id)
echoln quest_id
case quest_id
# Episode 1
when :main_stolen_parts
return _INTL("Sootopolis Void attacked the city and tried to steal a precious package from the Rangers headquarters. Littleroot Crimson was able to stop him, but now he's coming back with a vengeance...")
when :route_102_rematch
return _INTL("There was a part where Littleroot Crimson had a rematch with Fallarbor Bordeaux and he finally evolved his Combusken.")
when :petalburg_berry
return _INTL("There was an entire subplot about Rustboro Ivory entering a berry-growing contest that she ended up winning with a super-mutant berry.")
when :route104_rivalWeather
return _INTL("There was a part where Lilicove Viridian waited until the wind picked up to catch a Pidgeot that had been terrorizing the town.")
when :petalburgwoods_spores
return _INTL("At one point, Mauville Yellow met a scientist in the woods and helped him collect highly toxic spore.")
# Episode 2
when :main_steven_letter
return _INTL("Littleroot Crimson seeked out the help of the grandmaster that was hiding at the end of the dark cave.")
when :route104_oricorio
return _INTL("Rustboro Ivory befriended that lonely Oricorio in the flowers field.")
when :route104_oricorio_forms
return _INTL("The Oricorio kept switching forms!")
when :rustboro_whismur
return _INTL("Mauville Yellow fused a Pellipper with Exploud to create a sonic weapon. And then it ended up being much too loud, it was so funny!")
when :rustboro_shiny
return _INTL("Pacifidlog Cobalt found that shiny Azumarill. I never saw it coming!")
# Episode 3
when :main_devon_parts
return _INTL("At least, Littleroot Crimson finally delivered that precious package. I can't wait to see what happens next with that.")
when :dewford_fishing
return _INTL("Hey, that part where Fallarbor Bordeaux fished up that Dragalge was pretty neat.")
when :route109_tanning
return _INTL("That whole subplot about Pacifidlog Cobalt trying to get a tan definitely dragged on a bit...")
when :route109_seahouse
return _INTL("Although that scene with Lilicove Viridian beating up all the bad guys in the beach house was really fun!")
when :route109_beachball
return _INTL("The chase sequence with the Kingler when Mauville Yellow was carrying that beach ball was really funny though!")
# Episode 4
when :magma_help_grunts
return _INTL("I never expected Littleroot Crimson to infiltrate the villains's lair like that!")
when :aqua_help_grunts
return _INTL("I never expected Littleroot Crimson to infiltrate the villains's lair like that!")
# Episode 5
when :mauville_quests_1
return "" # directly in the event's dialog
end
end
def setDayCareOverworlds(land_event_ids = [], water_event_ids = [])
day_care_map = 74
return unless $game_map.map_id == day_care_map
land_event_ids.each_with_index do |event_id, i|
event = $game_map.events[event_id]
pbSetSelfSwitch(event.id, "A", false, day_care_map)
event.character_name = ""
end
water_event_ids.each_with_index do |event_id, i|
event = $game_map.events[event_id]
pbSetSelfSwitch(event.id, "A", false, day_care_map)
event.character_name = ""
end
$PokemonGlobal.daycare.each_with_index do |day_care_slot, i|
day_care_pokemon = day_care_slot[0]
next unless day_care_pokemon
if day_care_pokemon.hasType?(:WATER)
event_id = water_event_ids[i]
swimming = true
else
event_id = land_event_ids[i]
swimming = false
end
event = $game_map.events[event_id]
pbSetSelfSwitch(event.id, "A", true, day_care_map)
$game_map.refresh
overworldPath = getRoamingSprite(day_care_pokemon.species_data, day_care_pokemon.isShiny?)
is_flying = overworldPath.include?("_fly")
event.step_anime = true if is_flying
echoln overworldPath
event.character_name = overworldPath if overworldPath
if swimming
event.forced_bush_depth = 20
event.step_anime = true
event.set_animation_speed(2)
event.calculate_bush_depth
end
end
end
def getRandomWonderTradeNames(number=1)
names= RandTrainerNames_female + RandTrainerNames_male
return names.sample(number)
end
def getRandomUnisexName
return RandTrainerNames_unisex.sample
end
@@ -68,6 +68,7 @@ Events.onStepTaken += proc { |sender, e|
spawnSilhouette()
}
Events.onMapChange += proc { |sender, e|
next unless Settings::KANTO
next if $PokemonTemp.tempEvents.empty?
$PokemonTemp.pbClearTempEvents()
}
@@ -75,30 +76,7 @@ Events.onMapChange += proc { |sender, e|
def getRandomPositionOnPerimeter(width, height, center_x, center_y, variance=0,edge=nil)
half_width = width / 2.0
half_height = height / 2.0
# Randomly select one of the four edges of the rectangle
edge = rand(4) if !edge
case edge
when 0 # Top edge
random_x = center_x + rand(-half_width..half_width)
random_y = center_y - half_height
when 1 # Bottom edge
random_x = center_x + rand(-half_width..half_width)
random_y = center_y + half_height
when 2 # Left edge
random_x = center_x - half_width
random_y = center_y + rand(-half_height..half_height)
when 3 # Right edge
random_x = center_x + half_width
random_y = center_y + rand(-half_height..half_height)
end
return random_x.round, random_y.round
end
# def launchSilhouetteCommonEvent(event)
# $scene.spriteset.addUserAnimation(VIRUS_ANIMATION_ID, event.x, event.y, true)
@@ -16,4 +16,50 @@ def showPokemonInPokeballWithMessage(pif_sprite, message, x_position = nil, y_po
displaySpriteWindowWithMessage(pif_sprite, message, 90, -10, 201)
background_sprite.dispose
foreground_sprite.dispose
end
def set_player_graphics(name)
$game_player.setPlayerGraphicsOverride(name)
$game_map.refresh
end
def reset_player_graphics()
$game_player.removeGraphicsOverride
end
def get_spritecharacter_for_event(event_id)
for sprite in $scene.spriteset.character_sprites
if sprite.character.id == event_id
return sprite
end
end
end
def get_player_sprite_character
return nil if !$scene || !$scene.spriteset
for sprite in $scene.spriteset.character_sprites
echoln "sprite: #{sprite}, character: #{sprite.character}"
if sprite.character == $game_player
return sprite
end
end
return nil
end
def setFog(intensity)
current_weather = $game_weather.current_weather[$game_map.map_id]
if current_weather && current_weather[0] == :Fog
starting_intensity = current_weather[1]
else
starting_intensity =0
end
echoln starting_intensity
$scene.spriteset.fade_in_fog(starting_intensity,intensity)
end
def show_starter(species, pokemonName)
pif_sprite = BattleSpriteLoader.new.get_pif_sprite_from_species(species)
showPokemonInPokeballWithMessage(pif_sprite, _INTL("This Poké Ball contains {1}",pokemonName))
return pif_sprite
end
@@ -1,225 +1,225 @@
class Game_Temp
attr_accessor :temp_waterfall
attr_accessor :waterfall_sprites
attr_accessor :splash_sprites
attr_accessor :splash_coords
end
def generate_dynamic_waterfall(starting_x_position, waterfall_top_y, thickness=1)
map_height = $game_map.height - 8
echoln map_height
boulder_positions = []
CIANWOOD_BOULDER_IDS.each do |event_id|
event = $game_map.events[event_id]
boulder_positions << [event.x, event.y]
end
# Add columns from starting_x_position to the right
active_columns = []
(starting_x_position...(starting_x_position + thickness)).each do |x|
break if x >= $game_map.width # Don't go past map edge
active_columns << { x: x, y: waterfall_top_y }
end
visited = []
final_coords = []
splash_coords = []
while !active_columns.empty?
new_columns = []
active_columns.each do |segment|
x = segment[:x]
y = segment[:y]
next if visited.include?([x, y])
visited << [x, y]
while y < map_height
pos = [x, y]
final_coords << pos
if boulder_positions.include?(pos)
splash_coords << [x - 1, y] if x > 0
splash_coords << [x + 1, y] if x < $game_map.width - 1
splash_coords << [x, y]
new_y = y
new_columns << { x: x - 1, y: new_y } if x > 0 && !visited.include?([x - 1, new_y])
new_columns << { x: x + 1, y: new_y } if x < $game_map.width - 1 && !visited.include?([x + 1, new_y])
break
end
#currents section
if y > CIANWOOD_WATERFALL_EDGE+10
if !$game_map.passable?(x, y + 1, DIRECTION_DOWN)
splash_coords << [x, y + 1] if y + 1 < $game_map.height
break
end
end
if y == CIANWOOD_WATERFALL_EDGE
splash_coords << [x, y]
end
if y == map_height
splash_coords << [x, y]
end
y += 1
end
end
active_columns = new_columns
end
$game_temp.temp_waterfall = final_coords.uniq
$game_temp.splash_coords = splash_coords.uniq
echoln $game_temp.temp_waterfall
draw_waterfall_layer
end
def draw_waterfall_layer
return if !$game_temp.temp_waterfall || $game_temp.temp_waterfall.empty?
# Clear previous sprites
if $game_temp.waterfall_sprites
$game_temp.waterfall_sprites.each(&:dispose)
end
if $game_temp.splash_sprites
$game_temp.splash_sprites.each(&:dispose)
end
$game_temp.waterfall_sprites = []
$game_temp.splash_sprites = []
tile_size = 32
waterfall_tile_id = 0 # Waterfall
splash_tile_id = 4 # Splash impact tile, assuming we have this in the tileset
tileset = RPG::Cache.tileset($game_map.tileset_name)
# Draw waterfall tiles
$game_temp.temp_waterfall.each do |x, y|
sprite = Sprite.new(Spriteset_Map.viewport)
sprite.z = 10
sprite.x = x * tile_size
sprite.y = y * tile_size
sprite.bitmap = Bitmap.new(tile_size, tile_size)
source_rect = Rect.new(waterfall_tile_id * tile_size,0, tile_size, tile_size) # Frame 0
sprite.bitmap.blt(0, 0, tileset, source_rect)
# Store metadata for animation
sprite.instance_variable_set(:@frame_offset, rand(3)) # Optional: make them start at different frames
sprite.instance_variable_set(:@tile_x, x)
sprite.instance_variable_set(:@tile_y, y)
$game_temp.waterfall_sprites << sprite
end
# Draw splash impact tiles
$game_temp.splash_coords.each do |x, y|
sprite = Sprite.new(Spriteset_Map.viewport)
sprite.z = 300 # Draw splash above the waterfall
sprite.x = x * tile_size
sprite.y = y * tile_size
sprite.bitmap = Bitmap.new(tile_size, tile_size)
source_rect = Rect.new(splash_tile_id * tile_size,1, tile_size, tile_size) # Splash frame 0
sprite.bitmap.blt(0, 0, tileset, source_rect)
# Store metadata for splash animation
sprite.instance_variable_set(:@frame_offset, rand(3)) # Optional: make them start at different frames
sprite.instance_variable_set(:@tile_x, x)
sprite.instance_variable_set(:@tile_y, y)
$game_temp.splash_sprites << sprite
end
end
CIANWOOD_BOULDER_IDS = [2,3,5,6,
4 ]#chuck head
CIANWOOD_WATERFALL_EDGE =19
def player_on_temp_waterfall?
return false if !$game_temp.temp_waterfall
boulder_positions = []
CIANWOOD_BOULDER_IDS.each do |event_id|
event = $game_map.events[event_id]
boulder_positions << [event.x, event.y]
end
# Return false if a boulder is directly below the player
return false if boulder_positions.include?([$game_player.x, $game_player.y + 1])
return $game_temp.temp_waterfall.any? { |x, y, _| x == $game_player.x && y == $game_player.y }
end
class Spriteset_Map
alias_method :cianwood_waterfall_update, :update
def update
cianwood_waterfall_update
waterfall_edge = CIANWOOD_WATERFALL_EDGE
if $game_temp.waterfall_sprites
frame_count = Graphics.frame_count
tile_size = 32
autotile_id = 0
tileset = RPG::Cache.tileset($game_map.tileset_name)
# Animate waterfall sprites
$game_temp.waterfall_sprites.each do |sprite|
tile_y = sprite.instance_variable_get(:@tile_y)
frame_offset = sprite.instance_variable_get(:@frame_offset)
# Animate every 15 frames (change for speed control)
animation_frame = (frame_count / 15 + tile_y - frame_offset) % 4
tileset_x = (autotile_id * 4 + animation_frame) * tile_size
tileset_y = tile_y >= waterfall_edge ? tile_size : 0
source_rect = Rect.new(tileset_x,tileset_y, tile_size, tile_size)
sprite.bitmap.clear
sprite.bitmap.blt(0, 0, tileset, source_rect)
# Scroll with map
sprite.ox = $game_map.display_x / 4
sprite.oy = $game_map.display_y / 4
end
# Animate splash sprites
$game_temp.splash_sprites.each do |sprite|
tile_y = sprite.instance_variable_get(:@tile_y)
frame_offset = sprite.instance_variable_get(:@frame_offset)
# Animate every 10 frames for splash (you can adjust this speed)
offset = (autotile_id * 4 + 4) * tile_size
animation_frame = (frame_count / 10 + tile_y + frame_offset) % 4
source_rect = Rect.new((autotile_id * 4 + animation_frame) * tile_size + offset, 0, tile_size, tile_size)
sprite.bitmap.clear
sprite.bitmap.blt(0, 0, tileset, source_rect)
# Scroll with map
sprite.ox = $game_map.display_x / 4
sprite.oy = $game_map.display_y / 4
end
end
end
end
# class Game_Temp
# attr_accessor :temp_waterfall
# attr_accessor :waterfall_sprites
# attr_accessor :splash_sprites
# attr_accessor :splash_coords
#
#
# end
#
# def generate_dynamic_waterfall(starting_x_position, waterfall_top_y, thickness=1)
# map_height = $game_map.height - 8
# echoln map_height
#
# boulder_positions = []
# CIANWOOD_BOULDER_IDS.each do |event_id|
# event = $game_map.events[event_id]
# boulder_positions << [event.x, event.y]
# end
#
# # Add columns from starting_x_position to the right
# active_columns = []
# (starting_x_position...(starting_x_position + thickness)).each do |x|
# break if x >= $game_map.width # Don't go past map edge
# active_columns << { x: x, y: waterfall_top_y }
# end
#
# visited = []
# final_coords = []
# splash_coords = []
#
# while !active_columns.empty?
# new_columns = []
#
# active_columns.each do |segment|
# x = segment[:x]
# y = segment[:y]
# next if visited.include?([x, y])
#
# visited << [x, y]
#
# while y < map_height
# pos = [x, y]
# final_coords << pos
#
# if boulder_positions.include?(pos)
# splash_coords << [x - 1, y] if x > 0
# splash_coords << [x + 1, y] if x < $game_map.width - 1
# splash_coords << [x, y]
#
# new_y = y
# new_columns << { x: x - 1, y: new_y } if x > 0 && !visited.include?([x - 1, new_y])
# new_columns << { x: x + 1, y: new_y } if x < $game_map.width - 1 && !visited.include?([x + 1, new_y])
# break
# end
#
# #currents section
# if y > CIANWOOD_WATERFALL_EDGE+10
# if !$game_map.passable?(x, y + 1, DIRECTION_DOWN)
# splash_coords << [x, y + 1] if y + 1 < $game_map.height
# break
# end
# end
#
# if y == CIANWOOD_WATERFALL_EDGE
# splash_coords << [x, y]
# end
#
# if y == map_height
# splash_coords << [x, y]
# end
#
# y += 1
# end
# end
#
# active_columns = new_columns
# end
#
# $game_temp.temp_waterfall = final_coords.uniq
# $game_temp.splash_coords = splash_coords.uniq
# echoln $game_temp.temp_waterfall
# draw_waterfall_layer
# end
#
# def draw_waterfall_layer
# return if !$game_temp.temp_waterfall || $game_temp.temp_waterfall.empty?
#
# # Clear previous sprites
# if $game_temp.waterfall_sprites
# $game_temp.waterfall_sprites.each(&:dispose)
# end
# if $game_temp.splash_sprites
# $game_temp.splash_sprites.each(&:dispose)
# end
#
# $game_temp.waterfall_sprites = []
# $game_temp.splash_sprites = []
#
# tile_size = 32
# waterfall_tile_id = 0 # Waterfall
#
# splash_tile_id = 4 # Splash impact tile, assuming we have this in the tileset
# tileset = RPG::Cache.tileset($game_map.tileset_name)
#
# # Draw waterfall tiles
# $game_temp.temp_waterfall.each do |x, y|
# sprite = Sprite.new(Spriteset_Map.viewport)
#
# sprite.z = 10
# sprite.x = x * tile_size
# sprite.y = y * tile_size
#
# sprite.bitmap = Bitmap.new(tile_size, tile_size)
# source_rect = Rect.new(waterfall_tile_id * tile_size,0, tile_size, tile_size) # Frame 0
# sprite.bitmap.blt(0, 0, tileset, source_rect)
#
# # Store metadata for animation
# sprite.instance_variable_set(:@frame_offset, rand(3)) # Optional: make them start at different frames
# sprite.instance_variable_set(:@tile_x, x)
# sprite.instance_variable_set(:@tile_y, y)
#
# $game_temp.waterfall_sprites << sprite
# end
#
# # Draw splash impact tiles
# $game_temp.splash_coords.each do |x, y|
# sprite = Sprite.new(Spriteset_Map.viewport)
# sprite.z = 300 # Draw splash above the waterfall
# sprite.x = x * tile_size
# sprite.y = y * tile_size
#
# sprite.bitmap = Bitmap.new(tile_size, tile_size)
# source_rect = Rect.new(splash_tile_id * tile_size,1, tile_size, tile_size) # Splash frame 0
# sprite.bitmap.blt(0, 0, tileset, source_rect)
#
# # Store metadata for splash animation
# sprite.instance_variable_set(:@frame_offset, rand(3)) # Optional: make them start at different frames
# sprite.instance_variable_set(:@tile_x, x)
# sprite.instance_variable_set(:@tile_y, y)
#
# $game_temp.splash_sprites << sprite
# end
# end
#
#
#
#
# CIANWOOD_BOULDER_IDS = [2,3,5,6,
# 4 ]#chuck head
# CIANWOOD_WATERFALL_EDGE =19
#
#
# def player_on_temp_waterfall?
# return false if !$game_temp.temp_waterfall
#
# boulder_positions = []
# CIANWOOD_BOULDER_IDS.each do |event_id|
# event = $game_map.events[event_id]
# boulder_positions << [event.x, event.y]
# end
#
# # Return false if a boulder is directly below the player
# return false if boulder_positions.include?([$game_player.x, $game_player.y + 1])
#
# return $game_temp.temp_waterfall.any? { |x, y, _| x == $game_player.x && y == $game_player.y }
# end
#
#
#
#
#
#
#
# class Spriteset_Map
# alias_method :cianwood_waterfall_update, :update
# def update
# cianwood_waterfall_update
#
# waterfall_edge = CIANWOOD_WATERFALL_EDGE
# if $game_temp.waterfall_sprites
# frame_count = Graphics.frame_count
# tile_size = 32
# autotile_id = 0
# tileset = RPG::Cache.tileset($game_map.tileset_name)
#
# # Animate waterfall sprites
# $game_temp.waterfall_sprites.each do |sprite|
# tile_y = sprite.instance_variable_get(:@tile_y)
# frame_offset = sprite.instance_variable_get(:@frame_offset)
#
# # Animate every 15 frames (change for speed control)
# animation_frame = (frame_count / 15 + tile_y - frame_offset) % 4
#
# tileset_x = (autotile_id * 4 + animation_frame) * tile_size
# tileset_y = tile_y >= waterfall_edge ? tile_size : 0
# source_rect = Rect.new(tileset_x,tileset_y, tile_size, tile_size)
#
# sprite.bitmap.clear
# sprite.bitmap.blt(0, 0, tileset, source_rect)
#
# # Scroll with map
# sprite.ox = $game_map.display_x / 4
# sprite.oy = $game_map.display_y / 4
# end
#
# # Animate splash sprites
# $game_temp.splash_sprites.each do |sprite|
# tile_y = sprite.instance_variable_get(:@tile_y)
# frame_offset = sprite.instance_variable_get(:@frame_offset)
#
# # Animate every 10 frames for splash (you can adjust this speed)
# offset = (autotile_id * 4 + 4) * tile_size
# animation_frame = (frame_count / 10 + tile_y + frame_offset) % 4
# source_rect = Rect.new((autotile_id * 4 + animation_frame) * tile_size + offset, 0, tile_size, tile_size)
#
# sprite.bitmap.clear
# sprite.bitmap.blt(0, 0, tileset, source_rect)
#
# # Scroll with map
# sprite.ox = $game_map.display_x / 4
# sprite.oy = $game_map.display_y / 4
# end
# end
# end
# end
@@ -2,7 +2,7 @@
def oricorioEventPickFlower(flower_color)
quest_progression = pbGet(VAR_ORICORIO_FLOWERS)
if flower_color == :PINK
if !$game_switches[SWITCH_ORICORIO_QUEST_PINK]
if Settings::KANTO && !$game_switches[SWITCH_ORICORIO_QUEST_PINK]
pbMessage(_INTL("Woah! A Pokémon jumped out of the flower!"))
pbWildBattle(:FOMANTIS, 10)
end
@@ -28,6 +28,15 @@ def hasOricorioInParty()
end
def changeOricorioFlower(form = 1)
#guaranteed encounter first time you interact with a flower
if Settings::HOENN && !$game_switches[SWITCH_FOMANTIS_GUARANTEED_FLOWER]
pbMessage(_INTL("Woah! A Pokémon jumped out of the flower!"))
pbWildBattle(:FOMANTIS, 4)
$game_switches[SWITCH_FOMANTIS_GUARANTEED_FLOWER] = true
return
end
if $PokemonGlobal.stepcount % 25 == 0
if !hatUnlocked?(HAT_FLOWER) && rand(2) == 0
obtainHat(HAT_FLOWER)
@@ -118,7 +127,7 @@ def changeOricorioForm(pokemon, form = nil)
newForm = pokemon.isFusion? ? getSpeciesIdForFusion(head_number, body_number) : head_id
$Trainer.pokedex.set_seen(newForm)
$Trainer.pokedex.set_owned(newForm)
pokemon.pif_sprite = nil
pokemon.species = newForm
return true
end
@@ -1,5 +1,113 @@
def isOutdoor()
current_map = $game_map.map_id
def isOutdoor(current_map = nil)
current_map = $game_map.map_id if current_map.nil?
map_metadata = GameData::MapMetadata.try_get(current_map)
return map_metadata && map_metadata.outdoor_map
end
def find_random_walkable_coordinates_near_player(width, height, variance, max_nb_tries = 10)
max_nb_tries.times do
x, y = getRandomPositionOnPerimeter(width, height, $game_player.x, $game_player.y, variance)
return [x, y] if $game_map.playerPassable?(x, y, $game_player.direction)
end
return nil
end
def find_random_tall_grass_coordinates_near_player(width,height,variance,max_nb_tries = 10)
found_available_position = false
current_try = 0
while !found_available_position
x, y = getRandomPositionOnPerimeter(width, height, $game_player.x, $game_player.y, variance)
terrain = $game_map.terrain_tag(x, y)
found_available_position = terrain.land_wild_encounters
current_try += 1
return nil if current_try > max_nb_tries
end
encounter_type = :Land #default grass
encounter_type = :Land1 if terrain.id == :Grass_alt1
encounter_type = :Land2 if terrain.id == :Grass_alt2
encounter_type = :Land3 if terrain.id == :Grass_alt3
encounter_type = :TallGrass if terrain.id == :TallGrass
return [x,y],encounter_type
end
def find_random_surfable_coordinates_near_player(width,height,variance,max_nb_tries = 10)
found_available_position = false
current_try = 0
while !found_available_position
x, y = getRandomPositionOnPerimeter(width, height, $game_player.x, $game_player.y, variance)
terrain = $game_map.terrain_tag(x, y)
found_available_position = terrain.can_surf
current_try += 1
return nil if current_try > max_nb_tries
end
return [x,y]
end
def getRandomPositionOnPerimeter(width, height, center_x, center_y, variance=0,edge=nil)
half_width = width / 2.0
half_height = height / 2.0
# Randomly select one of the four edges of the rectangle
edge = rand(4) if !edge
case edge
when 0 # Top edge
random_x = center_x + rand(-half_width..half_width)
random_y = center_y - half_height
when 1 # Bottom edge
random_x = center_x + rand(-half_width..half_width)
random_y = center_y + half_height
when 2 # Left edge
random_x = center_x - half_width
random_y = center_y + rand(-half_height..half_height)
when 3 # Right edge
random_x = center_x + half_width
random_y = center_y + rand(-half_height..half_height)
end
return random_x.round, random_y.round
end
def setVariableToLeaderType(variable=5)
if $game_switches[SWITCH_RANDOM_TRAINERS]
gymArray = pbGet(VAR_GYM_TYPES_ARRAY)
else
gymArray = GYM_TYPES_ARRAY
end
currentGym = pbGet(VAR_CURRENT_GYM_TYPE)
typeIndex = gymArray[currentGym]
type = PBTypes.getName(typeIndex)
$game_variables[variable] = type
end
def increaseDarknessRadius(increase_by)
return unless $PokemonTemp.darknessSprite
$PokemonTemp.darknessSprite.radius += increase_by
end
def setDarknessRadius(value)
return unless $PokemonTemp.darknessSprite
echoln "setting to #{value}"
$PokemonTemp.darknessSprite.radius = value
end
Events.onMapChange += proc { |_sender, e|
$game_player.floating=false
$game_player.walk_anime = true
}
def showLocation(map_name=nil)
scene = $scene
if scene.is_a?(Scene_Map)
map_name = $game_map.name unless map_name
LocationWindow.new($game_map.name)
scene.spriteset.addUserSprite(LocationWindow.new(map_name))
end
end
@@ -28,11 +28,30 @@ def get_city_numerical_id(city_sym)
return current_city_numerical[city_sym]
end
# POKEMON_CENTER_MAP = 25
# POKEMON_CENTER_DOOR_POS = [10,10]
# POKEMON_CENTER_BIRTHDAY_MAP = 27
# def enter_pokemon_center
# pbSetPokemonCenter
# pokemon_center_map = isPlayerBirthDay? ? POKEMON_CENTER_BIRTHDAY_MAP : POKEMON_CENTER_MAP
# pbFadeOutIn {
# $game_temp.player_new_map_id = pokemon_center_map
# $game_temp.player_new_x = POKEMON_CENTER_DOOR_POS[0]
# $game_temp.player_new_y = POKEMON_CENTER_DOOR_POS[1]
# $scene.transfer_player(true)
# $game_map.autoplay
# $game_map.refresh
# }
# end
POKEMART_MAP_ID = 357
POKEMART_DOOR_POS = [12, 12]
# city -> Symbol
# used only in pif:kanto
def enter_pokemart(city)
pbSet(VAR_CURRENT_MART, city)
pbSet(VAR_CURRENT_CITY, city)
pbSet(VAR_CURRENT_CITY_NUMERICAL_ID, get_city_numerical_id(city))
echoln get_city_numerical_id(city)
pbFadeOutIn {
@@ -67,7 +86,7 @@ def exit_pokemart()
:OLIVINE => [138, 33, 23],
:CIANWOOD => [709.8, 46],
}
current_city = pbGet(VAR_CURRENT_MART)
current_city = pbGet(VAR_CURRENT_CITY)
current_city = :PEWTER if !current_city.is_a?(Symbol)
entrance_map = pokemart_entrances[current_city][0]
@@ -88,11 +107,16 @@ end
def reset_pokemart_variables
pbSet(VAR_CURRENT_CITY_NUMERICAL_ID, 0)
pbSet(VAR_CURRENT_MART, 0)
pbSet(VAR_CURRENT_CITY, 0)
end
def get_current_city_tag()
current_city = pbGet(VAR_CURRENT_CITY) if !current_city
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
end
def pokemart_clothes_shop(current_city = nil, include_defaults = true)
current_city = pbGet(VAR_CURRENT_MART) if !current_city
echoln current_city
current_city = pbGet(VAR_CURRENT_CITY) if !current_city
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
selector = OutfitSelector.new
@@ -105,7 +129,7 @@ def pokemart_clothes_shop(current_city = nil, include_defaults = true)
end
def pokemart_hat_shop(include_defaults = true)
current_city = pbGet(VAR_CURRENT_MART)
current_city = pbGet(VAR_CURRENT_CITY)
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
selector = OutfitSelector.new
@@ -119,7 +143,7 @@ def pokemart_hat_shop(include_defaults = true)
end
def get_mart_exclusive_items(city)
return get_mart_exclusive_items_hoenn if Settings::GAME_ID == :IF_HOENN
return get_mart_exclusive_items_hoenn(city) if Settings::GAME_ID == :IF_HOENN
items_list = []
case city
when :PEWTER;
@@ -170,4 +194,73 @@ def get_mart_exclusive_items(city)
items_list = []
end
return items_list
end
def get_mart_exclusive_items_hoenn(city)
items_list = []
case city
when :OLDALE
items_list = [:BERRYJUICE]
when :PETALBURG
items_list = [:POKETOY, :NESTBALL]
when :RUSTBORO
items_list = [:EVERSTONE, :LEVELBALL]
when :DEWFORD
items_list = [:RINGTARGET, :LUREBALL]
when :SLATEPORT
items_list = [:SOOTHEBELL, :NETBALL]
when :MAUVILLE
items_list = [:CELLBATTERY, :FASTBALL]
when :VERDANTURF
items_list = [:MENTALHERB, :LUXURYBALL]
when :LAVARIDGE
items_list = [:LAVACOOKIE, :REPEATBALL]
when :FALLARBOR
items_list = [:LIGHTCLAY, :HEAVYBALL]
when :FORTREE
items_list = [:ABSORBBULB, :FRIENDBALL]
when :LILYCOVE
items_list = [:METRONOME, :QUICKBALL,:TIMERBALL]
when :MOSSDEEP
items_list = [:AIRBALLOON, :MOONBALL]
when :SOOTOPOLIS
items_list = [:CLEANSETAG, :DUSKBALL]
when :EVERGRANDE
items_list = [:ABILITYURGE, :PUREBALL]
when :PACIFIDLOG
items_list = [:FLOATSTONE, :DIVEBALL]
end
return items_list
end
def regional_clothes_shop(regionTag)
selector = OutfitSelector.new
list = selector.generate_clothes_choice(
baseOptions = false,
additionalIds = [],
additionalTags = [regionTag],
filterOutTags = [])
clothesShop(list)
end
def regional_hats_shop(regionTag)
selector = OutfitSelector.new
list = selector.generate_hats_choice(
baseOptions = false,
additionalIds = [],
additionalTags = [regionTag],
filterOutTags = [])
hatShop(list)
end
def regional_hairstyle_shop(regionTag)
selector = OutfitSelector.new
list = selector.generate_hairstyle_choice(
baseOptions = false,
additionalIds = [],
additionalTags = [regionTag],
filterOutTags = [])
hairShop(list)
end
@@ -13,4 +13,21 @@ end
def isPostgame?()
return $game_switches[SWITCH_BEAT_THE_LEAGUE]
end
def isPlayerBirthDate? #used only for the nurse to wish you happy birthday. The normal check needs to be deactivated before petalburg lol
return unless $Trainer.birth_day && $Trainer.birth_month
current_date = Time.now
return current_date.day == $Trainer.birth_day && current_date.month == $Trainer.birth_month
end
def isPlayerBirthDay?
return false unless $game_switches[SWITCH_PETALBURG_WOODS_UNLOCKED]
return false unless $Trainer.birth_day && $Trainer.birth_month
current_date = Time.now
return current_date.day == $Trainer.birth_day && current_date.month == $Trainer.birth_month
end
def obtainedTransferBox?
return $PokemonSystem.obtained_transfer_box
end
@@ -14,6 +14,8 @@ def obtainStarter(starterIndex = 0)
startersList = Settings::DEFAULT_STARTERS
if $game_switches[SWITCH_JOHTO_STARTERS]
startersList = Settings::JOHTO_STARTERS
elsif $game_switches[SWITCH_KANTO_STARTERS]
startersList = Settings::KANTO_STARTERS
elsif $game_switches[SWITCH_HOENN_STARTERS]
startersList = Settings::HOENN_STARTERS
elsif $game_switches[SWITCH_SINNOH_STARTERS]
@@ -51,12 +51,12 @@ class PokedexUtils
return $game_temp.custom_sprites_list[sprite_id]
end
def pbGetAvailableAlts(species, includeAutogens=false)
dex_number = getDexNumberForSpecies(species)
def pbGetAvailableAlts(dex_number, includeAutogens=false)
if isFusion(dex_number)
body_id = getBodyID(dex_number)
head_id = getHeadID(dex_number,body_id)
available_alts = getFusionSpriteAlts(head_id,body_id)
echoln available_alts
available_alts = [] if !available_alts
local_alts = getLocalFusionSpriteAlts(head_id,body_id)
else
@@ -1,12 +1,20 @@
class PokemonPokedexInfo_Scene
#todo add indicator to show which one is the main sprite -
# also maybe add an indicator in main list for when a sprite has available alts
# Todo: There are 2 modes in here:
# - Selecting a specific sprite
# - Selecting which sprites are available for that species (blacklist stuff)
# _
# It would be good to separate the logic into 2 different pages based on the same one instead of doing everything
# in this one
Y_POSITION_SMALL = 40 #90
class PokemonGlobalMetadata
attr_accessor :seen_sprites_tutorial
end
class PokemonPokedexInfo_Scene
Y_POSITION_SMALL = 40 # 90
Y_POSITION_BIG = 60
X_POSITION_PREVIOUS = -30 #20
X_POSITION_PREVIOUS = -30 # 20
X_POSITION_SELECTED = 105
X_POSITION_NEXT = 340 #380
X_POSITION_NEXT = 340 # 380
Y_POSITION_BG_SMALL = 70
Y_POSITION_BG_BIG = 93
@@ -21,11 +29,23 @@ class PokemonPokedexInfo_Scene
base = Color.new(88, 88, 80)
shadow = Color.new(168, 184, 184)
#alts_list= pbGetAvailableAlts
# alts_list= pbGetAvailableAlts
@selected_index = 0 if !@selected_index
update_displayed
end
def checkSpritesPageTutorial
return unless $PokemonSystem.random_sprites
return unless @selecting_blacklist
return if $PokemonGlobal.seen_sprites_tutorial
pbMessage(_INTL("Pokémon are assigned a random sprite when you encounter them in the wild."))
pbMessage(_INTL("This page allows you to select the sprites that can appear for each Pokémon."))
unless @pokemon
pbMessage(_INTL("To change one of your caught Pokémon's sprite, you need to open its Pokédex entry from the the Pokémon's Summary page."))
end
$PokemonGlobal.seen_sprites_tutorial = true
end
def init_selected_bg
@sprites["bgSelected_previous"] = IconSprite.new(0, 0, @viewport)
@sprites["bgSelected_previous"].x = X_POSITION_BG_PREVIOUS
@@ -55,7 +75,7 @@ class PokemonPokedexInfo_Scene
init_selected_bg
@speciesData = getSpecies(@species)
@species_id = @speciesData.species
@selected_index = 0
set_displayed_to_current_alt(altsList)
@@ -86,9 +106,9 @@ class PokemonPokedexInfo_Scene
@sprites["previousSprite"].z = 9999999
@sprites["nextSprite"].z = 9999999
@selected_pif_sprite = get_pif_sprite(@available[@selected_index])
@previous_pif_sprite = get_pif_sprite(@available[@selected_index - 1])
@next_pif_sprite = get_pif_sprite(@available[@selected_index + 1])
@selected_pif_sprite = @available[@selected_index]
@previous_pif_sprite = @available[@selected_index - 1]
@next_pif_sprite = @available[@selected_index + 1]
@sprites["selectedSprite"].bitmap = load_pif_sprite(@selected_pif_sprite)
if altsList.size >= 2
@@ -102,10 +122,143 @@ class PokemonPokedexInfo_Scene
@sprites["previousSprite"].visible = true
end
@selecting_blacklist = $PokemonSystem.random_sprites && !@pokemon
init_blacklist_icons
end
def init_blacklist_icons
blacklist_icons_x_offset_big = 130
blacklist_icons_y_offset_big = 235
blacklist_icons_x_offset_small = 80
blacklist_icons_y_offset_small = 140
@sprites["selectedSprite_blacklistEnabled"] = IconSprite.new(0, 0, @viewport)
@sprites["selectedSprite_blacklistEnabled"].setBitmap("Graphics/Pictures/Pokedex/enabled_icon")
@sprites["selectedSprite_blacklistEnabled"].x = X_POSITION_SELECTED + blacklist_icons_x_offset_big
@sprites["selectedSprite_blacklistEnabled"].y = Y_POSITION_BIG + blacklist_icons_y_offset_big
@sprites["selectedSprite_blacklistEnabled"].z = 9999999
@sprites["selectedSprite_blacklistEnabled"].visible = false
@sprites["selectedSprite_blacklistDisabled"] = IconSprite.new(0, 0, @viewport)
@sprites["selectedSprite_blacklistDisabled"].setBitmap("Graphics/Pictures/Pokedex/disabled_icon")
@sprites["selectedSprite_blacklistDisabled"].x = X_POSITION_SELECTED + blacklist_icons_x_offset_big
@sprites["selectedSprite_blacklistDisabled"].y = Y_POSITION_BIG + blacklist_icons_y_offset_big
@sprites["selectedSprite_blacklistDisabled"].z = 9999999
@sprites["selectedSprite_blacklistDisabled"].visible = false
@sprites["selectedSprite_blacklistAutogen"] = IconSprite.new(0, 0, @viewport)
@sprites["selectedSprite_blacklistAutogen"].setBitmap("Graphics/Pictures/Pokedex/autogen_icon")
@sprites["selectedSprite_blacklistAutogen"].x = X_POSITION_SELECTED + blacklist_icons_x_offset_big
@sprites["selectedSprite_blacklistAutogen"].y = Y_POSITION_BIG + blacklist_icons_y_offset_big
@sprites["selectedSprite_blacklistAutogen"].z = 9999999
@sprites["selectedSprite_blacklistAutogen"].visible = false
##############
@sprites["previousSprite_blacklistEnabled"] = IconSprite.new(0, 0, @viewport)
@sprites["previousSprite_blacklistEnabled"].setBitmap("Graphics/Pictures/Pokedex/enabled_icon")
@sprites["previousSprite_blacklistEnabled"].x = X_POSITION_PREVIOUS + blacklist_icons_x_offset_small
@sprites["previousSprite_blacklistEnabled"].y = Y_POSITION_SMALL + blacklist_icons_y_offset_small
@sprites["previousSprite_blacklistEnabled"].z = 9999999
@sprites["previousSprite_blacklistEnabled"].visible = false
@sprites["previousSprite_blacklistDisabled"] = IconSprite.new(0, 0, @viewport)
@sprites["previousSprite_blacklistDisabled"].setBitmap("Graphics/Pictures/Pokedex/disabled_icon")
@sprites["previousSprite_blacklistDisabled"].x = X_POSITION_PREVIOUS + blacklist_icons_x_offset_small
@sprites["previousSprite_blacklistDisabled"].y = Y_POSITION_SMALL + blacklist_icons_y_offset_small
@sprites["previousSprite_blacklistDisabled"].z = 9999999
@sprites["previousSprite_blacklistDisabled"].visible = false
@sprites["previousSprite_blacklistAutogen"] = IconSprite.new(0, 0, @viewport)
@sprites["previousSprite_blacklistAutogen"].setBitmap("Graphics/Pictures/Pokedex/autogen_icon")
@sprites["previousSprite_blacklistAutogen"].x = X_POSITION_PREVIOUS + blacklist_icons_x_offset_small
@sprites["previousSprite_blacklistAutogen"].y = Y_POSITION_SMALL + blacklist_icons_y_offset_small
@sprites["previousSprite_blacklistAutogen"].z = 9999999
@sprites["previousSprite_blacklistAutogen"].visible = false
###################
@sprites["nextSprite_blacklistEnabled"] = IconSprite.new(0, 0, @viewport)
@sprites["nextSprite_blacklistEnabled"].setBitmap("Graphics/Pictures/Pokedex/enabled_icon")
@sprites["nextSprite_blacklistEnabled"].x = X_POSITION_NEXT + blacklist_icons_x_offset_small
@sprites["nextSprite_blacklistEnabled"].y = Y_POSITION_SMALL + blacklist_icons_y_offset_small
@sprites["nextSprite_blacklistEnabled"].z = 9999999
@sprites["nextSprite_blacklistEnabled"].visible = false
@sprites["nextSprite_blacklistDisabled"] = IconSprite.new(0, 0, @viewport)
@sprites["nextSprite_blacklistDisabled"].setBitmap("Graphics/Pictures/Pokedex/disabled_icon")
@sprites["nextSprite_blacklistDisabled"].x = X_POSITION_NEXT + blacklist_icons_x_offset_small
@sprites["nextSprite_blacklistDisabled"].y = Y_POSITION_SMALL + blacklist_icons_y_offset_small
@sprites["nextSprite_blacklistDisabled"].z = 9999999
@sprites["nextSprite_blacklistDisabled"].visible = false
@sprites["nextSprite_blacklistAutogen"] = IconSprite.new(0, 0, @viewport)
@sprites["nextSprite_blacklistAutogen"].setBitmap("Graphics/Pictures/Pokedex/autogen_icon")
@sprites["nextSprite_blacklistAutogen"].x = X_POSITION_NEXT + blacklist_icons_x_offset_small
@sprites["nextSprite_blacklistAutogen"].y = Y_POSITION_SMALL + blacklist_icons_y_offset_small
@sprites["nextSprite_blacklistAutogen"].z = 9999999
@sprites["nextSprite_blacklistAutogen"].visible = false
end
def setBlacklistIconDisabled(spritename)
@sprites["#{spritename}_blacklistEnabled"].visible = false
@sprites["#{spritename}_blacklistDisabled"].visible = true
end
def setBlacklistIconEnabled(spritename)
@sprites["#{spritename}_blacklistEnabled"].visible = true
@sprites["#{spritename}_blacklistDisabled"].visible = false
end
def hide_blacklist_icons
@sprites["nextSprite_blacklistDisabled"].visible = false
@sprites["nextSprite_blacklistEnabled"].visible = false
@sprites["nextSprite_blacklistAutogen"].visible = false
@sprites["selectedSprite_blacklistDisabled"].visible = false
@sprites["selectedSprite_blacklistEnabled"].visible = false
@sprites["selectedSprite_blacklistAutogen"].visible = false
@sprites["previousSprite_blacklistDisabled"].visible = false
@sprites["previousSprite_blacklistEnabled"].visible = false
@sprites["previousSprite_blacklistAutogen"].visible = false
end
def update_blacklist_icons
$PokemonSystem.sprites_blacklist = {} unless $PokemonSystem.sprites_blacklist
species_blacklist = $PokemonSystem.sprites_blacklist[@species_id]
species_blacklist = initialize_species_blacklist(@species_id) unless species_blacklist
# previous sprite
previous_position = @selected_index - 1 < 0 ? @available.length - 1 : @selected_index - 1
current_position = @selected_index
next_position = @selected_index + 1 > @available.length - 1 ? 0 : @selected_index + 1
setIconStatus("previousSprite", previous_position, species_blacklist)
setIconStatus("selectedSprite", current_position, species_blacklist)
setIconStatus("nextSprite", next_position, species_blacklist)
end
def setIconStatus(iconName, position, species_blacklist)
sprite = @available[position]
if sprite.type == :AUTOGEN && @available.length == 1
if @available.length > 1
setBlacklistIconDisabled(iconName)
else
setBlacklistIconEnabled(iconName)
end
else
if species_blacklist.include?(sprite.alt_letter)
setBlacklistIconDisabled(iconName)
else
setBlacklistIconEnabled(iconName)
end
end
end
def load_pif_sprite(pif_sprite)
animated_bitmap = @spritesLoader.load_pif_sprite_directly(pif_sprite)
animated_bitmap = @spritesLoader.load_pif_sprite_directly(pif_sprite) if pif_sprite
return animated_bitmap.bitmap if animated_bitmap
return nil
end
@@ -122,16 +275,18 @@ class PokemonPokedexInfo_Scene
end
def set_displayed_to_current_alt(altsList)
dex_number = getDexNumberForSpecies(@species)
species_id = get_substitution_id(dex_number)
initialize_alt_sprite_substitutions()
return if !$PokemonGlobal.alt_sprite_substitutions[species_id]
current_sprite = $PokemonGlobal.alt_sprite_substitutions[species_id]
if @pokemon && @pokemon.pif_sprite
current_sprite = @pokemon.pif_sprite
else
dex_number = getDexNumberForSpecies(@species)
species_id = get_substitution_id(dex_number)
initialize_alt_sprite_substitutions()
return if !$PokemonSystem.alt_sprite_substitutions[species_id]
current_sprite = $PokemonSystem.alt_sprite_substitutions[species_id]
end
index = @selected_index
for alt in altsList
if alt == current_sprite.alt_letter
if alt.alt_letter == current_sprite.alt_letter
@selected_index = index
return
end
@@ -139,11 +294,78 @@ class PokemonPokedexInfo_Scene
end
end
SHARED_BODIES = {}
SHARED_HEADS = {}
def get_shared_bodies
#return SHARED_BODIES
return {
GameData::Species.get(NB_POKEMON-3).species => GameData::Species.get(NB_POKEMON-1).species,
GameData::Species.get(NB_POKEMON-1).species => GameData::Species.get(NB_POKEMON-3).species,
GameData::Species.get(NB_POKEMON-2).species => GameData::Species.get(NB_POKEMON).species,
GameData::Species.get(NB_POKEMON).species => GameData::Species.get(NB_POKEMON-2).species,
}
end
def get_shared_heads
return SHARED_HEADS
end
def list_shared_sprites(species_id)
pokedexUtils = PokedexUtils.new
shared_alts = []
body_num, head_num = splitHeadBody(species_id)
if body_num && head_num # fusion
body_species = GameData::Species.get(body_num)&.species
head_species = GameData::Species.get(head_num)&.species
shared_bodies = get_shared_bodies
shared_heads = get_shared_heads
if shared_bodies[body_species]
shared_dex_num = GameData::Species.get(shared_bodies[body_species]).id_number
fusion_species = getFusedPokemonIdFromDexNum(shared_dex_num, head_num)
fusion_number = GameData::Species.get(fusion_species).id_number
shared_body_alts = pokedexUtils.pbGetAvailableAlts(fusion_number, false)
shared_body_sprites = []
shared_body_alts.each do |alt|
shared_body_sprites << get_pif_sprite(alt, fusion_species)
end
shared_alts += shared_body_sprites
end
if shared_heads[head_species]
shared_dex_num = GameData::Species.get(shared_heads[head_species]).id_number
fusion_species = getFusedPokemonIdFromDexNum(body_num, shared_dex_num)
fusion_number = GameData::Species.get(fusion_species).id_number
shared_head_alts = pokedexUtils.pbGetAvailableAlts(fusion_number, false)
shared_head_sprites = []
shared_head_alts.each do |alt|
shared_head_sprites << get_pif_sprite(alt, fusion_species)
end
shared_alts += shared_head_sprites
end
end
return shared_alts
end
def pbGetAvailableForms(species = nil)
pokedexUtils = PokedexUtils.new
chosen_species = species != nil ? species : @species
dex_num = getDexNumberForSpecies(chosen_species)
species_data = GameData::Species.get(chosen_species)
dex_num = species_data.id_number
includeAutogens = isFusion(dex_num)
return PokedexUtils.new.pbGetAvailableAlts(chosen_species, includeAutogens)
available_alt_letters = pokedexUtils.pbGetAvailableAlts(dex_num, includeAutogens)
available_sprites = []
available_alt_letters.each do |alt|
available_sprites << get_pif_sprite(alt,chosen_species)
end
available_sprites += list_shared_sprites(species_data.species)
return available_sprites
end
def hide_all_selected_windows
@@ -157,35 +379,36 @@ class PokemonPokedexInfo_Scene
previous_index = @selected_index == 0 ? @available.size - 1 : @selected_index - 1
next_index = @selected_index == @available.size - 1 ? 0 : @selected_index + 1
get_pif_sprite(@available[@selected_index])
@available[@selected_index]
@sprites["bgSelected_previous"].visible = true if is_main_sprite(previous_index) && @available.size > 2
@sprites["bgSelected_center"].visible = true if is_main_sprite(@selected_index)
@sprites["bgSelected_next"].visible = true if is_main_sprite(next_index) && @available.size > 1
end
def get_pif_sprite(alt_letter)
dex_number = getDexNumberForSpecies(@species) #@species is a symbol when called from the summary screen and an int from the pokedex... Would be nice to refactor
def get_pif_sprite(alt_letter, species = nil)
species = @species unless species
dex_number = getDexNumberForSpecies(species) #@species is a symbol when called from the summary screen and an int from the pokedex... Would be nice to refactor
if isFusion(dex_number)
body_id = getBodyID(dex_number)
head_id = getHeadID(dex_number, body_id)
#Autogen sprite
# Autogen sprite
if alt_letter == "autogen"
pif_sprite = PIFSprite.new(:AUTOGEN, head_id, body_id)
#Imported custom sprite
pif_sprite = PIFSprite.new(:AUTOGEN, head_id, body_id, "autogen")
# Imported custom sprite
else
#Spritesheet custom sprite
# Spritesheet custom sprite
pif_sprite = PIFSprite.new(:CUSTOM, head_id, body_id, alt_letter)
end
else
pif_sprite = PIFSprite.new(:BASE, dex_number, nil, alt_letter)
end
#use local sprites instead if they exist
# use local sprites instead if they exist
if alt_letter && isLocalSprite(alt_letter)
sprite_path = alt_letter.split("_", 2)[1]
pif_sprite.local_path = sprite_path
end
#pif_sprite.dump_info
# pif_sprite.dump_info
return pif_sprite
end
@@ -207,27 +430,27 @@ class PokemonPokedexInfo_Scene
if previousIndex < 0
previousIndex = @available.size - 1
end
@selected_pif_sprite = get_pif_sprite(@available[@selected_index])
@selected_pif_sprite = @available[@selected_index]
@previous_pif_sprite = get_pif_sprite(@available[previousIndex])
@next_pif_sprite = get_pif_sprite(@available[nextIndex])
@previous_pif_sprite = @available[previousIndex]
@next_pif_sprite = @available[nextIndex]
@sprites["previousSprite"].bitmap = load_pif_sprite(@previous_pif_sprite) if previousIndex != nextIndex
@sprites["selectedSprite"].bitmap = load_pif_sprite(@selected_pif_sprite)
@sprites["nextSprite"].bitmap = load_pif_sprite(@next_pif_sprite)
#selected_bitmap = @sprites["selectedSprite"].getBitmap
# selected_bitmap = @sprites["selectedSprite"].getBitmap
# sprite_path = selected_bitmap.path
#isBaseSprite = isBaseSpritePath(@available[@selected_index])
is_generated = @selected_pif_sprite.type == :AUTOGEN
spritename = @selected_pif_sprite.to_filename()
# isBaseSprite = isBaseSpritePath(@available[@selected_index])
@displayed_pif_sprite= @selected_pif_sprite
is_generated = @selected_pif_sprite&.type == :AUTOGEN
spritename = @selected_pif_sprite&.to_filename()
showSpriteCredits(spritename, is_generated)
update_selected
end
def showSpriteCredits(filename, generated_sprite = false)
return unless filename
@creditsOverlay.dispose
spritename = File.basename(filename, '.*')
@@ -236,7 +459,7 @@ class PokemonPokedexInfo_Scene
discord_name = getSpriteCredits(spritename)
discord_name = "Unknown artist" if !discord_name
else
#todo give credits to Japeal - need to differenciate unfused sprites
# todo give credits to Japeal - need to differenciate unfused sprites
discord_name = "" #"Japeal\n(Generated)"
end
discord_name = "Imported sprite" if @selected_pif_sprite.local_path
@@ -282,60 +505,91 @@ class PokemonPokedexInfo_Scene
end
def pbChooseAlt(brief = false)
checkSpritesPageTutorial
@selecting_sprites = true
updateBlackListInstructionIcons
update_blacklist_icons if @selecting_blacklist
if @available.size <= 0
pbPlayBuzzerSE
return
end
loop do
@sprites["rightarrow"].visible = true
@sprites["leftarrow"].visible = true
if @forms_list.length >= 1
@sprites["uparrow"].visible = true
@sprites["downarrow"].visible = true
end
multiple_forms = @forms_list.length > 0
Graphics.update
Input.update
pbUpdate
@sprites["leftarrow"].visible = true
@sprites["rightarrow"].visible = true
@sprites["uparrow"].visible = @forms_list.length > 0
@sprites["downarrow"].visible = @forms_list.length > 0
if Input.trigger?(Input::LEFT)
pbPlayCursorSE
@selected_index -= 1 #(index+@available.length-1)%@available.length
if @selected_index < 0
@selected_index = @available.size - 1
end
@selected_index = (@selected_index - 1) % @available.size
update_displayed
update_blacklist_icons if @selecting_blacklist
updateBlacklistIconVisibility
elsif Input.trigger?(Input::RIGHT)
pbPlayCursorSE
@selected_index += 1
if @selected_index > @available.size - 1
@selected_index = 0
end
@selected_index = (@selected_index + 1) % @available.size
update_displayed
update_blacklist_icons if @selecting_blacklist
updateBlacklistIconVisibility
elsif Input.trigger?(Input::USE)
if @selecting_blacklist
toggle_sprite_blacklist
update_blacklist_icons
updateBlacklistIconVisibility
else
pbPlayDecisionSE
if select_species_sprite(brief)
@endscene = true
break
end
end
elsif Input.trigger?(Input::BACK)
pbPlayCancelSE
@sprites["leftarrow"].visible = false
@sprites["rightarrow"].visible = false
break
elsif Input.trigger?(Input::USE)
pbPlayDecisionSE
if select_sprite(brief)
@endscene = true
break
end
elsif Input.trigger?(Input::UP) && @selecting_blacklist
pbPlayCancelSE
@sprites["leftarrow"].visible = false
@sprites["rightarrow"].visible = false
@selecting_blacklist = false
end
end
@selecting_blacklist = false
@selecting_sprites = false
hide_blacklist_icons
@sprites["uparrow"].visible = false
@sprites["downarrow"].visible = false
updateBlackListInstructionIcons
end
def is_main_sprite(index = nil)
dex_number = getDexNumberForSpecies(@species)
if !index
index = @selected_index
end
species_id = get_substitution_id(dex_number)
if @pokemon && @pokemon.pif_sprite && $PokemonSystem.random_sprites
selected_pif_sprite = @available[index]
return false unless selected_pif_sprite
same_alt = selected_pif_sprite.alt_letter == @pokemon.pif_sprite.alt_letter
same_species = selected_pif_sprite.species == @pokemon.pif_sprite.species
return same_alt && same_species
else
dex_number = getDexNumberForSpecies(@species)
species_id = get_substitution_id(dex_number)
current_pif_sprite = $PokemonSystem.alt_sprite_substitutions[species_id]
selected_pif_sprite = @available[index]
current_pif_sprite = $PokemonGlobal.alt_sprite_substitutions[species_id]
selected_pif_sprite = get_pif_sprite(@available[index])
if current_pif_sprite
return current_pif_sprite.equals(selected_pif_sprite)
if current_pif_sprite
return current_pif_sprite.equals(selected_pif_sprite)
end
return false
end
return false
end
def sprite_is_alt(sprite_path)
@@ -343,7 +597,34 @@ class PokemonPokedexInfo_Scene
return spritename.match?(/[a-zA-Z]/)
end
def select_sprite(brief = false)
def toggle_sprite_blacklist
$PokemonSystem.sprites_blacklist ||= {}
species_blacklist = $PokemonSystem.sprites_blacklist[@species_id]
species_blacklist ||= initialize_species_blacklist(@species_id)
selected_letter = @available[@selected_index].alt_letter
total = @available.length
blacklisted = species_blacklist.length
allowed = total - blacklisted
if species_blacklist.include?(selected_letter)
pbSEPlay("GUI storage put down")
species_blacklist.delete(selected_letter)
else
if allowed <= 1
pbPlayBuzzerSE()
pbMessage(_INTL("You need to allow at least one sprite!"))
return
end
pbSEPlay("GUI storage pick up")
species_blacklist << selected_letter
end
$PokemonSystem.sprites_blacklist[@species_id] = species_blacklist
end
def select_species_sprite(brief = false)
if @available.length > 1
if is_main_sprite()
if brief
@@ -353,7 +634,8 @@ class PokemonPokedexInfo_Scene
pbMessage(_INTL("This sprite is already the displayed sprite"))
end
else
message = _INTL('Would you like to use this sprite instead of the current sprite?')
message = _INTL("Would you like to use this sprite instead of the current sprite?")
message = _INTL("Would you like to use this sprite instead of the current sprite for the entire species?") unless @pokemon
if pbConfirmMessage(message)
swap_main_sprite()
return true
@@ -368,10 +650,15 @@ class PokemonPokedexInfo_Scene
def swap_main_sprite
species_number = dexNum(@species)
substitution_id = get_substitution_id(species_number)
$PokemonGlobal.alt_sprite_substitutions[substitution_id] = @selected_pif_sprite
$PokemonSystem.alt_sprite_substitutions[substitution_id] = @selected_pif_sprite
if @pokemon
@pokemon.pif_sprite = @selected_pif_sprite
end
end
end
class PokemonGlobalMetadata
class PokemonSystem
attr_accessor :alt_sprite_substitutions
attr_accessor :sprites_blacklist
end
@@ -1,32 +1,39 @@
def setDialogIconOff(eventId=nil)
eventId = @event_id if !eventId
event = $game_map.events[eventId]
return unless event
event.setDialogIconManualOffValue(true)
event.setTradeIconManualOffValue(true)
event.setTutorIconManualOffValue(true)
end
def setDialogIconOn(eventId=nil)
eventId = @event_id if !eventId
event = $game_map.events[eventId]
return unless event
event.setDialogIconManualOffValue(false)
event.setTradeIconManualOffValue(false)
event.setTutorIconManualOffValue(false)
end
class Game_Event < Game_Character
#set from analyzing the event's content at load
attr_accessor :show_quest_icon
attr_accessor :show_dialog_icon
attr_accessor :show_trade_icon
attr_accessor :show_tutor_icon
#set manually from inside the event when triggered
attr_accessor :quest_icon_manual_off
attr_accessor :dialog_icon_manual_off
attr_accessor :trade_icon_manual_off
attr_accessor :tutor_icon_manual_off
QUEST_NPC_TRIGGER = "questNPC"
MAPS_WITH_NO_ICONS = [] #Maps in which the game shouldn't try to look for quest icons(e.g. maps with a lot of events - mostly for possible performance issues)
DIALOG_ICON_COMMENT_TRIGGER=["dialogIcon"]
QUEST_ICON_COMMENT_TRIGGER=["questIcon"] #Only when it can't be defined in the event's name (multiple page - only one is quest giver)
TRADE_ICON_COMMENT_TRIGGER=["tradeIcon"]
MOVE_TUTOR_ICON_COMMENT_TRIGGER=["tutorIcon"]
alias eventQuestIcon_init initialize
def initialize(map_id, event, map=nil)
@@ -34,6 +41,19 @@ class Game_Event < Game_Character
addQuestMarkersToSprite unless MAPS_WITH_NO_ICONS.include?($game_map.map_id)
end
alias _orig_start start
def start
setDialogIconManualOffValue(true)
setQuestIconManualOffValue(true)
_orig_start
end
alias eventQuestIcon_refresh refresh
def refresh
eventQuestIcon_refresh
addQuestMarkersToSprite
end
def setDialogIconManualOffValue(value)
@dialog_icon_manual_off=value
@show_dialog_icon = !@dialog_icon_manual_off
@@ -47,28 +67,37 @@ class Game_Event < Game_Character
@show_trade_icon = !@trade_icon_manual_off
end
def setTutorIconManualOffValue(value)
@tutor_icon_manual_off=value
@show_tutor_icon = !@tutor_icon_manual_off
end
def addQuestMarkersToSprite()
@show_quest_icon = detectQuestSwitch(self) && !@quest_icon_manual_off
@show_quest_icon = (detectQuestSwitch(self) || detectQuestIcon(self)) && !@quest_icon_manual_off
@show_dialog_icon = detectDialogueIcon(self) && !@dialog_icon_manual_off
@show_trade_icon = detectTradeIcon(self) && !@trade_icon_manual_off
@show_tutor_icon = detectTutorIcon(self) && !@tutor_icon_manual_off
end
def detectDialogueIcon(event)
return nil if !validateEventIsCompatibleWithIcons(event)
page = pbGetActiveEventPage(event)
first_command = page.list[0]
return nil if !(first_command.code == 108 || first_command.code == 408)
comments = first_command.parameters
return comments.any? { |str| DIALOG_ICON_COMMENT_TRIGGER.include?(str) }
return detectCommentCommand(DIALOG_ICON_COMMENT_TRIGGER,event)
end
def detectTradeIcon(event)
return nil if !validateEventIsCompatibleWithIcons(event)
page = pbGetActiveEventPage(event)
first_command = page.list[0]
return nil if !(first_command.code == 108 || first_command.code == 408)
comments = first_command.parameters
return comments.any? { |str| TRADE_ICON_COMMENT_TRIGGER.include?(str) }
return detectCommentCommand(TRADE_ICON_COMMENT_TRIGGER,event)
end
def detectQuestIcon(event)
return nil if !validateEventIsCompatibleWithIcons(event)
return detectCommentCommand(QUEST_ICON_COMMENT_TRIGGER,event)
end
def detectTutorIcon(event)
return nil if !validateEventIsCompatibleWithIcons(event)
return detectCommentCommand(MOVE_TUTOR_ICON_COMMENT_TRIGGER,event)
end
def detectQuestSwitch(event)
@@ -86,6 +115,7 @@ class Game_Event < Game_Character
def validateEventIsCompatibleWithIcons(event)
return false if event.is_a?(Game_Player)
return false if event.erased
return false unless event.visible?
page = pbGetActiveEventPage(event)
return false unless page
return false if page.graphic.character_name.empty?
@@ -98,9 +128,10 @@ end
class Sprite_Character
DIALOGUE_ICON_NAME = "Graphics/Pictures/Quests/dialogIcon"
QUEST_ICON_NAME = "Graphics/Pictures/Quests/questIcon"
TRADE_ICON_NAME = "Graphics/Pictures/Quests/tradeIcon"
DIALOGUE_ICON_NAME = "Graphics/Pictures/NPCIcons/dialogIcon"
QUEST_ICON_NAME = "Graphics/Pictures/NPCIcons/questIcon"
TRADE_ICON_NAME = "Graphics/Pictures/NPCIcons/tradeIcon"
TUTOR_ICON_NAME = "Graphics/Pictures/NPCIcons/tutorIcon"
attr_accessor :questIcon
alias questIcon_init initialize
@@ -115,6 +146,9 @@ class Sprite_Character
if character.is_a?(Game_Event) && character.show_trade_icon
addQuestMarkerToSprite(:TRADE_ICON)
end
if character.is_a?(Game_Event) && character.show_tutor_icon
addQuestMarkerToSprite(:TUTOR_ICON)
end
#addQuestMarkersToSprite(character) unless MAPS_WITH_NO_ICONS.include?($game_map.map_id)
end
@@ -137,7 +171,22 @@ class Sprite_Character
end
def updateGameEvent
removeQuestIcon if !@character.show_dialog_icon && !@character.show_quest_icon && !@character.show_trade_icon
if !@character.show_dialog_icon &&
!@character.show_quest_icon &&
!@character.show_trade_icon &&
!@character.show_tutor_icon
removeQuestIcon
elsif !@questIcon
if @character.show_dialog_icon
addQuestMarkerToSprite(:DIALOG_ICON)
elsif @character.show_quest_icon
addQuestMarkerToSprite(:QUEST_ICON)
elsif @character.show_trade_icon
addQuestMarkerToSprite(:TRADE_ICON)
elsif @character.show_tutor_icon
addQuestMarkerToSprite(:TUTOR_ICON)
end
end
positionQuestIndicator if @questIcon
end
@@ -153,10 +202,6 @@ class Sprite_Character
# Event name must contain questNPC(x) for a quest icon to be displayed
# Where x is the quest ID
# if the quest has not already been accepted, the quest marker will be shown
#type: :QUEST_ICON, :DIALOG_ICON
def addQuestMarkerToSprite(iconType)
removeQuestIcon if @questIcon
@@ -168,6 +213,8 @@ class Sprite_Character
iconPath = DIALOGUE_ICON_NAME
when :TRADE_ICON
iconPath = TRADE_ICON_NAME
when :TUTOR_ICON
iconPath = TUTOR_ICON_NAME
end
return if !iconPath
@questIcon.bmp(iconPath)
@@ -193,6 +240,7 @@ class Sprite_Character
def removeQuestIcon()
@questIcon.dispose if @questIcon
@questIcon = nil
@character.show_quest_icon = false if @character.is_a?(Game_Event)
end
end
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,8 @@
#
# Rewards given by hotel questman after a certain nb. of completed quests
#
QUEST_REWARDS = [
QUEST_REWARDS = Settings::KANTO ? [
# Kanto quest rewards
QuestReward.new(1, :HM08, 1, _INTL("This HM will allow you to illuminate dark caves and should help you to progress in your journey!")),
QuestReward.new(5, :AMULETCOIN, 1, _INTL("This item will allows you to get twice the money in a battle if the Pokémon holding it took part in it!")),
QuestReward.new(10, :LANTERN, 1, _INTL("This will allow you to illuminate caves without having to use a HM! Practical, isn't it?")),
@@ -10,4 +11,15 @@ QUEST_REWARDS = [
QuestReward.new(30, :MISTSTONE, 1, _INTL("This rare stone can evolve any Pokémon, regardless of their level or evolution method. Use it wisely!"), true),
QuestReward.new(50, :GSBALL, 1, _INTL("This mysterious ball is rumored to be the key to call upon the protector of Ilex Forest. It's a precious relic.")),
QuestReward.new(60, :MASTERBALL, 1, _INTL("This rare ball can catch any Pokémon. Don't waste it!"), true),
]
] : [
# Hoenn quest rewards
QuestReward.new(2, :AMULETCOIN, 1, _INTL("This doubles the money you get in Pokémon battles. Maybe it'll help finance the show!")),
QuestReward.new(5, :INCUBATOR, 1, _INTL("The note that came with it said that it allows you to hatch an egg instantly!")),
QuestReward.new(10, :ITEMFINDER, 1, _INTL("There's a note with it. If there's a hidden item anywhere near you, that little thing will react to tell you.")),
QuestReward.new(15, :INCUBATOR, 3, _INTL("Looks like they sent even more of these incubators for hatching Eggs. There must be a high-profile Pokémon breeder that's a fan of the show!")),
QuestReward.new(20, :SLEEPINGBAG, 1, _INTL("There's a note with it. This deluxe sleeping bag will allow you to sleep anywhere you want. It's so comfortable that you can sleep in it for hours!")),
QuestReward.new(25, :LINKINGCORD, 1, _INTL("Apparently, this strange cable triggers the evolution of Pokémon that typically evolve via trade. I know you'll put it to good use!")),
QuestReward.new(50, :MISTSTONE, 1, _INTL("This rare stone can evolve any Pokémon, regardless of their level or evolution method. Use it wisely!"), true),
QuestReward.new(60, :GSBALL, 1, _INTL("This mysterious ball is rumored to be the key to call upon the protector of Ilex Forest. It's a precious relic.")),
QuestReward.new(70, :MASTERBALL, 1, _INTL("This rare ball can catch any Pokémon. Don't waste it!"), true),
]
@@ -29,4 +29,30 @@ end
def player_has_quest_journal?
return $PokemonBag.pbHasItem?(:DEVONSCOPE) || $PokemonBag.pbHasItem?(:NOTEBOOK)
end
def count_nb_quests(stage,var_nb_total=1,var_nb_remaining=2, var_nb_relative_to_last_stage=3)
nb_quests_for_next_reward = QUEST_REWARDS[stage].nb_quests
nb_quests_completed = get_completed_quests(false).length
nb_remaining = nb_quests_for_next_reward - nb_quests_completed
diff_with_last_stage = -1
diff_with_last_stage = nb_quests_for_next_reward - QUEST_REWARDS[stage-1].nb_quests if stage >= 1
pbSet(var_nb_total,nb_quests_for_next_reward)
pbSet(var_nb_remaining,nb_remaining)
pbSet(var_nb_relative_to_last_stage,diff_with_last_stage)
end
def enough_quest_for_reward?(stage)
return true
nb_quests_for_next_reward = QUEST_REWARDS[stage].nb_quests
return get_completed_quests(false).length >= nb_quests_for_next_reward
end
def receiveQuestReward(stage)
item = QUEST_REWARDS[stage].item
quantity =QUEST_REWARDS[stage].quantity
pbReceiveItem(item, quantity)
reward_message = QUEST_REWARDS[stage].description
pbCallBub(2,@event_id)
pbMessage(reward_message)
end
@@ -1,26 +1,86 @@
def define_quest(quest_id,quest_type,quest_name,quest_description,quest_location,npc_sprite)
case quest_type
when :HOTEL_QUEST
text_color = HotelQuestColor
when :FIELD_QUEST
text_color = FieldQuestColor
when :LEGENDARY_QUEST
text_color = LegendaryQuestColor
when :ROCKET_QUEST
text_color = TRQuestColor
MainQuestColor = :GREEN
HotelQuestColor = :GOLD
class Quest
attr_accessor :id
attr_accessor :name
attr_accessor :desc
attr_accessor :npc
attr_accessor :sprite
attr_accessor :location
attr_accessor :color
attr_accessor :time
attr_accessor :completed
attr_accessor :type
attr_accessor :location_map_id
def name
return _INTL(@name)
end
new_quest = Quest.new(quest_id, quest_name, quest_description, npc_sprite, quest_location, quest_location, text_color)
def desc
return _INTL(@desc)
end
def location
return _INTL(@location)
end
def initialize(id, name, desc, sprite, location, color = :WHITE, time = Time.now, completed = false, map_id=nil)
self.id = id
self.name = name
self.desc = desc
self.npc = npc
self.sprite = sprite
self.location = location
self.color = pbColor(color)
self.time = time
self.completed = completed
self.location_map_id = map_id
end
end
def default_color
return pbColor(get_quest_color(@type))
end
def get_quest_color(quest_type)
case quest_type
when :MAIN_QUEST
return MainQuestColor
when :HOTEL_QUEST
return HotelQuestColor
when :FIELD_QUEST
return FieldQuestColor
when :LEGENDARY_QUEST
return LegendaryQuestColor
when :ROCKET_QUEST
return TRQuestColor
when :MAGMA_QUEST
return MagmaQuestColor
when :AQUA_QUEST
return AquaQuestColor
else
return :WHITE
end
end
def define_quest(quest_id,quest_type,quest_name,quest_description,quest_location,npc_sprite,map_id=nil)
text_color = get_quest_color(quest_type)
new_quest = Quest.new(quest_id, quest_name, quest_description, npc_sprite, quest_location, text_color,Time.now,false,map_id)
new_quest.type= quest_type
QUESTS[quest_id] = new_quest
end
QUESTS = {
#Pokemart
"pokemart_johto" => Quest.new("pokemart_johto", _INTL("Johto Pokémon"), _INTL("A traveler in the PokéMart wants you to show him a Pokémon native to the Johto region."), "traveler_johto", _INTL("Cerulean City"), HotelQuestColor),
"pokemart_hoenn" => Quest.new("pokemart_hoenn", _INTL("Hoenn Pokémon"), _INTL("A traveler in the PokéMart you to show him a Pokémon native to the Hoenn region."), "traveler_hoenn", _INTL("Vermillion City"), HotelQuestColor),
"pokemart_johto" => Quest.new("pokemart_johto", _INTL("Johto Pokémon"), _INTL("A traveler in the Poké Mart wants you to show him a Pokémon native to the Johto region."), "traveler_johto", _INTL("Cerulean City"), HotelQuestColor),
"pokemart_hoenn" => Quest.new("pokemart_hoenn", _INTL("Hoenn Pokémon"), _INTL("A traveler in the Poké Mart you to show him a Pokémon native to the Hoenn region."), "traveler_hoenn", _INTL("Vermillion City"), HotelQuestColor),
"pokemart_sinnoh" => Quest.new("pokemart_sinnoh", _INTL("Sinnoh Pokémon"), _INTL("A traveler in the Department Center wants you to show him a Pokémon native to the Sinnoh region."), "traveler_sinnoh", _INTL("Celadon City"), HotelQuestColor),
"pokemart_unova" => Quest.new( "pokemart_unova", _INTL("Unova Pokémon"), _INTL("A traveler in the PokéMart wants you to show him a Pokémon native to the Unova region."), "traveler_unova", _INTL("Fuchsia City"), HotelQuestColor),
"pokemart_kalos" => Quest.new("pokemart_kalos", _INTL("Kalos Pokémon"), _INTL("A traveler in the PokéMart wants you to show him a Pokémon native to the Kalos region."), "traveler_kalos", _INTL("Saffron City"), HotelQuestColor),
"pokemart_alola" => Quest.new("pokemart_alola", _INTL("Alola Pokémon"), _INTL("A traveler in the PokéMart wants you to show him a Pokémon native to the Alola region."), "traveler_alola", _INTL("Cinnabar Island"), HotelQuestColor),
"pokemart_unova" => Quest.new( "pokemart_unova", _INTL("Unova Pokémon"), _INTL("A traveler in the Poké Mart wants you to show him a Pokémon native to the Unova region."), "traveler_unova", _INTL("Fuchsia City"), HotelQuestColor),
"pokemart_kalos" => Quest.new("pokemart_kalos", _INTL("Kalos Pokémon"), _INTL("A traveler in the Poké Mart wants you to show him a Pokémon native to the Kalos region."), "traveler_kalos", _INTL("Saffron City"), HotelQuestColor),
"pokemart_alola" => Quest.new("pokemart_alola", _INTL("Alola Pokémon"), _INTL("A traveler in the Poké Mart wants you to show him a Pokémon native to the Alola region."), "traveler_alola", _INTL("Cinnabar Island"), HotelQuestColor),
#Pewter hotel
@@ -28,7 +88,7 @@ QUESTS = {
"pewter_2" =>Quest.new("pewter_2", _INTL("Lost Medicine"), _INTL("A youngster in Pewter City needs your help to find a lost Revive. He lost it by sitting on a bench somewhere in Pewter City."), "BW (19)", _INTL("Pewter City"), HotelQuestColor),
"pewter_3" =>Quest.new("pewter_3", _INTL("Bug Evolution "), _INTL("A Bug Catcher in Pewter City wants you to show him a fully-evolved Bug Pokémon."), "BWBugCatcher_male", _INTL("Pewter City"), HotelQuestColor),
"pewter_field_1" => Quest.new("pewter_field_1", _INTL("Nectar garden"), _INTL("An old man wants you to bring differently colored flowers for the city's garden."), "BW (039)", _INTL("Pewter City"), FieldQuestColor),
"pewter_field_2" => Quest.new("pewter_field_2", _INTL("I Choose You!"), _INTL("A Pikachu in the PokéMart has lost its official Pokémon League Hat. Find one and give it to the Pikachu!"), "YOUNGSTER_LeagueHat", _INTL("Pewter City"), FieldQuestColor),
"pewter_field_2" => Quest.new("pewter_field_2", _INTL("I Choose You!"), _INTL("A Pikachu in the Poké Mart has lost its official Pokémon League Hat. Find one and give it to the Pikachu!"), "YOUNGSTER_LeagueHat", _INTL("Pewter City"), FieldQuestColor),
"pewter_field_3" => Quest.new("pewter_field_3", _INTL("Prehistoric Amber!"), _INTL("Meetup with a scientist in Viridian Forest to look for prehistoric amber."), "BW (82)", _INTL("Pewter City"), FieldQuestColor),
#Cerulean hotel
@@ -127,11 +187,37 @@ QUESTS = {
# HOENN QUESTS ##
# ################
## MAIN QUESTS
define_quest("main_dad",:MAIN_QUEST,_INTL("Visit Dad!"), _INTL("Go visit your Dad at his Gym in Petalburg Town!"),_INTL("Petalburg City"),"NPC_Hoenn_Leader_Norman",MAP_PETALBURG)
define_quest("main_wally",:MAIN_QUEST,_INTL("Catching Tutoring"), _INTL("Catch a wild Pokémon for Wally."),_INTL("Petalburg City"),"NPC_Hoenn_Wally",MAP_PETALBURG)
define_quest("main_gym_1",:MAIN_QUEST,_INTL("The Pokémon Gym Challenge"), _INTL("Challenge Roxanne in Rustboro City to obtain your first Gym Badge."),_INTL("Rustboro City"),"NPC_Hoenn_Leader_Roxanne",MAP_RUSTBORO)
define_quest("main_gym_2",:MAIN_QUEST,_INTL("The Pokémon Gym Challenge"), _INTL("Challenge Brawly in Dewford Town to obtain your second Gym Badge."),_INTL("Dewford Town"),"NPC_Hoenn_Leader_Brawly",MAP_DEWFORD)
define_quest("main_gym_3",:MAIN_QUEST,_INTL("The Pokémon Gym Challenge"), _INTL("Challenge Wattson in Mauville City to obtain your third Gym Badge."),_INTL("Mauville City"),"NPC_Hoenn_Leader_Wattson",MAP_MAUVILLE)
define_quest("main_gym_4",:MAIN_QUEST,_INTL("The Pokémon Gym Challenge"), _INTL("Challenge Flannery in Lavaridge Town to obtain your fourth Gym Badge."),_INTL("Lavaridge Town"),"NPC_Hoenn_Leader_Flannery",MAP_LAVARIDGE)
define_quest("main_gym_5",:MAIN_QUEST,_INTL("The Pokémon Gym Challenge"), _INTL("Challenge Norman in Petalburg City to obtain your fifth Gym Badge."),_INTL("Petalburg Town"),"NPC_Hoenn_Leader_Norman",MAP_PETALBURG)
define_quest("main_gym_6",:MAIN_QUEST,_INTL("The Pokémon Gym Challenge"), _INTL("Challenge Winona in Fortree City to obtain your sixth Gym Badge."),_INTL("Fortree City"),"NPC_Hoenn_Leader_Winona",MAP_FORTREE)
define_quest("main_gym_7",:MAIN_QUEST,_INTL("The Pokémon Gym Challenge"), _INTL("Challenge Tate & Liza in Mossdeep City to obtain your seventh Gym Badge."),_INTL("Mossdeep City"),"NPC_Hoenn_Leader_TateLiza",MAP_MOSSDEEP)
define_quest("main_gym_8",:MAIN_QUEST,_INTL("The Pokémon Gym Challenge"), _INTL("Challenge Wallace in Sootopolis City to obtain your final Gym Badge."),_INTL("Sootopolis City"),"NPC_Hoenn_Leader_Wallace",MAP_SOOTOPOLIS)
define_quest("main_league",:MAIN_QUEST,_INTL("Pokémon League Challenge"), _INTL("Collect all 8 Gym Badges and take part in the Pokémon League!"),_INTL("Hoenn"),"NPC_Hoenn_GymMan",MAP_LEAGUE)
define_quest("main_stolen_parts",:MAIN_QUEST,_INTL("Stolen Package"), _INTL("Recover a package stolen by Team Magma!"),_INTL("Rustboro City"),"NPC_Hoenn_MrStone")
define_quest("main_steven_letter",:MAIN_QUEST,_INTL("Steven's Letter"), _INTL("Deliver a letter from the Devon Corp. president to Steven in Granite Cave. "),_INTL("Granite Cave"),"NPC_Hoenn_MrStone",MAP_DEWFORD)
define_quest("main_devon_parts",:MAIN_QUEST,_INTL("Devon Parts Delivery"), _INTL("Deliver the Devon Parts to the Shipyard in Slateport City."),_INTL("Slateport City"),"NPC_Hoenn_MrStone",MAP_SLATEPORT)
#SIDE QUESTS
define_quest("template",:FIELD_QUEST,_INTL("Template Quest"), _INTL("Don't forget to change the quest ID if you copy paste this!"),_INTL("Unknown"),"000")
#route 102
define_quest("route_102_rematch",:FIELD_QUEST,_INTL("Trainer Rematches"), _INTL("A lass you battled wants to switch up her team and rematch you!"),_INTL("Route 102"),"NPC_Hoenn_Lass")
#Petalburg Town
define_quest("petalburg_berry",:FIELD_QUEST,_INTL("Berry Contest"), _INTL("Take part in the berry-growing contest in Petalburg Town!"),_INTL("Petalburg Town"),"NPC_Hoenn_Breeder_F")
#Route 116
define_quest("route116_glasses",:FIELD_QUEST,_INTL("Lost glasses"), _INTL("A trainer has lost their glasses, help him find them!"),_INTL("Route 116"),"NPC_Hoenn_BugManiac")
define_quest("route116_glasses",:FIELD_QUEST,_INTL("Lost glasses"), _INTL("A trainer has lost their glasses, help him find them!"),_INTL("Route 116"),"NPC_Hoenn_Collector_NoGlasses")
#Route 104 (South)
define_quest("route104_rivalWeather",:FIELD_QUEST,_INTL("Weather Watch"), _INTL("Help your rival with fieldwork and find a Pokémon that only appears when it's windy!"),_INTL("Route 104"),"rival")
@@ -142,9 +228,69 @@ define_quest("petalburgwoods_spores",:FIELD_QUEST,_INTL("Spores Harvest"), _INTL
#Route 104 (North)
define_quest("route104_oricorio",:FIELD_QUEST,_INTL("Special Flowery Grass"), _INTL("Find an Oricorio in the flowery grass behind the flower shop."),_INTL("Route 104"),"NPC_Hoenn_AromaLady")
define_quest("route104_oricorio_forms",:FIELD_QUEST,_INTL("Nectar Flowers"), _INTL("Find all 4 types of nectar flowers to transform Oricorio."),_INTL("Route 104"),"NPC_Hoenn_AromaLady")
define_quest("route104_allergic",:FIELD_QUEST,_INTL("The Allergic Rich Boy"), _INTL("An allergy-ridden rich boy is looking for a flowery Pokémon to give to his girlfriend."),_INTL("Route 104"),"NPC_Hoenn_RichBoy")
#Route 115
define_quest("route115_secretBase",:FIELD_QUEST,_INTL("Your Very Own Secret Base!"), _INTL("Talk to Aarune near his secret base to learn how to make your own."),_INTL("Route 115"),"NPC_Hoenn_AromaLady")
#Rustboro
define_quest("rustboro_whismur",:FIELD_QUEST,_INTL("Volume Booster!"), _INTL("Find a Wingull to fuse with a Whismur to make it louder."),_INTL("Rustboro City"),"NPC_schoolgirl")
define_quest("rustboro_shiny",:FIELD_QUEST,_INTL("A Green Marill?"), _INTL("A child claims they've seen a green Marill by the pond on Route 104. Go investigate!"),_INTL("Rustboro City"),"NPC_preschooler_m")
define_quest("rustboro_trash",:FIELD_QUEST,_INTL("Clean Up the Beach!"), _INTL("Help the ranger clean-up the beach behind the Devon Corp. building."),_INTL("Rustboro City"),"NPC_Hoenn_Ranger_M")
define_quest("rustboro_fusion",:FIELD_QUEST,_INTL("Wild Fusion Study"), _INTL("Help a scientist gather data by getting wild Pokémon to fuse before a battle 3 different times."),_INTL("Rustboro City"),"NPC_scientist_m")
#Dewford
define_quest("dewford_fishing",:FIELD_QUEST,_INTL("The Angler's Rite of Passage"), _INTL("It's tradition to fish a Skrelp near Dewford Town as a rite of passage. Find one and show it to the fisherman!"),_INTL("Dewford Town"),"NPC_Hoenn_Fisherman")
#Slateport
define_quest("slateport_team_aqua",:AQUA_QUEST,_INTL("Join Team Aqua!"), _INTL("Archie invited you to join Team Aqua. Go meet them at their camp on Slateport Beach if you so choose."),_INTL("Slateport City"),"NPC_Hoenn_Aqua_Archie",MAP_AQUA_CAMP)
define_quest("slateport_team_magma",:MAGMA_QUEST,_INTL("Join Team Magma!"), _INTL("Maxie invited you to join Team Magma. Go meet them at their camp, North of Slateport if you so choose."),_INTL("Slateport City"),"NPC_Hoenn_Magma_Maxie",MAP_MAGMA_CAMP)
# Route 109
define_quest("route109_tanning",:FIELD_QUEST,_INTL("Soaking in the sun"), _INTL("Sit in a beach chair until your suntan is on point!"),_INTL("Route 109"),"NPC_Hoenn_Triathlete_F")
define_quest("route109_seahouse",:FIELD_QUEST,_INTL("Hot Battles at the Seashore House"), _INTL("Defeat all of the trainers in the Seashore House!"),_INTL("Route 109"),"NPC_Hoenn_Fisherman")
define_quest("route109_beachball",:FIELD_QUEST,_INTL("Find a New Beach Ball!"), _INTL("Replace the popped beach ball of the kids playing on the beach"),_INTL("Route 109"),"NPC_Hoenn_Tuber_M")
#Team Magma - Route 103
define_quest("magma_camp_attack",:MAGMA_QUEST,_INTL("Under Attack!"), _INTL("Defend the Team Magma Camp against Team Aqua!"),_INTL("Magma Camp"),"NPC_Hoenn_Magma_Exec_M")
define_quest("magma_slugma_eggs",:MAGMA_QUEST,_INTL("Egg Hunt!"), _INTL("Collect Slugma Eggs with Tabitha."),_INTL("Cliffside Sanctuary"),"NPC_Hoenn_Magma_Exec_M")
define_quest("magma_help_grunts",:MAGMA_QUEST,_INTL("Grunt Work!"), _INTL("Help 3 grunts in the Team Magma Camp, then report back to Tabitha!"),_INTL("Magma Camp"),"NPC_Hoenn_Magma_Exec_M")
define_quest("magma_numel",:MAGMA_QUEST,_INTL("Anti-Water Training!"), _INTL("Fuse Numel to make it resistant Water-type attacks."),_INTL("Magma Camp"),"NPC_Hoenn_Magma_Grunt_M")
define_quest("magma_graffiti",:MAGMA_QUEST,_INTL("Painting the Town Red"), _INTL("Team Aqua painted their logo on various walls in Slateport City. Cover them up with the Team Magma logo instead!"),_INTL("Magma Camp"),"NPC_Hoenn_Magma_Grunt_F")
define_quest("magma_song",:MAGMA_QUEST,_INTL("The Magma Theme Song"), _INTL("Help compose lyrics to the official Team Magma theme song!"),_INTL("Magma Camp"),"NPC_Hoenn_Magma_Grunt_F")
#Team Aqua - Route 108
define_quest("aqua_camp_attack",:AQUA_QUEST,_INTL("Under Attack!"), _INTL("Defend the Team Aqua Camp against Team Magma!"),_INTL("Aqua Camp"),"NPC_Hoenn_Aqua_Exec_F")
define_quest("aqua_wailmer_eggs",:AQUA_QUEST,_INTL("Egg Hunt!"), _INTL("Collect Wailmer Eggs for Shelly."),_INTL("Route 108"),"NPC_Hoenn_Aqua_Exec_F")
define_quest("aqua_help_grunts",:AQUA_QUEST,_INTL("Grunt Work!"), _INTL("Help 3 grunts in the Team Aqua Camp, then report back to Shelly!"),_INTL("Aqua Camp"),"NPC_Hoenn_Aqua_Exec_F")
define_quest("aqua_carvanha",:AQUA_QUEST,_INTL("Just Add Water!"), _INTL("You were given two Zubats and a Geodude. Fuse all three of them into Water-type Pokémon."),_INTL("Aqua Camp"),"NPC_Hoenn_Aqua_Grunt_F")
define_quest("aqua_graffiti",:AQUA_QUEST,_INTL("Painting the Town Blue"), _INTL("Team Magma painted their logo on various walls in Slateport City. Cover them up with the Team Aqua logo instead!"),_INTL("Aqua Camp"),"NPC_Hoenn_Aqua_Grunt_M")
define_quest("aqua_song",:AQUA_QUEST,_INTL("The Aqua Theme Song"), _INTL("Help compose lyrics to the official Team Aqua theme song!"),_INTL("Aqua Camp"),"NPC_Hoenn_Aqua_Grunt_F")
#Route 110
define_quest("route110_bike",:FIELD_QUEST,_INTL("Cycling Road Time Trial"), _INTL("Go through the Cycling Road as fast as possible. You'll be penalized if you hit the walls!"),_INTL("Route 110"),"NPC_Hoenn_Triathlete_M_bike")
#Mauville
define_quest("mauville_quests_1",:FIELD_QUEST,_INTL("Associate Producer! - Episode 1"), _INTL("You've been hired as an associate producer on a TV show! Complete 2 quests to help write the second season of the show."),_INTL("Mauville TV"),"NPC_Hoenn_Collector")
define_quest("mauville_quests_2",:FIELD_QUEST,_INTL("Associate Producer! - Episode 2"), _INTL("You've been hired as an associate producer on a TV show! Complete 5 quests to help write the second season of the show."),_INTL("Mauville TV"),"NPC_Hoenn_Collector")
define_quest("mauville_quests_3",:FIELD_QUEST,_INTL("Associate Producer! - Episode 3"), _INTL("You've been hired as an associate producer on a TV show! Complete 10 quests to help write the second season of the show."),_INTL("Mauville TV"),"NPC_Hoenn_Collector")
define_quest("mauville_quests_4",:FIELD_QUEST,_INTL("Associate Producer! - Episode 4"), _INTL("You've been hired as an associate producer on a TV show! Complete 15 quests to help write the second season of the show."),_INTL("Mauville TV"),"NPC_Hoenn_Collector")
define_quest("mauville_quests_5",:FIELD_QUEST,_INTL("Associate Producer! - Episode 5"), _INTL("You've been hired as an associate producer on a TV show! Complete 20 quests to help write the second season of the show."),_INTL("Mauville TV"),"NPC_Hoenn_Collector")
define_quest("mauville_quests_6",:FIELD_QUEST,_INTL("Associate Producer! - Episode 6"), _INTL("You've been hired as an associate producer on a TV show! Complete 25 quests to help write the second season of the show."),_INTL("Mauville TV"),"NPC_Hoenn_Collector")
define_quest("mauville_quests_7",:FIELD_QUEST,_INTL("Associate Producer! - Episode 7"), _INTL("You've been hired as an associate producer on a TV show! Complete 30 quests to help write the second season of the show."),_INTL("Mauville TV"),"NPC_Hoenn_Collector")
define_quest("mauville_magma",:MAGMA_QUEST,_INTL("The Element of Surprise!"), _INTL("Catch a Tynamo in the waters near New Mauville to catch Team Aqua by surprise."),_INTL("Mauville City"),"NPC_Hoenn_Magma_Grunt_M")
define_quest("mauville_aqua",:AQUA_QUEST,_INTL("The Element of Surprise!"), _INTL("Catch a Tynamo in the waters near New Mauville to catch Team Magma by surprise."),_INTL("Mauville City"),"NPC_Hoenn_Aqua_Grunt_M")
#Route 111
define_quest("route111_winstrate",:FIELD_QUEST,_INTL("The Winstrate Family"), _INTL("Defeat all 4 members of the Winstrate family in back-to-back battles."),_INTL("Route 111"),"NPC_Hoenn_Pokefan_M")
#Verdanturf
define_quest("verdanturf_shroomish",:FIELD_QUEST,_INTL("A Lost Shroomish"), _INTL("A girl lost her Shroomish and needs your help to find it."),_INTL("Verdanturf Town"),"NPC_Hoenn_Schoolgirl")
define_quest("verdanturf_nurse",:FIELD_QUEST,_INTL("The Bored Nurse"), _INTL("The Pokémon Center's nurse challenged you to a battle. Meet her in the meadow behind the Pokémon Center."),_INTL("Verdanturf Town"),"NPC_nurse")
#Rusturf Tunnel
define_quest("rusturf_trumpet",:FIELD_QUEST,_INTL("Uproar in B Flat"), _INTL("A trumpet player is cornered in Rusturf Tunnel. Find a way to help him!"),_INTL("Rusturf Tunnel"),"NPC_Hoenn_trumpet_playing")
define_quest("evergrande_trumpet",:FIELD_QUEST,_INTL("The Trumpet Festival!"), _INTL("Find the 4 Trumpet Brothers and join the Trumpet Festival in Evergrande City."),_INTL("Evergrande City"),"NPC_Hoenn_trumpet_playing",MAP_EVERGRANDE)
@@ -0,0 +1,915 @@
##=============================================================================
## Easy Questing System - Refactored with Extensible Mode System
## Original by M3rein
# Refactored using by Claude
# Adapted for Pokemon Infinite Fusion by chardub
##=============================================================================
## Main entry point for the quest log
##=============================================================================
def pbQuestlog
ensure_quests_repaired
loop do
if $Trainer&.pokenav&.last_opened_quest_mode == :LIST || Settings::KANTO
ql = Questlog.new
break unless ql.switch_to_map
$Trainer&.pokenav&.last_opened_quest_mode = :MAP
else
qm = showQuestMap
break unless qm&.reopen_map
$Trainer&.pokenav&.last_opened_quest_mode = :LIST
end
end
end
def ensure_quests_repaired
return if $Trainer.quests_repaired
fix_quest_ids
$Trainer.quests_repaired = true
end
##=============================================================================
## QuestSprite - Sprite class for quest list items
##=============================================================================
class QuestSprite < IconSprite
attr_accessor :quest
end
##=============================================================================
## QuestMode - Base class for quest filtering modes
##=============================================================================
class QuestCategory
attr_reader :name, :button_text
attr_accessor :last_index
def initialize(name, button_text)
@name = name
@button_text = button_text
@last_index = 0
end
# Override this method to define filtering logic
def filter_quests(all_quests)
raise NotImplementedError, "Subclasses must implement filter_quests"
end
# Override to customize empty message
def empty_message
"No quests"
end
# Override to customize title
def title
@name
end
end
##=============================================================================
## Built-in Quest Modes
##=============================================================================
class CompletedQuestMode < QuestCategory
def initialize
super("Completed Quests", "Completed")
end
def button_path
return "Graphics/Pictures/eqi/quest_button_complete"
end
def filter_quests(all_quests)
all_quests.select { |q| q.completed }
end
def empty_message
_INTL("No completed quests")
end
end
class MainQuestMode < QuestCategory
def initialize
super("Main Quests", "Main Quests")
end
def button_path
return "Graphics/Pictures/eqi/quest_button_main"
end
def filter_quests(all_quests)
return all_quests.select { |q| !q.completed && q.type == :MAIN_QUEST }
end
def empty_message
_INTL("No ongoing main quests")
end
end
class SideQuestMode < QuestCategory
def initialize
super("Side Quests", "Side Quests")
end
def button_path
return "Graphics/Pictures/eqi/quest_button_side"
end
def filter_quests(all_quests)
return all_quests.select { |q| !q.completed && q.type != :MAIN_QUEST }
end
def empty_message
_INTL("No side quests")
end
end
# class LocationQuestMode < QuestMode
# attr_reader :location
#
# def initialize(location)
# @location = location
# super("#{location} Quests", location)
# end
#
# def filter_quests(all_quests)
# return all_quests.select { |q| !q.completed && q.location.include?(@location) }
# end
#
# def empty_message
# _INTL("No quests in {1}", @location)
# end
# end
##=============================================================================
## Questlog - Main quest interface controller (Refactored)
##=============================================================================
class Questlog
attr_reader :switch_to_map
# Scene constants
SCENE_MAIN = 0
SCENE_LIST = 1
SCENE_DETAIL = 2
# UI constants
MAX_VISIBLE_QUESTS = 6
FADE_SPEED = 32
ANIMATION_FRAMES = 12
CHAR_ANIMATION_INTERVAL = 6
def initialize(open_quest: nil, from_map: false)
@from_map = from_map
@switch_to_map = false
initialize_data
initialize_modes
initialize_viewport
if open_quest
create_sprites(false)
setup_open_quest(open_quest)
else
create_sprites(false)
animate_intro
end
main_loop
cleanup
end
private
##---------------------------------------------------------------------------
## Initialization
##---------------------------------------------------------------------------
def setup_open_quest(quest)
@skip_menu = true
# Find which mode contains this quest
@current_mode = @modes.find { |mode| mode.filter_quests($Trainer.quests).include?(quest) }
# Fall back to first mode if not found (e.g. completed quests shown via direct open)
@current_mode ||= @modes.first
@filtered_quests = @current_mode.filter_quests($Trainer.quests)
@quest_list_menu_index = @filtered_quests.index(quest) || 0
@box = 0
# Jump straight to detail view
@scene = SCENE_DETAIL
create_detail_background
create_character_sprite("char", quest, 62, 130)
draw_quest_details(quest)
animate_detail_in
end
def initialize_data
$Trainer.quests = [] if $Trainer.quests.nil?
@page = 0
@main_menu_index = 0
@quest_list_menu_index = 0
@scene = SCENE_MAIN
@current_mode = nil
@box = 0 # Visible quest index (0-5)
@frame = 0
@filtered_quests = []
@scroll_timer = 12 # Cooldown counter for holding up/down
@scroll_delay = 6 # Frames to wait before repeating movement
fix_broken_TR_quests
end
def initialize_modes
# Register all available modes here
@modes = []
@modes << MainQuestMode.new if Settings::HOENN
@modes << SideQuestMode.new
@modes << CompletedQuestMode.new
# You can dynamically add location-based modes:
# @modes << LocationQuestMode.new("Cerulean City")
# @modes << LocationQuestMode.new("Viridian Forest")
end
def initialize_viewport
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 100002
@sprites = {}
end
def create_sprites(main_page = true)
create_main_bitmap
create_background
create_mode_buttons #if main_page
draw_main_text
end
def create_main_bitmap
@sprites["main"] = BitmapSprite.new(Graphics.width, Graphics.height, @viewport)
@sprites["main"].z = 1
@sprites["main"].opacity = 0
@main = @sprites["main"].bitmap
pbSetSystemFont(@main)
end
def create_background
@sprites["bg0"] = IconSprite.new(0, 0, @viewport)
bg_path = isDarkMode ?
"Graphics/Pictures/Pokegear/bg_dark" :
"Graphics/Pictures/Pokegear/bg"
@sprites["bg0"].setBitmap(bg_path)
@sprites["bg0"].opacity = 0
end
def create_mode_buttons
default_button_path = "Graphics/Pictures/eqi/quest_button"
@modes.size.times do |i|
@sprites["btn#{i}"] = IconSprite.new(0, 0, @viewport)
button_path = @modes[i].button_path
if button_path
@sprites["btn#{i}"].setBitmap(button_path)
else
@sprites["btn#{i}"].setBitmap(default_button_path)
end
@sprites["btn#{i}"].x = 84
@sprites["btn#{i}"].y = 130 + 56 * i
@sprites["btn#{i}"].src_rect.height = (@sprites["btn#{i}"].bitmap.height / 2).round
@sprites["btn#{i}"].src_rect.y = i == 0 ? (@sprites["btn#{i}"].bitmap.height / 2).round : 0
@sprites["btn#{i}"].opacity = 0
end
end
def draw_main_text
pbDrawOutlineText(@main, -160, 8, 512, 384, _INTL("Quest Log"),
Color.new(255, 255, 255), Color.new(0, 0, 0), 1)
if can_switch_mode?
pbDrawOutlineText(@main, 160, 8, 512, 384, _INTL("L/R : MAP"),
Color.new(255, 255, 255), Color.new(0, 0, 0), 1)
end
# Draw button labels and quest counts
@modes.each_with_index do |mode, i|
quest_count = mode.filter_quests($Trainer.quests).size
y_pos = 142 + (56 * i)
pbDrawOutlineText(@main, 0, y_pos, 512, 384,
_INTL("{1}: {2}", mode.button_text, quest_count),
Color.new(255, 255, 255), Color.new(0, 0, 0), 1)
end
end
def animate_intro
ANIMATION_FRAMES.times do |i|
Graphics.update
@sprites["bg0"]&.opacity += FADE_SPEED if i < 8
# Fade in all mode buttons
@modes.size.times do |j|
@sprites["btn#{j}"]&.opacity += FADE_SPEED if i > 3
end
@sprites["main"]&.opacity += 64 if i > 7
end
end
##---------------------------------------------------------------------------
## Main Loop
##---------------------------------------------------------------------------
def main_loop
@frame = 0
loop do
@frame += 1
Graphics.update
Input.update
break if handle_input
@frame = 0 if @frame == 18
end
end
def handle_input
case @scene
when SCENE_MAIN
return handle_main_input
when SCENE_LIST
return handle_list_input
when SCENE_DETAIL
return handle_detail_input
end
return false
end
def handle_main_input
if (Input.trigger?(Input::L) || Input.trigger?(Input::R)) && can_switch_mode?
@switch_to_map = true
pbSEPlay("GUI storage show party panel")
$Trainer&.pokenav&.last_opened_quest_mode = :MAP
return true
end
return true if Input.trigger?(Input::B)
if Input.trigger?(Input::C)
show_quest_list(@main_menu_index)
end
if @scroll_timer > 0
@scroll_timer -= 1
else
if Input.press?(Input::DOWN)
switch_button(:DOWN)
@scroll_timer = @scroll_delay
elsif Input.press?(Input::UP)
switch_button(:UP)
@scroll_timer = @scroll_delay
end
end
false
end
def can_switch_mode?
return Settings::HOENN && (@scene != SCENE_DETAIL)
end
def handle_list_input
if (Input.trigger?(Input::L) || Input.trigger?(Input::R)) && can_switch_mode?
@switch_to_map = true
return true
end
if Input.trigger?(Input::B)
return_to_main
elsif Input.trigger?(Input::C)
show_quest_detail
else
handle_scroll_input
end
animate_arrows
return false
end
def handle_scroll_input
# Only scroll when timer allows
if @scroll_timer > 0
@scroll_timer -= 1
return
end
if Input.press?(Input::DOWN)
move_selection(:DOWN)
@scroll_timer = @scroll_delay
elsif Input.press?(Input::UP)
move_selection(:UP)
@scroll_timer = @scroll_delay
end
end
def handle_detail_input
if Input.trigger?(Input::B)
return true
end
animate_character if [6, 12, 18].include?(@frame)
return false
end
##---------------------------------------------------------------------------
## Navigation
##---------------------------------------------------------------------------
def update_button_selection(index, selected)
return unless @sprites["btn#{index}"]
height = (@sprites["btn#{index}"].bitmap.height / 2).round
@sprites["btn#{index}"].src_rect.y = selected ? height : 0
end
def switch_button(dir)
max_index = @modes.size - 1
if dir == :DOWN
return if @main_menu_index >= max_index
update_button_selection(@main_menu_index, false)
@main_menu_index += 1
update_button_selection(@main_menu_index, true)
else
return if @main_menu_index <= 0
update_button_selection(@main_menu_index, false)
@main_menu_index -= 1
update_button_selection(@main_menu_index, true)
end
end
def move_selection(dir)
return if @filtered_quests.empty?
if dir == :DOWN
return if @quest_list_menu_index == @filtered_quests.size - 1
deselect_current_quest
@quest_list_menu_index += 1
@box += 1
@box = 5 if @box > 5
select_current_quest
refresh_quest_list if @box == 5
else
return if @quest_list_menu_index == 0
deselect_current_quest
@quest_list_menu_index -= 1
@box -= 1
@box = 0 if @box < 0
select_current_quest
refresh_quest_list if @box == 0
end
#pbWait(4)
end
def deselect_current_quest
@sprites["quest#{@box}"].src_rect.y = 0 if @sprites["quest#{@box}"]
end
def select_current_quest
if @sprites["quest#{@box}"]
@sprites["quest#{@box}"].src_rect.y = (@sprites["quest#{@box}"].bitmap.height / 2).round
end
end
##---------------------------------------------------------------------------
## Scene Transitions
##---------------------------------------------------------------------------
def return_to_main
pbWait(1)
dispose_quest_list_sprites
fade_to_main
reset_list_state
redraw_main_screen
animate_main_return
end
def fade_to_main
ANIMATION_FRAMES.times do |i|
Graphics.update
fade_sprites_out(i)
end
dispose_list_sprites
clear_bitmaps
end
def fade_sprites_out(index)
@sprites["main"].opacity -= FADE_SPEED if @sprites["main"]
@sprites["bg0"].opacity += FADE_SPEED if @sprites["bg0"].opacity < 255
if index > 3
@sprites["bg1"].opacity -= FADE_SPEED if @sprites["bg1"]
@sprites["bg2"].opacity -= FADE_SPEED if @sprites["bg2"]
@sprites["pager"].opacity -= FADE_SPEED if @sprites["pager"]
@sprites["pager2"].opacity -= FADE_SPEED if @sprites["pager2"]
end
@sprites["char"].opacity -= FADE_SPEED if @sprites["char"]
@sprites["char2"].opacity -= FADE_SPEED if @sprites["char2"]
@sprites["text"].opacity -= FADE_SPEED if @sprites["text"]
@sprites["up"].opacity -= FADE_SPEED if @sprites["up"]
@sprites["down"].opacity -= FADE_SPEED if @sprites["down"]
fade_quest_sprites
end
def fade_quest_sprites
MAX_VISIBLE_QUESTS.times do |i|
@sprites["quest#{i}"].opacity -= FADE_SPEED if @sprites["quest#{i}"]
end
end
def dispose_list_sprites
@sprites["up"].dispose if @sprites["up"]
@sprites["down"].dispose if @sprites["down"]
end
def clear_bitmaps
@main.clear if @main
@text.clear if @text
@text2.clear if @text2
end
def reset_list_state
@scene = SCENE_MAIN
end
def redraw_main_screen
pbDrawOutlineText(@main, 0, 2, 512, 384, _INTL("Quest Log"),
Color.new(255, 255, 255), Color.new(0, 0, 0), 1)
@modes.each_with_index do |mode, i|
quest_count = mode.filter_quests($Trainer.quests).size
y_pos = 142 + (56 * i)
pbDrawOutlineText(@main, 0, y_pos, 512, 384,
_INTL("{1}: {2}", mode.button_text, quest_count),
Color.new(255, 255, 255), Color.new(0, 0, 0), 1)
end
end
def animate_main_return
ANIMATION_FRAMES.times do |i|
Graphics.update
@sprites["bg0"].opacity += FADE_SPEED if i < 8
@modes.size.times do |j|
@sprites["btn#{j}"].opacity += FADE_SPEED if i > 3
end
@sprites["main"].opacity += 48 if i > 5
end
end
##---------------------------------------------------------------------------
## Quest List Display
##---------------------------------------------------------------------------
def show_quest_list(mode_index)
pbWait(2)
@scene = SCENE_LIST
@current_mode = @modes[mode_index]
@quest_list_menu_index = @current_mode.last_index
@box = [@quest_list_menu_index, MAX_VISIBLE_QUESTS - 1].min
@filtered_quests = @current_mode.filter_quests($Trainer.quests)
create_arrow_sprites
fade_to_list
clear_bitmaps
display_quest_list
end
def create_arrow_sprites
@sprites["up"] = create_arrow(36, false)
@sprites["down"] = create_arrow(360, true)
@sprites["down"].visible = @filtered_quests.size > MAX_VISIBLE_QUESTS
@sprites["down"].opacity = 0
end
def create_arrow(y_pos, flip)
arrow = IconSprite.new(0, 0, @viewport)
arrow.setBitmap("Graphics/Pictures/EQI/quest_arrow")
arrow.zoom_x = 1.25
arrow.zoom_y = 1.25
arrow.x = Graphics.width / 2 + (flip ? 21 : 0)
arrow.y = y_pos
arrow.z = 2
arrow.angle = flip ? 180 : 0
arrow.visible = false
arrow
end
def fade_to_list
10.times do |i|
Graphics.update
if i > 1
@modes.size.times do |j|
@sprites["btn#{j}"].opacity -= FADE_SPEED
end
@sprites["main"].opacity -= FADE_SPEED
fade_detail_sprites
end
end
end
def fade_detail_sprites
@sprites["bg1"].opacity -= FADE_SPEED if @sprites["bg1"]
@sprites["bg2"].opacity -= FADE_SPEED if @sprites["bg2"]
@sprites["pager"].opacity -= FADE_SPEED if @sprites["pager"]
@sprites["pager2"].opacity -= FADE_SPEED if @sprites["pager2"]
@sprites["char"].opacity -= FADE_SPEED if @sprites["char"]
@sprites["char2"].opacity -= FADE_SPEED if @sprites["char2"]
@sprites["text"].opacity -= FADE_SPEED if @sprites["text"]
@sprites["text2"].opacity -= FADE_SPEED if @sprites["text2"]
end
def display_quest_list
[@filtered_quests.size, MAX_VISIBLE_QUESTS].min.times do |i|
create_quest_sprite(i, @filtered_quests[i])
draw_quest_name_on_main(i, @filtered_quests[i])
end
if @filtered_quests.empty?
pbDrawOutlineText(@main, 0, 175, 512, 384, @current_mode.empty_message,
pbColor(:WHITE), pbColor(:BLACK), 1)
end
pbDrawOutlineText(@main, 0, 2, 512, 384, @current_mode.title,
Color.new(255, 255, 255), Color.new(0, 0, 0), 1)
animate_quest_list
end
def create_quest_sprite(index, quest)
sprite_key = "quest#{index}"
@sprites[sprite_key] = QuestSprite.new(0, 0, @viewport)
sprite = @sprites[sprite_key]
sprite.setBitmap("Graphics/Pictures/EQI/quest_button")
sprite.quest = quest
sprite.x = 94
sprite.y = 42 + 52 * index
sprite.src_rect.height = (sprite.bitmap.height / 2).round
sprite.src_rect.y = (sprite.bitmap.height / 2).round if index == @quest_list_menu_index
sprite.opacity = 0
draw_quest_name_on_main(index, quest)
set_quest_list_sprite(index,quest)
end
def draw_quest_name_on_main(index, quest)
y_pos = get_cell_y_position(index)
pbDrawOutlineText(@main, 11, y_pos, 512, 384,
quest.name,
quest.default_color,
Color.new(0, 0, 0),
1)
end
def get_cell_y_position(index)
56 + (52 * index)
end
def animate_quest_list
ANIMATION_FRAMES.times do |i|
Graphics.update
@sprites["main"].opacity += FADE_SPEED if i < 8
@sprites["down"].opacity += FADE_SPEED if i > 3
[@filtered_quests.size, MAX_VISIBLE_QUESTS].min.times do |j|
@sprites["quest#{j}"].opacity += FADE_SPEED if i > 3
@sprites["quest_icon#{j}"].opacity += FADE_SPEED if i > 3 # Fade in icon
end
end
end
def set_quest_list_sprite(index, quest)
quest_button = @sprites["quest#{index}"]
icon_key = "quest_icon#{index}"
if @sprites[icon_key]
sprite = @sprites[icon_key]
sprite.setBitmap("Graphics/Characters/#{quest.sprite}")
sprite.x = quest_button.x - 64
sprite.y = quest_button.y - 20
sprite.src_rect.width = (sprite.bitmap.width / 4).round
sprite.src_rect.height = (sprite.bitmap.height / 4).round
sprite.src_rect.x = 0
sprite.src_rect.y = 0
sprite.visible = true
else
create_character_sprite(icon_key, quest, quest_button.x - 64, quest_button.y - 20)
end
end
def refresh_quest_list
@main.clear if @main
MAX_VISIBLE_QUESTS.times do |i|
quest_index = @quest_list_menu_index - @box + i
next if quest_index < 0 || quest_index >= @filtered_quests.size
quest = @filtered_quests[quest_index]
# Update the quest button
sprite = @sprites["quest#{i}"]
sprite.quest = quest if sprite
sprite.src_rect.y = (i == @box ? (sprite.bitmap.height / 2).round : 0) if sprite
draw_quest_name_on_main(i, quest)
set_quest_list_sprite(i, quest)
end
# Update arrow visibility
@sprites["up"].visible = @quest_list_menu_index > 0
@sprites["down"].visible = @quest_list_menu_index < @filtered_quests.size - 1
# Redraw the title
pbDrawOutlineText(@main, 0, 2, 512, 384, @current_mode.title,
Color.new(255, 255, 255), Color.new(0, 0, 0), 1)
end
##---------------------------------------------------------------------------
## Quest Detail Display
##---------------------------------------------------------------------------
def dispose_quest_list_sprites
MAX_VISIBLE_QUESTS.times do |i|
if @sprites["quest#{i}"]
@sprites["quest#{i}"].dispose
@sprites.delete("quest#{i}")
end
if @sprites["quest_icon#{i}"]
@sprites["quest_icon#{i}"].dispose
@sprites.delete("quest_icon#{i}")
end
end
end
def show_quest_detail
return if @filtered_quests.empty?
@current_mode.last_index = @quest_list_menu_index
dispose_quest_list_sprites
quest = @filtered_quests[@quest_list_menu_index]
pbWait(1)
@scene = SCENE_DETAIL
create_detail_background
fade_to_detail
create_character_sprite("char", quest, 62, 130)
draw_quest_details(quest)
animate_detail_in
end
def create_detail_background
@sprites["bg1"] = IconSprite.new(0, 0, @viewport)
@sprites["bg1"].setBitmap("Graphics/Pictures/EQI/quest_page1")
@sprites["bg1"].opacity = 0
@sprites["pager"] = IconSprite.new(0, 0, @viewport)
@sprites["pager"].setBitmap("Graphics/Pictures/EQI/quest_pager")
@sprites["pager"].x = 442
@sprites["pager"].y = 3
@sprites["pager"].z = 1
@sprites["pager"].opacity = 0
end
def fade_to_detail
8.times do
Graphics.update
@sprites["up"]&.opacity -= FADE_SPEED
@sprites["down"]&.opacity -= FADE_SPEED
@sprites["main"]&.opacity -= FADE_SPEED
@sprites["bg1"]&.opacity += FADE_SPEED if @sprites["bg1"]
@sprites["pager"]&.opacity = 0 if @sprites["pager"]
@sprites["char"]&.opacity -= FADE_SPEED if @sprites["char"]
fade_quest_list_sprites
end
@sprites["up"]&.dispose
@sprites["down"]&.dispose
end
def fade_quest_list_sprites
MAX_VISIBLE_QUESTS.times do |i|
@sprites["quest#{i}"].opacity -= FADE_SPEED if @sprites["quest#{i}"]
end
end
def create_character_sprite(spriteId,quest,x,y, max_height=nil)
@sprites[spriteId] = IconSprite.new(0, 0, @viewport)
@sprites[spriteId].setBitmap("Graphics/Characters/#{quest.sprite}")
@sprites[spriteId].x = x
@sprites[spriteId].y = y
@sprites[spriteId].src_rect.height = max_height ? max_height : (@sprites[spriteId].bitmap.height / 4).round
@sprites[spriteId].src_rect.width = (@sprites[spriteId].bitmap.width / 4).round
@sprites[spriteId].opacity = 0
end
def draw_quest_details(quest)
@main.clear if @main
@text.clear if @text
@text2.clear if @text2
pbDrawOutlineText(@main, 188, 54, 512, 384, quest.name,
Color.new(255, 172, 115), Color.new(0, 0, 0))
drawTextExMulti(@main, 188, 84, 318, 8, quest.desc,
Color.new(255, 255, 255), Color.new(0, 0, 0))
pbDrawOutlineText(@main, 188, 330, 512, 384, quest.location,
Color.new(255, 172, 115), Color.new(0, 0, 0))
draw_completion_status(quest)
end
def draw_completion_status(quest)
if quest.completed
pbDrawOutlineText(@main, 8, 315, 512, 384, _INTL("Completed"),
pbColor(:LIGHTBLUE), Color.new(0, 0, 0))
else
pbDrawOutlineText(@main, 8, 315, 512, 384, _INTL("Not Completed"),
pbColor(:LIGHTRED), Color.new(0, 0, 0))
end
end
def animate_detail_in
10.times do |i|
Graphics.update
@sprites["bg0"].opacity += FADE_SPEED
@sprites["main"].opacity += FADE_SPEED
@sprites["bg1"].opacity += FADE_SPEED if @sprites["bg1"]
@sprites["char"].opacity += FADE_SPEED if i > 1
end
end
##---------------------------------------------------------------------------
## Animations
##---------------------------------------------------------------------------
def animate_arrows
return unless @sprites["up"] && !@sprites["up"].disposed?
return unless @sprites["down"] && !@sprites["down"].disposed?
if [2, 4, 14, 16].include?(@frame)
@sprites["up"].y -= 1
@sprites["down"].y -= 1
elsif [6, 8, 10, 12].include?(@frame)
@sprites["up"].y += 1
@sprites["down"].y += 1
end
end
def animate_character
["char", "char2"].each do |char_key|
next unless @sprites[char_key]
sprite = @sprites[char_key]
sprite.src_rect.x += (sprite.bitmap.width / 4).round
sprite.src_rect.x = 0 if sprite.src_rect.x >= sprite.bitmap.width
end
end
##---------------------------------------------------------------------------
## Cleanup
##---------------------------------------------------------------------------
def cleanup
if @switch_to_map
showBlk(1) # instant black
else
ANIMATION_FRAMES.times do |i|
Graphics.update
@sprites["bg0"].opacity -= FADE_SPEED if @sprites["bg0"] && i > 3
@sprites["bg1"].opacity -= FADE_SPEED if @sprites["bg1"] && i > 3
@sprites["pager"].opacity -= FADE_SPEED if @sprites["pager"] && i > 3
@modes.size.times do |j|
@sprites["btn#{j}"].opacity -= FADE_SPEED if @sprites["btn#{j}"]
end
@sprites["main"].opacity -= FADE_SPEED if @sprites["main"]
@sprites["char"].opacity -= 40 if @sprites["char"]
@sprites["char2"].opacity -= 40 if @sprites["char2"]
end
end
pbDisposeSpriteHash(@sprites)
@viewport.dispose
pbWait(1)
end
end
@@ -53,7 +53,7 @@ def registeel_ice_press_switch(letter)
pbSet(VAR_REGI_PUZZLE_SWITCH_PRESSED, order)
if order == solution
echoln "OK"
pbSEPlay("Evolution start", nil, 130)
pbMEPlay("evolution_start", nil, 130)
elsif order.length >= solution.length
registeel_ice_reset_switches()
end
@@ -98,4 +98,4 @@ def regirock_steel_move_boulder()
pbSEPlay("Entering Door")
pbSetSelfSwitch(switch_event.id, "A", true) if switch_event
end
end
end
@@ -1,9 +1,16 @@
TEAM_ROCKET_CLOTHES = [CLOTHES_TEAM_ROCKET_MALE, CLOTHES_TEAM_ROCKET_FEMALE, CLOTHES_ROCKET_WHITE_M, CLOTHES_ROCKET_WHITE_F]
def isWearingTeamRocketOutfit()
return false if !$game_switches[SWITCH_JOINED_TEAM_ROCKET]
return (isWearingClothes(CLOTHES_TEAM_ROCKET_MALE) || isWearingClothes(CLOTHES_TEAM_ROCKET_FEMALE)) && isWearingHat(HAT_TEAM_ROCKET)
wearing_rocket_clothes = false
TEAM_ROCKET_CLOTHES.each do |clothes|
wearing_rocket_clothes = true if isWearingClothes(clothes)
end
return wearing_rocket_clothes && isWearingHat(HAT_TEAM_ROCKET)
end
def isWearingFavoriteOutfit()
favorites = {
hat: $Trainer.favorite_hat,
@@ -72,8 +79,8 @@ def finishTRQuest(id, status, silent = false)
return if pbCompletedQuest?(id)
pbMEPlay("Register phone") if status == :SUCCESS && !silent
pbMEPlay("Voltorb Flip Game Over") if status == :FAILURE && !silent
Kernel.pbMessage("\\C[2]Mission completed!") if status == :SUCCESS && !silent
Kernel.pbMessage("\\C[2]Mission Failed...") if status == :FAILURE && !silent
Kernel.pbMessage(_INTL("\\C[2]Mission completed!")) if status == :SUCCESS && !silent
Kernel.pbMessage(_INTL("\\C[2]Mission Failed...")) if status == :FAILURE && !silent
$game_variables[VAR_KARMA] -= 5 # karma
$game_variables[VAR_NB_ROCKET_MISSIONS] += 1 #nb. quests completed
@@ -377,4 +384,4 @@ def resetPinkanIsland()
$game_self_switches[[map_id, event.id, "D"]] = false
end
end
end
end
@@ -1,91 +0,0 @@
def obtainBadgeMessage(badgeName)
Kernel.pbMessage(_INTL("\\me[Badge get]{1} obtained the {2}!", $Trainer.name, badgeName))
end
def promptCaughtPokemonAction(pokemon)
pickedOption = false
return pbStorePokemon(pokemon) if !$Trainer.party_full?
return promptKeepOrRelease(pokemon) if isOnPinkanIsland() && !$game_switches[SWITCH_PINKAN_FINISHED]
while !pickedOption
command = pbMessage(_INTL("\\ts[]Your team is full!"),
[_INTL("Add to your party"), _INTL("Store to PC"),], 2)
echoln ("command " + command.to_s)
case command
when 0 # SWAP
if swapCaughtPokemon(pokemon)
echoln pickedOption
pickedOption = true
end
else
# STORE
pbStorePokemon(pokemon)
echoln pickedOption
pickedOption = true
end
end
end
def promptKeepOrRelease(pokemon)
pickedOption = false
while !pickedOption
command = pbMessage(_INTL("\\ts[]Your team is full!"),
[_INTL("Release a party member"), _INTL("Release this #{pokemon.name}"),], 2)
echoln ("command " + command.to_s)
case command
when 0 # SWAP
if swapReleaseCaughtPokemon(pokemon)
pickedOption = true
end
else
pickedOption = true
end
end
end
# def pbChoosePokemon(variableNumber, nameVarNumber, ableProc = nil, allowIneligible = false)
def swapCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isShadow? rescue false)
})
index = pbGet(1)
return false if index == -1
$PokemonStorage.pbStoreCaught($Trainer.party[index])
pbRemovePokemonAt(index)
pbStorePokemon(caughtPokemon)
tmp = $Trainer.party[index]
$Trainer.party[index] = $Trainer.party[-1]
$Trainer.party[-1] = tmp
return true
end
def swapReleaseCaughtPokemon(caughtPokemon)
pbChoosePokemon(1, 2,
proc { |poke|
!poke.egg? &&
!(poke.isShadow? rescue false)
})
index = pbGet(1)
return false if index == -1
releasedPokemon = $Trainer.party[index]
pbMessage(_INTL("{1} was released.",releasedPokemon.name))
pbRemovePokemonAt(index)
pbStorePokemon(caughtPokemon)
tmp = $Trainer.party[index]
$Trainer.party[index] = $Trainer.party[-1]
$Trainer.party[-1] = tmp
return true
end
def select_any_pokemon()
commands = []
for dex_num in 1..NB_POKEMON
species = getPokemon(dex_num)
commands.push([dex_num - 1, species.real_name, species.id])
end
return pbChooseList(commands, 0, nil, 1)
end
@@ -1,159 +0,0 @@
def splitSpriteCredits(name, bitmap, max_width)
name_full_width = bitmap.text_size(name).width
# use original name if can fit on one line
return [ name ] if name_full_width <= max_width
temp_string = name
name_split = []
# split name by collab separator " & " nearest to max width
start_pos = temp_string.index(' & ')
temp_pos = nil
while start_pos && (bitmap.text_size(temp_string).width > max_width)
substring_width = bitmap.text_size(temp_string[0, start_pos]).width
if substring_width > max_width
name_split << temp_string[0, temp_pos].strip
temp_string = temp_string[(temp_pos + 1)..].strip
start_pos = temp_string.index(' & ')
temp_pos = nil
next
end
temp_pos = start_pos
start_pos = temp_string.index(' & ', start_pos + 1)
end
# append remainder of " & " split if within max width
if temp_pos != nil
name_split << temp_string[0, temp_pos].strip
temp_string = temp_string[(temp_pos + 1)..].strip
end
# split remaining string by space
temp_pos = nil
if (bitmap.text_size(temp_string).width > max_width) && (start_pos = temp_string.index(' '))
while start_pos && (bitmap.text_size(temp_string).width > max_width)
substring_width = bitmap.text_size(temp_string[0, start_pos]).width
if substring_width > max_width
name_split << temp_string[0, temp_pos].strip
temp_string = temp_string[(temp_pos + 1)..].strip
start_pos = temp_string.index(' ')
temp_pos = nil
next
end
temp_pos = start_pos
start_pos = temp_string.index(' ', start_pos + 1)
end
end
# append remaining text, even if too long for screen
name_split << temp_string if temp_string != ''
return name_split
end
def pbLoadPokemonBitmapSpecies(pokemon, species, back = false, scale = POKEMONSPRITESCALE)
ret = nil
pokemon = pokemon.pokemon if pokemon.respond_to?(:pokemon)
if pokemon.isEgg?
bitmapFileName = getEggBitmapPath(pokemon)
bitmapFileName = pbResolveBitmap(bitmapFileName)
elsif pokemon.species >= ZAPMOLCUNO_NB #zapmolcuno
bitmapFileName = getSpecialSpriteName(pokemon.species) #sprintf("Graphics/Battlers/special/144.145.146")
bitmapFileName = pbResolveBitmap(bitmapFileName)
else
#edited here
isFusion = species > NB_POKEMON
if isFusion
poke1 = getBodyID(species)
poke2 = getHeadID(species, poke1)
else
poke1 = species
poke2 = species
end
bitmapFileName = GetSpritePath(poke1, poke2, isFusion)
# Alter bitmap if supported
alterBitmap = (MultipleForms.getFunction(species, "alterBitmap") rescue nil)
end
if bitmapFileName && alterBitmap
animatedBitmap = AnimatedBitmap.new(bitmapFileName)
copiedBitmap = animatedBitmap.copy
animatedBitmap.dispose
copiedBitmap.each { |bitmap| alterBitmap.call(pokemon, bitmap) }
ret = copiedBitmap
elsif bitmapFileName
ret = AnimatedBitmap.new(bitmapFileName)
end
return ret
end
def pbPokemonBitmapFile(species)
# Used by the Pokédex
# Load normal bitmap
#get body and head num
isFused = species > NB_POKEMON
if isFused
if species >= ZAPMOLCUNO_NB
path = getSpecialSpriteName(species) + ".png"
else
poke1 = getBodyID(species) #getBasePokemonID(species,true)
poke2 = getHeadID(species, poke1) #getBasePokemonID(species,false)
path = GetSpritePath(poke1, poke2, isFused)
end
else
path = GetSpritePath(species, species, false)
end
ret = sprintf(path) rescue nil
if !pbResolveBitmap(ret)
ret = "Graphics/Battlers/000.png"
end
return ret
end
def pbLoadPokemonBitmap(pokemon, species, back = false)
#species est utilisé par elitebattle mais ca sert a rien
return pbLoadPokemonBitmapSpecies(pokemon, pokemon.species, back)
end
def getEggBitmapPath(pokemon)
return "Graphics/Battlers/Eggs/000" if $PokemonSystem.hide_custom_eggs
bitmapFileName = sprintf("Graphics/Battlers/Eggs/%s", getConstantName(PBSpecies, pokemon.species)) rescue nil
if !pbResolveBitmap(bitmapFileName)
if pokemon.species >= NUM_ZAPMOLCUNO
bitmapFileName = "Graphics/Battlers/Eggs/egg_base"
else
bitmapFileName = sprintf("Graphics/Battlers/Eggs/%03d", pokemon.species)
if !pbResolveBitmap(bitmapFileName)
bitmapFileName = sprintf("Graphics/Battlers/Eggs/000")
end
end
end
return bitmapFileName
end
def GetSpritePath(poke1, poke2, isFused)
#Check if custom exists
spritename = GetSpriteName(poke1, poke2, isFused)
pathCustom = sprintf("Graphics/%s/indexed/%s/%s.png", DOSSIERCUSTOMSPRITES,poke2, spritename)
pathReg = sprintf("Graphics/%s/%s/%s.png", BATTLERSPATH, poke2, spritename)
path = pbResolveBitmap(pathCustom) && $game_variables[196] == 0 ? pathCustom : pathReg
return path
end
def GetSpritePathForced(poke1, poke2, isFused)
#Check if custom exists
spritename = GetSpriteName(poke1, poke2, isFused)
pathCustom = sprintf("Graphics/%s/indexed/%s/%s.png", DOSSIERCUSTOMSPRITES, poke2, spritename)
pathReg = sprintf("Graphics/%s/%s/%s.png", BATTLERSPATH, poke2, spritename)
path = pbResolveBitmap(pathCustom) ? pathCustom : pathReg
return path
end
def GetSpriteName(poke1, poke2, isFused)
ret = isFused ? sprintf("%d.%d", poke2, poke1) : sprintf("%d", poke2) rescue nil
return ret
end
File diff suppressed because it is too large Load Diff
@@ -105,17 +105,8 @@ def pbWonderTrade(lvl, except = [], except2 = [], premiumWonderTrade = true)
# raise "{1}'s bst ist {2}, new ist {3}",myPoke,chosenBST,bst
# species=0 if (except.include?(species) && except2.include?(species))
# use this above line instead if you wish to neither receive pokemon that YOU
# cannot trade.
if rare == true #turn on rareness
if species > 0
rareness = GameData::Species.get(species).catch_rate
species = 0 if rarecap >= rareness
end
end
end
randTrainerNames = RandTrainerNames_male + RandTrainerNames_female + RandTrainerNames_others
randTrainerNames = RandTrainerNames_male + RandTrainerNames_female + RandTrainerNames_others + RandTrainerNames_unisex
#tname = randTrainerNames[rand(randTrainerNames.size)] # Randomizes Trainer Names
pname = RandPokeNick[rand(RandPokeNick.size)] # Randomizes Pokemon Nicknames