Release 6.9.0

This commit is contained in:
chardub
2026-11-02 11:34:46 -05:00
parent 060726298d
commit ae6e2ebc64
5697 changed files with 131795 additions and 17423 deletions
@@ -163,87 +163,117 @@ class PokeblockCase_Screen
@pokeblocks = $Trainer.pokeblocks
end
def pbStartScreen
def pbStartScreen(is_feeding_pokemon)
@scene.pbStartScene
item = nil
loop do
item = @scene.pbChooseItem
break if !item
cmdUse = -1
cmdToss = -1
cmdDebug = -1
cmdUse = _INTL("Feed")
cmdPlace = _INTL("Place down")
cmdToss = _INTL("Toss")
cmdDebug = _INTL("Debug")
cmdCancel = _INTL("Cancel")
commands = []
# Generate command list
commands[cmdUse = commands.length] = _INTL("Use")
commands[cmdToss = commands.length] = _INTL("Toss")
commands[cmdDebug = commands.length] = _INTL("Debug") if $DEBUG
commands[commands.length] = _INTL("Cancel")
commands.push(cmdUse)
commands.push(cmdPlace) if is_outdoor_map?
commands.push(cmdToss)
commands.push(cmdDebug) if $DEBUG
commands.push(cmdCancel)
# Show commands generated above
itemname = item.name
command = @scene.pbShowCommands(_INTL("{1} is selected.", itemname), commands)
if cmdUse >= 0 && command == cmdUse # Use item
ret = pbFeedPokeblock(item, @scene)
# ret: 0=Item wasn't used; 1=Item used; 2=Close Bag to use in field
break if ret == 2 # End screen
@scene.pbRefresh
case commands[command]
when cmdUse
if is_feeding_pokemon
ret = pbFeedPokeblock(item, @scene)
break if ret == 2 # End screen
@scene.pbRefresh
else
@scene.pbEndScene
return(item)
end
next
elsif cmdToss >= 0 && command == cmdToss # Toss item
# qty = @bag.quantity(item)
# if qty > 1
# helptext = _INTL("Toss out how many {1}?", itm.name_plural)
# qty = @scene.pbChooseNumber(helptext, qty)
# end
# if qty > 0
# itemname = itm.name_plural if qty > 1
# if pbConfirm(_INTL("Is it OK to throw away {1} {2}?", qty, itemname))
# pbDisplay(_INTL("Threw away {1} {2}.", qty, itemname))
# qty.times { @bag.remove(item) }
# @scene.pbRefresh
# end
# end
when cmdPlace
color = item.color#:RED
position = pbFacingTile($game_player.direction)
x_pos, y_pos = position[1],position[2]
if tile_passable_or_water(x_pos, y_pos)
if !tile_is_water?($game_player.x, $game_player.y) && tile_is_water?(x_pos, y_pos)
dx = x_pos - $game_player.x
dy = y_pos - $game_player.y
far_x, far_y = x_pos + dx, y_pos + dy
if tile_is_water?(far_x, far_y) && tile_passable_or_water(far_x, far_y)
x_pos, y_pos = far_x, far_y
end
end
else
x_pos, y_pos = $game_player.x, $game_player.y
end
event = $PokemonTemp.createTempEvent(TEMPLATE_EVENT_POKEBLOCK,
$game_map.map_id,
[x_pos, y_pos],
$game_player.direction,
PokeblockEvent, [item])
if event.is_on_water
event.floating = true
event.forced_bush_depth = 8
event.calculate_bush_depth
end
pbRemovePokeblock(item)
@scene.pbEndScene
break
when cmdToss
if pbConfirm(_INTL("Is it OK to throw away the {1}?", itemname))
pbDisplay(_INTL("Threw away the {1}.", itemname))
#@pokeblocks.remove(item)
pbRemovePokeblock(item)
@scene.pbRefresh
end
elsif cmdDebug >= 0 && command == cmdDebug # Debug
when cmdDebug
command = 0
loop do
command = @scene.pbShowCommands(_INTL("Do what with {1}?", itemname),
[_INTL("Change flavor"),_INTL("Change feel"),
_INTL("Cancel")], command)
case command
### Cancel ###
when -1, 2
break
### Change flavor ###
when 0
flavor = item.flavor
fNames = ["Spicy", "Dry", "Sweet", "Bitter", "Sour"]
flavor.each_with_index { |f,i|
command = @scene.pbShowCommands(_INTL("Do what with {1}?", itemname),
[_INTL("Change flavor"),_INTL("Change feel"),
_INTL("Cancel")], command)
case command
### Cancel ###
when -1, 2
break
### Change flavor ###
when 0
flavor = item.flavor
fNames = ["Spicy", "Dry", "Sweet", "Bitter", "Sour"]
flavor.each_with_index { |f,i|
params = ChooseNumberParams.new
params.setRange(0, 99)
params.setDefaultValue(f)
value = pbMessageChooseNumber(
_INTL("Choose new {1} value (max. 99).", fNames[i]), params
) { @scene.pbUpdate }
item.flavor[i] = value
}
item.level = item.flavor.max
@scene.pbRefresh
### Change feel ###
when 1
feel = item.smoothness
params = ChooseNumberParams.new
params.setRange(0, 99)
params.setDefaultValue(f)
value = pbMessageChooseNumber(
_INTL("Choose new {1} value (max. 99).", fNames[i]), params
params.setRange(0, 255)
params.setDefaultValue(feel)
item.smoothness = pbMessageChooseNumber(
_INTL("Choose new Feel value (max. 255)."), params
) { @scene.pbUpdate }
item.flavor[i] = value
}
item.level = item.flavor.max
@scene.pbRefresh
### Change feel ###
when 1
feel = item.smoothness
params = ChooseNumberParams.new
params.setRange(0, 255)
params.setDefaultValue(feel)
item.smoothness = pbMessageChooseNumber(
_INTL("Choose new Feel value (max. 255)."), params
) { @scene.pbUpdate }
@scene.pbRefresh
end
@scene.pbRefresh
end
end
end
end
@@ -89,7 +89,7 @@ def pbFeedPokeblock(pokeblock,oldScene=nil)
return ret
end
def pbPokeblockCase
def pbPokeblockCase(feeding_pokemon=true)
if !$Trainer.hasPokeblocks?
pbMessage(_INTL("You don't have any Pokéblocks!"))
return false
@@ -97,7 +97,7 @@ def pbPokeblockCase
pbFadeOutIn {
scene = PokeblockCase_Scene.new
screen = PokeblockCase_Screen.new(scene)
ret = screen.pbStartScreen
ret = screen.pbStartScreen(feeding_pokemon)
}
end
@@ -221,7 +221,7 @@ class PokemonContest
bonus += 80
elsif hat_match
pbCallBub(1, @crowdNPCs.sample.id)
pbMessage(_INTL("It matches its Trainer's!"))
pbMessage(_INTL("It matches its Trainer's hat!"))
bonus += 40
elsif clothes_match
pbCallBub(1, @crowdNPCs.sample.id)
@@ -253,7 +253,7 @@ class PokemonContest
if val >= req[0]
events = @crowdNPCs.sample(s)
events.each { |event|
$scene.spriteset(map).addUserAnimation(ContestSettings::HEART_ANIMATION_ID, event.x, event.y, false, 2)
$scene.spriteset.addUserAnimation(ContestSettings::HEART_ANIMATION_ID, event.x, event.y, false, 2)
pbWait(rand(6)+4)
}
hearts = 8
@@ -62,6 +62,17 @@ def pbMessageDisplayContest(msgwindow,message,letterbyletter=true,commandProc=ni
text.gsub!(/\\b/i,"<c3=3050C8,D0D0C8>")
text.gsub!(/\\r/i,"<c3=E00808,D0D0C8>")
text.gsub!(/\\[Ww]\[([^\]]*)\]/) {
text.gsub!("<-","←")
text.gsub!("->","→")
text.gsub!("<arr_left>","←")
text.gsub!("<arr_right>","→")
text.gsub!("<arr_down>","↓")
text.gsub!("<arr_up>","↑")
text.gsub!("<arr_down>","↓")
w = $1.to_s
if w==""
msgwindow.windowskin = nil
@@ -21,7 +21,7 @@ class PokemonEncounters
return pokemonEssentials_PokemonEncounter_choose_wild_pokemon(enc_type, *args)
end
SUBSTITUTABLE_ENCOUNTER_TYPES = [:LandDay, :LandNight, :LandMorning, :Land, :Land1, :Land2, :Land3, :TallGrass, :Water]
SUBSTITUTABLE_ENCOUNTER_TYPES = [:LandDay, :LandNight, :LandMorning, :Land, :Land1, :Land2, :Land3, :Land4, :TallGrass, :TallGrassNight, :Water]
def can_substitute_for_weather_encounter(encounter_type, current_weather)
return false if Settings::GAME_ID != :IF_HOENN
@@ -77,6 +77,12 @@ GameData::EncounterType.register({
:old_slots => [30,30,10,15,5,10],
})
GameData::EncounterType.register({
:id => :TallGrassNight,
:type => :land,
:old_slots => [30,30,10,15,5,10],
})
@@ -88,8 +88,10 @@ def generate_neighbor_map_from_connections
return neighbor_map
end
def is_indoor_map?(map_id)
return false
def is_outdoor_map?(map_id = $game_map.map_id)
return !is_indoor_map?(map_id)
end
def is_indoor_map?(map_id = $game_map.map_id)
mapMetadata = GameData::MapMetadata.try_get(map_id)
return true if !mapMetadata
return !mapMetadata.outdoor_map
@@ -24,7 +24,9 @@ def clear_current_map_weather
$game_screen.weather(:None,0,0)
end
def update_overworld_weather(current_map)
return unless $game_weather
return if current_map.nil?
return if !$game_weather.current_weather
@@ -35,6 +37,28 @@ def update_overworld_weather(current_map)
current_weather_type = :None if !current_weather_type
current_weather_intensity=0 if !current_weather_intensity
current_weather_type = :None if PBDayNight.isNight? && current_weather_type == :Sunny
set_weather_ambient_sounds(current_weather_type,current_weather_intensity)
$game_screen.weather(current_weather_type,current_weather_intensity,0)
end
end
def restore_weather_ambient_sounds()
return unless $game_weather
current_map = $game_map.map_id
return if !$game_weather.current_weather
current_weather_array = $game_weather.current_weather[current_map]
return if current_weather_array.nil?
current_weather_type = current_weather_array[0]
current_weather_intensity = current_weather_array[1]
set_weather_ambient_sounds(current_weather_type,current_weather_intensity)
end
def set_weather_ambient_sounds(weather_type,intensity)
base_volume = 60 #At intensity 1
volume = [base_volume + base_volume * (intensity/2),10].min #Intensity at 10: volume 100
case weather_type
when :Rain, :Storm
pbBGSPlay("ambient/rain",volume)
when :Wind, :Blizzard, :StrongWind, :Storm
pbBGSPlay("ambient/wind",volume)
end
end
@@ -1,46 +1,51 @@
# frozen_string_literal: true
def isRaining?()
return isWeatherRain? || isWeatherStorm?
def isRaining?(map_id=$game_map.map_id)
return isWeatherRain?(map_id) || isWeatherStorm?(map_id)
end
def isWeatherRain?()
def isWeatherRain?(map_id=$game_map.map_id)
return true if GameData::Weather.get($game_screen.weather_type).category == :Rain
return $game_weather.get_map_weather_type($game_map.map_id) == :Rain || $game_weather.get_map_weather_type($game_map.map_id) == :HeavyRain
return $game_weather.get_map_weather_type(map_id) == :Rain || $game_weather.get_map_weather_type($game_map.map_id) == :HeavyRain
end
def isWeatherSunny?()
def isWeatherSunny?(map_id=$game_map.map_id)
return true if GameData::Weather.get($game_screen.weather_type).category == :Sunny
return $game_weather.get_map_weather_type($game_map.map_id) == :Sunny || $game_weather.get_map_weather_type($game_map.map_id) == :HarshSun
return $game_weather.get_map_weather_type(map_id) == :Sunny || $game_weather.get_map_weather_type(map_id) == :HarshSun
end
def isWeatherStorm?()
def isWeatherStorm?(map_id=$game_map.map_id)
return true if GameData::Weather.get($game_screen.weather_type).category == :Storm
return $game_weather.get_map_weather_type($game_map.map_id) == :Storm
return $game_weather.get_map_weather_type(map_id) == :Storm
end
def isWeatherWind?()
def isWeatherWind?(map_id=$game_map.map_id)
return true if GameData::Weather.get($game_screen.weather_type).category == :Wind
return $game_weather.get_map_weather_type($game_map.map_id) == :Wind || $game_weather.get_map_weather_type($game_map.map_id) == :StrongWinds
return $game_weather.get_map_weather_type(map_id) == :Wind || $game_weather.get_map_weather_type(map_id) == :StrongWinds
end
def isWeatherFog?()
def isWeatherFog?(map_id=$game_map.map_id)
return true if GameData::Weather.get($game_screen.weather_type).category == :Fog
return $game_weather.get_map_weather_type($game_map.map_id) == :Fog
return $game_weather.get_map_weather_type(map_id) == :Fog
end
def isWeatherSnow?()
def isWeatherAsh?(map_id=$game_map.map_id)
return true if GameData::Weather.get($game_screen.weather_type).category == :Ash
return $game_weather.get_map_weather_type(map_id) == :Ash
end
def isWeatherSnow?(map_id=$game_map.map_id)
return true if GameData::Weather.get($game_screen.weather_type).category == :Snow
return $game_weather.get_map_weather_type($game_map.map_id) == :Snow
return $game_weather.get_map_weather_type(map_id) == :Snow
end
def changeCurrentWeather(weatherType,intensity)
def changeCurrentWeather(weatherType,intensity,force=false)
new_map_id = $game_map.map_id
mapMetadata = GameData::MapMetadata.try_get(new_map_id)
return nil if mapMetadata.nil?
return nil if !mapMetadata.outdoor_map
return nil if !mapMetadata.outdoor_map && !force
if $game_weather
$game_weather.set_map_weather($game_map.map_id,weatherType,intensity)
$game_weather.update_overworld_weather($game_map.map_id)
@@ -40,17 +40,23 @@ class GameWeather
BASE_CHANCES_OF_WEATHER_MOVE = 10
DEBUG_PROPAGATION = false
NO_WEATHER_MAPS = [MAP_DESERT_UNDERPASS] #For outdoor maps that shouldn't get weather
COLD_MAPS = [MAP_SHOAL_CAVE] # Rain is snow on that map (shoal cave)
SNOW_LIMITS = [MAP_ROUTE_121,MAP_PACIFIDLOG] #Snow turns to rain if it reaches these maps
NO_SNOW_MAPS = [MAP_ROUTE_121, MAP_FORTREE, MAP_ROUTE_120] #Maps where it's too warm to snow
SOOT_LIMITS = [MAP_ROUTE_113,MAP_FALLARBOR, MAP_ROUTE_111] #Can't let it propagate too much because then the grass would have to be covered in soot in those maps too....
SANDSTORM_MAPS = [MAP_DESERT] # Always sandstorm, doesn't spread
NO_WIND_MAPS = [MAP_SOOTOPOLIS]
NO_RAIN_MAPS = [MAP_MT_CHIMNEY,MAP_DESERT]
FREQUENT_WEATHER = [MAP_ROUTE_113,MAP_ROUTE_120] #More likely to spawn a new weather
#Maps where it's likely to spawn a new weather. Value is the number of weather re-rolls.
FREQUENT_WEATHER = {MAP_ROUTE_113=> 3,
MAP_ROUTE_120 => 2}
WINDY_MAPS = [MAP_MT_CHIMNEY,MAP_MT_PYRE] #More likely to be windy
RAINY_MAPS = [MAP_ROUTE_113,MAP_ROUTE_119,MAP_ROUTE_120] #More likely to be raining,
RAINY_MAPS = [MAP_ROUTE_113, MAP_ROUTE_119_SOUTH, MAP_ROUTE_120] #More likely to be raining,
# 113 is in there because rain turns into soot there
SOOT_MAPS = [MAP_ROUTE_113]
@@ -155,7 +161,10 @@ class GameWeather
def try_spawn_new_weather(map_id,map_weather_type,spawn_chance=nil)
return if map_weather_type != :None
spawn_chance = CHANCE_OF_NEW_WEATHER unless spawn_chance
spawn_chance*=2 if FREQUENT_WEATHER.include?(map_id)
if FREQUENT_WEATHER.include?(map_id)
nb_rerolls =FREQUENT_WEATHER[map_id]
spawn_chance*=nb_rerolls
end
new_weather = select_new_weather_spawn(spawn_chance, map_id)
@current_weather[map_id] = adjust_weather_for_map(new_weather,map_id)
end
@@ -233,6 +242,9 @@ class GameWeather
end
def get_updated_weather(type, intensity, map_id)
if NO_WEATHER_MAPS.include?(map_id)
return [:None,0]
end
if COLD_MAPS.include?(map_id) || Settings::SNOW_DAY
type = :Snow if type == :Rain
type = :Blizzard if type == :Storm
@@ -260,6 +272,7 @@ class GameWeather
type = :Sandstorm
intensity = 9
end
if (PBDayNight.isNight? || PBDayNight.isEvening?) && type == :Sunny
type = :None
intensity = 0
@@ -0,0 +1,474 @@
#PIF2 Safari Zone takes place entirely in the overworld, no battles. You throw Pokemon like you do in Legends Arceus.
# - Safari Balls only work if a Pokemon doesn't see you and the catch rate improves the closer you are to a Pokemon.
# - Catching bonus if the Pokemon hasn't seen you before (caught off guard)
# - You can place berries to attract Pokemon and distract them.
#
# Can hold the throw button to throw further (?)
#
TEMPLATE_EVENT_SAFARI_BALL = 15
TEMPLATE_EVENT_POKEBLOCK = 16
HOENN_SAFARI_MAPS = [MAP_SAFARI_1,MAP_SAFARI_2,MAP_SAFARI_3,MAP_SAFARI_4,MAP_SAFARI_5,MAP_SAFARI_6]
class PokemonTemp
attr_accessor :overworld_safari
end
class SafariState
attr_accessor :caught_pokemon
attr_accessor :area_types
attr_accessor :area_unlock_methods
end
def initialize_safari
nb_balls = pbGet(VAR_HOENN_SAFARI_NB_BALLS)
nb_balls = 18 if nb_balls <= 0
pbSafariState.pbStart(nb_balls)
$PokemonTemp.overworld_safari = true
updateSafariBallDisplay()
pbSafariState.area_types= initialize_area_types
pbSafariState.area_unlock_methods= initialize_unlock_methods
respawn_safari_ball_piles
end
def initialize_area_types
return {
:wetland => [
[:same_species,nil,3],
],
:lakeland => [[:different_species,:WATER,5]],
:badland => [[:different_species,:NORMAL,6]],
:grassland => [[:different_species,:GROUND,5]],
:woodland => [[:different_species,nil,20]],
:mountains => [[:different_species,:ELECTRIC,5]],
}
end
def initialize_unlock_methods
unlock_methods = {}
pbSafariState.area_types.each do |type, methods|
chosen_method = rand(methods.size)
unlock_methods[type] = chosen_method
end
echoln unlock_methods
return unlock_methods
end
def get_area_name(area_id)
case area_id
when :lakeland
return _INTL("Lake Zone")
when :wetland
return _INTL("Wetland Zone")
when :badland
return _INTL("Badland Zone")
when :grassland
return _INTL("Grassland Zone")
when :woodland
return _INTL("Woodland Zone")
when :mountains
return _INTL("Mountains Zone")
end
end
# Returns how many catches count toward the requirement.
# :different_species => number of distinct species (optionally only of the given type)
# :same_species => highest number of catches of any single species (optionally only of the given type)
def count_safari_caught(method_type, type = nil)
caught = pbSafariState.caught_pokemon || []
caught = caught.select { |s| GameData::Species.get(s).hasType?(type) } if type
case method_type
when :same_species
return caught.group_by { |species| species }.values.map(&:size).max || 0
else # :different_species
return caught.uniq.size
end
end
def count_safari_species(compared_species)
nb = 0
caught = pbSafariState.caught_pokemon || []
caught.each do |caught_species|
if caught_species == compared_species
nb += 1
end
end
return nb
end
def safari_requirement_text(method_type, type_id, nb_to_catch)
type_name = type_id ? GameData::Type.get(type_id).name : nil
case method_type
when :different_species
if type_name
return _INTL("I can only let you through if you've caught at least \\C[1]{1}\\C[0] different \\C[1]{2}-type\\C[0] Pokémon on this Safari.", nb_to_catch, type_name)
else
return _INTL("I can only let you through if you've caught at least \\C[1]{1}\\C[0] different species of Pokémon on this Safari.", nb_to_catch)
end
when :same_species
if type_name
return _INTL("I can only let you through if you've caught at least \\C[1]{1}\\C[0] \\C[1]{2}-type\\C[0] Pokémon of the same species on this Safari.", nb_to_catch, type_name)
else
return _INTL("I can only let you through if you've caught at least \\C[1]{1}\\C[0] Pokémon of the same species on this Safari.", nb_to_catch)
end
end
end
def safariNewAreaCheck(area_id)
area_name = get_area_name(area_id)
unlock_methods = pbSafariState.area_types[area_id]
unlock_method = unlock_methods[pbSafariState.area_unlock_methods[area_id]]
method_type, type_id, nb_to_catch = unlock_method
pbCallBub(2, @event_id)
pbMessage(_INTL("Halt! This way is the \\C[1]{1}\\C[0].", area_name))
pbCallBub(2, @event_id)
pbMessage(safari_requirement_text(method_type, type_id, nb_to_catch))
icons = displayCaughtPokemonIcons
pbWait(40)
icons.dispose
nb_caught = count_safari_caught(method_type, type_id)
if nb_caught >= nb_to_catch
pbSEPlay("GUI naming confirm")
pbCallBub(2, @event_id)
pbMessage(_INTL("Yes! You've met the requirement. Go right ahead!"))
return true
else
pbSEPlay("GUI sel buzzer")
pbCallBub(2, @event_id)
pbMessage(_INTL("Oh, no! You've only got {1} so far... That's not enough!", nb_caught))
pbCallBub(2, @event_id)
pbMessage(_INTL("You need to catch more Pokémon before I can let you through!"))
return false
end
end
def updateSafariBallDisplay
return unless $PokemonTemp.overworld_safari
pbSafariState.updateBallDisplay
end
def throw_ow_safari_ball
template_event = TEMPLATE_EVENT_SAFARI_BALL
position = [$game_player.x, $game_player.y]
event = $PokemonTemp.createTempEvent(template_event, $game_map.map_id, position, $game_player.direction)
return event
end
def use_safari_feeder(price, floating=false)
discount = pbGet(VAR_HOENN_SAFARI_FEEDER_DISCOUNT)
price-=discount
if price > 0
message = _INTL("\\GWould you like to use the Pokéblock Feeder for ${1}?",price)
else
message = _INTL("\\GWould you like to use the Pokéblock Feeder?",price)
end
if pbConfirmMessage(message)
colors = [:red, :red, :red,
:blue, :blue, :blue,
:pink, :pink, :pink,
:green, :green, :green,
:yellow, :yellow, :yellow].sample(4)
pbSpendMoney(price) if price > 0
feeder_event = this_event()
positions = [[-1,0], [1,0], [0,1], [0,-1]]
i=0
template_event = TEMPLATE_EVENT_POKEBLOCK
colors.each do |color|
block_event=$PokemonTemp.createTempEvent(template_event,
$game_map.map_id,
[feeder_event.x,feeder_event.y],
$game_player.direction,
PokeblockEvent, [color,12])
if floating
block_event.floating = true
block_event.forced_bush_depth = 8
block_event.calculate_bush_depth
end
block_event.jump(*positions[i])
i+=1
end
end
end
def create_overworld_pokemon_event(pokemon, position, terrain, behavior_roaming = nil, behavior_noticed = nil)
template_event = TEMPLATE_EVENT_OW_POKEMON_NORMAL
species = pokemon[0]
level = pokemon[1]
event = $PokemonTemp.createTempEvent(template_event, $game_map.map_id, position, nil, DynamicOverworldPokemonEvent) do |event|
event.setup_pokemon(species, level, terrain, behavior_roaming, behavior_noticed)
end
return unless event
event.direction = [DIRECTION_LEFT, DIRECTION_RIGHT, DIRECTION_DOWN, DIRECTION_UP].sample
playOverworldPokemonSpawnAnimation(event, terrain)
return event
end
def safari_ball_check_collision(ball_event)
colliding_event = $game_map.get_event_at_position(ball_event.x, ball_event.y, [ball_event.id])
if colliding_event
if colliding_event.is_a?(OverworldPokemonEvent)
echoln "touched a Pokemon! #{colliding_event.name}"
ball_event.despawn
try_catch_safari_pokemon(colliding_event)
renew_overworld_pokemon(colliding_event.id)
else
pbSEPlay("MiningPick")
echoln "touched something that's not a Pokemon! #{colliding_event.name}"
ball_event.despawn
end
end
end
def release_caught_pokemon
allowed_pokemon = ($game_temp.last_safari_stats[0] || []).map(&:personalID)
filter = proc {|pokemon|
allowed_pokemon.include?(pokemon.personalID)
}
released = []
pbFadeOutIn {
scene = SafariReleaseStorageScene.new
scene.cursormode == "multiselect"
screen = SafariReleaseStorageScreen.new(scene, $PokemonStorage)
screen.setFilter(filter)
released = screen.pbStartScreen(0) # Boot PC in release only mode
}
nb_points = calculate_release_points(released)
return nb_points
echoln "Obtained #{nb_points} points for releasing Pokemon"
end
def calculate_catch_rate_points(rate)
case rate
when 0..45 then 4
when 45..55 then 3
when 55..90 then 2
when 90..200 then 1
else 0
end
end
#Base points: 2
# duplicate: -1
# Shiny: +10 points
#
def calculate_release_points(released_pokemon)
total_points = 0
species_counts = Hash.new(0)
released_pokemon.each { |p| species_counts[p.species] += 1 }
total_points = 0
released_pokemon.each do |pokemon|
species = GameData::Species.get(pokemon.species)
points = 2
catch_rate_points = calculate_catch_rate_points(species.catch_rate)
points += catch_rate_points
points += 10 if pokemon.shiny?
is_duplicate = species_counts[pokemon.species] > 1
points -= 1 if is_duplicate
total_points += points
echoln "calculating points for #{pokemon.species}: #{points}"
end
return total_points
end
class Trainer
attr_accessor :safari_caught
end
def record_safari_catch(pokemon)
pbSafariState.caught_pokemon = [] unless pbSafariState.caught_pokemon
pbSafariState.caught_pokemon << pokemon# unless pbSafariState.caught_pokemon.include?(pokemon.species)
end
ANIMATION_POKEBALL = 8
MAX_THROW_DISTANCE = 4
CATCH_RATE_FLOOR = 60
SNEAK_FLAT_BONUS = 50
def try_catch_safari_pokemon(pokemon_event)
pokemon_state = pokemon_event.current_state
playAnimation(ANIMATION_POKEBALL, pokemon_event.x, pokemon_event.y)
initial_name = pokemon_event.character_name
pokemon_event.character_name="safari_ball_throw"
pokemon_event.hide_notice_icon
pokemon = pokemon_event.pokemon
pokemon_event.lock
pbWait(14)
distance_from_player = pokemon_event.distance_from_player
unnoticed = !pokemon_event.noticed_player_once
distance = distance_from_player.clamp(1, MAX_THROW_DISTANCE)
closeness = (MAX_THROW_DISTANCE + 1 - distance) / MAX_THROW_DISTANCE.to_f
capture_rate = [pokemon.species_data.catch_rate, CATCH_RATE_FLOOR].max
multiplier = unnoticed ? 1 + (2 * closeness) : 1 + closeness
capture_rate = (capture_rate * multiplier) + (SNEAK_FLAT_BONUS * closeness)
capture_rate = 0 if pokemon_state == :NOTICED_PLAYER
echoln "base capture rate: #{pokemon.species_data.catch_rate}"
echoln "safari capture rate: #{capture_rate}"
echoln "-----"
num_shakes = pbCaptureCalc(pokemon, capture_rate, :SAFARIBALL)
shake = 0
num_shakes.times do
shake+=1
if shake < 4
pbSEPlay("ballshake")
else
pbSEPlay("Battle catch click")
end
pokemon_event.pattern=1
pbWait(2)
if shake >= 4
spritesLoader = BattleSpriteLoader.new
pokemon.pif_sprite = spritesLoader.obtain_pif_sprite(pokemon.species)
showPokemonInPokeballWithMessage(pokemon.pif_sprite, _INTL("{1} obtained {2}!\\me[Pkmn get]\\wtnp[80]\1",$Trainer.name,pokemon.name))
record_safari_catch(pokemon)
pbAddPokemonSilent(pokemon)
pokemon_event.despawn
return
end
pokemon_event.pattern=0
pbWait(24)
end
playAnimation(ANIMATION_POKEBALL, pokemon_event.x, pokemon_event.y)
pokemon_event.character_name = initial_name
pokemon_event.show_notice_icon
pokemon_event.unlock
end
class Event
def prepend(callback)
@callbacks.unshift(callback)
return self
end
end
Events.onAction.prepend(proc { |_sender, _e|
next unless Settings::HOENN && $PokemonTemp.overworld_safari
next if $game_player.jumping? || $game_player.moving?
next if $game_player.pbFacingEvent
next if $game_player.pbFacingTerrainTag.can_surf_freely && !$PokemonGlobal.surfing
next if pbSafariState.ballcount <= 0
pbSafariState.ballcount -= 1
updateSafariBallDisplay
ball_event = throw_ow_safari_ball
check_nb_safari_balls_left
})
def check_nb_safari_balls_left
echoln "#{pbSafariState.ballcount} balls left"
if pbSafariState.ballcount < 0 #when directly zero, the player can still run around and find another pile
pbMessage(_INTL("PA: Ding-dong!\1"))
pbMessage(_INTL("PA: Your safari game is over!"))
pbSafariState.decision = 1
pbSafariState.pbGoToStart
end
end
#Simplified copy of the method in PokeBattle to be used outside of a battle (safari zone)
def pbCaptureCalc(pkmn, catch_rate, ball)
battler = PokeBattle_FakeBattler.new(nil,0, pkmn)
return 4 if $DEBUG && Input.press?(Input::CTRL)
# Get a catch rate if one wasn't provided
catch_rate = pkmn.species_data.catch_rate if !catch_rate
# First half of the shakes calculation
a = battler.totalhp
b = battler.hp
x = ((3 * a - 2 * b) * catch_rate.to_f) / (3 * a)
# Calculation modifiers
if battler.status == :SLEEP || battler.status == :FROZEN
x *= 2.5
elsif battler.status != :NONE
x *= 1.5
end
x = x.floor
x = 1 if x < 1
# Definite capture, no need to perform randomness checks
return 4 if x >= 255 || BallHandlers.isUnconditional?(ball, self, battler)
# Second half of the shakes calculation
y = (65536 / ((255.0 / x) ** 0.1875)).floor
# Calculate the number of shakes
numShakes = 0
for i in 0...4
break if numShakes < i
numShakes += 1 if rand(65536) < y
end
return numShakes
end
def placePokeblock()
block = pbPokeblockCase(false)
pbRemovePokeblock(block)
return block
end
def safari_ball_pile(min_nb, max_nb)
if min_nb == max_nb
nb = min_nb
else
nb = rand(min_nb...max_nb)
end
pbSafariState.ballcount+=nb
pbMEPlay("Item get")
pbMessage(_INTL("{1} found {2} \\C[1]Safari Balls\\C[0]!", $Trainer.name, nb))
updateSafariBallDisplay()
end
def respawn_safari_ball_piles
HOENN_SAFARI_MAPS.each do |map_id|
map = $MapFactory.getMapNoAdd(map_id)
for event_data in map.events
event_id = event_data[0]
event = event_data[1]
if event.name == "SafariBalls"
pbSetSelfSwitch(event.id,"A",false,map_id)
end
end
end
end
SWITCH_UNLOCKED_WOODLANDS = 2252
SWITCH_UNLOCKED_WETLANDS = 2253
SWITCH_UNLOCKED_BADLANDS = 2254
SWITCH_UNLOCKED_GRASSLANDS = 2255
SWITCH_UNLOCKED_LAKE = 2256
SWITCH_UNLOCKED_MOUNTAINS = 2257
def list_unlocked_zones
unlocked = []
unlocked << :woodland if $game_switches[SWITCH_UNLOCKED_WOODLANDS]
unlocked << :wetland if $game_switches[SWITCH_UNLOCKED_WETLANDS]
unlocked << :badland if $game_switches[SWITCH_UNLOCKED_BADLANDS]
unlocked << :grassland if $game_switches[SWITCH_UNLOCKED_GRASSLANDS]
unlocked << :lakeland if $game_switches[SWITCH_UNLOCKED_LAKE]
unlocked << :mountains if $game_switches[SWITCH_UNLOCKED_MOUNTAINS]
return unlocked
end
@@ -0,0 +1,140 @@
def displayCaughtPokemonIcons
pbSafariState.caught_pokemon = [] unless pbSafariState.caught_pokemon
return SafariCaughtIcons_UI.new(pbSafariState.caught_pokemon)
end
class SafariCaughtIcons_UI < PokeRadar_UI
SAFARI_ICON_START_X = 8
SAFARI_ICON_START_Y = 40
SAFARI_ICON_SPACING_X = 24 # gap between dupes
SAFARI_ICON_MARGIN_Y = 44 # preferred row height
SAFARI_ICON_MIN_MARGIN = 24
SAFARI_ICON_BOTTOM = 32
SAFARI_ICON_RIGHT = 8
SAFARI_ICON_WIDTH = 32
SAFARI_GRAPHICS_Z = 19998
SAFARI_BG_IMAGE = "Safari/safari_caught_bg" # Graphics/Pictures/
SAFARI_BG_OPACITY = 200
SAFARI_COLUMN_GAP = 8 # space between columns
SAFARI_BG_PADDING = 8
def initialize(caught_pokemon = [])
counts = Hash.new(0)
caught_pokemon.each { |pokemon| counts[pokemon.species] += 1 }
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = SAFARI_GRAPHICS_Z
@sprites = {}
@bounds = nil
return if counts.empty?
usable_height = Graphics.height - SAFARI_ICON_START_Y - SAFARI_ICON_BOTTOM
usable_width = Graphics.width - SAFARI_ICON_START_X - SAFARI_ICON_RIGHT
entries = counts.to_a # [[species, count], ...]
ideal_width = proc { |count| SAFARI_ICON_WIDTH + (count - 1) * SAFARI_ICON_SPACING_X }
# Try 1, 2, 3... columns. Pass 1 wants comfortable row height,
# pass 2 accepts the tightest row height.
layout = nil
[SAFARI_ICON_MARGIN_Y, SAFARI_ICON_MIN_MARGIN].each do |min_row_height|
(1..entries.size).each do |num_cols|
rows_per_col = (entries.size.to_f / num_cols).ceil
next if usable_height / rows_per_col < min_row_height
columns = entries.each_slice(rows_per_col).to_a
col_widths = columns.map { |col| col.map { |_, c| ideal_width.call(c) }.max }
total = col_widths.sum + SAFARI_COLUMN_GAP * (columns.size - 1)
next if total > usable_width
layout = [rows_per_col, columns, col_widths]
break
end
break if layout
end
# Fallback: too many to fit comfortably, so squeeze columns/dupes as needed
if !layout
max_rows = [usable_height / SAFARI_ICON_MIN_MARGIN, 1].max
num_cols = (entries.size.to_f / max_rows).ceil
rows_per_col = (entries.size.to_f / num_cols).ceil
columns = entries.each_slice(rows_per_col).to_a
col_widths = columns.map { |col| col.map { |_, c| ideal_width.call(c) }.max }
available = usable_width - SAFARI_COLUMN_GAP * (columns.size - 1)
total = col_widths.sum
if total > available
scale = available.to_f / total
col_widths = col_widths.map { |w| (w * scale).floor }
end
layout = [rows_per_col, columns, col_widths]
end
rows_per_col, columns, col_widths = layout
row_margin = [[usable_height / rows_per_col, SAFARI_ICON_MARGIN_Y].min,
SAFARI_ICON_MIN_MARGIN].max
x = SAFARI_ICON_START_X
columns.each_with_index do |col, col_index|
col.each_with_index do |(species, count), row|
y = SAFARI_ICON_START_Y + row * row_margin
addSpeciesRow(species, count, x, y, col_widths[col_index])
end
x += col_widths[col_index] + SAFARI_COLUMN_GAP
end
addBackground
end
def expandBounds(x, y, w, h)
if !@bounds
@bounds = [x, y, x + w, y + h]
else
@bounds[0] = [@bounds[0], x].min
@bounds[1] = [@bounds[1], y].min
@bounds[2] = [@bounds[2], x + w].max
@bounds[3] = [@bounds[3], y + h].max
end
end
def addBackground
return if !@bounds
left = [@bounds[0] - SAFARI_BG_PADDING, 0].max
top = [@bounds[1] - SAFARI_BG_PADDING, 0].max
right = [@bounds[2] + SAFARI_BG_PADDING, Graphics.width].min
bottom = [@bounds[3] + SAFARI_BG_PADDING, Graphics.height].min
win = SpriteWindow_Base.new(left, top, right - left, bottom - top)
win.viewport = @viewport
win.setSkin(SAFARI_BG_IMAGE) if SAFARI_BG_IMAGE
win.back_opacity = SAFARI_BG_OPACITY # opacity of the stretched middle
win.z = SAFARI_GRAPHICS_Z # icons are at +1 and above
@sprites["bg"] = win
end
def addSpeciesRow(species, count, start_x, y, column_width)
pokemonId = dexNum(species)
return if !pokemonId
# Dupes must fit inside this column, not the whole screen
available_width = column_width - SAFARI_ICON_WIDTH
spacing = SAFARI_ICON_SPACING_X
spacing = [available_width / (count - 1), spacing].min if count > 1
count.times do |i|
x = start_x + i * spacing
if pokemonId > NB_POKEMON
iconSprite = createFusionIcon(pokemonId, x, y)
else
iconSprite = IconSprite.new(x, y)
iconSprite.setBitmap(pbCheckPokemonIconFiles(species))
end
iconSprite.src_rect.width /= 2 # icon sheets have 2 frames, show only the first
iconSprite.x = x
iconSprite.y = y
iconSprite.z = SAFARI_GRAPHICS_Z + 1 + i
iconSprite.visible = true
expandBounds(x, y, iconSprite.src_rect.width, iconSprite.src_rect.height)
@sprites[_INTL("{1}_{2}", species, i)] = iconSprite
end
end
end
@@ -0,0 +1,356 @@
#===============================================================================
# Pokémon storage mechanics
#===============================================================================
class SafariReleaseStorageScreen < PokemonStorageScreen
attr_reader :scene
attr_reader :storage
attr_accessor :heldpkmn
attr_accessor :fusionMode
attr_accessor :filterProc
def initialize(scene, storage)
super(scene, storage)
@release_pokemon = []
end
def pbStartScreen(command, animate = true)
super
return @release_pokemon
end
def pcOrganizeCommand
@scene.pbSetCursorMode("multiselect")
super
end
def singlePokemonCommands(selected)
return multipleSelectedPokemonCommands([selected],1)
end
#differences from normal: release is in first position
def multipleSelectedPokemonCommands(selected, pokemonCount)
commands = []
cmdRelease = _INTL("Release")
cmdMove = _INTL("Move")
cmdCancel = _INTL("Cancel")
cmdSort = _INTL("Sort")
helptext = _INTL("Selected {1} Pokémon.", pokemonCount)
commands << cmdRelease
commands << cmdMove
commands << cmdSort
commands << cmdCancel
chosen = pbShowCommands(helptext, commands)
case commands[chosen]
when cmdMove
pbHoldMulti(selected[0], selected[1])
when cmdSort
pbSortMulti(selected[0])
when cmdRelease
pbReleaseMulti(selected[0])
end
end
def releasable?(pokemon)
return false if !pokemon
return true if @filterProc.nil?
return @filterProc.call(pokemon)
end
#differences from normal: release is in first position
def pbReleaseMulti(box)
selected = getMultiSelection(box, nil)
return if selected.length == 0
able_count = 0
final_released = []
released_mons = []
for index in selected
pokemon = @storage[box, index]
next if !pokemon
next if !releasable?(pokemon) # ignore Pokémon that fail the filter
if pokemon.owner.name == "RENTAL"
pbDisplay(_INTL("This Pokémon cannot be released"))
return
elsif pokemon.egg?
pbDisplay(_INTL("You can't release an Egg."))
return false
elsif pokemon.mail
pbDisplay(_INTL("Please remove the mail."))
return false
end
able_count += 1 if pbAble?(pokemon)
final_released << index
released_mons << pokemon
end
if final_released.empty?
pbPlayBuzzerSE
pbDisplay(_INTL("None of the selected Pokémon can be released."))
return
end
if box == BOX_NAME && pbAbleCount == able_count
pbPlayBuzzerSE
pbDisplay(_INTL("That's your last Pokémon!"))
return
end
command = pbShowCommands(_INTL("Release {1} Pokémon?", final_released.length), [_INTL("Yes"), _INTL("No")])
if command == 0
command_confirm = pbShowCommands(_INTL("The {1} Pokémon will be lost forever. Release them?", final_released.length), [_INTL("Yes"), _INTL("No")])
if command_confirm == 0
@multiSelectRange = nil
@scene.pbUpdateSelectionRect(0, 0)
@scene.animate_release_multi(box, final_released)
@storage.pbDeleteMulti(box, final_released)
@scene.pbRefresh
pbDisplay(_INTL("The Pokémon were released."))
pbDisplay(_INTL("Bye-bye!"))
@scene.pbRefresh
@release_pokemon.concat(released_mons)
end
end
return
end
# def setFilter(filterProc)
# @filterProc = filterProc
# end
# TODO: Open party screen by default.
# Handle when player chooses a Pokemon from their party instead of a box
# def choosePokemon
# super
# end
#
# def organizeActions(selected, pokemon, heldpoke, isTransferBox)
# commands = []
# cmdMove = -1
# cmdSummary = -1
# cmdWithdraw = -1
# cmdItem = -1
# cmdFuse = -1
# cmdUnfuse = -1
# cmdReverse = -1
# cmdRelease = -1
# cmdDebug = -1
# cmdCancel = -1
# cmdNickname = -1
#
# if heldpoke
# helptext = _INTL("{1} is selected.", heldpoke.name)
# commands[cmdMove = commands.length] = (pokemon) ? _INTL("Shift") : _INTL("Place")
# elsif pokemon
# helptext = _INTL("{1} is selected.", pokemon.name)
# commands[cmdMove = commands.length] = _INTL("Move")
# end
# commands[cmdSummary = commands.length] = _INTL("Summary")
# # if pokemon != nil && !isTransferBox
# # if dexNum(pokemon.species) > NB_POKEMON
# # commands[cmdUnfuse = commands.length] = _INTL("Unfuse")
# # commands[cmdReverse = commands.length] = _INTL("Reverse") if $PokemonBag.pbQuantity(:DNAREVERSER) > 0 || $PokemonBag.pbQuantity(:INFINITEREVERSERS) > 0
# # else
# # commands[cmdFuse = commands.length] = _INTL("Fuse") if !@heldpkmn
# # end
# # end
# # commands[cmdNickname = commands.length] = _INTL("Nickname") if !@heldpkmn && !isTransferBox
# # commands[cmdWithdraw = commands.length] = (selected[0] == -1) ? _INTL("Store") : _INTL("Withdraw")
# # commands[cmdItem = commands.length] = _INTL("Item") if !isTransferBox
#
# commands[cmdRelease = commands.length] = _INTL("Release")
# commands[cmdDebug = commands.length] = _INTL("Debug") if $DEBUG
# commands[cmdCancel = commands.length] = _INTL("Cancel")
# command = pbShowCommands(helptext, commands)
# if cmdMove >= 0 && command == cmdMove # Move/Shift/Place
# #@scene.pbSetCursorMode("default")
# if @heldpkmn
# (pokemon) ? pbSwap(selected) : pbPlace(selected)
# else
# if @scene.cursormode == "multiselect"
# pbHoldMulti(selected[0], selected[1])
# else
# pbHold(selected)
# end
# end
# elsif cmdSummary >= 0 && command == cmdSummary # Summary
# pbSummary(selected, @heldpkmn)
# elsif cmdNickname >= 0 && command == cmdNickname # Summary
# renamePokemon(selected)
# elsif cmdWithdraw >= 0 && command == cmdWithdraw # Store/Withdraw
# (selected[0] == -1) ? pbStore(selected, @heldpkmn) : pbWithdraw(selected, @heldpkmn)
# elsif cmdItem >= 0 && command == cmdItem # Item
# pbItem(selected, @heldpkmn)
# elsif cmdFuse >= 0 && command == cmdFuse # fuse
# pbFuseFromPC(selected, @heldpkmn)
# elsif cmdUnfuse >= 0 && command == cmdUnfuse # unfuse
# pbUnfuseFromPC(selected)
# elsif cmdReverse >= 0 && command == cmdReverse # unfuse
# reverseFromPC(selected)
# elsif cmdRelease >= 0 && command == cmdRelease # Release
# pbRelease(selected, @heldpkmn)
# elsif cmdDebug >= 0 && command == cmdDebug # Debug
# pbPokemonDebug((@heldpkmn) ? @heldpkmn : pokemon, selected, heldpoke)
# end
# end
# def quickSwap(selected, pokemon)
# if @heldpkmn
# (pokemon) ? pbSwap(selected) : pbPlace(selected)
# else
# pbHold(selected)
# end
# end
# def pcSelectCommand
# @scene.choseFromParty = true
# loop do
# selected = @scene.pbSelectBox(@storage.party)
# if selected == nil
# next if pbConfirm(_INTL("Continue Box operations?"))
# break
# else
# case selected[0]
# when -2 # Party Pokémon
# pbDisplay(_INTL("Which one will you choose?"))
# next
# when -3 # Close box
# if pbConfirm(_INTL("Cancel choosing a Pokémon?"))
# pbSEPlay("PC close")
# break
# end
# return nil
# when -4 # Box name
# pbBoxCommands
# next
# end
# pokemon = @storage[selected[0], selected[1]]
# next if !pokemon
# if @filterProc.call(pokemon)
# command = pbShowCommands(_INTL("{1} is selected.", pokemon.name), [
# _INTL("Choose"),
# _INTL("Summary"),
# _INTL("Cancel")
# ])
# case command
# when 0 then
# return selected
# when 1 then
# pbSummary(selected, nil)
# end
# else
# pbDisplay(_INTL("This Pokémon cannot be chosen..."))
# next
# end
# end
# end
# @scene.pbCloseBox
# end
def pbHold(selected)
super
end
def pbPlace(selected)
super
end
def pbSwap(selected)
super
end
def pbSummary(selected, heldpoke)
@scene.pbSummary(selected, heldpoke)
end
# def pbChoosePokemon(_party = nil)
# @heldpkmn = nil
# @scene.pbStartBox(self, 1)
# retval = nil
# loop do
# selected = @scene.pbSelectBox(@storage.party)
# if selected && selected[0] == -3 # Close box
# if pbConfirm(_INTL("Exit from the Box?"))
# pbSEPlay("PC close")
# break
# end
# next
# end
# if selected == nil
# next if pbConfirm(_INTL("Continue Box operations?"))
# break
# elsif selected[0] == -4 # Box name
# pbBoxCommands
# else
# pokemon = @storage[selected[0], selected[1]]
# next if !pokemon
# commands = [
# _INTL("Select"),
# _INTL("Summary"),
# _INTL("Withdraw"),
# _INTL("Item"),
# _INTL("Mark")
# ]
# commands.push(_INTL("Cancel"))
# commands[2] = _INTL("Store") if selected[0] == -1
# helptext = _INTL("{1} is selected.", pokemon.name)
# command = pbShowCommands(helptext, commands)
# case command
# when 0 # Select
# if pokemon
# retval = selected
# break
# end
# when 1
# pbSummary(selected, nil)
# when 2 # Store/Withdraw
# if selected[0] == -1
# pbStore(selected, nil)
# else
# pbWithdraw(selected, nil)
# end
# when 3
# pbItem(selected, nil)
# when 4
# pbMark(selected, nil)
# end
# end
# end
# @scene.pbCloseBox
# return retval
# end
def deleteHeldPokemon(heldpoke, selected)
@scene.pbReleaseInstant(selected, heldpoke)
@heldpkmn = nil
end
def deleteSelectedPokemon(heldpoke, selected)
pbSwap(selected)
deleteHeldPokemon(heldpoke, selected)
end
end
class SafariReleaseStorageScene < PokemonStorageScene
def transfer_box?(box_index)
box_index >= 0 && @storage[box_index].is_a?(StorageTransferBox)
end
def next_valid_box(from, step)
total = @storage.maxBoxes
box = from
total.times do
box = (box + step) % total
return box unless transfer_box?(box)
end
from
end
def pbNextCursorMode()
return
end
end
@@ -234,7 +234,7 @@ def convertHeartScalesToCoins
pbSEPlay("MiningRevealItem")
pbWait(4)
pbCallBubDown(2, @event_id)
pbMessage(_INTL("Here you go! I converted your Heart Scales into {1} \\C[1]{2}\\C[0]!", nb_coins, COSMETIC_CURRENCY_NAME))
pbMessage(_INTL("Here you go! I converted your Heart Scales into {1} \\C[1]{2}\\C[0]!", nb_coins, get_cosmetic_currency_name))
pbReceiveCosmeticsMoney(nb_coins)
pbCallBubDown(2, @event_id)
pbMessage(_INTL("Come back whenever you find more Heart Scales to convert!"))
@@ -321,3 +321,95 @@ def inputColorCode(codeVariable)
return ColorCodeDoor.new(codeVariable).inputColorCode
end
def count_soot()
return count_tile(:SootGrass)
end
def count_tile(terrain_tag)
map = $MapFactory.getMap($game_map.map_id)
count = 0
for x in 0...map.data.xsize
for y in 0...map.data.ysize
for i in 0...map.data.zsize
tile_id = map.data[x, y, i]
next if GameData::TerrainTag.try_get(map.terrain_tags[tile_id]).id != terrain_tag
#echoln [x,y]
count+=1
end
end
end
return count
end
def obtainBirthdayHat(celebration_id)
current_year = Time.now.year
birthday_id = "#{celebration_id}_#{current_year}".to_sym
$Trainer.birthdays_celebrated = [] unless $Trainer.birthdays_celebrated
return if $Trainer.birthdays_celebrated.include?(birthday_id)
possible_hats = [HAT_PARTY_1, HAT_PARTY_2, HAT_PARTY_3, HAT_PARTY_4, HAT_PARTY_5, HAT_PARTY_6, HAT_PARTY_7]
possible_hats = possible_hats.reject { |hatID| hasHat?(hatID) }
unless possible_hats.empty?
obtainHat(possible_hats.sample)
$Trainer.birthdays_celebrated << birthday_id
end
end
def crumbleMirageTower(event_base_id, event_top_id, tiles = 8)
event_base = $game_map.events[event_base_id]
event_top = $game_map.events[event_top_id]
return unless event_base && event_top
ground_y = event_base.y
tiles.times do
event_base.move_down
event_top.move_down
loop do
pbSEPlay("Earth4",80,80,)
update_crumble_mask(event_base, ground_y)
update_crumble_mask(event_top, ground_y)
Graphics.update
Input.update
pbUpdateSceneMap
break if !event_base.moving? && !event_top.moving?
end
end
end
def update_crumble_mask(ev, ground_y)
ground_real = ground_y * Game_Map::REAL_RES_Y
sunk_real = ev.real_y - ground_real
sunk_px = (sunk_real / Game_Map::Y_SUBPIXELS).to_i
depth = [sunk_px, 0].max
return if ev.forced_bush_depth == depth
ev.forced_bush_depth = depth
ev.calculate_bush_depth
end
Events.onWildBattleEnd += proc { |_sender, e|
$game_switches[SWITCH_ENCOUNTERED_A_POKEMON] = true
}
def petalburg_unlock_doors(doors=[])
for door in doors
pbSetSelfSwitch(door,"A",true)
end
pbWait(8)
pbSEPlay("unlock")
pbWait(8)
if doors.length >1
pbMessage(_INTL("The doors unlocked!"))
else
pbMessage(_INTL("The door unlocked!"))
end
end
def obtainNormanHat
gender=getPlayerGenderId()
if gender == GENDER_MALE
obtainHat(HAT_GYM_REWARD_5_HOENN_M)
else
obtainHat(HAT_GYM_REWARD_5_HOENN_F)
end
end
@@ -1,3 +1,5 @@
class OverworldPokemonEvent < Game_Event
attr_accessor :species
@@ -14,6 +16,8 @@ class OverworldPokemonEvent < Game_Event
attr_reader :noticed_player_once
attr_reader :last_facing_direction
attr_reader :glow_in_the_dark
DISTANCE_FOR_DESPAWN = 16
FLEEING_BEHAVIORS = [:flee, :flee_flying, :teleport_away]
@@ -33,7 +37,7 @@ class OverworldPokemonEvent < Game_Event
@disguised = false
species_data = GameData::Species.get(@species)
@pokemon = Pokemon.new(@species, @level)
@pokemon = pbGenerateWildPokemon(@species,@level)#Pokemon.new(@species, @level)
@behavior_species = getBehaviorSpecies(species_data)
unless behavior_roaming
@@ -64,6 +68,7 @@ class OverworldPokemonEvent < Game_Event
@current_state = :ROAMING # Possible values: :ROAMING, :NOTICED_PLAYER, :FLEEING
@noticed_player_once = false
@manual_ow_pokemon = false
@manual_appearance = nil #if this is set to something, it overrides the pokemon's normal appearance
#@event.name = "OW/#{species.to_s}/#{level.to_s}"
weather = $game_weather.get_current_map_weather if $game_weather
if weather
@@ -86,6 +91,7 @@ class OverworldPokemonEvent < Game_Event
@step_anime = @is_flying
@forced_z = 300 if @is_flying && $PokemonGlobal.boat #@always_on_top = @is_flying
@part_of_pokeradar_chain = is_pokeradar_chain
@pack_size = 0
if @terrain == :Water
set_swimming
end
@@ -95,11 +101,28 @@ class OverworldPokemonEvent < Game_Event
pbSEPlay("shiny", 60)
playAnimation(Settings::SPARKLE_SHORT_ANIMATION_ID, @x, @y)
end
if POKEMON_BEHAVIOR_DATA[@behavior_species][:hop_cliff]
@can_hop_cliff = true
end
set_roaming_movement
@last_facing_direction = @direction
setup_glow
@setup_complete = true
end
def setup_glow
unless Settings::EXPERIMENTAL_FEATURES
@glow_in_the_dark = false
return
end
@glow_in_the_dark = POKEMON_BEHAVIOR_DATA[@behavior_species][:glow_in_the_dark]
if @glow_in_the_dark
@light_effect = LightEffect_PokemonGlow.new(self)
$scene.spriteset.addUserSprite(@light_effect)
end
end
def roll_for_special_encounters
# Mew encounter
if rand(15100) < Settings::MEW_OW_ENCOUNTER_CHANCE
@@ -115,6 +138,7 @@ class OverworldPokemonEvent < Game_Event
initialize_sprite(@terrain, species_data)
end
def is_pokeradar_chain
if $PokemonTemp.pokeradar
pokeradar_species = $PokemonTemp.pokeradar[0]
@@ -138,6 +162,15 @@ class OverworldPokemonEvent < Game_Event
return GameData::Species.get(@species)
end
def override_appearance(sprite_path)
set_sprite(sprite_path)
@manual_appearance =sprite_path
end
def cancel_appearance_override()
@manual_appearance =nil
end
def get_behavior_for_species(species, behavior_type)
behavior = POKEMON_BEHAVIOR_DATA[species][behavior_type]
if @terrain == :Water
@@ -190,11 +223,21 @@ class OverworldPokemonEvent < Game_Event
return @species
end
def getBodySpecies
is_fusion = isSpeciesFusion(@species)
if is_fusion
return GameData::Species.get(@species).get_body_species_symbol
end
return @species
end
def initialize_sprite(terrain, species_data)
@land_sprite = getOverworldLandPath(species_data, @pokemon.shiny?)
@flying_sprite = getOverworldFlyingPath(species_data, @pokemon.shiny?)
@swimming_sprite = getOverworldSwimmingPath(species_data, @pokemon.shiny?)
@idle_animation_sprite = getOverworldIdleAnimation(species_data,@is_flying, @pokemon.shiny?)
@noticed_sprite = getOverworldNoticedPath(species_data, @pokemon.shiny?)
@noticed_sprite = @flying_sprite if !@noticed_sprite && @flying_sprite
@roaming_sprite = @land_sprite
@@ -207,6 +250,13 @@ class OverworldPokemonEvent < Game_Event
end
end
def pokemon
unless @pokemon
@pokemon = Pokemon.new(@species, @level)
end
return @pokemon
end
def initialize_water_sprite
if @flying_sprite
@character_name = @flying_sprite
@@ -228,7 +278,9 @@ class OverworldPokemonEvent < Game_Event
def get_current_state
return @current_state
end
def is_eating?
return @noticed_pokemon_behavior == :eat_pokeblock
end
####
# ACTIONS
# ###
@@ -252,7 +304,7 @@ class OverworldPokemonEvent < Game_Event
return
end
def flee(behavior)
def flee(behavior=nil)
return if @pokemon.shiny?
playCry(@species)
pbSEPlay(SE_FLEE)
@@ -299,18 +351,31 @@ class OverworldPokemonEvent < Game_Event
initialize_sprite(@terrain, species_data)
end
def playDetectPlayerAnimation
return unless @current_state == :ROAMING
return unless noticed_state_different_from_roaming()
ANIMATION_OW_CURIOUS = 41
ANIMATION_OW_ANGRY = 42
ANIMATION_OW_EXCITED = 43
ANIMATION_OW_SURPRISED = 44
if @behavior_noticed == :curious
playAnimation(Settings::QUESTION_MARK_ANIMATION_ID, @x, @y)
elsif @behavior_noticed == :aggressive
playAnimation(Settings::ANGRY_ANIMATION_ID, @x, @y)
elsif @behavior_noticed == :semi_aggressive
playAnimation(Settings::ANGRY_SHORT_ANIMATION_ID, @x, @y)
def playDetectAnimation(behavior_noticed = @behavior_noticed, play_sound = true)
return unless @current_state == :ROAMING
return unless @behavior_noticed
#return unless noticed_state_different_from_roaming()
if behavior_noticed == :curious
pbSEPlay("Exclaim") if play_sound
playAnimation(ANIMATION_OW_CURIOUS, @x, @y)
elsif behavior_noticed == :aggressive
pbSEPlay("angry") if play_sound
playAnimation(ANIMATION_OW_ANGRY, @x, @y)
elsif behavior_noticed == :excited
pbSEPlay("Exclaim") if play_sound
playAnimation(ANIMATION_OW_EXCITED, @x, @y)
elsif behavior_noticed == :semi_aggressive
pbSEPlay("angry") if play_sound
playAnimation(ANIMATION_OW_ANGRY, @x, @y)
else
playAnimation(Settings::EXCLAMATION_ANIMATION_ID, @x, @y)
pbSEPlay("Exclaim") if play_sound
playAnimation(ANIMATION_OW_SURPRISED, @x, @y)
end
end
@@ -323,13 +388,15 @@ class OverworldPokemonEvent < Game_Event
distance = distance_from_player()
is_near_player = distance <= @detection_radius
if distance >= DISTANCE_FOR_DESPAWN
despawn unless @manual_ow_pokemon
despawn unless @manual_ow_pokemon || @pokemon.shiny?
end
if is_near_player
if should_start_battle? # Battle
if isRepelActive && pokemon_can_be_repelled
playAnimation(Settings::EXCLAMATION_ANIMATION_ID, @x, @y)
flee(@behavior_noticed)
elsif $PokemonTemp.overworld_safari
flee() unless is_eating?
else
overworldPokemonBattle
end
@@ -337,7 +404,8 @@ class OverworldPokemonEvent < Game_Event
# check for noticed
if @current_state == :ROAMING
if check_detect_trainer
playDetectPlayerAnimation
playDetectAnimation
@target = :player
breakDisguise if @disguised
@noticed_player_once = true
update_state(:NOTICED_PLAYER)
@@ -345,7 +413,7 @@ class OverworldPokemonEvent < Game_Event
end
end
else
if @current_state != :ROAMING
if @current_state != :ROAMING && @current_state != :NOTICED_POKEMON
update_state(:ROAMING)
back_to_roaming_action
end
@@ -355,7 +423,7 @@ class OverworldPokemonEvent < Game_Event
# Automatically starts a battle if the player is 1 tile away from the Pokemon.
# If the player is behind or to the side of the pokemon, there is a slight delay
def should_start_battle?
return false unless $PokemonTemp.overworld_wild_battle_participants
$PokemonTemp.overworld_wild_battle_participants = [] unless $PokemonTemp.overworld_wild_battle_participants
should_start = false
if player_near_event?(1)
return true if $PokemonTemp.overworld_wild_battle_participants.length >= 1 # Notice immediately if a pokemon is already attacking so that double battles are more likely
@@ -390,6 +458,7 @@ class OverworldPokemonEvent < Game_Event
# called when a pokemon that has noticed the player goes back to roaming
def back_to_roaming_action
@target = nil
case @behavior_noticed
when :skittish, :shy
turn_toward_player
@@ -407,17 +476,17 @@ class OverworldPokemonEvent < Game_Event
when :ROAMING
set_roaming_movement
when :NOTICED_PLAYER
set_noticed_movement
set_noticed_movement if @behavior_noticed
end
set_sprite_to_current_state
end
def check_detect_trainer
return unless noticed_state_different_from_roaming()
return if $game_system.map_interpreter.running? || @starting
# return pbEventCanReachPlayer?(self, $game_player, @detection_radius)
return pbPlayerInEventCone?(self, $game_player, @detection_radius)
end
# def check_detect_trainer
# return unless noticed_state_different_from_roaming()
# return if $game_system.map_interpreter.running? || @starting
# # return pbEventCanReachPlayer?(self, $game_player, @detection_radius)
# return pbPlayerInEventCone?(self, $game_player, @detection_radius)
# end
def pbCheckEventTriggerAfterTurning
return if $game_system.map_interpreter.running? || @starting
@@ -498,6 +567,7 @@ class OverworldPokemonEvent < Game_Event
end
def set_sprite(sprite_path)
return if @manual_appearance
@character_name = sprite_path
@need_refresh = true
end
@@ -511,6 +581,10 @@ class OverworldPokemonEvent < Game_Event
end
effective_behavior = @behavior_noticed || @behavior_roaming # fallback on @behavior_roaming if no @behavior_noticed
if @current_state == :NOTICED_PLAYER && @pack_size && @pack_size >= 3
pack_behavior = POKEMON_BEHAVIOR_DATA[@behavior_species][:pack_behavior_noticed]
effective_behavior = pack_behavior if pack_behavior
end
case effective_behavior
when :random
@@ -521,7 +595,7 @@ class OverworldPokemonEvent < Game_Event
@move_type = MOVE_TYPE_CURIOUS
when :semi_aggressive
@move_type = MOVE_TYPE_TOWARDS_PLAYER
when :aggressive
when :aggressive, :excited
@move_type = MOVE_TYPE_TOWARDS_PLAYER
self.move_frequency = 6
when :skittish
@@ -545,13 +619,19 @@ class OverworldPokemonEvent < Game_Event
return
end
case @behavior_roaming
effective_behavior = @behavior_roaming
if @current_state == :ROAMING && @pack_size && @pack_size >= 3
pack_behavior = POKEMON_BEHAVIOR_DATA[@behavior_species][:pack_behavior_roaming]
effective_behavior = pack_behavior if pack_behavior
end
case effective_behavior
when :random
@move_type = MOVE_TYPE_RANDOM
when :still
@move_type = MOVE_TYPE_FIXED
else
set_custom_move_route(OW_BEHAVIOR_MOVE_ROUTES[:roaming][@behavior_roaming])
set_custom_move_route(OW_BEHAVIOR_MOVE_ROUTES[:roaming][effective_behavior])
end
self.move_frequency = 3
check_weather_roaming_behavior
@@ -561,17 +641,17 @@ class OverworldPokemonEvent < Game_Event
def check_weather_roaming_behavior
if @weather_type_at_spawn == :Wind || @weather_type_at_spawn == :Storm
wind_behavior = POKEMON_BEHAVIOR_DATA[@species][:behavior_wind_roaming]
wind_behavior = POKEMON_BEHAVIOR_DATA[@behavior_species][:behavior_wind_roaming]
if wind_behavior
set_custom_move_route(OW_BEHAVIOR_MOVE_ROUTES[:roaming][wind_behavior])
end
elsif @weather_type_at_spawn == :Rain || @weather_type_at_spawn == :Storm
rain_behavior = POKEMON_BEHAVIOR_DATA[@species][:behavior_rain_roaming]
rain_behavior = POKEMON_BEHAVIOR_DATA[@behavior_species][:behavior_rain_roaming]
if rain_behavior
set_custom_move_route(OW_BEHAVIOR_MOVE_ROUTES[:roaming][rain_behavior])
end
elsif @weather_type_at_spawn == :Sunny
sun_behavior = POKEMON_BEHAVIOR_DATA[@species][:behavior_sunny_roaming]
sun_behavior = POKEMON_BEHAVIOR_DATA[@behavior_species][:behavior_sunny_roaming]
if sun_behavior
set_custom_move_route(OW_BEHAVIOR_MOVE_ROUTES[:roaming][sun_behavior])
end
@@ -587,6 +667,18 @@ class OverworldPokemonEvent < Game_Event
end
def despawn
@light_effect&.dispose
dispose_notice_icon
spriteset = $scene.respond_to?(:spritesets) ? $scene.spritesets[@map_id] : nil
if spriteset
sprite = spriteset.character_sprites.find { |s| s.character == self }
if sprite
spriteset.character_sprites.delete(sprite)
sprite.dispose
end
end
erase
$game_map.events.delete(@id)
$PokemonTemp.overworld_pokemon_on_map&.delete(@id)
@@ -601,6 +693,13 @@ class OverworldPokemonEvent < Game_Event
case @move_type
when MOVE_TYPE_CURIOUS
move_type_curious(ready_for_next_movement)
when MOVE_TYPE_TOWARDS_TARGET
move_type_toward_target(@target, ready_for_next_movement) if ready_for_next_movement
when MOVE_TYPE_AWAY_FROM_TARGET
move_type_away_from_target(@target) if ready_for_next_movement
when MOVE_TYPE_SHY_FROM_TARGET
move_type_away_from_target(@target) if ready_for_next_movement
turnEventTowardsEvent(self, @target)
end
end
@@ -611,9 +710,13 @@ class OverworldPokemonEvent < Game_Event
def update
super
update_idle_animation
update_notice_icon if $PokemonTemp.overworld_safari
if $game_temp.message_window_showing
pause_movement unless @current_state == :PAUSED
else
update_attack_target
update_retaliation
@behavior_update_counter = (@behavior_update_counter || 0) + 1
if @behavior_update_counter >= UPDATE_TIME
@behavior_update_counter = 0
@@ -621,5 +724,24 @@ class OverworldPokemonEvent < Game_Event
end
end
end
#Override marshall dump to exclude stuff that crashes the game (the ref to lignt_effect)
def marshal_dump
ivars = {}
instance_variables.each do |var|
next if var == :@light_effect || var == :@notice_icon
ivars[var] = instance_variable_get(var)
end
return ivars
end
def marshal_load(ivars)
ivars.each { |var, val| instance_variable_set(var, val) }
@light_effect = nil
@notice_icon = nil
end
end
@@ -0,0 +1,384 @@
class OverworldPokemonEvent < Game_Event
alias setup_pokemon_detection setup_pokemon
RETALIATION_DELAY = 20 # frames of "stunned/reacting" before fighting back
def setup_pokemon(*args)
setup_pokemon_detection(*args)
@currently_seen_events = []
@previously_seen_events = []
@target = nil
@noticed_pokemon_behavior = nil
@attack_timer = 0
@retaliation_timer = 0
@pending_retaliation_target = nil
end
#Version that only detects when the Pokemon is actually looking at the pokemon
#
# alias turn_generic_pokemon_detection turn_generic
# def turn_generic(*args)
# turn_generic_pokemon_detection(*args)
# @currently_seen_events = listEventsInVisionCone
# @currently_seen_events.each do |event|
# event_pokemon = event[0]
# distance = event[1]
# noticed_pokemon_behaviors = POKEMON_BEHAVIOR_DATA[@species][:behavior_pokemon]
# if noticed_pokemon_behaviors && noticed_pokemon_behaviors.include?(event_pokemon.species)
# behavior = noticed_pokemon_behaviors[event_pokemon.species]
# playDetectAnimation(behavior)
# update_state(:NOTICED_POKEMON)
# set_noticed_pokemon_movement(behavior, event_pokemon)
# end
# end
# echoln @currently_seen_events
# end
BEHAVIOR_PRIORITY = {
skittish: 1,
aggressive: 2,
shy: 3,
semi_aggressive: 4,
curious: 5
}.freeze
alias turn_generic_pokemon_detection turn_generic
def turn_generic(*args)
turn_generic_pokemon_detection(*args)
return unless Settings::EXPERIMENTAL_FEATURES
@currently_seen_events = listEventsInRadius(@detection_radius)
if @current_state == :NOTICED_POKEMON
unless target_still_valid?
update_state(:ROAMING)
back_to_roaming_action
return
end
end
behavior_data = POKEMON_BEHAVIOR_DATA[@species]
noticed_pokemon_behaviors = behavior_data ? behavior_data[:behavior_pokemon] : nil
sorted_events = @currently_seen_events.sort_by { |_event, distance| distance }
if sorted_events.empty?
if @current_state == :NOTICED_POKEMON
update_state(:ROAMING)
back_to_roaming_action
@target = nil
end
return
end
@pack_size = 0
nearest_distance = nil
candidates = [] # [event, behavior] pairs, all at nearest_distance
pokeblock_candidate = nil
sorted_events.each do |event_pokemon, distance|
# Once we've passed the nearest distance that had any qualifying target, stop
break if nearest_distance && distance > nearest_distance
if event_pokemon.is_a?(PokeblockEvent)
pokeblock_candidate ||= event_pokemon
nearest_distance ||= distance
next
end
next if event_pokemon.pokemon.shiny?
if noticed_pokemon_behaviors && noticed_pokemon_behaviors.include?(event_pokemon.species)
candidates << [event_pokemon, noticed_pokemon_behaviors[event_pokemon.species]]
nearest_distance ||= distance
elsif event_pokemon.species == @pokemon.species
@pack_size += 1
elsif noticed_pokemon_behaviors && noticed_pokemon_behaviors.include?(:everything)
candidates << [event_pokemon, noticed_pokemon_behaviors[:everything]]
nearest_distance ||= distance
end
end
if pokeblock_candidate
unless @current_state == :NOTICED_POKEMON
playAnimation(HEART_ANIMATION_SHORT_ID, @x, @y)
end
update_state(:NOTICED_POKEMON)
@target = pokeblock_candidate
@noticed_pokemon_behavior = :eat_pokeblock
@move_type = MOVE_TYPE_TOWARDS_TARGET
self.move_frequency = 6
return
end
return if candidates.empty?
best_event, best_behavior = candidates.min_by { |_event, behavior| BEHAVIOR_PRIORITY[behavior] || 99 }
playDetectAnimation(best_behavior, false)
update_state(:NOTICED_POKEMON)
set_noticed_pokemon_movement(best_behavior, best_event)
end
def target_still_valid?
return false unless @target && !@target.erased
@currently_seen_events.any? { |event| event[0] == @target }
end
def set_noticed_pokemon_movement(behavior, target_event)
@noticed_pokemon_behavior = behavior if target_event
@target = target_event
case behavior
when :random
@move_type = MOVE_TYPE_RANDOM
self.move_frequency = @roaming_frequency
when :still
@move_type = MOVE_TYPE_FIXED
when :curious
@move_type = MOVE_TYPE_TOWARDS_TARGET
self.move_frequency = @roaming_frequency
when :semi_aggressive
@move_type = MOVE_TYPE_TOWARDS_TARGET
self.move_frequency = @roaming_frequency
when :aggressive
@move_type = MOVE_TYPE_TOWARDS_TARGET
self.move_frequency = 6
when :shy
@move_type = MOVE_TYPE_SHY_FROM_TARGET
self.move_frequency = @roaming_frequency
when :skittish
@move_type = MOVE_TYPE_AWAY_FROM_TARGET
self.move_frequency = 6
when :flee, :flee_flying, :teleport_away
flee(behavior)
else
category = @behavior_noticed ? :noticed : :roaming
set_custom_move_route(OW_BEHAVIOR_MOVE_ROUTES[category][behavior])
end
@step_anime = true unless behavior == :still
@move_speed = @noticed_move_speed
end
def update_attack_target
unless @current_state == :NOTICED_POKEMON &&
[:aggressive, :semi_aggressive, :eat_pokeblock].include?(@noticed_pokemon_behavior) &&
adjacent_to?(@target)
@attack_timer = 0
return
end
@attack_timer += 1
if @attack_timer >= 80
attack_pokemon_target
@attack_timer = 0
end
end
def attack_pokemon_target
hp_chunk = calculate_damage_on_target
# Attacks of pokemon's type 1, except if it's type 1. Then type 2 (if it has one) - so that normal/flying uses flying moves.
attack_type = @pokemon.type1 == :NORMAL && @pokemon.type2 ? @pokemon.type2 : @pokemon.type1
effectiveness = Effectiveness.calculate(attack_type, @target.pokemon.type1, @target.pokemon.type2) / 8.0
hp_chunk = (hp_chunk * effectiveness).floor
#echoln "#{attack_type} on #{@target.pokemon.type1}, #{@target.pokemon.type2} : x#{effectiveness}"
@target.pokemon.hp -= hp_chunk
flash_white(@target)
unless @target.is_a?(PokeblockEvent)
@target.knock_back(self)
@target.queue_retaliation_against(self) if @target.pokemon.hp > 0
end
if @target.pokemon.hp <= 0
@target.despawn
@target = nil
update_state(:ROAMING)
end
end
def queue_retaliation_against(attacker)
return unless attacker && !attacker.erased
@pending_retaliation_target = attacker
@retaliation_timer = RETALIATION_DELAY
end
def update_retaliation
return unless @pending_retaliation_target
unless @pending_retaliation_target.erased
@retaliation_timer -= 1
if @retaliation_timer <= 0
target = @pending_retaliation_target
@pending_retaliation_target = nil
update_state(:NOTICED_POKEMON)
set_noticed_pokemon_movement(:aggressive, target)
end
else
@pending_retaliation_target = nil
end
end
#Equivalent of a neutral base 20 damage attack
# Simplified version of PokeBattle_Move.pbCalcDamage
def calculate_damage_on_target()
baseDmg = 20
atk = @pokemon.attack
defense = @target.pokemon.defense
damage = (((2.0 * @pokemon.level / 5 + 2).floor * baseDmg * atk / defense).floor / 50).floor + 2
return damage
end
def flash_white(target, duration = 20, alpha = 200)
return unless target && $scene && $scene.respond_to?(:spriteset)
spriteset = $scene.spriteset
return unless spriteset
sprite = spriteset.character_sprites.find { |s| s.character == target }
sprite&.flash(Color.new(255, 255, 255, alpha), duration)
end
def knock_back(event_knocking_back)
turnEventTowardsEvent(self,event_knocking_back)
original_direction_fix = @direction_fix
@direction_fix = true
self.jumpBackward
#self.move_backward
@direction_fix = original_direction_fix
end
# Orthogonal adjacency check (no diagonals), same rule used when
# stopping movement toward a target in moveEventTowardsEvent.
def adjacent_to?(event)
return false unless event && !event.erased
dx = event.x - self.x
dy = event.y - self.y
(dx == 0 && dy.abs == 1) || (dy == 0 && dx.abs == 1)
end
# def update
# super
# if $game_temp.message_window_showing
# pause_movement unless @current_state == :PAUSED
# else
# update_attack_target
# update_retaliation
# @behavior_update_counter = (@behavior_update_counter || 0) + 1
# if @behavior_update_counter >= UPDATE_TIME
# @behavior_update_counter = 0
# update_behavior
# end
# end
# end
#-----------------------------------------------------------------------
# Returns the forward distance (along the facing axis) to (px, py) if it
# falls inside the vision cone, or nil if it doesn't. Returning the
# distance instead of a bool lets callers build a hash without
# recomputing dy/dx a second time.
#-----------------------------------------------------------------------
def pbConeDistanceTo(px, py, distance, spread = 1)
return nil if distance <= 0
ex = self.x
ey = self.y
case self.direction
when 2 # Facing Down
dy = py - ey
return nil if dy <= 0 || dy > distance
side = (px - ex).abs
return (side <= dy * spread) ? dy : nil
when 8 # Facing Up
dy = ey - py
return nil if dy <= 0 || dy > distance
side = (px - ex).abs
return (side <= dy * spread) ? dy : nil
when 6 # Facing Right
dx = px - ex
return nil if dx <= 0 || dx > distance
side = (py - ey).abs
return (side <= dx * spread) ? dx : nil
when 4 # Facing Left
dx = ex - px
return nil if dx <= 0 || dx > distance
side = (py - ey).abs
return (side <= dx * spread) ? dx : nil
else
return nil
end
end
# Boolean wrapper, kept so existing call sites don't need to change.
def pbPointInVisionCone?(px, py, distance, spread = 1)
!pbConeDistanceTo(px, py, distance, spread).nil?
end
def pbPlayerInEventCone?(player, distance, spread = 1)
return false if !player
pbPointInVisionCone?(player.x, player.y, distance, spread)
end
#-----------------------------------------------------------------------
# { event => distance }
#-----------------------------------------------------------------------
def listEventsInVisionCone(distance = @detection_radius, spread = 1)
seen = {}
return seen if !$game_map
#TODO: Maybe. Use this for player also and refactor player detection in base OverworldEvent
# If not too costly to run this every frame like we do for the player detection...
#
# player_distance = pbConeDistanceTo($game_player.x, $game_player.y, distance, spread)
# seen[$game_player] = player_distance if player_distance
$game_map.events.each_value do |event|
next unless event.is_a?(OverworldPokemonEvent)
next if event == self
next if event.erased
d = pbConeDistanceTo(event.x, event.y, distance, spread)
seen[event] = d if d
end
return seen
end
#-----------------------------------------------------------------------
# { event => distance }
#-----------------------------------------------------------------------
def listEventsInRadius(radius = @detection_radius)
seen = {}
return seen if !$game_map
$game_map.events.each_value do |event|
next unless event.is_a?(OverworldPokemonEvent) || event.is_a?(PokeblockEvent)
next if event == self
next if event.erased
d = pbDistanceTo(event.x, event.y, radius)
seen[event] = d if d
end
return seen
end
def pbDistanceTo(px, py, radius)
return nil if radius <= 0
dx = (px - self.x).abs
dy = (py - self.y).abs
dist = dx + dy
return (dist <= radius) ? dist : nil
end
def pbPointInRadius?(px, py, radius)
!pbDistanceTo(px, py, radius).nil?
end
def pbPlayerInEventRadius?(player, radius)
return false if !player
pbPointInRadius?(player.x, player.y, radius)
end
def check_detect_trainer
#return unless noticed_state_different_from_roaming()
return if $game_system.map_interpreter.running? || @starting
return pbPlayerInEventCone?($game_player, @detection_radius)
end
end
@@ -6,7 +6,11 @@ MOVE_TYPE_AWAY_PLAYER = 4
MOVE_TYPE_CURIOUS = 5
MOVE_TYPE_SHY = 6
class Game_Character
MOVE_TYPE_TOWARDS_TARGET = 7
MOVE_TYPE_AWAY_FROM_TARGET = 8
MOVE_TYPE_SHY_FROM_TARGET = 9
class OverworldPokemonEvent
attr_accessor :notice_icon
# @stop_count : nb frames since last movement
#wait until next frequency frame
@@ -31,30 +35,99 @@ class Game_Character
end
end
# def move_type_shy(next_movement_ready = false)
# if next_movement_ready
# move_type_away_from_player
# turn_toward_player
# end
# end
def move_type_toward_target(target_event, next_movement_ready = true)
return unless next_movement_ready
unless target_event
move_type_random
return
end
dx = (target_event.x - self.x).abs
dy = (target_event.y - self.y).abs
distance = dx + dy
# def move_type_bounce_random(frames_since_last_movement, next_movement_ready = false)
# echoln @stop_count
# if next_movement_ready
# case rand(6)
# when 0..3 then
# turn_random
# jump_forward(1)
# when 4 then
# jump_forward(1)
# when 5 then
# wait
# end
# else
# if @stop_count % 15 == 0
# jump(0, 0, false)
# end
# end
# end
if distance > 1
if rand(10) == 0
move_random
#turnEventTowardsEvent(self,target_event)
else
moveEventTowardsEvent(self, target_event)
end
return
end
if @noticed_pokemon_behavior == :curious
roll = rand(10)
if roll <= 3
turn_random
elsif roll <= 6
turnEventTowardsEvent(self, target_event)
else
wait
end
else
turnEventTowardsEvent(self, target_event)
end
end
def move_type_away_from_target(target_event)
unless target_event
move_type_random
return
end
moveEventAwayFromEvent(self, target_event)
end
def move_type_random
if Settings::EXPERIMENTAL_FEATURES && @idle_animation_sprite && rand(6)==0
play_idle_animation
else
super
end
end
def play_idle_animation
return if @playing_idle_animation
@playing_idle_animation = true
@old_character_name = @character_name
@character_name = @idle_animation_sprite
@stop_count = 0
nb_times = rand(1..3)
echoln nb_times
play_step_animation(nb_times)
end
def update_idle_animation
return unless @playing_idle_animation
total_frames = @step_animation_nb_times * 4
if @playing_idle_animation && @step_anime_once_frame_count >= total_frames
@character_name = @old_character_name
@playing_idle_animation = false
end
end
def update_notice_icon
if @current_state == :NOTICED_PLAYER && @opacity > 0 && !@notice_icon_hidden
if !@notice_icon || @notice_icon.disposed?
@notice_icon = OverworldNoticeIcon.new(self, @behavior_noticed)
end
@notice_icon.update
else
dispose_notice_icon
end
end
def hide_notice_icon
@notice_icon_hidden = true
dispose_notice_icon
end
def show_notice_icon
@notice_icon_hidden = false
end
def dispose_notice_icon
@notice_icon.dispose if @notice_icon && !@notice_icon.disposed?
@notice_icon = nil
end
end
@@ -0,0 +1,47 @@
class OverworldNoticeIcon < Sprite
DEFAULT_PATH = "Graphics/Pictures/Overworld/notice_icon"
Y_OFFSET = -12
BOB_RANGE = 1
def initialize(event, behavior = nil)
viewport = ($scene.spriteset.viewport1 rescue nil)
super(viewport)
@event = event
@frame = 0
@char_height = 32
self.bitmap = load_icon_bitmap(behavior)
self.ox = bitmap.width / 2
self.oy = bitmap.height / 2
refresh_character_height
update
end
def load_icon_bitmap(behavior)
path = pbResolveBitmap("Graphics/Pictures/Overworld/notice_#{behavior}") if behavior
path ||= pbResolveBitmap(DEFAULT_PATH)
return Bitmap.new(path) if path
return nil
end
def refresh_character_height
return unless $scene.respond_to?(:spriteset) && $scene.spriteset
spr = $scene.spriteset.character_sprites.find { |s| s.character == @event }
@char_height = spr.oy if spr && spr.oy > 0
end
def update
return if disposed?
@frame += 1
refresh_character_height if @frame % 10 == 0
bob = BOB_RANGE > 0 ? (Math.sin(@frame / 8.0) * BOB_RANGE).round : 0
self.x = @event.screen_x
self.y = @event.screen_y - @char_height - Y_OFFSET + bob
self.z = @event.screen_z + 100
self.opacity = @event.opacity
end
def dispose
self.bitmap.dispose if self.bitmap && !self.bitmap.disposed?
super
end
end
@@ -212,6 +212,12 @@ def spawn_overworld_pokemon(wild_pokemon, position, terrain, behavior_roaming =
return event
end
#Adds a pokemon to the end of the list so that it doesn't get despawned right away
def renew_overworld_pokemon(event_id)
$PokemonTemp.overworld_pokemon_on_map.delete(event_id)
$PokemonTemp.overworld_pokemon_on_map << event_id
end
def despawn_overworld_pokemon(event_id, terrain)
event = $game_map.events[event_id]
if !event
@@ -219,8 +225,7 @@ def despawn_overworld_pokemon(event_id, terrain)
return
end
if event.pokemon.shiny? # re-add it ad the end of the list instead
$PokemonTemp.overworld_pokemon_on_map.delete(event.id)
$PokemonTemp.overworld_pokemon_on_map << event.id
renew_overworld_pokemon(event.id)
event_id = $PokemonTemp.overworld_pokemon_on_map[0]
event = $game_map.events[event_id]
end
@@ -255,6 +260,7 @@ Events.onMapChanging += proc { |_sender, e|
}
def clearOverworldPokemon
return unless $game_map&.events
echoln "Clearing Overworld Pokemon"
$game_map.events.clone.each do |id, event|
if event.is_a?(DynamicOverworldPokemonEvent)
@@ -0,0 +1,28 @@
class PokeblockEvent < Game_Event
attr_accessor :pokemon
attr_accessor :color
DESPAWN_SECONDS = 60
#Level is for calculating the HP
def initialize(map_id, event, map=nil, color=:RED, level=16)
super(map_id, event, map)
@pokemon = Pokemon.new(:DITTO, level) #fake pokemon for calcualting damage when pokemon eat it
@color = color
@drain_per_frame = @pokemon.totalhp.to_f / (DESPAWN_SECONDS * Graphics.frame_rate)
@hp_float = @pokemon.hp.to_f
end
def update_opacity
@opacity = (255 * (@pokemon.hp.to_f / @pokemon.totalhp)).round
end
def update
super
return if @erased
@hp_float -= @drain_per_frame
@pokemon.hp = [@hp_float.round, 0].max
update_opacity
despawn if @pokemon.hp <= 0
end
end
@@ -1,5 +1,6 @@
OVERWORLD_POKEMON_EVENT_NAME = "OverworldPokemon"
LEGENDARY_EVENT_NAME = "Legendary"
POKEBLOCK_EVENT_NAME = "PokeBlock"
# For adding wild overworld Pokemon as static events.
#
# The event needs to have the name OverworldPokemon and be have a first comment at the top setup like this
@@ -65,6 +66,9 @@ class Game_Map
event.erase
return event
end
elsif event.name.start_with?(POKEBLOCK_EVENT_NAME)
game_event = PokeblockEvent.new(@map_id, event, self)
return game_event if game_event
end
return ow_game_map_create_new_event(event)
@@ -25,33 +25,34 @@
# :teleport_away The Pokémon flees when it sees the player with a a teleport animation and despawns
# :explode Waits a bit, then explodes (despawn)
#todo: defend. Attacks if being attacked by another ow pokemon
POKEMON_BEHAVIOR_DATA =
{
:BULBASAUR => { behavior_noticed: nil, behavior_roaming: :random },
:BULBASAUR => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:HERACROSS => :shy}},
:IVYSAUR => { behavior_noticed: nil, behavior_roaming: :random },
:VENUSAUR => { behavior_noticed: nil, behavior_roaming: :random },
:CHARMANDER => { behavior_noticed: :shy, behavior_roaming: :random },
:CHARMELEON => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CHARIZARD => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SQUIRTLE => { behavior_noticed: :curious, behavior_roaming: :random },
:SQUIRTLE => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:SHARPEDO => :skittish}},
:WARTORTLE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BLASTOISE => { behavior_noticed: nil, behavior_roaming: :random },
:CATERPIE => { behavior_noticed: :shy, behavior_roaming: :random },
:METAPOD => { behavior_noticed: :still, behavior_roaming: :still },
:BUTTERFREE => { behavior_noticed: :skittish, behavior_roaming: :random },
:BUTTERFREE => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:CUTIEFLY => :semi_aggressive, :HERACROSS => :curious}},
:WEEDLE => { behavior_noticed: :shy, behavior_roaming: :random },
:KAKUNA => { behavior_noticed: :still, behavior_roaming: :still },
:BEEDRILL => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PIDGEY => { behavior_noticed: nil, behavior_roaming: :random },
:PIDGEOTTO => { behavior_noticed: nil, behavior_roaming: :random },
:PIDGEOT => { behavior_noticed: nil, behavior_roaming: :random },
:RATTATA => { behavior_noticed: :shy, behavior_roaming: :random },
:RATICATE => { behavior_noticed: nil, behavior_roaming: :random },
:SPEAROW => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BEEDRILL => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:TEDDIURSA => :aggressive}},
:PIDGEY => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:EKANS => :shy, :SNEASEL => :skittish, :PERSIAN => :skittish}},
:PIDGEOTTO => { behavior_noticed: :semi_aggressive, behavior_roaming: :random, behavior_pokemon: {:MAGIKARP => :aggressive, :EXEGGCUTE => :aggressive, :CATERPIE => :aggressive}},
:PIDGEOT => { behavior_noticed: :semi_aggressive, behavior_roaming: :random, behavior_pokemon: {:MAGIKARP => :aggressive}},
:RATTATA => { behavior_noticed: :shy, behavior_roaming: :random , behavior_pokemon: {:GUMSHOOS => :shy, :MEOWTH => :skittish, :ALOLAN_MEOWTH => :skittish}},
:RATICATE => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:GUMSHOOS => :shy}},
:SPEAROW => { behavior_noticed: :aggressive, behavior_roaming: :random, behavior_pokemon: {:SUNKERN => :aggressive}},
:FEAROW => { behavior_noticed: :aggressive, behavior_roaming: :random },
:EKANS => { behavior_noticed: :shy, behavior_roaming: :random },
:ARBOK => { behavior_noticed: :aggressive, behavior_roaming: :random },
:EKANS => { behavior_noticed: :shy, behavior_roaming: :random , behavior_pokemon: {:PIDGEY => :semi_aggressive, :SPEAROW => :semi_aggressive}},
:ARBOK => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:WOOPER => :aggressive}},
:PIKACHU => { behavior_noticed: :curious, behavior_roaming: :random },
:RAICHU => { behavior_noticed: nil, behavior_roaming: :random },
:SANDSHREW => { behavior_noticed: :shy, behavior_roaming: :random },
@@ -74,18 +75,18 @@ POKEMON_BEHAVIOR_DATA =
:GLOOM => { behavior_noticed: nil, behavior_roaming: :random },
:VILEPLUME => { behavior_noticed: nil, behavior_roaming: :random },
:PARAS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PARASECT => { behavior_noticed: :aggressive, behavior_roaming: :random },
:VENONAT => { behavior_noticed: :shy, behavior_roaming: :random },
:PARASECT => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:SHIINOTIC => :aggressive}},
:VENONAT => { behavior_noticed: :shy, behavior_roaming: :random , behavior_pokemon: {:CATERPIE => :semi_aggressive, :WEEDLE => :semi_aggressive}},
:VENOMOTH => { behavior_noticed: :shy, behavior_roaming: :random },
:DIGLETT => { behavior_noticed: :still, behavior_roaming: :random_burrow },
:DUGTRIO => { behavior_noticed: :still, behavior_roaming: :random_burrow },
:MEOWTH => { behavior_noticed: :curious, behavior_roaming: :random },
:PERSIAN => { behavior_noticed: :aggressive, behavior_roaming: :random },
:DIGLETT => { behavior_noticed: :still, behavior_roaming: :random_burrow , behavior_pokemon: {:DRUDDIGON => :shy}},
:DUGTRIO => { behavior_noticed: :still, behavior_roaming: :random_burrow , behavior_pokemon: {:DRUDDIGON => :shy}},
:MEOWTH => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:RATTATA => :semi_aggressive, :ALOLAN_RATTATA => :semi_aggressive, :MAGIKARP => :semi_aggressive, :MURKROW => :semi_aggressive}},
:PERSIAN => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:STARLY => :semi_aggressive, :PIDGEY => :semi_aggressive, :SPEAROW => :semi_aggressive}},
:PSYDUCK => { behavior_noticed: nil, behavior_roaming: :random },
:GOLDUCK => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MANKEY => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PRIMEAPE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GROWLITHE => { behavior_noticed: :curious, behavior_roaming: :random },
:PRIMEAPE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:URSARING => :aggressive, :HAWLUCHA => :aggressive}},
:GROWLITHE => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:ROCKRUFF => :semi_aggressive}},
:ARCANINE => { behavior_noticed: nil, behavior_roaming: :random },
:POLIWAG => { behavior_noticed: :shy, behavior_roaming: :random },
:POLIWHIRL => { behavior_noticed: nil, behavior_roaming: :random },
@@ -93,16 +94,16 @@ POKEMON_BEHAVIOR_DATA =
:ABRA => { behavior_noticed: :teleport_away, behavior_roaming: :still_teleport },
:KADABRA => { behavior_noticed: :skittish, behavior_roaming: :random },
:ALAKAZAM => { behavior_noticed: nil, behavior_roaming: :random },
:MACHOP => { behavior_noticed: nil, behavior_roaming: :random },
:MACHOP => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:MAKUHITA => :semi_aggressive}},
:MACHOKE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MACHAMP => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BELLSPROUT => { behavior_noticed: :shy, behavior_roaming: :random },
:WEEPINBELL => { behavior_noticed: nil, behavior_roaming: :random },
:VICTREEBEL => { behavior_noticed: :aggressive, behavior_roaming: :random },
:TENTACOOL => { behavior_noticed: nil, behavior_roaming: :random },
:TENTACRUEL => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GEODUDE => { behavior_noticed: nil, behavior_roaming: :look_around},
:GRAVELER => { behavior_noticed: :aggressive, behavior_roaming: :random },
:TENTACOOL => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true },
:TENTACRUEL => { behavior_noticed: :aggressive, behavior_roaming: :random, glow_in_the_dark: true },
:GEODUDE => { behavior_noticed: :still, behavior_roaming: :random, hop_cliff:true},
:GRAVELER => { behavior_noticed: :aggressive, behavior_roaming: :random, hop_cliff:true },
:GOLEM => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PONYTA => { behavior_noticed: :shy, behavior_roaming: :random },
:RAPIDASH => { behavior_noticed: :aggressive, behavior_roaming: :random },
@@ -114,47 +115,47 @@ POKEMON_BEHAVIOR_DATA =
:DODUO => { behavior_noticed: :shy, behavior_roaming: :charge },
:DODRIO => { behavior_noticed: :aggressive, behavior_roaming: :charge },
:SEEL => { behavior_noticed: :curious, behavior_roaming: :random_dive },
:DEWGONG => { behavior_noticed: nil, behavior_roaming: :random_dive },
:GRIMER => { behavior_noticed: :curious, behavior_roaming: :random },
:MUK => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SHELLDER => { behavior_noticed: :skittish, behavior_roaming: :look_around },
:CLOYSTER => { behavior_noticed: nil, behavior_roaming: :random },
:DEWGONG => { behavior_noticed: nil, behavior_roaming: :random_dive , behavior_pokemon: {:WISHIWASHI => :aggressive}},
:GRIMER => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:TRUBBISH => :aggressive, :GARBODOR => :aggressive}},
:MUK => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:TRUBBISH => :aggressive, :GARBODOR => :aggressive}},
:SHELLDER => { behavior_noticed: :skittish, behavior_roaming: :look_around, behavior_pokemon: {:KINGLER => :skittish, :OMASTAR => :skittish, :RUFFLET => :skittish, :BRUXISH => :skittish, :SLOWPOKE => :curious, :SLOWBRO => :curious}},
:CLOYSTER => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:KINGLER => :shy, :SLOWPOKE => :semi_aggressive}},
:GASTLY => { behavior_noticed: :curious, behavior_roaming: :random_vanish },
:HAUNTER => { behavior_noticed: :curious, behavior_roaming: :random_vanish },
:GENGAR => { behavior_noticed: nil, behavior_roaming: :random_vanish },
:ONIX => { behavior_noticed: :aggressive, behavior_roaming: :random },
:DROWZEE => { behavior_noticed: :curious, behavior_roaming: :random },
:HYPNO => { behavior_noticed: :aggressive, behavior_roaming: :random },
:DROWZEE => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:KOMALA => :curious}},
:HYPNO => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:KOMALA => :curious}},
:KRABBY => { behavior_noticed: :skittish, behavior_roaming: :random },
:KINGLER => { behavior_noticed: :aggressive, behavior_roaming: :random },
:KINGLER => { behavior_noticed: :aggressive, behavior_roaming: :random, behavior_pokemon: {:SHELLDER => :aggressive, :CLOYSTER => :aggressive}},
:VOLTORB => { behavior_noticed: :explode, behavior_roaming: :look_around },
:ELECTRODE => { behavior_noticed: :explode, behavior_roaming: :random },
:EXEGGCUTE => { behavior_noticed: nil, behavior_roaming: :random },
:EXEGGCUTE => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:PIDGEOTTO => :shy}},
:EXEGGUTOR => { behavior_noticed: nil, behavior_roaming: :random },
:CUBONE => { behavior_noticed: nil, behavior_roaming: :random },
:MAROWAK => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CUBONE => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:VULLABY => :shy, :MANDIBUZZ => :skittish}},
:MAROWAK => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:MANDIBUZZ => :aggressive}},
:HITMONLEE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:HITMONCHAN => { behavior_noticed: :aggressive, behavior_roaming: :random },
:LICKITUNG => { behavior_noticed: nil, behavior_roaming: :random },
:KOFFING => { behavior_noticed: :explode, behavior_roaming: :random },
:WEEZING => { behavior_noticed: :aggressive, behavior_roaming: :random },
:WEEZING => { behavior_noticed: nil, behavior_roaming: :random },
:RHYHORN => { behavior_noticed: :aggressive, behavior_roaming: :charge },
:RHYDON => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CHANSEY => { behavior_noticed: :flee, behavior_roaming: :random },
:TANGELA => { behavior_noticed: nil, behavior_roaming: :random },
:KANGASKHAN => { behavior_noticed: :aggressive, behavior_roaming: :random },
:HORSEA => { behavior_noticed: :shy, behavior_roaming: :random_dive },
:SEADRA => { behavior_noticed: :aggressive, behavior_roaming: :random_dive },
:GOLDEEN => { behavior_noticed: nil, behavior_roaming: :random_dive },
:HORSEA => { behavior_noticed: :shy, behavior_roaming: :random_dive , behavior_pokemon: {:CORSOLA => :curious}},
:SEADRA => { behavior_noticed: :aggressive, behavior_roaming: :random_dive , behavior_pokemon: {:CORSOLA => :curious, :MAREANIE => :semi_aggressive, :TOXAPEX => :semi_aggressive}},
:GOLDEEN => { behavior_noticed: :semi_aggressive, behavior_roaming: :random_dive },
:SEAKING => { behavior_noticed: nil, behavior_roaming: :random_dive },
:STARYU => { behavior_noticed: nil, behavior_roaming: :random },
:STARMIE => { behavior_noticed: nil, behavior_roaming: :random },
:STARYU => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true , behavior_pokemon: {:LUMINEON => :shy, :LANTURN => :shy}},
:STARMIE => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true , behavior_pokemon: {:LUMINEON => :skittish, :LANTURN => :skittish}},
:MRMIME => { behavior_noticed: :curious, behavior_roaming: :random },
:SCYTHER => { behavior_noticed: :aggressive, behavior_roaming: :random },
:JYNX => { behavior_noticed: nil, behavior_roaming: :random },
:ELECTABUZZ => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MAGMAR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PINSIR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PINSIR => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:HERACROSS => :aggressive, :VIKAVOLT => :aggressive}},
:TAUROS => { behavior_noticed: :aggressive, behavior_roaming: :charge },
:MAGIKARP => { behavior_noticed: nil, behavior_roaming: :random },
:GYARADOS => { behavior_noticed: :aggressive, behavior_roaming: :random },
@@ -165,8 +166,8 @@ POKEMON_BEHAVIOR_DATA =
:JOLTEON => { behavior_noticed: :shy, behavior_roaming: :random },
:FLAREON => { behavior_noticed: :shy, behavior_roaming: :random },
:PORYGON => { behavior_noticed: nil, behavior_roaming: :random },
:OMANYTE => { behavior_noticed: :shy, behavior_roaming: :random },
:OMASTAR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:OMANYTE => { behavior_noticed: :shy, behavior_roaming: :random , behavior_pokemon: {:CARRACOSTA => :shy, :ARCHEOPS => :skittish}},
:OMASTAR => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:SHELLDER => :semi_aggressive, :CARRACOSTA => :shy}},
:KABUTO => { behavior_noticed: :shy, behavior_roaming: :random },
:KABUTOPS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:AERODACTYL => { behavior_noticed: :aggressive, behavior_roaming: :random },
@@ -176,7 +177,7 @@ POKEMON_BEHAVIOR_DATA =
:MOLTRES => { behavior_noticed: :aggressive, behavior_roaming: :random },
:DRATINI => { behavior_noticed: :skittish, behavior_roaming: :random },
:DRAGONAIR => { behavior_noticed: :skittish, behavior_roaming: :random },
:DRAGONITE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:DRAGONITE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:KINGDRA => :aggressive}},
:MEWTWO => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MEW => { behavior_noticed: :flee, behavior_roaming: :random },
:CHIKORITA => { behavior_noticed: :curious, behavior_roaming: :random },
@@ -189,7 +190,7 @@ POKEMON_BEHAVIOR_DATA =
:CROCONAW => { behavior_noticed: :aggressive, behavior_roaming: :random },
:FERALIGATR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SENTRET => { behavior_noticed: nil, behavior_roaming: :random },
:FURRET => { behavior_noticed: nil, behavior_roaming: :random },
:FURRET => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:RATTATA => :aggressive, :MIGHTYENA => :skittish}},
:HOOTHOOT => { behavior_noticed: :shy, behavior_roaming: :random },
:NOCTOWL => { behavior_noticed: nil, behavior_roaming: :random },
:LEDYBA => { behavior_noticed: nil, behavior_roaming: :random },
@@ -197,10 +198,10 @@ POKEMON_BEHAVIOR_DATA =
:SPINARAK => { behavior_noticed: nil, behavior_roaming: :random },
:ARIADOS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CROBAT => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CHINCHOU => { behavior_noticed: nil, behavior_roaming: :random },
:LANTURN => { behavior_noticed: nil, behavior_roaming: :random },
:CHINCHOU => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true , behavior_pokemon: {:INKAY => :shy}},
:LANTURN => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true , behavior_pokemon: {:SHARPEDO => :skittish, :STARMIE => :aggressive, :FRILLISHfE => :shy, :FRILLISHmA => :shy}},
:PICHU => { behavior_noticed: :curious, behavior_roaming: :random },
:CLEFFA => { behavior_noticed: :curious, behavior_roaming: :random },
:CLEFFA => { behavior_noticed: :shy, behavior_roaming: :random },
:IGGLYBUFF => { behavior_noticed: :curious, behavior_roaming: :random, behavior_wind_roaming: :blown_away },
:TOGEPI => { behavior_noticed: :curious, behavior_roaming: :random },
:TOGETIC => { behavior_noticed: :curious, behavior_roaming: :random },
@@ -217,15 +218,15 @@ POKEMON_BEHAVIOR_DATA =
:HOPPIP => { behavior_noticed: nil, behavior_roaming: :random, behavior_wind_roaming: :blown_away},
:SKIPLOOM => { behavior_noticed: nil, behavior_roaming: :random, behavior_wind_roaming: :blown_away },
:JUMPLUFF => { behavior_noticed: nil, behavior_roaming: :random, behavior_wind_roaming: :blown_away },
:AIPOM => { behavior_noticed: :curious, behavior_roaming: :random },
:AIPOM => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:BOUNSWEET => :semi_aggressive}},
:SUNKERN => { behavior_noticed: nil, behavior_roaming: :random, behavior_sunny_roaming: :random_spin},
:SUNFLORA => { behavior_noticed: nil, behavior_roaming: :random, behavior_sunny_roaming: :random_spin },
:YANMA => { behavior_noticed: nil, behavior_roaming: :random },
:WOOPER => { behavior_noticed: nil, behavior_roaming: :random },
:WOOPER => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:ARBOK => :shy}},
:QUAGSIRE => { behavior_noticed: nil, behavior_roaming: :random },
:ESPEON => { behavior_noticed: nil, behavior_roaming: :random },
:UMBREON => { behavior_noticed: nil, behavior_roaming: :random },
:MURKROW => { behavior_noticed: :aggressive, behavior_roaming: :random },
:UMBREON => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true },
:MURKROW => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:MEOWTH => :semi_aggressive, :ALOLAN_MEOWTH => :semi_aggressive}},
:SLOWKING => { behavior_noticed: nil, behavior_roaming: :random },
:MISDREAVUS => { behavior_noticed: :curious, behavior_roaming: :random_vanish },
:UNOWN => { behavior_noticed: :flee, behavior_roaming: :random },
@@ -238,26 +239,26 @@ POKEMON_BEHAVIOR_DATA =
:STEELIX => { behavior_noticed: nil, behavior_roaming: :random },
:SNUBBULL => { behavior_noticed: nil, behavior_roaming: :random },
:GRANBULL => { behavior_noticed: :aggressive, behavior_roaming: :random },
:QWILFISH => { behavior_noticed: :aggressive, behavior_roaming: :random },
:QWILFISH => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:LUVDISC => :aggressive}},
:SCIZOR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SHUCKLE => { behavior_noticed: :still, behavior_roaming: :random },
:HERACROSS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SNEASEL => { behavior_noticed: :skittish, behavior_roaming: :random },
:TEDDIURSA => { behavior_noticed: :curious, behavior_roaming: :random },
:URSARING => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SLUGMA => { behavior_noticed: nil, behavior_roaming: :random },
:MAGCARGO => { behavior_noticed: nil, behavior_roaming: :random },
:HERACROSS => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:PINSIR => :aggressive, :VIKAVOLT => :aggressive, :BULBASAUR => :curious, :BUTTERFREE => :curious}},
:SNEASEL => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:PIDGEY => :aggressive, :ALOLAN_SANDSHREW => :semi_aggressive, :DELIBIRD => :aggressive}},
:TEDDIURSA => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:COMBEE => :curious}},
:URSARING => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:PRIMEAPE => :aggressive}},
:SLUGMA => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true},
:MAGCARGO => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true },
:SWINUB => { behavior_noticed: :shy, behavior_roaming: :random },
:PILOSWINE => { behavior_noticed: nil, behavior_roaming: :random },
:CORSOLA => { behavior_noticed: nil, behavior_roaming: :random },
:REMORAID => { behavior_noticed: nil, behavior_roaming: :random },
:CORSOLA => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:MAREANIE => :skittish, :TOXAPEX => :skittish, :SEADRA => :curious}},
:REMORAID => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:BURMY_P => :semi_aggressive, :BURMY_S => :semi_aggressive, :BURMY_T => :semi_aggressive, :MANTINE => :curious}},
:OCTILLERY => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:DELIBIRD => { behavior_noticed: :curious, behavior_roaming: :random },
:DELIBIRD => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:SNEASEL => :shy}},
:MANTINE => { behavior_noticed: nil, behavior_roaming: :random },
:SKARMORY => { behavior_noticed: :aggressive, behavior_roaming: :random },
:HOUNDOUR => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:HOUNDOOM => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:KINGDRA => { behavior_noticed: nil, behavior_roaming: :random },
:KINGDRA => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:DRAGONITE => :aggressive}},
:PHANPY => { behavior_noticed: nil, behavior_roaming: :random },
:DONPHAN => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PORYGON2 => { behavior_noticed: nil, behavior_roaming: :random },
@@ -266,7 +267,7 @@ POKEMON_BEHAVIOR_DATA =
:TYROGUE => { behavior_noticed: nil, behavior_roaming: :random },
:HITMONTOP => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SMOOCHUM => { behavior_noticed: :curious, behavior_roaming: :random },
:ELEKID => { behavior_noticed: :curious, behavior_roaming: :random },
:ELEKID => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:TOGEDEMARU => :semi_aggressive}},
:MAGBY => { behavior_noticed: :skittish, behavior_roaming: :random },
:MILTANK => { behavior_noticed: nil, behavior_roaming: :random },
:BLISSEY => { behavior_noticed: :curious, behavior_roaming: :random },
@@ -288,13 +289,13 @@ POKEMON_BEHAVIOR_DATA =
:MUDKIP => { behavior_noticed: :curious, behavior_roaming: :random },
:MARSHTOMP => { behavior_noticed: nil, behavior_roaming: :random },
:SWAMPERT => { behavior_noticed: nil, behavior_roaming: :random },
:POOCHYENA => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:MIGHTYENA => { behavior_noticed: :aggressive, behavior_roaming: :random },
:POOCHYENA => { behavior_noticed: :semi_aggressive, behavior_roaming: :random, behavior_pokemon: {:everything => :semi_aggressive} },
:MIGHTYENA => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:FURRET => :aggressive}},
:ZIGZAGOON => { behavior_noticed: :curious, behavior_roaming: :random },
:LINOONE => { behavior_noticed: nil, behavior_roaming: :random },
:WURMPLE => { behavior_noticed: :shy, behavior_roaming: :random },
:WURMPLE => { behavior_noticed: :shy, behavior_roaming: :random , behavior_pokemon: {:SWELLOW => :shy}},
:SILCOON => { behavior_noticed: :still, behavior_roaming: :still },
:BEAUTIFLY => { behavior_noticed: :skittish, behavior_roaming: :random },
:BEAUTIFLY => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:COMBEE => :semi_aggressive}},
:CASCOON => { behavior_noticed: :still, behavior_roaming: :still },
:DUSTOX => { behavior_noticed: :skittish, behavior_roaming: :random },
:LOTAD => { behavior_noticed: :shy, behavior_roaming: :random },
@@ -303,15 +304,15 @@ POKEMON_BEHAVIOR_DATA =
:SEEDOT => { behavior_noticed: :still, behavior_roaming: :random },
:NUZLEAF => { behavior_noticed: nil, behavior_roaming: :random },
:SHIFTRY => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:TAILLOW => { behavior_noticed: :skittish, behavior_roaming: :random },
:SWELLOW => { behavior_noticed: :skittish, behavior_roaming: :random },
:WINGULL => { behavior_noticed: :flee_flying, behavior_roaming: :random },
:PELIPPER => { behavior_noticed: nil, behavior_roaming: :random },
:TAILLOW => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:WURMPLE => :aggressive}},
:SWELLOW => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:WURMPLE => :aggressive}},
:WINGULL => { behavior_noticed: :flee_flying, behavior_roaming: :random , behavior_pokemon: {:FINNEON => :aggressive, :WISHIWASHI => :aggressive, :TALONFLAME => :skittish}},
:PELIPPER => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:LUVDISC => :aggressive, :WISHIWASHI => :aggressive}},
:RALTS => { behavior_noticed: :teleport_away, behavior_roaming: :random },
:KIRLIA => { behavior_noticed: :skittish, behavior_roaming: :random },
:GARDEVOIR => { behavior_noticed: nil, behavior_roaming: :random },
:GALLADE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SURSKIT => { behavior_noticed: nil, behavior_roaming: :water_skip },
:SURSKIT => { behavior_noticed: nil, behavior_roaming: :water_skip , behavior_pokemon: {:DEWPIDER => :semi_aggressive}},
:MASQUERAIN => { behavior_noticed: :skittish, behavior_roaming: :random },
:SHROOMISH => { behavior_noticed: :still, behavior_roaming: :random },
:BRELOOM => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
@@ -323,14 +324,14 @@ POKEMON_BEHAVIOR_DATA =
:SHEDINJA => { behavior_noticed: :still, behavior_roaming: :still },
:WHISMUR => { behavior_noticed: :shy, behavior_roaming: :random },
:LOUDRED => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:EXPLOUD => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MAKUHITA => { behavior_noticed: :curious, behavior_roaming: :random },
:EXPLOUD => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:AXEW => :semi_aggressive}},
:MAKUHITA => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:MACHOP => :semi_aggressive}},
:HARIYAMA => { behavior_noticed: nil, behavior_roaming: :random },
:AZURILL => { behavior_noticed: :shy, behavior_roaming: :random },
:NOSEPASS => { behavior_noticed: :still, behavior_roaming: :still },
:SKITTY => { behavior_noticed: :curious, behavior_roaming: :random },
:DELCATTY => { behavior_noticed: nil, behavior_roaming: :random },
:SABLEYE => { behavior_noticed: :curious, behavior_roaming: :random },
:SABLEYE => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:CARBINK => :semi_aggressive, :GABITE => :semi_aggressive}},
:MAWILE => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:ARON => { behavior_noticed: :aggressive, behavior_roaming: :charge },
:LAIRON => { behavior_noticed: :aggressive, behavior_roaming: :charge },
@@ -341,30 +342,30 @@ POKEMON_BEHAVIOR_DATA =
:MANECTRIC => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PLUSLE => { behavior_noticed: :curious, behavior_roaming: :random },
:MINUN => { behavior_noticed: :curious, behavior_roaming: :random },
:VOLBEAT => { behavior_noticed: nil, behavior_roaming: :random },
:ILLUMISE => { behavior_noticed: nil, behavior_roaming: :random },
:VOLBEAT => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true },
:ILLUMISE => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true },
:ROSELIA => { behavior_noticed: nil, behavior_roaming: :random },
:GULPIN => { behavior_noticed: nil, behavior_roaming: :random },
:SWALOT => { behavior_noticed: nil, behavior_roaming: :random },
:CARVANHA => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SHARPEDO => { behavior_noticed: :aggressive, behavior_roaming: :random },
:WAILMER => { behavior_noticed: :curious, behavior_roaming: :random },
:WAILORD => { behavior_noticed: nil, behavior_roaming: :random },
:CARVANHA => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:BASCULIN => :aggressive}},
:SHARPEDO => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:WAILMER => :aggressive, :SQUIRTLE => :aggressive, :LANTURN => :aggressive, :FINNEON => :aggressive, :LUMINEON => :aggressive}},
:WAILMER => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:WISHIWASHI => :semi_aggressive, :SHARPEDO => :skittish, :DHELMISE => :shy}},
:WAILORD => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:WISHIWASHI_SCHOOL => :semi_aggressive}},
:NUMEL => { behavior_noticed: nil, behavior_roaming: :random },
:CAMERUPT => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:TORKOAL => { behavior_noticed: :still, behavior_roaming: :look_around },
:SPOINK => { behavior_noticed: :curious, behavior_roaming: :random },
:SPOINK => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:CLAMPERL => :semi_aggressive}},
:GRUMPIG => { behavior_noticed: nil, behavior_roaming: :random },
:SPINDA => { behavior_noticed: :curious, behavior_roaming: :random_spin },
:TRAPINCH => { behavior_noticed: :still, behavior_roaming: :random },
:VIBRAVA => { behavior_noticed: nil, behavior_roaming: :random },
:FLYGON => { behavior_noticed: nil, behavior_roaming: :random },
:FLYGON => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:KROOKODILE => :curious}},
:CACNEA => { behavior_noticed: nil, behavior_roaming: :random },
:CACTURNE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SWABLU => { behavior_noticed: :skittish, behavior_roaming: :random },
:ALTARIA => { behavior_noticed: nil, behavior_roaming: :random },
:ZANGOOSE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SEVIPER => { behavior_noticed: :aggressive, behavior_roaming: :random },
:ZANGOOSE => { behavior_noticed: :aggressive, behavior_roaming: :random, behavior_pokemon: {:SEVIPER => :aggressive}},
:SEVIPER => { behavior_noticed: :aggressive, behavior_roaming: :random, behavior_pokemon: {:ZANGOOSE => :aggressive}},
:LUNATONE => { behavior_noticed: :still, behavior_roaming: :random },
:SOLROCK => { behavior_noticed: :still, behavior_roaming: :random },
:BARBOACH => { behavior_noticed: nil, behavior_roaming: :random },
@@ -392,7 +393,7 @@ POKEMON_BEHAVIOR_DATA =
:ABSOL => { behavior_noticed: :skittish, behavior_roaming: :random },
:WYNAUT => { behavior_noticed: :curious, behavior_roaming: :random },
:SNORUNT => { behavior_noticed: :skittish, behavior_roaming: :random },
:GLALIE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GLALIE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:VANILLITE => :aggressive}},
:FROSLASS => { behavior_noticed: :skittish, behavior_roaming: :random_vanish },
:SPHEAL => { behavior_noticed: :curious, behavior_roaming: :random },
:SEALEO => { behavior_noticed: nil, behavior_roaming: :random },
@@ -401,12 +402,12 @@ POKEMON_BEHAVIOR_DATA =
:HUNTAIL => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GOREBYSS => { behavior_noticed: nil, behavior_roaming: :random },
:RELICANTH => { behavior_noticed: :still, behavior_roaming: :random },
:LUVDISC => { behavior_noticed: :curious, behavior_roaming: :random },
:LUVDISC => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:PELIPPER => :skittish, :QWILFISH => :skittish, :CORSOLA => :curious}},
:BAGON => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:SHELGON => { behavior_noticed: :still, behavior_roaming: :random },
:SALAMENCE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SALAMENCE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:GARCHOMP => :aggressive}},
:BELDUM => { behavior_noticed: :still, behavior_roaming: :random },
:METANG => { behavior_noticed: nil, behavior_roaming: :random },
:METANG => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:NOSEPASS => :excited}},
:METAGROSS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:REGIROCK => { behavior_noticed: :still, behavior_roaming: :look_around },
:REGICE => { behavior_noticed: :still, behavior_roaming: :look_around },
@@ -427,7 +428,7 @@ POKEMON_BEHAVIOR_DATA =
:PIPLUP => { behavior_noticed: nil, behavior_roaming: :random },
:PRINPLUP => { behavior_noticed: nil, behavior_roaming: :random },
:EMPOLEON => { behavior_noticed: nil, behavior_roaming: :random },
:STARLY => { behavior_noticed: :skittish, behavior_roaming: :random },
:STARLY => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:WURMPLE => :aggressive, :CHERUBI => :semi_aggressive, :WORMADAM_P => :semi_aggressive, :WORMADAM_S => :semi_aggressive, :WORMADAM_T => :semi_aggressive, :SCATTERBUG => :aggressive, :PERSIAN => :skittish, :GROTLE => :curious}},
:STARAVIA => { behavior_noticed: :aggressive, behavior_roaming: :random },
:STARAPTOR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BIDOOF => { behavior_noticed: nil, behavior_roaming: :random },
@@ -446,10 +447,10 @@ POKEMON_BEHAVIOR_DATA =
:BURMY_P => { behavior_noticed: :shy, behavior_roaming: :still },
:BURMY_S => { behavior_noticed: :shy, behavior_roaming: :still },
:BURMY_T => { behavior_noticed: :shy, behavior_roaming: :still },
:WORMADAM_P => { behavior_noticed: :still, behavior_roaming: :still },
:WORMADAM_P => { behavior_noticed: :still, behavior_roaming: :still , behavior_pokemon: {:STARLY => :skittish}},
:WORMADAM_S => { behavior_noticed: :still, behavior_roaming: :still },
:WORMADAM_T => { behavior_noticed: :still, behavior_roaming: :still },
:MOTHIM => { behavior_noticed: :curious, behavior_roaming: :random },
:WORMADAM_T => { behavior_noticed: :still, behavior_roaming: :still , behavior_pokemon: {:STARLY => :shy}},
:MOTHIM => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:COMBEE => :curious}},
:COMBEE => { behavior_noticed: :skittish, behavior_roaming: :random },
:VESPIQUEN => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PACHIRISU => { behavior_noticed: :curious, behavior_roaming: :random },
@@ -462,9 +463,9 @@ POKEMON_BEHAVIOR_DATA =
:SHELLOS_W => { behavior_noticed: nil, behavior_roaming: :random },
:GASTRODON_E => { behavior_noticed: nil, behavior_roaming: :random },
:GASTRODON_W => { behavior_noticed: nil, behavior_roaming: :random },
:AMBIPOM => { behavior_noticed: :curious, behavior_roaming: :random },
:DRIFLOON => { behavior_noticed: :curious, behavior_roaming: :random, behavior_wind_roaming: :blown_away },
:DRIFBLIM => { behavior_noticed: :curious, behavior_roaming: :random },
:AMBIPOM => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:PASSIMIAN => :semi_aggressive}},
:DRIFLOON => { behavior_noticed: :curious, behavior_roaming: :random, behavior_wind_roaming: :blown_away , behavior_pokemon: {:JOLTIK => :semi_aggressive}},
:DRIFBLIM => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:CLAMPERL => :semi_aggressive}},
:BUNEARY => { behavior_noticed: :skittish, behavior_roaming: :random },
:LOPUNNY => { behavior_noticed: nil, behavior_roaming: :random },
:MISMAGIUS => { behavior_noticed: :curious, behavior_roaming: :random },
@@ -483,8 +484,8 @@ POKEMON_BEHAVIOR_DATA =
:CHATOT => { behavior_noticed: :curious, behavior_roaming: :random },
:SPIRITOMB => { behavior_noticed: :still, behavior_roaming: :still },
:GIBLE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GABITE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GARCHOMP => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GABITE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:SABLEYE => :semi_aggressive}},
:GARCHOMP => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:SALAMENCE => :aggressive}},
:MUNCHLAX => { behavior_noticed: :curious, behavior_roaming: :random },
:RIOLU => { behavior_noticed: :curious, behavior_roaming: :random },
:LUCARIO => { behavior_noticed: :aggressive, behavior_roaming: :random },
@@ -495,11 +496,11 @@ POKEMON_BEHAVIOR_DATA =
:CROAGUNK => { behavior_noticed: :curious, behavior_roaming: :random },
:TOXICROAK => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CARNIVINE => { behavior_noticed: :aggressive, behavior_roaming: :look_around },
:FINNEON => { behavior_noticed: :skittish, behavior_roaming: :random },
:LUMINEON => { behavior_noticed: nil, behavior_roaming: :random },
:SNOVER => { behavior_noticed: nil, behavior_roaming: :random },
:FINNEON => { behavior_noticed: :skittish, behavior_roaming: :random, glow_in_the_dark: true , behavior_pokemon: {:WINGULL => :shy, :SHARPEDO => :skittish}},
:LUMINEON => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true , behavior_pokemon: {:STARYU => :semi_aggressive, :SHARPEDO => :skittish, :CLAMPERL => :semi_aggressive}},
:SNOVER => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:STARMIE => :aggressive}},
:ABOMASNOW => { behavior_noticed: :aggressive, behavior_roaming: :random },
:WEAVILE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:WEAVILE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:ALOLAN_SANDSHREW => :aggressive, :ALOLAN_VULPIX => :aggressive, :MAMOSWINE => :aggressive}},
:MAGNEZONE => { behavior_noticed: :still, behavior_roaming: :random },
:LICKILICKY => { behavior_noticed: nil, behavior_roaming: :random },
:RHYFERIOR => { behavior_noticed: :aggressive, behavior_roaming: :random },
@@ -559,7 +560,7 @@ POKEMON_BEHAVIOR_DATA =
:UNFEZANT => { behavior_noticed: nil, behavior_roaming: :random },
:BLITZLE => { behavior_noticed: nil, behavior_roaming: :random },
:ZEBSTRIKA => { behavior_noticed: :aggressive, behavior_roaming: :random },
:ROGGENROLA => { behavior_noticed: :still, behavior_roaming: :look_around },
:ROGGENROLA => { behavior_noticed: :still, behavior_roaming: :look_around , behavior_pokemon: {:DWEBBLE => :shy}},
:BOLDORE => { behavior_noticed: :still, behavior_roaming: :look_around },
:GIGALITH => { behavior_noticed: :still, behavior_roaming: :look_around },
:WOOBAT => { behavior_noticed: :curious, behavior_roaming: :random },
@@ -581,19 +582,19 @@ POKEMON_BEHAVIOR_DATA =
:VENIPEDE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:WHIRLIPEDE => { behavior_noticed: :still, behavior_roaming: :charge },
:SCOLIPEDE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:COTTONEE => { behavior_noticed: :skittish, behavior_roaming: :random },
:COTTONEE => { behavior_noticed: :skittish, behavior_roaming: :random, behavior_wind_roaming: :blown_away },
:WHIMSICOTT => { behavior_noticed: :curious, behavior_roaming: :random },
:PETILIL => { behavior_noticed: :shy, behavior_roaming: :random },
:LILLIGANT => { behavior_noticed: nil, behavior_roaming: :random_spin },
:BASCULIN => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SANDILE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BASCULIN => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:CARVANHA => :aggressive}},
:SANDILE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:TRAPINCH => :semi_aggressive}},
:KROKOROK => { behavior_noticed: :aggressive, behavior_roaming: :random },
:KROOKODILE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:KROOKODILE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:FLYGON => :curious}},
:DARUMAKA => { behavior_noticed: :curious, behavior_roaming: :random },
:DARMANITAN => { behavior_noticed: nil, behavior_roaming: :random },
:DARMANITAN_ZEN => { behavior_noticed: :still, behavior_roaming: :still },
:MARACTUS => { behavior_noticed: nil, behavior_roaming: :random },
:DWEBBLE => { behavior_noticed: :shy, behavior_roaming: :random },
:DWEBBLE => { behavior_noticed: :skittish, behavior_roaming: :still , behavior_pokemon: {:ROGGENROLA => :semi_aggressive, :HIPPOWDON => :curious}},
:CRUSTLE => { behavior_noticed: :still, behavior_roaming: :random },
:SCRAGGY => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SCRAFTY => { behavior_noticed: :aggressive, behavior_roaming: :random },
@@ -601,11 +602,11 @@ POKEMON_BEHAVIOR_DATA =
:YAMASK => { behavior_noticed: :skittish, behavior_roaming: :random },
:COFAGRIGUS => { behavior_noticed: :still, behavior_roaming: :random },
:TIRTOUGA => { behavior_noticed: nil, behavior_roaming: :random },
:CARRACOSTA => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CARRACOSTA => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:OMANYTE => :semi_aggressive, :OMASTAR => :semi_aggressive}},
:ARCHEN => { behavior_noticed: :skittish, behavior_roaming: :random },
:ARCHEOPS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:TRUBBISH => { behavior_noticed: :curious, behavior_roaming: :random },
:GARBODOR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:ARCHEOPS => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:OMANYTE => :aggressive}},
:TRUBBISH => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:ALOLAN_GRIMER => :skittish, :ALOLAN_MUK => :skittish, :GRIMER => :skittish, :MUK => :skittish}},
:GARBODOR => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:ALOLAN_GRIMER => :shy, :ALOLAN_MUK => :shy, :GRIMER => :shy, :MUK => :shy}},
:ZORUA => { behavior_noticed: :flee, behavior_roaming: :random },
:ZOROARK => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MINCCINO => { behavior_noticed: :curious, behavior_roaming: :random },
@@ -618,25 +619,25 @@ POKEMON_BEHAVIOR_DATA =
:REUNICLUS => { behavior_noticed: nil, behavior_roaming: :random },
:DUCKLETT => { behavior_noticed: :skittish, behavior_roaming: :random },
:SWANNA => { behavior_noticed: nil, behavior_roaming: :random },
:VANILLITE => { behavior_noticed: nil, behavior_roaming: :random },
:VANILLITE => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:GLALIE => :skittish}},
:VANILLISH => { behavior_noticed: nil, behavior_roaming: :random },
:VANILLUXE => { behavior_noticed: nil, behavior_roaming: :random },
:DEERLING_SPRING => { behavior_noticed: :skittish, behavior_roaming: :random },
:DEERLING_SUMMER => { behavior_noticed: :skittish, behavior_roaming: :random },
:DEERLING_AUTUMN => { behavior_noticed: :skittish, behavior_roaming: :random },
:DEERLING_WINTER => { behavior_noticed: :skittish, behavior_roaming: :random },
:DEERLING_SPRING => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:LYCANROC_D => :skittish, :LYCANROC_DUSK => :skittish, :LYCANROC_N => :skittish}},
:DEERLING_SUMMER => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:LYCANROC_D => :skittish, :LYCANROC_DUSK => :skittish, :LYCANROC_N => :skittish}},
:DEERLING_AUTUMN => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:LYCANROC_D => :skittish, :LYCANROC_DUSK => :skittish, :LYCANROC_N => :skittish}},
:DEERLING_WINTER => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:LYCANROC_D => :skittish, :LYCANROC_DUSK => :skittish, :LYCANROC_N => :skittish}},
:SAWSBUCK_SPRING => { behavior_noticed: nil, behavior_roaming: :random },
:SAWSBUCK_SUMMER => { behavior_noticed: nil, behavior_roaming: :random },
:SAWSBUCK_AUTUMN => { behavior_noticed: nil, behavior_roaming: :random },
:SAWSBUCK_WINTER => { behavior_noticed: nil, behavior_roaming: :random },
:EMOLGA => { behavior_noticed: :skittish, behavior_roaming: :random },
:KARRABLAST => { behavior_noticed: :aggressive, behavior_roaming: :random },
:ESCAVALIER => { behavior_noticed: nil, behavior_roaming: :random },
:KARRABLAST => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:SHELMET => :semi_aggressive}},
:ESCAVALIER => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:SHELMET => :semi_aggressive}},
:FOONGUS => { behavior_noticed: :still, behavior_roaming: :random },
:AMOONGUSS => { behavior_noticed: :still, behavior_roaming: :random },
:FRILLISH => { behavior_noticed: :skittish, behavior_roaming: :random },
:JELLICENT => { behavior_noticed: nil, behavior_roaming: :random },
:JOLTIK => { behavior_noticed: nil, behavior_roaming: :random },
:JELLICENT => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:JOLTIK => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:PIKACHU => :semi_aggressive, :STUNFISK => :semi_aggressive, :EMOLGA => :semi_aggressive}},
:GALVANTULA => { behavior_noticed: nil, behavior_roaming: :random },
:FERROSEED => { behavior_noticed: nil, behavior_roaming: :random },
:FERROTHORN => { behavior_noticed: nil, behavior_roaming: :random },
@@ -652,27 +653,27 @@ POKEMON_BEHAVIOR_DATA =
:LAMPENT => { behavior_noticed: nil, behavior_roaming: :random },
:CHANDELURE => { behavior_noticed: nil, behavior_roaming: :random },
:AXEW => { behavior_noticed: :semi_aggressive, behavior_roaming: :random },
:FRAXURE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:FRAXURE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:BISHARP => :aggressive}},
:HAXORUS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CUBCHOO => { behavior_noticed: :curious, behavior_roaming: :random },
:BEARTIC => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BEARTIC => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:MAGIKARP => :semi_aggressive}},
:CRYOGONAL => { behavior_noticed: nil, behavior_roaming: :random },
:SHELMET => { behavior_noticed: nil, behavior_roaming: :random },
:ACCELGOR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:STUNFISK => { behavior_noticed: :shy, behavior_roaming: :still },
:MIENFOO => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MIENSHAO => { behavior_noticed: :aggressive, behavior_roaming: :random },
:DRUDDIGON => { behavior_noticed: :aggressive, behavior_roaming: :random },
:DRUDDIGON => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:ALOLAN_DIGLETT => :semi_aggressive, :ALOLAN_DUGTRIO => :semi_aggressive, :DIGLETT => :semi_aggressive, :DUGTRIO => :semi_aggressive}},
:GOLETT => { behavior_noticed: nil, behavior_roaming: :random },
:GOLURK => { behavior_noticed: nil, behavior_roaming: :random },
:PAWNIARD => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BISHARP => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BISHARP => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:FRAXURE => :aggressive}},
:BOUFFALANT => { behavior_noticed: :aggressive, behavior_roaming: :random },
:RUFFLET => { behavior_noticed: :aggressive, behavior_roaming: :random },
:RUFFLET => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:SHELLDER => :aggressive, :SPEWPA => :semi_aggressive}},
:BRAVIARY => { behavior_noticed: :aggressive, behavior_roaming: :random },
:VULLABY => { behavior_noticed: :skittish, behavior_roaming: :random },
:MANDIBUZZ => { behavior_noticed: :aggressive, behavior_roaming: :random },
:HEATMOR => { behavior_noticed: nil, behavior_roaming: :random },
:MANDIBUZZ => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:CUBONE => :aggressive}},
:HEATMOR => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:DURANT => :aggressive}},
:DURANT => { behavior_noticed: :aggressive, behavior_roaming: :random },
:DEINO => { behavior_noticed: :aggressive, behavior_roaming: :random },
:ZWEILOUS => { behavior_noticed: :aggressive, behavior_roaming: :random },
@@ -706,19 +707,19 @@ POKEMON_BEHAVIOR_DATA =
:GRENINJA => { behavior_noticed: nil, behavior_roaming: :random },
:BUNNELBY => { behavior_noticed: nil, behavior_roaming: :random },
:DIGGERSBY => { behavior_noticed: :aggressive, behavior_roaming: :random },
:FLETCHLING => { behavior_noticed: :skittish, behavior_roaming: :random },
:FLETCHINDER => { behavior_noticed: :aggressive, behavior_roaming: :random },
:TALONFLAME => { behavior_noticed: :aggressive, behavior_roaming: :random },
:FLETCHLING => { behavior_noticed: :curious, behavior_roaming: :random },
:FLETCHINDER => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:PIKIPEK => :aggressive}},
:TALONFLAME => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:WINGULL => :aggressive, :PIKIPEK => :aggressive}},
:SCATTERBUG => { behavior_noticed: :shy, behavior_roaming: :random },
:SPEWPA => { behavior_noticed: :still, behavior_roaming: :still },
:VIVILLON => { behavior_noticed: :skittish, behavior_roaming: :random },
:LITLEO => { behavior_noticed: :curious, behavior_roaming: :random },
:PYROAR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:FLABEBE => { behavior_noticed: nil, behavior_roaming: :random },
:FLOETTE => { behavior_noticed: nil, behavior_roaming: :random },
:FLORGES => { behavior_noticed: nil, behavior_roaming: :random },
:SKIDDO => { behavior_noticed: :curious, behavior_roaming: :random },
:GOGOAT => { behavior_noticed: nil, behavior_roaming: :random },
:FLABEBE => { behavior_noticed: :curious, behavior_roaming: :random },
:FLOETTE => { behavior_noticed: :curious, behavior_roaming: :random },
:FLORGES => { behavior_noticed: :curious, behavior_roaming: :random },
:SKIDDO => { behavior_noticed: :curious, behavior_roaming: :random, hop_cliff:true},
:GOGOAT => { behavior_noticed: nil, behavior_roaming: :random, hop_cliff:true},
:PANCHAM => { behavior_noticed: :curious, behavior_roaming: :random },
:PANGORO => { behavior_noticed: :aggressive, behavior_roaming: :random },
:FURFROU => { behavior_noticed: nil, behavior_roaming: :random },
@@ -732,12 +733,12 @@ POKEMON_BEHAVIOR_DATA =
:AROMATISSE => { behavior_noticed: nil, behavior_roaming: :random },
:SWIRLIX => { behavior_noticed: :curious, behavior_roaming: :random },
:SLURPUFF => { behavior_noticed: :curious, behavior_roaming: :random },
:INKAY => { behavior_noticed: :curious, behavior_roaming: :random },
:INKAY => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:CHINCHOU => :semi_aggressive}},
:MALAMAR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BINACLE => { behavior_noticed: :still, behavior_roaming: :look_around },
:BARBARACLE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SKRELP => { behavior_noticed: nil, behavior_roaming: :random },
:DRAGALGE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SKRELP => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:DHELMISE => :curious}},
:DRAGALGE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:DHELMISE => :curious}},
:CLAUNCHER => { behavior_noticed: nil, behavior_roaming: :random },
:CLAWITZER => { behavior_noticed: :aggressive, behavior_roaming: :random },
:HELIOPTILE => { behavior_noticed: :curious, behavior_roaming: :random },
@@ -747,9 +748,9 @@ POKEMON_BEHAVIOR_DATA =
:AMAURA => { behavior_noticed: :shy, behavior_roaming: :random },
:AURORUS => { behavior_noticed: nil, behavior_roaming: :random },
:SYLVEON => { behavior_noticed: :curious, behavior_roaming: :random },
:HAWLUCHA => { behavior_noticed: nil, behavior_roaming: :random },
:HAWLUCHA => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:PRIMEAPE => :aggressive}},
:DEDENNE => { behavior_noticed: :skittish, behavior_roaming: :random },
:CARBINK => { behavior_noticed: :still, behavior_roaming: :look_around },
:CARBINK => { behavior_noticed: :still, behavior_roaming: :look_around , behavior_pokemon: {:SABLEYE => :shy}},
:GOOMY => { behavior_noticed: :shy, behavior_roaming: :random, behavior_rain_roaming: :random_spin },
:SLIGGOO => { behavior_noticed: nil, behavior_roaming: :random, behavior_rain_roaming: :random_spin },
:GOODRA => { behavior_noticed: nil, behavior_roaming: :random,behavior_rain_roaming: :random_spin },
@@ -778,45 +779,45 @@ POKEMON_BEHAVIOR_DATA =
:POPPLIO => { behavior_noticed: :curious, behavior_roaming: :random },
:BRIONNE => { behavior_noticed: nil, behavior_roaming: :random },
:PRIMARINA => { behavior_noticed: nil, behavior_roaming: :random },
:PIKIPEK => { behavior_noticed: :curious, behavior_roaming: :random },
:PIKIPEK => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:TALONFLAME => :skittish, :METAPOD => :aggressive, :FLETCHINDER => :shy, :BOUNSWEET => :aggressive}},
:TRUMBEAK => { behavior_noticed: :curious, behavior_roaming: :random },
:TOUCANNON => { behavior_noticed: :aggressive, behavior_roaming: :random },
:TOUCANNON => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:BOUNSWEET => :aggressive}},
:YUNGOOS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GUMSHOOS => { behavior_noticed: :aggressive, behavior_roaming: :random },
:GUMSHOOS => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:RATTATA => :semi_aggressive, :RATICATE => :semi_aggressive, :ALOLAN_RATTATA => :semi_aggressive, :ALOLAN_RATICATE => :semi_aggressive}},
:GRUBBIN => { behavior_noticed: :shy, behavior_roaming: :random },
:CHARJABUG => { behavior_noticed: :still, behavior_roaming: :look_around },
:VIKAVOLT => { behavior_noticed: :aggressive, behavior_roaming: :random },
:CRABRAWLER => { behavior_noticed: :aggressive, behavior_roaming: :random },
:VIKAVOLT => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:PINSIR => :aggressive, :HERACROSS => :aggressive}},
:CRABRAWLER => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:EXEGGCUTE => :semi_aggressive}},
:CRABOMINABLE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:ORICORIO_1 => { behavior_noticed: :curious, behavior_roaming: :random_spin },
:ORICORIO_2 => { behavior_noticed: :curious, behavior_roaming: :random_spin },
:ORICORIO_3 => { behavior_noticed: :curious, behavior_roaming: :random_spin },
:ORICORIO_4 => { behavior_noticed: :curious, behavior_roaming: :random_spin },
:CUTIEFLY => { behavior_noticed: :skittish, behavior_roaming: :random },
:CUTIEFLY => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:SPINARAK => :shy, :PINECO => :shy, :BUTTERFREE => :semi_aggressive, :FOMANTIS => :curious}},
:RIBOMBEE => { behavior_noticed: :skittish, behavior_roaming: :random },
:ROCKRUFF => { behavior_noticed: :curious, behavior_roaming: :random },
:LYCANROC_D => { behavior_noticed: nil, behavior_roaming: :random },
:LYCANROC_DUSK => { behavior_noticed: :curious, behavior_roaming: :random },
:LYCANROC_N => { behavior_noticed: :aggressive, behavior_roaming: :random },
:WISHIWASHI => { behavior_noticed: :skittish, behavior_roaming: :random },
:WISHIWASHI_SCHOOL => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MAREANIE => { behavior_noticed: :aggressive, behavior_roaming: :random },
:TOXAPEX => { behavior_noticed: :aggressive, behavior_roaming: :random },
:ROCKRUFF => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:GROWLITHE => :semi_aggressive}},
:LYCANROC_D => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:DEERLING_SPRING => :semi_aggressive, :DEERLING_SUMMER => :semi_aggressive, :DEERLING_AUTUMN => :semi_aggressive, :DEERLING_WINTER => :semi_aggressive}},
:LYCANROC_DUSK => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:DEERLING_SPRING => :semi_aggressive, :DEERLING_SUMMER => :semi_aggressive, :DEERLING_AUTUMN => :semi_aggressive, :DEERLING_WINTER => :semi_aggressive}},
:LYCANROC_N => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:DEERLING_SPRING => :aggressive, :DEERLING_SUMMER => :aggressive, :DEERLING_AUTUMN => :aggressive, :DEERLING_WINTER => :aggressive}},
:WISHIWASHI => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:DEWGONG => :skittish, :WAILMER => :skittish, :WAILORD => :skittish, :WINGULL => :skittish, :PELIPPER => :skittish}},
:WISHIWASHI_SCHOOL => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:WAILORD => :skittish}},
:MAREANIE => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:CORSOLA => :aggressive, :CLAMPERL => :semi_aggressive}},
:TOXAPEX => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:CORSOLA => :semi_aggressive, :BRUXISH => :aggressive}},
:MUDSDALE => { behavior_noticed: nil, behavior_roaming: :random },
:DEWPIDER => { behavior_noticed: nil, behavior_roaming: :random },
:DEWPIDER => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:SURSKIT => :semi_aggressive}},
:ARAQUANID => { behavior_noticed: nil, behavior_roaming: :random },
:FOMANTIS => { behavior_noticed: :shy, behavior_roaming: :random },
:LURANTIS => { behavior_noticed: nil, behavior_roaming: :random },
:MORELULL => { behavior_noticed: :shy, behavior_roaming: :random },
:SHIINOTIC => { behavior_noticed: nil, behavior_roaming: :random },
:FOMANTIS => { behavior_noticed: :shy, behavior_roaming: :random , behavior_pokemon: {:CUTIEFLY => :semi_aggressive}},
:LURANTIS => { behavior_noticed: nil, behavior_roaming: :random , behavior_pokemon: {:KRICKETOT => :semi_aggressive}},
:MORELULL => { behavior_noticed: :shy, behavior_roaming: :random, glow_in_the_dark: true },
:SHIINOTIC => { behavior_noticed: nil, behavior_roaming: :random, glow_in_the_dark: true , behavior_pokemon: {:PARASECT => :aggressive}},
:STUFFUL => { behavior_noticed: :curious, behavior_roaming: :random },
:BEWEAR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BOUNSWEET => { behavior_noticed: :skittish, behavior_roaming: :random },
:BEWEAR => { behavior_noticed: :excited, behavior_roaming: :random },
:BOUNSWEET => { behavior_noticed: :skittish, behavior_roaming: :random , behavior_pokemon: {:AIPOM => :skittish, :BOUNSWEET => :skittish}},
:STEENEE => { behavior_noticed: nil, behavior_roaming: :random },
:TSAREENA => { behavior_noticed: nil, behavior_roaming: :random },
:COMFEY => { behavior_noticed: nil, behavior_roaming: :random },
:ORANGURU => { behavior_noticed: nil, behavior_roaming: :random },
:PASSIMIAN => { behavior_noticed: :aggressive, behavior_roaming: :random },
:PASSIMIAN => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:AMBIPOM => :semi_aggressive}},
:WIMPOD => { behavior_noticed: :flee, behavior_roaming: :random },
:GOLISOPOD => { behavior_noticed: :aggressive, behavior_roaming: :random },
:SANDYGAST => { behavior_noticed: :still, behavior_roaming: :still },
@@ -828,11 +829,11 @@ POKEMON_BEHAVIOR_DATA =
:MINIOR_M => { behavior_noticed: nil, behavior_roaming: :random },
:KOMALA => { behavior_noticed: nil, behavior_roaming: :look_around },
:TURTONATOR => { behavior_noticed: :aggressive, behavior_roaming: :random },
:TOGEDEMARU => { behavior_noticed: :curious, behavior_roaming: :random },
:TOGEDEMARU => { behavior_noticed: :curious, behavior_roaming: :random , behavior_pokemon: {:ELEKID => :semi_aggressive}},
:MIMIKYU => { behavior_noticed: :shy, behavior_roaming: :random },
:BRUXISH => { behavior_noticed: :aggressive, behavior_roaming: :random },
:BRUXISH => { behavior_noticed: :aggressive, behavior_roaming: :random , behavior_pokemon: {:SHELLDER => :aggressive, :MAREANIE => :aggressive, :TOXAPEX => :aggressive}},
:DRAMPA => { behavior_noticed: nil, behavior_roaming: :random },
:DHELMISE => { behavior_noticed: :still, behavior_roaming: :look_around },
:DHELMISE => { behavior_noticed: :still, behavior_roaming: :look_around , behavior_pokemon: {:WAILMER => :semi_aggressive, :WAILORD => :aggressive, :SKRELP => :curious, :DRAGALGE => :curious}},
:JANGMOO => { behavior_noticed: :curious, behavior_roaming: :random },
:HAKAMOO => { behavior_noticed: nil, behavior_roaming: :random },
:KOMMOO => { behavior_noticed: :aggressive, behavior_roaming: :random },
@@ -862,7 +863,6 @@ POKEMON_BEHAVIOR_DATA =
:ZERAORA => { behavior_noticed: :aggressive, behavior_roaming: :random },
:MELTAN => { behavior_noticed: :curious, behavior_roaming: :random },
:MELMETAL => { behavior_noticed: :aggressive, behavior_roaming: :random },
}
@@ -21,6 +21,21 @@ def getRoamingSprite(species_data,shiny=false)
return flyingPath if flyingPath
end
def get_ow_sprite_path(species_data,sprite_name,shiny=false)
species = species_data.species
is_fusion = isSpeciesFusion(species)
if is_fusion
species_name = species_data.get_body_species_symbol.to_s
else
species_name = species.to_s
end
base_path = get_base_sprite_path(is_fusion, shiny)
path = "#{base_path}#{species_name}_#{sprite_name}"
if pbResolveBitmap("Graphics/Characters/#{path}")
return path
end
end
def getOverworldLandPath(species_data,shiny=false)
species = species_data.species
is_fusion = isSpeciesFusion(species)
@@ -37,48 +52,22 @@ def getOverworldLandPath(species_data,shiny=false)
end
def getOverworldFlyingPath(species_data,shiny=false)
species = species_data.species
is_fusion = isSpeciesFusion(species)
if is_fusion
species_name = species_data.get_body_species_symbol.to_s
else
species_name = species.to_s
end
base_path = get_base_sprite_path(is_fusion, shiny)
path = "#{base_path}#{species_name}_fly"
if pbResolveBitmap("Graphics/Characters/#{path}")
return path
end
return get_ow_sprite_path(species_data,"fly",shiny)
end
def getOverworldNoticedPath(species_data,shiny=false)
species = species_data.species
is_fusion = isSpeciesFusion(species)
if is_fusion
species_name = species_data.get_body_species_symbol.to_s
else
species_name = species.to_s
end
base_path = get_base_sprite_path(is_fusion, shiny)
path = "#{base_path}#{species_name}_notice"
if pbResolveBitmap("Graphics/Characters/#{path}")
return path
end
return get_ow_sprite_path(species_data,"notice",shiny)
end
def getOverworldSwimmingPath(species_data,shiny=false)
species = species_data.species
return get_ow_sprite_path(species_data,"swim",shiny)
end
is_fusion = isSpeciesFusion(species)
if is_fusion
species_name = species_data.get_body_species_symbol.to_s
def getOverworldIdleAnimation(species_data,is_flying, shiny=false)
if is_flying
return get_ow_sprite_path(species_data,"fly_idle",shiny)
else
species_name = species.to_s
end
base_path = get_base_sprite_path(is_fusion, shiny)
path = "#{base_path}#{species_name}_swim"
if pbResolveBitmap("Graphics/Characters/#{path}")
return path
return get_ow_sprite_path(species_data,"idle",shiny)
end
end
@@ -93,4 +82,19 @@ def getRandomPokemonFromRoute(excluded_species,terrain)
i+=1
end
return GameData::Species.get(random_species)
end
#Used when using Roar in the OW. Makes all the pokemon near the player back off.
def scareOffWildPokemon(radius=5)
pokemon_in_radius = []
events_in_radius = getEventsInRadius(radius)
events_in_radius.each do |event|
pokemon_in_radius << event if event.is_a?(OverworldPokemonEvent)
end
pokemon_in_radius.each do |pokemon_event|
playAnimation(EXCLAMATION_ANIMATION_ID,pokemon_event.x,pokemon_event.y)
pokemon_event.move_away_from_player
pokemon_event.move_away_from_player
end
end
@@ -0,0 +1,60 @@
DEFAULT_AMBIENT_VOLUME = 40
Events.onStepTakenFieldMovement += proc { |_sender, e|
next unless Settings::EXPERIMENTAL_FEATURES
event = e[0]
next unless event == $game_player
nearby_ambient_sounds = scan_for_ambient_sounds
if nearby_ambient_sounds.size > 0
sound, volume = nearby_ambient_sounds.min_by { |sound, volume| volume }
pbBGSPlay(sound, volume)
else
pbBGSFade(2)
restore_weather_ambient_sounds
end
}
AMBIENT_SOUND_SCAN_RADIUS = 5
AMBIENT_SOUND_SCAN_OFFSETS = (-AMBIENT_SOUND_SCAN_RADIUS..AMBIENT_SOUND_SCAN_RADIUS).flat_map { |dx|
(-AMBIENT_SOUND_SCAN_RADIUS..AMBIENT_SOUND_SCAN_RADIUS).map { |dy| [dx, dy, dx.abs + dy.abs] }
}.select { |_dx, _dy, dist| dist <= AMBIENT_SOUND_SCAN_RADIUS }
.sort_by { |_dx, _dy, dist| dist }
.freeze
def scan_for_ambient_sounds
map = $MapFactory.getMapNoAdd($game_map.map_id)
return [] if !map
px = $game_player.x
py = $game_player.y
best_sound = nil
best_priority = nil
best_distance = nil
AMBIENT_SOUND_SCAN_OFFSETS.each do |dx, dy, distance|
terrain_tag = map.terrain_tag(px + dx, py + dy, true)
next unless terrain_tag&.ambient_sound
priority = terrain_tag.ambient_sound_priority
next if best_priority && best_priority >= priority
best_sound = terrain_tag.ambient_sound
best_priority = priority
best_distance = distance
end
return [] if best_sound.nil?
return [[best_sound, calculate_ambient_sound_volume(best_distance)]]
end
def calculate_ambient_sound_volume(distance_from_player)
return DEFAULT_AMBIENT_VOLUME - (5 * distance_from_player)
end
def calculate_distance_from_player(x, y)
dx = (x - $game_player.x).abs
dy = (y - $game_player.y).abs
return dx + dy
end
@@ -0,0 +1,79 @@
#Tiles that change to a different tile when the player or an event steps on it.
# Used for suspended bridges. Maybe some other cool uses.
#
# shifting_tile_vertical -> shifts all tiles aligned vertically with the current one to the tile to the right of it in the tileset.
# shifting_tile_horizontal -> shifts all tiles aligned horizontally with the current one to the tile under it in the tileset.
class Game_Temp
attr_accessor :shifting_tiles
end
def pbGetShiftingTile(map, x, y)
return nil unless map.valid?(x, y)
for layer in [2, 1, 0]
tile_id = map.data[x, y, layer]
next if tile_id.nil?
terrain_tag = GameData::TerrainTag.try_get(map.terrain_tags[tile_id])
next unless terrain_tag
next if terrain_tag.bridge && $PokemonGlobal.bridge == 0
return [layer, tile_id, :vertical] if terrain_tag.shifting_tile_vertical
return [layer, tile_id, :horizontal] if terrain_tag.shifting_tile_horizontal
end
return nil
end
def pbShiftedTileId(tile_id, mode)
return (mode == :horizontal) ? tile_id + 8 : tile_id + 1
end
def pbCollectShiftingTiles(map, mx, my, layer, tile_id, mode)
tiles = [[mx, my, layer, tile_id]]
dirs = (mode == :vertical) ? [[0, -1], [0, 1]] : [[-1, 0], [1, 0]]
dirs.each do |dx, dy|
x, y = mx + dx, my + dy
loop do
result = pbGetShiftingTile(map, x, y)
break unless result && result[2] == mode
tiles << [x, y, result[0], result[1]]
x += dx
y += dy
end
end
return tiles
end
Events.onStepTakenFieldMovement += proc { |_sender, e|
event = e[0]
thistile = $MapFactory.getRealTilePos(event.map.map_id, event.x, event.y)
map = $MapFactory.getMap(thistile[0])
mx, my = thistile[1], thistile[2]
$game_temp.shifting_tiles ||= {}
key = event.object_id
prev = $game_temp.shifting_tiles[key]
current = pbGetShiftingTile(map, mx, my)
if current
layer, tile_id, mode = current
tiles = pbCollectShiftingTiles(map, mx, my, layer, tile_id, mode)
new_coords = tiles.map { |t| t[0, 3] }.sort
prev_coords = prev&.map { |t| [t[:x], t[:y], t[:layer]] }&.sort
unless new_coords == prev_coords
if prev
prev_map = $MapFactory.getMap(prev.first[:map_id])
prev.each { |t| prev_map.set_tile(t[:x], t[:y], t[:layer], t[:original]) }
end
tiles.each { |x, y, layer, tid| map.set_tile(x, y, layer, pbShiftedTileId(tid, mode)) }
$game_temp.shifting_tiles[key] = tiles.map { |x, y, layer, tid|
{ map_id: thistile[0], x: x, y: y, layer: layer, original: tid }
}
end
elsif prev
prev_map = $MapFactory.getMap(prev.first[:map_id])
prev.each { |t| prev_map.set_tile(t[:x], t[:y], t[:layer], t[:original]) }
$game_temp.shifting_tiles.delete(key)
end
}
@@ -35,6 +35,10 @@ class ContactsAppScreen
contacts_list_by_location[_INTL("Favorites")] << trainer
else
location = trainer.location
if trainer.location_map_id
translated_location = pbGetMessage(MessageTypes::MapNames, trainer.location_map_id)
location = translated_location if translated_location && translated_location != ""
end
contacts_list_by_location[location] ||= []
contacts_list_by_location[location] << trainer
end
@@ -357,7 +357,7 @@ class PokeRadarAppScene < PokeNavAppScene
end
def showAreaName
map_name = getMapName($game_map.map_id)
map_name = pbGetMapNameFromId($game_map.map_id)
text = _INTL("{1}", map_name)
encounter_type = get_encounter_type_name
if encounter_type && !encounter_type.empty?
@@ -389,8 +389,10 @@ class PokeRadarAppScene < PokeNavAppScene
return _INTL("Grass")
when :WaterMorning, :WaterDay, :WaterNight
return _INTL("Water")
when :TallGrass
when :TallGrass, :TallGrassNight
return _INTL("Tall Grass")
when :Puddle
return _INTL("Shallow Water")
else
return encounter_type.to_s
end
@@ -401,7 +403,7 @@ end
def getTerrainType
encounter_type = $PokemonEncounters.encounter_type
case encounter_type
when :Land, :Land1, :Land2, :Land3, :LandMorning, :LandDay, :LandNight, :TallGrass
when :Land, :Land1, :Land2, :Land3, :Land4, :LandMorning, :LandDay, :LandNight, :TallGrass, :TallGrassNight
return :Grass
else
return encounter_type
@@ -6,6 +6,11 @@ HOENN_MOM_BRENDAN_CHARNAME = "NPC_Hoenn_BrendanMom"
HOENN_MOM_MAY_CHARNAME = "NPC_Hoenn_MayMom"
HOENN_MAX_CHARNAME = "NPC_Hoenn_Max"
SWITCH_RIVAL_ON_MT_CHIMNEY = 2213
COMMON_EVENT_RIVAL_FOLLOWING_DIALOGUE = 204
class Player < Trainer
attr_accessor :rival_appearance
@@ -47,14 +52,20 @@ def get_hoenn_character_name(name)
return pbGetMessageFromHash(MessageTypes::TrainerNames, name)
end
def get_rival_name
def get_default_rival_name
rival_name = get_hoenn_character_name("Brendan") if isPlayerFemale
rival_name = get_hoenn_character_name("May") if isPlayerMale
return rival_name
end
def get_system_rival_name
rival_name = "Brendan" if isPlayerFemale
rival_name = "May" if isPlayerMale
return rival_name
end
def init_rival_name
rival_name = get_rival_name
rival_name = get_default_rival_name
@name = rival_name
return rival_name
end
@@ -77,14 +88,13 @@ class Sprite_Character
def checkModifySpriteGraphics(character)
PIF_typeExpert_checkModifySpriteGraphics(character)
return if character == $game_player
unless character.visible?
if !character.visible? && !character.is_rival_following
@bitmap_override = nil
updateBitmap
return
end
setSpriteToAppearance($Trainer.rival_appearance) if isPlayerFemale && character.name.start_with?(HOENN_RIVAL_EVENT_NAME) && character.character_name == TEMPLATE_CHARACTER_FILE
setSpriteToAppearance($Trainer.rival_appearance) if isPlayerMale && character.name.start_with?(HOENN_RIVAL_EVENT_NAME) && character.character_name == TEMPLATE_CHARACTER_FILE
setSpriteToAppearance($Trainer.rival_appearance) if isPlayerFemale && is_rival_character(character)
setSpriteToAppearance($Trainer.rival_appearance) if isPlayerMale && is_rival_character(character)
if character.character_name == HOENN_MOM_BRENDAN_CHARNAME
skinColor = $Trainer.skin_tone if isPlayerMale
skinColor = $Trainer.rival_appearance.skin_color if isPlayerFemale
@@ -106,6 +116,11 @@ class Sprite_Character
end
end
def is_rival_character(character)
return true if character&.is_rival_following
return character.name.start_with?(HOENN_RIVAL_EVENT_NAME) && character.character_name == TEMPLATE_CHARACTER_FILE
end
def get_hoenn_rival_starter
case get_rival_starter_type()
when :GRASS
@@ -308,8 +323,9 @@ def initializeRivalBattledTrainer
trainer_type = :RIVAL1
trainer_name = pbGet(VAR_RIVAL_NAME)
trainer_appearance = $Trainer.rival_appearance
rivalBattledTrainer = BattledTrainer.new(trainer_type, trainer_name, 0, BATTLED_TRAINER_RIVAL_KEY)
rivalBattledTrainer = BattledTrainer.new(trainer_type, get_system_rival_name, 0, BATTLED_TRAINER_RIVAL_KEY)
rivalBattledTrainer.set_custom_appearance(trainer_appearance)
rivalBattledTrainer.trainerName = trainer_name
rivalBattledTrainer.friendship_level = 1
team = []
team << Pokemon.new(get_hoenn_rival_starter, 5, trainer_name)
@@ -350,3 +366,38 @@ def hoennRivalBattle(loseDialog = "...", canLose = false, items = [])
end
return customTrainerBattle(rival_trainer.trainerName, rival_trainer.trainerType, rival_trainer.currentTeam, rival_trainer, loseDialog, nil, $Trainer.rival_appearance, items, canLose)
end
def rival_follow(eventId)
trainer = $PokemonGlobal.battledTrainers[BATTLED_TRAINER_RIVAL_KEY]
partnerWithTrainer(eventId, $game_map.map_id, trainer, BATTLED_TRAINER_RIVAL_KEY, COMMON_EVENT_RIVAL_FOLLOWING_DIALOGUE)
partner_event = pbGetDependency(BATTLED_TRAINER_RIVAL_KEY)
return unless partner_event
partner_event.is_rival_following = true
partner_event.name = HOENN_RIVAL_EVENT_NAME
end
def rival_unfollow()
unpartnerWithTrainer()
end
def playRivalBgm()
if isPlayerFemale()
pbBGMPlay("rival_brendan",100)
else
pbBGMPlay("rival_may",100)
end
end
class DependentEvents
alias hoennRival_createEvent createEvent
def createEvent(eventData)
newEvent = hoennRival_createEvent(eventData)
if eventData[8] == BATTLED_TRAINER_RIVAL_KEY
newEvent.name = HOENN_RIVAL_EVENT_NAME
newEvent.is_rival_following = true
end
return newEvent
end
end
@@ -108,6 +108,9 @@ class SecretBaseImporter
pokemon.pif_sprite = PIFSprite.new(:BASE, pokemon.id_number,nil,poke_json[:alt_sprite])
end
end
pokemon.shiny=poke_json[:shiny]
pokemon.natural_shiny=true if pokemon.shiny?
moves = poke_json[:moves]
pokemon_moves = []
moves.each do |move_id|
+138 -138
View File
@@ -1,142 +1,142 @@
# frozen_string_literal: true
SURF_SPLASH_ANIMATION_ID = 31
class Game_Temp
attr_accessor :surf_patches
def initializeSurfPatches
@surf_patches = []
end
def clearSurfSplashPatches
return unless @surf_patches
@surf_patches.clear
end
end
class Spriteset_Map
alias surf_patch_update update
def update
surf_patch_update
return unless $scene.is_a?(Scene_Map)
return unless Settings::GAME_ID == :IF_HOENN
return unless $PokemonGlobal.surfing
return if Graphics.frame_count % 60 != 0
animate_surf_water_splashes
end
end
class SurfPatch
MAX_NUMBER_SURF_SPLASHES = 4
attr_accessor :shape
def initialize(patch_size)
x, y = getRandomPositionOnPerimeter(8, 6, $game_player.x, $game_player.y, 2)
variance = rand(5..8)
@shape = getRandomSplashPatch(patch_size, x, y, variance)
end
def getRandomSplashPatch(tile_count, center_x, center_y, variance = rand(4))
return [] if tile_count <= 0
center_pos = getRandomPositionOnPerimeter(tile_count, tile_count, center_x, center_y, variance)
area = [center_pos]
visited = {} # Use hash with key format "x,y" for O(1) lookups
visited["#{center_pos[0]},#{center_pos[1]}"] = true
queue = [center_pos]
# Pre-shuffle directions once
directions = [[1, 0], [-1, 0], [0, 1], [0, -1],
[1, 1], [-1, -1], [1, -1], [-1, 1]].shuffle
map_id = $game_map.map_id # Cache map_id
while area.length < tile_count && !queue.empty?
current = queue.sample
queue.delete(current)
cx, cy = current
directions.take(rand(1..4)).each do |dx, dy|
nx, ny = cx + dx, cy + dy
key = "#{nx},#{ny}"
next if visited[key]
# Check terrain validity immediately before adding
terrain = $MapFactory.getTerrainTag(map_id, nx, ny, false)
next unless terrain&.can_surf
next unless $game_map.playerPassable?(nx, ny, 2)
visited[key] = true
new_pos = [nx, ny]
area << new_pos
queue << new_pos
break if area.length >= tile_count
end
end
area
end
end
def animate_surf_water_splashes
return unless $game_temp.surf_patches
$game_temp.surf_patches.each do |patch|
next if patch.nil? || patch.shape.empty?
patch.shape.each do |x_pos, y_pos|
$scene.spriteset.addUserAnimation(SURF_SPLASH_ANIMATION_ID, x_pos, y_pos, true, -1)
end
end
end
def try_spawn_surf_water_splashes
return if $PokemonGlobal.stepcount % 5 != 0
return unless rand < 0.1
spawnSurfSplashPatch
end
# Events.onStepTaken += proc { |sender, e|
# next unless $scene.is_a?(Scene_Map)
# next unless Settings::GAME_ID == :IF_HOENN
# next unless $PokemonGlobal.surfing
# # frozen_string_literal: true
# SURF_SPLASH_ANIMATION_ID = 31
#
# player_pos = [$game_player.x, $game_player.y] # Cache player position
# class Game_Temp
# attr_accessor :surf_patches
#
# if $game_temp.surf_patches
# # Use reverse_each to safely delete while iterating
# $game_temp.surf_patches.reverse_each.with_index do |patch, reverse_idx|
# next unless patch && patch.shape
#
# if patch.shape.include?(player_pos)
# next if rand(100) > 25
#
# # Calculate actual index for deletion
# actual_idx = $game_temp.surf_patches.length - 1 - reverse_idx
# $game_temp.surf_patches.delete_at(actual_idx)
#
# echoln "surf patch encounter!"
# wild_pokemon = $PokemonEncounters.choose_wild_pokemon(:Water)
# if wild_pokemon
# pbWildBattle(wild_pokemon[0], wild_pokemon[1])
# else
# pbItemBall(:OLDBOOT)
# end
# break
# end
# end
# def initializeSurfPatches
# @surf_patches = []
# end
#
# try_spawn_surf_water_splashes
# }
def spawnSurfSplashPatch
$game_temp.initializeSurfPatches unless $game_temp.surf_patches
patch_size = rand(3..6) # Faster than .sample for small ranges
splash_patch = SurfPatch.new(patch_size)
$game_temp.surf_patches << splash_patch
$game_temp.surf_patches.shift if $game_temp.surf_patches.length > SurfPatch::MAX_NUMBER_SURF_SPLASHES
echoln $game_temp.surf_patches
end
# def clearSurfSplashPatches
# return unless @surf_patches
# @surf_patches.clear
# end
# end
#
# class Spriteset_Map
# alias surf_patch_update update
# def update
# surf_patch_update
# return unless $scene.is_a?(Scene_Map)
# return unless Settings::GAME_ID == :IF_HOENN
# return unless $PokemonGlobal.surfing
# return if Graphics.frame_count % 60 != 0
# animate_surf_water_splashes
# end
# end
#
# class SurfPatch
# MAX_NUMBER_SURF_SPLASHES = 4
#
# attr_accessor :shape
#
# def initialize(patch_size)
# x, y = getRandomPositionOnPerimeter(8, 6, $game_player.x, $game_player.y, 2)
# variance = rand(5..8)
# @shape = getRandomSplashPatch(patch_size, x, y, variance)
# end
#
# def getRandomSplashPatch(tile_count, center_x, center_y, variance = rand(4))
# return [] if tile_count <= 0
#
# center_pos = getRandomPositionOnPerimeter(tile_count, tile_count, center_x, center_y, variance)
# area = [center_pos]
# visited = {} # Use hash with key format "x,y" for O(1) lookups
# visited["#{center_pos[0]},#{center_pos[1]}"] = true
# queue = [center_pos]
#
# # Pre-shuffle directions once
# directions = [[1, 0], [-1, 0], [0, 1], [0, -1],
# [1, 1], [-1, -1], [1, -1], [-1, 1]].shuffle
#
# map_id = $game_map.map_id # Cache map_id
#
# while area.length < tile_count && !queue.empty?
# current = queue.sample
# queue.delete(current)
# cx, cy = current
#
# directions.take(rand(1..4)).each do |dx, dy|
# nx, ny = cx + dx, cy + dy
# key = "#{nx},#{ny}"
# next if visited[key]
#
# # Check terrain validity immediately before adding
# terrain = $MapFactory.getTerrainTag(map_id, nx, ny, false)
# next unless terrain&.can_surf
# next unless $game_map.playerPassable?(nx, ny, 2)
#
# visited[key] = true
# new_pos = [nx, ny]
# area << new_pos
# queue << new_pos
#
# break if area.length >= tile_count
# end
# end
#
# area
# end
# end
#
# def animate_surf_water_splashes
# return unless $game_temp.surf_patches
#
# $game_temp.surf_patches.each do |patch|
# next if patch.nil? || patch.shape.empty?
# patch.shape.each do |x_pos, y_pos|
# $scene.spriteset.addUserAnimation(SURF_SPLASH_ANIMATION_ID, x_pos, y_pos, true, -1)
# end
# end
# end
#
# def try_spawn_surf_water_splashes
# return if $PokemonGlobal.stepcount % 5 != 0
# return unless rand < 0.1
# spawnSurfSplashPatch
# end
#
# # Events.onStepTaken += proc { |sender, e|
# # next unless $scene.is_a?(Scene_Map)
# # next unless Settings::GAME_ID == :IF_HOENN
# # next unless $PokemonGlobal.surfing
# #
# # player_pos = [$game_player.x, $game_player.y] # Cache player position
# #
# # if $game_temp.surf_patches
# # # Use reverse_each to safely delete while iterating
# # $game_temp.surf_patches.reverse_each.with_index do |patch, reverse_idx|
# # next unless patch && patch.shape
# #
# # if patch.shape.include?(player_pos)
# # next if rand(100) > 25
# #
# # # Calculate actual index for deletion
# # actual_idx = $game_temp.surf_patches.length - 1 - reverse_idx
# # $game_temp.surf_patches.delete_at(actual_idx)
# #
# # echoln "surf patch encounter!"
# # wild_pokemon = $PokemonEncounters.choose_wild_pokemon(:Water)
# # if wild_pokemon
# # pbWildBattle(wild_pokemon[0], wild_pokemon[1])
# # else
# # pbItemBall(:OLDBOOT)
# # end
# # break
# # end
# # end
# # end
# #
# # try_spawn_surf_water_splashes
# # }
#
# def spawnSurfSplashPatch
# $game_temp.initializeSurfPatches unless $game_temp.surf_patches
#
# patch_size = rand(3..6) # Faster than .sample for small ranges
# splash_patch = SurfPatch.new(patch_size)
# $game_temp.surf_patches << splash_patch
# $game_temp.surf_patches.shift if $game_temp.surf_patches.length > SurfPatch::MAX_NUMBER_SURF_SPLASHES
# echoln $game_temp.surf_patches
# end
@@ -7,6 +7,9 @@ def getTVAnnouncementsHash #Keep in the function
:hidden_ability => _INTL("This is a special bulletin for all Pokémon Trainers!\nPokémon boasting their hidden abilities have been spotted around \\C[1]{1}\\C[0]! Make sure to make your way over there for rare Pokémon before they're gone!\nThis concludes our special bulletin.", getCurrentHiddenAbilityMapName),
:petalburg_contest => _INTL("Attention all Berry enthusiasts! The Petalburg Berry Contest is now about to begin!\nWe'll be covering the event live in Petalburg Town, so make sure to tune in for this special broadcast!"),
:petalburg_interview => proc { berryContestTVNews },
:trainer_search_rt112 => proc { trainerSearchRt112 },
:trainer_search_rt118 => proc { trainerSearchRt118 },
}
end
@@ -62,15 +62,15 @@ def getTVTrendMessages()
end
pbMessage(_INTL("It's the trend-watcher network channel!"))
pbMessage(_INTL("\"Everybody's talking about it, #{current_phrase} has been all the rage all around the region!\""))
pbMessage(_INTL("\"Nobody knows where it's started, but #{current_phrase} is all that the younger people are talking about these days.\""))
pbMessage(_INTL("\"Everybody's talking about it, {1} has been all the rage all around the region!\"", current_phrase))
pbMessage(_INTL("\"Nobody knows where it's started, but {1} is all that the younger people are talking about these days.\"", current_phrase))
case rand(3)
when 0
pbMessage(_INTL("\"Where can someone get their hands on #{adverb} #{current_phrase}? We'll continue our investigation to find out!'\""))
pbMessage(_INTL("\"Where can someone get their hands on {1} {2}? We'll continue our investigation to find out!'\"", adverb, current_phrase))
when 1
pbMessage(_INTL("\"Experts say that #{current_phrase} may just be the next big thing! Stay tuned for updates!\""))
pbMessage(_INTL("\"Experts say that {1} may just be the next big thing! Stay tuned for updates!\"", current_phrase))
when 2
pbMessage(_INTL("\"Some say that #{current_phrase} just a fad, but others seem to think it's here to stay! Stay tuned for updates!\""))
pbMessage(_INTL("\"Some say that {1} just a fad, but others seem to think it's here to stay! Stay tuned for updates!\"", current_phrase))
end
end
@@ -135,3 +135,64 @@ def berryContestTVNews
pbWait(10)
pbMessage(_INTL("\"This was Gabby, reporting live from Petalburg Town. We'll see you again on our next broadcast!\""))
end
VAR_REPORTER_POKEMON_112 = 976
def trainerSearchRt112
poke_name = pbGet(VAR_REPORTER_POKEMON_112)
pbMessage(_INTL("\"...This is Gabby for Trainer Search, We're currently standing at the foot of Mt. Chimney, where local Trainers like to gather.\"",$Trainer.name))
pbMessage(_INTL("\"We're currently joined by {1}, a young Trainer who bested me in a Pokémon battle.\"",$Trainer.name))
if poke_name.is_a?(String)
pbMessage(_INTL("\"Their {1} absolutely wiped the floor with my Pokémon!\"", poke_name))
end
player_response_q1 = pbGet(VAR_REPORTER_Q1)
player_response_q2 = pbGet(VAR_REPORTER_Q2)
case player_response_q1
when 0
pbMessage(_INTL("\"They responded that they were looking for rare Pokémon! Indeed, Mt. Chimney is home to many rare fire-type Pokémon that aren't found anywhere else in the region.\""))
when 1
pbMessage(_INTL("\"They said that it was the thrill of exploring that brought them here. Such an adventurous spirit at such a young age!\""))
when 2
pbMessage(_INTL("\"They said that they were simply trying to get the other side of the volcano. Of course, Mt. Chimney sits at the center of the region, so Trainers who want to get Fallarbor Town need to cross right through it.\"",$Trainer.name))
when 3
pbMessage(_INTL("\"They said they got lost and didn't know where they were! I made sure to point them in the right direction.\""))
end
pbMessage(_INTL("\"I then asked {1} what exactly it was that they were expecting to find here in Mt. Chimney and their answer totally floored me!\"",$Trainer.name))
pbMessage(_INTL("\"They said that they're looking for {1}. How crazy is that!\"",player_response_q2))
pbMessage(_INTL("\"But it does makes total sense if you think about it!\""))
pbWait(10)
pbMessage(_INTL("\"That's all for today. We'll continue our search throughout the region for more Trainers to interview! Thanks for joining me on Trainer Search. This was Gabby, reporting from Mt. Chimney.\""))
end
VAR_REPORTER_POKEMON_118 = 977
def trainerSearchRt118
poke_name = pbGet(VAR_REPORTER_POKEMON_118)
pbMessage(_INTL("\"...This is Gabby for Trainer Search, We're currently standing on the beach on Route 118\"",$Trainer.name))
pbMessage(_INTL("\"We're currently joined by {1}, a young Trainer who bested me in a Pokémon battle.\"",$Trainer.name))
if poke_name.is_a?(String)
pbMessage(_INTL("\"My Pokémon stood no chance against their {1}!\"", poke_name))
end
player_response_q1 = pbGet(VAR_REPORTER_Q1)
player_response_q2 = pbGet(VAR_REPORTER_Q2)
pbMessage(_INTL("\"They seemed to be on their way to Fortree City, so I started by asking them what they were expecting to see on the way there.\"",$Trainer.name))
case player_response_q1
when 0
pbMessage(_INTL("\"They responded that they were looking for rare Pokémon! Indeed, the way to Fortree City is home to many rare tropical Pokémon that aren't found anywhere else in the region.\""))
when 1
pbMessage(_INTL("\"As it turns out, they came here to appreciate the beautiful tropical landscapes that the route has to offer.\""))
when 2
pbMessage(_INTL("\"Apparently, they were looking for strong Trainers to fight! I'm sure they'll find their match somewhere in this untamed wilderness.\""))
when 3
pbMessage(_INTL("\"They seemed worried about all of the plants that grow on this route. Trainers around here have to watch their steps carefully if they want to avoid getting a mean rash!'\""))
end
pbMessage(_INTL("\"I then asked {1} what exactly what made them decide to brave the wilderness to go to Fortree City.'\"",$Trainer.name))
pbMessage(_INTL("\"They said that they're looking for {1}. That sounds about right!\"",player_response_q2))
pbWait(10)
pbMessage(_INTL("\"That's all for today. We'll continue our search throughout the region for more Trainers to interview! Thanks for joining me on Trainer Search. This was Gabby, reporting from Mt. Chimney.\""))
end
@@ -48,6 +48,7 @@ class BattledTrainer
attr_accessor :friendship_level
attr_accessor :overworld_sprite
attr_accessor :location_map_id
attr_reader :favorite
@@ -146,8 +147,9 @@ class BattledTrainer
while @friendship_level < thresholds.length && @friendship >= thresholds[@friendship_level]
@friendship_level += 1
trainerClassName = GameData::TrainerType.get(@trainerType).real_name
pbMessage(_INTL("\\C[3]Friendship increased with {1} {2}!", trainerClassName, @trainerName))
trainerClassName = GameData::TrainerType.get(@trainerType).name
trainerName = pbGetMessageFromHash(MessageTypes::TrainerNames, @trainerName)
pbMessage(_INTL("\\C[3]Friendship increased with {1} {2}!", trainerClassName, trainerName))
case @friendship_level
when 1
pbMessage(_INTL("You can now trade with each other!"))
@@ -172,7 +174,7 @@ class BattledTrainer
store_usable_item_chance = 80
chance_to_give_item = 60
@inventory = [] unless @inventory
#Move pokemon held items to inventory
@currentTeam.each do |pokemon|
next unless pokemon.item
@@ -289,8 +291,17 @@ class BattledTrainer
pbMessage(_INTL("Don't say anything... I know you want this."))
obtainClothes(CLOTHES_PSYSHAMAN_F)
end
when :TRIATHLETE_BIKE_M, :TRIATHLETE_BIKE_F
if !hasClothes?(CLOTHES_BIKE)
pbCallBub(2, event.id)
pbMessage(_INTL("The best athletes need the best gear! This should help improve your performance even more."))
obtainClothes(CLOTHES_BIKE)
obtainHat(HAT_BIKE)
end
when :POKEFAN_M, :POKEFAN_F
possible_masks = [HAT_POOCHYENA_MASK, HAT_LOTAD_MASK, HAT_ZIGZAGOON_MASK, HAT_WURMPLE_MASK]
possible_masks = [HAT_POOCHYENA_MASK, HAT_LOTAD_MASK, HAT_ZIGZAGOON_MASK, HAT_WURMPLE_MASK,
HAT_SEEDOT_MASK, HAT_TAILLOW_MASK, HAT_TREECKO_MASK, HAT_MUDKIP_MASK]
unobtained_masks = possible_masks.reject { |hatID| hasHat?(hatID) }
unless unobtained_masks.empty?
pbCallBub(2, event.id)
@@ -427,4 +438,4 @@ class BattledTrainer
end
return list
end
end
end
@@ -127,6 +127,7 @@ def registerBattledTrainer(event_id, mapId, trainerType, trainerName, trainerVer
trainer.setLinkedTrainer(linked_event) if linked_event
trainer.setOverworldSprite(getOverworldSprite(event_id,mapId))
trainer.setLocation(getMapName(mapId))
trainer.location_map_id = mapId
$PokemonGlobal.battledTrainers[key] = trainer
echoln "Registered rematchable trainer #{key}"
return trainer
@@ -54,7 +54,7 @@ TRAINER_REMATCH_SPECIFIC_GIFTS = {
:LADY => [[:LUXURYBALL], [:NUGGET]],
:GENTLEMAN => [[:LUXURYBALL], [:NUGGET]],
:HIKER => [[:TINYMUSHROOM, :REPEL], [:BIGMUSHROOM]],
:HIKER => [[:TINYMUSHROOM, :REPEL, :ESCAPEROPE, :FRESHWATER], [:BIGMUSHROOM]],
:CRUSHGIRL => [[:XSPEED], [:CARBOS]],
:BLACKBELT => [[:XATTACK], [:PROTEIN]],
:NURSE => [[:HEALBALL, :SUPERPOTION], [:FULLRESTORE]],
@@ -65,6 +65,9 @@ TRAINER_REMATCH_SPECIFIC_GIFTS = {
:AROMALADY => [[:PINKNECTAR, :REDNECTAR, :YELLOWNECTAR, :BLUENECTAR], [:LEAFSTONE]],
:TRIATHLETE_BIKE_F => [[:FRESHWATER], [:FRESHWATER]],
:TRIATHLETE_BIKE_M => [[:FRESHWATER], [:FRESHWATER]],
:NINJABOY => [[:SMOKEBALL], [:SMOKEBALL]],
}
def should_find_item(trainer)
@@ -7,7 +7,8 @@ class Trainer
end
def partnerWithTrainer(eventId, mapID, trainer,trainer_key=nil ,common_event=nil)
common_event = COMMON_EVENT_TRAINER_REMATCH_PARTNER if !common_event
Kernel.pbAddDependency2(eventId,trainer.trainerName,common_event)
trainer_key = getRebattledTrainerKey(eventId,mapID) if !trainer_key
Kernel.pbAddDependency2(eventId,trainer_key,common_event)
pbCancelVehicles
originalTrainer = pbLoadTrainer(trainer.trainerType, trainer.trainerName, 0)
Events.onTrainerPartyLoad.trigger(nil, originalTrainer)
@@ -200,16 +200,18 @@ def generateTrainerTradeOffer(trainer)
pbChoosePokemon(1, 2)
else
wanted_types_string = wanted_types.map { |type|
type_name = GameData::Type.get(type).real_name
type_name = GameData::Type.get(type).name
"\\C[1]#{type_name}\\C[0]"
}.join(", ")
trainerClassName = GameData::TrainerType.get(trainer.trainerType).real_name
trainerClassName = GameData::TrainerType.get(trainer.trainerType).name
trainerName = pbGetMessageFromHash(MessageTypes::TrainerNames, trainer.trainerName)
pbMessage(_INTL("{1} {2} is looking for Pokémon of the following type(s):\\n{3}\\nWhich Pokémon do you want to trade?",
trainerClassName, trainer.trainerName, wanted_types_string))
trainerClassName, trainerName, wanted_types_string))
pbChoosePokemon(1, 2,
proc { |pokemon|
pokemon.hasOneOfTheseTypes?(wanted_types)
pokemon.hasOneOfTheseTypes?(wanted_types) &&
!pokemon.egg?
})
end
chosen_index = pbGet(1)
@@ -217,15 +219,15 @@ def generateTrainerTradeOffer(trainer)
chosen_pokemon = $Trainer.party[chosen_index]
offered_pokemon = offerPokemonForTrade(chosen_pokemon, trainer.currentTeam, trainer.trainerType, trainer.favorite_type)
if !offered_pokemon
pbMessage(_INTL("{1} {2} does not want to trade...", trainerClassName, trainer.trainerName))
pbMessage(_INTL("{1} {2} does not want to trade...", trainerClassName, trainerName))
return trainer
end
pif_sprite = BattleSpriteLoader.new.get_pif_sprite_from_species(offered_pokemon.species)
message = _INTL("{1} {2} is offering {3} (Level {4}) for your {5}.", trainerClassName, trainer.trainerName, offered_pokemon.name, offered_pokemon.level, chosen_pokemon.name)
message = _INTL("{1} {2} is offering {3} (Level {4}) for your {5}.", trainerClassName, trainerName, offered_pokemon.name, offered_pokemon.level, chosen_pokemon.name)
showPokemonInPokeballWithMessage(pif_sprite, message)
if pbConfirmMessage(_INTL("Trade away {1} for {2} {3}'s {4}?", chosen_pokemon.name, trainerClassName, trainer.trainerName, offered_pokemon.name))
if pbConfirmMessage(_INTL("Trade away {1} for {2} {3}'s {4}?", chosen_pokemon.name, trainerClassName, trainerName, offered_pokemon.name))
pbStartTrade(chosen_index, offered_pokemon, offered_pokemon.name, trainer.trainerName, 0)
updated_party = trainer.currentTeam
trainer.increase_friendship(10) if GameData::Type.exists?(trainer.favorite_type) && offered_pokemon.hasType?(trainer.favorite_type)