Update 6.8

This commit is contained in:
chardub
2026-07-10 15:42:06 -04:00
parent 5b85e72cb2
commit 6a6f126a18
7871 changed files with 493194 additions and 224826 deletions
@@ -0,0 +1,33 @@
def berryContest(map_id,plots_event_ids=[])
total_yield = 0
berry_types= []
plots_event_ids.each do |event_id|
berryData = $PokemonGlobal.eventvars[[map_id, event_id]]
if berryData
berry_type = berryData[1]
growth_stage= berryData[0]
if berry_type && growth_stage == 5
berry_types << berry_type unless berry_types.include?(berry_type)
berry_yield = calculateBerryYield(berryData)
total_yield += berry_yield
end
end
end
return total_yield + berry_types.length
end
def calculateBerryYield(berryData)
berryvalues = GameData::BerryPlant.get(berryData[1])
berrycount = [berryvalues.maximum_yield - berryData[6], berryvalues.minimum_yield].max
return berrycount
end
def berry_contest_results(player_score)
contestants = {"Evelyn" => rand(5..8),
"Martin" => rand(4..8),
"Sarah" => rand(3..5)}
contestants[$Trainer.name] = player_score
results = contestants.sort_by { |name, score| score }
return results
end
@@ -0,0 +1,29 @@
class Game_Event < Game_Character
#Detects if the event has a specific comment command at the top (can pass multiple comments to test for as an array)
def detectCommentCommand(comment_text,event)
comment_text = [comment_text] if comment_text.is_a?(String)
page = pbGetActiveEventPage(event)
return unless page
first_command = page.list[0]
return nil if !(first_command.code == 108 || first_command.code == 408)
comments = first_command.parameters
return comments.any? { |str| comment_text.include?(str) }
end
# def getCommentCommandAtTop
# page = pbGetActiveEventPage(event)
# first_command = page.list[0]
# return nil if !(first_command.code == 108 || first_command.code == 408)
# comments = first_command.parameters.first
# return comments
# end
end
@@ -1,4 +1,11 @@
def turnEventTowardsEvent(turning, turnedTowards)
if turnedTowards.is_a?(Integer)
turnedTowards = $game_map.events[turnedTowards]
end
if turning.is_a?(Integer)
turning = $game_map.events[turning]
end
event_x = turnedTowards.x
event_y = turnedTowards.y
if turning.x < event_x
@@ -12,6 +19,13 @@ def turnEventTowardsEvent(turning, turnedTowards)
end
end
def resetFrames(event)
if event.is_a?(Integer)
event = $game_map.events[event]
end
event.pattern=0
end
def turnPlayerTowardsEvent(event)
if event.is_a?(Integer)
event = $game_map.events[event]
@@ -55,14 +69,23 @@ end
# 1: wood
def sign(message, type = 0)
signId = "sign_#{type}"
formatted_message = "\\sign[#{signId}]#{message}"
translated = MessageTypes.getFromMapHash($game_map.map_id, message)
formatted_message = "\\sign[#{signId}]#{translated}"
pbMessage(formatted_message)
end
def setEventGraphicsToPokemon(species, eventId)
def setEventGraphicsToPokemon(species, eventId, shiny=false)
event = $game_map.events[eventId]
return if !event
event.character_name = "Followers/#{species.to_s}"
shiny_folder= shiny ? "Shiny/" : ""
path = "Followers/#{shiny_folder}#{species.to_s}"
echoln path
if pbResolveBitmap("Graphics/Characters/" +path)
event.character_name = path
else
path = "Followers/#{shiny_folder}#{species.to_s}_fly"
event.character_name = path
end
event.refresh
end
@@ -81,3 +104,591 @@ def idleHatEvent(hatId, time, switchToActivate = nil)
$game_switches[switchToActivate] = true if switchToActivate
obtainHat(hatId)
end
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
DIRECTION_ALL = 0
DIRECTION_LEFT = 4
DIRECTION_RIGHT = 6
DIRECTION_DOWN = 2
DIRECTION_UP = 8
def kick_ball(eventId, obstacleName = nil, targetDestination = nil, targetSwitch = nil)
target_radius = 2
ball = $game_map.events[eventId]
return if !ball
dir = $game_player.direction
dx = (dir == DIRECTION_RIGHT ? 1 : dir == DIRECTION_LEFT ? -1 : 0)
dy = (dir == DIRECTION_DOWN ? 1 : dir == DIRECTION_UP ? -1 : 0)
# Shorter kick distance — scales gently with speed
player_speed = $game_player.move_speed
remaining_distance = [player_speed * 0.8, 1].max.floor
pbSEPlay("jump", 80, 100) rescue nil
pbWait(3)
current_dir = dir
total_bounces = 0
max_bounces = 3
will_pop = false
while remaining_distance > 0 && total_bounces < max_bounces
travel = 0
while travel < remaining_distance
test_x = ball.x + dx * (travel + 1)
test_y = ball.y + dy * (travel + 1)
event_at_test = $game_map.get_event_at_position(test_x, test_y)
if event_at_test && event_at_test.name == obstacleName && event_at_test.active?
ball.through = true
will_pop = true
else
break if !$game_map.passable?(test_x - dx, test_y - dy, current_dir) ||
!$game_map.passable?(test_x, test_y, current_dir)
end
travel += 1
end
if travel > 0
ball.jump(dx * travel, dy * travel)
pbWait(6)
end
if travel < remaining_distance
pbSEPlay("jump", 80, 80) rescue nil
total_bounces += 1
remaining_distance = [remaining_distance / 2.0, 1].max.floor
pbWait(6)
dx *= -1
dy *= -1
current_dir = case current_dir
when DIRECTION_UP then DIRECTION_DOWN
when DIRECTION_DOWN then DIRECTION_UP
when DIRECTION_LEFT then DIRECTION_RIGHT
when DIRECTION_RIGHT then DIRECTION_LEFT
end
bounce_dist = [remaining_distance / 2.0, 1].max.floor
ball.jump(dx * bounce_dist, dy * bounce_dist)
pbWait(8)
else
remaining_distance = 0
end
# After it lands
if will_pop
pbWait(24)
pbSetSelfSwitch(eventId, "A", true)
elsif targetDestination && targetSwitch
pbWait(24)
dist = (ball.x - targetDestination[0]).abs + (ball.y - targetDestination[1]).abs
if dist <= target_radius
$game_switches[targetSwitch] = true
$scene.reset_map(false)
end
end
end
end
def showTimeWindow
timeText = pbGetTimeNow.strftime(_INTL("%I:%M %p"))
window = LocationWindow.new(timeText)
window.set_close_automatically(false)
$scene.spriteset.addUserSprite(window)
return window
end
def updateTimeWindow(window)
return if !window || window.disposed?
window.text = pbGetTimeNow.strftime(_INTL("%I:%M %p"))
end
def update_weather(last_weather_hour)
now = pbGetTimeNow
current_hour = now.hour
if current_hour != last_weather_hour
if current_hour % 4 == 0 # Update every 4 hours
$game_weather.update_weather
end
last_weather_hour = current_hour
end
return if last_weather_hour
end
def sit_on_chair
pbSEPlay("jump", 80, 100)
max_faster_time = 20
# Enter sitting state
$game_temp.faster_time = 4
is_outdoor = isOutdoor()
time_window = showTimeWindow if is_outdoor
$game_player.through = true
$game_player.jump_forward
$game_player.turn_180
$game_player.through = false
last_weather_hour = pbGetTimeNow.hour
time_on_chair = 0
loop do
Graphics.update
Input.update
pbUpdateSceneMap
if is_outdoor
updateTimeWindow(time_window)
last_weather_hour = update_weather(last_weather_hour) if time_on_chair % 100 == 0
time_on_chair += 1
if time_on_chair % 100 == 0
$game_temp.faster_time += 1 if $game_temp.faster_time < max_faster_time
end
end
direction = checkInputDirection
next if !direction
facing_terrain = $game_player.pbFacingTerrainTag(direction)
if facing_terrain&.chair
pbSEPlay("jump", 80, 100)
$game_player.direction_fix = true
$game_player.jumpTowards(direction)
$game_player.direction_fix = false
else
passable = $game_map.passable?($game_player.x, $game_player.y, direction)
dest_x = $game_player.x + (direction == 6 ? 1 : direction == 4 ? -1 : 0)
dest_y = $game_player.y + (direction == 2 ? 1 : direction == 8 ? -1 : 0)
if passable #&& !$game_map.event_at_position(dest_x, dest_y) #todo Meant to make it so that you can't get stuck, but also prevents from interacting with
$game_player.turn_generic(direction)
$game_player.jump_forward
break
else
$game_player.turn_generic(direction)
$game_player.turn_180
end
end
pbWait(8)
end
ensure
# Always clean up
$game_temp.faster_time = nil
time_window.dispose if time_window && !time_window.disposed?
end
def checkInputDirection
return DIRECTION_UP if Input.trigger?(Input::UP)
return DIRECTION_DOWN if Input.trigger?(Input::DOWN)
return DIRECTION_LEFT if Input.trigger?(Input::LEFT)
return DIRECTION_RIGHT if Input.trigger?(Input::RIGHT)
return nil
end
def getOnBoat
set_player_graphics("boat_briney_peeko")
$PokemonTemp.prevent_ow_battles = true
$PokemonGlobal.boat = true
end
def getOffBoat
reset_player_graphics
$PokemonTemp.prevent_ow_battles = false
$PokemonGlobal.boat = false
$game_map.refresh
end
def check_beach_seashell
pbMessage(_INTL("{1} flipped the seashell over...", $Trainer.name))
pearl_chance = 2
heartscale_chance = 20
pokemon_chance = 40
roll = rand(1..100)
if roll <= pearl_chance
pbReceiveItem(:PEARL)
elsif roll <= pearl_chance + heartscale_chance
pbReceiveItem(:HEARTSCALE)
elsif roll <= pearl_chance + heartscale_chance + pokemon_chance
possible_pokemon = [:KRABBY] # if added to the game, also dwebble, binacle?
event = $game_map.events[@event_id]
# Spawn Pokémon
level = rand(8..16)
pbWait(4)
playAnimation(Settings::EXCLAMATION_ANIMATION_ID, $game_player.x, $game_player.y)
spawn_random_overworld_pokemon_group([possible_pokemon.sample, level], 1, 3, [event.x, event.y], :Cave)
else
# Nothing
pbMessage(_INTL("...There's nothing there."))
end
end
# shortcut for events
def spawn_near(species, level, group_size)
spawn_random_overworld_pokemon_group([species, level], 1, group_size)
end
def clefairy_minigame(length = 4, clefairy_event_id = nil)
if clefairy_event_id
event = $game_map.events[clefairy_event_id]
end
possible_elements = [_INTL("Left!"), _INTL("Up!"), _INTL("Right!"), _INTL("Down!")]
pbMessage(_INTL("Listen up and remember this!"))
sequence = []
message = ""
(0...length).each { |i|
element = possible_elements.sample
sequence << element
message += element
message += "\\wt[20]"
message += " "
}
message += "\\wtnp[40]"
pbWait(8)
pbMessage(message)
pbMessage(_INTL("Get ready... Press the buttons!\\wtnp[20]"))
player_input = []
loop do
if Input.trigger?(Input::LEFT)
player_input << possible_elements[0]
pbSEPlay("GUI save choice", 80, 100)
end
if Input.trigger?(Input::UP)
player_input << possible_elements[1]
pbSEPlay("GUI save choice", 80, 100)
end
if Input.trigger?(Input::RIGHT)
player_input << possible_elements[2]
pbSEPlay("GUI save choice", 80, 100)
end
if Input.trigger?(Input::DOWN)
player_input << possible_elements[3]
pbSEPlay("GUI save choice", 80, 100)
end
if Input.trigger?(Input::BACK)
pbSEPlay("GUI sel buzzer", 80, 100)
return false
end
Graphics.update
Input.update
break if player_input.size == sequence.size
end
pbWait(10)
if player_input == sequence
pbSEPlay("GUI naming confirm", 80, 100)
pbMEPlay("clefairy_correct",100)
pbMessage(_INTL("Correct!\\wtnp[40]"))
12.times do
event.turn_left_90 if event
pbWait(20)
end
return true
else
pbSEPlay("GUI sel buzzer", 80, 100)
pbMessage(_INTL("Incorrect!\\wtnp[40]"))
return false
end
end
# Switch 20
def isDebugMode()
return $DEBUG
end
def side_stairs_right
case $game_player.direction
when DIRECTION_RIGHT # Going up
destination_x = $game_player.x + 1
destination_y = $game_player.y - 1
if $game_player.destination_is_passable(destination_x, destination_y)
$game_player.move_upper_right
elsif $game_player.destination_is_passable(destination_x, $game_player.y)
$game_player.move_right
end
when DIRECTION_LEFT # Going down
destination_x = $game_player.x - 1
destination_y = $game_player.y + 1
if $game_player.destination_is_passable(destination_x, destination_y)
$game_player.move_lower_left
elsif $game_player.destination_is_passable(destination_x, $game_player.y)
$game_player.move_left
end
end
end
def side_stairs_left
case $game_player.direction
when DIRECTION_LEFT # Going up
destination_x = $game_player.x - 1
destination_y = $game_player.y - 1
if $game_player.destination_is_passable(destination_x, destination_y)
$game_player.move_upper_left
elsif $game_player.destination_is_passable(destination_x, $game_player.y)
$game_player.move_left
end
when DIRECTION_RIGHT # Going down
destination_x = $game_player.x + 1
destination_y = $game_player.y + 1
if $game_player.destination_is_passable(destination_x, destination_y)
$game_player.move_lower_right
elsif $game_player.destination_is_passable(destination_x, $game_player.y)
$game_player.move_right
end
end
end
def get_random_trend
items = list_all_item_names.reject { |name| name.include?("TM") || name.include?("HM") || name.include?("unknown_item") }
name1, name2 = items.sample(2)
word1 = name1.split.first
word2 = name2.split[1] || name2.split.first
"#{word1} #{word2}"
end
def trendSet(option1, option2)
choice = pbMessage(_INTL("What do you think? Do you think any of these have any potential?"), [_INTL("Not really..."), "#{option1} is pretty cool!", "I like #{option2}!"])
case choice
when 0
return false
when 1
pbSet(VAR_TRENDY_PHRASE, option1)
return true
when 2
pbSet(VAR_TRENDY_PHRASE, option2)
return true
end
return false
end
def vendingMachine(stock)
pbPokemonMart(stock, _INTL("It's a vending machine. What do you want to buy?"), true, _INTL(""), _INTL("Purchase anything else?"))
end
# Shiny egg of a random Pokemon (from a list)
def obtainBirthdayGift
possible_species =
[
:PICHU, :CLEFFA, :IGGLYBUFF, :TOGEPI, :EEVEE, :HAPPINY, :BUDEW, :CHINGLING, :MUNCHLAX, :RIOLU,
]
species = possible_species.sample
pokemon = Pokemon.new(species, Settings::EGG_LEVEL)
pokemon.shiny = true
pokemon.natural_shiny = true
pokemon.moves[0] = Pokemon::Move.new(:HOLDHANDS)
pbGenerateEgg(pokemon)
end
# Called from an event. The event's name must be the legendary Pokemon's species
# Returns true is it's not in $trainer.caught_legendaries or $trainer.encountered_legendaries
# Returns false if it is
def is_legendary_active?(species)
$Trainer.caught_legendaries = [] unless $Trainer.caught_legendaries
$Trainer.encountered_legendaries = [] unless $Trainer.encountered_legendaries
is_caught = $Trainer.caught_legendaries.include?(species)
is_encountered = $Trainer.encountered_legendaries.include?(species)
return !is_caught && !is_encountered
end
def setEventGraphicPokemon(species, event_id)
species_data = GameData::Species.get(species)
event = $game_map.events[event_id]
return unless event
if event
echoln event.get_page(1)
event.get_page(1).graphic.character_name = getOverworldLandPath(species_data)
# event.character_name= #"Graphics/Characters/#{getOverworldLandPath(species_data)}"
event.refresh
end
end
# ZORUA FOREST
#
ZORUA_FOLLOWED_VARIABLE = 1031
def shapeshift_zorua
zorua_events = [32, 36, 38, 34, 37, 61, 41]
nb_active = $game_variables[ZORUA_FOLLOWED_VARIABLE]
for i in 0..nb_active
event_id = zorua_events[i]
event = $game_map.events[event_id]
next unless event
next if event.erased
encounter_type = getTimeBasedEncounter(:Land)
disguise_species = getRandomPokemonFromRoute(:ZORUA, encounter_type)
species_data = GameData::Species.get(disguise_species)
event.character_name = getOverworldLandPath(species_data)
event.refresh
end
end
def transfer_subtle(new_x, new_y)
return if isWearingHat(HAT_ZOROARK)
map = $game_map.map_id
$game_temp.player_new_map_id = map
$game_temp.player_new_x = new_x
$game_temp.player_new_y = new_y
pbFadeOutIn {
$scene.transfer_player(false)
shapeshift_zorua
}
end
def this_event()
return $game_map.events[@event_id]
end
def get_event(id)
return $game_map.events[id]
end
def select_tv_show_quests(episode = 0)
all_episodes = [
[],
[:main_stolen_parts, :route_102_rematch, :petalburg_berry, :route104_rivalWeather, :petalburgwoods_spores],
[:main_steven_letter, :route104_oricorio, :route104_oricorio_forms, :rustboro_whismur, :rustboro_shiny],
[:main_devon_parts, :dewford_fishing, :route109_tanning, :route109_seahouse, :route109_beachball],
[:magma_help_grunts, :aqua_help_grunts],
[:mauville_quests_1]
]
episode_quests = all_episodes[episode] || []
completed_ids = get_completed_quests.map { |q| q.id.to_s }
filtered = episode_quests.select { |q| completed_ids.include?(q.to_s) }
#filtered = episode_quests # For debugging with all quests
filtered.sample(2)
end
def get_show_dialog(quest_id)
echoln quest_id
case quest_id
# Episode 1
when :main_stolen_parts
return _INTL("Sootopolis Void attacked the city and tried to steal a precious package from the Rangers headquarters. Littleroot Crimson was able to stop him, but now he's coming back with a vengeance...")
when :route_102_rematch
return _INTL("There was a part where Littleroot Crimson had a rematch with Fallarbor Bordeaux and he finally evolved his Combusken.")
when :petalburg_berry
return _INTL("There was an entire subplot about Rustboro Ivory entering a berry-growing contest that she ended up winning with a super-mutant berry.")
when :route104_rivalWeather
return _INTL("There was a part where Lilicove Viridian waited until the wind picked up to catch a Pidgeot that had been terrorizing the town.")
when :petalburgwoods_spores
return _INTL("At one point, Mauville Yellow met a scientist in the woods and helped him collect highly toxic spore.")
# Episode 2
when :main_steven_letter
return _INTL("Littleroot Crimson seeked out the help of the grandmaster that was hiding at the end of the dark cave.")
when :route104_oricorio
return _INTL("Rustboro Ivory befriended that lonely Oricorio in the flowers field.")
when :route104_oricorio_forms
return _INTL("The Oricorio kept switching forms!")
when :rustboro_whismur
return _INTL("Mauville Yellow fused a Pellipper with Exploud to create a sonic weapon. And then it ended up being much too loud, it was so funny!")
when :rustboro_shiny
return _INTL("Pacifidlog Cobalt found that shiny Azumarill. I never saw it coming!")
# Episode 3
when :main_devon_parts
return _INTL("At least, Littleroot Crimson finally delivered that precious package. I can't wait to see what happens next with that.")
when :dewford_fishing
return _INTL("Hey, that part where Fallarbor Bordeaux fished up that Dragalge was pretty neat.")
when :route109_tanning
return _INTL("That whole subplot about Pacifidlog Cobalt trying to get a tan definitely dragged on a bit...")
when :route109_seahouse
return _INTL("Although that scene with Lilicove Viridian beating up all the bad guys in the beach house was really fun!")
when :route109_beachball
return _INTL("The chase sequence with the Kingler when Mauville Yellow was carrying that beach ball was really funny though!")
# Episode 4
when :magma_help_grunts
return _INTL("I never expected Littleroot Crimson to infiltrate the villains's lair like that!")
when :aqua_help_grunts
return _INTL("I never expected Littleroot Crimson to infiltrate the villains's lair like that!")
# Episode 5
when :mauville_quests_1
return "" # directly in the event's dialog
end
end
def setDayCareOverworlds(land_event_ids = [], water_event_ids = [])
day_care_map = 74
return unless $game_map.map_id == day_care_map
land_event_ids.each_with_index do |event_id, i|
event = $game_map.events[event_id]
pbSetSelfSwitch(event.id, "A", false, day_care_map)
event.character_name = ""
end
water_event_ids.each_with_index do |event_id, i|
event = $game_map.events[event_id]
pbSetSelfSwitch(event.id, "A", false, day_care_map)
event.character_name = ""
end
$PokemonGlobal.daycare.each_with_index do |day_care_slot, i|
day_care_pokemon = day_care_slot[0]
next unless day_care_pokemon
if day_care_pokemon.hasType?(:WATER)
event_id = water_event_ids[i]
swimming = true
else
event_id = land_event_ids[i]
swimming = false
end
event = $game_map.events[event_id]
pbSetSelfSwitch(event.id, "A", true, day_care_map)
$game_map.refresh
overworldPath = getRoamingSprite(day_care_pokemon.species_data, day_care_pokemon.isShiny?)
is_flying = overworldPath.include?("_fly")
event.step_anime = true if is_flying
echoln overworldPath
event.character_name = overworldPath if overworldPath
if swimming
event.forced_bush_depth = 20
event.step_anime = true
event.set_animation_speed(2)
event.calculate_bush_depth
end
end
end
def getRandomWonderTradeNames(number=1)
names= RandTrainerNames_female + RandTrainerNames_male
return names.sample(number)
end
def getRandomUnisexName
return RandTrainerNames_unisex.sample
end
@@ -68,6 +68,7 @@ Events.onStepTaken += proc { |sender, e|
spawnSilhouette()
}
Events.onMapChange += proc { |sender, e|
next unless Settings::KANTO
next if $PokemonTemp.tempEvents.empty?
$PokemonTemp.pbClearTempEvents()
}
@@ -75,30 +76,7 @@ Events.onMapChange += proc { |sender, e|
def getRandomPositionOnPerimeter(width, height, center_x, center_y, variance=0,edge=nil)
half_width = width / 2.0
half_height = height / 2.0
# Randomly select one of the four edges of the rectangle
edge = rand(4) if !edge
case edge
when 0 # Top edge
random_x = center_x + rand(-half_width..half_width)
random_y = center_y - half_height
when 1 # Bottom edge
random_x = center_x + rand(-half_width..half_width)
random_y = center_y + half_height
when 2 # Left edge
random_x = center_x - half_width
random_y = center_y + rand(-half_height..half_height)
when 3 # Right edge
random_x = center_x + half_width
random_y = center_y + rand(-half_height..half_height)
end
return random_x.round, random_y.round
end
# def launchSilhouetteCommonEvent(event)
# $scene.spriteset.addUserAnimation(VIRUS_ANIMATION_ID, event.x, event.y, true)
@@ -16,4 +16,50 @@ def showPokemonInPokeballWithMessage(pif_sprite, message, x_position = nil, y_po
displaySpriteWindowWithMessage(pif_sprite, message, 90, -10, 201)
background_sprite.dispose
foreground_sprite.dispose
end
def set_player_graphics(name)
$game_player.setPlayerGraphicsOverride(name)
$game_map.refresh
end
def reset_player_graphics()
$game_player.removeGraphicsOverride
end
def get_spritecharacter_for_event(event_id)
for sprite in $scene.spriteset.character_sprites
if sprite.character.id == event_id
return sprite
end
end
end
def get_player_sprite_character
return nil if !$scene || !$scene.spriteset
for sprite in $scene.spriteset.character_sprites
echoln "sprite: #{sprite}, character: #{sprite.character}"
if sprite.character == $game_player
return sprite
end
end
return nil
end
def setFog(intensity)
current_weather = $game_weather.current_weather[$game_map.map_id]
if current_weather && current_weather[0] == :Fog
starting_intensity = current_weather[1]
else
starting_intensity =0
end
echoln starting_intensity
$scene.spriteset.fade_in_fog(starting_intensity,intensity)
end
def show_starter(species, pokemonName)
pif_sprite = BattleSpriteLoader.new.get_pif_sprite_from_species(species)
showPokemonInPokeballWithMessage(pif_sprite, _INTL("This Poké Ball contains {1}",pokemonName))
return pif_sprite
end
@@ -1,225 +1,225 @@
class Game_Temp
attr_accessor :temp_waterfall
attr_accessor :waterfall_sprites
attr_accessor :splash_sprites
attr_accessor :splash_coords
end
def generate_dynamic_waterfall(starting_x_position, waterfall_top_y, thickness=1)
map_height = $game_map.height - 8
echoln map_height
boulder_positions = []
CIANWOOD_BOULDER_IDS.each do |event_id|
event = $game_map.events[event_id]
boulder_positions << [event.x, event.y]
end
# Add columns from starting_x_position to the right
active_columns = []
(starting_x_position...(starting_x_position + thickness)).each do |x|
break if x >= $game_map.width # Don't go past map edge
active_columns << { x: x, y: waterfall_top_y }
end
visited = []
final_coords = []
splash_coords = []
while !active_columns.empty?
new_columns = []
active_columns.each do |segment|
x = segment[:x]
y = segment[:y]
next if visited.include?([x, y])
visited << [x, y]
while y < map_height
pos = [x, y]
final_coords << pos
if boulder_positions.include?(pos)
splash_coords << [x - 1, y] if x > 0
splash_coords << [x + 1, y] if x < $game_map.width - 1
splash_coords << [x, y]
new_y = y
new_columns << { x: x - 1, y: new_y } if x > 0 && !visited.include?([x - 1, new_y])
new_columns << { x: x + 1, y: new_y } if x < $game_map.width - 1 && !visited.include?([x + 1, new_y])
break
end
#currents section
if y > CIANWOOD_WATERFALL_EDGE+10
if !$game_map.passable?(x, y + 1, DIRECTION_DOWN)
splash_coords << [x, y + 1] if y + 1 < $game_map.height
break
end
end
if y == CIANWOOD_WATERFALL_EDGE
splash_coords << [x, y]
end
if y == map_height
splash_coords << [x, y]
end
y += 1
end
end
active_columns = new_columns
end
$game_temp.temp_waterfall = final_coords.uniq
$game_temp.splash_coords = splash_coords.uniq
echoln $game_temp.temp_waterfall
draw_waterfall_layer
end
def draw_waterfall_layer
return if !$game_temp.temp_waterfall || $game_temp.temp_waterfall.empty?
# Clear previous sprites
if $game_temp.waterfall_sprites
$game_temp.waterfall_sprites.each(&:dispose)
end
if $game_temp.splash_sprites
$game_temp.splash_sprites.each(&:dispose)
end
$game_temp.waterfall_sprites = []
$game_temp.splash_sprites = []
tile_size = 32
waterfall_tile_id = 0 # Waterfall
splash_tile_id = 4 # Splash impact tile, assuming we have this in the tileset
tileset = RPG::Cache.tileset($game_map.tileset_name)
# Draw waterfall tiles
$game_temp.temp_waterfall.each do |x, y|
sprite = Sprite.new(Spriteset_Map.viewport)
sprite.z = 10
sprite.x = x * tile_size
sprite.y = y * tile_size
sprite.bitmap = Bitmap.new(tile_size, tile_size)
source_rect = Rect.new(waterfall_tile_id * tile_size,0, tile_size, tile_size) # Frame 0
sprite.bitmap.blt(0, 0, tileset, source_rect)
# Store metadata for animation
sprite.instance_variable_set(:@frame_offset, rand(3)) # Optional: make them start at different frames
sprite.instance_variable_set(:@tile_x, x)
sprite.instance_variable_set(:@tile_y, y)
$game_temp.waterfall_sprites << sprite
end
# Draw splash impact tiles
$game_temp.splash_coords.each do |x, y|
sprite = Sprite.new(Spriteset_Map.viewport)
sprite.z = 300 # Draw splash above the waterfall
sprite.x = x * tile_size
sprite.y = y * tile_size
sprite.bitmap = Bitmap.new(tile_size, tile_size)
source_rect = Rect.new(splash_tile_id * tile_size,1, tile_size, tile_size) # Splash frame 0
sprite.bitmap.blt(0, 0, tileset, source_rect)
# Store metadata for splash animation
sprite.instance_variable_set(:@frame_offset, rand(3)) # Optional: make them start at different frames
sprite.instance_variable_set(:@tile_x, x)
sprite.instance_variable_set(:@tile_y, y)
$game_temp.splash_sprites << sprite
end
end
CIANWOOD_BOULDER_IDS = [2,3,5,6,
4 ]#chuck head
CIANWOOD_WATERFALL_EDGE =19
def player_on_temp_waterfall?
return false if !$game_temp.temp_waterfall
boulder_positions = []
CIANWOOD_BOULDER_IDS.each do |event_id|
event = $game_map.events[event_id]
boulder_positions << [event.x, event.y]
end
# Return false if a boulder is directly below the player
return false if boulder_positions.include?([$game_player.x, $game_player.y + 1])
return $game_temp.temp_waterfall.any? { |x, y, _| x == $game_player.x && y == $game_player.y }
end
class Spriteset_Map
alias_method :cianwood_waterfall_update, :update
def update
cianwood_waterfall_update
waterfall_edge = CIANWOOD_WATERFALL_EDGE
if $game_temp.waterfall_sprites
frame_count = Graphics.frame_count
tile_size = 32
autotile_id = 0
tileset = RPG::Cache.tileset($game_map.tileset_name)
# Animate waterfall sprites
$game_temp.waterfall_sprites.each do |sprite|
tile_y = sprite.instance_variable_get(:@tile_y)
frame_offset = sprite.instance_variable_get(:@frame_offset)
# Animate every 15 frames (change for speed control)
animation_frame = (frame_count / 15 + tile_y - frame_offset) % 4
tileset_x = (autotile_id * 4 + animation_frame) * tile_size
tileset_y = tile_y >= waterfall_edge ? tile_size : 0
source_rect = Rect.new(tileset_x,tileset_y, tile_size, tile_size)
sprite.bitmap.clear
sprite.bitmap.blt(0, 0, tileset, source_rect)
# Scroll with map
sprite.ox = $game_map.display_x / 4
sprite.oy = $game_map.display_y / 4
end
# Animate splash sprites
$game_temp.splash_sprites.each do |sprite|
tile_y = sprite.instance_variable_get(:@tile_y)
frame_offset = sprite.instance_variable_get(:@frame_offset)
# Animate every 10 frames for splash (you can adjust this speed)
offset = (autotile_id * 4 + 4) * tile_size
animation_frame = (frame_count / 10 + tile_y + frame_offset) % 4
source_rect = Rect.new((autotile_id * 4 + animation_frame) * tile_size + offset, 0, tile_size, tile_size)
sprite.bitmap.clear
sprite.bitmap.blt(0, 0, tileset, source_rect)
# Scroll with map
sprite.ox = $game_map.display_x / 4
sprite.oy = $game_map.display_y / 4
end
end
end
end
# class Game_Temp
# attr_accessor :temp_waterfall
# attr_accessor :waterfall_sprites
# attr_accessor :splash_sprites
# attr_accessor :splash_coords
#
#
# end
#
# def generate_dynamic_waterfall(starting_x_position, waterfall_top_y, thickness=1)
# map_height = $game_map.height - 8
# echoln map_height
#
# boulder_positions = []
# CIANWOOD_BOULDER_IDS.each do |event_id|
# event = $game_map.events[event_id]
# boulder_positions << [event.x, event.y]
# end
#
# # Add columns from starting_x_position to the right
# active_columns = []
# (starting_x_position...(starting_x_position + thickness)).each do |x|
# break if x >= $game_map.width # Don't go past map edge
# active_columns << { x: x, y: waterfall_top_y }
# end
#
# visited = []
# final_coords = []
# splash_coords = []
#
# while !active_columns.empty?
# new_columns = []
#
# active_columns.each do |segment|
# x = segment[:x]
# y = segment[:y]
# next if visited.include?([x, y])
#
# visited << [x, y]
#
# while y < map_height
# pos = [x, y]
# final_coords << pos
#
# if boulder_positions.include?(pos)
# splash_coords << [x - 1, y] if x > 0
# splash_coords << [x + 1, y] if x < $game_map.width - 1
# splash_coords << [x, y]
#
# new_y = y
# new_columns << { x: x - 1, y: new_y } if x > 0 && !visited.include?([x - 1, new_y])
# new_columns << { x: x + 1, y: new_y } if x < $game_map.width - 1 && !visited.include?([x + 1, new_y])
# break
# end
#
# #currents section
# if y > CIANWOOD_WATERFALL_EDGE+10
# if !$game_map.passable?(x, y + 1, DIRECTION_DOWN)
# splash_coords << [x, y + 1] if y + 1 < $game_map.height
# break
# end
# end
#
# if y == CIANWOOD_WATERFALL_EDGE
# splash_coords << [x, y]
# end
#
# if y == map_height
# splash_coords << [x, y]
# end
#
# y += 1
# end
# end
#
# active_columns = new_columns
# end
#
# $game_temp.temp_waterfall = final_coords.uniq
# $game_temp.splash_coords = splash_coords.uniq
# echoln $game_temp.temp_waterfall
# draw_waterfall_layer
# end
#
# def draw_waterfall_layer
# return if !$game_temp.temp_waterfall || $game_temp.temp_waterfall.empty?
#
# # Clear previous sprites
# if $game_temp.waterfall_sprites
# $game_temp.waterfall_sprites.each(&:dispose)
# end
# if $game_temp.splash_sprites
# $game_temp.splash_sprites.each(&:dispose)
# end
#
# $game_temp.waterfall_sprites = []
# $game_temp.splash_sprites = []
#
# tile_size = 32
# waterfall_tile_id = 0 # Waterfall
#
# splash_tile_id = 4 # Splash impact tile, assuming we have this in the tileset
# tileset = RPG::Cache.tileset($game_map.tileset_name)
#
# # Draw waterfall tiles
# $game_temp.temp_waterfall.each do |x, y|
# sprite = Sprite.new(Spriteset_Map.viewport)
#
# sprite.z = 10
# sprite.x = x * tile_size
# sprite.y = y * tile_size
#
# sprite.bitmap = Bitmap.new(tile_size, tile_size)
# source_rect = Rect.new(waterfall_tile_id * tile_size,0, tile_size, tile_size) # Frame 0
# sprite.bitmap.blt(0, 0, tileset, source_rect)
#
# # Store metadata for animation
# sprite.instance_variable_set(:@frame_offset, rand(3)) # Optional: make them start at different frames
# sprite.instance_variable_set(:@tile_x, x)
# sprite.instance_variable_set(:@tile_y, y)
#
# $game_temp.waterfall_sprites << sprite
# end
#
# # Draw splash impact tiles
# $game_temp.splash_coords.each do |x, y|
# sprite = Sprite.new(Spriteset_Map.viewport)
# sprite.z = 300 # Draw splash above the waterfall
# sprite.x = x * tile_size
# sprite.y = y * tile_size
#
# sprite.bitmap = Bitmap.new(tile_size, tile_size)
# source_rect = Rect.new(splash_tile_id * tile_size,1, tile_size, tile_size) # Splash frame 0
# sprite.bitmap.blt(0, 0, tileset, source_rect)
#
# # Store metadata for splash animation
# sprite.instance_variable_set(:@frame_offset, rand(3)) # Optional: make them start at different frames
# sprite.instance_variable_set(:@tile_x, x)
# sprite.instance_variable_set(:@tile_y, y)
#
# $game_temp.splash_sprites << sprite
# end
# end
#
#
#
#
# CIANWOOD_BOULDER_IDS = [2,3,5,6,
# 4 ]#chuck head
# CIANWOOD_WATERFALL_EDGE =19
#
#
# def player_on_temp_waterfall?
# return false if !$game_temp.temp_waterfall
#
# boulder_positions = []
# CIANWOOD_BOULDER_IDS.each do |event_id|
# event = $game_map.events[event_id]
# boulder_positions << [event.x, event.y]
# end
#
# # Return false if a boulder is directly below the player
# return false if boulder_positions.include?([$game_player.x, $game_player.y + 1])
#
# return $game_temp.temp_waterfall.any? { |x, y, _| x == $game_player.x && y == $game_player.y }
# end
#
#
#
#
#
#
#
# class Spriteset_Map
# alias_method :cianwood_waterfall_update, :update
# def update
# cianwood_waterfall_update
#
# waterfall_edge = CIANWOOD_WATERFALL_EDGE
# if $game_temp.waterfall_sprites
# frame_count = Graphics.frame_count
# tile_size = 32
# autotile_id = 0
# tileset = RPG::Cache.tileset($game_map.tileset_name)
#
# # Animate waterfall sprites
# $game_temp.waterfall_sprites.each do |sprite|
# tile_y = sprite.instance_variable_get(:@tile_y)
# frame_offset = sprite.instance_variable_get(:@frame_offset)
#
# # Animate every 15 frames (change for speed control)
# animation_frame = (frame_count / 15 + tile_y - frame_offset) % 4
#
# tileset_x = (autotile_id * 4 + animation_frame) * tile_size
# tileset_y = tile_y >= waterfall_edge ? tile_size : 0
# source_rect = Rect.new(tileset_x,tileset_y, tile_size, tile_size)
#
# sprite.bitmap.clear
# sprite.bitmap.blt(0, 0, tileset, source_rect)
#
# # Scroll with map
# sprite.ox = $game_map.display_x / 4
# sprite.oy = $game_map.display_y / 4
# end
#
# # Animate splash sprites
# $game_temp.splash_sprites.each do |sprite|
# tile_y = sprite.instance_variable_get(:@tile_y)
# frame_offset = sprite.instance_variable_get(:@frame_offset)
#
# # Animate every 10 frames for splash (you can adjust this speed)
# offset = (autotile_id * 4 + 4) * tile_size
# animation_frame = (frame_count / 10 + tile_y + frame_offset) % 4
# source_rect = Rect.new((autotile_id * 4 + animation_frame) * tile_size + offset, 0, tile_size, tile_size)
#
# sprite.bitmap.clear
# sprite.bitmap.blt(0, 0, tileset, source_rect)
#
# # Scroll with map
# sprite.ox = $game_map.display_x / 4
# sprite.oy = $game_map.display_y / 4
# end
# end
# end
# end
@@ -2,7 +2,7 @@
def oricorioEventPickFlower(flower_color)
quest_progression = pbGet(VAR_ORICORIO_FLOWERS)
if flower_color == :PINK
if !$game_switches[SWITCH_ORICORIO_QUEST_PINK]
if Settings::KANTO && !$game_switches[SWITCH_ORICORIO_QUEST_PINK]
pbMessage(_INTL("Woah! A Pokémon jumped out of the flower!"))
pbWildBattle(:FOMANTIS, 10)
end
@@ -28,6 +28,15 @@ def hasOricorioInParty()
end
def changeOricorioFlower(form = 1)
#guaranteed encounter first time you interact with a flower
if Settings::HOENN && !$game_switches[SWITCH_FOMANTIS_GUARANTEED_FLOWER]
pbMessage(_INTL("Woah! A Pokémon jumped out of the flower!"))
pbWildBattle(:FOMANTIS, 4)
$game_switches[SWITCH_FOMANTIS_GUARANTEED_FLOWER] = true
return
end
if $PokemonGlobal.stepcount % 25 == 0
if !hatUnlocked?(HAT_FLOWER) && rand(2) == 0
obtainHat(HAT_FLOWER)
@@ -118,7 +127,7 @@ def changeOricorioForm(pokemon, form = nil)
newForm = pokemon.isFusion? ? getSpeciesIdForFusion(head_number, body_number) : head_id
$Trainer.pokedex.set_seen(newForm)
$Trainer.pokedex.set_owned(newForm)
pokemon.pif_sprite = nil
pokemon.species = newForm
return true
end
@@ -1,5 +1,113 @@
def isOutdoor()
current_map = $game_map.map_id
def isOutdoor(current_map = nil)
current_map = $game_map.map_id if current_map.nil?
map_metadata = GameData::MapMetadata.try_get(current_map)
return map_metadata && map_metadata.outdoor_map
end
def find_random_walkable_coordinates_near_player(width, height, variance, max_nb_tries = 10)
max_nb_tries.times do
x, y = getRandomPositionOnPerimeter(width, height, $game_player.x, $game_player.y, variance)
return [x, y] if $game_map.playerPassable?(x, y, $game_player.direction)
end
return nil
end
def find_random_tall_grass_coordinates_near_player(width,height,variance,max_nb_tries = 10)
found_available_position = false
current_try = 0
while !found_available_position
x, y = getRandomPositionOnPerimeter(width, height, $game_player.x, $game_player.y, variance)
terrain = $game_map.terrain_tag(x, y)
found_available_position = terrain.land_wild_encounters
current_try += 1
return nil if current_try > max_nb_tries
end
encounter_type = :Land #default grass
encounter_type = :Land1 if terrain.id == :Grass_alt1
encounter_type = :Land2 if terrain.id == :Grass_alt2
encounter_type = :Land3 if terrain.id == :Grass_alt3
encounter_type = :TallGrass if terrain.id == :TallGrass
return [x,y],encounter_type
end
def find_random_surfable_coordinates_near_player(width,height,variance,max_nb_tries = 10)
found_available_position = false
current_try = 0
while !found_available_position
x, y = getRandomPositionOnPerimeter(width, height, $game_player.x, $game_player.y, variance)
terrain = $game_map.terrain_tag(x, y)
found_available_position = terrain.can_surf
current_try += 1
return nil if current_try > max_nb_tries
end
return [x,y]
end
def getRandomPositionOnPerimeter(width, height, center_x, center_y, variance=0,edge=nil)
half_width = width / 2.0
half_height = height / 2.0
# Randomly select one of the four edges of the rectangle
edge = rand(4) if !edge
case edge
when 0 # Top edge
random_x = center_x + rand(-half_width..half_width)
random_y = center_y - half_height
when 1 # Bottom edge
random_x = center_x + rand(-half_width..half_width)
random_y = center_y + half_height
when 2 # Left edge
random_x = center_x - half_width
random_y = center_y + rand(-half_height..half_height)
when 3 # Right edge
random_x = center_x + half_width
random_y = center_y + rand(-half_height..half_height)
end
return random_x.round, random_y.round
end
def setVariableToLeaderType(variable=5)
if $game_switches[SWITCH_RANDOM_TRAINERS]
gymArray = pbGet(VAR_GYM_TYPES_ARRAY)
else
gymArray = GYM_TYPES_ARRAY
end
currentGym = pbGet(VAR_CURRENT_GYM_TYPE)
typeIndex = gymArray[currentGym]
type = PBTypes.getName(typeIndex)
$game_variables[variable] = type
end
def increaseDarknessRadius(increase_by)
return unless $PokemonTemp.darknessSprite
$PokemonTemp.darknessSprite.radius += increase_by
end
def setDarknessRadius(value)
return unless $PokemonTemp.darknessSprite
echoln "setting to #{value}"
$PokemonTemp.darknessSprite.radius = value
end
Events.onMapChange += proc { |_sender, e|
$game_player.floating=false
$game_player.walk_anime = true
}
def showLocation(map_name=nil)
scene = $scene
if scene.is_a?(Scene_Map)
map_name = $game_map.name unless map_name
LocationWindow.new($game_map.name)
scene.spriteset.addUserSprite(LocationWindow.new(map_name))
end
end
@@ -28,11 +28,30 @@ def get_city_numerical_id(city_sym)
return current_city_numerical[city_sym]
end
# POKEMON_CENTER_MAP = 25
# POKEMON_CENTER_DOOR_POS = [10,10]
# POKEMON_CENTER_BIRTHDAY_MAP = 27
# def enter_pokemon_center
# pbSetPokemonCenter
# pokemon_center_map = isPlayerBirthDay? ? POKEMON_CENTER_BIRTHDAY_MAP : POKEMON_CENTER_MAP
# pbFadeOutIn {
# $game_temp.player_new_map_id = pokemon_center_map
# $game_temp.player_new_x = POKEMON_CENTER_DOOR_POS[0]
# $game_temp.player_new_y = POKEMON_CENTER_DOOR_POS[1]
# $scene.transfer_player(true)
# $game_map.autoplay
# $game_map.refresh
# }
# end
POKEMART_MAP_ID = 357
POKEMART_DOOR_POS = [12, 12]
# city -> Symbol
# used only in pif:kanto
def enter_pokemart(city)
pbSet(VAR_CURRENT_MART, city)
pbSet(VAR_CURRENT_CITY, city)
pbSet(VAR_CURRENT_CITY_NUMERICAL_ID, get_city_numerical_id(city))
echoln get_city_numerical_id(city)
pbFadeOutIn {
@@ -67,7 +86,7 @@ def exit_pokemart()
:OLIVINE => [138, 33, 23],
:CIANWOOD => [709.8, 46],
}
current_city = pbGet(VAR_CURRENT_MART)
current_city = pbGet(VAR_CURRENT_CITY)
current_city = :PEWTER if !current_city.is_a?(Symbol)
entrance_map = pokemart_entrances[current_city][0]
@@ -88,11 +107,16 @@ end
def reset_pokemart_variables
pbSet(VAR_CURRENT_CITY_NUMERICAL_ID, 0)
pbSet(VAR_CURRENT_MART, 0)
pbSet(VAR_CURRENT_CITY, 0)
end
def get_current_city_tag()
current_city = pbGet(VAR_CURRENT_CITY) if !current_city
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
end
def pokemart_clothes_shop(current_city = nil, include_defaults = true)
current_city = pbGet(VAR_CURRENT_MART) if !current_city
echoln current_city
current_city = pbGet(VAR_CURRENT_CITY) if !current_city
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
selector = OutfitSelector.new
@@ -105,7 +129,7 @@ def pokemart_clothes_shop(current_city = nil, include_defaults = true)
end
def pokemart_hat_shop(include_defaults = true)
current_city = pbGet(VAR_CURRENT_MART)
current_city = pbGet(VAR_CURRENT_CITY)
current_city = :PEWTER if !current_city.is_a?(Symbol)
current_city_tag = current_city.to_s.downcase
selector = OutfitSelector.new
@@ -119,7 +143,7 @@ def pokemart_hat_shop(include_defaults = true)
end
def get_mart_exclusive_items(city)
return get_mart_exclusive_items_hoenn if Settings::GAME_ID == :IF_HOENN
return get_mart_exclusive_items_hoenn(city) if Settings::GAME_ID == :IF_HOENN
items_list = []
case city
when :PEWTER;
@@ -170,4 +194,73 @@ def get_mart_exclusive_items(city)
items_list = []
end
return items_list
end
def get_mart_exclusive_items_hoenn(city)
items_list = []
case city
when :OLDALE
items_list = [:BERRYJUICE]
when :PETALBURG
items_list = [:POKETOY, :NESTBALL]
when :RUSTBORO
items_list = [:EVERSTONE, :LEVELBALL]
when :DEWFORD
items_list = [:RINGTARGET, :LUREBALL]
when :SLATEPORT
items_list = [:SOOTHEBELL, :NETBALL]
when :MAUVILLE
items_list = [:CELLBATTERY, :FASTBALL]
when :VERDANTURF
items_list = [:MENTALHERB, :LUXURYBALL]
when :LAVARIDGE
items_list = [:LAVACOOKIE, :REPEATBALL]
when :FALLARBOR
items_list = [:LIGHTCLAY, :HEAVYBALL]
when :FORTREE
items_list = [:ABSORBBULB, :FRIENDBALL]
when :LILYCOVE
items_list = [:METRONOME, :QUICKBALL,:TIMERBALL]
when :MOSSDEEP
items_list = [:AIRBALLOON, :MOONBALL]
when :SOOTOPOLIS
items_list = [:CLEANSETAG, :DUSKBALL]
when :EVERGRANDE
items_list = [:ABILITYURGE, :PUREBALL]
when :PACIFIDLOG
items_list = [:FLOATSTONE, :DIVEBALL]
end
return items_list
end
def regional_clothes_shop(regionTag)
selector = OutfitSelector.new
list = selector.generate_clothes_choice(
baseOptions = false,
additionalIds = [],
additionalTags = [regionTag],
filterOutTags = [])
clothesShop(list)
end
def regional_hats_shop(regionTag)
selector = OutfitSelector.new
list = selector.generate_hats_choice(
baseOptions = false,
additionalIds = [],
additionalTags = [regionTag],
filterOutTags = [])
hatShop(list)
end
def regional_hairstyle_shop(regionTag)
selector = OutfitSelector.new
list = selector.generate_hairstyle_choice(
baseOptions = false,
additionalIds = [],
additionalTags = [regionTag],
filterOutTags = [])
hairShop(list)
end