#=============================================================================== # General purpose utilities #=============================================================================== def _pbNextComb(comb, length) i = comb.length - 1 loop do valid = true (i...comb.length).each do |j| if j == i comb[j] += 1 else comb[j] = comb[i] + (j - i) end if comb[j] >= length valid = false break end end return true if valid i -= 1 break unless i >= 0 end return false end # Iterates through the array and yields each combination of _num_ elements in # the array. def pbEachCombination(array, num) return if array.length < num || num <= 0 if array.length == num yield array return elsif num == 1 array.each do |x| yield [x] end return end currentComb = [] arr = [] num.times { |i| currentComb[i] = i } loop do num.times { |i| arr[i] = array[currentComb[i]] } yield arr break unless _pbNextComb(currentComb, array.length) end end # Returns a language ID def pbGetLanguage case System.user_language[0..1] when "ja" then return 1 # Japanese when "en" then return 2 # English when "fr" then return 3 # French when "it" then return 4 # Italian when "de" then return 5 # German when "es" then return 7 # Spanish when "ko" then return 8 # Korean end return 2 # Use 'English' by default end # Converts a Celsius temperature to Fahrenheit. def toFahrenheit(celsius) return (celsius * 9.0 / 5.0).round + 32 end # Converts a Fahrenheit temperature to Celsius. def toCelsius(fahrenheit) return ((fahrenheit - 32) * 5.0 / 9.0).round end #=============================================================================== # Constants utilities #=============================================================================== # Unused def isConst?(val, mod, constant) begin return false if !mod.const_defined?(constant.to_sym) rescue return false end return (val == mod.const_get(constant.to_sym)) end # Unused def hasConst?(mod, constant) return false if !mod || constant.nil? return mod.const_defined?(constant.to_sym) rescue false end # Unused def getConst(mod, constant) return nil if !mod || constant.nil? return mod.const_get(constant.to_sym) rescue nil end # Unused def getID(mod, constant) return nil if !mod || constant.nil? if constant.is_a?(Symbol) || constant.is_a?(String) if (mod.const_defined?(constant.to_sym) rescue false) return mod.const_get(constant.to_sym) rescue 0 end return 0 end return constant end def getConstantName(mod, value) mod = Object.const_get(mod) if mod.is_a?(Symbol) mod.constants.each do |c| return c.to_s if mod.const_get(c.to_sym) == value end raise _INTL("Value {1} not defined by a constant in {2}", value, mod.name) end def getConstantNameOrValue(mod, value) mod = Object.const_get(mod) if mod.is_a?(Symbol) mod.constants.each do |c| return c.to_s if mod.const_get(c.to_sym) == value end return value.inspect end #=============================================================================== # Event utilities #=============================================================================== def pbTimeEvent(variableNumber, secs = 86_400) return if !$game_variables return if !variableNumber || variableNumber < 0 secs = 0 if secs < 0 timenow = pbGetTimeNow $game_variables[variableNumber] = [timenow.to_f, secs] $game_map&.refresh end def pbTimeEventDays(variableNumber, days = 0) return if !$game_variables return if !variableNumber || variableNumber < 0 days = 0 if days < 0 timenow = pbGetTimeNow time = timenow.to_f expiry = (time % 86_400.0) + (days * 86_400.0) $game_variables[variableNumber] = [time, expiry - time] $game_map&.refresh end def pbTimeEventValid(variableNumber) return false if !$game_variables return false if !variableNumber || variableNumber < 0 ret = false value = $game_variables[variableNumber] if value.is_a?(Array) timenow = pbGetTimeNow ret = (timenow.to_f - value[0] > value[1]) # value[1] is age in seconds ret = false if value[1] <= 0 # zero age end if !ret $game_variables[variableNumber] = 0 $game_map&.refresh end return ret end def pbExclaim(event, id = Settings::EXCLAMATION_ANIMATION_ID, tinting = false) if event.is_a?(Array) sprite = nil done = [] event.each do |i| next if done.include?(i.id) spriteset = $scene.spriteset(i.map_id) sprite ||= spriteset&.addUserAnimation(id, i.x, i.y, tinting, 2) done.push(i.id) end else spriteset = $scene.spriteset(event.map_id) sprite = spriteset&.addUserAnimation(id, event.x, event.y, tinting, 2) end until sprite.disposed? Graphics.update Input.update pbUpdateSceneMap end end def pbNoticePlayer(event) if !pbFacingEachOther(event, $game_player) pbExclaim(event) end pbTurnTowardEvent($game_player, event) pbMoveTowardPlayer(event) end #=============================================================================== # Player-related utilities, random name generator #=============================================================================== # Unused def pbGetPlayerGraphic id = $player.character_ID return "" if id < 1 meta = GameData::PlayerMetadata.get(id) return "" if !meta return GameData::TrainerType.player_front_sprite_filename(meta.trainer_type) end def pbGetTrainerTypeGender(trainer_type) return GameData::TrainerType.get(trainer_type).gender end def pbChangePlayer(id) return false if id < 1 meta = GameData::PlayerMetadata.get(id) return false if !meta $player.character_ID = id end def pbTrainerName(name = nil, outfit = 0) pbChangePlayer(1) if $player.character_ID < 1 if name.nil? name = pbEnterPlayerName(_INTL("Your name?"), 0, Settings::MAX_PLAYER_NAME_SIZE) if name.nil? || name.empty? player_metadata = GameData::PlayerMetadata.get($player.character_ID) trainer_type = (player_metadata) ? player_metadata.trainer_type : nil gender = pbGetTrainerTypeGender(trainer_type) name = pbSuggestTrainerName(gender) end end $player.name = name $player.outfit = outfit end def pbSuggestTrainerName(gender) userName = pbGetUserName userName = userName.gsub(/\s+.*$/, "") if userName.length > 0 && userName.length < Settings::MAX_PLAYER_NAME_SIZE userName[0, 1] = userName[0, 1].upcase return userName end userName = userName.gsub(/\d+$/, "") if userName.length > 0 && userName.length < Settings::MAX_PLAYER_NAME_SIZE userName[0, 1] = userName[0, 1].upcase return userName end userName = System.user_name.capitalize userName = userName[0, Settings::MAX_PLAYER_NAME_SIZE] return userName # Unreachable # return getRandomNameEx(gender, nil, 1, Settings::MAX_PLAYER_NAME_SIZE) end def pbGetUserName return System.user_name end def getRandomNameEx(type, variable, upper, maxLength = 100) return "" if maxLength <= 0 name = "" 50.times { name = "" formats = [] case type when 0 then formats = %w[F5 BvE FE FE5 FEvE] # Names for males when 1 then formats = %w[vE6 vEvE6 BvE6 B4 v3 vEv3 Bv3] # Names for females when 2 then formats = %w[WE WEU WEvE BvE BvEU BvEvE] # Neutral gender names else return "" end format = formats[rand(formats.length)] format.scan(/./) { |c| case c when "c" # consonant set = %w[b c d f g h j k l m n p r s t v w x z] name += set[rand(set.length)] when "v" # vowel set = %w[a a a e e e i i i o o o u u u] name += set[rand(set.length)] when "W" # beginning vowel set = %w[a a a e e e i i i o o o u u u au au ay ay ea ea ee ee oo oo ou ou] name += set[rand(set.length)] when "U" # ending vowel set = %w[a a a a a e e e i i i o o o o o u u ay ay ie ie ee ue oo] name += set[rand(set.length)] when "B" # beginning consonant set1 = %w[b c d f g h j k l l m n n p r r s s t t v w y z] set2 = %w[bl br ch cl cr dr fr fl gl gr kh kl kr ph pl pr sc sk sl sm sn sp st sw th tr tw vl zh] name += (rand(3) > 0) ? set1[rand(set1.length)] : set2[rand(set2.length)] when "E" # ending consonant set1 = %w[b c d f g h j k k l l m n n p r r s s t t v z] set2 = %w[bb bs ch cs ds fs ft gs gg ld ls nd ng nk rn kt ks ms ns ph pt ps sk sh sp ss st rd rn rp rm rt rk ns th zh] name += (rand(3) > 0) ? set1[rand(set1.length)] : set2[rand(set2.length)] when "f" # consonant and vowel set = %w[iz us or] name += set[rand(set.length)] when "F" # consonant and vowel set = %w[bo ba be bu re ro si mi zho se nya gru gruu glee gra glo ra do zo ri di ze go ga pree pro po pa ka ki ku de da ma mo le la li] name += set[rand(set.length)] when "2" set = %w[c f g k l p r s t] name += set[rand(set.length)] when "3" set = %w[nka nda la li ndra sta cha chie] name += set[rand(set.length)] when "4" set = %w[una ona ina ita ila ala ana ia iana] name += set[rand(set.length)] when "5" set = %w[e e o o ius io u u ito io ius us] name += set[rand(set.length)] when "6" set = %w[a a a elle ine ika ina ita ila ala ana] name += set[rand(set.length)] end } break if name.length <= maxLength } name = name[0, maxLength] case upper when 0 then name = name.upcase when 1 then name[0, 1] = name[0, 1].upcase end if $game_variables && variable $game_variables[variable] = name $game_map.need_refresh = true if $game_map end return name end def getRandomName(maxLength = 100) return getRandomNameEx(2, nil, nil, maxLength) end #=============================================================================== # Regional and National Pokédexes utilities #=============================================================================== # Returns the ID number of the region containing the player's current location, # as determined by the current map's metadata. def pbGetCurrentRegion(default = -1) return default if !$game_map map_pos = $game_map.metadata&.town_map_position return (map_pos) ? map_pos[0] : default end # Returns the Regional Pokédex number of the given species in the given Regional # Dex. The parameter "region" is zero-based. For example, if two regions are # defined, they would each be specified as 0 and 1. def pbGetRegionalNumber(region, species) dex_list = pbLoadRegionalDexes[region] return 0 if !dex_list || dex_list.length == 0 species_data = GameData::Species.try_get(species) return 0 if !species_data dex_list.each_with_index do |s, index| return index + 1 if s == species_data.species end return 0 end # Returns an array of all species in the given Regional Dex in that Dex's order. def pbAllRegionalSpecies(region_dex) return nil if region_dex < 0 dex_list = pbLoadRegionalDexes[region_dex] return nil if !dex_list || dex_list.length == 0 return dex_list.clone end # Returns the number of species in the given Regional Dex. Returns 0 if that # Regional Dex doesn't exist. If region_dex is a negative number, returns the # number of species in the National Dex (i.e. all species). def pbGetRegionalDexLength(region_dex) if region_dex < 0 ret = 0 GameData::Species.each_species { |s| ret += 1 } return ret end dex_list = pbLoadRegionalDexes[region_dex] return (dex_list) ? dex_list.length : 0 end #=============================================================================== # Other utilities #=============================================================================== def pbTextEntry(helptext, minlength, maxlength, variableNumber) $game_variables[variableNumber] = pbEnterText(helptext, minlength, maxlength) $game_map.need_refresh = true if $game_map end def pbMoveTutorAnnotations(move, movelist = nil) ret = [] $player.party.each_with_index do |pkmn, i| if pkmn.egg? ret[i] = _INTL("NOT ABLE") elsif pkmn.hasMove?(move) ret[i] = _INTL("LEARNED") else species = pkmn.species if movelist&.any? { |j| j == species } # Checked data from movelist given in parameter ret[i] = _INTL("ABLE") elsif pkmn.compatible_with_move?(move) # Checked data from Pokémon's tutor moves in pokemon.txt ret[i] = _INTL("ABLE") else ret[i] = _INTL("NOT ABLE") end end end return ret end def pbMoveTutorChoose(move, movelist = nil, bymachine = false, oneusemachine = false) ret = false move = GameData::Move.get(move).id if movelist.is_a?(Array) movelist.map! { |m| GameData::Move.get(m).id } end pbFadeOutIn { movename = GameData::Move.get(move).name annot = pbMoveTutorAnnotations(move, movelist) scene = PokemonParty_Scene.new screen = PokemonPartyScreen.new(scene, $player.party) screen.pbStartScene(_INTL("Teach which Pokémon?"), false, annot) loop do chosen = screen.pbChoosePokemon break if chosen < 0 pokemon = $player.party[chosen] if pokemon.egg? pbMessage(_INTL("Eggs can't be taught any moves.")) { screen.pbUpdate } elsif pokemon.shadowPokemon? pbMessage(_INTL("Shadow Pokémon can't be taught any moves.")) { screen.pbUpdate } elsif movelist && !movelist.any? { |j| j == pokemon.species } pbMessage(_INTL("{1} can't learn {2}.", pokemon.name, movename)) { screen.pbUpdate } elsif !pokemon.compatible_with_move?(move) pbMessage(_INTL("{1} can't learn {2}.", pokemon.name, movename)) { screen.pbUpdate } elsif pbLearnMove(pokemon, move, false, bymachine) { screen.pbUpdate } $stats.moves_taught_by_item += 1 if bymachine $stats.moves_taught_by_tutor += 1 if !bymachine pokemon.add_first_move(move) if oneusemachine ret = true break end end screen.pbEndScene } return ret # Returns whether the move was learned by a Pokemon end def pbConvertItemToItem(variable, array) item = GameData::Item.get(pbGet(variable)) pbSet(variable, nil) (array.length / 2).times do |i| next if item != array[2 * i] pbSet(variable, array[(2 * i) + 1]) return end end def pbConvertItemToPokemon(variable, array) item = GameData::Item.get(pbGet(variable)) pbSet(variable, nil) (array.length / 2).times do |i| next if item != array[2 * i] pbSet(variable, GameData::Species.get(array[(2 * i) + 1]).id) return end end # Gets the value of a variable. def pbGet(id) return 0 if !id || !$game_variables return $game_variables[id] end # Sets the value of a variable. def pbSet(id, value) return if !id || id < 0 $game_variables[id] = value if $game_variables $game_map.need_refresh = true if $game_map end # Runs a common event and waits until the common event is finished. # Requires the script "Messages" def pbCommonEvent(id) return false if id < 0 ce = $data_common_events[id] return false if !ce celist = ce.list interp = Interpreter.new interp.setup(celist, 0) loop do Graphics.update Input.update interp.update pbUpdateSceneMap break unless interp.running? end return true end def pbHideVisibleObjects visibleObjects = [] ObjectSpace.each_object(Sprite) { |o| if !o.disposed? && o.visible visibleObjects.push(o) o.visible = false end } ObjectSpace.each_object(Viewport) { |o| if !pbDisposed?(o) && o.visible visibleObjects.push(o) o.visible = false end } ObjectSpace.each_object(Plane) { |o| if !o.disposed? && o.visible visibleObjects.push(o) o.visible = false end } ObjectSpace.each_object(Tilemap) { |o| if !o.disposed? && o.visible visibleObjects.push(o) o.visible = false end } ObjectSpace.each_object(Window) { |o| if !o.disposed? && o.visible visibleObjects.push(o) o.visible = false end } return visibleObjects end def pbShowObjects(visibleObjects) visibleObjects.each do |o| next if pbDisposed?(o) o.visible = true end end def pbLoadRpgxpScene(scene) return if !$scene.is_a?(Scene_Map) oldscene = $scene $scene = scene Graphics.freeze oldscene.disposeSpritesets visibleObjects = pbHideVisibleObjects Graphics.transition Graphics.freeze while $scene && !$scene.is_a?(Scene_Map) $scene.main end Graphics.transition Graphics.freeze $scene = oldscene $scene.createSpritesets pbShowObjects(visibleObjects) Graphics.transition end def pbChooseLanguage commands = [] Settings::LANGUAGES.each do |lang| commands.push(lang[0]) end return pbShowCommands(nil, commands) end def pbScreenCapture t = pbGetTimeNow filestart = t.strftime("[%Y-%m-%d] %H_%M_%S.%L") capturefile = RTP.getSaveFileName(sprintf("%s.png", filestart)) Graphics.screenshot(capturefile) pbSEPlay("Pkmn exp full") if FileTest.audio_exist?("Audio/SE/Pkmn exp full") end