Update 6.8

This commit is contained in:
chardub
2026-07-10 15:42:06 -04:00
parent 5b85e72cb2
commit 6a6f126a18
7871 changed files with 493194 additions and 224826 deletions
@@ -0,0 +1,520 @@
# todo:
# When all pokemon in the route are seen, can "scan" for species
# - spawns a pokemon of that species nearby with notice behavior to flee
class PokeRadarAppScene < PokeNavAppScene
INFO_TEXT_Y = 270
def header_name
return _INTL("PokéRadar")
end
def cursor_path
return "Graphics/Pictures/Pokeradar/icon_button"
end
def header_path
return "Graphics/Pictures/Pokeradar/bg_header"
end
def display_mode
return :GRID
end
def x_gap
return 75;
end
def y_gap
return 50;
end
def columns
return 6
end
def visible_rows
return 3
end
def start_x
return 40;
end
def start_y
return 80;
end
def pbStartScene(main_menu_scene)
@unseenPokemon = [] unless @unseenPokemon
@seenPokemon = [] unless @seenPokemon
@pokenav_main_menu_scene = main_menu_scene
if $PokemonTemp.pokeradar
buttons = showCurrentScanningTarget
super(buttons)
else
buttons = showWildPokemonList
super(buttons)
showSelectedPokemonInfo
end
showHeaderInfo
end
def showSelectedPokemonInfo
hover(@buttons[@index]&.id)
if @unseenPokemon.empty? && @seenPokemon.empty?
showEmpty
end
end
def showHeaderInfo
showBattery
showHeaderName
showAreaName
showWeatherIcon
end
def showWildPokemonList
@encounter_type = $PokemonEncounters.encounter_type
@weatherEncounters = $PokemonEncounters.list_weather_encounters_species(@encounter_type)
@unseenPokemon = listPokemonInCurrentRoute(@encounter_type, false, true, true)
@seenPokemon = listPokemonInCurrentRoute(@encounter_type, true, false, true)
buttons = []
@seenPokemon.each do |pokemon_species|
icon_path = pbCheckPokemonIconFiles(pokemon_species)
bmp = load_bitmap(icon_path, false)
button = PokenavButton.new(pokemon_species, bmp)
button.crop_width = button.icon_bitmap.bitmap.width / 2
button.refresh
buttons << button if button
end
@unseenPokemon.each do |pokemon_species|
icon_path = pbCheckPokemonIconFiles(pokemon_species)
bmp = load_bitmap(icon_path, true)
button = PokenavButton.new(pokemon_species, bmp)
button.crop_width = button.icon_bitmap.bitmap.width / 2
button.refresh
buttons << button
end
return buttons
end
def createCursor
return if $PokemonTemp.pokeradar
super
end
def showEmpty
Kernel.pbDisplayText(_INTL("No wild Pokémon found nearby."), Graphics.width / 2, Graphics.height / 2, nil, @text_color_base, @text_color_shadow)
Kernel.pbDisplayText(_INTL("Stand in tall grass to start scanning."), Graphics.width / 2,( Graphics.height / 2)+32, nil, @text_color_base, @text_color_shadow)
end
def showCurrentScanningTarget
scanningPokemon = $PokemonTemp.pokeradar[0]
icon_path = pbCheckPokemonIconFiles(scanningPokemon)
bmp = load_bitmap(icon_path, false)
button = PokenavButton.new(scanningPokemon, bmp)
button.refresh
species_name = GameData::Species.get(scanningPokemon).name
Kernel.pbDisplayText(_INTL("Currently scanning for {1}.", species_name), Graphics.width / 2, 200, 500000, @text_color_base, @text_color_shadow)
Kernel.pbDisplayText(_INTL("Current chain: {1}.", $PokemonTemp.pokeradar[2]), Graphics.width / 2, 230, 500000, @text_color_base, @text_color_shadow)
return [button]
end
def load_bitmap(path, dark = false)
return nil unless path && path != ""
bmp = Bitmap.new(path)
if dark
darken_bitmap(bmp, 220) # strength 0255
end
return AnimatedBitmap.from_bitmap(bmp)
end
def darken_bitmap(bmp, amount)
for x in 0...bmp.width
for y in 0...bmp.height
pixel = bmp.get_pixel(x, y)
next if pixel.alpha == 0
factor = (255 - amount) / 255.0
r = (pixel.red * factor).to_i
g = (pixel.green * factor).to_i
b = (pixel.blue * factor).to_i
bmp.set_pixel(x, y, Color.new(r, g, b, pixel.alpha))
end
end
end
#[rareness, species, minLevel, maxLevel]
def get_encounter(species,include_weather=true)
for encounter in $PokemonEncounters.listPossibleEncounters(@encounter_type, include_weather)
if encounter[1] == species
return encounter
end
end
return nil
end
def get_weather_encounter(species)
for encounter in $PokemonEncounters.list_weather_encounters(@encounter_type)
if encounter[1] == species
return encounter
end
end
return nil
end
def get_energy_for_scan(species)
encounter = get_encounter(species)
if @weatherEncounters.include?(species)
base_rareness = encounter[0]
rareness =calculate_weather_encounter_rareness(encounter,base_rareness)
else
rareness = encounter[0]
end
energy = (110 - rareness) * 5
(energy / 50.0).round * 50
end
def get_rarity_flavor_text(species)
encounter = get_encounter(species,false)
weather_encounter = get_weather_encounter(species)
return unless encounter || weather_encounter
if (encounter && encounter[1] == species) || (weather_encounter && weather_encounter[1] == species)
base_rareness =0
base_rareness = encounter[0] if encounter
base_rareness = weather_encounter[0] if weather_encounter
if @weatherEncounters.include?(species)
rareness = calculate_weather_encounter_rareness(weather_encounter,base_rareness)
else
rareness = base_rareness
end
if rareness < 5
text = _INTL("Very rare")
elsif rareness < 10
text = _INTL("Rare")
elsif rareness < 25
text = _INTL("Uncommon")
elsif rareness < 40
text = _INTL("Common")
else
text = _INTL("Very Common")
end
return text
end
end
def calculate_weather_encounter_rareness(encounter,base_rareness)
map_weather = $game_weather.current_weather[$game_map.map_id]
if map_weather
weather_intensity = map_weather[1]
weather_intensity = 0 if !weather_intensity
chance_of_weather_encounter = $PokemonEncounters.weather_encounter_chance(weather_intensity)
weather_rareness = encounter[0]
return weather_rareness * (chance_of_weather_encounter.to_f / 100) * (base_rareness/100)
end
return 0
end
def click(button_id)
species = button_id
if $PokemonTemp.pokeradar
click_stop_scan(species)
else
if @seenPokemon.include?(species)
click_seen(species)
else
click_unseen
end
end
super
end
def hover(button_id)
return if $PokemonTemp.pokeradar
if @seenPokemon.include?(button_id)
hover_seen(button_id)
else
hover_unseen
end
super
end
def click_stop_scan(species)
species_name = GameData::Species.get(species).name
options = []
cmd_stop_scan = _INTL("Stop Scanning")
cmd_cancel = _INTL("Cancel")
options << cmd_stop_scan
options << cmd_cancel
Kernel.pbClearText()
showHeaderInfo
chosen = pbMessage(_INTL("You are currently scanning for {1}.", species_name), options, options.length)
case options[chosen]
when cmd_stop_scan
$PokemonTemp.pokeradar = nil
pbEndScene
pbStartScene(@pokenav_main_menu_scene)
else
showCurrentScanningTarget
return
end
end
def click_seen(species)
options = []
cmd_scan = _INTL("Scan")
cmd_cancel = _INTL("Cancel")
options << cmd_scan
options << cmd_cancel
Kernel.pbClearText()
showHeaderInfo
chosen = pbMessage(_INTL("What would you like to do?"), options, options.length)
case options[chosen]
when cmd_scan
energy_needed = get_energy_for_scan(species)
if Settings::POKERADAR_BATTERY_STEPS - $PokemonGlobal.pokeradarBattery >= energy_needed
$PokemonGlobal.pokeradarBattery += energy_needed
displayTextElements
@exiting = true
pbEndScene
@pokenav_main_menu_scene.exiting = true
@pokenav_main_menu_scene.pbEndScene
encounter = get_encounter(species)
min_level = encounter[2]
max_level = encounter[3]
level = rand(min_level..max_level)
pbWait(16)
pbMessage(_INTL("Scanning for {1}...\\wtnp[5]", GameData::Species.get(species).name))
possible_tiles = getTerrainTilesNearPlayer(getTerrainType, 3)
position = possible_tiles.sample
if position
set_pokeradar_data(species, level, position)
spawn_pokeradar_pokemon(species, level)
else
pbPokeRadarCancel
pbMessage(_INTL("The Pokéradar scan failed... Try again somewhere else"))
end
else
pbPokeRadarCancel
Kernel.pbClearText()
showHeaderInfo
pbMessage(_INTL("The battery is not charged enough for this scan!"))
showSelectedPokemonInfo
end
else
showSelectedPokemonInfo
return
end
end
def click_unseen
return unless @unseenPokemon.any?
Kernel.pbClearText()
showHeaderInfo
pbMessage(_INTL("You need to encounter the Pokémon before you can scan for it."))
hover_unseen
end
def hover_seen(species)
displayTextElements
pokemon_name = GameData::Species.get(species).name
Kernel.pbDisplayText(pokemon_name, Graphics.width / 2, INFO_TEXT_Y, 99999, @text_color_base, @text_color_shadow)
Kernel.pbDisplayText(get_rarity_flavor_text(species), Graphics.width / 2, INFO_TEXT_Y + 30, 99999, @text_color_base, @text_color_shadow)
Kernel.pbDisplayText(_INTL("Battery for scan: {1}", get_energy_for_scan(species)), Graphics.width / 2, INFO_TEXT_Y + 60, 99999, @text_color_base, @text_color_shadow)
end
def hover_unseen()
return unless @unseenPokemon.any?
displayTextElements
pokemon_name = _INTL("Unknown Pokémon")
Kernel.pbDisplayText(pokemon_name, Graphics.width / 2, INFO_TEXT_Y, 999999, @text_color_base, @text_color_shadow)
end
def displayTextElements
super
showBattery
showAreaName
end
def showBattery
$PokemonGlobal.pokeradarBattery = Settings::POKERADAR_BATTERY_STEPS unless $PokemonGlobal.pokeradarBattery
battery_power = Settings::POKERADAR_BATTERY_STEPS - $PokemonGlobal.pokeradarBattery
Kernel.pbDisplayText(_INTL("{1}/1000", battery_power), 450, HEADER_HEIGHT,nil, @text_color_base, @text_color_shadow)
end
def showAreaName
map_name = getMapName($game_map.map_id)
text = _INTL("{1}", map_name)
encounter_type = get_encounter_type_name
if encounter_type && !encounter_type.empty?
text += _INTL(" ({1})", encounter_type)
end
Kernel.pbDisplayText(text, Graphics.width / 2, 40,nil, @text_color_base, @text_color_shadow)
end
def showWeatherIcon
icon_path = get_current_weather_icon
return unless icon_path
@sprites["weather"] = IconSprite.new(400, 48, @viewport)
@sprites["weather"].setBitmap(icon_path)
@sprites["weather"].z = 100000
end
def get_encounter_type_name
encounter_type = $PokemonEncounters.encounter_type
case encounter_type
when :Land
return _INTL("Grass")
when :Land1
return _INTL("Clovers")
when :Land2
return _INTL("Dry Grass")
when :Land3
return _INTL("Flowers")
when :LandMorning, :LandDay, :LandNight
return _INTL("Grass")
when :WaterMorning, :WaterDay, :WaterNight
return _INTL("Water")
when :TallGrass
return _INTL("Tall Grass")
else
return encounter_type.to_s
end
end
end
def getTerrainType
encounter_type = $PokemonEncounters.encounter_type
case encounter_type
when :Land, :Land1, :Land2, :Land3, :LandMorning, :LandDay, :LandNight, :TallGrass
return :Grass
else
return encounter_type
end
end
def continue_pokeradar_app_chain()
pbWait(12)
species = $PokemonTemp.pokeradar[0]
level = $PokemonTemp.pokeradar[1]
possible_tiles = getTerrainTilesNearPlayer(getTerrainType, 3)
position = possible_tiles.sample
if position
set_pokeradar_data(species, level, position)
spawn_pokeradar_pokemon(species, level)
else
pbPokeRadarCancel
pbMessage(_INTL("The Pokéradar scan failed... Try again somewhere else"))
end
end
def update_pokeradar_overworld_ui
if $PokemonTemp.pokeradar
current_chain = $PokemonTemp.pokeradar[2]
return unless current_chain >= 1
species = $PokemonTemp.pokeradar[0]
$PokemonTemp.pokeradar_ui.dispose if $PokemonTemp.pokeradar_ui
$PokemonTemp.pokeradar_ui = PokeRadar_UI.new([species], [], [])
if current_chain >= 40
$PokemonTemp.pokeradar_ui.set_text(_INTL("PokéRadar Chain: {1}", current_chain), 72, 12, pbColor(:GREEN), pbColor(:DARKGREEN))
else
$PokemonTemp.pokeradar_ui.set_text(_INTL("PokéRadar Chain: {1}", current_chain), 72, 12)
end
else
$PokemonTemp.pokeradar_ui.dispose if $PokemonTemp.pokeradar_ui
end
end
def spawn_pokeradar_pokemon(species, level)
max_attempts = 50
return unless species && level
pbWait(20)
playAnimation(Settings::POKERADAR_LIGHT_ANIMATION_RED_ID, $game_player.x, $game_player.y)
pbWait(10)
spawned_events = nil
radius = 4
max_radius = 8
max_attempts.times do |current_attempt|
radius += 1 if current_attempt > 0 && current_attempt % 10 == 0
radius += (current_attempt / 10).floor
radius = [radius, max_radius].min
spawned_events = spawn_ow_pokemon(species, level, 1, radius)
break if spawned_events&.length.to_i > 0
end
if spawned_events&.length.to_i > 0
event = spawned_events[0]
grass = $PokemonTemp&.pokeradar[3]
if grass && grass[3] == 2
pbSEPlay("shiny", 60)
playAnimation(Settings::SPARKLE_SHORT_ANIMATION_ID, event.x, event.y)
event.make_shiny
end
#todo: MAYBE increase the move frequency past a certain chain number (50?) to make it more difficult
event.behavior_roaming = :look_around_player
event.behavior_noticed = event.pokemon.shiny? ? :curious : :flee
event.update_movement_type
event.turn_away_from_player
playAnimation(Settings::POKERADAR_LIGHT_ANIMATION_RED_ID, event.x, event.y)
else
echoln "failed to spawn after #{max_attempts} attempts"
pbPokeRadarCancel
pbMessage(_INTL("The Pokéradar scan failed... Try again somewhere else"))
end
update_pokeradar_overworld_ui
end
# Reusing the old pokeradar mechanics for chaining
def set_pokeradar_data(species, level, position)
x = position[0]
y = position[1]
existing_chain = ($PokemonTemp.pokeradar && $PokemonTemp.pokeradar[2]) ? $PokemonTemp.pokeradar[2] : 0
$PokemonTemp.pokeradar = [0, 0, 0, []] unless $PokemonTemp.pokeradar
$PokemonTemp.pokeradar[0] = species
$PokemonTemp.pokeradar[1] = level
$PokemonTemp.pokeradar[2] = existing_chain
$PokemonTemp.pokeradar[3] = [x, y, 0, determine_shininess]
end
def determine_shininess
chain_length = ($PokemonTemp.pokeradar && $PokemonTemp.pokeradar[2]) ? $PokemonTemp.pokeradar[2] : 0
rarity = (rand(100) < 25) ? 1 : 0
if chain_length > 0
capped_chain = [chain_length, 40].min
shiny_threshold = [(65536 / Settings::SHINY_POKEMON_CHANCE) - capped_chain * 200, 200].max
shiny_divisor = 0xFFFF / shiny_threshold
shiny_roll = rand(65536) / shiny_divisor
rarity = 2 if shiny_roll == 0
end
return rarity
end
Events.onMapChange += proc { |_sender, e|
pbPokeRadarCancel
}
@@ -0,0 +1,17 @@
#===============================================================================
#
#===============================================================================
class PokeRadarAppScreen
def initialize(scene)
@scene = scene
end
def pbStartScreen(main_menu_scene)
@scene.pbStartScene(main_menu_scene)
@scene.pbScene
@scene.pbEndScene
end
end