mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Merge branch 'dev' into ai
This commit is contained in:
@@ -154,7 +154,7 @@ Style/SymbolArray:
|
||||
Style/WordArray:
|
||||
EnforcedStyle: brackets
|
||||
|
||||
# Patentheses around the condition in a ternary operator helps to differentiate
|
||||
# Parentheses around the condition in a ternary operator helps to differentiate
|
||||
# it from the true/false results.
|
||||
Style/TernaryParentheses:
|
||||
EnforcedStyle: require_parentheses
|
||||
|
||||
@@ -359,7 +359,7 @@ class CallbackWrapper
|
||||
def execute(given_block = nil, *args)
|
||||
execute_block = given_block || @code_block
|
||||
@params.each do |key, value|
|
||||
args.instance_variable_set("@#{key.to_s}", value)
|
||||
args.instance_variable_set("@#{key}", value)
|
||||
end
|
||||
args.instance_eval(&execute_block)
|
||||
end
|
||||
|
||||
@@ -627,7 +627,11 @@ module PluginManager
|
||||
# get the order of plugins to interpret
|
||||
order, plugins = self.getPluginOrder
|
||||
# compile if necessary
|
||||
self.compilePlugins(order, plugins) if self.needCompiling?(order, plugins)
|
||||
if self.needCompiling?(order, plugins)
|
||||
self.compilePlugins(order, plugins)
|
||||
else
|
||||
Console.echoln_li "Plugins were not compiled."
|
||||
end
|
||||
# load plugins
|
||||
scripts = load_data("Data/PluginScripts.rxdata")
|
||||
echoed_plugins = []
|
||||
|
||||
@@ -79,19 +79,4 @@ module SaveData
|
||||
end
|
||||
return hash
|
||||
end
|
||||
|
||||
# Moves a save file from the old Saved Games folder to the new
|
||||
# location specified by {FILE_PATH}. Does nothing if a save file
|
||||
# already exists in {FILE_PATH}.
|
||||
def self.move_old_windows_save
|
||||
return if File.file?(FILE_PATH)
|
||||
game_title = System.game_title.gsub(/[^\w ]/, "_")
|
||||
home = ENV["HOME"] || ENV["HOMEPATH"]
|
||||
return if home.nil?
|
||||
old_location = File.join(home, "Saved Games", game_title)
|
||||
return unless File.directory?(old_location)
|
||||
old_file = File.join(old_location, "Game.rxdata")
|
||||
return unless File.file?(old_file)
|
||||
File.move(old_file, FILE_PATH)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,7 +19,6 @@ module Game
|
||||
# Loads bootup data from save file (if it exists) or creates bootup data (if
|
||||
# it doesn't).
|
||||
def self.set_up_system
|
||||
SaveData.move_old_windows_save if System.platform[/Windows/]
|
||||
save_data = (SaveData.exists?) ? SaveData.read_from_file(SaveData::FILE_PATH) : {}
|
||||
if save_data.empty?
|
||||
SaveData.initialize_bootup_values
|
||||
|
||||
@@ -474,7 +474,7 @@ class Game_Player < Game_Character
|
||||
if !@moved_last_frame || @stopped_last_frame # Started a new step
|
||||
if pbTerrainTag.ice
|
||||
set_movement_type(:ice_sliding)
|
||||
else#if !@move_route_forcing
|
||||
else
|
||||
faster = can_run?
|
||||
if $PokemonGlobal&.diving
|
||||
set_movement_type((faster) ? :diving_fast : :diving)
|
||||
|
||||
@@ -278,14 +278,8 @@ class Game_FollowerFactory
|
||||
facing_tile = $map_factory.getFacingTile
|
||||
# Assumes player is 1x1 tile in size
|
||||
each_follower do |event, follower|
|
||||
if event.at_coordinate?($game_player.x, $game_player.y) # Underneath player
|
||||
next if !event.over_trigger?
|
||||
elsif facing_tile && event.map.map_id == facing_tile[0] &&
|
||||
event.at_coordinate?(facing_tile[1], facing_tile[2]) # On facing tile
|
||||
next if event.over_trigger?
|
||||
else # Somewhere else
|
||||
next
|
||||
end
|
||||
next if !facing_tile || event.map.map_id != facing_tile[0] ||
|
||||
!event.at_coordinate?(facing_tile[1], facing_tile[2]) # Not on facing tile
|
||||
next if event.jumping?
|
||||
follower.interact(event)
|
||||
end
|
||||
|
||||
@@ -37,23 +37,38 @@ class TileDrawingHelper
|
||||
36, 24, 36, 24, 21, 6, 21, 4, 36, 24, 36, 24, 20, 2, 20, 0
|
||||
]
|
||||
|
||||
def self.tableNeighbors(data, x, y)
|
||||
def self.tableNeighbors(data, x, y, layer = nil)
|
||||
return 0 if x < 0 || x >= data.xsize
|
||||
return 0 if y < 0 || y >= data.ysize
|
||||
if layer.nil?
|
||||
t = data[x, y]
|
||||
else
|
||||
t = data[x, y, layer]
|
||||
end
|
||||
xp1 = [x + 1, data.xsize - 1].min
|
||||
yp1 = [y + 1, data.ysize - 1].min
|
||||
xm1 = [x - 1, 0].max
|
||||
ym1 = [y - 1, 0].max
|
||||
i = 0
|
||||
i |= 0x01 if data[x, ym1] == t # N
|
||||
if layer.nil?
|
||||
i |= 0x01 if data[ x, ym1] == t # N
|
||||
i |= 0x02 if data[xp1, ym1] == t # NE
|
||||
i |= 0x04 if data[xp1, y] == t # E
|
||||
i |= 0x08 if data[xp1, yp1] == t # SE
|
||||
i |= 0x10 if data[x, yp1] == t # S
|
||||
i |= 0x10 if data[ x, yp1] == t # S
|
||||
i |= 0x20 if data[xm1, yp1] == t # SW
|
||||
i |= 0x40 if data[xm1, y] == t # W
|
||||
i |= 0x80 if data[xm1, ym1] == t # NW
|
||||
else
|
||||
i |= 0x01 if data[ x, ym1, layer] == t # N
|
||||
i |= 0x02 if data[xp1, ym1, layer] == t # NE
|
||||
i |= 0x04 if data[xp1, y, layer] == t # E
|
||||
i |= 0x08 if data[xp1, yp1, layer] == t # SE
|
||||
i |= 0x10 if data[ x, yp1, layer] == t # S
|
||||
i |= 0x20 if data[xm1, yp1, layer] == t # SW
|
||||
i |= 0x40 if data[xm1, y, layer] == t # W
|
||||
i |= 0x80 if data[xm1, ym1, layer] == t # NW
|
||||
end
|
||||
return i
|
||||
end
|
||||
|
||||
|
||||
@@ -940,12 +940,24 @@ def drawSingleFormattedChar(bitmap, ch)
|
||||
graphicRect = ch[15]
|
||||
bitmap.blt(ch[1], ch[2], graphic, graphicRect, ch[8].alpha)
|
||||
graphic.dispose
|
||||
else
|
||||
bitmap.font.size = ch[13] if bitmap.font.size != ch[13]
|
||||
if ch[0] != "\n" && ch[0] != "\r" && ch[0] != " " && !isWaitChar(ch[0])
|
||||
return
|
||||
end
|
||||
bitmap.font.bold = ch[6] if bitmap.font.bold != ch[6]
|
||||
bitmap.font.italic = ch[7] if bitmap.font.italic != ch[7]
|
||||
bitmap.font.name = ch[12] if bitmap.font.name != ch[12]
|
||||
bitmap.font.size = ch[13] if bitmap.font.size != ch[13]
|
||||
if ch[9] # shadow
|
||||
if ch[10] # underline
|
||||
bitmap.fill_rect(ch[1], ch[2] + ch[4] - [(ch[4] - bitmap.font.size) / 2, 0].max - 2,
|
||||
ch[3], 4, ch[9])
|
||||
end
|
||||
if ch[11] # strikeout
|
||||
bitmap.fill_rect(ch[1], ch[2] + 2 + (ch[4] / 2), ch[3], 4, ch[9])
|
||||
end
|
||||
end
|
||||
if ch[0] == "\n" || ch[0] == "\r" || ch[0] == " " || isWaitChar(ch[0])
|
||||
bitmap.font.color = ch[8] if bitmap.font.color != ch[8]
|
||||
else
|
||||
offset = 0
|
||||
if ch[9] # shadow
|
||||
bitmap.font.color = ch[9]
|
||||
@@ -977,16 +989,13 @@ def drawSingleFormattedChar(bitmap, ch)
|
||||
end
|
||||
bitmap.font.color = ch[8] if bitmap.font.color != ch[8]
|
||||
bitmap.draw_text(ch[1] + offset, ch[2] + offset, ch[3], ch[4], ch[0])
|
||||
elsif bitmap.font.color != ch[8]
|
||||
bitmap.font.color = ch[8]
|
||||
end
|
||||
if ch[10] # underline
|
||||
bitmap.fill_rect(ch[1], ch[2] + ch[4] - 4 - [(ch[4] - bitmap.font.size) / 2, 0].max - 2,
|
||||
bitmap.fill_rect(ch[1], ch[2] + ch[4] - [(ch[4] - bitmap.font.size) / 2, 0].max - 2,
|
||||
ch[3] - 2, 2, ch[8])
|
||||
end
|
||||
if ch[11] # strikeout
|
||||
bitmap.fill_rect(ch[1], ch[2] + (ch[4] / 2) - 4, ch[3] - 2, 2, ch[8])
|
||||
end
|
||||
bitmap.fill_rect(ch[1], ch[2] + 2 + (ch[4] / 2), ch[3] - 2, 2, ch[8])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -819,7 +819,7 @@ def pbShowCommandsWithHelp(msgwindow, commands, help, cmdIfCancel = 0, defaultCm
|
||||
Input.update
|
||||
end
|
||||
msgwin.letterbyletter = oldlbl
|
||||
msgwin.dispose if !msgwindow
|
||||
pbDisposeMessageWindow(msgwin) if !msgwindow
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
@@ -240,5 +240,8 @@ module GameData
|
||||
Metadata.load
|
||||
PlayerMetadata.load
|
||||
MapMetadata.load
|
||||
DungeonTileset.load
|
||||
DungeonParameters.load
|
||||
PhoneMessage.load
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#===============================================================================
|
||||
class Game_Temp
|
||||
attr_accessor :town_map_data
|
||||
attr_accessor :phone_messages_data
|
||||
attr_accessor :regional_dexes_data
|
||||
attr_accessor :battle_animations_data
|
||||
attr_accessor :move_to_battle_animation_data
|
||||
@@ -13,7 +12,6 @@ end
|
||||
def pbClearData
|
||||
if $game_temp
|
||||
$game_temp.town_map_data = nil
|
||||
$game_temp.phone_messages_data = nil
|
||||
$game_temp.regional_dexes_data = nil
|
||||
$game_temp.battle_animations_data = nil
|
||||
$game_temp.move_to_battle_animation_data = nil
|
||||
@@ -37,17 +35,6 @@ def pbLoadTownMapData
|
||||
return $game_temp.town_map_data
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Method to get phone call data.
|
||||
#===============================================================================
|
||||
def pbLoadPhoneData
|
||||
$game_temp = Game_Temp.new if !$game_temp
|
||||
if !$game_temp.phone_messages_data && pbRgssExists?("Data/phone.dat")
|
||||
$game_temp.phone_messages_data = load_data("Data/phone.dat")
|
||||
end
|
||||
return $game_temp.phone_messages_data
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Method to get Regional Dexes data.
|
||||
#===============================================================================
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#===============================================================================
|
||||
# Phone data
|
||||
#===============================================================================
|
||||
class PhoneDatabase
|
||||
attr_accessor :generics
|
||||
attr_accessor :greetings
|
||||
attr_accessor :greetingsMorning
|
||||
attr_accessor :greetingsEvening
|
||||
attr_accessor :bodies1
|
||||
attr_accessor :bodies2
|
||||
attr_accessor :battleRequests
|
||||
attr_accessor :trainers
|
||||
|
||||
def initialize
|
||||
@generics = []
|
||||
@greetings = []
|
||||
@greetingsMorning = []
|
||||
@greetingsEvening = []
|
||||
@bodies1 = []
|
||||
@bodies2 = []
|
||||
@battleRequests = []
|
||||
@trainers = []
|
||||
end
|
||||
end
|
||||
@@ -57,6 +57,11 @@ module GameData
|
||||
return (ret) ? ret : pbResolveBitmap("Graphics/Pokemon/Eggs/000")
|
||||
end
|
||||
|
||||
def self.egg_cracks_sprite_filename(species, form)
|
||||
ret = self.check_egg_graphic_file("Graphics/Pokemon/Eggs/", species, form, "_cracks")
|
||||
return (ret) ? ret : pbResolveBitmap("Graphics/Pokemon/Eggs/000_cracks")
|
||||
end
|
||||
|
||||
def self.sprite_filename(species, form = 0, gender = 0, shiny = false, shadow = false, back = false, egg = false)
|
||||
return self.egg_sprite_filename(species, form) if egg
|
||||
return self.back_sprite_filename(species, form, gender, shiny, shadow) if back
|
||||
209
Data/Scripts/010_Data/002_PBS data/018_DungeonTileset.rb
Normal file
209
Data/Scripts/010_Data/002_PBS data/018_DungeonTileset.rb
Normal file
@@ -0,0 +1,209 @@
|
||||
module GameData
|
||||
class DungeonTileset
|
||||
attr_reader :id
|
||||
attr_reader :tile_type_ids
|
||||
attr_reader :snap_to_large_grid # "large" means 2x2 tiles
|
||||
attr_reader :large_void_tiles # "large" means 2x2 tiles
|
||||
attr_reader :large_wall_tiles # "large" means 1x2 or 2x1 tiles depending on side
|
||||
attr_reader :large_floor_tiles # "large" means 2x2 tiles
|
||||
attr_reader :double_walls
|
||||
attr_reader :floor_patch_under_walls
|
||||
attr_reader :thin_north_wall_offset
|
||||
attr_reader :flags
|
||||
|
||||
DATA = {}
|
||||
DATA_FILENAME = "dungeon_tilesets.dat"
|
||||
|
||||
SCHEMA = {
|
||||
"Autotile" => [:autotile, "us"],
|
||||
"Tile" => [:tile, "us"],
|
||||
"SnapToLargeGrid" => [:snap_to_large_grid, "b"],
|
||||
"LargeVoidTiles" => [:large_void_tiles, "b"],
|
||||
"LargeWallTiles" => [:large_wall_tiles, "b"],
|
||||
"LargeFloorTiles" => [:large_floor_tiles, "b"],
|
||||
"DoubleWalls" => [:double_walls, "b"],
|
||||
"FloorPatchUnderWalls" => [:floor_patch_under_walls, "b"],
|
||||
"ThinNorthWallOffset" => [:thin_north_wall_offset, "i"],
|
||||
"Flags" => [:flags, "*s"]
|
||||
}
|
||||
|
||||
extend ClassMethodsIDNumbers
|
||||
include InstanceMethods
|
||||
|
||||
# @param other [self, Integer]
|
||||
# @return [self]
|
||||
def self.try_get(other)
|
||||
validate other => [Integer, self]
|
||||
return other if other.is_a?(self)
|
||||
return (self::DATA.has_key?(other)) ? self::DATA[other] : self.get(self::DATA.keys.first)
|
||||
end
|
||||
|
||||
def initialize(hash)
|
||||
@id = hash[:id]
|
||||
@snap_to_large_grid = hash[:snap_to_large_grid] || false
|
||||
@large_void_tiles = hash[:large_void_tiles] || false
|
||||
@large_wall_tiles = hash[:large_wall_tiles] || false
|
||||
@large_floor_tiles = hash[:large_floor_tiles] || false
|
||||
@double_walls = hash[:double_walls] || false
|
||||
@floor_patch_under_walls = hash[:floor_patch_under_walls] || false
|
||||
@thin_north_wall_offset = hash[:thin_north_wall_offset] || 0
|
||||
@flags = hash[:flags] || []
|
||||
@tile_type_ids = {}
|
||||
set_tile_type_ids(hash)
|
||||
end
|
||||
|
||||
def set_tile_type_ids(hash)
|
||||
[hash[:autotile], hash[:tile]].each_with_index do |array, i|
|
||||
array.each do |tile_info|
|
||||
next if !tile_info
|
||||
tile_type = tile_info[1].downcase.to_sym
|
||||
if tile_type == :walls
|
||||
if @double_walls
|
||||
if @large_wall_tiles
|
||||
push_tile(:wall_1, 384 + tile_info[0] + 33)
|
||||
push_tile(:wall_2, 384 + tile_info[0] + 34)
|
||||
push_tile(:wall_3, 384 + tile_info[0] + 36)
|
||||
push_tile(:wall_4, 384 + tile_info[0] + 17)
|
||||
push_tile(:wall_6, 384 + tile_info[0] + 20)
|
||||
push_tile(:wall_7, 384 + tile_info[0] + 9)
|
||||
push_tile(:wall_8, 384 + tile_info[0] + 10)
|
||||
push_tile(:wall_9, 384 + tile_info[0] + 12)
|
||||
push_tile(:wall_in_1, 384 + tile_info[0] + 23)
|
||||
push_tile(:wall_in_3, 384 + tile_info[0] + 22)
|
||||
push_tile(:wall_in_7, 384 + tile_info[0] + 31)
|
||||
push_tile(:wall_in_9, 384 + tile_info[0] + 30)
|
||||
push_tile(:upper_wall_1, 384 + tile_info[0] + 40)
|
||||
push_tile(:upper_wall_2, 384 + tile_info[0] + 42)
|
||||
push_tile(:upper_wall_3, 384 + tile_info[0] + 45)
|
||||
push_tile(:upper_wall_4, 384 + tile_info[0] + 16)
|
||||
push_tile(:upper_wall_6, 384 + tile_info[0] + 21)
|
||||
push_tile(:upper_wall_7, 384 + tile_info[0] + 0)
|
||||
push_tile(:upper_wall_8, 384 + tile_info[0] + 2)
|
||||
push_tile(:upper_wall_9, 384 + tile_info[0] + 5)
|
||||
push_tile(:upper_wall_in_1, 384 + tile_info[0] + 7)
|
||||
push_tile(:upper_wall_in_3, 384 + tile_info[0] + 6)
|
||||
push_tile(:upper_wall_in_7, 384 + tile_info[0] + 15)
|
||||
push_tile(:upper_wall_in_9, 384 + tile_info[0] + 14)
|
||||
else
|
||||
push_tile(:wall_1, 384 + tile_info[0] + 25)
|
||||
push_tile(:wall_2, 384 + tile_info[0] + 26)
|
||||
push_tile(:wall_3, 384 + tile_info[0] + 27)
|
||||
push_tile(:wall_4, 384 + tile_info[0] + 17)
|
||||
push_tile(:wall_6, 384 + tile_info[0] + 19)
|
||||
push_tile(:wall_7, 384 + tile_info[0] + 9)
|
||||
push_tile(:wall_8, 384 + tile_info[0] + 10)
|
||||
push_tile(:wall_9, 384 + tile_info[0] + 11)
|
||||
push_tile(:wall_in_1, 384 + tile_info[0] + 22)
|
||||
push_tile(:wall_in_3, 384 + tile_info[0] + 21)
|
||||
push_tile(:wall_in_7, 384 + tile_info[0] + 30)
|
||||
push_tile(:wall_in_9, 384 + tile_info[0] + 29)
|
||||
push_tile(:upper_wall_1, 384 + tile_info[0] + 32)
|
||||
push_tile(:upper_wall_2, 384 + tile_info[0] + 34)
|
||||
push_tile(:upper_wall_3, 384 + tile_info[0] + 36)
|
||||
push_tile(:upper_wall_4, 384 + tile_info[0] + 16)
|
||||
push_tile(:upper_wall_6, 384 + tile_info[0] + 20)
|
||||
push_tile(:upper_wall_7, 384 + tile_info[0] + 0)
|
||||
push_tile(:upper_wall_8, 384 + tile_info[0] + 2)
|
||||
push_tile(:upper_wall_9, 384 + tile_info[0] + 4)
|
||||
push_tile(:upper_wall_in_1, 384 + tile_info[0] + 6)
|
||||
push_tile(:upper_wall_in_3, 384 + tile_info[0] + 5)
|
||||
push_tile(:upper_wall_in_7, 384 + tile_info[0] + 14)
|
||||
push_tile(:upper_wall_in_9, 384 + tile_info[0] + 13)
|
||||
end
|
||||
elsif @large_wall_tiles
|
||||
push_tile(:wall_1, 384 + tile_info[0] + 24)
|
||||
push_tile(:wall_2, 384 + tile_info[0] + 25)
|
||||
push_tile(:wall_3, 384 + tile_info[0] + 27)
|
||||
push_tile(:wall_4, 384 + tile_info[0] + 8)
|
||||
push_tile(:wall_6, 384 + tile_info[0] + 11)
|
||||
push_tile(:wall_7, 384 + tile_info[0] + 0)
|
||||
push_tile(:wall_8, 384 + tile_info[0] + 1)
|
||||
push_tile(:wall_9, 384 + tile_info[0] + 3)
|
||||
push_tile(:wall_in_1, 384 + tile_info[0] + 5)
|
||||
push_tile(:wall_in_3, 384 + tile_info[0] + 4)
|
||||
push_tile(:wall_in_7, 384 + tile_info[0] + 13)
|
||||
push_tile(:wall_in_9, 384 + tile_info[0] + 12)
|
||||
else
|
||||
push_tile(:wall_1, 384 + tile_info[0] + 16)
|
||||
push_tile(:wall_2, 384 + tile_info[0] + 17)
|
||||
push_tile(:wall_3, 384 + tile_info[0] + 18)
|
||||
push_tile(:wall_4, 384 + tile_info[0] + 8)
|
||||
push_tile(:wall_6, 384 + tile_info[0] + 10)
|
||||
push_tile(:wall_7, 384 + tile_info[0] + 0)
|
||||
push_tile(:wall_8, 384 + tile_info[0] + 1)
|
||||
push_tile(:wall_9, 384 + tile_info[0] + 2)
|
||||
push_tile(:wall_in_1, 384 + tile_info[0] + 4)
|
||||
push_tile(:wall_in_3, 384 + tile_info[0] + 3)
|
||||
push_tile(:wall_in_7, 384 + tile_info[0] + 12)
|
||||
push_tile(:wall_in_9, 384 + tile_info[0] + 11)
|
||||
end
|
||||
end
|
||||
id = (i == 0) ? tile_info[0] * 48 : 384 + tile_info[0]
|
||||
push_tile(tile_type, id, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def push_tile(tile_type, id, auto = true)
|
||||
@tile_type_ids[tile_type] ||= []
|
||||
@tile_type_ids[tile_type].push([id, auto])
|
||||
end
|
||||
|
||||
def has_flag?(flag)
|
||||
return @flags.any? { |f| f.downcase == flag.downcase }
|
||||
end
|
||||
|
||||
def has_decoration?(deco)
|
||||
return @tile_type_ids.include?(deco) && @tile_type_ids[deco].length > 0
|
||||
end
|
||||
|
||||
def get_random_tile_of_type(tile_type, dungeon, x, y, layer)
|
||||
tiles = @tile_type_ids[tile_type]
|
||||
return 0 if !tiles || tiles.empty?
|
||||
ret = tiles.sample[0]
|
||||
if ret < 384 # Autotile
|
||||
nb = TileDrawingHelper.tableNeighbors(dungeon, x, y, layer)
|
||||
variant = TileDrawingHelper::NEIGHBORS_TO_AUTOTILE_INDEX[nb]
|
||||
ret += variant
|
||||
else
|
||||
case tile_type
|
||||
when :void
|
||||
if @large_void_tiles
|
||||
ret += 1 if x.odd?
|
||||
ret += 8 if y.odd?
|
||||
end
|
||||
when :floor
|
||||
if large_floor_tiles
|
||||
ret += 1 if x.odd?
|
||||
ret += 8 if y.odd?
|
||||
end
|
||||
when :wall_2, :wall_8, :wall_top
|
||||
ret += 1 if @large_wall_tiles && x.odd?
|
||||
when :wall_4, :wall_6
|
||||
ret += 8 if @large_wall_tiles && y.odd?
|
||||
end
|
||||
# Different wall tiles for northern walls if there's another wall directly
|
||||
# north of them (i.e. tree tiles that shouldn't have shaded grass because
|
||||
# there isn't a tree-enclosed area there)
|
||||
if @thin_north_wall_offset != 0 && [:wall_7, :wall_8, :wall_9].include?(tile_type)
|
||||
ret += @thin_north_wall_offset if dungeon.tile_is_wall?(dungeon[x, y - 1, 1])
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def property_from_string(str)
|
||||
case str
|
||||
when "SnapToLargeGrid" then return @snap_to_large_grid
|
||||
when "LargeVoidTiles" then return @large_void_tiles
|
||||
when "LargeWallTiles" then return @large_wall_tiles
|
||||
when "LargeFloorTiles" then return @large_floor_tiles
|
||||
when "DoubleWalls" then return @double_walls
|
||||
when "FloorPatchUnderWalls" then return @floor_patch_under_walls
|
||||
when "ThinNorthWallOffset" then return @thin_north_wall_offset
|
||||
when "Flags" then return @flags
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
138
Data/Scripts/010_Data/002_PBS data/020_DungeonParameters.rb
Normal file
138
Data/Scripts/010_Data/002_PBS data/020_DungeonParameters.rb
Normal file
@@ -0,0 +1,138 @@
|
||||
# TODO: Add tileset number in here?
|
||||
module GameData
|
||||
class DungeonParameters
|
||||
attr_reader :id, :area, :version
|
||||
attr_reader :cell_count_x, :cell_count_y
|
||||
attr_reader :cell_width, :cell_height
|
||||
attr_reader :room_min_width, :room_min_height
|
||||
attr_reader :room_max_width, :room_max_height
|
||||
attr_reader :corridor_width, :random_corridor_shift
|
||||
# Layouts:
|
||||
# :full - every node in the map
|
||||
# :no_corners - every node except for one in each corner
|
||||
# :ring - every node around the edge of the map
|
||||
# :antiring - every node except one that touches an edge of the map
|
||||
# :plus - every node in a plus (+) shape
|
||||
# :diagonal_up - every node in a line from bottom left to top right (/)
|
||||
# :diagonal_down - every node in a line from top left to bottom right (\)
|
||||
# :cross - every node in a cross (x) shape
|
||||
# :quadrants - every node except the middles of each edge (i.e. each corner bulges out)
|
||||
attr_reader :node_layout, :room_layout
|
||||
attr_reader :room_chance # Percentage of active roomable nodes that will become rooms
|
||||
attr_reader :extra_connections_count
|
||||
attr_reader :floor_patch_radius, :floor_patch_chance, :floor_patch_smooth_rate
|
||||
attr_reader :floor_decoration_density, :floor_decoration_large_density
|
||||
attr_reader :void_decoration_density, :void_decoration_large_density
|
||||
attr_reader :rng_seed
|
||||
attr_reader :flags
|
||||
|
||||
DATA = {}
|
||||
DATA_FILENAME = "dungeon_parameters.dat"
|
||||
|
||||
SCHEMA = {
|
||||
"DungeonSize" => [:dungeon_size, "vv"],
|
||||
"CellSize" => [:cell_size, "vv"],
|
||||
"MinRoomSize" => [:min_room_size, "vv"],
|
||||
"MaxRoomSize" => [:max_room_size, "vv"],
|
||||
"CorridorWidth" => [:corridor_width, "v"],
|
||||
"ShiftCorridors" => [:shift_corridors, "b"],
|
||||
"NodeLayout" => [:node_layout, "s"],
|
||||
"RoomLayout" => [:room_layout, "s"],
|
||||
"RoomChance" => [:room_chance, "v"],
|
||||
"ExtraConnections" => [:extra_connections_count, "u"],
|
||||
"FloorPatches" => [:floor_patches, "vvu"],
|
||||
"FloorDecorations" => [:floor_decorations, "uu"],
|
||||
"VoidDecorations" => [:void_decorations, "uu"],
|
||||
"RNGSeed" => [:rng_seed, "u"],
|
||||
"Flags" => [:flags, "*s"]
|
||||
}
|
||||
|
||||
extend ClassMethodsSymbols
|
||||
include InstanceMethods
|
||||
|
||||
# @param other [Symbol, String, self]
|
||||
# @param version [Integer]
|
||||
# @return [self]
|
||||
def self.try_get(area, version = 0)
|
||||
validate area => [Symbol, self, String]
|
||||
validate version => Integer
|
||||
area = area.id if area.is_a?(self)
|
||||
area = area.to_sym if area.is_a?(String)
|
||||
trial = sprintf("%s_%d", area, version).to_sym
|
||||
area_version = (DATA[trial].nil?) ? area : trial
|
||||
return (DATA.has_key?(area_version)) ? DATA[area_version] : self.new({})
|
||||
end
|
||||
|
||||
def initialize(hash)
|
||||
@id = hash[:id]
|
||||
@area = hash[:area]
|
||||
@version = hash[:version] || 0
|
||||
@cell_count_x = (hash[:dungeon_size]) ? hash[:dungeon_size][0] : 5
|
||||
@cell_count_y = (hash[:dungeon_size]) ? hash[:dungeon_size][1] : 5
|
||||
@cell_width = (hash[:cell_size]) ? hash[:cell_size][0] : 10
|
||||
@cell_height = (hash[:cell_size]) ? hash[:cell_size][1] : 10
|
||||
@room_min_width = (hash[:min_room_size]) ? hash[:min_room_size][0] : 5
|
||||
@room_min_height = (hash[:min_room_size]) ? hash[:min_room_size][1] : 5
|
||||
@room_max_width = (hash[:max_room_size]) ? hash[:max_room_size][0] : @cell_width - 1
|
||||
@room_max_height = (hash[:max_room_size]) ? hash[:max_room_size][1] : @cell_height - 1
|
||||
@corridor_width = hash[:corridor_width] || 2
|
||||
@random_corridor_shift = hash[:shift_corridors]
|
||||
@node_layout = hash[:node_layout]&.downcase&.to_sym || :full
|
||||
@room_layout = hash[:room_layout]&.downcase&.to_sym || :full
|
||||
@room_chance = hash[:room_chance] || 70
|
||||
@extra_connections_count = hash[:extra_connections_count] || 2
|
||||
@floor_patch_radius = (hash[:floor_patches]) ? hash[:floor_patches][0] : 3
|
||||
@floor_patch_chance = (hash[:floor_patches]) ? hash[:floor_patches][1] : 75
|
||||
@floor_patch_smooth_rate = (hash[:floor_patches]) ? hash[:floor_patches][2] : 25
|
||||
@floor_decoration_density = (hash[:floor_decorations]) ? hash[:floor_decorations][0] : 50
|
||||
@floor_decoration_large_density = (hash[:floor_decorations]) ? hash[:floor_decorations][1] : 200
|
||||
@void_decoration_density = (hash[:void_decorations]) ? hash[:void_decorations][0] : 50
|
||||
@void_decoration_large_density = (hash[:void_decorations]) ? hash[:void_decorations][1] : 200
|
||||
@rng_seed = hash[:rng_seed]
|
||||
@flags = hash[:flags] || []
|
||||
end
|
||||
|
||||
def has_flag?(flag)
|
||||
return @flags.any? { |f| f.downcase == flag.downcase }
|
||||
end
|
||||
|
||||
def rand_cell_center
|
||||
x = (@cell_width / 2) + rand(-2..2)
|
||||
y = (@cell_height / 2) + rand(-2..2)
|
||||
return x, y
|
||||
end
|
||||
|
||||
def rand_room_size
|
||||
width = @room_min_width
|
||||
if @room_max_width > @room_min_width
|
||||
width = rand(@room_min_width..@room_max_width)
|
||||
end
|
||||
height = @room_min_height
|
||||
if @room_max_height > @room_min_height
|
||||
height = rand(@room_min_height..@room_max_height)
|
||||
end
|
||||
return width, height
|
||||
end
|
||||
|
||||
def property_from_string(str)
|
||||
case str
|
||||
when "DungeonSize" then return [@cell_count_x, @cell_count_y]
|
||||
when "CellSize" then return [@cell_width, @cell_height]
|
||||
when "MinRoomSize" then return [@room_min_width, @room_min_height]
|
||||
when "MaxRoomSize" then return [@room_max_width, @room_max_height]
|
||||
when "CorridorWidth" then return @corridor_width
|
||||
when "ShiftCorridors" then return @random_corridor_shift
|
||||
when "NodeLayout" then return @node_layout
|
||||
when "RoomLayout" then return @room_layout
|
||||
when "RoomChance" then return @room_chance
|
||||
when "ExtraConnections" then return @extra_connections_count
|
||||
when "FloorPatches" then return [@floor_patch_radius, @floor_patch_chance, @floor_patch_smooth_rate]
|
||||
when "FloorDecorations" then return [@floor_decoration_density, @floor_decoration_large_density]
|
||||
when "VoidDecorations" then return [@void_decoration_density, @void_decoration_large_density]
|
||||
when "RNGSeed" then return @rng_seed
|
||||
when "Flags" then return @flags
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
96
Data/Scripts/010_Data/002_PBS data/020_PhoneMessage.rb
Normal file
96
Data/Scripts/010_Data/002_PBS data/020_PhoneMessage.rb
Normal file
@@ -0,0 +1,96 @@
|
||||
module GameData
|
||||
class PhoneMessage
|
||||
attr_reader :id
|
||||
attr_reader :trainer_type, :real_name, :version
|
||||
attr_reader :intro, :intro_morning, :intro_afternoon, :intro_evening
|
||||
attr_reader :body, :body1, :body2
|
||||
attr_reader :battle_request, :battle_remind
|
||||
attr_reader :end
|
||||
|
||||
DATA = {}
|
||||
DATA_FILENAME = "phone.dat"
|
||||
|
||||
SCHEMA = {
|
||||
"Intro" => [:intro, "q"],
|
||||
"IntroMorning" => [:intro_morning, "q"],
|
||||
"IntroAfternoon" => [:intro_afternoon, "q"],
|
||||
"IntroEvening" => [:intro_evening, "q"],
|
||||
"Body" => [:body, "q"],
|
||||
"Body1" => [:body1, "q"],
|
||||
"Body2" => [:body2, "q"],
|
||||
"BattleRequest" => [:battle_request, "q"],
|
||||
"BattleRemind" => [:battle_remind, "q"],
|
||||
"End" => [:end, "q"]
|
||||
}
|
||||
|
||||
extend ClassMethodsSymbols
|
||||
include InstanceMethods
|
||||
|
||||
# @param tr_type [Symbol, String]
|
||||
# @param tr_name [String]
|
||||
# @param tr_version [Integer, nil]
|
||||
# @return [Boolean] whether the given other is defined as a self
|
||||
def self.exists?(tr_type, tr_name, tr_version = 0)
|
||||
validate tr_type => [Symbol, String]
|
||||
validate tr_name => [String]
|
||||
key = [tr_type.to_sym, tr_name, tr_version]
|
||||
return !self::DATA[key].nil?
|
||||
end
|
||||
|
||||
# @param tr_type [Symbol, String]
|
||||
# @param tr_name [String]
|
||||
# @param tr_version [Integer, nil]
|
||||
# @return [self]
|
||||
def self.get(tr_type, tr_name, tr_version = 0)
|
||||
validate tr_type => [Symbol, String]
|
||||
validate tr_name => [String]
|
||||
key = [tr_type.to_sym, tr_name, tr_version]
|
||||
raise "Phone messages not found for #{tr_type} #{tr_name} #{tr_version}." unless self::DATA.has_key?(key)
|
||||
return self::DATA[key]
|
||||
end
|
||||
|
||||
# @param tr_type [Symbol, String]
|
||||
# @param tr_name [String]
|
||||
# @param tr_version [Integer, nil]
|
||||
# @return [self, nil]
|
||||
def self.try_get(tr_type, tr_name, tr_version = 0)
|
||||
validate tr_type => [Symbol, String]
|
||||
validate tr_name => [String]
|
||||
key = [tr_type.to_sym, tr_name, tr_version]
|
||||
return (self::DATA.has_key?(key)) ? self::DATA[key] : nil
|
||||
end
|
||||
|
||||
def initialize(hash)
|
||||
@id = hash[:id]
|
||||
@trainer_type = hash[:trainer_type]
|
||||
@real_name = hash[:name]
|
||||
@version = hash[:version] || 0
|
||||
@intro = hash[:intro]
|
||||
@intro_morning = hash[:intro_morning]
|
||||
@intro_afternoon = hash[:intro_afternoon]
|
||||
@intro_evening = hash[:intro_evening]
|
||||
@body = hash[:body]
|
||||
@body1 = hash[:body1]
|
||||
@body2 = hash[:body2]
|
||||
@battle_request = hash[:battle_request]
|
||||
@battle_remind = hash[:battle_remind]
|
||||
@end = hash[:end]
|
||||
end
|
||||
|
||||
def property_from_string(str)
|
||||
case str
|
||||
when "Intro" then return @intro
|
||||
when "IntroMorning" then return @intro_morning
|
||||
when "IntroAfternoon" then return @intro_afternoon
|
||||
when "IntroEvening" then return @intro_evening
|
||||
when "Body" then return @body
|
||||
when "Body1" then return @body1
|
||||
when "Body2" then return @body2
|
||||
when "BattleRequest" then return @battle_request
|
||||
when "BattleRemind" then return @battle_remind
|
||||
when "End" then return @end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -21,6 +21,36 @@ class Battle
|
||||
return true
|
||||
end
|
||||
|
||||
# Return values:
|
||||
# -1: Chose not to end the battle via Debug means
|
||||
# 0: Couldn't end the battle via Debug means; carry on trying to run
|
||||
# 1: Ended the battle via Debug means
|
||||
def pbDebugRun
|
||||
return 0 if !$DEBUG || !Input.press?(Input::CTRL)
|
||||
commands = [_INTL("Treat as a win"), _INTL("Treat as a loss"),
|
||||
_INTL("Treat as a draw"), _INTL("Treat as running away/forfeit")]
|
||||
commands.push(_INTL("Treat as a capture")) if wildBattle?
|
||||
commands.push(_INTL("Cancel"))
|
||||
case pbShowCommands(_INTL("Choose the outcome of this battle."), commands)
|
||||
when 0 # Win
|
||||
@decision = 1
|
||||
when 1 # Loss
|
||||
@decision = 2
|
||||
when 2 # Draw
|
||||
@decision = 5
|
||||
when 3 # Run away/forfeit
|
||||
pbSEPlay("Battle flee")
|
||||
pbDisplayPaused(_INTL("You got away safely!"))
|
||||
@decision = 3
|
||||
when 4 # Capture
|
||||
return -1 if trainerBattle?
|
||||
@decision = 4
|
||||
else
|
||||
return -1
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
# Return values:
|
||||
# -1: Failed fleeing
|
||||
# 0: Wasn't possible to attempt fleeing, continue choosing action for the round
|
||||
@@ -36,17 +66,12 @@ class Battle
|
||||
@choices[idxBattler][2] = nil
|
||||
return -1
|
||||
end
|
||||
# Fleeing from trainer battles
|
||||
# Debug ending the battle
|
||||
debug_ret = pbDebugRun
|
||||
return debug_ret if debug_ret != 0
|
||||
# Running from trainer battles
|
||||
if trainerBattle?
|
||||
if $DEBUG && Input.press?(Input::CTRL)
|
||||
if pbDisplayConfirm(_INTL("Treat this battle as a win?"))
|
||||
@decision = 1
|
||||
return 1
|
||||
elsif pbDisplayConfirm(_INTL("Treat this battle as a loss?"))
|
||||
@decision = 2
|
||||
return 1
|
||||
end
|
||||
elsif @internalBattle
|
||||
if @internalBattle
|
||||
pbDisplayPaused(_INTL("No! There's no running from a Trainer battle!"))
|
||||
elsif pbDisplayConfirm(_INTL("Would you like to forfeit the match and quit now?"))
|
||||
pbSEPlay("Battle flee")
|
||||
@@ -56,13 +81,6 @@ class Battle
|
||||
end
|
||||
return 0
|
||||
end
|
||||
# Fleeing from wild battles
|
||||
if $DEBUG && Input.press?(Input::CTRL)
|
||||
pbSEPlay("Battle flee")
|
||||
pbDisplayPaused(_INTL("You got away safely!"))
|
||||
@decision = 3
|
||||
return 1
|
||||
end
|
||||
if !@canRun
|
||||
pbDisplayPaused(_INTL("You can't escape!"))
|
||||
return 0
|
||||
|
||||
@@ -36,6 +36,9 @@ class Battle
|
||||
end
|
||||
|
||||
def pbCall(idxBattler)
|
||||
# Debug ending the battle
|
||||
return if pbDebugRun != 0
|
||||
# Call the battler
|
||||
battler = @battlers[idxBattler]
|
||||
trainerName = pbGetOwnerName(idxBattler)
|
||||
pbDisplay(_INTL("{1} called {2}!", trainerName, battler.pbThis(true)))
|
||||
|
||||
@@ -24,7 +24,7 @@ class Battle::Battler
|
||||
|
||||
def pbCanInflictStatus?(newStatus, user, showMessages, move = nil, ignoreStatus = false)
|
||||
return false if fainted?
|
||||
selfInflicted = (user && user.index == @index)
|
||||
self_inflicted = (user && user.index == @index) # Rest and Flame Orb/Toxic Orb only
|
||||
# Already have that status problem
|
||||
if self.status == newStatus && !ignoreStatus
|
||||
if showMessages
|
||||
@@ -41,13 +41,13 @@ class Battle::Battler
|
||||
return false
|
||||
end
|
||||
# Trying to replace a status problem with another one
|
||||
if self.status != :NONE && !ignoreStatus && !selfInflicted
|
||||
if self.status != :NONE && !ignoreStatus && !(self_inflicted && move) # Rest can replace a status problem
|
||||
@battle.pbDisplay(_INTL("It doesn't affect {1}...", pbThis(true))) if showMessages
|
||||
return false
|
||||
end
|
||||
# Trying to inflict a status problem on a Pokémon behind a substitute
|
||||
if @effects[PBEffects::Substitute] > 0 && !(move && move.ignoresSubstitute?(user)) &&
|
||||
!selfInflicted
|
||||
!self_inflicted
|
||||
@battle.pbDisplay(_INTL("It doesn't affect {1}...", pbThis(true))) if showMessages
|
||||
return false
|
||||
end
|
||||
@@ -105,7 +105,7 @@ class Battle::Battler
|
||||
immAlly = nil
|
||||
if Battle::AbilityEffects.triggerStatusImmunityNonIgnorable(self.ability, self, newStatus)
|
||||
immuneByAbility = true
|
||||
elsif selfInflicted || !@battle.moldBreaker
|
||||
elsif self_inflicted || !@battle.moldBreaker
|
||||
if abilityActive? && Battle::AbilityEffects.triggerStatusImmunity(self.ability, self, newStatus)
|
||||
immuneByAbility = true
|
||||
else
|
||||
@@ -163,7 +163,7 @@ class Battle::Battler
|
||||
return false
|
||||
end
|
||||
# Safeguard immunity
|
||||
if pbOwnSide.effects[PBEffects::Safeguard] > 0 && !selfInflicted && move &&
|
||||
if pbOwnSide.effects[PBEffects::Safeguard] > 0 && !self_inflicted && move &&
|
||||
!(user && user.hasActiveAbility?(:INFILTRATOR))
|
||||
@battle.pbDisplay(_INTL("{1}'s team is protected by Safeguard!", pbThis)) if showMessages
|
||||
return false
|
||||
|
||||
@@ -496,6 +496,12 @@ Battle::AbilityEffects::StatusImmunityFromAlly.add(:FLOWERVEIL,
|
||||
}
|
||||
)
|
||||
|
||||
Battle::AbilityEffects::StatusImmunityFromAlly.add(:PASTELVEIL,
|
||||
proc { |ability, battler, status|
|
||||
next true if status == :POISON
|
||||
}
|
||||
)
|
||||
|
||||
Battle::AbilityEffects::StatusImmunityFromAlly.add(:SWEETVEIL,
|
||||
proc { |ability, battler, status|
|
||||
next true if status == :SLEEP
|
||||
@@ -561,6 +567,8 @@ Battle::AbilityEffects::StatusCure.add(:IMMUNITY,
|
||||
}
|
||||
)
|
||||
|
||||
Battle::AbilityEffects::StatusCure.copy(:IMMUNITY, :PASTELVEIL)
|
||||
|
||||
Battle::AbilityEffects::StatusCure.add(:INSOMNIA,
|
||||
proc { |ability, battler|
|
||||
next if battler.status != :SLEEP
|
||||
|
||||
@@ -32,10 +32,10 @@ EventHandlers.add(:on_wild_pokemon_created, :level_depends_on_party,
|
||||
# Note that you can only modify a partner trainer's Pokémon, and not the trainer
|
||||
# themselves nor their items this way, as those are generated from scratch
|
||||
# before each battle.
|
||||
#EventHandlers.add(:on_trainer_load, :put_a_name_here,
|
||||
# EventHandlers.add(:on_trainer_load, :put_a_name_here,
|
||||
# proc { |trainer|
|
||||
# if trainer # An NPCTrainer object containing party/items/lose text, etc.
|
||||
# YOUR CODE HERE
|
||||
# end
|
||||
# }
|
||||
#)
|
||||
# )
|
||||
|
||||
@@ -259,7 +259,8 @@ class BerryPlantSprite
|
||||
when 2 then @event.turn_down # X sprouted
|
||||
when 3 then @event.turn_left # X taller
|
||||
when 4 then @event.turn_right # X flowering
|
||||
when 5 then @event.turn_up # X berries
|
||||
else
|
||||
@event.turn_up if berry_plant.growth_stage >= 5 # X berries
|
||||
end
|
||||
else
|
||||
@event.character_name = "Object ball"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,25 @@
|
||||
# TODO: Add an information window with details of the person in a phone call.
|
||||
# Make this work with common event calls (create and dispose the info
|
||||
# window in start_message and end_message).
|
||||
# TODO: Rewrite the Phone UI. Have more than one method. Choosable icons/marks
|
||||
# for each contact? Show an icon representing phone signal.
|
||||
# TODO: Look at the "ready to rematch" timers to see if they can be improved?
|
||||
# Should they be limited to one trainer becoming ready every ~5 minutes?
|
||||
# Should a rematch-ready contact become unready again after some time if
|
||||
# they haven't told the player they're ready?
|
||||
# TODO: See if incoming phone calls can be made optional somehow. Maybe just
|
||||
# interrupt as normal with the start of the call and ask if the player
|
||||
# wants to answer? Wait for a couple of seconds before asking to make sure
|
||||
# the player doesn't accidentally skip/answer a call they didn't want to.
|
||||
# TODO: Add a Debug way of upgrading old phone script calls to new ones, or at
|
||||
# least to find events using old phone scripts for the dev to update.
|
||||
# TODO: More Debug control over contacts (changing their "time to rebattle",
|
||||
# unhiding hidden contacts, etc.) and the phone (time until next call).
|
||||
|
||||
# TODO: Add a trainer comment for giving a trainer a common event ID.
|
||||
# TODO: Add calling a contact at a particular time forcing rematch readiness.
|
||||
# Add trainer comments for this.
|
||||
# TODO: Allow individual trainers to never arrange a rematch by themself, thus
|
||||
# requiring the player to call them at their particular time of day/week.
|
||||
# TODO: Be able to put the Phone on silent mode (prevent all phone calls from
|
||||
# trainers, but allow scripted calls as normal).
|
||||
|
||||
# TODO: Better messages, more customisation of messages.
|
||||
# TODO: Add a Debug way of upgrading old phone script calls to new ones, or at
|
||||
# least to find events using old phone scripts for the dev to update.
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
@@ -70,8 +75,8 @@ class Phone
|
||||
return true
|
||||
end
|
||||
|
||||
# Event, trainer type, name, versions_count = 1, start_version = 0
|
||||
# Map ID, event ID, trainer type, name, versions_count = 1, start_version = 0
|
||||
# Event, trainer type, name, versions_count = 1, start_version = 0, common event ID = 0
|
||||
# Map ID, event ID, trainer type, name, versions_count = 1, start_version = 0, common event ID = 0
|
||||
# Map ID, name, common event ID
|
||||
def add(*args)
|
||||
if args[0].is_a?(Game_Event)
|
||||
@@ -82,9 +87,11 @@ class Phone
|
||||
contact = get(true, trainer_type, name, args[3] || 0)
|
||||
if contact
|
||||
contact.visible = true
|
||||
@contacts.delete(contact)
|
||||
@contacts.push(contact)
|
||||
else
|
||||
contact = Contact.new(true, args[0].map_id, args[0].id,
|
||||
trainer_type, name, args[3] || 1, args[4] || 0)
|
||||
trainer_type, name, args[3], args[4], args[5])
|
||||
contact.increment_version
|
||||
@contacts.push(contact)
|
||||
end
|
||||
@@ -96,9 +103,11 @@ class Phone
|
||||
contact = get(true, trainer_type, name, args[4] || 0)
|
||||
if contact
|
||||
contact.visible = true
|
||||
@contacts.delete(contact)
|
||||
@contacts.push(contact)
|
||||
else
|
||||
contact = Contact.new(true, args[0], args[1],
|
||||
trainer_type, name, args[4] || 1, args[5] || 0)
|
||||
trainer_type, name, args[4], args[5], args[6])
|
||||
contact.increment_version
|
||||
@contacts.push(contact)
|
||||
end
|
||||
@@ -108,14 +117,30 @@ class Phone
|
||||
contact = get(false, name)
|
||||
if contact
|
||||
contact.visible = true
|
||||
@contacts.delete(contact)
|
||||
@contacts.push(contact)
|
||||
else
|
||||
contact = Contact.new(false, *args)
|
||||
@contacts.push(contact)
|
||||
end
|
||||
end
|
||||
sort_contacts
|
||||
return true
|
||||
end
|
||||
|
||||
# Rearranges the list of phone contacts to put all visible contacts first,
|
||||
# followed by all invisible contacts.
|
||||
def sort_contacts
|
||||
new_contacts = []
|
||||
2.times do |i|
|
||||
@contacts.each do |con|
|
||||
next if (i == 0 && !con.visible?) || (i == 1 && con.visible?)
|
||||
new_contacts.push(con)
|
||||
end
|
||||
end
|
||||
@contacts = new_contacts
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
|
||||
# Checks once every second.
|
||||
@@ -233,7 +258,7 @@ class Phone
|
||||
attr_accessor :trainer_type, :start_version, :versions_count, :version
|
||||
attr_accessor :time_to_ready, :rematch_flag, :variant_beaten
|
||||
attr_accessor :common_event_id
|
||||
attr_accessor :visible
|
||||
attr_reader :visible
|
||||
|
||||
# Map ID, event ID, trainer type, name, versions count = 1, start version = 0
|
||||
# Map ID, name, common event ID
|
||||
@@ -251,7 +276,7 @@ class Phone
|
||||
@variant_beaten = 0
|
||||
@time_to_ready = 0
|
||||
@rematch_flag = 0 # 0=counting down, 1=ready for rematch, 2=ready and told player
|
||||
@common_event_id = 0
|
||||
@common_event_id = args[6] || 0
|
||||
else
|
||||
# Non-trainer
|
||||
@map_id = args[0]
|
||||
@@ -280,6 +305,10 @@ class Phone
|
||||
end
|
||||
end
|
||||
|
||||
def can_hide?
|
||||
return trainer?
|
||||
end
|
||||
|
||||
def common_event_call?
|
||||
return @common_event_id > 0
|
||||
end
|
||||
@@ -373,7 +402,13 @@ class Phone
|
||||
def make_incoming
|
||||
return if !can_make?
|
||||
contact = get_random_trainer_for_incoming_call
|
||||
if contact
|
||||
return if !contact
|
||||
if contact.common_event_call?
|
||||
if !pbCommonEvent(contact.common_event_id)
|
||||
pbMessage(_INTL("{1}'s messages not defined.\nCouldn't call common event {2}.",
|
||||
contact.display_name, contact.common_event_id))
|
||||
end
|
||||
else
|
||||
call = generate_trainer_dialogue(contact)
|
||||
play(call, contact)
|
||||
end
|
||||
@@ -403,7 +438,7 @@ class Phone
|
||||
end
|
||||
end
|
||||
|
||||
def start_message(contact)
|
||||
def start_message(contact = nil)
|
||||
pbMessage(_INTL("......\\wt[5] ......\\1"))
|
||||
end
|
||||
|
||||
@@ -434,7 +469,7 @@ class Phone
|
||||
end_message(contact)
|
||||
end
|
||||
|
||||
def end_message(contact)
|
||||
def end_message(contact = nil)
|
||||
pbMessage(_INTL("Click!\\wt[10]\n......\\wt[5] ......\\1"))
|
||||
end
|
||||
|
||||
@@ -442,36 +477,58 @@ class Phone
|
||||
|
||||
def generate_trainer_dialogue(contact)
|
||||
validate contact => Phone::Contact
|
||||
# Get the set of messages to be used by the contact
|
||||
messages = GameData::PhoneMessage.try_get(contact.trainer_type, contact.name, contact.version)
|
||||
messages = GameData::PhoneMessage.try_get(contact.trainer_type, contact.name, contact.start_version) if !messages
|
||||
messages = GameData::PhoneMessage::DATA["default"] if !messages
|
||||
# Create lambda for choosing a random message and translating it
|
||||
get_random_message = lambda do |messages|
|
||||
return "" if !messages
|
||||
msg = messages.sample
|
||||
return "" if !msg
|
||||
return pbGetMessageFromHash(MessageTypes::PhoneMessages, msg)
|
||||
end
|
||||
phone_data = pbLoadPhoneData
|
||||
# Choose random greeting depending on time of day
|
||||
ret = get_random_message.call(phone_data.greetings)
|
||||
ret = get_random_message.call(messages.intro)
|
||||
time = pbGetTimeNow
|
||||
if PBDayNight.isMorning?(time)
|
||||
modcall = get_random_message.call(phone_data.greetingsMorning)
|
||||
ret = modcall if !nil_or_empty?(modcall)
|
||||
mod_call = get_random_message.call(messages.intro_morning)
|
||||
ret = mod_call if !nil_or_empty?(mod_call)
|
||||
elsif PBDayNight.isAfternoon?(time)
|
||||
mod_call = get_random_message.call(messages.intro_afternoon)
|
||||
ret = mod_call if !nil_or_empty?(mod_call)
|
||||
elsif PBDayNight.isEvening?(time)
|
||||
modcall = get_random_message.call(phone_data.greetingsEvening)
|
||||
ret = modcall if !nil_or_empty?(modcall)
|
||||
mod_call = get_random_message.call(messages.intro_evening)
|
||||
ret = mod_call if !nil_or_empty?(mod_call)
|
||||
end
|
||||
ret += "\\m"
|
||||
if Phone.rematches_enabled && (contact.rematch_flag == 1 ||
|
||||
(contact.rematch_flag == 2 && rand(100) < 50))
|
||||
# If ready for rematch, tell the player (50% chance to remind the player)
|
||||
ret += get_random_message.call(phone_data.battleRequests)
|
||||
# Choose main message set
|
||||
if Phone.rematches_enabled && contact.rematch_flag > 0
|
||||
# Trainer is ready for a rematch, so tell/remind the player
|
||||
if contact.rematch_flag == 1 # Tell the player
|
||||
ret += get_random_message.call(messages.battle_request)
|
||||
contact.rematch_flag = 2 # Ready for rematch and told player
|
||||
elsif rand(100) < 75
|
||||
# Choose random body
|
||||
ret += get_random_message.call(phone_data.bodies1)
|
||||
ret += "\\m"
|
||||
ret += get_random_message.call(phone_data.bodies2)
|
||||
elsif contact.rematch_flag == 2 # Remind the player
|
||||
if messages.battle_remind
|
||||
ret += get_random_message.call(messages.battle_remind)
|
||||
else
|
||||
# Choose random generic
|
||||
ret += get_random_message.call(phone_data.generics)
|
||||
ret += get_random_message.call(messages.battle_request)
|
||||
end
|
||||
end
|
||||
else
|
||||
# Standard messages
|
||||
if messages.body1 && messages.body2 && (!messages.body || rand(100) < 75)
|
||||
# Choose random pair of body messages
|
||||
ret += get_random_message.call(messages.body1)
|
||||
ret += "\\m"
|
||||
ret += get_random_message.call(messages.body2)
|
||||
else
|
||||
# Choose random full body message
|
||||
ret += get_random_message.call(messages.body)
|
||||
end
|
||||
# Choose end message
|
||||
mod_call = get_random_message.call(messages.end)
|
||||
ret += "\\m" + mod_call if !nil_or_empty?(mod_call)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -28,9 +28,7 @@ class PokemonEggHatch_Scene
|
||||
@pokemon.form, @pokemon.shiny?,
|
||||
false, false, true) # Egg sprite
|
||||
# Load egg cracks bitmap
|
||||
crackfilename = sprintf("Graphics/Pokemon/Eggs/%s_cracks", @pokemon.species)
|
||||
crackfilename = sprintf("Graphics/Pokemon/Eggs/000_cracks") if !pbResolveBitmap(crackfilename)
|
||||
crackfilename = pbResolveBitmap(crackfilename)
|
||||
crackfilename = GameData::Species.egg_cracks_sprite_filename(@pokemon.species, @pokemon.form)
|
||||
@hatchSheet = AnimatedBitmap.new(crackfilename)
|
||||
# Create egg cracks sprite
|
||||
@sprites["hatch"] = Sprite.new(@viewport)
|
||||
|
||||
@@ -811,6 +811,7 @@ class PokemonParty_Scene
|
||||
currentsel = Settings::MAX_PARTY_SIZE
|
||||
elsif currentsel == numsprites
|
||||
currentsel = 0
|
||||
currentsel = numsprites - 1 if currentsel >= @party.length
|
||||
end
|
||||
when Input::UP
|
||||
if currentsel >= Settings::MAX_PARTY_SIZE
|
||||
@@ -818,6 +819,7 @@ class PokemonParty_Scene
|
||||
while currentsel > 0 && currentsel < Settings::MAX_PARTY_SIZE && !@party[currentsel]
|
||||
currentsel -= 1
|
||||
end
|
||||
currentsel = numsprites - 1 if currentsel >= @party.length
|
||||
else
|
||||
loop do
|
||||
currentsel -= 2
|
||||
@@ -839,6 +841,7 @@ class PokemonParty_Scene
|
||||
currentsel = Settings::MAX_PARTY_SIZE
|
||||
elsif currentsel >= numsprites
|
||||
currentsel = 0
|
||||
currentsel = numsprites - 1 if currentsel >= @party.length
|
||||
end
|
||||
end
|
||||
return currentsel
|
||||
@@ -853,7 +856,7 @@ class PokemonParty_Scene
|
||||
@sprites["pokemon#{i}"].dispose
|
||||
end
|
||||
lastselected = @party.length - 1 if lastselected >= @party.length
|
||||
lastselected = 0 if lastselected < 0
|
||||
lastselected = Settings::MAX_PARTY_SIZE if lastselected < 0
|
||||
Settings::MAX_PARTY_SIZE.times do |i|
|
||||
if @party[i]
|
||||
@sprites["pokemon#{i}"] = PokemonPartyPanel.new(@party[i], i, @viewport)
|
||||
|
||||
@@ -182,7 +182,11 @@ MenuHandlers.add(:pokegear_menu, :phone, {
|
||||
"order" => 20,
|
||||
# "condition" => proc { next $PokemonGlobal.phone && $PokemonGlobal.phone.contacts.length > 0 },
|
||||
"effect" => proc { |menu|
|
||||
pbFadeOutIn { PokemonPhoneScene.new.start }
|
||||
pbFadeOutIn {
|
||||
scene = PokemonPhone_Scene.new
|
||||
screen = PokemonPhoneScreen.new(scene)
|
||||
screen.pbStartScreen
|
||||
}
|
||||
next false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
# TODO: Choosable icons/marks for each contact? Add a "sort by" option for these.
|
||||
#===============================================================================
|
||||
# Phone screen
|
||||
# Phone list of contacts
|
||||
#===============================================================================
|
||||
class Window_PhoneList < Window_CommandPokemon
|
||||
attr_accessor :switching
|
||||
|
||||
def drawCursor(index, rect)
|
||||
selarrow = AnimatedBitmap.new("Graphics/UI/Phone/cursor")
|
||||
if self.index == index
|
||||
selarrow = AnimatedBitmap.new("Graphics/UI/Phone/cursor")
|
||||
pbCopyBitmap(self.contents, selarrow.bitmap, rect.x, rect.y + 2)
|
||||
end
|
||||
return Rect.new(rect.x + 28, rect.y + 8, rect.width - 16, rect.height)
|
||||
@@ -12,7 +15,13 @@ class Window_PhoneList < Window_CommandPokemon
|
||||
|
||||
def drawItem(index, count, rect)
|
||||
return if index >= self.top_row + self.page_item_max
|
||||
if self.index == index && @switching
|
||||
rect = drawCursor(index, rect)
|
||||
pbDrawShadowText(self.contents, rect.x, rect.y + (self.contents.text_offset_y || 0),
|
||||
rect.width, rect.height, @commands[index], Color.new(224, 0, 0), Color.new(224, 144, 144))
|
||||
else
|
||||
super
|
||||
end
|
||||
drawCursor(index - 1, itemRect(index - 1))
|
||||
end
|
||||
end
|
||||
@@ -20,17 +29,57 @@ end
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class PokemonPhoneScene
|
||||
def start
|
||||
# Get list of contacts
|
||||
class PokemonPhone_Scene
|
||||
def pbStartScene
|
||||
@sprites = {}
|
||||
# Create viewport
|
||||
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
@viewport.z = 99999
|
||||
# Background
|
||||
addBackgroundPlane(@sprites, "bg", "Phone/bg", @viewport)
|
||||
# List of contacts
|
||||
@sprites["list"] = Window_PhoneList.newEmpty(152, 32, Graphics.width - 142, Graphics.height - 80, @viewport)
|
||||
@sprites["list"].windowskin = nil
|
||||
# Rematch readiness icons
|
||||
if Phone.rematches_enabled
|
||||
@sprites["list"].page_item_max.times do |i|
|
||||
@sprites["rematch_#{i}"] = IconSprite.new(468, 62 + (i * 32), @viewport)
|
||||
end
|
||||
end
|
||||
# Phone signal icon
|
||||
@sprites["signal"] = IconSprite.new(Graphics.width - 32, 0, @viewport)
|
||||
if Phone::Call.can_make?
|
||||
@sprites["signal"].setBitmap("Graphics/UI/Phone/icon_signal")
|
||||
else
|
||||
@sprites["signal"].setBitmap("Graphics/UI/Phone/icon_nosignal")
|
||||
end
|
||||
# Title text
|
||||
@sprites["header"] = Window_UnformattedTextPokemon.newWithSize(
|
||||
_INTL("Phone"), 2, -18, 128, 64, @viewport
|
||||
)
|
||||
@sprites["header"].baseColor = Color.new(248, 248, 248)
|
||||
@sprites["header"].shadowColor = Color.black
|
||||
@sprites["header"].windowskin = nil
|
||||
# Info text about all contacts
|
||||
@sprites["info"] = Window_AdvancedTextPokemon.newWithSize("", -8, 224, 180, 160, @viewport)
|
||||
@sprites["info"].windowskin = nil
|
||||
# Portrait of contact
|
||||
@sprites["icon"] = IconSprite.new(70, 102, @viewport)
|
||||
# Contact's location text
|
||||
@sprites["bottom"] = Window_AdvancedTextPokemon.newWithSize(
|
||||
"", 162, Graphics.height - 64, Graphics.width - 158, 64, @viewport
|
||||
)
|
||||
@sprites["bottom"].windowskin = nil
|
||||
# Start scene
|
||||
pbRefreshList
|
||||
pbFadeInAndShow(@sprites) { pbUpdate }
|
||||
end
|
||||
|
||||
def pbRefreshList
|
||||
@contacts = []
|
||||
$PokemonGlobal.phone.contacts.each do |contact|
|
||||
@contacts.push(contact) if contact.visible?
|
||||
end
|
||||
if @contacts.length == 0
|
||||
pbMessage(_INTL("There are no phone numbers stored."))
|
||||
return
|
||||
end
|
||||
# Create list of commands (display names of contacts) and count rematches
|
||||
commands = []
|
||||
rematch_count = 0
|
||||
@@ -38,62 +87,36 @@ class PokemonPhoneScene
|
||||
commands.push(contact.display_name)
|
||||
rematch_count += 1 if contact.can_rematch?
|
||||
end
|
||||
# Create viewport and sprites
|
||||
@sprites = {}
|
||||
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
@viewport.z = 99999
|
||||
addBackgroundPlane(@sprites, "bg", "Phone/bg", @viewport)
|
||||
@sprites["list"] = Window_PhoneList.newEmpty(152, 32, Graphics.width - 142, Graphics.height - 80, @viewport)
|
||||
@sprites["list"].windowskin = nil
|
||||
# Set list's commands
|
||||
@sprites["list"].commands = commands
|
||||
@sprites["list"].page_item_max.times do |i|
|
||||
@sprites["rematch[#{i}]"] = IconSprite.new(468, 62 + (i * 32), @viewport)
|
||||
j = i + @sprites["list"].top_item
|
||||
if j < @contacts.length && @contacts[j].can_rematch?
|
||||
@sprites["rematch[#{i}]"].setBitmap("Graphics/UI/Phone/icon_rematch")
|
||||
@sprites["list"].index = commands.length - 1 if @sprites["list"].index >= commands.length
|
||||
if @sprites["list"].top_row > @sprites["list"].itemCount - @sprites["list"].page_item_max
|
||||
@sprites["list"].top_row = @sprites["list"].itemCount - @sprites["list"].page_item_max
|
||||
end
|
||||
end
|
||||
@sprites["header"] = Window_UnformattedTextPokemon.newWithSize(
|
||||
_INTL("Phone"), 2, -18, 128, 64, @viewport
|
||||
)
|
||||
@sprites["header"].baseColor = Color.new(248, 248, 248)
|
||||
@sprites["header"].shadowColor = Color.black
|
||||
@sprites["header"].windowskin = nil
|
||||
@sprites["bottom"] = Window_AdvancedTextPokemon.newWithSize(
|
||||
"", 162, Graphics.height - 64, Graphics.width - 158, 64, @viewport
|
||||
)
|
||||
@sprites["bottom"].windowskin = nil
|
||||
map_name = (@contacts[0].map_id > 0) ? pbGetMapNameFromId(@contacts[0].map_id) : ""
|
||||
@sprites["bottom"].text = "<ac>" + map_name
|
||||
@sprites["info"] = Window_AdvancedTextPokemon.newWithSize("", -8, 224, 180, 160, @viewport)
|
||||
@sprites["info"].windowskin = nil
|
||||
# Set info text
|
||||
infotext = _INTL("Registered<br>")
|
||||
infotext += _INTL(" <r>{1}<br>", @sprites["list"].commands.length)
|
||||
infotext += _INTL("Waiting for a rematch<r>{1}", rematch_count)
|
||||
@sprites["info"].text = infotext
|
||||
@sprites["icon"] = IconSprite.new(70, 102, @viewport)
|
||||
if @contacts[0].trainer?
|
||||
filename = GameData::TrainerType.charset_filename(@contacts[0].trainer_type)
|
||||
else
|
||||
filename = sprintf("Graphics/Characters/phone%03d", @contacts[0].common_event_id)
|
||||
pbRefreshScreen
|
||||
end
|
||||
@sprites["icon"].setBitmap(filename)
|
||||
charwidth = @sprites["icon"].bitmap.width
|
||||
charheight = @sprites["icon"].bitmap.height
|
||||
@sprites["icon"].x = 86 - (charwidth / 8)
|
||||
@sprites["icon"].y = 134 - (charheight / 8)
|
||||
@sprites["icon"].src_rect = Rect.new(0, 0, charwidth / 4, charheight / 4)
|
||||
# Start scene
|
||||
pbFadeInAndShow(@sprites)
|
||||
pbActivateWindow(@sprites, "list") {
|
||||
oldindex = -1
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
pbUpdateSpriteHash(@sprites)
|
||||
# Cursor moved, update display
|
||||
if @sprites["list"].index != oldindex
|
||||
|
||||
def pbRefreshScreen
|
||||
@sprites["list"].refresh
|
||||
# Redraw rematch readiness icons
|
||||
if @sprites["rematch_0"]
|
||||
@sprites["list"].page_item_max.times do |i|
|
||||
@sprites["rematch_#{i}"].clearBitmaps
|
||||
j = i + @sprites["list"].top_item
|
||||
if j < @contacts.length && @contacts[j].can_rematch?
|
||||
@sprites["rematch_#{i}"].setBitmap("Graphics/UI/Phone/icon_rematch")
|
||||
end
|
||||
end
|
||||
end
|
||||
# Get the selected contact
|
||||
contact = @contacts[@sprites["list"].index]
|
||||
if contact
|
||||
# Redraw contact's portrait
|
||||
if contact.trainer?
|
||||
filename = GameData::TrainerType.charset_filename(contact.trainer_type)
|
||||
else
|
||||
@@ -105,28 +128,145 @@ class PokemonPhoneScene
|
||||
@sprites["icon"].x = 86 - (charwidth / 8)
|
||||
@sprites["icon"].y = 134 - (charheight / 8)
|
||||
@sprites["icon"].src_rect = Rect.new(0, 0, charwidth / 4, charheight / 4)
|
||||
# Redraw contact's location text
|
||||
map_name = (contact.map_id > 0) ? pbGetMapNameFromId(contact.map_id) : ""
|
||||
@sprites["bottom"].text = "<ac>" + map_name
|
||||
@sprites["list"].page_item_max.times do |i|
|
||||
@sprites["rematch[#{i}]"].clearBitmaps
|
||||
j = i + @sprites["list"].top_item
|
||||
if j < @contacts.length && @contacts[j].can_rematch?
|
||||
@sprites["rematch[#{i}]"].setBitmap("Graphics/UI/Phone/icon_rematch")
|
||||
else
|
||||
@sprites["icon"].setBitmap(nil)
|
||||
@sprites["bottom"].text = ""
|
||||
end
|
||||
end
|
||||
|
||||
def pbChooseContact
|
||||
pbActivateWindow(@sprites, "list") {
|
||||
index = -1
|
||||
switch_index = -1
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
pbUpdateSpriteHash(@sprites)
|
||||
# Cursor moved, update display
|
||||
if @sprites["list"].index != index
|
||||
if switch_index >= 0
|
||||
real_contacts = $PokemonGlobal.phone.contacts
|
||||
real_contacts.insert(@sprites["list"].index, real_contacts.delete_at(index))
|
||||
pbRefreshList
|
||||
else
|
||||
pbRefreshScreen
|
||||
end
|
||||
end
|
||||
# Get inputs
|
||||
if Input.trigger?(Input::BACK)
|
||||
pbPlayCloseMenuSE
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
index = @sprites["list"].index
|
||||
Phone::Call.make_outgoing(@contacts[index]) if index >= 0
|
||||
# Get inputs
|
||||
if switch_index >= 0
|
||||
if Input.trigger?(Input::ACTION) ||
|
||||
Input.trigger?(Input::USE)
|
||||
pbPlayDecisionSE
|
||||
@sprites["list"].switching = false
|
||||
switch_index = -1
|
||||
pbRefreshScreen
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
pbPlayCancelSE
|
||||
real_contacts = $PokemonGlobal.phone.contacts
|
||||
real_contacts.insert(switch_index, real_contacts.delete_at(@sprites["list"].index))
|
||||
@sprites["list"].index = switch_index
|
||||
@sprites["list"].switching = false
|
||||
switch_index = -1
|
||||
pbRefreshList
|
||||
end
|
||||
else
|
||||
if Input.trigger?(Input::ACTION)
|
||||
switch_index = @sprites["list"].index
|
||||
@sprites["list"].switching = true
|
||||
pbRefreshScreen
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
pbPlayCloseMenuSE
|
||||
return nil
|
||||
elsif Input.trigger?(Input::USE)
|
||||
return @contacts[index] if index >= 0
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
pbFadeOutAndHide(@sprites)
|
||||
end
|
||||
|
||||
def pbEndScene
|
||||
pbFadeOutAndHide(@sprites) { pbUpdate }
|
||||
pbDisposeSpriteHash(@sprites)
|
||||
@viewport.dispose
|
||||
end
|
||||
|
||||
def pbUpdate
|
||||
pbUpdateSpriteHash(@sprites)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class PokemonPhoneScreen
|
||||
def initialize(scene)
|
||||
@scene = scene
|
||||
end
|
||||
|
||||
def pbStartScreen
|
||||
if $PokemonGlobal.phone.contacts.none? { |con| con.visible? }
|
||||
pbMessage(_INTL("There are no phone numbers stored."))
|
||||
return
|
||||
end
|
||||
@scene.pbStartScene
|
||||
loop do
|
||||
contact = @scene.pbChooseContact
|
||||
break if !contact
|
||||
commands = []
|
||||
commands.push(_INTL("Call"))
|
||||
commands.push(_INTL("Delete")) if contact.can_hide?
|
||||
commands.push(_INTL("Sort Contacts"))
|
||||
commands.push(_INTL("Cancel"))
|
||||
cmd = pbShowCommands(nil, commands, -1)
|
||||
cmd += 1 if cmd >=1 && !contact.can_hide?
|
||||
case cmd
|
||||
when 0 # Call
|
||||
Phone::Call.make_outgoing(contact)
|
||||
when 1 # Delete
|
||||
name = contact.display_name
|
||||
if pbConfirmMessage(_INTL("Are you sure you want to delete {1} from your phone?", name))
|
||||
contact.visible = false
|
||||
$PokemonGlobal.phone.sort_contacts
|
||||
@scene.pbRefreshList
|
||||
pbMessage(_INTL("{1} was deleted from your phone contacts.", name))
|
||||
if $PokemonGlobal.phone.contacts.none? { |con| con.visible? }
|
||||
pbMessage(_INTL("There are no phone numbers stored."))
|
||||
break
|
||||
end
|
||||
end
|
||||
when 2 # Sort Contacts
|
||||
case pbMessage(_INTL("How do you want to sort the contacts?"),
|
||||
[_INTL("By name"),
|
||||
_INTL("By Trainer type"),
|
||||
_INTL("Special contacts first"),
|
||||
_INTL("Cancel")], -1, nil, 0)
|
||||
when 0 # By name
|
||||
$PokemonGlobal.phone.contacts.sort! { |a, b| a.name <=> b.name }
|
||||
$PokemonGlobal.phone.sort_contacts
|
||||
@scene.pbRefreshList
|
||||
when 1 # By trainer type
|
||||
$PokemonGlobal.phone.contacts.sort! { |a, b| a.display_name <=> b.display_name }
|
||||
$PokemonGlobal.phone.sort_contacts
|
||||
@scene.pbRefreshList
|
||||
when 2 # Special contacts first
|
||||
new_contacts = []
|
||||
2.times do |i|
|
||||
$PokemonGlobal.phone.contacts.each do |con|
|
||||
next if (i == 0 && con.trainer?) || (i == 1 && !con.trainer?)
|
||||
new_contacts.push(con)
|
||||
end
|
||||
end
|
||||
$PokemonGlobal.phone.contacts = new_contacts
|
||||
$PokemonGlobal.phone.sort_contacts
|
||||
@scene.pbRefreshList
|
||||
end
|
||||
end
|
||||
end
|
||||
@scene.pbEndScene
|
||||
end
|
||||
end
|
||||
|
||||
@@ -79,7 +79,6 @@ class BugContestState
|
||||
@contestMaps.push(map)
|
||||
end
|
||||
end
|
||||
echoln "contest maps: #{@contestMaps}"
|
||||
end
|
||||
|
||||
# Reception map is handled separately from contest map since the reception map
|
||||
@@ -94,7 +93,6 @@ class BugContestState
|
||||
@reception.push(map)
|
||||
end
|
||||
end
|
||||
echoln "reception maps: #{@reception}"
|
||||
end
|
||||
|
||||
def pbOffLimits?(map)
|
||||
|
||||
@@ -70,7 +70,32 @@ def toCelsius(fahrenheit)
|
||||
return ((fahrenheit - 32) * 5.0 / 9.0).round
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# This class is designed to favor different values more than a uniform
|
||||
# random generator does.
|
||||
#===============================================================================
|
||||
class AntiRandom
|
||||
def initialize(size)
|
||||
@old = []
|
||||
@new = Array.new(size) { |i| i }
|
||||
end
|
||||
|
||||
def get
|
||||
if @new.length == 0 # No new values
|
||||
@new = @old.clone
|
||||
@old.clear
|
||||
end
|
||||
if @old.length > 0 && rand(7) == 0 # Get old value
|
||||
return @old[rand(@old.length)]
|
||||
end
|
||||
if @new.length > 0 # Get new value
|
||||
ret = @new.delete_at(rand(@new.length))
|
||||
@old.push(ret)
|
||||
return ret
|
||||
end
|
||||
return @old[rand(@old.length)] # Get old value
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Constants utilities
|
||||
@@ -125,8 +150,6 @@ def getConstantNameOrValue(mod, value)
|
||||
return value.inspect
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Event utilities
|
||||
#===============================================================================
|
||||
@@ -196,8 +219,6 @@ def pbNoticePlayer(event)
|
||||
pbMoveTowardPlayer(event)
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Player-related utilities, random name generator
|
||||
#===============================================================================
|
||||
@@ -339,8 +360,6 @@ def getRandomName(maxLength = 100)
|
||||
return getRandomNameEx(2, nil, nil, maxLength)
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Regional and National Pokédexes utilities
|
||||
#===============================================================================
|
||||
@@ -387,8 +406,6 @@ def pbGetRegionalDexLength(region_dex)
|
||||
return (dex_list) ? dex_list.length : 0
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Other utilities
|
||||
#===============================================================================
|
||||
|
||||
@@ -233,7 +233,7 @@ MenuHandlers.add(:debug_menu, :test_wild_battle_advanced, {
|
||||
params.setCancelValue(0)
|
||||
level = pbMessageChooseNumber(_INTL("Set the wild {1}'s level.",
|
||||
GameData::Species.get(species).name), params)
|
||||
pkmn.push(Pokemon.new(species, level)) if level > 0
|
||||
pkmn.push(pbGenerateWildPokemon(species, level)) if level > 0
|
||||
end
|
||||
else # Edit a Pokémon
|
||||
if pbConfirmMessage(_INTL("Change this Pokémon?"))
|
||||
@@ -336,6 +336,7 @@ MenuHandlers.add(:debug_menu, :test_trainer_battle_advanced, {
|
||||
trainerdata = pbListScreen(_INTL("CHOOSE A TRAINER"), TrainerBattleLister.new(0, false))
|
||||
if trainerdata
|
||||
tr = pbLoadTrainer(trainerdata[0], trainerdata[1], trainerdata[2])
|
||||
EventHandlers.trigger(:on_trainer_load, tr)
|
||||
trainers.push([0, tr])
|
||||
end
|
||||
else # Edit a trainer
|
||||
@@ -344,6 +345,7 @@ MenuHandlers.add(:debug_menu, :test_trainer_battle_advanced, {
|
||||
TrainerBattleLister.new(trainers[trainerCmd][0], false))
|
||||
if trainerdata
|
||||
tr = pbLoadTrainer(trainerdata[0], trainerdata[1], trainerdata[2])
|
||||
EventHandlers.trigger(:on_trainer_load, tr)
|
||||
trainers[trainerCmd] = [0, tr]
|
||||
end
|
||||
elsif pbConfirmMessage(_INTL("Delete this trainer?"))
|
||||
@@ -386,6 +388,17 @@ MenuHandlers.add(:debug_menu, :reset_trainers, {
|
||||
}
|
||||
})
|
||||
|
||||
MenuHandlers.add(:debug_menu, :toggle_rematches_possible, {
|
||||
"name" => _INTL("Toggle Phone Rematches Possible"),
|
||||
"parent" => :battle_menu,
|
||||
"description" => _INTL("Toggles whether trainers in the phone can be rebattled."),
|
||||
"effect" => proc {
|
||||
Phone.rematches_enabled = !Phone.rematches_enabled
|
||||
pbMessage(_INTL("Trainers in the phone can now be rebattled.")) if Phone.rematches_enabled
|
||||
pbMessage(_INTL("Trainers in the phone cannot be rebattled.")) if !Phone.rematches_enabled
|
||||
}
|
||||
})
|
||||
|
||||
MenuHandlers.add(:debug_menu, :ready_rematches, {
|
||||
"name" => _INTL("Ready All Phone Rematches"),
|
||||
"parent" => :battle_menu,
|
||||
@@ -1115,6 +1128,8 @@ MenuHandlers.add(:debug_menu, :create_pbs_files, {
|
||||
"abilities.txt",
|
||||
"battle_facility_lists.txt",
|
||||
"berry_plants.txt",
|
||||
"dungeon_parameters.txt",
|
||||
"dungeon_tilesets.txt",
|
||||
"encounters.txt",
|
||||
"items.txt",
|
||||
"map_connections.txt",
|
||||
@@ -1140,23 +1155,25 @@ MenuHandlers.add(:debug_menu, :create_pbs_files, {
|
||||
when 1 then Compiler.write_abilities
|
||||
when 2 then Compiler.write_trainer_lists
|
||||
when 3 then Compiler.write_berry_plants
|
||||
when 4 then Compiler.write_encounters
|
||||
when 5 then Compiler.write_items
|
||||
when 6 then Compiler.write_connections
|
||||
when 7 then Compiler.write_map_metadata
|
||||
when 8 then Compiler.write_metadata
|
||||
when 9 then Compiler.write_moves
|
||||
when 10 then Compiler.write_phone
|
||||
when 11 then Compiler.write_pokemon
|
||||
when 12 then Compiler.write_pokemon_forms
|
||||
when 13 then Compiler.write_pokemon_metrics
|
||||
when 14 then Compiler.write_regional_dexes
|
||||
when 15 then Compiler.write_ribbons
|
||||
when 16 then Compiler.write_shadow_pokemon
|
||||
when 17 then Compiler.write_town_map
|
||||
when 18 then Compiler.write_trainer_types
|
||||
when 19 then Compiler.write_trainers
|
||||
when 20 then Compiler.write_types
|
||||
when 4 then Compiler.write_dungeon_parameters
|
||||
when 5 then Compiler.write_dungeon_tilesets
|
||||
when 6 then Compiler.write_encounters
|
||||
when 7 then Compiler.write_items
|
||||
when 8 then Compiler.write_connections
|
||||
when 9 then Compiler.write_map_metadata
|
||||
when 10 then Compiler.write_metadata
|
||||
when 11 then Compiler.write_moves
|
||||
when 12 then Compiler.write_phone
|
||||
when 13 then Compiler.write_pokemon
|
||||
when 14 then Compiler.write_pokemon_forms
|
||||
when 15 then Compiler.write_pokemon_metrics
|
||||
when 16 then Compiler.write_regional_dexes
|
||||
when 17 then Compiler.write_ribbons
|
||||
when 18 then Compiler.write_shadow_pokemon
|
||||
when 19 then Compiler.write_town_map
|
||||
when 20 then Compiler.write_trainer_types
|
||||
when 21 then Compiler.write_trainers
|
||||
when 22 then Compiler.write_types
|
||||
else break
|
||||
end
|
||||
pbMessage(_INTL("File written."))
|
||||
|
||||
@@ -773,6 +773,11 @@ MenuHandlers.add(:pokemon_debug_menu, :species_and_form, {
|
||||
end
|
||||
if formcmds[0].length <= 1
|
||||
screen.pbDisplay(_INTL("Species {1} only has one form.", pkmn.speciesName))
|
||||
if pkmn.form != 0 && screen.pbConfirm(_INTL("Do you want to reset the form to 0?"))
|
||||
pkmn.form = 0
|
||||
$player.pokedex.register(pkmn) if !settingUpBattle && !pkmn.egg?
|
||||
screen.pbRefreshSingle(pkmnid)
|
||||
end
|
||||
else
|
||||
cmd2 = screen.pbShowCommands(_INTL("Set the Pokémon's form."), formcmds[1], cmd2)
|
||||
next if cmd2 < 0
|
||||
|
||||
@@ -757,7 +757,6 @@ module Compiler
|
||||
modify_pbs_file_contents_before_compiling
|
||||
compile_town_map
|
||||
compile_connections
|
||||
compile_phone
|
||||
compile_types
|
||||
compile_abilities
|
||||
compile_moves # Depends on Type
|
||||
@@ -775,12 +774,18 @@ module Compiler
|
||||
compile_trainer_lists # Depends on TrainerType
|
||||
compile_metadata # Depends on TrainerType
|
||||
compile_map_metadata
|
||||
compile_dungeon_tilesets
|
||||
compile_dungeon_parameters
|
||||
compile_phone # Depends on TrainerType
|
||||
end
|
||||
|
||||
def compile_all(mustCompile)
|
||||
return if !mustCompile
|
||||
if !mustCompile
|
||||
Console.echo_h1(_INTL("Game did not compile data"))
|
||||
return
|
||||
end
|
||||
FileLineData.clear
|
||||
Console.echo_h1 _INTL("Starting full compile")
|
||||
Console.echo_h1 _INTL("Compiling all data")
|
||||
compile_pbs_files
|
||||
compile_animations
|
||||
compile_trainer_events(mustCompile)
|
||||
@@ -793,7 +798,7 @@ module Compiler
|
||||
System.reload_cache
|
||||
Console.echo_done(true)
|
||||
echoln ""
|
||||
Console.echo_h2("Successfully fully compiled", text: :green)
|
||||
Console.echo_h2("Successfully compiled all data", text: :green)
|
||||
end
|
||||
|
||||
def main
|
||||
@@ -802,6 +807,8 @@ module Compiler
|
||||
dataFiles = [
|
||||
"abilities.dat",
|
||||
"berry_plants.dat",
|
||||
"dungeon_parameters.dat",
|
||||
"dungeon_tilesets.dat",
|
||||
"encounters.dat",
|
||||
"items.dat",
|
||||
"map_connections.dat",
|
||||
@@ -825,6 +832,8 @@ module Compiler
|
||||
"abilities.txt",
|
||||
"battle_facility_lists.txt",
|
||||
"berry_plants.txt",
|
||||
"dungeon_parameters.txt",
|
||||
"dungeon_tilesets.txt",
|
||||
"encounters.txt",
|
||||
"items.txt",
|
||||
"map_connections.txt",
|
||||
|
||||
@@ -102,37 +102,69 @@ module Compiler
|
||||
def compile_phone(path = "PBS/phone.txt")
|
||||
return if !safeExists?(path)
|
||||
compile_pbs_file_message_start(path)
|
||||
database = PhoneDatabase.new
|
||||
sections = []
|
||||
File.open(path, "rb") { |f|
|
||||
pbEachSection(f) { |section, name|
|
||||
case name
|
||||
when "<Generics>"
|
||||
database.generics = section
|
||||
sections.concat(section)
|
||||
when "<BattleRequests>"
|
||||
database.battleRequests = section
|
||||
sections.concat(section)
|
||||
when "<GreetingsMorning>"
|
||||
database.greetingsMorning = section
|
||||
sections.concat(section)
|
||||
when "<GreetingsEvening>"
|
||||
database.greetingsEvening = section
|
||||
sections.concat(section)
|
||||
when "<Greetings>"
|
||||
database.greetings = section
|
||||
sections.concat(section)
|
||||
when "<Bodies1>"
|
||||
database.bodies1 = section
|
||||
sections.concat(section)
|
||||
when "<Bodies2>"
|
||||
database.bodies2 = section
|
||||
sections.concat(section)
|
||||
GameData::PhoneMessage::DATA.clear
|
||||
schema = GameData::PhoneMessage::SCHEMA
|
||||
messages = []
|
||||
contact_hash = nil
|
||||
# Read each line of phone.txt at a time and compile it as a contact property
|
||||
idx = 0
|
||||
pbCompilerEachPreppedLine(path) { |line, line_no|
|
||||
echo "." if idx % 50 == 0
|
||||
idx += 1
|
||||
Graphics.update if idx % 250 == 0
|
||||
if line[/^\s*\[\s*(.+)\s*\]\s*$/]
|
||||
# New section [trainer_type, name] or [trainer_type, name, version]
|
||||
if contact_hash
|
||||
# Add contact's data to records
|
||||
if contact_hash[:trainer_type] == "default"
|
||||
contact_hash[:id] = contact_hash[:trainer_type]
|
||||
else
|
||||
contact_hash[:id] = [contact_hash[:trainer_type], contact_hash[:name], contact_hash[:version]]
|
||||
end
|
||||
GameData::PhoneMessage.register(contact_hash)
|
||||
end
|
||||
# Construct contact hash
|
||||
header = $~[1]
|
||||
if header.strip.downcase == "default"
|
||||
contact_hash = {
|
||||
:trainer_type => "default"
|
||||
}
|
||||
else
|
||||
line_data = pbGetCsvRecord($~[1], line_no, [0, "esU", :TrainerType])
|
||||
contact_hash = {
|
||||
:trainer_type => line_data[0],
|
||||
:name => line_data[1],
|
||||
:version => line_data[2] || 0
|
||||
}
|
||||
end
|
||||
elsif line[/^\s*(\w+)\s*=\s*(.*)$/]
|
||||
# XXX=YYY lines
|
||||
if !contact_hash
|
||||
raise _INTL("Expected a section at the beginning of the file.\r\n{1}", FileLineData.linereport)
|
||||
end
|
||||
property_name = $~[1]
|
||||
line_schema = schema[property_name]
|
||||
next if !line_schema
|
||||
property_value = pbGetCsvRecord($~[2], line_no, line_schema)
|
||||
# Record XXX=YYY setting
|
||||
contact_hash[line_schema[0]] ||= []
|
||||
contact_hash[line_schema[0]].push(property_value)
|
||||
messages.push(property_value)
|
||||
end
|
||||
}
|
||||
}
|
||||
MessageTypes.setMessagesAsHash(MessageTypes::PhoneMessages, sections)
|
||||
save_data(database, "Data/phone.dat")
|
||||
# Add last contact's data to records
|
||||
if contact_hash
|
||||
# Add contact's data to records
|
||||
if contact_hash[:trainer_type] == "default"
|
||||
contact_hash[:id] = contact_hash[:trainer_type]
|
||||
else
|
||||
contact_hash[:id] = [contact_hash[:trainer_type], contact_hash[:name], contact_hash[:version]]
|
||||
end
|
||||
GameData::PhoneMessage.register(contact_hash)
|
||||
end
|
||||
# Save all data
|
||||
GameData::PhoneMessage.save
|
||||
MessageTypes.setMessagesAsHash(MessageTypes::PhoneMessages, messages)
|
||||
process_pbs_file_message_end
|
||||
end
|
||||
|
||||
@@ -1816,6 +1848,110 @@ module Compiler
|
||||
process_pbs_file_message_end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile dungeon tileset data
|
||||
#=============================================================================
|
||||
def compile_dungeon_tilesets(path = "PBS/dungeon_tilesets.txt")
|
||||
compile_pbs_file_message_start(path)
|
||||
GameData::DungeonTileset::DATA.clear
|
||||
schema = GameData::DungeonTileset::SCHEMA
|
||||
tileset_hash = nil
|
||||
# Read each line of dungeon_tilesets.txt at a time and compile it as a tileset property
|
||||
idx = 0
|
||||
pbCompilerEachPreppedLine(path) { |line, line_no|
|
||||
echo "." if idx % 50 == 0
|
||||
idx += 1
|
||||
Graphics.update if idx % 250 == 0
|
||||
if line[/^\s*\[\s*(.+)\s*\]\s*$/]
|
||||
# New section
|
||||
# Add tileset's data to records
|
||||
GameData::DungeonTileset.register(tileset_hash) if tileset_hash
|
||||
# Construct tileset hash
|
||||
tileset_hash = {
|
||||
:id => $~[1].to_i,
|
||||
:tile => [],
|
||||
:autotile => []
|
||||
}
|
||||
elsif line[/^\s*(\w+)\s*=\s*(.*)$/]
|
||||
# XXX=YYY lines
|
||||
if !tileset_hash
|
||||
raise _INTL("Expected a section at the beginning of the file.\r\n{1}", FileLineData.linereport)
|
||||
end
|
||||
property_name = $~[1]
|
||||
line_schema = schema[property_name]
|
||||
next if !line_schema
|
||||
property_value = pbGetCsvRecord($~[2], line_no, line_schema)
|
||||
# Record XXX=YYY setting
|
||||
case property_name
|
||||
when "Tile", "Autotile"
|
||||
tileset_hash[line_schema[0]].push(property_value)
|
||||
else
|
||||
tileset_hash[line_schema[0]] = property_value
|
||||
end
|
||||
end
|
||||
}
|
||||
# Add last tileset's data to records
|
||||
GameData::DungeonTileset.register(tileset_hash) if tileset_hash
|
||||
# Save all data
|
||||
GameData::DungeonTileset.save
|
||||
process_pbs_file_message_end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile dungeon parameters data
|
||||
#=============================================================================
|
||||
def compile_dungeon_parameters(path = "PBS/dungeon_parameters.txt")
|
||||
compile_pbs_file_message_start(path)
|
||||
GameData::DungeonParameters::DATA.clear
|
||||
schema = GameData::DungeonParameters::SCHEMA
|
||||
# Read from PBS file
|
||||
File.open(path, "rb") { |f|
|
||||
FileLineData.file = path # For error reporting
|
||||
# Read a whole section's lines at once, then run through this code.
|
||||
# contents is a hash containing all the XXX=YYY lines in that section, where
|
||||
# the keys are the XXX and the values are the YYY (as unprocessed strings).
|
||||
idx = 0
|
||||
pbEachFileSection(f) { |contents, section_name|
|
||||
echo "." if idx % 50 == 0
|
||||
idx += 1
|
||||
Graphics.update if idx % 250 == 0
|
||||
FileLineData.setSection(section_name, "header", nil) # For error reporting
|
||||
# Split section_name into an area and version number
|
||||
split_section_name = section_name.split(/[-,\s]/)
|
||||
if split_section_name.length == 0 || split_section_name.length > 2
|
||||
raise _INTL("Section name {1} is invalid ({2}). Expected syntax like [XXX] or [XXX,Y] (XXX=area, Y=version).", section_name, path)
|
||||
end
|
||||
area_symbol = split_section_name[0].downcase.to_sym
|
||||
version = (split_section_name[1]) ? csvPosInt!(split_section_name[1]) : 0
|
||||
# Construct parameters hash
|
||||
area_version = (version > 0) ? sprintf("%s_%d", area_symbol.to_s, version).to_sym : area_symbol
|
||||
parameters_hash = {
|
||||
:id => area_version,
|
||||
:area => area_symbol,
|
||||
:version => version
|
||||
}
|
||||
# Go through schema hash of compilable data and compile this section
|
||||
schema.each_key do |key|
|
||||
# Skip empty properties (none are required)
|
||||
if nil_or_empty?(contents[key])
|
||||
contents[key] = nil
|
||||
next
|
||||
end
|
||||
FileLineData.setSection(section_name, key, contents[key]) # For error reporting
|
||||
# Compile value for key
|
||||
value = pbGetCsvRecord(contents[key], key, schema[key])
|
||||
value = nil if value.is_a?(Array) && value.length == 0
|
||||
parameters_hash[schema[key][0]] = value
|
||||
end
|
||||
# Add parameters data to records
|
||||
GameData::DungeonParameters.register(parameters_hash)
|
||||
}
|
||||
}
|
||||
# Save all data
|
||||
GameData::DungeonParameters.save
|
||||
process_pbs_file_message_end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Compile battle animations
|
||||
#=============================================================================
|
||||
|
||||
@@ -103,32 +103,26 @@ module Compiler
|
||||
# Save phone messages to PBS file
|
||||
#=============================================================================
|
||||
def write_phone(path = "PBS/phone.txt")
|
||||
data = load_data("Data/phone.dat") rescue nil
|
||||
return if !data
|
||||
write_pbs_file_message_start(path)
|
||||
keys = GameData::PhoneMessage::SCHEMA.keys
|
||||
File.open(path, "wb") { |f|
|
||||
add_PBS_header_to_file(f)
|
||||
# Write message sets
|
||||
GameData::PhoneMessage.each do |contact|
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Generics>]\r\n")
|
||||
f.write(data.generics.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<BattleRequests>]\r\n")
|
||||
f.write(data.battleRequests.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<GreetingsMorning>]\r\n")
|
||||
f.write(data.greetingsMorning.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<GreetingsEvening>]\r\n")
|
||||
f.write(data.greetingsEvening.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Greetings>]\r\n")
|
||||
f.write(data.greetings.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Bodies1>]\r\n")
|
||||
f.write(data.bodies1.join("\r\n") + "\r\n")
|
||||
f.write("\#-------------------------------\r\n")
|
||||
f.write("[<Bodies2>]\r\n")
|
||||
f.write(data.bodies2.join("\r\n") + "\r\n")
|
||||
if contact.id == "default"
|
||||
f.write("[Default]\r\n")
|
||||
elsif contact.version > 0
|
||||
f.write(sprintf("[%s,%s,%d]\r\n", contact.trainer_type, contact.real_name, contact.version))
|
||||
else
|
||||
f.write(sprintf("[%s,%s]\r\n", contact.trainer_type, contact.real_name))
|
||||
end
|
||||
keys.each do |key|
|
||||
msgs = contact.property_from_string(key)
|
||||
next if !msgs || msgs.length == 0
|
||||
msgs.each { |msg| f.write(key + " = " + msg + "\r\n") }
|
||||
end
|
||||
end
|
||||
}
|
||||
process_pbs_file_message_end
|
||||
end
|
||||
@@ -879,6 +873,91 @@ module Compiler
|
||||
process_pbs_file_message_end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Save dungeon tileset contents data to PBS file
|
||||
#=============================================================================
|
||||
def write_dungeon_tilesets(path = "PBS/dungeon_tilesets.txt")
|
||||
write_pbs_file_message_start(path)
|
||||
tilesets = load_data("Data/Tilesets.rxdata")
|
||||
schema = GameData::DungeonTileset::SCHEMA
|
||||
keys = schema.keys
|
||||
File.open(path, "wb") { |f|
|
||||
idx = 0
|
||||
add_PBS_header_to_file(f)
|
||||
GameData::DungeonTileset.each do |tileset_data|
|
||||
echo "." if idx % 50 == 0
|
||||
idx += 1
|
||||
Graphics.update if idx % 250 == 0
|
||||
f.write("\#-------------------------------\r\n")
|
||||
tileset_name = (tilesets && tilesets[tileset_data.id]) ? tilesets[tileset_data.id].name : nil
|
||||
if tileset_name
|
||||
f.write(sprintf("[%d] # %s\r\n", tileset_data.id, tileset_name))
|
||||
else
|
||||
f.write(sprintf("[%d]\r\n", tileset_data.id))
|
||||
end
|
||||
keys.each do |key|
|
||||
if ["Autotile", "Tile"].include?(key)
|
||||
tiles = tileset_data.tile_type_ids
|
||||
tiles.each do |tile_type, tile_ids|
|
||||
tile_ids.each do |tile|
|
||||
next if tile[1] # Tile was auto-generated from "walls" property
|
||||
if tile[0] < 384
|
||||
next if key == "Tile"
|
||||
f.write(sprintf("Autotile = %i,%s", tile[0] / 48, tile_type.to_s))
|
||||
else
|
||||
next if key == "Autotile"
|
||||
f.write(sprintf("Tile = %i,%s", tile[0] - 384, tile_type.to_s))
|
||||
end
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
else
|
||||
record = tileset_data.property_from_string(key)
|
||||
next if record.nil? || (record.is_a?(Array) && record.empty?)
|
||||
next if record == false || record == 0
|
||||
f.write(sprintf("%s = ", key))
|
||||
pbWriteCsvRecord(record, f, schema[key])
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
process_pbs_file_message_end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Save dungeon parameters to PBS file
|
||||
#=============================================================================
|
||||
def write_dungeon_parameters(path = "PBS/dungeon_parameters.txt")
|
||||
write_pbs_file_message_start(path)
|
||||
schema = GameData::DungeonParameters::SCHEMA
|
||||
keys = schema.keys
|
||||
# Write file
|
||||
File.open(path, "wb") { |f|
|
||||
idx = 0
|
||||
add_PBS_header_to_file(f)
|
||||
GameData::DungeonParameters.each do |parameters_data|
|
||||
echo "." if idx % 50 == 0
|
||||
idx += 1
|
||||
Graphics.update if idx % 250 == 0
|
||||
f.write("\#-------------------------------\r\n")
|
||||
if parameters_data.version > 0
|
||||
f.write(sprintf("[%s,%d]\r\n", parameters_data.area, parameters_data.version))
|
||||
else
|
||||
f.write(sprintf("[%s]\r\n", parameters_data.area))
|
||||
end
|
||||
keys.each do |key|
|
||||
value = parameters_data.property_from_string(key)
|
||||
next if !value || (value.is_a?(Array) && value.length == 0)
|
||||
f.write(sprintf("%s = ", key))
|
||||
pbWriteCsvRecord(value, f, schema[key])
|
||||
f.write("\r\n")
|
||||
end
|
||||
end
|
||||
}
|
||||
process_pbs_file_message_end
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Save all data to PBS files
|
||||
#=============================================================================
|
||||
@@ -886,7 +965,6 @@ module Compiler
|
||||
Console.echo_h1 _INTL("Writing all PBS files")
|
||||
write_town_map
|
||||
write_connections
|
||||
write_phone
|
||||
write_types
|
||||
write_abilities
|
||||
write_moves
|
||||
@@ -904,6 +982,9 @@ module Compiler
|
||||
write_trainer_lists
|
||||
write_metadata
|
||||
write_map_metadata
|
||||
write_dungeon_tilesets
|
||||
write_dungeon_parameters
|
||||
write_phone
|
||||
echoln ""
|
||||
Console.echo_h2("Successfully rewrote all PBS files", text: :green)
|
||||
end
|
||||
|
||||
@@ -506,7 +506,7 @@ module Compiler
|
||||
end
|
||||
end
|
||||
# Compile the trainer comments
|
||||
rewriteComments = true #false # You can change this
|
||||
rewriteComments = false # You can change this
|
||||
battles = []
|
||||
trtype = nil
|
||||
trname = nil
|
||||
@@ -519,6 +519,7 @@ module Compiler
|
||||
endifswitch = []
|
||||
vanishifswitch = []
|
||||
regspeech = nil
|
||||
common_event = 0
|
||||
commands.each do |command|
|
||||
if command[/^Battle\:\s*([\s\S]+)$/i]
|
||||
battles.push($~[1])
|
||||
@@ -558,6 +559,9 @@ module Compiler
|
||||
elsif command[/^RegSpeech\:\s*([\s\S]+)$/i]
|
||||
regspeech = $~[1].gsub(/^\s+/, "").gsub(/\s+$/, "")
|
||||
push_comment(firstpage.list, command) if rewriteComments
|
||||
elsif command[/^CommonEvent\:\s*(\d+)$/i]
|
||||
common_event = $~[1].to_i
|
||||
push_comment(firstpage.list, command) if rewriteComments
|
||||
end
|
||||
end
|
||||
return nil if battles.length <= 0
|
||||
@@ -600,11 +604,19 @@ module Compiler
|
||||
push_text(firstpage.list, regspeech, 2)
|
||||
push_choices(firstpage.list, ["Yes", "No"], 2, 2)
|
||||
push_choice(firstpage.list, 0, "Yes", 3)
|
||||
if common_event > 0
|
||||
if battleid > 0
|
||||
push_script(firstpage.list, sprintf("Phone.add(get_self,\n %s, %d, %d, %d\n)", brieftrcombo, battles.length, battleid, common_event), 3)
|
||||
else
|
||||
push_script(firstpage.list, sprintf("Phone.add(get_self,\n %s, %d, nil, %d\n)", brieftrcombo, battles.length, common_event), 3)
|
||||
end
|
||||
else
|
||||
if battleid > 0
|
||||
push_script(firstpage.list, sprintf("Phone.add(get_self,\n %s, %d, %d\n)", brieftrcombo, battles.length, battleid), 3)
|
||||
else
|
||||
push_script(firstpage.list, sprintf("Phone.add(get_self,\n %s, %d\n)", brieftrcombo, battles.length), 3)
|
||||
end
|
||||
end
|
||||
push_choice(firstpage.list, 1, "No", 3)
|
||||
push_choices_end(firstpage.list, 3)
|
||||
push_branch_end(firstpage.list, 2)
|
||||
@@ -679,11 +691,19 @@ module Compiler
|
||||
push_text(lastpage.list, regspeech, 1)
|
||||
push_choices(lastpage.list, ["Yes", "No"], 2, 1)
|
||||
push_choice(lastpage.list, 0, "Yes", 2)
|
||||
if common_event > 0
|
||||
if battleid > 0
|
||||
push_script(lastpage.list, sprintf("Phone.add(get_self,\n %s, %d, %d, %d\n)", brieftrcombo, battles.length, battleid, common_event), 2)
|
||||
else
|
||||
push_script(lastpage.list, sprintf("Phone.add(get_self,\n %s, %d, nil, %d\n)", brieftrcombo, battles.length, common_event), 2)
|
||||
end
|
||||
else
|
||||
if battleid > 0
|
||||
push_script(lastpage.list, sprintf("Phone.add(get_self,\n %s, %d, %d\n)", brieftrcombo, battles.length, battleid), 2)
|
||||
else
|
||||
push_script(lastpage.list, sprintf("Phone.add(get_self,\n %s, %d\n)", brieftrcombo, battles.length), 2)
|
||||
end
|
||||
end
|
||||
push_choice(lastpage.list, 1, "No", 2)
|
||||
push_choices_end(lastpage.list, 2)
|
||||
push_branch_end(lastpage.list, 1)
|
||||
|
||||
30
PBS/dungeon_parameters.txt
Normal file
30
PBS/dungeon_parameters.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
# See the documentation on the wiki to learn how to edit this file.
|
||||
#-------------------------------
|
||||
[cave]
|
||||
DungeonSize = 5,4
|
||||
CellSize = 10,10
|
||||
MinRoomSize = 5,5
|
||||
MaxRoomSize = 9,9
|
||||
CorridorWidth = 2
|
||||
ShiftCorridors = true
|
||||
NodeLayout = full
|
||||
RoomLayout = full
|
||||
RoomChance = 70
|
||||
ExtraConnections = 2
|
||||
FloorPatches = 2,50,25
|
||||
FloorDecorations = 50,200
|
||||
VoidDecorations = 50,200
|
||||
#-------------------------------
|
||||
[forest]
|
||||
DungeonSize = 5,4
|
||||
CellSize = 10,10
|
||||
MinRoomSize = 4,4
|
||||
MaxRoomSize = 8,8
|
||||
CorridorWidth = 2
|
||||
NodeLayout = full
|
||||
RoomLayout = full
|
||||
RoomChance = 70
|
||||
ExtraConnections = 2
|
||||
FloorPatches = 3,75,25
|
||||
FloorDecorations = 50,200
|
||||
VoidDecorations = 50,200
|
||||
28
PBS/dungeon_tilesets.txt
Normal file
28
PBS/dungeon_tilesets.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
# See the documentation on the wiki to learn how to edit this file.
|
||||
#-------------------------------
|
||||
[7] # Dungeon cave
|
||||
Autotile = 1,floor_patch
|
||||
Tile = 40,void
|
||||
Tile = 41,void_decoration
|
||||
Tile = 48,void_decoration_large
|
||||
Tile = 42,floor
|
||||
Tile = 50,floor_decoration_large
|
||||
Tile = 0,walls
|
||||
DoubleWalls = true
|
||||
FloorPatchUnderWalls = true
|
||||
#-------------------------------
|
||||
[23] # Dungeon forest
|
||||
Autotile = 1,floor_decoration
|
||||
Tile = 40,void
|
||||
Tile = 42,floor
|
||||
Tile = 43,floor
|
||||
Tile = 44,floor
|
||||
Tile = 45,floor
|
||||
Tile = 46,floor
|
||||
Tile = 47,floor_patch
|
||||
Tile = 8,walls
|
||||
Tile = 25,wall_top
|
||||
SnapToLargeGrid = true
|
||||
LargeVoidTiles = true
|
||||
LargeWallTiles = true
|
||||
ThinNorthWallOffset = -8
|
||||
@@ -1,34 +1,48 @@
|
||||
# See the documentation on the wiki to learn how to edit this file.
|
||||
#-------------------------------
|
||||
[<Generics>]
|
||||
How are your Pokémon doing?\mMy \TP's really energetic. It's a handful!\mOh yeah, I managed to beat a tough \TE.\mI need to make my party stronger.
|
||||
My \TP's looking really awesome.\mI wish I could show you.\mHey, listen! I almost caught a \TE the other day.\mOh, it was sooooooo close, too!
|
||||
[Default]
|
||||
Intro = Hello. This is \TN.
|
||||
Intro = Good day, \PN! Hi. This is \TN.
|
||||
Intro = How are you doing? \PN, howdy! This is \TN. Isn't it nice out?
|
||||
Intro = \PN, good day! It's me, \TN. Got a minute?
|
||||
Intro = Hello, \PN. This is \TN. How are things?
|
||||
IntroMorning = Good morning, \PN. This is \TN. Did I wake you?
|
||||
IntroAfternoon = Good afternoon, \PN! It's \TN here.
|
||||
IntroEvening = \PN, good evening! Hi. This is \TN.
|
||||
Body = How are your Pokémon doing?\mMy \TP's really energetic. It's a handful!\mOh yeah, I managed to beat a tough \TE.\mI need to make my party stronger.
|
||||
Body = My \TP's looking really awesome. I wish I could show you.\mHey, listen! I almost caught a \TE the other day.\mOh, it was sooooooo close, too!
|
||||
Body1 = How are your Pokémon doing?\mMy \TP's really energetic. It's a handful!
|
||||
Body1 = How are your Pokémon doing?\mI always keep my \TP in top shape by going to Pokémon Centers.
|
||||
Body1 = My \TP's looking really awesome. I wish I could show you.
|
||||
Body1 = I dressed my \TP and it looks even cuter than before.
|
||||
Body2 = Oh yeah, I managed to beat a tough \TE.\mI need to make my party stronger.
|
||||
Body2 = You have to hear this! I battled \TE the other day.\mIt was easy! I had a type advantage.
|
||||
Body2 = Hey, listen! I almost caught \TE the other day.\mOh, it was sooooooo close, too!
|
||||
Body2 = Guess what happened the other day. I missed catching \TE again.\mMaybe I'm not very good at this.
|
||||
BattleRequest = Want to battle? It's not going to be a repeat of the last time we met.\mI'll be waiting for you around \TM.
|
||||
BattleRequest = Do you want to battle? I'm going to win this time!\mI'll be waiting for you around \TM.\mLook for me, OK? My \TP will be expecting you.
|
||||
#-------------------------------
|
||||
[<BattleRequests>]
|
||||
Want to battle? It's not going to be a repeat of the last time we met.\mI'll be waiting for you around \TM.
|
||||
Do you want to battle? I'm going to win this time!\mI'll be waiting for you around \TM.\mLook for me, OK? My \TP will be expecting you.
|
||||
[CAMPER,Jeff]
|
||||
Intro = Hello. This is \TN...\mHow's it going, \PN?
|
||||
Body1 = My \TP is looking more and more like me. It's getting cuter!
|
||||
Body2 = And you know? Now we can KO \TE easily.\mI should challenge the Cedolan Gym.
|
||||
Body2 = And you know? We just failed to beat \TE by a tiny margin.\mI'm guessing my Pokémon's levels aren't high enough yet...
|
||||
BattleRequest = You must be a lot better now, huh?\mHow about showing me your technique in a real battle with me?\mI'll be waiting on \TM.
|
||||
BattleReminder = Where are you? Let's have our battle soon!\mI'll be waiting on \TM.
|
||||
End = See you later!
|
||||
#-------------------------------
|
||||
[<GreetingsMorning>]
|
||||
Good morning, \PN.\mThis is \TN. Did I wake you?
|
||||
#-------------------------------
|
||||
[<GreetingsEvening>]
|
||||
\PN, good evening! Hi.\mThis is \TN.
|
||||
#-------------------------------
|
||||
[<Greetings>]
|
||||
Hello. This is \TN.
|
||||
Good day, \PN! Hi. This is \TN.
|
||||
How are you doing? \PN, howdy! This is \TN. Isn't it nice out?
|
||||
\PN, good day! It's me, \TN. Got a minute?
|
||||
Hello, \PN. This is \TN. How are things?
|
||||
#-------------------------------
|
||||
[<Bodies1>]
|
||||
How are your Pokémon doing?\mMy \TP's really energetic. It's a handful!
|
||||
How are your Pokémon doing?\mI always keep my \TP in top shape by going to Pokémon Centers.
|
||||
My \TP's looking really awesome. I wish I could show you.
|
||||
I dressed my \TP and it looks even cuter than before.
|
||||
#-------------------------------
|
||||
[<Bodies2>]
|
||||
Oh yeah, I managed to beat a tough \TE.\mI need to make my party stronger.
|
||||
You have to hear this! I battled \TE the other day.\mIt was easy! I had a type advantage.
|
||||
Hey, listen! I almost caught \TE the other day.\mOh, it was sooooooo close, too!
|
||||
Guess what happened the other day. I missed catching \TE again.\mMaybe I'm not very good at this.
|
||||
[PICNICKER,Susie]
|
||||
Intro = This is \TN!
|
||||
Intro = Hi, this is \TN!
|
||||
IntroMorning = This is \TN! Good morning, \PN!
|
||||
IntroMorning = Hi, this is \TN! Good morning, \PN!
|
||||
IntroAfternoon = This is \TN! Good afternoon, \PN!
|
||||
IntroAfternoon = Hi, this is \TN! Good afternoon, \PN!
|
||||
IntroEvening = This is \TN! Good evening, \PN!
|
||||
IntroEvening = Hi, this is \TN! Good evening, \PN!
|
||||
Body1 = My \TP and I are getting more in sync with each other.
|
||||
Body2 = We battled a wild \TE and managed to beat it in a close match.\mWe're getting into the groove!
|
||||
Body2 = But, you know what? I still haven't caught \TE.\mIt's getting beyond frustrating...
|
||||
BattleRequest = Would you be my practice partner again sometime?\mI'll be waiting on \TM...\mCould you take it a little easier on me next time?
|
||||
BattleReminder = How soon can I expect to see you?\mDon't forget, \TM!
|
||||
End = Bye! Let's chat again!
|
||||
|
||||
Reference in New Issue
Block a user