From efea53aa5a85bac3f61c9f0bd0e27b867485243c Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Wed, 23 Aug 2023 21:08:32 +0100 Subject: [PATCH 01/21] =?UTF-8?q?Fixed=20Pok=C3=A9dex=20showing=20genders?= =?UTF-8?q?=20for=20the=20wrong=20species,=20fixed=20AI=20always=20switchi?= =?UTF-8?q?ng=20sleeping/frozen=20Pok=C3=A9mon,=20fixed=20class=20PngAnima?= =?UTF-8?q?tedBitmap=20animating=20slowly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb | 6 +++--- Data/Scripts/011_Battle/005_AI/002_AI_Switch.rb | 6 ++++-- Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb | 3 ++- Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb | 2 +- .../020_Debug/003_Debug menus/002_Debug_MenuCommands.rb | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb b/Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb index dbb3761f0..9cdf1b363 100644 --- a/Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb +++ b/Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb @@ -48,14 +48,14 @@ class PngAnimatedBitmap if filename[/^\[(\d+)(?:,(\d+))?\]/] # Starts with 1 or 2 numbers in brackets # File has a frame count numFrames = $1.to_i - duration = $2.to_i + duration = $2.to_i # In 1/20ths of a second duration = 5 if duration == 0 raise "Invalid frame count in #{filename}" if numFrames <= 0 raise "Invalid frame duration in #{filename}" if duration <= 0 if panorama.width % numFrames != 0 raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{filename}" end - @frame_duration = duration + @frame_duration = duration / 20.0 subWidth = panorama.width / numFrames numFrames.times do |i| subBitmap = Bitmap.new(subWidth, panorama.height) @@ -99,7 +99,7 @@ class PngAnimatedBitmap # Actually returns the total number of 1/20ths of a second this animation lasts. def totalFrames - return @frame_duration * @frames.length + return (@frame_duration * @frames.length * 20).to_i end def each diff --git a/Data/Scripts/011_Battle/005_AI/002_AI_Switch.rb b/Data/Scripts/011_Battle/005_AI/002_AI_Switch.rb index f00ca35ad..3867794b8 100644 --- a/Data/Scripts/011_Battle/005_AI/002_AI_Switch.rb +++ b/Data/Scripts/011_Battle/005_AI/002_AI_Switch.rb @@ -408,8 +408,10 @@ Battle::AI::Handlers::ShouldSwitch.add(:asleep, end # Doesn't have sufficiently raised stats that would be lost by switching next false if battler.stages.any? { |key, val| val >= 2 } - # 50% chance to not bother - next false if ai.pbAIRandom(100) < 50 + # A reserve Pokémon is awake and not frozen + next false if reserves.none? { |pkmn| ![:SLEEP, :FROZEN].include?(pkmn.status) } + # 60% chance to not bother + next false if ai.pbAIRandom(100) < 60 PBDebug.log_ai("#{battler.name} wants to switch because it is asleep and can't do anything") next true } diff --git a/Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb b/Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb index 2fc420528..1d02c079d 100644 --- a/Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb +++ b/Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb @@ -342,7 +342,8 @@ class Battle::AI if @trainer.high_skill? && @user.can_switch_lax? badMoves = false if max_score <= MOVE_USELESS_SCORE - badMoves = true + badMoves = user_battler.can_attack? + badMoves = true if !badMoves && pbAIRandom(100) < 25 elsif max_score < MOVE_BASE_SCORE * move_score_threshold && user_battler.turnCount > 2 badMoves = true if pbAIRandom(100) < 80 end diff --git a/Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb b/Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb index 25be87921..c5abc1c6c 100644 --- a/Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb +++ b/Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb @@ -154,7 +154,7 @@ class PokemonPokedexInfo_Scene def pbGetAvailableForms ret = [] multiple_forms = false - gender_differences = (GameData::Species.front_sprite_filename(@species, 0) == GameData::Species.front_sprite_filename(@species, 0, 1)) + gender_differences = (GameData::Species.front_sprite_filename(@species, 0) != GameData::Species.front_sprite_filename(@species, 0, 1)) # Find all genders/forms of @species that have been seen GameData::Species.each do |sp| next if sp.species != @species diff --git a/Data/Scripts/020_Debug/003_Debug menus/002_Debug_MenuCommands.rb b/Data/Scripts/020_Debug/003_Debug menus/002_Debug_MenuCommands.rb index 99c875507..6dd0c35a3 100644 --- a/Data/Scripts/020_Debug/003_Debug menus/002_Debug_MenuCommands.rb +++ b/Data/Scripts/020_Debug/003_Debug menus/002_Debug_MenuCommands.rb @@ -126,7 +126,7 @@ MenuHandlers.add(:debug_menu, :safari_zone_and_bug_contest, { break end end - when 1 # Safari Balls + when 1 # Sport Balls params = ChooseNumberParams.new params.setRange(0, 99999) params.setDefaultValue(contest.ballcount) @@ -162,7 +162,7 @@ MenuHandlers.add(:debug_menu, :edit_field_effects, { params = ChooseNumberParams.new params.setRange(0, 99999) params.setDefaultValue($PokemonGlobal.repel) - $PokemonGlobal.repel = pbMessageChooseNumber(_INTL("Set the Pokémon's level."), params) + $PokemonGlobal.repel = pbMessageChooseNumber(_INTL("Set the number of steps remaining."), params) when 1 # Strength used $PokemonMap.strengthUsed = !$PokemonMap.strengthUsed when 2 # Flash used From 02e45ebf194bb5cf362766afcc46ef12fd42d778 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 10 Sep 2023 15:59:14 +0100 Subject: [PATCH 02/21] NamedEvents can now be overwritten, fixed error in validating all types, replaced wiki shortcut --- Data/Scripts/003_Game processing/005_Event_Handlers.rb | 2 +- Data/Scripts/010_Data/001_GameData.rb | 2 +- Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb | 6 +++--- Essentials Docs Wiki.URL => Essentials Engine wiki.url | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename Essentials Docs Wiki.URL => Essentials Engine wiki.url (53%) diff --git a/Data/Scripts/003_Game processing/005_Event_Handlers.rb b/Data/Scripts/003_Game processing/005_Event_Handlers.rb index 9986977bb..8e6f098cc 100644 --- a/Data/Scripts/003_Game processing/005_Event_Handlers.rb +++ b/Data/Scripts/003_Game processing/005_Event_Handlers.rb @@ -70,7 +70,7 @@ class NamedEvent # Adds an event handler procedure from the event. def add(key, proc) - @callbacks[key] = proc if !@callbacks.has_key?(key) + @callbacks[key] = proc end # Removes an event handler procedure from the event. diff --git a/Data/Scripts/010_Data/001_GameData.rb b/Data/Scripts/010_Data/001_GameData.rb index f413c04e9..ccfd971a2 100644 --- a/Data/Scripts/010_Data/001_GameData.rb +++ b/Data/Scripts/010_Data/001_GameData.rb @@ -190,7 +190,7 @@ module GameData return self::DATA.keys end - # Yields all data in numberical order. + # Yields all data in numerical order. def each keys = self::DATA.keys.sort keys.each { |key| yield self::DATA[key] } diff --git a/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb b/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb index cd07c91f4..7f97840b1 100644 --- a/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb +++ b/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb @@ -159,15 +159,15 @@ module Compiler # Ensure all weaknesses/resistances/immunities are valid types type.weaknesses.each do |other_type| next if GameData::Type.exists?(other_type) - raise _INTL("'{1}' is not a defined type ({2}, section {3}, Weaknesses).", other_type.to_s, path, type.id) + raise _INTL("'{1}' is not a defined type (type {2}, Weaknesses).", other_type.to_s, type.id) end type.resistances.each do |other_type| next if GameData::Type.exists?(other_type) - raise _INTL("'{1}' is not a defined type ({2}, section {3}, Resistances).", other_type.to_s, path, type.id) + raise _INTL("'{1}' is not a defined type (type {2}, Resistances).", other_type.to_s, type.id) end type.immunities.each do |other_type| next if GameData::Type.exists?(other_type) - raise _INTL("'{1}' is not a defined type ({2}, section {3}, Immunities).", other_type.to_s, path, type.id) + raise _INTL("'{1}' is not a defined type (type {2}, Immunities).", other_type.to_s, type.id) end # Get type names for translating type_names.push(type.real_name) diff --git a/Essentials Docs Wiki.URL b/Essentials Engine wiki.url similarity index 53% rename from Essentials Docs Wiki.URL rename to Essentials Engine wiki.url index 21c27ec09..2ad21b529 100644 --- a/Essentials Docs Wiki.URL +++ b/Essentials Engine wiki.url @@ -1,5 +1,5 @@ [{000214A0-0000-0000-C000-000000000046}] Prop3=19,11 [InternetShortcut] -URL=https://essentialsdocs.fandom.com/wiki/Essentials_Docs_Wiki +URL=https://essentialsengine.miraheze.org/wiki/Essentials_Engine_wiki IDList= From 8f0030768508eacee7ba3186eeae9c16c4712a68 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 10 Sep 2023 16:26:05 +0100 Subject: [PATCH 03/21] Made Voltorb Flip board generation more accurate to HGSS --- .../017_Minigames/004_Minigame_VoltorbFlip.rb | 324 ++++++++++++------ 1 file changed, 212 insertions(+), 112 deletions(-) diff --git a/Data/Scripts/017_Minigames/004_Minigame_VoltorbFlip.rb b/Data/Scripts/017_Minigames/004_Minigame_VoltorbFlip.rb index 5166777e9..a4bd988bd 100644 --- a/Data/Scripts/017_Minigames/004_Minigame_VoltorbFlip.rb +++ b/Data/Scripts/017_Minigames/004_Minigame_VoltorbFlip.rb @@ -5,15 +5,113 @@ # Run with: pbVoltorbFlip #=============================================================================== class VoltorbFlip - # Ranges of total coins available in each level. - LEVEL_RANGES = [[20, 50], - [50, 100], - [100, 200], - [200, 350], - [350, 600], - [600, 1000], - [1000, 2000], - [2000, 3500]] + GRAPHICS_DIRECTORY = "Graphics/UI/Voltorb Flip/" + NUM_ROWS = 5 + NUM_COLUMNS = 5 + NUM_TILES = NUM_ROWS * NUM_COLUMNS + TILE_DISTRIBUTIONS = [ # Voltorbs, Twos, Threes, MaxFreePerRowOrCol, MaxFreeTotal + # NOTE: The MaxFree values are not inclusive. The board will only be valid + # if the corresponding counts are strictly less than these values. + # Level 1 + [ + [6, 3, 1, 3, 3], + [6, 0, 3, 2, 2], + [6, 5, 0, 3, 4], + [6, 2, 2, 3, 3], + [6, 4, 1, 3, 4] + ], + # Level 2 + [ + [7, 1, 3, 2, 3], + [7, 6, 0, 3, 4], + [7, 3, 2, 2, 3], + [7, 0, 4, 2, 3], + [7, 5, 1, 3, 4], + [7, 1, 3, 2, 2], + [7, 6, 0, 3, 3], + [7, 3, 2, 2, 2], + [7, 0, 4, 2, 2], + [7, 5, 1, 3, 3] + ], + # Level 3 + [ + [8, 2, 3, 2, 3], + [8, 7, 0, 3, 4], + [8, 4, 2, 3, 4], + [8, 1, 4, 2, 3], + [8, 6, 1, 4, 3], + [8, 2, 3, 2, 2], + [8, 7, 0, 3, 3], + [8, 4, 2, 3, 3], + [8, 1, 4, 2, 2], + [8, 6, 1, 3, 3] + ], + # Level 4 + [ + [8, 3, 3, 4, 3], + [8, 0, 5, 2, 3], + [10, 8, 0, 4, 5], + [10, 5, 2, 3, 4], + [10, 2, 4, 3, 4], + [8, 3, 3, 3, 3], + [8, 0, 5, 2, 2], + [10, 8, 0, 4, 4], + [10, 5, 2, 3, 3], + [10, 2, 4, 3, 3] + ], + # Level 5 + [ + [10, 7, 1, 4, 5], + [10, 4, 3, 3, 4], + [10, 1, 5, 3, 4], + [10, 9, 0, 4, 5], + [10, 6, 2, 4, 5], + [10, 7, 1, 4, 4], + [10, 4, 3, 3, 3], + [10, 1, 5, 3, 3], + [10, 9, 0, 4, 4], + [10, 6, 2, 4, 4] + ], + # Level 6 + [ + [10, 3, 4, 3, 4], + [10, 0, 6, 3, 4], + [10, 8, 1, 4, 5], + [10, 5, 3, 4, 5], + [10, 2, 5, 3, 4], + [10, 3, 4, 3, 3], + [10, 0, 6, 3, 3], + [10, 8, 1, 4, 4], + [10, 5, 3, 4, 4], + [10, 2, 5, 3, 3] + ], + # Level 7 + [ + [10, 7, 2, 4, 5], + [10, 4, 4, 4, 5], + [13, 1, 6, 3, 4], + [13, 9, 1, 5, 6], + [10, 6, 3, 4, 5], + [10, 7, 2, 4, 4], + [10, 4, 4, 4, 4], + [13, 1, 6, 3, 3], + [13, 9, 1, 5, 5], + [10, 6, 3, 4, 4] + ], + # Level 8 + [ + [10, 0, 7, 3, 4], + [10, 8, 2, 5, 6], + [10, 5, 4, 4, 5], + [10, 2, 6, 4, 5], + [10, 7, 3, 5, 6], + [10, 0, 7, 3, 3], + [10, 8, 2, 5, 5], + [10, 5, 4, 4, 4], + [10, 2, 6, 4, 4], + [10, 7, 3, 5, 5] + ] + ] def update pbUpdateSpriteHash(@sprites) @@ -25,6 +123,50 @@ class VoltorbFlip pbNewGame end + def generate_board + ret = [] + 1000.times do |attempt| + board_distro = TILE_DISTRIBUTIONS[@level - 1].sample + # Randomly distribute tiles + ret = [1] * NUM_TILES + index = 0 + [0, 2, 3].each do |value| + qty = board_distro[[value - 1, 0].max] + qty.times do |i| + ret[index] = value + index += 1 + end + end + ret.shuffle! + # Find how many Voltorbs are in each row/column + row_voltorbs = [0] * NUM_ROWS + col_voltorbs = [0] * NUM_COLUMNS + ret.each_with_index do |val, i| + next if val != 0 + row_voltorbs[i / NUM_COLUMNS] += 1 + col_voltorbs[i % NUM_COLUMNS] += 1 + end + # Count the number of x2 and x3 tiles are free (i.e. no Voltorbs in its row/column) + free_multipliers = 0 + free_row = [0] * NUM_ROWS + free_col = [0] * NUM_COLUMNS + ret.each_with_index do |val, i| + next if val <= 1 + next if row_voltorbs[i / NUM_COLUMNS] > 0 && col_voltorbs[i % NUM_COLUMNS] > 0 + free_multipliers += 1 + free_row[i / NUM_COLUMNS] += 1 + free_col[i % NUM_COLUMNS] += 1 + end + # Regnerate board if there are too many free multiplier tiles + next if free_multipliers >= board_distro[4] + next if free_row.any? { |i| i >= board_distro[3] } + next if free_col.any? { |i| i >= board_distro[3] } + # Board is valid; use it + break + end + return ret + end + def pbNewGame # Initialize variables @sprites = {} @@ -35,54 +177,17 @@ class VoltorbFlip @voltorbNumbers = [] @points = 0 @index = [0, 0] - # [x,y,points,selected] - @squares = [0, 0, 0, false] - @directory = "Graphics/UI/Voltorb Flip/" - squareValues = [] - total = 1 - voltorbs = 0 - 25.times do |i| - # Sets the value to 1 by default - squareValues[i] = 1 - # Sets the value to 0 (a voltorb) if # for that level hasn't been reached - if voltorbs < 5 + @level - squareValues[i] = 0 - voltorbs += 1 - # Sets the value randomly to a 2 or 3 if the total is less than the max - elsif total < LEVEL_RANGES[@level - 1][1] - squareValues[i] = rand(2..3) - total *= squareValues[i] - end - next if total <= LEVEL_RANGES[@level - 1][1] - # Lowers value of square to 1 if over max - total /= squareValues[i] - squareValues[i] = 1 - end - # Randomize the values a little - 25.times do |i| - temp = squareValues[i] - if squareValues[i] > 1 && rand(10) == 0 - total /= squareValues[i] - squareValues[i] -= 1 - total *= squareValues[i] - end - next if total >= LEVEL_RANGES[@level - 1][0] || squareValues[i] <= 0 - total /= squareValues[i] - squareValues[i] = temp - total *= squareValues[i] - end - # Populate @squares array - 25.times do |i| - r = rand(squareValues.length) - @squares[i] = [((i % 5) * 64) + 128, (i / 5).abs * 64, squareValues[r], false] - squareValues.delete_at(r) + @squares = [] # Each square is [x, y, points, revealed] + # Generate a board + squareValues = generate_board + # Apply the generated board + squareValues.each_with_index do |val, i| + @squares[i] = [((i % NUM_COLUMNS) * 64) + 128, (i / NUM_COLUMNS).abs * 64, val, false] end pbCreateSprites # Display numbers (all zeroes, as no values have been calculated yet) - 5.times do |i| - pbUpdateRowNumbers(0, 0, i) - pbUpdateColumnNumbers(0, 0, i) - end + NUM_ROWS.times { |i| pbUpdateRowNumbers(0, 0, i) } + NUM_COLUMNS.times { |i| pbUpdateColumnNumbers(0, 0, i) } pbDrawShadowText(@sprites["text"].bitmap, 8, 22, 118, 26, _INTL("Your coins"), Color.new(60, 60, 60), Color.new(150, 190, 170), 1) pbDrawShadowText(@sprites["text"].bitmap, 8, 88, 118, 26, @@ -122,27 +227,27 @@ class VoltorbFlip @voltorbNumbers = [] @numbers = [] # Draw numbers for each row (precautionary) - @squares.length.times do |i| - next if (i % 5) != 0 + NUM_ROWS.times do |j| num = 0 voltorbs = 0 - j = i + 5 - (i...j).each do |k| - num += @squares[k][2] - voltorbs += 1 if @squares[k][2] == 0 + NUM_COLUMNS.times do |i| + val = @squares[i + (j * NUM_COLUMNS)][2] + num += val + voltorbs += 1 if val == 0 end - pbUpdateRowNumbers(num, voltorbs, i / 5) + pbUpdateRowNumbers(num, voltorbs, j) end # Reset arrays to empty @voltorbNumbers = [] @numbers = [] # Draw numbers for each column - 5.times do |i| + NUM_COLUMNS.times do |i| num = 0 voltorbs = 0 - 5.times do |j| - num += @squares[i + (j * 5)][2] - voltorbs += 1 if @squares[i + (j * 5)][2] == 0 + NUM_ROWS.times do |j| + val = @squares[i + (j * NUM_COLUMNS)][2] + num += val + voltorbs += 1 if val == 0 end pbUpdateColumnNumbers(num, voltorbs, i) end @@ -153,7 +258,7 @@ class VoltorbFlip @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height) @viewport.z = 99999 @sprites["bg"] = Sprite.new(@viewport) - @sprites["bg"].bitmap = RPG::Cache.load_bitmap(@directory, _INTL("Voltorb Flip bg")) + @sprites["bg"].bitmap = RPG::Cache.load_bitmap(GRAPHICS_DIRECTORY, _INTL("Voltorb Flip bg")) @sprites["text"] = BitmapSprite.new(Graphics.width, Graphics.height, @viewport) pbSetSystemFont(@sprites["text"].bitmap) @sprites["level"] = BitmapSprite.new(Graphics.width, Graphics.height, @viewport) @@ -177,7 +282,7 @@ class VoltorbFlip @sprites["icon"].z = 99997 @sprites["mark"] = BitmapSprite.new(Graphics.width, Graphics.height, @viewport) @sprites["memo"] = Sprite.new(@viewport) - @sprites["memo"].bitmap = RPG::Cache.load_bitmap(@directory, _INTL("memo")) + @sprites["memo"].bitmap = RPG::Cache.load_bitmap(GRAPHICS_DIRECTORY, _INTL("memo")) @sprites["memo"].x = 10 @sprites["memo"].y = 244 @sprites["memo"].visible = false @@ -195,20 +300,20 @@ class VoltorbFlip icons = [] points = 0 3.times do |i| - 25.times do |j| + NUM_TILES.times do |j| points = @squares[j][2] if i == 2 - icons[j] = [@directory + "tiles", @squares[j][0], @squares[j][1], 320 + (i * 64) + (points * 64), 0, 64, 64] + icons[j] = [GRAPHICS_DIRECTORY + "tiles", @squares[j][0], @squares[j][1], 320 + (i * 64) + (points * 64), 0, 64, 64] end icons.compact! pbDrawImagePositions(@sprites[i].bitmap, icons) end icons = [] - 25.times do |i| - icons[i] = [@directory + "tiles", @squares[i][0], @squares[i][1], @squares[i][2] * 64, 0, 64, 64] + NUM_TILES.times do |i| + icons[i] = [GRAPHICS_DIRECTORY + "tiles", @squares[i][0], @squares[i][1], @squares[i][2] * 64, 0, 64, 64] end pbDrawImagePositions(@sprites[5].bitmap, icons) # Default cursor image - @cursor[0] = [@directory + "cursor", 0 + 128, 0, 0, 0, 64, 64] + @cursor[0] = [GRAPHICS_DIRECTORY + "cursor", 0 + 128, 0, 0, 0, 64, 64] end def getInput @@ -257,7 +362,7 @@ class VoltorbFlip end (@marks.length + 1).times do |i| if @marks[i].nil? - @marks[i] = [@directory + "tiles", (@index[0] * 64) + 128, @index[1] * 64, 256, 0, 64, 64] + @marks[i] = [GRAPHICS_DIRECTORY + "tiles", (@index[0] * 64) + 128, @index[1] * 64, 256, 0, 64, 64] elsif @marks[i][1] == (@index[0] * 64) + 128 && @marks[i][2] == @index[1] * 64 @marks.delete_at(i) @marks.compact! @@ -281,7 +386,7 @@ class VoltorbFlip # Part1 animation = [] 3.times do |j| - animation[0] = icons[0] = [@directory + "tiles", (@index[0] * 64) + 128, @index[1] * 64, + animation[0] = icons[0] = [GRAPHICS_DIRECTORY + "tiles", (@index[0] * 64) + 128, @index[1] * 64, 704 + (64 * j), 0, 64, 64] pbDrawImagePositions(@sprites["animation"].bitmap, animation) pbWait(0.05) @@ -290,7 +395,7 @@ class VoltorbFlip # Part2 animation = [] 6.times do |j| - animation[0] = [@directory + "explosion", (@index[0] * 64) - 32 + 128, (@index[1] * 64) - 32, + animation[0] = [GRAPHICS_DIRECTORY + "explosion", (@index[0] * 64) - 32 + 128, (@index[1] * 64) - 32, j * 128, 0, 128, 128] pbDrawImagePositions(@sprites["animation"].bitmap, animation) pbWait(0.1) @@ -302,14 +407,10 @@ class VoltorbFlip @sprites["mark"].bitmap.clear if @level > 1 # Determine how many levels to reduce by - newLevel = 0 - @squares.length.times do |j| - newLevel += 1 if @squares[j][3] == true && @squares[j][2] > 1 - end - newLevel = @level if newLevel > @level - if @level > newLevel + newLevel = @squares.count { |tile| tile[3] && tile[2] > 0 } + newLevel = newLevel.clamp(@level, 1) + if newLevel < @level @level = newLevel - @level = 1 if @level < 1 pbMessage("\\se[Voltorb Flip level down]" + _INTL("Dropped to Game Lv. {1}!", @level.to_s)) end end @@ -321,10 +422,8 @@ class VoltorbFlip pbUpdateCoins # Revert numbers to 0s @sprites["numbers"].bitmap.clear - 5.times do |j| - pbUpdateRowNumbers(0, 0, j) - pbUpdateColumnNumbers(0, 0, j) - end + NUM_ROWS.times { |j| pbUpdateRowNumbers(0, 0, j) } + NUM_COLUMNS.times { |j| pbUpdateColumnNumbers(0, 0, j) } pbDisposeSpriteHash(@sprites) @firstRound = false pbNewGame @@ -332,7 +431,7 @@ class VoltorbFlip # Play tile animation animation = [] 4.times do |j| - animation[0] = [@directory + "flipAnimation", (@index[0] * 64) - 14 + 128, (@index[1] * 64) - 16, + animation[0] = [GRAPHICS_DIRECTORY + "flipAnimation", (@index[0] * 64) - 14 + 128, (@index[1] * 64) - 16, j * 92, 0, 92, 96] pbDrawImagePositions(@sprites["animation"].bitmap, animation) pbWait(0.05) @@ -375,10 +474,8 @@ class VoltorbFlip pbShowAndDispose # Revert numbers to 0s @sprites["numbers"].bitmap.clear - 5.times do |i| - pbUpdateRowNumbers(0, 0, i) - pbUpdateColumnNumbers(0, 0, i) - end + NUM_ROWS.times { |i| pbUpdateRowNumbers(0, 0, i) } + NUM_COLUMNS.times { |i| pbUpdateColumnNumbers(0, 0, i) } @sprites["curtain"].opacity = 100 if @level < 8 @level += 1 @@ -395,11 +492,11 @@ class VoltorbFlip elsif Input.trigger?(Input::ACTION) pbPlayDecisionSE @sprites["cursor"].bitmap.clear - if @cursor[0][3] == 0 # If in normal mode - @cursor[0] = [@directory + "cursor", 128, 0, 64, 0, 64, 64] + if @cursor[0][3] == 0 # If in normal mode + @cursor[0] = [GRAPHICS_DIRECTORY + "cursor", 128, 0, 64, 0, 64, 64] @sprites["memo"].visible = true - else # Mark mode - @cursor[0] = [@directory + "cursor", 128, 0, 0, 0, 64, 64] + else # Mark mode + @cursor[0] = [GRAPHICS_DIRECTORY + "cursor", 128, 0, 0, 0, 64, 64] @sprites["memo"].visible = false end elsif Input.trigger?(Input::BACK) @@ -431,9 +528,9 @@ class VoltorbFlip def pbUpdateRowNumbers(num, voltorbs, i) numText = sprintf("%02d", num) numText.chars.each_with_index do |digit, j| - @numbers[j] = [@directory + "numbersSmall", 472 + (j * 16), 8 + (i * 64), digit.to_i * 16, 0, 16, 16] + @numbers[j] = [GRAPHICS_DIRECTORY + "numbersSmall", 472 + (j * 16), 8 + (i * 64), digit.to_i * 16, 0, 16, 16] end - @voltorbNumbers[i] = [@directory + "numbersSmall", 488, 34 + (i * 64), voltorbs * 16, 0, 16, 16] + @voltorbNumbers[i] = [GRAPHICS_DIRECTORY + "numbersSmall", 488, 34 + (i * 64), voltorbs * 16, 0, 16, 16] # Display the numbers pbDrawImagePositions(@sprites["numbers"].bitmap, @numbers) pbDrawImagePositions(@sprites["numbers"].bitmap, @voltorbNumbers) @@ -442,9 +539,9 @@ class VoltorbFlip def pbUpdateColumnNumbers(num, voltorbs, i) numText = sprintf("%02d", num) numText.chars.each_with_index do |digit, j| - @numbers[j] = [@directory + "numbersSmall", 152 + (i * 64) + (j * 16), 328, digit.to_i * 16, 0, 16, 16] + @numbers[j] = [GRAPHICS_DIRECTORY + "numbersSmall", 152 + (i * 64) + (j * 16), 328, digit.to_i * 16, 0, 16, 16] end - @voltorbNumbers[i] = [@directory + "numbersSmall", 168 + (i * 64), 354, voltorbs * 16, 0, 16, 16] + @voltorbNumbers[i] = [GRAPHICS_DIRECTORY + "numbersSmall", 168 + (i * 64), 354, voltorbs * 16, 0, 16, 16] # Display the numbers pbDrawImagePositions(@sprites["numbers"].bitmap, @numbers) pbDrawImagePositions(@sprites["numbers"].bitmap, @voltorbNumbers) @@ -453,7 +550,7 @@ class VoltorbFlip def pbCreateCoins(source, y) coinText = sprintf("%05d", source) coinText.chars.each_with_index do |digit, i| - @coins[i] = [@directory + "numbersScore", 6 + (i * 24), y, digit.to_i * 24, 0, 24, 38] + @coins[i] = [GRAPHICS_DIRECTORY + "numbersScore", 6 + (i * 24), y, digit.to_i * 24, 0, 24, 38] end end @@ -473,11 +570,11 @@ class VoltorbFlip points = 0 3.times do |i| points = tile if i == 2 - icons[i] = [@directory + "tiles", x, y, 320 + (i * 64) + (points * 64), 0, 64, 64] + icons[i] = [GRAPHICS_DIRECTORY + "tiles", x, y, 320 + (i * 64) + (points * 64), 0, 64, 64] pbDrawImagePositions(@sprites["icon"].bitmap, icons) pbWait(0.05) end - icons[3] = [@directory + "tiles", x, y, tile * 64, 0, 64, 64] + icons[3] = [GRAPHICS_DIRECTORY + "tiles", x, y, tile * 64, 0, 64, 64] pbDrawImagePositions(@sprites["icon"].bitmap, icons) pbSEPlay("Voltorb Flip tile") end @@ -504,27 +601,30 @@ class VoltorbFlip end end # "Dispose" of tiles by column - 5.times do |i| + NUM_COLUMNS.times do |i| icons = [] pbSEPlay("Voltorb Flip tile") - 5.times do |j| - icons[j] = [@directory + "tiles", @squares[i + (j * 5)][0], @squares[i + (j * 5)][1], - 448 + (@squares[i + (j * 5)][2] * 64), 0, 64, 64] + NUM_ROWS.times do |j| + icons[j] = [GRAPHICS_DIRECTORY + "tiles", @squares[i + (j * NUM_COLUMNS)][0], @squares[i + (j * NUM_COLUMNS)][1], + 448 + (@squares[i + (j * NUM_COLUMNS)][2] * 64), 0, 64, 64] end pbDrawImagePositions(@sprites[i].bitmap, icons) pbWait(0.05) - 5.times do |j| - icons[j] = [@directory + "tiles", @squares[i + (j * 5)][0], @squares[i + (j * 5)][1], 384, 0, 64, 64] + NUM_ROWS.times do |j| + icons[j] = [GRAPHICS_DIRECTORY + "tiles", @squares[i + (j * NUM_COLUMNS)][0], @squares[i + (j * NUM_COLUMNS)][1], + 384, 0, 64, 64] end pbDrawImagePositions(@sprites[i].bitmap, icons) pbWait(0.05) - 5.times do |j| - icons[j] = [@directory + "tiles", @squares[i + (j * 5)][0], @squares[i + (j * 5)][1], 320, 0, 64, 64] + NUM_ROWS.times do |j| + icons[j] = [GRAPHICS_DIRECTORY + "tiles", @squares[i + (j * NUM_COLUMNS)][0], @squares[i + (j * NUM_COLUMNS)][1], + 320, 0, 64, 64] end pbDrawImagePositions(@sprites[i].bitmap, icons) pbWait(0.05) - 5.times do |j| - icons[j] = [@directory + "tiles", @squares[i + (j * 5)][0], @squares[i + (j * 5)][1], 896, 0, 64, 64] + NUM_ROWS.times do |j| + icons[j] = [GRAPHICS_DIRECTORY + "tiles", @squares[i + (j * NUM_COLUMNS)][0], @squares[i + (j * NUM_COLUMNS)][1], + 896, 0, 64, 64] end pbDrawImagePositions(@sprites[i].bitmap, icons) pbWait(0.05) From bc18aa95f22d68780647c3b357faf54df9314eb6 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 10 Sep 2023 16:57:09 +0100 Subject: [PATCH 04/21] Fixed Cramorant not reverting form after coughing up a Gulp Missle, fixed crash when a phone contact calls when you're on a map with no metadata --- .../011_Battle/002_Battler/010_Battler_UseMoveTriggerEffects.rb | 1 + Data/Scripts/013_Items/004_Item_Phone.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Data/Scripts/011_Battle/002_Battler/010_Battler_UseMoveTriggerEffects.rb b/Data/Scripts/011_Battle/002_Battler/010_Battler_UseMoveTriggerEffects.rb index 450d61e98..f35de8ff5 100644 --- a/Data/Scripts/011_Battle/002_Battler/010_Battler_UseMoveTriggerEffects.rb +++ b/Data/Scripts/011_Battle/002_Battler/010_Battler_UseMoveTriggerEffects.rb @@ -18,6 +18,7 @@ class Battle::Battler # target Cramorant attacking the user) and the ability splash # shouldn't be shown. @battle.pbShowAbilitySplash(target) + target.pbChangeForm(0, nil) if user.takesIndirectDamage?(Battle::Scene::USE_ABILITY_SPLASH) @battle.scene.pbDamageAnimation(user) user.pbReduceHP(user.totalhp / 4, false) diff --git a/Data/Scripts/013_Items/004_Item_Phone.rb b/Data/Scripts/013_Items/004_Item_Phone.rb index 374c1d87d..e4d4e9a7e 100644 --- a/Data/Scripts/013_Items/004_Item_Phone.rb +++ b/Data/Scripts/013_Items/004_Item_Phone.rb @@ -320,7 +320,7 @@ class Phone module_function def can_make? - return false if $game_map.metadata.has_flag?("NoPhoneSignal") + return false if $game_map.metadata&.has_flag?("NoPhoneSignal") return true end From b2c66b7b0c935c2f9ffbc0e4d3a74bbcaf43d0ef Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Thu, 21 Sep 2023 19:36:10 +0100 Subject: [PATCH 05/21] =?UTF-8?q?Fixed=20typo=20relating=20to=20AI=20switc?= =?UTF-8?q?hing,=20fixed=20Pok=C3=A9mon=20sent=20from=20the=20party=20to?= =?UTF-8?q?=20storage=20in=20battle=20not=20resetting=20their=20battle-onl?= =?UTF-8?q?y=20conditions,=20fixed=20player's=20sprite=20in=20Duel=20minig?= =?UTF-8?q?ame=20not=20caring=20about=20the=20player's=20outfit,=20added?= =?UTF-8?q?=20missing=20move=20flags?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data/Scripts/001_Settings.rb | 5 +++-- Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb | 2 +- .../007_Other battle code/005_Battle_CatchAndStoreMixin.rb | 7 ++++++- Data/Scripts/017_Minigames/001_Minigame_Duel.rb | 2 +- PBS/Gen 8 backup/moves.txt | 4 ++-- PBS/moves.txt | 4 ++-- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Data/Scripts/001_Settings.rb b/Data/Scripts/001_Settings.rb index 88edb57b9..f8b9f6315 100644 --- a/Data/Scripts/001_Settings.rb +++ b/Data/Scripts/001_Settings.rb @@ -197,7 +197,8 @@ module Settings end # The maximum number of slots per pocket (-1 means infinite number). BAG_MAX_POCKET_SIZE = [-1, -1, -1, -1, -1, -1, -1, -1] - # Whether each pocket in turn auto-sorts itself by item ID number. + # Whether each pocket in turn auto-sorts itself by the order items are defined + # in the PBS file items.txt. BAG_POCKET_AUTO_SORT = [false, false, false, true, true, false, false, false] # The maximum number of items each slot in the Bag can hold. BAG_MAX_PER_SLOT = 999 @@ -206,7 +207,7 @@ module Settings # The number of boxes in Pokémon storage. NUM_STORAGE_BOXES = 40 - # Whether putting a Pokémon into Pokémon storage will heal it. IF false, they + # Whether putting a Pokémon into Pokémon storage will heal it. If false, they # are healed by the Recover All: Entire Party event command (at Poké Centers). HEAL_STORED_POKEMON = (MECHANICS_GENERATION <= 7) diff --git a/Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb b/Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb index 1d02c079d..30f8e28cc 100644 --- a/Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb +++ b/Data/Scripts/011_Battle/005_AI/005_AI_ChooseMove.rb @@ -342,7 +342,7 @@ class Battle::AI if @trainer.high_skill? && @user.can_switch_lax? badMoves = false if max_score <= MOVE_USELESS_SCORE - badMoves = user_battler.can_attack? + badMoves = user.can_attack? badMoves = true if !badMoves && pbAIRandom(100) < 25 elsif max_score < MOVE_BASE_SCORE * move_score_threshold && user_battler.turnCount > 2 badMoves = true if pbAIRandom(100) < 80 diff --git a/Data/Scripts/011_Battle/007_Other battle code/005_Battle_CatchAndStoreMixin.rb b/Data/Scripts/011_Battle/007_Other battle code/005_Battle_CatchAndStoreMixin.rb index dae58025d..5d9c5f596 100644 --- a/Data/Scripts/011_Battle/007_Other battle code/005_Battle_CatchAndStoreMixin.rb +++ b/Data/Scripts/011_Battle/007_Other battle code/005_Battle_CatchAndStoreMixin.rb @@ -32,8 +32,13 @@ module Battle::CatchAndStoreMixin end next if party_index < 0 # Cancelled party_size = pbPlayer.party.length - # Send chosen Pokémon to storage + # Get chosen Pokémon and clear battle-related conditions send_pkmn = pbPlayer.party[party_index] + @peer.pbOnLeavingBattle(self, send_pkmn, @usedInBattle[0][party_index], true) + send_pkmn.statusCount = 0 if send_pkmn.status == :POISON # Bad poison becomes regular + send_pkmn.makeUnmega + send_pkmn.makeUnprimal + # Send chosen Pokémon to storage stored_box = @peer.pbStorePokemon(pbPlayer, send_pkmn) pbPlayer.party.delete_at(party_index) box_name = @peer.pbBoxName(stored_box) diff --git a/Data/Scripts/017_Minigames/001_Minigame_Duel.rb b/Data/Scripts/017_Minigames/001_Minigame_Duel.rb index 84720d60a..bebbd5264 100644 --- a/Data/Scripts/017_Minigames/001_Minigame_Duel.rb +++ b/Data/Scripts/017_Minigames/001_Minigame_Duel.rb @@ -60,7 +60,7 @@ class PokemonDuel @viewport.z = 99999 @sprites = {} @sprites["player"] = IconSprite.new(-160, 96, @viewport) - @sprites["player"].setBitmap(GameData::TrainerType.front_sprite_filename($player.trainer_type)) + @sprites["player"].setBitmap(GameData::TrainerType.player_front_sprite_filename($player.trainer_type)) @sprites["opponent"] = IconSprite.new(Graphics.width + 32, 96, @viewport) @sprites["opponent"].setBitmap(GameData::TrainerType.front_sprite_filename(opponent.trainer_type)) @sprites["playerwindow"] = DuelWindow.new($player.name, false) diff --git a/PBS/Gen 8 backup/moves.txt b/PBS/Gen 8 backup/moves.txt index 0ee30413b..fa5dbaf27 100644 --- a/PBS/Gen 8 backup/moves.txt +++ b/PBS/Gen 8 backup/moves.txt @@ -479,7 +479,7 @@ Accuracy = 100 TotalPP = 5 Target = NearOther FunctionCode = AlwaysCriticalHit -Flags = Contact,CanProtect,CanMirrorMove,CannotMetronome +Flags = Contact,CanProtect,CanMirrorMove,Punching,CannotMetronome Description = Strikes with a fierce blow through mastery of the Dark style. Always results in a critical hit. #------------------------------- [LASHOUT] @@ -8633,7 +8633,7 @@ Accuracy = 100 TotalPP = 5 Target = NearOther FunctionCode = HitThreeTimesAlwaysCriticalHit -Flags = Contact,CanProtect,CanMirrorMove,CannotMetronome +Flags = Contact,CanProtect,CanMirrorMove,Punching,CannotMetronome Description = Hits three times in a row with mastery of the Water style. This attack always deals critical hits. #------------------------------- [WATERSHURIKEN] diff --git a/PBS/moves.txt b/PBS/moves.txt index 0ee30413b..fa5dbaf27 100644 --- a/PBS/moves.txt +++ b/PBS/moves.txt @@ -479,7 +479,7 @@ Accuracy = 100 TotalPP = 5 Target = NearOther FunctionCode = AlwaysCriticalHit -Flags = Contact,CanProtect,CanMirrorMove,CannotMetronome +Flags = Contact,CanProtect,CanMirrorMove,Punching,CannotMetronome Description = Strikes with a fierce blow through mastery of the Dark style. Always results in a critical hit. #------------------------------- [LASHOUT] @@ -8633,7 +8633,7 @@ Accuracy = 100 TotalPP = 5 Target = NearOther FunctionCode = HitThreeTimesAlwaysCriticalHit -Flags = Contact,CanProtect,CanMirrorMove,CannotMetronome +Flags = Contact,CanProtect,CanMirrorMove,Punching,CannotMetronome Description = Hits three times in a row with mastery of the Water style. This attack always deals critical hits. #------------------------------- [WATERSHURIKEN] From d9c389812476580cf64820953e6dfa867737cd18 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sat, 23 Sep 2023 19:20:44 +0100 Subject: [PATCH 06/21] Fixed long battle messages displaying weirdly --- Data/Scripts/001_Settings.rb | 3 +-- .../005_SpriteWindow_text.rb | 14 +++++--------- .../011_Battle/004_Scene/001_Battle_Scene.rb | 6 ++++-- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Data/Scripts/001_Settings.rb b/Data/Scripts/001_Settings.rb index f8b9f6315..b96e5b924 100644 --- a/Data/Scripts/001_Settings.rb +++ b/Data/Scripts/001_Settings.rb @@ -259,7 +259,6 @@ module Settings [0, 51, 16, 15, "hidden_Berth", false], [0, 52, 20, 14, "hidden_Faraday", false] ] - # Whether the player can use Fly while looking at the Town Map. This is only # allowed if the player can use Fly normally. CAN_FLY_FROM_TOWN_MAP = true @@ -296,7 +295,7 @@ module Settings # * Level. # * Game Switch; the Pokémon roams while this is ON. # * Encounter type (0=any, 1=grass/walking in cave, 2=surfing, 3=fishing, - # 4=surfing/fishing). See the bottom of PField_RoamingPokemon for lists. + # 4=surfing/fishing). See the bottom of Overworld_RoamingPokemon for lists. # * Name of BGM to play for that encounter (optional). # * Roaming areas specifically for this Pokémon (optional). ROAMING_SPECIES = [ diff --git a/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb b/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb index ae8530dc4..94397150a 100644 --- a/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb +++ b/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb @@ -406,19 +406,15 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base return if !busy? return if @textchars[@curchar] == "\n" resume - visiblelines = (self.height - self.borderY) / @lineHeight - loop do - curcharSkip(true) - break if @curchar >= @fmtchars.length # End of message - if @textchars[@curchar] == "\1" # Pause message + if curcharSkip(true) + visiblelines = (self.height - self.borderY) / @lineHeight + if @textchars[@curchar] == "\n" && @linesdrawn >= visiblelines - 1 + @scroll_timer_start = System.uptime + elsif @textchars[@curchar] == "\1" @pausing = true if @curchar < @numtextchars - 1 self.startPause refresh - break end - break if @textchars[@curchar] != "\n" # Skip past newlines only - break if @linesdrawn >= visiblelines - 1 # No more empty lines to continue to - @linesdrawn += 1 end end diff --git a/Data/Scripts/011_Battle/004_Scene/001_Battle_Scene.rb b/Data/Scripts/011_Battle/004_Scene/001_Battle_Scene.rb index 2c64ec037..1b9498144 100644 --- a/Data/Scripts/011_Battle/004_Scene/001_Battle_Scene.rb +++ b/Data/Scripts/011_Battle/004_Scene/001_Battle_Scene.rb @@ -188,7 +188,7 @@ class Battle::Scene cw.setText(msg) PBDebug.log_message(msg) yielded = false - timer_start = System.uptime + timer_start = nil loop do pbUpdate(cw) if !cw.busy? @@ -202,6 +202,7 @@ class Battle::Scene @briefMessage = true break end + timer_start = System.uptime if !timer_start if System.uptime - timer_start >= MESSAGE_PAUSE_TIME # Autoclose after 1 second cw.text = "" cw.visible = false @@ -233,7 +234,7 @@ class Battle::Scene cw.text = msg + "\1" PBDebug.log_message(msg) yielded = false - timer_start = System.uptime + timer_start = nil loop do pbUpdate(cw) if !cw.busy? @@ -242,6 +243,7 @@ class Battle::Scene yielded = true end if !@battleEnd + timer_start = System.uptime if !timer_start if System.uptime - timer_start >= MESSAGE_PAUSE_TIME * 3 # Autoclose after 3 seconds cw.text = "" cw.visible = false From e96f16c48429c24487a672756a27356191c0dfde Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 1 Oct 2023 17:51:13 +0100 Subject: [PATCH 07/21] Tweaked Compiler error messages, made some in def cast_csv_value show if trying to cast nil --- .../001_Technical/005_PluginManager.rb | 2 +- Data/Scripts/021_Compiler/001_Compiler.rb | 108 +++++++++--------- .../021_Compiler/002_Compiler_CompilePBS.rb | 91 +++++++-------- 3 files changed, 97 insertions(+), 104 deletions(-) diff --git a/Data/Scripts/001_Technical/005_PluginManager.rb b/Data/Scripts/001_Technical/005_PluginManager.rb index b84f390ab..2a3947d00 100644 --- a/Data/Scripts/001_Technical/005_PluginManager.rb +++ b/Data/Scripts/001_Technical/005_PluginManager.rb @@ -411,7 +411,7 @@ module PluginManager Compiler.pbCompilerEachPreppedLine(filename) do |line, line_no| # split line up into property name and values if !line[/^\s*(\w+)\s*=\s*(.*)$/] - raise _INTL("Bad line syntax (expected syntax like XXX=YYY)\n{1}", FileLineData.linereport) + raise _INTL("Bad line syntax (expected syntax like XXX=YYY).") + "\n" + FileLineData.linereport end property = $~[1].upcase data = $~[2].split(",") diff --git a/Data/Scripts/021_Compiler/001_Compiler.rb b/Data/Scripts/021_Compiler/001_Compiler.rb index 0eb7a5de2..726975986 100644 --- a/Data/Scripts/021_Compiler/001_Compiler.rb +++ b/Data/Scripts/021_Compiler/001_Compiler.rb @@ -112,11 +112,11 @@ module Compiler else if sectionname.nil? FileLineData.setLine(line, lineno) - raise _INTL("Expected a section at the beginning of the file. This error may also occur if the file was not saved in UTF-8.\n{1}", FileLineData.linereport) + raise _INTL("Expected a section at the beginning of the file.\nThis error may also occur if the file was not saved in UTF-8.") + "\n" + FileLineData.linereport end if !line[/^\s*(\w+)\s*=\s*(.*)$/] FileLineData.setSection(sectionname, nil, line) - raise _INTL("Bad line syntax (expected syntax like XXX=YYY)\n{1}", FileLineData.linereport) + raise _INTL("Bad line syntax (expected syntax like XXX=YYY).") + "\n" + FileLineData.linereport end r1 = $~[1] r2 = $~[2] @@ -316,7 +316,7 @@ module Compiler end str[0, fieldbytes] = "" if !str[/^\s*,/] && !str[/^\s*$/] - raise _INTL("Invalid quoted field (in: {1})\n{2}", str, FileLineData.linereport) + raise _INTL("Invalid quoted field (in: {1}).", str) + "\n" + FileLineData.linereport end str[0, str.length] = $~.post_match else @@ -337,14 +337,14 @@ module Compiler field = csvfield!(str) return true if field[/^(?:1|TRUE|YES|Y)$/i] return false if field[/^(?:0|FALSE|NO|N)$/i] - raise _INTL("Field {1} is not a Boolean value (true, false, 1, 0)\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' is not a Boolean value (true, false, 1, 0).", field) + "\n" + FileLineData.linereport end # Unused def csvInt!(str, _line = -1) ret = csvfield!(str) if !ret[/^\-?\d+$/] - raise _INTL("Field {1} is not an integer\n{2}", ret, FileLineData.linereport) + raise _INTL("Field '{1}' is not an integer.", ret) + "\n" + FileLineData.linereport end return ret.to_i end @@ -353,7 +353,7 @@ module Compiler def csvPosInt!(str, _line = -1) ret = csvfield!(str) if !ret[/^\d+$/] - raise _INTL("Field {1} is not a positive integer\n{2}", ret, FileLineData.linereport) + raise _INTL("Field '{1}' is not a positive integer.", ret) + "\n" + FileLineData.linereport end return ret.to_i end @@ -361,7 +361,7 @@ module Compiler # Unused def csvFloat!(str, _line = -1) ret = csvfield!(str) - return Float(ret) rescue raise _INTL("Field {1} is not a number\n{2}", ret, FileLineData.linereport) + return Float(ret) rescue raise _INTL("Field '{1}' is not a number.", ret) + "\n" + FileLineData.linereport end # Unused @@ -384,52 +384,52 @@ module Compiler def cast_csv_value(value, schema, enumer = nil) case schema.downcase when "i" # Integer - if !value[/^\-?\d+$/] - raise _INTL("Field {1} is not an integer\n{2}", value, FileLineData.linereport) + if !value || !value[/^\-?\d+$/] + raise _INTL("Field '{1}' is not an integer.", value) + "\n" + FileLineData.linereport end return value.to_i when "u" # Positive integer or zero - if !value[/^\d+$/] - raise _INTL("Field {1} is not a positive integer or 0\n{2}", value, FileLineData.linereport) + if !value || !value[/^\d+$/] + raise _INTL("Field '{1}' is not a positive integer or 0.", value) + "\n" + FileLineData.linereport end return value.to_i when "v" # Positive integer - if !value[/^\d+$/] - raise _INTL("Field {1} is not a positive integer\n{2}", value, FileLineData.linereport) + if !value || !value[/^\d+$/] + raise _INTL("Field '{1}' is not a positive integer.", value) + "\n" + FileLineData.linereport end if value.to_i == 0 - raise _INTL("Field '{1}' must be greater than 0\n{2}", value, FileLineData.linereport) + raise _INTL("Field '{1}' must be greater than 0.", value) + "\n" + FileLineData.linereport end return value.to_i when "x" # Hexadecimal number - if !value[/^[A-F0-9]+$/i] - raise _INTL("Field '{1}' is not a hexadecimal number\n{2}", value, FileLineData.linereport) + if !value || !value[/^[A-F0-9]+$/i] + raise _INTL("Field '{1}' is not a hexadecimal number.", value) + "\n" + FileLineData.linereport end return value.hex when "f" # Floating point number - if !value[/^\-?^\d*\.?\d*$/] - raise _INTL("Field {1} is not a number\n{2}", value, FileLineData.linereport) + if !value || !value[/^\-?^\d*\.?\d*$/] + raise _INTL("Field '{1}' is not a number.", value) + "\n" + FileLineData.linereport end return value.to_f when "b" # Boolean - return true if value[/^(?:1|TRUE|YES|Y)$/i] - return false if value[/^(?:0|FALSE|NO|N)$/i] - raise _INTL("Field {1} is not a Boolean value (true, false, 1, 0)\n{2}", value, FileLineData.linereport) + return true if value && value[/^(?:1|TRUE|YES|Y)$/i] + return false if value && value[/^(?:0|FALSE|NO|N)$/i] + raise _INTL("Field '{1}' is not a Boolean value (true, false, 1, 0).", value) + "\n" + FileLineData.linereport when "n" # Name - if !value[/^(?![0-9])\w+$/] - raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.\n{2}", value, FileLineData.linereport) + if !value || !value[/^(?![0-9])\w+$/] + raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.", value) + "\n" + FileLineData.linereport end when "s" # String when "q" # Unformatted text when "m" # Symbol - if !value[/^(?![0-9])\w+$/] - raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.\n{2}", value, FileLineData.linereport) + if !value || !value[/^(?![0-9])\w+$/] + raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.", value) + "\n" + FileLineData.linereport end return value.to_sym when "e" # Enumerable return checkEnumField(value, enumer) when "y" # Enumerable or integer - return value.to_i if value[/^\-?\d+$/] + return value.to_i if value && value[/^\-?\d+$/] return checkEnumField(value, enumer) end return value @@ -440,10 +440,10 @@ module Compiler when Module begin if nil_or_empty?(ret) || !enumer.const_defined?(ret) - raise _INTL("Undefined value {1} in {2}\n{3}", ret, enumer.name, FileLineData.linereport) + raise _INTL("Undefined value {1} in {2}.", ret, enumer.name) + "\n" + FileLineData.linereport end rescue NameError - raise _INTL("Incorrect value {1} in {2}\n{3}", ret, enumer.name, FileLineData.linereport) + raise _INTL("Incorrect value {1} in {2}.", ret, enumer.name) + "\n" + FileLineData.linereport end return enumer.const_get(ret.to_sym) when Symbol, String @@ -451,36 +451,36 @@ module Compiler enumer = GameData.const_get(enumer.to_sym) begin if nil_or_empty?(ret) || !enumer.exists?(ret.to_sym) - raise _INTL("Undefined value {1} in {2}\n{3}", ret, enumer.name, FileLineData.linereport) + raise _INTL("Undefined value {1} in {2}.", ret, enumer.name) + "\n" + FileLineData.linereport end rescue NameError - raise _INTL("Incorrect value {1} in {2}\n{3}", ret, enumer.name, FileLineData.linereport) + raise _INTL("Incorrect value {1} in {2}.", ret, enumer.name) + "\n" + FileLineData.linereport end return ret.to_sym end enumer = Object.const_get(enumer.to_sym) begin if nil_or_empty?(ret) || !enumer.const_defined?(ret) - raise _INTL("Undefined value {1} in {2}\n{3}", ret, enumer.name, FileLineData.linereport) + raise _INTL("Undefined value {1} in {2}.", ret, enumer.name) + "\n" + FileLineData.linereport end rescue NameError - raise _INTL("Incorrect value {1} in {2}\n{3}", ret, enumer.name, FileLineData.linereport) + raise _INTL("Incorrect value {1} in {2}.", ret, enumer.name) + "\n" + FileLineData.linereport end return enumer.const_get(ret.to_sym) when Array - idx = findIndex(enumer) { |item| ret == item } + idx = (nil_or_empty?(ret)) ? -1 : findIndex(enumer) { |item| ret == item } if idx < 0 - raise _INTL("Undefined value {1} (expected one of: {2})\n{3}", ret, enumer.inspect, FileLineData.linereport) + raise _INTL("Undefined value {1} (expected one of: {2}).", ret, enumer.inspect) + "\n" + FileLineData.linereport end return idx when Hash - value = enumer[ret] + value = (nil_or_empty?(ret)) ? nil : enumer[ret] if value.nil? - raise _INTL("Undefined value {1} (expected one of: {2})\n{3}", ret, enumer.keys.inspect, FileLineData.linereport) + raise _INTL("Undefined value {1} (expected one of: {2}).", ret, enumer.keys.inspect) + "\n" + FileLineData.linereport end return value end - raise _INTL("Enumeration not defined\n{1}", FileLineData.linereport) + raise _INTL("Enumeration not defined.") + "\n" + FileLineData.linereport end # Unused @@ -540,7 +540,7 @@ module Compiler if nil_or_empty?(field) subrecord.push(nil) elsif !field[/^\-?\d+$/] - raise _INTL("Field {1} is not an integer\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' is not an integer.", field) + "\n" + FileLineData.linereport else subrecord.push(field.to_i) end @@ -551,29 +551,29 @@ module Compiler if nil_or_empty?(field) subrecord.push(nil) elsif !field[/^\d+$/] - raise _INTL("Field '{1}' must be 0 or greater\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' must be 0 or greater.", field) + "\n" + FileLineData.linereport else subrecord.push(field.to_i) end when "v" # Positive integer field = csvPosInt!(rec, lineno) - raise _INTL("Field '{1}' must be greater than 0\n{2}", field, FileLineData.linereport) if field == 0 + raise _INTL("Field '{1}' must be greater than 0.", field) + "\n" + FileLineData.linereport if field == 0 subrecord.push(field) when "V" # Optional positive integer field = csvfield!(rec) if nil_or_empty?(field) subrecord.push(nil) elsif !field[/^\d+$/] - raise _INTL("Field '{1}' must be greater than 0\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' must be greater than 0.", field) + "\n" + FileLineData.linereport elsif field.to_i == 0 - raise _INTL("Field '{1}' must be greater than 0\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' must be greater than 0.", field) + "\n" + FileLineData.linereport else subrecord.push(field.to_i) end when "x" # Hexadecimal number field = csvfield!(rec) if !field[/^[A-Fa-f0-9]+$/] - raise _INTL("Field '{1}' is not a hexadecimal number\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' is not a hexadecimal number.", field) + "\n" + FileLineData.linereport end subrecord.push(field.hex) when "X" # Optional hexadecimal number @@ -581,7 +581,7 @@ module Compiler if nil_or_empty?(field) subrecord.push(nil) elsif !field[/^[A-Fa-f0-9]+$/] - raise _INTL("Field '{1}' is not a hexadecimal number\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' is not a hexadecimal number.", field) + "\n" + FileLineData.linereport else subrecord.push(field.hex) end @@ -592,7 +592,7 @@ module Compiler if nil_or_empty?(field) subrecord.push(nil) elsif !field[/^\-?^\d*\.?\d*$/] - raise _INTL("Field {1} is not a floating point number\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' is not a floating point number.", field) + "\n" + FileLineData.linereport else subrecord.push(field.to_f) end @@ -610,7 +610,7 @@ module Compiler when "n" # Name field = csvfield!(rec) if !field[/^(?![0-9])\w+$/] - raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.", field) + "\n" + FileLineData.linereport end subrecord.push(field) when "N" # Optional name @@ -618,7 +618,7 @@ module Compiler if nil_or_empty?(field) subrecord.push(nil) elsif !field[/^(?![0-9])\w+$/] - raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.", field) + "\n" + FileLineData.linereport else subrecord.push(field) end @@ -640,7 +640,7 @@ module Compiler when "m" # Symbol field = csvfield!(rec) if !field[/^(?![0-9])\w+$/] - raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.", field) + "\n" + FileLineData.linereport end subrecord.push(field.to_sym) when "M" # Optional symbol @@ -648,7 +648,7 @@ module Compiler if nil_or_empty?(field) subrecord.push(nil) elsif !field[/^(?![0-9])\w+$/] - raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.\n{2}", field, FileLineData.linereport) + raise _INTL("Field '{1}' must contain only letters, digits, and\nunderscores and can't begin with a number.", field) + "\n" + FileLineData.linereport else subrecord.push(field.to_sym) end @@ -854,7 +854,7 @@ module Compiler clonitem.sub!(/\s*$/, "") itm = GameData::Item.try_get(clonitem) if !itm - raise _INTL("Undefined item constant name: {1}\nMake sure the item is defined in PBS/items.txt.\n{2}", item, FileLineData.linereport) + raise _INTL("Undefined item constant name: {1}.\nMake sure the item is defined in PBS/items.txt.", item) + "\n" + FileLineData.linereport end return itm.id end @@ -867,7 +867,7 @@ module Compiler clonspecies = "NIDORANfE" if clonspecies == "NIDORANFE" spec = GameData::Species.try_get(clonspecies) if !spec - raise _INTL("Undefined species constant name: {1}\nMake sure the species is defined in PBS/pokemon.txt.\n{2}", species, FileLineData.linereport) + raise _INTL("Undefined species constant name: {1}.\nMake sure the species is defined in PBS/pokemon.txt.", species) + "\n" + FileLineData.linereport end return spec.id end @@ -879,7 +879,7 @@ module Compiler mov = GameData::Move.try_get(clonmove) if !mov return nil if skip_unknown - raise _INTL("Undefined move constant name: {1}\nMake sure the move is defined in PBS/moves.txt.\n{2}", move, FileLineData.linereport) + raise _INTL("Undefined move constant name: {1}.\nMake sure the move is defined in PBS/moves.txt.", move) + "\n" + FileLineData.linereport end return mov.id end @@ -891,7 +891,7 @@ module Compiler clonnature.sub!(/\s*$/, "") nat = GameData::Nature.try_get(clonnature) if !nat - raise _INTL("Undefined nature constant name: {1}\nMake sure the nature is defined in the scripts.\n{2}", nature, FileLineData.linereport) + raise _INTL("Undefined nature constant name: {1}.\nMake sure the nature is defined in the scripts.", nature) + "\n" + FileLineData.linereport end return nat.id end @@ -903,7 +903,7 @@ module Compiler clontype.sub!(/\s*$/, "") typ = GameData::TrainerType.try_get(clontype) if !typ - raise _INTL("Undefined Trainer type constant name: {1}\nMake sure the trainer type is defined in PBS/trainer_types.txt.\n{2}", type, FileLineData.linereport) + raise _INTL("Undefined trainer type constant name: {1}.\nMake sure the trainer type is defined in PBS/trainer_types.txt.", type) + "\n" + FileLineData.linereport end return typ.id end diff --git a/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb b/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb index 7f97840b1..c35dbd66b 100644 --- a/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb +++ b/Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb @@ -54,7 +54,7 @@ module Compiler # Validate and modify the compiled data yield false, data_hash if block_given? if game_data.exists?(data_hash[:id]) - raise _INTL("Section name '{1}' is used twice.\n{2}", data_hash[:id], FileLineData.linereport) + raise _INTL("Section name '{1}' is used twice.", data_hash[:id]) + "\n" + FileLineData.linereport end # Add section's data to records game_data.register(data_hash) @@ -116,19 +116,19 @@ module Compiler FileLineData.setLine(line, lineno) record = get_csv_record(line, schema) if !pbRgssExists?(sprintf("Data/Map%03d.rxdata", record[0])) - print _INTL("Warning: Map {1}, as mentioned in the map connection data, was not found.\n{2}", record[0], FileLineData.linereport) + print _INTL("Warning: Map {1}, as mentioned in the map connection data, was not found.", record[0]) + "\n" + FileLineData.linereport elsif !pbRgssExists?(sprintf("Data/Map%03d.rxdata", record[3])) - print _INTL("Warning: Map {1}, as mentioned in the map connection data, was not found.\n{2}", record[3], FileLineData.linereport) + print _INTL("Warning: Map {1}, as mentioned in the map connection data, was not found.", record[3]) + "\n" + FileLineData.linereport end case record[1] when "N" - raise _INTL("North side of first map must connect with south side of second map\n{1}", FileLineData.linereport) if record[4] != "S" + raise _INTL("North side of first map must connect with south side of second map.") + "\n" + FileLineData.linereport if record[4] != "S" when "S" - raise _INTL("South side of first map must connect with north side of second map\n{1}", FileLineData.linereport) if record[4] != "N" + raise _INTL("South side of first map must connect with north side of second map.") + "\n" + FileLineData.linereport if record[4] != "N" when "E" - raise _INTL("East side of first map must connect with west side of second map\n{1}", FileLineData.linereport) if record[4] != "W" + raise _INTL("East side of first map must connect with west side of second map.") + "\n" + FileLineData.linereport if record[4] != "W" when "W" - raise _INTL("West side of first map must connect with east side of second map\n{1}", FileLineData.linereport) if record[4] != "E" + raise _INTL("West side of first map must connect with east side of second map.") + "\n" + FileLineData.linereport if record[4] != "E" end records.push(record) end @@ -210,11 +210,9 @@ module Compiler def validate_compiled_move(hash) if (hash[:category] || 2) == 2 && (hash[:power] || 0) != 0 - raise _INTL("Move {1} is defined as a Status move with a non-zero base damage.\n{2}", - hash[:real_name], FileLineData.linereport) + raise _INTL("Move {1} is defined as a Status move with a non-zero base damage.", hash[:real_name]) + "\n" + FileLineData.linereport elsif (hash[:category] || 2) != 2 && (hash[:power] || 0) == 0 - print _INTL("Warning: Move {1} is defined as Physical or Special but has a base damage of 0. Changing it to a Status move.\n{2}", - hash[:real_name], FileLineData.linereport) + print _INTL("Warning: Move {1} is defined as Physical or Special but has a base damage of 0. Changing it to a Status move.", hash[:real_name]) + "\n" + FileLineData.linereport hash[:category] = 2 end end @@ -424,7 +422,7 @@ module Compiler # Validate and modify the compiled data validate_compiled_pokemon_form(data_hash) if GameData::Species.exists?(data_hash[:id]) - raise _INTL("Section name '{1}' is used twice.\n{2}", data_hash[:id], FileLineData.linereport) + raise _INTL("Section name '{1}' is used twice.", data_hash[:id]) + "\n" + FileLineData.linereport end # Add section's data to records GameData::Species.register(data_hash) @@ -443,9 +441,9 @@ module Compiler hash[:form] = hash[:id][1] hash[:id] = sprintf("%s_%d", hash[:species].to_s, hash[:form]).to_sym if !GameData::Species.exists?(hash[:species]) - raise _INTL("Undefined species ID '{1}'.\n{3}", hash[:species], FileLineData.linereport) + raise _INTL("Undefined species ID '{1}'.", hash[:species]) + "\n" + FileLineData.linereport elsif GameData::Species.exists?(hash[:id]) - raise _INTL("Form {1} for species ID {2} is defined twice.\n{3}", hash[:form], hash[:species], FileLineData.linereport) + raise _INTL("Form {1} for species ID '{2}' is defined twice.", hash[:form], hash[:species]) + "\n" + FileLineData.linereport end # Perform the same validations on this form as for a regular species validate_compiled_pokemon(hash) @@ -592,11 +590,11 @@ module Compiler if line[/^\s*\[\s*(\d+)\s*\]\s*$/] section = $~[1].to_i if dex_lists[section] - raise _INTL("Dex list number {1} is defined at least twice.\n{2}", section, FileLineData.linereport) + raise _INTL("Dex list number {1} is defined at least twice.", section) + "\n" + FileLineData.linereport end dex_lists[section] = [] else - raise _INTL("Expected a section at the beginning of the file.\n{1}", FileLineData.linereport) if !section + raise _INTL("Expected a section at the beginning of the file.") + "\n" + FileLineData.linereport if !section species_list = line.split(",") species_list.each do |species| next if !species || species.empty? @@ -613,7 +611,7 @@ module Compiler next if list == unique_list list.each_with_index do |s, i| next if unique_list[i] == s - raise _INTL("Dex list number {1} has species {2} listed twice.\n{3}", index, s, FileLineData.linereport) + raise _INTL("Dex list number {1} has species {2} listed twice.", index, s) + "\n" + FileLineData.linereport end end # Save all data @@ -665,17 +663,17 @@ module Compiler if current_type && line[/^\d+,/] # Species line values = line.split(",").collect! { |v| v.strip } if !values || values.length < 3 - raise _INTL("Expected a species entry line for encounter type {1} for map '{2}', got \"{3}\" instead.\n{4}", - GameData::EncounterType.get(current_type).real_name, encounter_hash[:map], line, FileLineData.linereport) + raise _INTL("Expected a species entry line for encounter type {1} for map {2}.", + GameData::EncounterType.get(current_type).real_name, encounter_hash[:map]) + "\n" + FileLineData.linereport end values = get_csv_record(line, [nil, "vevV", nil, :Species]) values[3] = values[2] if !values[3] if values[2] > max_level - raise _INTL("Level number {1} is not valid (max. {2}).\n{3}", values[2], max_level, FileLineData.linereport) + raise _INTL("Level number {1} is not valid (max. {2}).", values[2], max_level) + "\n" + FileLineData.linereport elsif values[3] > max_level - raise _INTL("Level number {1} is not valid (max. {2}).\n{3}", values[3], max_level, FileLineData.linereport) + raise _INTL("Level number {1} is not valid (max. {2}).", values[3], max_level) + "\n" + FileLineData.linereport elsif values[2] > values[3] - raise _INTL("Minimum level is greater than maximum level: {1}\n{2}", line, FileLineData.linereport) + raise _INTL("Minimum level is greater than maximum level.") + "\n" + FileLineData.linereport end encounter_hash[:types][current_type].push(values) elsif line[/^\[\s*(.+)\s*\]$/] # Map ID line @@ -704,7 +702,7 @@ module Compiler # Raise an error if a map/version combo is used twice key = sprintf("%s_%d", map_number, map_version).to_sym if GameData::Encounter::DATA[key] - raise _INTL("Encounters for map '{1}' are defined twice.\n{2}", map_number, FileLineData.linereport) + raise _INTL("Encounters for map '{1}' are defined twice.", map_number) + "\n" + FileLineData.linereport end step_chances = {} # Construct encounter hash @@ -718,7 +716,7 @@ module Compiler } current_type = nil elsif !encounter_hash # File began with something other than a map ID line - raise _INTL("Expected a map number, got \"{1}\" instead.\n{2}", line, FileLineData.linereport) + raise _INTL("Expected a map number, got \"{1}\" instead.", line) + "\n" + FileLineData.linereport else # Check if line is an encounter method name or not values = line.split(",").collect! { |v| v.strip } @@ -728,8 +726,7 @@ module Compiler step_chances[current_type] ||= GameData::EncounterType.get(current_type).trigger_chance encounter_hash[:types][current_type] = [] else - raise _INTL("Undefined encounter type \"{1}\" for map '{2}'.\n{3}", - line, encounter_hash[:map], FileLineData.linereport) + raise _INTL("Undefined encounter type \"{1}\" for map '{2}'.", line, encounter_hash[:map]) + "\n" + FileLineData.linereport end end end @@ -819,7 +816,7 @@ module Compiler elsif line[/^\s*(\w+)\s*=\s*(.*)$/] # XXX=YYY lines if !data_hash - raise _INTL("Expected a section at the beginning of the file.\n{1}", FileLineData.linereport) + raise _INTL("Expected a section at the beginning of the file.") + "\n" + FileLineData.linereport end key = $~[1] if schema[key] # Property of the trainer @@ -835,7 +832,7 @@ module Compiler end elsif sub_schema[key] # Property of a Pokémon if !current_pkmn - raise _INTL("Pokémon hasn't been defined yet!\n{1}", FileLineData.linereport) + raise _INTL("Pokémon hasn't been defined yet!") + "\n" + FileLineData.linereport end current_pkmn[sub_schema[key][0]] = get_csv_record($~[2], sub_schema[key]) end @@ -862,19 +859,18 @@ module Compiler hash[:version] = hash[:id][2] # Ensure the trainer has at least one Pokémon if hash[:pokemon].empty? - raise _INTL("Trainer with ID {1} has no Pokémon.\n{2}", hash[:id], FileLineData.linereport) + raise _INTL("Trainer with ID '{1}' has no Pokémon.", hash[:id]) + "\n" + FileLineData.linereport end max_level = GameData::GrowthRate.max_level hash[:pokemon].each do |pkmn| # Ensure valid level if pkmn[:level] > max_level - raise _INTL("Invalid Pokémon level {1} (must be 1-{2}).\n{3}", - pkmn[:level], max_level, FileLineData.linereport) + raise _INTL("Invalid Pokémon level {1} (must be 1-{2}).", pkmn[:level], max_level) + "\n" + FileLineData.linereport end # Ensure valid name length if pkmn[:real_name] && pkmn[:real_name].length > Pokemon::MAX_NAME_SIZE - raise _INTL("Invalid Pokémon nickname: {1} (must be 1-{2} characters).\n{3}", - pkmn[:real_name], Pokemon::MAX_NAME_SIZE, FileLineData.linereport) + raise _INTL("Invalid Pokémon nickname: {1} (must be 1-{2} characters).", + pkmn[:real_name], Pokemon::MAX_NAME_SIZE) + "\n" + FileLineData.linereport end # Ensure no duplicate moves pkmn[:moves].uniq! if pkmn[:moves] @@ -885,8 +881,7 @@ module Compiler next if s.pbs_order < 0 iv_hash[s.id] = pkmn[:iv][s.pbs_order] || pkmn[:iv][0] if iv_hash[s.id] > Pokemon::IV_STAT_LIMIT - raise _INTL("Invalid IV: {1} (must be 0-{2}).\n{3}", - iv_hash[s.id], Pokemon::IV_STAT_LIMIT, FileLineData.linereport) + raise _INTL("Invalid IV: {1} (must be 0-{2}).", iv_hash[s.id], Pokemon::IV_STAT_LIMIT) + "\n" + FileLineData.linereport end end pkmn[:iv] = iv_hash @@ -900,26 +895,24 @@ module Compiler ev_hash[s.id] = pkmn[:ev][s.pbs_order] || pkmn[:ev][0] ev_total += ev_hash[s.id] if ev_hash[s.id] > Pokemon::EV_STAT_LIMIT - raise _INTL("Invalid EV: {1} (must be 0-{2}).\n{3}", - ev_hash[s.id], Pokemon::EV_STAT_LIMIT, FileLineData.linereport) + raise _INTL("Invalid EV: {1} (must be 0-{2}).", ev_hash[s.id], Pokemon::EV_STAT_LIMIT) + "\n" + FileLineData.linereport end end pkmn[:ev] = ev_hash if ev_total > Pokemon::EV_LIMIT - raise _INTL("Invalid EV set (must sum to {1} or less).\n{2}", - Pokemon::EV_LIMIT, FileLineData.linereport) + raise _INTL("Invalid EV set (must sum to {1} or less).", Pokemon::EV_LIMIT) + "\n" + FileLineData.linereport end end # Ensure valid happiness if pkmn[:happiness] if pkmn[:happiness] > 255 - raise _INTL("Bad happiness: {1} (must be 0-255).\n{2}", pkmn[:happiness], FileLineData.linereport) + raise _INTL("Bad happiness: {1} (must be 0-255).", pkmn[:happiness]) + "\n" + FileLineData.linereport end end # Ensure valid Poké Ball if pkmn[:poke_ball] if !GameData::Item.get(pkmn[:poke_ball]).is_poke_ball? - raise _INTL("Value {1} isn't a defined Poké Ball.\n{2}", pkmn[:poke_ball], FileLineData.linereport) + raise _INTL("Value '{1}' isn't a defined Poké Ball.", pkmn[:poke_ball]) + "\n" + FileLineData.linereport end end end @@ -984,10 +977,10 @@ module Compiler rsection[schema[0]] = record end if !rsection[0] - raise _INTL("No trainer data file given in section {1}.\n{2}", name, FileLineData.linereport) + raise _INTL("No trainer data file given in section {1}.", name) + "\n" + FileLineData.linereport end if !rsection[1] - raise _INTL("No trainer data file given in section {1}.\n{2}", name, FileLineData.linereport) + raise _INTL("No trainer data file given in section {1}.", name) + "\n" + FileLineData.linereport end rsection[3] = rsection[0] rsection[4] = rsection[1] @@ -1116,12 +1109,12 @@ module Compiler if data_hash[:id] == 0 validate_compiled_global_metadata(data_hash) if GameData::Metadata.exists?(data_hash[:id]) - raise _INTL("Global metadata ID '{1}' is used twice.\n{2}", data_hash[:id], FileLineData.linereport) + raise _INTL("Global metadata ID '{1}' is used twice.", data_hash[:id]) + "\n" + FileLineData.linereport end else validate_compiled_player_metadata(data_hash) if GameData::PlayerMetadata.exists?(data_hash[:id]) - raise _INTL("Player metadata ID '{1}' is used twice.\n{2}", data_hash[:id], FileLineData.linereport) + raise _INTL("Player metadata ID '{1}' is used twice.", data_hash[:id]) + "\n" + FileLineData.linereport end end # Add section's data to records @@ -1142,7 +1135,7 @@ module Compiler def validate_compiled_global_metadata(hash) if hash[:home].nil? - raise _INTL("The entry 'Home' is required in metadata.txt section 0.\n{1}", FileLineData.linereport) + raise _INTL("The entry 'Home' is required in metadata.txt section 0.") + "\n" + FileLineData.linereport end end @@ -1153,11 +1146,11 @@ module Compiler def validate_all_compiled_metadata # Ensure global metadata is defined if !GameData::Metadata.exists?(0) - raise _INTL("Global metadata is not defined in metadata.txt but should be.\n{1}", FileLineData.linereport) + raise _INTL("Global metadata is not defined in metadata.txt but should be.") + "\n" + FileLineData.linereport end # Ensure player character 1's metadata is defined if !GameData::PlayerMetadata.exists?(1) - raise _INTL("Metadata for player character 1 is not defined in metadata.txt but should be.\n{1}", FileLineData.linereport) + raise _INTL("Metadata for player character 1 is not defined in metadata.txt but should be.") + "\n" + FileLineData.linereport end # Get storage creator's name for translating storage_creator = [GameData::Metadata.get.real_storage_creator] @@ -1221,7 +1214,7 @@ module Compiler hash[:id] = sprintf("%s_%d", hash[:area].to_s, hash[:version]).to_sym end if GameData::DungeonParameters.exists?(hash[:id]) - raise _INTL("Version {1} of dungeon area {2} is defined twice.\n{3}", hash[:version], hash[:area], FileLineData.linereport) + raise _INTL("Version {1} of dungeon area {2} is defined twice.", hash[:version], hash[:area]) + "\n" + FileLineData.linereport end end From cd32b5e725dd538bcbb7aff9ef9c24d9cf6b9e09 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 1 Oct 2023 18:06:54 +0100 Subject: [PATCH 08/21] Fixed language files not being loadable in an encrypted game, fixed language files not reverting to default if they don't exist and other language files are already loaded --- Data/Scripts/001_Technical/003_Intl_Messages.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Data/Scripts/001_Technical/003_Intl_Messages.rb b/Data/Scripts/001_Technical/003_Intl_Messages.rb index 85b5b062c..f6c27e5d6 100644 --- a/Data/Scripts/001_Technical/003_Intl_Messages.rb +++ b/Data/Scripts/001_Technical/003_Intl_Messages.rb @@ -509,17 +509,19 @@ class Translation end def load_message_files(filename) + @core_messages = nil + @game_messages = nil begin core_filename = sprintf("Data/messages_%s_core.dat", filename) if FileTest.exist?(core_filename) - pbRgssOpen(core_filename, "rb") { |f| @core_messages = Marshal.load(f) } + @core_messages = load_data(core_filename) + @core_messages = nil if !@core_messages.is_a?(Array) end - @core_messages = nil if !@core_messages.is_a?(Array) game_filename = sprintf("Data/messages_%s_game.dat", filename) if FileTest.exist?(game_filename) - pbRgssOpen(game_filename, "rb") { |f| @game_messages = Marshal.load(f) } + @game_messages = load_data(game_filename) + @game_messages = nil if !@game_messages.is_a?(Array) end - @game_messages = nil if !@game_messages.is_a?(Array) rescue @core_messages = nil @game_messages = nil From a6c7e2c1ff4c9ccdb61b6f8ed53c784c6192c845 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 1 Oct 2023 18:52:48 +0100 Subject: [PATCH 09/21] Added Setting that prompts compiling upon startup --- Data/Scripts/001_Settings.rb | 7 +++++++ Data/Scripts/001_Technical/005_PluginManager.rb | 1 + Data/Scripts/021_Compiler/001_Compiler.rb | 2 +- Data/Scripts/999_Main/999_Main.rb | 6 ++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Data/Scripts/001_Settings.rb b/Data/Scripts/001_Settings.rb index b96e5b924..795152420 100644 --- a/Data/Scripts/001_Settings.rb +++ b/Data/Scripts/001_Settings.rb @@ -452,6 +452,13 @@ module Settings "Pizza" ] end + + #============================================================================= + + # Whether the game will ask you if you want to fully compile every time you + # start the game (in Debug mode). You will not need to hold Ctrl/Shift to + # compile anything. + PROMPT_TO_COMPILE = false end # DO NOT EDIT THESE! diff --git a/Data/Scripts/001_Technical/005_PluginManager.rb b/Data/Scripts/001_Technical/005_PluginManager.rb index 2a3947d00..9ef2c3e29 100644 --- a/Data/Scripts/001_Technical/005_PluginManager.rb +++ b/Data/Scripts/001_Technical/005_PluginManager.rb @@ -555,6 +555,7 @@ module PluginManager def self.needCompiling?(order, plugins) # fixed actions return false if !$DEBUG || FileTest.exist?("Game.rgssad") + return true if $full_compile return true if !FileTest.exist?("Data/PluginScripts.rxdata") Input.update return true if Input.press?(Input::SHIFT) || Input.press?(Input::CTRL) diff --git a/Data/Scripts/021_Compiler/001_Compiler.rb b/Data/Scripts/021_Compiler/001_Compiler.rb index 726975986..a050bc5e1 100644 --- a/Data/Scripts/021_Compiler/001_Compiler.rb +++ b/Data/Scripts/021_Compiler/001_Compiler.rb @@ -1078,7 +1078,7 @@ module Compiler mustCompile |= (latestTextTime >= latestDataTime) # Should recompile if holding Ctrl Input.update - mustCompile = true if Input.press?(Input::CTRL) + mustCompile = true if $full_compile || Input.press?(Input::CTRL) # Delete old data files in preparation for recompiling if mustCompile data_files.each do |filename| diff --git a/Data/Scripts/999_Main/999_Main.rb b/Data/Scripts/999_Main/999_Main.rb index 95cd485d1..1dc013c24 100644 --- a/Data/Scripts/999_Main/999_Main.rb +++ b/Data/Scripts/999_Main/999_Main.rb @@ -25,6 +25,12 @@ end def mainFunctionDebug begin MessageTypes.load_default_messages if FileTest.exist?("Data/messages_core.dat") + if $DEBUG && !FileTest.exist?("Game.rgssad") && Settings::PROMPT_TO_COMPILE + pbSetResizeFactor(1) # Needed to make the message look good + if pbConfirmMessage("\\ts[]" + "Do you want to compile your data and plugins?") + $full_compile = true + end + end PluginManager.runPlugins Compiler.main Game.initialize From d267956c6eed140ff1a9f4d2c1add29f1ce74dec Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 1 Oct 2023 19:24:49 +0100 Subject: [PATCH 10/21] Fixed being able to Fly in the Town Map despite the Setting, fixed being unable to interact with an event next to you if standing on an event --- Data/Scripts/001_Settings.rb | 8 ++++++-- .../004_Game classes/008_Game_Player.rb | 20 ++++++++++--------- Data/Scripts/016_UI/009_UI_RegionMap.rb | 3 ++- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Data/Scripts/001_Settings.rb b/Data/Scripts/001_Settings.rb index 795152420..4b41d7d0a 100644 --- a/Data/Scripts/001_Settings.rb +++ b/Data/Scripts/001_Settings.rb @@ -294,8 +294,12 @@ module Settings # * Species. # * Level. # * Game Switch; the Pokémon roams while this is ON. - # * Encounter type (0=any, 1=grass/walking in cave, 2=surfing, 3=fishing, - # 4=surfing/fishing). See the bottom of Overworld_RoamingPokemon for lists. + # * Encounter type (see def pbRoamingMethodAllowed for their use): + # 0 = grass, walking in cave, surfing + # 1 = grass, walking in cave + # 2 = surfing + # 3 = fishing + # 4 = surfing, fishing # * Name of BGM to play for that encounter (optional). # * Roaming areas specifically for this Pokémon (optional). ROAMING_SPECIES = [ diff --git a/Data/Scripts/004_Game classes/008_Game_Player.rb b/Data/Scripts/004_Game classes/008_Game_Player.rb index 6c03a8b19..5c5776fce 100644 --- a/Data/Scripts/004_Game classes/008_Game_Player.rb +++ b/Data/Scripts/004_Game classes/008_Game_Player.rb @@ -316,13 +316,15 @@ class Game_Player < Game_Character def pbCheckEventTriggerAfterTurning; end def pbCheckEventTriggerFromDistance(triggers) - ret = pbTriggeredTrainerEvents(triggers) - ret.concat(pbTriggeredCounterEvents(triggers)) - return false if ret.length == 0 - ret.each do |event| + events = pbTriggeredTrainerEvents(triggers) + events.concat(pbTriggeredCounterEvents(triggers)) + return false if events.length == 0 + ret = false + events.each do |event| event.start + ret = true if event.starting end - return true + return ret end # Trigger event(s) at the same coordinates as self with the appropriate @@ -339,7 +341,7 @@ class Game_Player < Game_Character # If starting determinant is same position event (other than jumping) next if event.jumping? || !event.over_trigger? event.start - result = true + result = true if event.starting end return result end @@ -361,7 +363,7 @@ class Game_Player < Game_Character # If starting determinant is front event (other than jumping) next if event.jumping? || event.over_trigger? event.start - result = true + result = true if event.starting end # If fitting event is not found if result == false && $game_map.counter?(new_x, new_y) @@ -377,7 +379,7 @@ class Game_Player < Game_Character # If starting determinant is front event (other than jumping) next if event.jumping? || event.over_trigger? event.start - result = true + result = true if event.starting end end return result @@ -404,7 +406,7 @@ class Game_Player < Game_Character # If starting determinant is front event (other than jumping) next if event.jumping? || event.over_trigger? event.start - result = true + result = true if event.starting end return result end diff --git a/Data/Scripts/016_UI/009_UI_RegionMap.rb b/Data/Scripts/016_UI/009_UI_RegionMap.rb index 4124fa833..3749127d0 100644 --- a/Data/Scripts/016_UI/009_UI_RegionMap.rb +++ b/Data/Scripts/016_UI/009_UI_RegionMap.rb @@ -308,7 +308,8 @@ class PokemonRegionMap_Scene end elsif Input.trigger?(Input::USE) && @editor # Intentionally after other USE input check pbChangeMapLocation(@map_x, @map_y) - elsif Input.trigger?(Input::ACTION) && !@wallmap && !@fly_map && pbCanFly? + elsif Input.trigger?(Input::ACTION) && Settings::CAN_FLY_FROM_TOWN_MAP && + !@wallmap && !@fly_map && pbCanFly? pbPlayDecisionSE @mode = (@mode == 1) ? 0 : 1 refresh_fly_screen From 25f85a9a8b0a31457d550841192fdb8a1ec54df4 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sat, 14 Oct 2023 16:28:37 +0100 Subject: [PATCH 11/21] Added mp3 support back in, changed layout of townmapgen.html, screenshots now go in Screenshots folder, added "NoName" flag for trainer types --- .../001_Technical/002_Files/001_FileTests.rb | 8 +- .../015_Trainers and player/001_Trainer.rb | 3 +- Data/Scripts/019_Utilities/001_Utilities.rb | 11 ++- .../005_AnimEditor_Functions.rb | 2 +- .../003_Debug_MenuExtraCode.rb | 2 +- Data/Scripts/020_Debug/003_Editor_Listers.rb | 7 +- townmapgen.html | 97 +++++++++++++------ 7 files changed, 90 insertions(+), 40 deletions(-) diff --git a/Data/Scripts/001_Technical/002_Files/001_FileTests.rb b/Data/Scripts/001_Technical/002_Files/001_FileTests.rb index 68977e097..d753bdae8 100644 --- a/Data/Scripts/001_Technical/002_Files/001_FileTests.rb +++ b/Data/Scripts/001_Technical/002_Files/001_FileTests.rb @@ -108,8 +108,8 @@ end def pbResolveAudioSE(file) return nil if !file - if RTP.exists?("Audio/SE/" + file, ["", ".wav", ".ogg"]) # ".mp3" - return RTP.getPath("Audio/SE/" + file, ["", ".wav", ".ogg"]) # ".mp3" + if RTP.exists?("Audio/SE/" + file, ["", ".wav", ".ogg", ".mp3", ".wma"]) + return RTP.getPath("Audio/SE/" + file, ["", ".wav", ".ogg", ".mp3", ".wma"]) end return nil end @@ -197,7 +197,7 @@ module RTP end def self.getAudioPath(filename) - return self.getPath(filename, ["", ".wav", ".wma", ".mid", ".ogg", ".midi"]) # ".mp3" + return self.getPath(filename, ["", ".wav", ".ogg", ".mp3", ".midi", ".mid", ".wma"]) end def self.getPath(filename, extensions = []) @@ -261,7 +261,7 @@ end #=============================================================================== module FileTest IMAGE_EXTENSIONS = [".png", ".gif"] # ".jpg", ".jpeg", ".bmp", - AUDIO_EXTENSIONS = [".mid", ".midi", ".ogg", ".wav", ".wma"] # ".mp3" + AUDIO_EXTENSIONS = [".wav", ".ogg", ".mp3", ".midi", ".mid", ".wma"] def self.audio_exist?(filename) return RTP.exists?(filename, AUDIO_EXTENSIONS) diff --git a/Data/Scripts/015_Trainers and player/001_Trainer.rb b/Data/Scripts/015_Trainers and player/001_Trainer.rb index 8a33185b8..a78515d0c 100644 --- a/Data/Scripts/015_Trainers and player/001_Trainer.rb +++ b/Data/Scripts/015_Trainers and player/001_Trainer.rb @@ -16,7 +16,8 @@ class Trainer end def full_name - return _INTL("{1} {2}", trainer_type_name, @name) + return @name if has_flag?("NoName") + return "#{trainer_type_name} #{@name}" end #============================================================================= diff --git a/Data/Scripts/019_Utilities/001_Utilities.rb b/Data/Scripts/019_Utilities/001_Utilities.rb index 8d94094f3..39df7ce43 100644 --- a/Data/Scripts/019_Utilities/001_Utilities.rb +++ b/Data/Scripts/019_Utilities/001_Utilities.rb @@ -611,7 +611,14 @@ end def pbScreenCapture t = Time.now filestart = t.strftime("[%Y-%m-%d] %H_%M_%S.%L") - capturefile = RTP.getSaveFileName(sprintf("%s.png", filestart)) - Graphics.screenshot(capturefile) + begin + folder_name = "Screenshots" + Dir.create(folder_name) if !Dir.safe?(folder_name) + capturefile = folder_name + "/" + sprintf("%s.png", filestart) + Graphics.screenshot(capturefile) + rescue + capturefile = RTP.getSaveFileName(sprintf("%s.png", filestart)) + Graphics.screenshot(capturefile) + end pbSEPlay("Pkmn exp full") if FileTest.audio_exist?("Audio/SE/Pkmn exp full") end diff --git a/Data/Scripts/020_Debug/002_Animation editor/005_AnimEditor_Functions.rb b/Data/Scripts/020_Debug/002_Animation editor/005_AnimEditor_Functions.rb index 42d794da0..560bd0b97 100644 --- a/Data/Scripts/020_Debug/002_Animation editor/005_AnimEditor_Functions.rb +++ b/Data/Scripts/020_Debug/002_Animation editor/005_AnimEditor_Functions.rb @@ -508,8 +508,8 @@ module BattleAnimationEditor ret = false pbRgssChdir(File.join("Audio", "SE", "Anim")) do animfiles.concat(Dir.glob("*.wav")) - # animfiles.concat(Dir.glob("*.mp3")) animfiles.concat(Dir.glob("*.ogg")) + animfiles.concat(Dir.glob("*.mp3")) animfiles.concat(Dir.glob("*.wma")) end animfiles.uniq! diff --git a/Data/Scripts/020_Debug/003_Debug menus/003_Debug_MenuExtraCode.rb b/Data/Scripts/020_Debug/003_Debug menus/003_Debug_MenuExtraCode.rb index 12d2feb2c..6fd27602f 100644 --- a/Data/Scripts/020_Debug/003_Debug menus/003_Debug_MenuExtraCode.rb +++ b/Data/Scripts/020_Debug/003_Debug menus/003_Debug_MenuExtraCode.rb @@ -613,7 +613,7 @@ def pbImportAllAnimations Graphics.update audios = [] files = Dir.glob(folder + "/*.*") - ["wav", "ogg", "mid", "wma"].each do |ext| # mp3 + ["wav", "ogg", "mp3", "midi", "mid", "wma"].each do |ext| upext = ext.upcase audios.concat(files.find_all { |f| f[f.length - 3, 3] == ext }) audios.concat(files.find_all { |f| f[f.length - 3, 3] == upext }) diff --git a/Data/Scripts/020_Debug/003_Editor_Listers.rb b/Data/Scripts/020_Debug/003_Editor_Listers.rb index 802d0c620..b34487c49 100644 --- a/Data/Scripts/020_Debug/003_Editor_Listers.rb +++ b/Data/Scripts/020_Debug/003_Editor_Listers.rb @@ -213,11 +213,12 @@ class MusicFileLister folder = (@bgm) ? "Audio/BGM/" : "Audio/ME/" @commands.clear Dir.chdir(folder) do -# Dir.glob("*.mp3") { |f| @commands.push(f) } - Dir.glob("*.ogg") { |f| @commands.push(f) } Dir.glob("*.wav") { |f| @commands.push(f) } - Dir.glob("*.mid") { |f| @commands.push(f) } + Dir.glob("*.ogg") { |f| @commands.push(f) } + Dir.glob("*.mp3") { |f| @commands.push(f) } Dir.glob("*.midi") { |f| @commands.push(f) } + Dir.glob("*.mid") { |f| @commands.push(f) } + Dir.glob("*.wma") { |f| @commands.push(f) } end @commands.uniq! @commands.sort! { |a, b| a.downcase <=> b.downcase } diff --git a/townmapgen.html b/townmapgen.html index 804d2282b..6bffe3fc6 100644 --- a/townmapgen.html +++ b/townmapgen.html @@ -1,49 +1,80 @@ -
- +
+ Town Map Generator
-
- Map Filename (in Graphics/Pictures/):   -
- Square width:   - Square height:   -
- Region Name:   - -
-
-
-
- - + + + + - + + - - + + + - - + + + + +
Current Position:Filename:Name of the region graphic (in Graphics/UI/Town Map/)
Name: + Name of the region
Point of Interest: + Square width:Width of each point in the Town Map (in pixels)
Fly Destination: + Square height:Height of each point in the Town Map (in pixels)
+
+
+
+ Edit point properties
+ Click on a point in the Town Map to edit its properties. +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + - +
Co-ordinates:X and Y co-ordinates of this point in the Town Map (click in the map above)
Name:Name of this location
Landmark:Name of a landmark found in this location
Fly destination:Map ID, X and Y tile co-ordinates the player will appear at when Flying to this location
Switch: + Number of a Game Switch that needs to be ON to see this point's name/landmark and to Fly to this location

- Single section from townmap.txt (without section heading):
+
+ PBS file "town_map.txt" text for this region

- (To load data into the editor)
- Copy the data above into townmap.txt when you're done. +   + Apply the data in this box to the map above
+ When you're done, copy this text into "town_map.txt". Remember that it needs a section line (a number in square brackets).