mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-07 21:24:59 +00:00
6.6 update
This commit is contained in:
320
Data/Scripts/020_Debug/001_Editor screens/001_EditorScreens.rb
Normal file
320
Data/Scripts/020_Debug/001_Editor screens/001_EditorScreens.rb
Normal file
@@ -0,0 +1,320 @@
|
||||
|
||||
|
||||
#===
|
||||
|
||||
#===============================================================================
|
||||
# Metadata editor
|
||||
#===============================================================================
|
||||
def pbMetadataScreen(map_id = 0)
|
||||
loop do
|
||||
map_id = pbListScreen(_INTL("SET METADATA"), MapLister.new(map_id, true))
|
||||
break if map_id < 0
|
||||
pbEditMetadata(map_id)
|
||||
end
|
||||
end
|
||||
|
||||
def pbEditMetadata(map_id = 0)
|
||||
mapinfos = pbLoadMapInfos
|
||||
data = []
|
||||
if map_id == 0 # Global metadata
|
||||
map_name = _INTL("Global Metadata")
|
||||
metadata = GameData::Metadata.get
|
||||
properties = GameData::Metadata.editor_properties
|
||||
else # Map metadata
|
||||
map_name = mapinfos[map_id].name
|
||||
metadata = GameData::MapMetadata.try_get(map_id)
|
||||
metadata = GameData::Metadata.new({}) if !metadata
|
||||
properties = GameData::MapMetadata.editor_properties
|
||||
end
|
||||
properties.each do |property|
|
||||
data.push(metadata.property_from_string(property[0]))
|
||||
end
|
||||
if pbPropertyList(map_name, data, properties, true)
|
||||
if map_id == 0 # Global metadata
|
||||
# Construct metadata hash
|
||||
metadata_hash = {
|
||||
:id => map_id,
|
||||
:home => data[0],
|
||||
:wild_battle_BGM => data[1],
|
||||
:trainer_battle_BGM => data[2],
|
||||
:wild_victory_ME => data[3],
|
||||
:trainer_victory_ME => data[4],
|
||||
:wild_capture_ME => data[5],
|
||||
:surf_BGM => data[6],
|
||||
:bicycle_BGM => data[7],
|
||||
:player_A => data[8],
|
||||
:player_B => data[9],
|
||||
:player_C => data[10],
|
||||
:player_D => data[11],
|
||||
:player_E => data[12],
|
||||
:player_F => data[13],
|
||||
:player_G => data[14],
|
||||
:player_H => data[15]
|
||||
}
|
||||
# Add metadata's data to records
|
||||
GameData::Metadata.register(metadata_hash)
|
||||
GameData::Metadata.save
|
||||
else # Map metadata
|
||||
# Construct metadata hash
|
||||
metadata_hash = {
|
||||
:id => map_id,
|
||||
:outdoor_map => data[0],
|
||||
:announce_location => data[1],
|
||||
:can_bicycle => data[2],
|
||||
:always_bicycle => data[3],
|
||||
:teleport_destination => data[4],
|
||||
:weather => data[5],
|
||||
:town_map_position => data[6],
|
||||
:dive_map_id => data[7],
|
||||
:dark_map => data[8],
|
||||
:safari_map => data[9],
|
||||
:snap_edges => data[10],
|
||||
:random_dungeon => data[11],
|
||||
:battle_background => data[12],
|
||||
:wild_battle_BGM => data[13],
|
||||
:trainer_battle_BGM => data[14],
|
||||
:wild_victory_ME => data[15],
|
||||
:trainer_victory_ME => data[16],
|
||||
:wild_capture_ME => data[17],
|
||||
:town_map_size => data[18],
|
||||
:battle_environment => data[19]
|
||||
}
|
||||
# Add metadata's data to records
|
||||
GameData::MapMetadata.register(metadata_hash)
|
||||
GameData::MapMetadata.save
|
||||
end
|
||||
Compiler.write_metadata
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Regional Dexes editor
|
||||
#===============================================================================
|
||||
def pbRegionalDexEditor(dex)
|
||||
viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
viewport.z = 99999
|
||||
cmd_window = pbListWindow([])
|
||||
info = Window_AdvancedTextPokemon.newWithSize(
|
||||
_INTL("Z+Up/Down: Rearrange entries\nZ+Right: Insert new entry\nZ+Left: Delete entry\nD: Clear entry"),
|
||||
Graphics.width / 2, 64, Graphics.width / 2, Graphics.height - 64, viewport)
|
||||
info.z = 2
|
||||
dex.compact!
|
||||
ret = dex.clone
|
||||
commands = []
|
||||
refresh_list = true
|
||||
cmd = [0, 0] # [action, index in list]
|
||||
loop do
|
||||
# Populate commands
|
||||
if refresh_list
|
||||
loop do
|
||||
break if dex.length == 0 || dex[-1]
|
||||
dex.slice!(-1)
|
||||
end
|
||||
commands = []
|
||||
dex.each_with_index do |species, i|
|
||||
text = (species) ? GameData::Species.get(species).real_name : "----------"
|
||||
commands.push(sprintf("%03d: %s", i + 1, text))
|
||||
end
|
||||
commands.push(sprintf("%03d: ----------", commands.length + 1))
|
||||
cmd[1] = [cmd[1], commands.length - 1].min
|
||||
refresh_list = false
|
||||
end
|
||||
# Choose to do something
|
||||
cmd = pbCommands3(cmd_window, commands, -1, cmd[1], true)
|
||||
case cmd[0]
|
||||
when 1 # Swap entry up
|
||||
if cmd[1] < dex.length - 1
|
||||
dex[cmd[1] + 1], dex[cmd[1]] = dex[cmd[1]], dex[cmd[1] + 1]
|
||||
refresh_list = true
|
||||
end
|
||||
when 2 # Swap entry down
|
||||
if cmd[1] > 0
|
||||
dex[cmd[1] - 1], dex[cmd[1]] = dex[cmd[1]], dex[cmd[1] - 1]
|
||||
refresh_list = true
|
||||
end
|
||||
when 3 # Delete spot
|
||||
if cmd[1] < dex.length
|
||||
dex.delete_at(cmd[1])
|
||||
refresh_list = true
|
||||
end
|
||||
when 4 # Insert spot
|
||||
if cmd[1] < dex.length
|
||||
dex.insert(cmd[1], nil)
|
||||
refresh_list = true
|
||||
end
|
||||
when 5 # Clear spot
|
||||
if dex[cmd[1]]
|
||||
dex[cmd[1]] = nil
|
||||
refresh_list = true
|
||||
end
|
||||
when 0
|
||||
if cmd[1] >= 0 # Edit entry
|
||||
case pbMessage(_INTL("\\ts[]Do what with this entry?"),
|
||||
[_INTL("Change species"), _INTL("Clear"), _INTL("Insert entry"), _INTL("Delete entry"), _INTL("Cancel")], 5)
|
||||
when 0 # Change species
|
||||
species = pbChooseSpeciesList(dex[cmd[1]])
|
||||
if species
|
||||
dex[cmd[1]] = species
|
||||
dex.each_with_index { |s, i| dex[i] = nil if i != cmd[1] && s == species }
|
||||
refresh_list = true
|
||||
end
|
||||
when 1 # Clear spot
|
||||
if dex[cmd[1]]
|
||||
dex[cmd[1]] = nil
|
||||
refresh_list = true
|
||||
end
|
||||
when 2 # Insert spot
|
||||
if cmd[1] < dex.length
|
||||
dex.insert(cmd[1], nil)
|
||||
refresh_list = true
|
||||
end
|
||||
when 3 # Delete spot
|
||||
if cmd[1] < dex.length
|
||||
dex.delete_at(cmd[1])
|
||||
refresh_list = true
|
||||
end
|
||||
end
|
||||
else # Cancel
|
||||
case pbMessage(_INTL("Save changes?"),
|
||||
[_INTL("Yes"),_INTL("No"),_INTL("Cancel")],3)
|
||||
when 0 # Save all changes to Dex
|
||||
dex.slice!(-1) while !dex[-1]
|
||||
ret = dex
|
||||
break
|
||||
when 1 # Just quit
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
info.dispose
|
||||
cmd_window.dispose
|
||||
viewport.dispose
|
||||
ret.compact!
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbAppendEvoToFamilyArray(species, array, seenarray)
|
||||
return if seenarray[species]
|
||||
array.push(species)
|
||||
seenarray[species] = true
|
||||
evos = GameData::Species.get(species).get_evolutions
|
||||
if evos.length > 0
|
||||
evos.sort! { |a, b| GameData::Species.get(a[0]).id_number <=> GameData::Species.get(b[0]).id_number }
|
||||
subarray = []
|
||||
for i in evos
|
||||
pbAppendEvoToFamilyArray(i[0], subarray, seenarray)
|
||||
end
|
||||
array.push(subarray) if subarray.length > 0
|
||||
end
|
||||
end
|
||||
|
||||
def pbGetEvoFamilies
|
||||
seen = []
|
||||
ret = []
|
||||
GameData::Species.each do |sp|
|
||||
next if sp.form > 0
|
||||
species = sp.get_baby_species
|
||||
next if seen[species]
|
||||
subret = []
|
||||
pbAppendEvoToFamilyArray(species, subret, seen)
|
||||
ret.push(subret.flatten) if subret.length > 0
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbEvoFamiliesToStrings
|
||||
ret = []
|
||||
families = pbGetEvoFamilies
|
||||
for fam in 0...families.length
|
||||
string = ""
|
||||
for p in 0...families[fam].length
|
||||
if p>=3
|
||||
string += " + #{families[fam].length - 3} more"
|
||||
break
|
||||
end
|
||||
string += "/" if p > 0
|
||||
string += GameData::Species.get(families[fam][p]).name
|
||||
end
|
||||
ret[fam] = string
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Battle animations rearranger
|
||||
#===============================================================================
|
||||
def pbAnimationsOrganiser
|
||||
list = pbLoadBattleAnimations
|
||||
if !list || !list[0]
|
||||
pbMessage(_INTL("No animations exist."))
|
||||
return
|
||||
end
|
||||
viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
|
||||
viewport.z = 99999
|
||||
cmdwin = pbListWindow([])
|
||||
cmdwin.viewport = viewport
|
||||
cmdwin.z = 2
|
||||
title = Window_UnformattedTextPokemon.newWithSize(_INTL("Animations Organiser"),
|
||||
Graphics.width / 2, 0, Graphics.width / 2, 64, viewport)
|
||||
title.z = 2
|
||||
info = Window_AdvancedTextPokemon.newWithSize(_INTL("Z+Up/Down: Swap\nZ+Left: Delete\nZ+Right: Insert"),
|
||||
Graphics.width / 2, 64, Graphics.width / 2, Graphics.height - 64, viewport)
|
||||
info.z = 2
|
||||
commands = []
|
||||
refreshlist = true; oldsel = -1
|
||||
cmd = [0,0]
|
||||
loop do
|
||||
if refreshlist
|
||||
commands = []
|
||||
for i in 0...list.length
|
||||
commands.push(sprintf("%d: %s",i,(list[i]) ? list[i].name : "???"))
|
||||
end
|
||||
end
|
||||
refreshlist = false; oldsel = -1
|
||||
cmd = pbCommands3(cmdwin,commands,-1,cmd[1],true)
|
||||
if cmd[0]==1 # Swap animation up
|
||||
if cmd[1]>=0 && cmd[1]<commands.length-1
|
||||
list[cmd[1]+1],list[cmd[1]] = list[cmd[1]],list[cmd[1]+1]
|
||||
refreshlist = true
|
||||
end
|
||||
elsif cmd[0]==2 # Swap animation down
|
||||
if cmd[1]>0
|
||||
list[cmd[1]-1],list[cmd[1]] = list[cmd[1]],list[cmd[1]-1]
|
||||
refreshlist = true
|
||||
end
|
||||
elsif cmd[0]==3 # Delete spot
|
||||
list.delete_at(cmd[1])
|
||||
cmd[1] = [cmd[1],list.length-1].min
|
||||
refreshlist = true
|
||||
pbWait(Graphics.frame_rate*2/10)
|
||||
elsif cmd[0]==4 # Insert spot
|
||||
list.insert(cmd[1],PBAnimation.new)
|
||||
refreshlist = true
|
||||
pbWait(Graphics.frame_rate*2/10)
|
||||
elsif cmd[0]==0
|
||||
cmd2 = pbMessage(_INTL("Save changes?"),
|
||||
[_INTL("Yes"),_INTL("No"),_INTL("Cancel")],3)
|
||||
if cmd2==0 || cmd2==1
|
||||
if cmd2==0
|
||||
# Save animations here
|
||||
save_data(list,"Data/PkmnAnimations.rxdata")
|
||||
$PokemonTemp.battleAnims = nil
|
||||
pbMessage(_INTL("Data saved."))
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
title.dispose
|
||||
info.dispose
|
||||
cmdwin.dispose
|
||||
viewport.dispose
|
||||
end
|
||||
@@ -0,0 +1,234 @@
|
||||
#===============================================================================
|
||||
# Edits the terrain tags of tiles in tilesets.
|
||||
#===============================================================================
|
||||
class PokemonTilesetScene
|
||||
TILE_SIZE = 32 # in pixels
|
||||
TILES_PER_ROW = 8
|
||||
TILESET_WIDTH = TILES_PER_ROW * TILE_SIZE
|
||||
TILES_PER_AUTOTILE = 48
|
||||
TILESET_START_ID = TILES_PER_ROW * TILES_PER_AUTOTILE
|
||||
CURSOR_COLOR = Color.new(255, 0, 0)
|
||||
TEXT_COLOR = Color.new(80, 80, 80)
|
||||
TEXT_SHADOW_COLOR = Color.new(192, 192, 192)
|
||||
|
||||
def initialize
|
||||
@tilesets_data = load_data("Data/Tilesets.rxdata")
|
||||
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
@viewport.z = 99999
|
||||
@sprites = {}
|
||||
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(
|
||||
_INTL("Tileset Editor\r\nA/S: SCROLL\r\nZ: MENU"),
|
||||
TILESET_WIDTH, 0, Graphics.width - TILESET_WIDTH, 128, @viewport)
|
||||
@sprites["tileset"] = BitmapSprite.new(TILESET_WIDTH, Graphics.height, @viewport)
|
||||
@sprites["overlay"] = BitmapSprite.new(Graphics.width, Graphics.height, @viewport)
|
||||
pbSetSystemFont(@sprites["overlay"].bitmap)
|
||||
@visible_height = @sprites["tileset"].bitmap.height / TILE_SIZE
|
||||
load_tileset(1)
|
||||
end
|
||||
|
||||
def open_screen
|
||||
pbFadeInAndShow(@sprites)
|
||||
end
|
||||
|
||||
def close_screen
|
||||
pbFadeOutAndHide(@sprites)
|
||||
pbDisposeSpriteHash(@sprites)
|
||||
@viewport.dispose
|
||||
@tilehelper.dispose
|
||||
if $game_map && $map_factory
|
||||
$map_factory.setup($game_map.map_id)
|
||||
$game_player.center($game_player.x, $game_player.y)
|
||||
if $scene.is_a?(Scene_Map)
|
||||
$scene.dispose
|
||||
$scene.createSpritesets
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def load_tileset(id)
|
||||
@tileset = @tilesets_data[id]
|
||||
@tilehelper.dispose if @tilehelper
|
||||
@tilehelper = TileDrawingHelper.fromTileset(@tileset)
|
||||
@x = 0
|
||||
@y = 0
|
||||
@top_y = 0
|
||||
@height = (@tileset.terrain_tags.xsize - TILESET_START_ID) / TILES_PER_ROW + 1
|
||||
draw_tiles
|
||||
draw_overlay
|
||||
end
|
||||
|
||||
def choose_tileset
|
||||
commands = []
|
||||
for i in 1...@tilesets_data.length
|
||||
commands.push(sprintf("%03d %s", i, @tilesets_data[i].name))
|
||||
end
|
||||
ret = pbShowCommands(nil, commands, -1)
|
||||
load_tileset(ret + 1) if ret >= 0
|
||||
end
|
||||
|
||||
def draw_tiles
|
||||
@sprites["tileset"].bitmap.clear
|
||||
for yy in 0...@visible_height
|
||||
autotile_row = (@top_y == 0 && yy == 0) # Autotiles
|
||||
id_y_offset = (autotile_row) ? 0 : TILESET_START_ID + (@top_y + yy - 1) * TILES_PER_ROW
|
||||
for xx in 0...TILES_PER_ROW
|
||||
id_x_offset = (autotile_row) ? xx * TILES_PER_AUTOTILE : xx
|
||||
@tilehelper.bltTile(@sprites["tileset"].bitmap, xx * TILE_SIZE, yy * TILE_SIZE,
|
||||
id_y_offset + id_x_offset)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def draw_overlay
|
||||
@sprites["overlay"].bitmap.clear
|
||||
# Draw all text over tiles (terrain tag numbers)
|
||||
textpos = []
|
||||
for yy in 0...@visible_height
|
||||
for xx in 0...TILES_PER_ROW
|
||||
tile_id = tile_ID_from_coordinates(xx, @top_y + yy)
|
||||
terr = @tileset.terrain_tags[tile_id]
|
||||
textpos.push(["#{terr}", xx * TILE_SIZE + TILE_SIZE / 2, yy * TILE_SIZE - 6, 2, TEXT_COLOR, TEXT_SHADOW_COLOR])
|
||||
end
|
||||
end
|
||||
pbDrawTextPositions(@sprites["overlay"].bitmap, textpos)
|
||||
# Draw cursor
|
||||
cursor_x = @x * TILE_SIZE
|
||||
cursor_y = (@y - @top_y) * TILE_SIZE
|
||||
@sprites["overlay"].bitmap.fill_rect(cursor_x, cursor_y, TILE_SIZE, 4, CURSOR_COLOR)
|
||||
@sprites["overlay"].bitmap.fill_rect(cursor_x, cursor_y, 4, TILE_SIZE, CURSOR_COLOR)
|
||||
@sprites["overlay"].bitmap.fill_rect(cursor_x, cursor_y + TILE_SIZE - 4, TILE_SIZE, 4, CURSOR_COLOR)
|
||||
@sprites["overlay"].bitmap.fill_rect(cursor_x + TILE_SIZE - 4, cursor_y, 4, TILE_SIZE, CURSOR_COLOR)
|
||||
# Draw information about selected tile on right side
|
||||
draw_tile_details
|
||||
end
|
||||
|
||||
def draw_tile_details
|
||||
overlay = @sprites["overlay"].bitmap
|
||||
tile_x = Graphics.width * 3 / 4 - TILE_SIZE
|
||||
tile_y = Graphics.height / 2 - TILE_SIZE
|
||||
tile_id = tile_ID_from_coordinates(@x, @y) || 0
|
||||
# Draw tile (at 200% size)
|
||||
@tilehelper.bltSmallTile(overlay, tile_x, tile_y, TILE_SIZE * 2, TILE_SIZE * 2, tile_id)
|
||||
# Draw box around tile image
|
||||
overlay.fill_rect(tile_x - 1, tile_y - 1, TILE_SIZE * 2 + 2, 1, Color.new(255, 255, 255))
|
||||
overlay.fill_rect(tile_x - 1, tile_y - 1, 1, TILE_SIZE * 2 + 2, Color.new(255, 255, 255))
|
||||
overlay.fill_rect(tile_x - 1, tile_y + TILE_SIZE * 2, TILE_SIZE * 2 + 2, 1, Color.new(255, 255, 255))
|
||||
overlay.fill_rect(tile_x + TILE_SIZE * 2, tile_y - 1, 1, TILE_SIZE * 2 + 2, Color.new(255, 255, 255))
|
||||
# Write terrain tag info about selected tile
|
||||
terrain_tag = @tileset.terrain_tags[tile_id] || 0
|
||||
if GameData::TerrainTag.exists?(terrain_tag)
|
||||
terrain_tag_name = sprintf("%d: %s", terrain_tag, GameData::TerrainTag.get(terrain_tag).real_name)
|
||||
else
|
||||
terrain_tag_name = terrain_tag.to_s
|
||||
end
|
||||
textpos = [
|
||||
[_INTL("Terrain Tag:"), tile_x + TILE_SIZE, tile_y + TILE_SIZE * 2 + 10, 2, Color.new(248, 248, 248), Color.new(40, 40, 40)],
|
||||
[terrain_tag_name, tile_x + TILE_SIZE, tile_y + TILE_SIZE * 2 + 42, 2, Color.new(248, 248, 248), Color.new(40, 40, 40)]
|
||||
]
|
||||
# Draw all text
|
||||
pbDrawTextPositions(overlay, textpos)
|
||||
end
|
||||
|
||||
def tile_ID_from_coordinates(x, y)
|
||||
return x * TILES_PER_AUTOTILE if y == 0 # Autotile
|
||||
return TILESET_START_ID + (y - 1) * TILES_PER_ROW + x
|
||||
end
|
||||
|
||||
def set_terrain_tag_for_tile_ID(i, value)
|
||||
if i < TILESET_START_ID
|
||||
for j in 0...TILES_PER_AUTOTILE
|
||||
@tileset.terrain_tags[i + j] = value
|
||||
end
|
||||
else
|
||||
@tileset.terrain_tags[i] = value
|
||||
end
|
||||
end
|
||||
|
||||
def update_cursor_position(x_offset, y_offset)
|
||||
old_x = @x
|
||||
old_y = @y
|
||||
old_top_y = @top_y
|
||||
if x_offset != 0
|
||||
@x += x_offset
|
||||
@x = @x.clamp(0, TILES_PER_ROW - 1)
|
||||
end
|
||||
if y_offset != 0
|
||||
@y += y_offset
|
||||
@y = @y.clamp(0, @height - 1)
|
||||
@top_y = @y if @y < @top_y
|
||||
@top_y = @y - @visible_height + 1 if @y >= @top_y + @visible_height
|
||||
@top_y = 0 if @top_y < 0
|
||||
end
|
||||
draw_tiles if @top_y != old_top_y
|
||||
draw_overlay if @x != old_x || @y != old_y
|
||||
end
|
||||
|
||||
def pbStartScene
|
||||
open_screen
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.repeat?(Input::UP)
|
||||
update_cursor_position(0, -1)
|
||||
elsif Input.repeat?(Input::DOWN)
|
||||
update_cursor_position(0, 1)
|
||||
elsif Input.repeat?(Input::LEFT)
|
||||
update_cursor_position(-1, 0)
|
||||
elsif Input.repeat?(Input::RIGHT)
|
||||
update_cursor_position(1, 0)
|
||||
elsif Input.repeat?(Input::JUMPUP)
|
||||
update_cursor_position(0, -@visible_height)
|
||||
elsif Input.repeat?(Input::JUMPDOWN)
|
||||
update_cursor_position(0, @visible_height)
|
||||
elsif Input.trigger?(Input::ACTION)
|
||||
commands = [
|
||||
_INTL("Go to bottom"),
|
||||
_INTL("Go to top"),
|
||||
_INTL("Change tileset"),
|
||||
_INTL("Cancel")
|
||||
]
|
||||
case pbShowCommands(nil, commands, -1)
|
||||
when 0
|
||||
update_cursor_position(0, 99999)
|
||||
when 1
|
||||
update_cursor_position(0, -99999)
|
||||
when 2
|
||||
choose_tileset
|
||||
end
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
if pbConfirmMessage(_INTL("Save changes?"))
|
||||
save_data(@tilesets_data, "Data/Tilesets.rxdata")
|
||||
$data_tilesets = @tilesets_data
|
||||
if $game_map && $MapFactory
|
||||
$MapFactory.setup($game_map.map_id)
|
||||
$game_player.center($game_player.x, $game_player.y)
|
||||
if $scene.is_a?(Scene_Map)
|
||||
$scene.disposeSpritesets
|
||||
$scene.createSpritesets
|
||||
end
|
||||
end
|
||||
pbMessage(_INTL("To ensure that the changes remain, close and reopen RPG Maker XP."))
|
||||
end
|
||||
break if pbConfirmMessage(_INTL("Exit from the editor?"))
|
||||
elsif Input.trigger?(Input::USE)
|
||||
selected = tile_ID_from_coordinates(@x, @y)
|
||||
params = ChooseNumberParams.new
|
||||
params.setRange(0, 99)
|
||||
params.setDefaultValue(@tileset.terrain_tags[selected])
|
||||
set_terrain_tag_for_tile_ID(selected, pbMessageChooseNumber(_INTL("Set the terrain tag."), params))
|
||||
draw_overlay
|
||||
end
|
||||
end
|
||||
close_screen
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
def pbTilesetScreen
|
||||
pbFadeOutIn {
|
||||
scene = PokemonTilesetScene.new
|
||||
scene.pbStartScene
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,590 @@
|
||||
#===============================================================================
|
||||
# Miniature game map drawing
|
||||
#===============================================================================
|
||||
class MapSprite
|
||||
def initialize(map,viewport=nil)
|
||||
@sprite=Sprite.new(viewport)
|
||||
@sprite.bitmap=createMinimap(map)
|
||||
@sprite.x=(Graphics.width/2)-(@sprite.bitmap.width/2)
|
||||
@sprite.y=(Graphics.height/2)-(@sprite.bitmap.height/2)
|
||||
end
|
||||
|
||||
def dispose
|
||||
@sprite.bitmap.dispose
|
||||
@sprite.dispose
|
||||
end
|
||||
|
||||
def z=(value)
|
||||
@sprite.z=value
|
||||
end
|
||||
|
||||
def getXY
|
||||
return nil if !Input.trigger?(Input::MOUSELEFT)
|
||||
mouse = Mouse::getMousePos(true)
|
||||
return nil if !mouse
|
||||
if mouse[0]<@sprite.x || mouse[0]>=@sprite.x+@sprite.bitmap.width
|
||||
return nil
|
||||
end
|
||||
if mouse[1]<@sprite.y || mouse[1]>=@sprite.y+@sprite.bitmap.height
|
||||
return nil
|
||||
end
|
||||
x = mouse[0]-@sprite.x
|
||||
y = mouse[1]-@sprite.y
|
||||
return [x/4,y/4]
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class SelectionSprite < Sprite
|
||||
def initialize(viewport=nil)
|
||||
@sprite=Sprite.new(viewport)
|
||||
@sprite.bitmap=nil
|
||||
@sprite.z=2
|
||||
@othersprite=nil
|
||||
end
|
||||
|
||||
def disposed?
|
||||
return @sprite.disposed?
|
||||
end
|
||||
|
||||
def dispose
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
@othersprite=nil
|
||||
@sprite.dispose
|
||||
end
|
||||
|
||||
def othersprite=(value)
|
||||
@othersprite=value
|
||||
if @othersprite && !@othersprite.disposed? &&
|
||||
@othersprite.bitmap && !@othersprite.bitmap.disposed?
|
||||
@sprite.bitmap=pbDoEnsureBitmap(
|
||||
@sprite.bitmap,@othersprite.bitmap.width,@othersprite.bitmap.height)
|
||||
red=Color.new(255,0,0)
|
||||
@sprite.bitmap.clear
|
||||
@sprite.bitmap.fill_rect(0,0,@othersprite.bitmap.width,2,red)
|
||||
@sprite.bitmap.fill_rect(0,@othersprite.bitmap.height-2,
|
||||
@othersprite.bitmap.width,2,red)
|
||||
@sprite.bitmap.fill_rect(0,0,2,@othersprite.bitmap.height,red)
|
||||
@sprite.bitmap.fill_rect(@othersprite.bitmap.width-2,0,2,
|
||||
@othersprite.bitmap.height,red)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @othersprite && !@othersprite.disposed?
|
||||
@sprite.visible=@othersprite.visible
|
||||
@sprite.x=@othersprite.x
|
||||
@sprite.y=@othersprite.y
|
||||
else
|
||||
@sprite.visible=false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class RegionMapSprite
|
||||
def initialize(map,viewport=nil)
|
||||
@sprite=Sprite.new(viewport)
|
||||
@sprite.bitmap=createRegionMap(map)
|
||||
@sprite.x=(Graphics.width/2)-(@sprite.bitmap.width/2)
|
||||
@sprite.y=(Graphics.height/2)-(@sprite.bitmap.height/2)
|
||||
end
|
||||
|
||||
def dispose
|
||||
@sprite.bitmap.dispose
|
||||
@sprite.dispose
|
||||
end
|
||||
|
||||
def z=(value)
|
||||
@sprite.z=value
|
||||
end
|
||||
|
||||
def createRegionMap(map)
|
||||
@mapdata = pbLoadTownMapData
|
||||
@map=@mapdata[map]
|
||||
bitmap=AnimatedBitmap.new("Graphics/Pictures/#{@map[1]}").deanimate
|
||||
retbitmap=BitmapWrapper.new(bitmap.width/2,bitmap.height/2)
|
||||
retbitmap.stretch_blt(
|
||||
Rect.new(0,0,bitmap.width/2,bitmap.height/2),
|
||||
bitmap,
|
||||
Rect.new(0,0,bitmap.width,bitmap.height)
|
||||
)
|
||||
bitmap.dispose
|
||||
return retbitmap
|
||||
end
|
||||
|
||||
def getXY
|
||||
return nil if !Input.trigger?(Input::MOUSELEFT)
|
||||
mouse=Mouse::getMousePos(true)
|
||||
return nil if !mouse
|
||||
if mouse[0]<@sprite.x||mouse[0]>=@sprite.x+@sprite.bitmap.width
|
||||
return nil
|
||||
end
|
||||
if mouse[1]<@sprite.y||mouse[1]>=@sprite.y+@sprite.bitmap.height
|
||||
return nil
|
||||
end
|
||||
x=mouse[0]-@sprite.x
|
||||
y=mouse[1]-@sprite.y
|
||||
return [x/8,y/8]
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Visual Editor (map connections)
|
||||
#===============================================================================
|
||||
class MapScreenScene
|
||||
def getMapSprite(id)
|
||||
if !@mapsprites[id]
|
||||
@mapsprites[id]=Sprite.new(@viewport)
|
||||
@mapsprites[id].z=0
|
||||
@mapsprites[id].bitmap=nil
|
||||
end
|
||||
if !@mapsprites[id].bitmap || @mapsprites[id].bitmap.disposed?
|
||||
@mapsprites[id].bitmap=createMinimap(id)
|
||||
end
|
||||
return @mapsprites[id]
|
||||
end
|
||||
|
||||
def close
|
||||
pbDisposeSpriteHash(@sprites)
|
||||
pbDisposeSpriteHash(@mapsprites)
|
||||
@viewport.dispose
|
||||
end
|
||||
|
||||
def setMapSpritePos(id,x,y)
|
||||
sprite=getMapSprite(id)
|
||||
sprite.x=x
|
||||
sprite.y=y
|
||||
sprite.visible=true
|
||||
end
|
||||
|
||||
def putNeighbors(id,sprites)
|
||||
conns=@mapconns
|
||||
mapsprite=getMapSprite(id)
|
||||
dispx=mapsprite.x
|
||||
dispy=mapsprite.y
|
||||
for conn in conns
|
||||
if conn[0]==id
|
||||
b=sprites.any? { |i| i==conn[3] }
|
||||
if !b
|
||||
x=(conn[1]-conn[4])*4+dispx
|
||||
y=(conn[2]-conn[5])*4+dispy
|
||||
setMapSpritePos(conn[3],x,y)
|
||||
sprites.push(conn[3])
|
||||
putNeighbors(conn[3],sprites)
|
||||
end
|
||||
elsif conn[3]==id
|
||||
b=sprites.any? { |i| i==conn[0] }
|
||||
if !b
|
||||
x=(conn[4]-conn[1])*4+dispx
|
||||
y=(conn[5]-conn[2])*4+dispy
|
||||
setMapSpritePos(conn[0],x,y)
|
||||
sprites.push(conn[3])
|
||||
putNeighbors(conn[0],sprites)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def hasConnections?(conns,id)
|
||||
for conn in conns
|
||||
return true if conn[0]==id || conn[3]==id
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def connectionsSymmetric?(conn1,conn2)
|
||||
if conn1[0]==conn2[0]
|
||||
# Equality
|
||||
return false if conn1[1]!=conn2[1]
|
||||
return false if conn1[2]!=conn2[2]
|
||||
return false if conn1[3]!=conn2[3]
|
||||
return false if conn1[4]!=conn2[4]
|
||||
return false if conn1[5]!=conn2[5]
|
||||
return true
|
||||
elsif conn1[0]==conn2[3]
|
||||
# Symmetry
|
||||
return false if conn1[1]!=-conn2[1]
|
||||
return false if conn1[2]!=-conn2[2]
|
||||
return false if conn1[3]!=conn2[0]
|
||||
return false if conn1[4]!=-conn2[4]
|
||||
return false if conn1[5]!=-conn2[5]
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def removeOldConnections(ret,mapid)
|
||||
for i in 0...ret.length
|
||||
ret[i]=nil if ret[i][0]==mapid || ret[i][3]==mapid
|
||||
end
|
||||
ret.compact!
|
||||
end
|
||||
|
||||
# Returns the maps within _keys_ that are directly connected to this map, _map_.
|
||||
def getDirectConnections(keys,map)
|
||||
thissprite=getMapSprite(map)
|
||||
thisdims=MapFactoryHelper.getMapDims(map)
|
||||
ret=[]
|
||||
for i in keys
|
||||
next if i==map
|
||||
othersprite=getMapSprite(i)
|
||||
otherdims=MapFactoryHelper.getMapDims(i)
|
||||
x1=(thissprite.x-othersprite.x)/4
|
||||
y1=(thissprite.y-othersprite.y)/4
|
||||
if (x1==otherdims[0] || x1==-thisdims[0] ||
|
||||
y1==otherdims[1] || y1==-thisdims[1])
|
||||
ret.push(i)
|
||||
end
|
||||
end
|
||||
# If no direct connections, add an indirect connection
|
||||
if ret.length==0
|
||||
key=(map==keys[0]) ? keys[1] : keys[0]
|
||||
ret.push(key)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def generateConnectionData
|
||||
ret=[]
|
||||
# Create a clone of current map connection
|
||||
for conn in @mapconns
|
||||
ret.push(conn.clone)
|
||||
end
|
||||
keys=@mapsprites.keys
|
||||
return ret if keys.length<2
|
||||
# Remove all connections containing any sprites on the canvas from the array
|
||||
for i in keys
|
||||
removeOldConnections(ret,i)
|
||||
end
|
||||
# Rebuild connections
|
||||
for i in keys
|
||||
refs=getDirectConnections(keys,i)
|
||||
for refmap in refs
|
||||
othersprite=getMapSprite(i)
|
||||
refsprite=getMapSprite(refmap)
|
||||
c1=(refsprite.x-othersprite.x)/4
|
||||
c2=(refsprite.y-othersprite.y)/4
|
||||
conn=[refmap,0,0,i,c1,c2]
|
||||
j=0
|
||||
while j<ret.length && !connectionsSymmetric?(ret[j],conn)
|
||||
j+=1
|
||||
end
|
||||
if j==ret.length
|
||||
ret.push(conn)
|
||||
end
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def serializeConnectionData
|
||||
conndata=generateConnectionData()
|
||||
save_data(conndata, "Data/map_connections.dat")
|
||||
Compiler.write_connections
|
||||
@mapconns=conndata
|
||||
end
|
||||
|
||||
def putSprite(id)
|
||||
addSprite(id)
|
||||
putNeighbors(id,[])
|
||||
end
|
||||
|
||||
def addSprite(id)
|
||||
mapsprite=getMapSprite(id)
|
||||
x=(Graphics.width-mapsprite.bitmap.width)/2
|
||||
y=(Graphics.height-mapsprite.bitmap.height)/2
|
||||
mapsprite.x=x.to_i&~3
|
||||
mapsprite.y=y.to_i&~3
|
||||
end
|
||||
|
||||
def saveMapSpritePos
|
||||
@mapspritepos.clear
|
||||
for i in @mapsprites.keys
|
||||
s=@mapsprites[i]
|
||||
@mapspritepos[i]=[s.x,s.y] if s && !s.disposed?
|
||||
end
|
||||
end
|
||||
|
||||
def mapScreen
|
||||
@sprites={}
|
||||
@mapsprites={}
|
||||
@mapspritepos={}
|
||||
@viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
|
||||
@viewport.z=99999
|
||||
@lasthitmap=-1
|
||||
@lastclick=-1
|
||||
@oldmousex=nil
|
||||
@oldmousey=nil
|
||||
@dragging=false
|
||||
@dragmapid=-1
|
||||
@dragOffsetX=0
|
||||
@dragOffsetY=0
|
||||
@selmapid=-1
|
||||
@sprites["background"] = ColoredPlane.new(Color.new(160, 208, 240), @viewport)
|
||||
@sprites["selsprite"]=SelectionSprite.new(@viewport)
|
||||
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(_INTL("D: Help"),
|
||||
0, Graphics.height - 64, Graphics.width, 64, @viewport)
|
||||
@sprites["title"].z = 2
|
||||
@mapinfos=pbLoadMapInfos
|
||||
conns=MapFactoryHelper.getMapConnections
|
||||
@mapconns=[]
|
||||
for map_conns in conns
|
||||
next if !map_conns
|
||||
map_conns.each do |c|
|
||||
@mapconns.push(c.clone) if !@mapconns.any? { |x| x[0] == c[0] && x[3] == c[3] }
|
||||
end
|
||||
end
|
||||
if $game_map
|
||||
@currentmap=$game_map.map_id
|
||||
else
|
||||
@currentmap=($data_system) ? $data_system.edit_map_id : 1
|
||||
end
|
||||
putSprite(@currentmap)
|
||||
end
|
||||
|
||||
def setTopSprite(id)
|
||||
for i in @mapsprites.keys
|
||||
@mapsprites[i].z = (i == id) ? 1 : 0
|
||||
end
|
||||
end
|
||||
|
||||
def helpWindow
|
||||
helptext=_INTL("A: Add map to canvas\r\n")
|
||||
helptext+=_INTL("DEL: Delete map from canvas\r\n")
|
||||
helptext+=_INTL("S: Go to another map\r\n")
|
||||
helptext+=_INTL("Click to select a map\r\n")
|
||||
helptext+=_INTL("Double-click: Edit map's metadata\r\n")
|
||||
helptext+=_INTL("Drag map to move it\r\n")
|
||||
helptext+=_INTL("Arrow keys/drag canvas: Move around canvas")
|
||||
title = Window_UnformattedTextPokemon.newWithSize(helptext,
|
||||
0, 0, Graphics.width * 8 / 10, Graphics.height, @viewport)
|
||||
title.z = 2
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
break if Input.trigger?(Input::BACK) || Input.trigger?(Input::USE)
|
||||
end
|
||||
Input.update
|
||||
title.dispose
|
||||
end
|
||||
|
||||
def getMapRect(mapid)
|
||||
sprite=getMapSprite(mapid)
|
||||
if sprite
|
||||
return [
|
||||
sprite.x,
|
||||
sprite.y,
|
||||
sprite.x+sprite.bitmap.width,
|
||||
sprite.y+sprite.bitmap.height
|
||||
]
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def onDoubleClick(map_id)
|
||||
pbEditMetadata(map_id) if map_id > 0
|
||||
end
|
||||
|
||||
def onClick(mapid,x,y)
|
||||
if @lastclick>0 && Graphics.frame_count - @lastclick < Graphics.frame_rate * 0.5
|
||||
onDoubleClick(mapid)
|
||||
@lastclick=-1
|
||||
else
|
||||
@lastclick=Graphics.frame_count
|
||||
if mapid>=0
|
||||
@dragging=true
|
||||
@dragmapid=mapid
|
||||
sprite=getMapSprite(mapid)
|
||||
@sprites["selsprite"].othersprite=sprite
|
||||
@selmapid=mapid
|
||||
@dragOffsetX=sprite.x-x
|
||||
@dragOffsetY=sprite.y-y
|
||||
setTopSprite(mapid)
|
||||
else
|
||||
@sprites["selsprite"].othersprite=nil
|
||||
@dragging=true
|
||||
@dragmapid=mapid
|
||||
@selmapid=-1
|
||||
@dragOffsetX=x
|
||||
@dragOffsetY=y
|
||||
saveMapSpritePos
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def onRightClick(mapid,x,y)
|
||||
# echoln("rightclick (#{mapid})")
|
||||
end
|
||||
|
||||
def onMouseUp(mapid)
|
||||
# echoln("mouseup (#{mapid})")
|
||||
@dragging=false if @dragging
|
||||
end
|
||||
|
||||
def onRightMouseUp(mapid)
|
||||
# echoln("rightmouseup (#{mapid})")
|
||||
end
|
||||
|
||||
def onMouseOver(mapid,x,y)
|
||||
# echoln("mouseover (#{mapid},#{x},#{y})")
|
||||
end
|
||||
|
||||
def onMouseMove(mapid,x,y)
|
||||
# echoln("mousemove (#{mapid},#{x},#{y})")
|
||||
if @dragging
|
||||
if @dragmapid>=0
|
||||
sprite=getMapSprite(@dragmapid)
|
||||
x=x+@dragOffsetX
|
||||
y=y+@dragOffsetY
|
||||
sprite.x=x&~3
|
||||
sprite.y=y&~3
|
||||
@sprites["title"].text=_ISPRINTF("D: Help [{1:03d}: {2:s}]",mapid,@mapinfos[@dragmapid].name)
|
||||
else
|
||||
xpos=x-@dragOffsetX
|
||||
ypos=y-@dragOffsetY
|
||||
for i in @mapspritepos.keys
|
||||
sprite=getMapSprite(i)
|
||||
sprite.x=(@mapspritepos[i][0]+xpos)&~3
|
||||
sprite.y=(@mapspritepos[i][1]+ypos)&~3
|
||||
end
|
||||
@sprites["title"].text=_INTL("D: Help")
|
||||
end
|
||||
else
|
||||
if mapid>=0
|
||||
@sprites["title"].text=_ISPRINTF("D: Help [{1:03d}: {2:s}]",mapid,@mapinfos[mapid].name)
|
||||
else
|
||||
@sprites["title"].text=_INTL("D: Help")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def hittest(x,y)
|
||||
for i in @mapsprites.keys
|
||||
sx=@mapsprites[i].x
|
||||
sy=@mapsprites[i].y
|
||||
sr=sx+@mapsprites[i].bitmap.width
|
||||
sb=sy+@mapsprites[i].bitmap.height
|
||||
return i if x>=sx && x<sr && y>=sy && y<sb
|
||||
end
|
||||
return -1
|
||||
end
|
||||
|
||||
def chooseMapScreen(title,currentmap)
|
||||
return pbListScreen(title,MapLister.new(currentmap))
|
||||
end
|
||||
|
||||
def update
|
||||
mousepos=Mouse::getMousePos
|
||||
if mousepos
|
||||
hitmap=hittest(mousepos[0],mousepos[1])
|
||||
if Input.trigger?(Input::MOUSELEFT)
|
||||
onClick(hitmap,mousepos[0],mousepos[1])
|
||||
elsif Input.trigger?(Input::MOUSERIGHT)
|
||||
onRightClick(hitmap,mousepos[0],mousepos[1])
|
||||
elsif Input.release?(Input::MOUSELEFT)
|
||||
onMouseUp(hitmap)
|
||||
elsif Input.release?(Input::MOUSERIGHT)
|
||||
onRightMouseUp(hitmap)
|
||||
else
|
||||
if @lasthitmap!=hitmap
|
||||
onMouseOver(hitmap,mousepos[0],mousepos[1])
|
||||
@lasthitmap=hitmap
|
||||
end
|
||||
if @oldmousex!=mousepos[0] || @oldmousey!=mousepos[1]
|
||||
onMouseMove(hitmap,mousepos[0],mousepos[1])
|
||||
@oldmousex=mousepos[0]
|
||||
@oldmousey=mousepos[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
if Input.press?(Input::UP)
|
||||
for i in @mapsprites
|
||||
i[1].y += 4 if i
|
||||
end
|
||||
end
|
||||
if Input.press?(Input::DOWN)
|
||||
for i in @mapsprites
|
||||
i[1].y -= 4 if i
|
||||
end
|
||||
end
|
||||
if Input.press?(Input::LEFT)
|
||||
for i in @mapsprites
|
||||
i[1].x += 4 if i
|
||||
end
|
||||
end
|
||||
if Input.press?(Input::RIGHT)
|
||||
for i in @mapsprites
|
||||
i[1].x -= 4 if i
|
||||
end
|
||||
end
|
||||
if Input.triggerex?(:A)
|
||||
id=chooseMapScreen(_INTL("Add Map"),@currentmap)
|
||||
if id>0
|
||||
addSprite(id)
|
||||
setTopSprite(id)
|
||||
@mapconns=generateConnectionData
|
||||
end
|
||||
elsif Input.triggerex?(:S)
|
||||
id=chooseMapScreen(_INTL("Go to Map"),@currentmap)
|
||||
if id>0
|
||||
@mapconns=generateConnectionData
|
||||
pbDisposeSpriteHash(@mapsprites)
|
||||
@mapsprites.clear
|
||||
@sprites["selsprite"].othersprite=nil
|
||||
@selmapid=-1
|
||||
putSprite(id)
|
||||
@currentmap=id
|
||||
end
|
||||
elsif Input.triggerex?(:DELETE)
|
||||
if @mapsprites.keys.length>1 && @selmapid>=0
|
||||
@mapsprites[@selmapid].bitmap.dispose
|
||||
@mapsprites[@selmapid].dispose
|
||||
@mapsprites.delete(@selmapid)
|
||||
@sprites["selsprite"].othersprite=nil
|
||||
@selmapid=-1
|
||||
end
|
||||
elsif Input.triggerex?(:D)
|
||||
helpWindow
|
||||
end
|
||||
pbUpdateSpriteHash(@sprites)
|
||||
end
|
||||
|
||||
def pbMapScreenLoop
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
update
|
||||
if Input.trigger?(Input::BACK)
|
||||
if pbConfirmMessage(_INTL("Save changes?"))
|
||||
serializeConnectionData
|
||||
MapFactoryHelper.clear
|
||||
else
|
||||
GameData::Encounter.load
|
||||
end
|
||||
break if pbConfirmMessage(_INTL("Exit from the editor?"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
def pbConnectionsEditor
|
||||
pbCriticalCode {
|
||||
Graphics.resize_screen(Settings::SCREEN_WIDTH + 288, Settings::SCREEN_HEIGHT + 288)
|
||||
pbSetResizeFactor(1)
|
||||
mapscreen = MapScreenScene.new
|
||||
mapscreen.mapScreen
|
||||
mapscreen.pbMapScreenLoop
|
||||
mapscreen.close
|
||||
Graphics.resize_screen(Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT)
|
||||
pbSetResizeFactor($PokemonSystem.screensize)
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,421 @@
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
def findBottom(bitmap)
|
||||
return 0 if !bitmap
|
||||
for i in 1..bitmap.height
|
||||
for j in 0..bitmap.width - 1
|
||||
return bitmap.height - i if bitmap.get_pixel(j, bitmap.height - i).alpha > 0
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
def pbAutoPositionAll
|
||||
GameData::Species.each do |sp|
|
||||
Graphics.update if sp.id_number % 50 == 0
|
||||
bitmap1 = GameData::Species.sprite_bitmap(sp.species, sp.form, nil, nil, nil, true)
|
||||
bitmap2 = GameData::Species.sprite_bitmap(sp.species, sp.form)
|
||||
if bitmap1 && bitmap1.bitmap # Player's y
|
||||
sp.back_sprite_x = 0
|
||||
sp.back_sprite_y = (bitmap1.height - (findBottom(bitmap1.bitmap) + 1)) / 2
|
||||
end
|
||||
if bitmap2 && bitmap2.bitmap # Foe's y
|
||||
sp.front_sprite_x = 0
|
||||
sp.front_sprite_y = (bitmap2.height - (findBottom(bitmap2.bitmap) + 1)) / 2
|
||||
sp.front_sprite_y += 4 # Just because
|
||||
end
|
||||
sp.front_sprite_altitude = 0 # Shouldn't be used
|
||||
sp.shadow_x = 0
|
||||
sp.shadow_size = 2
|
||||
bitmap1.dispose if bitmap1
|
||||
bitmap2.dispose if bitmap2
|
||||
end
|
||||
GameData::Species.save
|
||||
Compiler.write_pokemon
|
||||
Compiler.write_pokemon_forms
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class SpritePositioner
|
||||
def pbOpen
|
||||
@sprites = {}
|
||||
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
@viewport.z = 99999
|
||||
battlebg = "Graphics/Battlebacks/battlebg/indoorc"
|
||||
enemybase = "Graphics/Battlebacks/enemybase/indoorc"
|
||||
playerbase = "Graphics/Battlebacks/playerbase/indoorc"
|
||||
@sprites["battle_bg"] = AnimatedPlane.new(@viewport)
|
||||
@sprites["battle_bg"].setBitmap(battlebg)
|
||||
@sprites["battle_bg"].z = 0
|
||||
baseX, baseY = PokeBattle_SceneConstants.pbBattlerPosition(0)
|
||||
@sprites["base_0"] = IconSprite.new(baseX, baseY, @viewport)
|
||||
@sprites["base_0"].setBitmap(playerbase)
|
||||
@sprites["base_0"].x -= @sprites["base_0"].bitmap.width / 2 if @sprites["base_0"].bitmap
|
||||
@sprites["base_0"].y -= @sprites["base_0"].bitmap.height if @sprites["base_0"].bitmap
|
||||
@sprites["base_0"].z = 1
|
||||
baseX, baseY = PokeBattle_SceneConstants.pbBattlerPosition(1)
|
||||
@sprites["base_1"] = IconSprite.new(baseX, baseY, @viewport)
|
||||
@sprites["base_1"].setBitmap(enemybase)
|
||||
@sprites["base_1"].x -= @sprites["base_1"].bitmap.width / 2 if @sprites["base_1"].bitmap
|
||||
@sprites["base_1"].y -= @sprites["base_1"].bitmap.height / 2 if @sprites["base_1"].bitmap
|
||||
@sprites["base_1"].z = 1
|
||||
@sprites["messageBox"] = IconSprite.new(0, Graphics.height - 96, @viewport)
|
||||
@sprites["messageBox"].setBitmap("Graphics/Pictures/Battle/debug_message")
|
||||
@sprites["messageBox"].z = 2
|
||||
@sprites["shadow_1"] = IconSprite.new(0, 0, @viewport)
|
||||
@sprites["shadow_1"].z = 3
|
||||
@sprites["pokemon_0"] = PokemonSprite.new(@viewport)
|
||||
@sprites["pokemon_0"].zoom_x = Settings::BACKRPSPRITE_SCALE
|
||||
@sprites["pokemon_0"].zoom_y = Settings::BACKRPSPRITE_SCALE
|
||||
@sprites["pokemon_0"].mirror = true
|
||||
|
||||
@sprites["pokemon_0"].setOffset(PictureOrigin::Bottom)
|
||||
@sprites["pokemon_0"].z = 1
|
||||
@sprites["pokemon_1"] = PokemonSprite.new(@viewport)
|
||||
@sprites["pokemon_1"].setOffset(PictureOrigin::Bottom)
|
||||
@sprites["pokemon_1"].z = 4
|
||||
# @sprites["pokemon_1"] = PokemonSprite.new(@viewport)
|
||||
@sprites["pokemon_1"].zoom_x = Settings::FRONTSPRITE_SCALE
|
||||
@sprites["pokemon_1"].zoom_y = Settings::FRONTSPRITE_SCALE
|
||||
|
||||
@sprites["info"] = Window_UnformattedTextPokemon.new("")
|
||||
@sprites["info"].viewport = @viewport
|
||||
@sprites["info"].visible = false
|
||||
@oldSpeciesIndex = 0
|
||||
@species = nil # This can be a species_form
|
||||
@metricsChanged = false
|
||||
refresh
|
||||
@starting = true
|
||||
end
|
||||
|
||||
def pbClose
|
||||
if @metricsChanged && pbConfirmMessage(_INTL("Some metrics have been edited. Save changes?"))
|
||||
pbSaveMetrics
|
||||
@metricsChanged = false
|
||||
else
|
||||
GameData::Species.load # Clear all changes to metrics
|
||||
end
|
||||
pbFadeOutAndHide(@sprites) { update }
|
||||
pbDisposeSpriteHash(@sprites)
|
||||
@viewport.dispose
|
||||
end
|
||||
|
||||
def pbSaveMetrics
|
||||
GameData::Species.save
|
||||
Compiler.write_pokemon
|
||||
Compiler.write_pokemon_forms
|
||||
end
|
||||
|
||||
def update
|
||||
pbUpdateSpriteHash(@sprites)
|
||||
end
|
||||
|
||||
def refresh
|
||||
if !@species
|
||||
@sprites["pokemon_0"].visible = false
|
||||
@sprites["pokemon_1"].visible = false
|
||||
@sprites["shadow_1"].visible = false
|
||||
return
|
||||
end
|
||||
species_data = GameData::Species.get(@species)
|
||||
for i in 0...2
|
||||
pos = PokeBattle_SceneConstants.pbBattlerPosition(i, 1)
|
||||
@sprites["pokemon_#{i}"].x = pos[0]
|
||||
@sprites["pokemon_#{i}"].y = pos[1]
|
||||
species_data.apply_metrics_to_sprite(@sprites["pokemon_#{i}"], i)
|
||||
@sprites["pokemon_#{i}"].visible = true
|
||||
next if i != 1
|
||||
@sprites["shadow_1"].x = pos[0]
|
||||
@sprites["shadow_1"].y = pos[1]
|
||||
if @sprites["shadow_1"].bitmap
|
||||
@sprites["shadow_1"].x -= @sprites["shadow_1"].bitmap.width / 2
|
||||
@sprites["shadow_1"].y -= @sprites["shadow_1"].bitmap.height / 2
|
||||
end
|
||||
species_data.apply_metrics_to_sprite(@sprites["shadow_1"], i, true)
|
||||
@sprites["shadow_1"].visible = true
|
||||
end
|
||||
end
|
||||
|
||||
def pbAutoPosition
|
||||
species_data = GameData::Species.get(@species)
|
||||
old_back_y = species_data.back_sprite_y
|
||||
old_front_y = species_data.front_sprite_y
|
||||
old_front_altitude = species_data.front_sprite_altitude
|
||||
bitmap1 = @sprites["pokemon_0"].bitmap
|
||||
bitmap2 = @sprites["pokemon_1"].bitmap
|
||||
new_back_y = (bitmap1.height - (findBottom(bitmap1) + 1)) / 2
|
||||
new_front_y = (bitmap2.height - (findBottom(bitmap2) + 1)) / 2
|
||||
new_front_y += 4 # Just because
|
||||
if new_back_y != old_back_y || new_front_y != old_front_y || old_front_altitude != 0
|
||||
species_data.back_sprite_y = new_back_y
|
||||
species_data.front_sprite_y = new_front_y
|
||||
species_data.front_sprite_altitude = 0
|
||||
@metricsChanged = true
|
||||
refresh
|
||||
end
|
||||
end
|
||||
|
||||
def pbChangeSpecies(species)
|
||||
@species = species
|
||||
species_data = GameData::Species.try_get(@species)
|
||||
return if !species_data
|
||||
spe = species_data.species
|
||||
frm = species_data.form
|
||||
# @sprites["pokemon_0"].setSpeciesBitmap(spe, 0, frm, false, false, true)
|
||||
# @sprites["pokemon_1"].setSpeciesBitmap(spe, 0, frm)
|
||||
@sprites["pokemon_0"].setPokemonBitmapFromId(spe, true)
|
||||
@sprites["pokemon_1"].setPokemonBitmapFromId(spe)
|
||||
@sprites["shadow_1"].setBitmap(GameData::Species.shadow_filename(spe, frm))
|
||||
end
|
||||
|
||||
def pbShadowSize
|
||||
pbChangeSpecies(@species)
|
||||
refresh
|
||||
species_data = GameData::Species.get(@species)
|
||||
if pbResolveBitmap(sprintf("Graphics/Pokemon/Shadow/%s_%d", species_data.species, species_data.form)) ||
|
||||
pbResolveBitmap(sprintf("Graphics/Pokemon/Shadow/%s", species_data.species))
|
||||
pbMessage("This species has its own shadow sprite in Graphics/Pokemon/Shadow/. The shadow size metric cannot be edited.")
|
||||
return false
|
||||
end
|
||||
oldval = species_data.shadow_size
|
||||
cmdvals = [0]
|
||||
commands = [_INTL("None")]
|
||||
defindex = 0
|
||||
i = 0
|
||||
loop do
|
||||
i += 1
|
||||
fn = sprintf("Graphics/Pokemon/Shadow/%d", i)
|
||||
break if !pbResolveBitmap(fn)
|
||||
cmdvals.push(i)
|
||||
commands.push(i.to_s)
|
||||
defindex = cmdvals.length - 1 if oldval == i
|
||||
end
|
||||
cw = Window_CommandPokemon.new(commands)
|
||||
cw.index = defindex
|
||||
cw.viewport = @viewport
|
||||
ret = false
|
||||
oldindex = cw.index
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cw.update
|
||||
self.update
|
||||
if cw.index != oldindex
|
||||
oldindex = cw.index
|
||||
species_data.shadow_size = cmdvals[cw.index]
|
||||
pbChangeSpecies(@species)
|
||||
refresh
|
||||
end
|
||||
if Input.trigger?(Input::ACTION) # Cycle to next option
|
||||
pbPlayDecisionSE
|
||||
@metricsChanged = true if species_data.shadow_size != oldval
|
||||
ret = true
|
||||
break
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
species_data.shadow_size = oldval
|
||||
pbPlayCancelSE
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
pbPlayDecisionSE
|
||||
@metricsChanged = true if species_data.shadow_size != oldval
|
||||
break
|
||||
end
|
||||
end
|
||||
cw.dispose
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbSetParameter(param)
|
||||
return if !@species
|
||||
return pbShadowSize if param == 2
|
||||
if param == 4
|
||||
pbAutoPosition
|
||||
return false
|
||||
end
|
||||
species_data = GameData::Species.get(@species)
|
||||
case param
|
||||
when 0
|
||||
sprite = @sprites["pokemon_0"]
|
||||
xpos = species_data.back_sprite_x
|
||||
ypos = species_data.back_sprite_y
|
||||
when 1
|
||||
sprite = @sprites["pokemon_1"]
|
||||
xpos = species_data.front_sprite_x
|
||||
ypos = species_data.front_sprite_y
|
||||
when 3
|
||||
sprite = @sprites["shadow_1"]
|
||||
xpos = species_data.shadow_x
|
||||
ypos = 0
|
||||
end
|
||||
oldxpos = xpos
|
||||
oldypos = ypos
|
||||
@sprites["info"].visible = true
|
||||
ret = false
|
||||
loop do
|
||||
sprite.visible = (Graphics.frame_count % 16) < 12 # Flash the selected sprite
|
||||
Graphics.update
|
||||
Input.update
|
||||
self.update
|
||||
case param
|
||||
when 0 then @sprites["info"].setTextToFit("Ally Position = #{xpos},#{ypos}")
|
||||
when 1 then @sprites["info"].setTextToFit("Enemy Position = #{xpos},#{ypos}")
|
||||
when 3 then @sprites["info"].setTextToFit("Shadow Position = #{xpos}")
|
||||
end
|
||||
if (Input.repeat?(Input::UP) || Input.repeat?(Input::DOWN)) && param != 3
|
||||
ypos += (Input.repeat?(Input::DOWN)) ? 1 : -1
|
||||
case param
|
||||
when 0 then species_data.back_sprite_y = ypos
|
||||
when 1 then species_data.front_sprite_y = ypos
|
||||
end
|
||||
refresh
|
||||
end
|
||||
if Input.repeat?(Input::LEFT) || Input.repeat?(Input::RIGHT)
|
||||
xpos += (Input.repeat?(Input::RIGHT)) ? 1 : -1
|
||||
case param
|
||||
when 0 then species_data.back_sprite_x = xpos
|
||||
when 1 then species_data.front_sprite_x = xpos
|
||||
when 3 then species_data.shadow_x = xpos
|
||||
end
|
||||
refresh
|
||||
end
|
||||
if Input.repeat?(Input::ACTION) && param != 3 # Cycle to next option
|
||||
@metricsChanged = true if xpos != oldxpos || ypos != oldypos
|
||||
ret = true
|
||||
pbPlayDecisionSE
|
||||
break
|
||||
elsif Input.repeat?(Input::BACK)
|
||||
case param
|
||||
when 0
|
||||
species_data.back_sprite_x = oldxpos
|
||||
species_data.back_sprite_y = oldypos
|
||||
when 1
|
||||
species_data.front_sprite_x = oldxpos
|
||||
species_data.front_sprite_y = oldypos
|
||||
when 3
|
||||
species_data.shadow_x = oldxpos
|
||||
end
|
||||
pbPlayCancelSE
|
||||
refresh
|
||||
break
|
||||
elsif Input.repeat?(Input::USE)
|
||||
@metricsChanged = true if xpos != oldxpos || (param != 3 && ypos != oldypos)
|
||||
pbPlayDecisionSE
|
||||
break
|
||||
end
|
||||
end
|
||||
@sprites["info"].visible = false
|
||||
sprite.visible = true
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbMenu
|
||||
# pbChangeSpecies(species)
|
||||
refresh
|
||||
cw = Window_CommandPokemon.new([
|
||||
_INTL("Set Ally Position"),
|
||||
_INTL("Set Enemy Position"),
|
||||
_INTL("Set Shadow Size"),
|
||||
_INTL("Set Shadow Position"),
|
||||
_INTL("Auto-Position Sprites")
|
||||
])
|
||||
cw.x = Graphics.width - cw.width
|
||||
cw.y = Graphics.height - cw.height
|
||||
cw.viewport = @viewport
|
||||
ret = -1
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cw.update
|
||||
self.update
|
||||
if Input.trigger?(Input::USE)
|
||||
pbPlayDecisionSE
|
||||
ret = cw.index
|
||||
break
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
pbPlayCancelSE
|
||||
break
|
||||
end
|
||||
end
|
||||
cw.dispose
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbChooseSpecies
|
||||
if @starting
|
||||
pbFadeInAndShow(@sprites) { update }
|
||||
@starting = false
|
||||
end
|
||||
cw = Window_CommandPokemonEx.newEmpty(0, 0, 260, 32 + 24 * 6, @viewport)
|
||||
cw.rowHeight = 24
|
||||
pbSetSmallFont(cw.contents)
|
||||
cw.x = Graphics.width - cw.width
|
||||
cw.y = Graphics.height - cw.height
|
||||
allspecies = []
|
||||
GameData::Species.each do |sp|
|
||||
name = (sp.form == 0) ? sp.name : _INTL("{1} (form {2})", sp.real_name, sp.form)
|
||||
# allspecies.push([sp.id, sp.species, name]) if name && !name.empty?
|
||||
allspecies.push([sp.id, sp.id_number, name]) if name && !name.empty? # Switched to descending order using the ID of the Pokemon
|
||||
end
|
||||
# allspecies.sort! { |a, b| a[2] <=> b[2] }
|
||||
allspecies.sort! { |a, b| b[1] <=> a[1] } # Switched to descending order using the ID of the Pokemon
|
||||
commands = []
|
||||
allspecies.each { |sp| commands.push(sp[2]) }
|
||||
cw.commands = commands
|
||||
cw.index = @oldSpeciesIndex
|
||||
ret = false
|
||||
oldindex = -1
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cw.update
|
||||
if cw.index != oldindex
|
||||
oldindex = cw.index
|
||||
pbChangeSpecies(allspecies[cw.index][0])
|
||||
refresh
|
||||
end
|
||||
self.update
|
||||
if Input.trigger?(Input::BACK)
|
||||
pbChangeSpecies(nil)
|
||||
refresh
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
pbChangeSpecies(allspecies[cw.index][0])
|
||||
ret = true
|
||||
break
|
||||
end
|
||||
end
|
||||
@oldSpeciesIndex = cw.index
|
||||
cw.dispose
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class SpritePositionerScreen
|
||||
def initialize(scene)
|
||||
@scene = scene
|
||||
end
|
||||
|
||||
def pbStart
|
||||
@scene.pbOpen
|
||||
loop do
|
||||
species = @scene.pbChooseSpecies
|
||||
break if !species
|
||||
loop do
|
||||
command = @scene.pbMenu
|
||||
break if command < 0
|
||||
loop do
|
||||
par = @scene.pbSetParameter(command)
|
||||
break if !par
|
||||
command = (command + 1) % 3
|
||||
end
|
||||
end
|
||||
end
|
||||
@scene.pbClose
|
||||
end
|
||||
end
|
||||
417
Data/Scripts/020_Debug/001_Editor_Utilities.rb
Normal file
417
Data/Scripts/020_Debug/001_Editor_Utilities.rb
Normal file
@@ -0,0 +1,417 @@
|
||||
def pbGetLegalMoves(species)
|
||||
species_data = GameData::Species.get(species)
|
||||
moves = []
|
||||
return moves if !species_data
|
||||
species_data.moves.each { |m| moves.push(m[1]) }
|
||||
species_data.tutor_moves.each { |m| moves.push(m) }
|
||||
babyspecies = species_data.get_baby_species
|
||||
GameData::Species.get(babyspecies).egg_moves.each { |m| moves.push(m) }
|
||||
moves |= [] # Remove duplicates
|
||||
return moves
|
||||
end
|
||||
|
||||
def pbSafeCopyFile(x,y,z=nil)
|
||||
if safeExists?(x)
|
||||
safetocopy = true
|
||||
filedata = nil
|
||||
if safeExists?(y)
|
||||
different = false
|
||||
if FileTest.size(x)!=FileTest.size(y)
|
||||
different = true
|
||||
else
|
||||
filedata2 = ""
|
||||
File.open(x,"rb") { |f| filedata = f.read }
|
||||
File.open(y,"rb") { |f| filedata2 = f.read }
|
||||
different = true if filedata!=filedata2
|
||||
end
|
||||
if different
|
||||
safetocopy=pbConfirmMessage(_INTL("A different file named '{1}' already exists. Overwrite it?",y))
|
||||
else
|
||||
# No need to copy
|
||||
return
|
||||
end
|
||||
end
|
||||
if safetocopy
|
||||
if !filedata
|
||||
File.open(x,"rb") { |f| filedata = f.read }
|
||||
end
|
||||
File.open((z) ? z : y,"wb") { |f| f.write(filedata) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbAllocateAnimation(animations,name)
|
||||
for i in 1...animations.length
|
||||
anim = animations[i]
|
||||
return i if !anim
|
||||
# if name && name!="" && anim.name==name
|
||||
# # use animation with same name
|
||||
# return i
|
||||
# end
|
||||
if anim.length==1 && anim[0].length==2 && anim.name==""
|
||||
# assume empty
|
||||
return i
|
||||
end
|
||||
end
|
||||
oldlength = animations.length
|
||||
animations.resize(10)
|
||||
return oldlength
|
||||
end
|
||||
|
||||
def pbMapTree
|
||||
mapinfos = pbLoadMapInfos
|
||||
maplevels = []
|
||||
retarray = []
|
||||
for i in mapinfos.keys
|
||||
info = mapinfos[i]
|
||||
level = -1
|
||||
while info
|
||||
info = mapinfos[info.parent_id]
|
||||
level += 1
|
||||
end
|
||||
if level>=0
|
||||
info = mapinfos[i]
|
||||
maplevels.push([i,level,info.parent_id,info.order])
|
||||
end
|
||||
end
|
||||
maplevels.sort! { |a,b|
|
||||
next a[1]<=>b[1] if a[1]!=b[1] # level
|
||||
next a[2]<=>b[2] if a[2]!=b[2] # parent ID
|
||||
next a[3]<=>b[3] # order
|
||||
}
|
||||
stack = []
|
||||
stack.push(0,0)
|
||||
while stack.length>0
|
||||
parent = stack[stack.length-1]
|
||||
index = stack[stack.length-2]
|
||||
if index>=maplevels.length
|
||||
stack.pop
|
||||
stack.pop
|
||||
next
|
||||
end
|
||||
maplevel = maplevels[index]
|
||||
stack[stack.length-2] += 1
|
||||
if maplevel[2]!=parent
|
||||
stack.pop
|
||||
stack.pop
|
||||
next
|
||||
end
|
||||
retarray.push([maplevel[0],mapinfos[maplevel[0]].name,maplevel[1]])
|
||||
for i in index+1...maplevels.length
|
||||
if maplevels[i][2]==maplevel[0]
|
||||
stack.push(i)
|
||||
stack.push(maplevel[0])
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return retarray
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# List all members of a class
|
||||
#===============================================================================
|
||||
# Displays a list of all Pokémon species, and returns the ID of the species
|
||||
# selected (or nil if the selection was canceled). "default", if specified, is
|
||||
# the ID of the species to initially select. Pressing Input::ACTION will toggle
|
||||
# the list sorting between numerical and alphabetical.
|
||||
def pbChooseSpeciesList(default = nil,max=nil)
|
||||
# commands = []
|
||||
# GameData::Species.each { |s| commands.push([s.id_number, s.real_name, s.id]) if s.form == 0 }
|
||||
# return pbChooseList(commands, default, nil, -1)
|
||||
#
|
||||
defaultNumber = default == nil ? 1 : getDexNumberForSpecies(default)
|
||||
params = ChooseNumberParams.new
|
||||
|
||||
max = max ? max : PBSpecies.maxValue
|
||||
params.setRange(1,max)
|
||||
params.setInitialValue(defaultNumber)
|
||||
dexNum = pbMessageChooseNumber("dex number?",params)
|
||||
return GameData::Species.get(dexNum)
|
||||
end
|
||||
|
||||
def pbChooseSpeciesTextList(default = nil)
|
||||
commands = []
|
||||
for i in 1..NB_POKEMON
|
||||
species = GameData::Species.get(i)
|
||||
commands.push([species.id_number, species.real_name, species.id])
|
||||
end
|
||||
return pbChooseList(commands, default, nil, -1)
|
||||
end
|
||||
|
||||
|
||||
def pbChooseSpeciesFormList(default = nil)
|
||||
commands = []
|
||||
GameData::Species.each do |s|
|
||||
name = (s.form == 0) ? s.real_name : sprintf("%s_%d", s.real_name, s.form)
|
||||
commands.push([s.id_number, name, s.id])
|
||||
end
|
||||
return pbChooseList(commands, default, nil, -1)
|
||||
end
|
||||
|
||||
# Displays a list of all moves, and returns the ID of the move selected (or nil
|
||||
# if the selection was canceled). "default", if specified, is the ID of the move
|
||||
# to initially select. Pressing Input::ACTION will toggle the list sorting
|
||||
# between numerical and alphabetical.
|
||||
def pbChooseMoveList(default = nil)
|
||||
commands = []
|
||||
GameData::Move.each { |i| commands.push([i.id_number, i.real_name, i.id]) }
|
||||
return pbChooseList(commands, default, nil, 1)
|
||||
end
|
||||
|
||||
def pbChooseMoveListForSpecies(species, defaultMoveID = nil)
|
||||
cmdwin = pbListWindow([], 200)
|
||||
commands = []
|
||||
# Get all legal moves
|
||||
legalMoves = pbGetLegalMoves(species)
|
||||
legalMoves.each do |move|
|
||||
move_data = GameData::Move.get(move)
|
||||
commands.push([move_data.id_number, move_data.name, move_data.id])
|
||||
end
|
||||
commands.sort! { |a, b| a[1] <=> b[1] }
|
||||
moveDefault = 0
|
||||
if defaultMoveID
|
||||
commands.each_with_index do |_item, i|
|
||||
moveDefault = i if moveDefault == 0 && i[2] == defaultMoveID
|
||||
end
|
||||
end
|
||||
# Get all moves
|
||||
commands2 = []
|
||||
GameData::Move.each do |move_data|
|
||||
commands2.push([move_data.id_number, move_data.name, move_data.id])
|
||||
end
|
||||
commands2.sort! { |a, b| a[1] <=> b[1] }
|
||||
if defaultMoveID
|
||||
commands2.each_with_index do |_item, i|
|
||||
moveDefault = i if moveDefault == 0 && i[2] == defaultMoveID
|
||||
end
|
||||
end
|
||||
# Choose from all moves
|
||||
commands.concat(commands2)
|
||||
realcommands = []
|
||||
commands.each { |cmd| realcommands.push(cmd[1]) }
|
||||
ret = pbCommands2(cmdwin, realcommands, -1, moveDefault, true)
|
||||
cmdwin.dispose
|
||||
return (ret >= 0) ? commands[ret][2] : nil
|
||||
end
|
||||
|
||||
# Displays a list of all types, and returns the ID of the type selected (or nil
|
||||
# if the selection was canceled). "default", if specified, is the ID of the type
|
||||
# to initially select. Pressing Input::ACTION will toggle the list sorting
|
||||
# between numerical and alphabetical.
|
||||
def pbChooseTypeList(default = nil)
|
||||
commands = []
|
||||
GameData::Type.each { |t| commands.push([t.id_number, t.name, t.id]) if !t.pseudo_type }
|
||||
return pbChooseList(commands, default, nil, -1)
|
||||
end
|
||||
|
||||
# Displays a list of all items, and returns the ID of the item selected (or nil
|
||||
# if the selection was canceled). "default", if specified, is the ID of the item
|
||||
# to initially select. Pressing Input::ACTION will toggle the list sorting
|
||||
# between numerical and alphabetical.
|
||||
def pbChooseItemList(default = nil)
|
||||
commands = []
|
||||
GameData::Item.each { |i| commands.push([i.id_number, i.name, i.id]) }
|
||||
return pbChooseList(commands, default, nil, -1)
|
||||
end
|
||||
|
||||
# Displays a list of all abilities, and returns the ID of the ability selected
|
||||
# (or nil if the selection was canceled). "default", if specified, is the ID of
|
||||
# the ability to initially select. Pressing Input::ACTION will toggle the list
|
||||
# sorting between numerical and alphabetical.
|
||||
def pbChooseAbilityList(default = nil)
|
||||
commands = []
|
||||
GameData::Ability.each { |a| commands.push([a.id_number, a.name, a.id]) }
|
||||
return pbChooseList(commands, default, nil, -1)
|
||||
end
|
||||
|
||||
def pbChooseBallList(defaultMoveID = nil)
|
||||
cmdwin = pbListWindow([], 200)
|
||||
commands = []
|
||||
moveDefault = 0
|
||||
for key in $BallTypes.keys
|
||||
item = GameData::Item.try_get($BallTypes[key])
|
||||
commands.push([$BallTypes[key], item.name]) if item
|
||||
end
|
||||
commands.sort! { |a, b| a[1] <=> b[1] }
|
||||
if defaultMoveID
|
||||
for i in 0...commands.length
|
||||
moveDefault = i if commands[i][0] == defaultMoveID
|
||||
end
|
||||
end
|
||||
realcommands = []
|
||||
for i in commands
|
||||
realcommands.push(i[1])
|
||||
end
|
||||
ret = pbCommands2(cmdwin, realcommands, -1, moveDefault, true)
|
||||
cmdwin.dispose
|
||||
return (ret >= 0) ? commands[ret][0] : defaultMoveID
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# General list methods
|
||||
#===============================================================================
|
||||
def pbCommands2(cmdwindow,commands,cmdIfCancel,defaultindex=-1,noresize=false)
|
||||
cmdwindow.commands = commands
|
||||
cmdwindow.index = defaultindex if defaultindex>=0
|
||||
cmdwindow.x = 0
|
||||
cmdwindow.y = 0
|
||||
if noresize
|
||||
cmdwindow.height = Graphics.height
|
||||
else
|
||||
cmdwindow.width = Graphics.width/2
|
||||
end
|
||||
cmdwindow.height = Graphics.height if cmdwindow.height>Graphics.height
|
||||
cmdwindow.z = 99999
|
||||
cmdwindow.visible = true
|
||||
cmdwindow.active = true
|
||||
command = 0
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cmdwindow.update
|
||||
if Input.trigger?(Input::BACK)
|
||||
if cmdIfCancel>0
|
||||
command = cmdIfCancel-1
|
||||
break
|
||||
elsif cmdIfCancel<0
|
||||
command = cmdIfCancel
|
||||
break
|
||||
end
|
||||
elsif Input.trigger?(Input::USE)
|
||||
command = cmdwindow.index
|
||||
break
|
||||
end
|
||||
end
|
||||
ret = command
|
||||
cmdwindow.active = false
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbCommands3(cmdwindow,commands,cmdIfCancel,defaultindex=-1,noresize=false)
|
||||
cmdwindow.commands = commands
|
||||
cmdwindow.index = defaultindex if defaultindex>=0
|
||||
cmdwindow.x = 0
|
||||
cmdwindow.y = 0
|
||||
if noresize
|
||||
cmdwindow.height = Graphics.height
|
||||
else
|
||||
cmdwindow.width = Graphics.width/2
|
||||
end
|
||||
cmdwindow.height = Graphics.height if cmdwindow.height>Graphics.height
|
||||
cmdwindow.z = 99999
|
||||
cmdwindow.visible = true
|
||||
cmdwindow.active = true
|
||||
command = 0
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cmdwindow.update
|
||||
if Input.trigger?(Input::SPECIAL)
|
||||
command = [5,cmdwindow.index]
|
||||
break
|
||||
elsif Input.press?(Input::ACTION)
|
||||
if Input.repeat?(Input::UP)
|
||||
command = [1,cmdwindow.index]
|
||||
break
|
||||
elsif Input.repeat?(Input::DOWN)
|
||||
command = [2,cmdwindow.index]
|
||||
break
|
||||
elsif Input.trigger?(Input::LEFT)
|
||||
command = [3,cmdwindow.index]
|
||||
break
|
||||
elsif Input.trigger?(Input::RIGHT)
|
||||
command = [4,cmdwindow.index]
|
||||
break
|
||||
end
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
if cmdIfCancel>0
|
||||
command = [0,cmdIfCancel-1]
|
||||
break
|
||||
elsif cmdIfCancel<0
|
||||
command = [0,cmdIfCancel]
|
||||
break
|
||||
end
|
||||
elsif Input.trigger?(Input::USE)
|
||||
command = [0,cmdwindow.index]
|
||||
break
|
||||
end
|
||||
end
|
||||
ret = command
|
||||
cmdwindow.active = false
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbChooseList(commands, default = 0, cancelValue = -1, sortType = 1)
|
||||
cmdwin = pbListWindow([])
|
||||
itemID = default
|
||||
itemIndex = 0
|
||||
sortMode = (sortType >= 0) ? sortType : 0 # 0=ID, 1=alphabetical
|
||||
sorting = true
|
||||
loop do
|
||||
if sorting
|
||||
if sortMode == 0
|
||||
commands.sort! { |a, b| a[0] <=> b[0] }
|
||||
elsif sortMode == 1
|
||||
commands.sort! { |a, b| a[1] <=> b[1] }
|
||||
end
|
||||
if itemID.is_a?(Symbol)
|
||||
commands.each_with_index { |command, i| itemIndex = i if command[2] == itemID }
|
||||
elsif itemID && itemID > 0
|
||||
commands.each_with_index { |command, i| itemIndex = i if command[0] == itemID }
|
||||
end
|
||||
realcommands = []
|
||||
for command in commands
|
||||
if sortType <= 0
|
||||
realcommands.push(sprintf("%03d: %s", command[0], command[1]))
|
||||
else
|
||||
realcommands.push(command[1])
|
||||
end
|
||||
end
|
||||
sorting = false
|
||||
end
|
||||
cmd = pbCommandsSortable(cmdwin, realcommands, -1, itemIndex, (sortType < 0))
|
||||
if cmd[0] == 0 # Chose an option or cancelled
|
||||
itemID = (cmd[1] < 0) ? cancelValue : (commands[cmd[1]][2] || commands[cmd[1]][0])
|
||||
break
|
||||
elsif cmd[0] == 1 # Toggle sorting
|
||||
itemID = commands[cmd[1]][2] || commands[cmd[1]][0]
|
||||
sortMode = (sortMode + 1) % 2
|
||||
sorting = true
|
||||
end
|
||||
end
|
||||
cmdwin.dispose
|
||||
return itemID
|
||||
end
|
||||
|
||||
def pbCommandsSortable(cmdwindow,commands,cmdIfCancel,defaultindex=-1,sortable=false)
|
||||
cmdwindow.commands = commands
|
||||
cmdwindow.index = defaultindex if defaultindex >= 0
|
||||
cmdwindow.x = 0
|
||||
cmdwindow.y = 0
|
||||
cmdwindow.width = Graphics.width / 2 if cmdwindow.width < Graphics.width / 2
|
||||
cmdwindow.height = Graphics.height
|
||||
cmdwindow.z = 99999
|
||||
cmdwindow.active = true
|
||||
command = 0
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cmdwindow.update
|
||||
if Input.trigger?(Input::ACTION) && sortable
|
||||
command = [1,cmdwindow.index]
|
||||
break
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
command = [0,(cmdIfCancel>0) ? cmdIfCancel-1 : cmdIfCancel]
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
command = [0,cmdwindow.index]
|
||||
break
|
||||
end
|
||||
end
|
||||
ret = command
|
||||
cmdwindow.active = false
|
||||
return ret
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,910 @@
|
||||
module ShadowText
|
||||
def shadowtext(bitmap,x,y,w,h,t,disabled=false,align=0)
|
||||
width=bitmap.text_size(t).width
|
||||
if align==2
|
||||
x+=(w-width)
|
||||
elsif align==1
|
||||
x+=(w/2)-(width/2)
|
||||
end
|
||||
pbDrawShadowText(bitmap,x,y,w,h,t,
|
||||
disabled ? Color.new(26*8,26*8,25*8) : Color.new(12*8,12*8,12*8),
|
||||
Color.new(26*8,26*8,25*8))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class UIControl
|
||||
include ShadowText
|
||||
attr_accessor :bitmap
|
||||
attr_accessor :label
|
||||
attr_accessor :x
|
||||
attr_accessor :y
|
||||
attr_accessor :width
|
||||
attr_accessor :height
|
||||
attr_accessor :changed
|
||||
attr_accessor :parent
|
||||
attr_accessor :disabled
|
||||
|
||||
def text
|
||||
return self.label
|
||||
end
|
||||
|
||||
def text=(value)
|
||||
self.label=value
|
||||
end
|
||||
|
||||
def initialize(label)
|
||||
@label=label
|
||||
@x=0
|
||||
@y=0
|
||||
@width=0
|
||||
@height=0
|
||||
@changed=false
|
||||
@disabled=false
|
||||
@invalid=true
|
||||
end
|
||||
|
||||
def toAbsoluteRect(rc)
|
||||
return Rect.new(
|
||||
rc.x+self.parentX,
|
||||
rc.y+self.parentY,
|
||||
rc.width,rc.height)
|
||||
end
|
||||
|
||||
def parentX
|
||||
return 0 if !self.parent
|
||||
return self.parent.x+self.parent.leftEdge if self.parent.is_a?(SpriteWindow)
|
||||
return self.parent.x+16 if self.parent.is_a?(Window)
|
||||
return self.parent.x
|
||||
end
|
||||
|
||||
def parentY
|
||||
return 0 if !self.parent
|
||||
return self.parent.y+self.parent.topEdge if self.parent.is_a?(SpriteWindow)
|
||||
return self.parent.y+16 if self.parent.is_a?(Window)
|
||||
return self.parent.y
|
||||
end
|
||||
|
||||
def invalid?
|
||||
return @invalid
|
||||
end
|
||||
|
||||
def invalidate # Marks that the control must be redrawn to reflect current logic
|
||||
@invalid=true
|
||||
end
|
||||
|
||||
def update # Updates the logic on the control, invalidating it if necessary
|
||||
end
|
||||
|
||||
def refresh # Redraws the control
|
||||
end
|
||||
|
||||
def validate # Makes the control no longer invalid
|
||||
@invalid=false
|
||||
end
|
||||
|
||||
def repaint # Redraws the control only if it is invalid
|
||||
if self.invalid?
|
||||
self.refresh
|
||||
self.validate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Label < UIControl
|
||||
def text=(value)
|
||||
self.label=value
|
||||
refresh
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
bitmap.fill_rect(self.x,self.y,self.width,self.height,Color.new(0,0,0,0))
|
||||
size=bitmap.text_size(self.label).width
|
||||
shadowtext(bitmap,self.x+4,self.y,size,self.height,self.label,@disabled)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Button < UIControl
|
||||
attr_accessor :label
|
||||
|
||||
def initialize(label)
|
||||
super
|
||||
@captured=false
|
||||
@label=label
|
||||
end
|
||||
|
||||
def update
|
||||
mousepos=Mouse::getMousePos
|
||||
self.changed=false
|
||||
return if !mousepos
|
||||
rect=Rect.new(self.x+1,self.y+1,self.width-2,self.height-2)
|
||||
rect=toAbsoluteRect(rect)
|
||||
if Input.trigger?(Input::MOUSELEFT) &&
|
||||
rect.contains(mousepos[0],mousepos[1]) && !@captured
|
||||
@captured=true
|
||||
self.invalidate
|
||||
end
|
||||
if Input.release?(Input::MOUSELEFT) && @captured
|
||||
self.changed=true if rect.contains(mousepos[0],mousepos[1])
|
||||
@captured=false
|
||||
self.invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=self.width
|
||||
height=self.height
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.fill_rect(x+1,y+1,width-2,height-2,color)
|
||||
ret=Rect.new(x+1,y+1,width-2,height-2)
|
||||
if !@captured
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(0,0,0,0))
|
||||
else
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(120,120,120,80))
|
||||
end
|
||||
size=bitmap.text_size(self.label).width
|
||||
shadowtext(bitmap,x+4,y,size,height,self.label,@disabled)
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Checkbox < Button
|
||||
attr_reader :checked
|
||||
|
||||
def curvalue
|
||||
return self.checked
|
||||
end
|
||||
|
||||
def curvalue=(value)
|
||||
self.checked=value
|
||||
end
|
||||
|
||||
def checked=(value)
|
||||
@checked=value
|
||||
invalidate
|
||||
end
|
||||
|
||||
def initialize(label)
|
||||
super
|
||||
@checked=false
|
||||
end
|
||||
|
||||
def update
|
||||
super
|
||||
if self.changed
|
||||
@checked=!@checked
|
||||
self.invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=[self.width,32].min
|
||||
height=[self.height,32].min
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.fill_rect(x+2,y+2,self.width-4,self.height-4,Color.new(0,0,0,0))
|
||||
bitmap.fill_rect(x+1,y+1,width-2,height-2,color)
|
||||
ret=Rect.new(x+1,y+1,width-2,height-2)
|
||||
if !@captured
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(0,0,0,0))
|
||||
else
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(120,120,120,80))
|
||||
end
|
||||
if self.checked
|
||||
shadowtext(bitmap,x,y,32,32,"X",@disabled,1)
|
||||
end
|
||||
size=bitmap.text_size(self.label).width
|
||||
shadowtext(bitmap,x+36,y,size,height,self.label,@disabled)
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class TextField < UIControl
|
||||
attr_accessor :label
|
||||
attr_reader :text
|
||||
|
||||
def text=(value)
|
||||
@text=value
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def initialize(label,text)
|
||||
super(label)
|
||||
@frame=0
|
||||
@label=label
|
||||
@text=text
|
||||
@cursor=text.scan(/./m).length
|
||||
end
|
||||
|
||||
def insert(ch)
|
||||
chars=self.text.scan(/./m)
|
||||
chars.insert(@cursor,ch)
|
||||
@text=""
|
||||
for ch in chars
|
||||
@text+=ch
|
||||
end
|
||||
@cursor+=1
|
||||
@frame=0
|
||||
self.changed=true
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def delete
|
||||
chars=self.text.scan(/./m)
|
||||
chars.delete_at(@cursor-1)
|
||||
@text=""
|
||||
for ch in chars
|
||||
@text+=ch
|
||||
end
|
||||
@cursor-=1
|
||||
@frame=0
|
||||
self.changed=true
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def update
|
||||
@frame+=1
|
||||
@frame%=20
|
||||
self.changed=false
|
||||
self.invalidate if ((@frame%10)==0)
|
||||
# Moving cursor
|
||||
if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
|
||||
if @cursor > 0
|
||||
@cursor-=1
|
||||
@frame=0
|
||||
self.invalidate
|
||||
end
|
||||
return
|
||||
end
|
||||
if Input.triggerex?(:LEFT) || Input.repeatex?(:RIGHT)
|
||||
if @cursor < self.text.scan(/./m).length
|
||||
@cursor+=1
|
||||
@frame=0
|
||||
self.invalidate
|
||||
end
|
||||
return
|
||||
end
|
||||
# Backspace
|
||||
if Input.triggerex?(:BACKSPACE) || Input.repeatex?(:BACKSPACE) ||
|
||||
Input.triggerex?(:DELETE) || Input.repeatex?(:DELETE)
|
||||
self.delete if @cursor > 0
|
||||
return
|
||||
end
|
||||
# Letter & Number keys
|
||||
Input.gets.each_char{|c|insert(c)}
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=self.width
|
||||
height=self.height
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.font.color=color
|
||||
bitmap.fill_rect(x,y,width,height,Color.new(0,0,0,0))
|
||||
size=bitmap.text_size(self.label).width
|
||||
shadowtext(bitmap,x,y,size,height,self.label)
|
||||
x+=size
|
||||
width-=size
|
||||
bitmap.fill_rect(x+1,y+1,width-2,height-2,color)
|
||||
ret=Rect.new(x+1,y+1,width-2,height-2)
|
||||
if !@captured
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(0,0,0,0))
|
||||
else
|
||||
bitmap.fill_rect(x+2,y+2,width-4,height-4,Color.new(120,120,120,80))
|
||||
end
|
||||
x+=4
|
||||
textscan=self.text.scan(/./m)
|
||||
scanlength=textscan.length
|
||||
@cursor=scanlength if @cursor>scanlength
|
||||
@cursor=0 if @cursor<0
|
||||
startpos=@cursor
|
||||
fromcursor=0
|
||||
while (startpos>0)
|
||||
c=textscan[startpos-1]
|
||||
fromcursor+=bitmap.text_size(c).width
|
||||
break if fromcursor>width-4
|
||||
startpos-=1
|
||||
end
|
||||
for i in startpos...scanlength
|
||||
c=textscan[i]
|
||||
textwidth=bitmap.text_size(c).width
|
||||
next if c=="\n"
|
||||
# Draw text
|
||||
shadowtext(bitmap,x,y, textwidth+4, 32, c)
|
||||
# Draw cursor if necessary
|
||||
if ((@frame/10)&1) == 0 && i==@cursor
|
||||
bitmap.fill_rect(x,y+4,2,24,Color.new(120,120,120))
|
||||
end
|
||||
# Add x to drawn text width
|
||||
x += textwidth
|
||||
end
|
||||
if ((@frame/10)&1) == 0 && textscan.length==@cursor
|
||||
bitmap.fill_rect(x,y+4,2,24,Color.new(120,120,120))
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class Slider < UIControl
|
||||
attr_reader :minvalue
|
||||
attr_reader :maxvalue
|
||||
attr_reader :curvalue
|
||||
attr_accessor :label
|
||||
|
||||
def curvalue=(value)
|
||||
@curvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def minvalue=(value)
|
||||
@minvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def maxvalue=(value)
|
||||
@maxvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def initialize(label,minvalue,maxvalue,curval)
|
||||
super(label)
|
||||
@minvalue=minvalue
|
||||
@maxvalue=maxvalue
|
||||
@curvalue=curval
|
||||
@label=label
|
||||
@leftarrow=Rect.new(0,0,0,0)
|
||||
@rightarrow=Rect.new(0,0,0,0)
|
||||
self.minvalue=minvalue
|
||||
self.maxvalue=maxvalue
|
||||
self.curvalue=curval
|
||||
end
|
||||
|
||||
def update
|
||||
mousepos=Mouse::getMousePos
|
||||
self.changed=false
|
||||
if self.minvalue<self.maxvalue && self.curvalue<self.minvalue
|
||||
self.curvalue=self.minvalue
|
||||
end
|
||||
return false if self.disabled
|
||||
return false if !Input.repeat?(Input::MOUSELEFT)
|
||||
return false if !mousepos
|
||||
left=toAbsoluteRect(@leftarrow)
|
||||
right=toAbsoluteRect(@rightarrow)
|
||||
oldvalue=self.curvalue
|
||||
repeattime = Input.time?(Input::MOUSELEFT) / 1000
|
||||
# Left arrow
|
||||
if left.contains(mousepos[0],mousepos[1])
|
||||
if repeattime>2500
|
||||
self.curvalue-=10
|
||||
self.curvalue=self.curvalue.floor
|
||||
elsif repeattime>1250
|
||||
self.curvalue-=5
|
||||
self.curvalue=self.curvalue.floor
|
||||
else
|
||||
self.curvalue-=1
|
||||
self.curvalue=self.curvalue.floor
|
||||
end
|
||||
self.changed=(self.curvalue!=oldvalue)
|
||||
self.invalidate
|
||||
end
|
||||
#Right arrow
|
||||
if right.contains(mousepos[0],mousepos[1])
|
||||
if repeattime>2500
|
||||
self.curvalue+=10
|
||||
self.curvalue=self.curvalue.floor
|
||||
elsif repeattime>1250
|
||||
self.curvalue+=5
|
||||
self.curvalue=self.curvalue.floor
|
||||
else
|
||||
self.curvalue+=1
|
||||
self.curvalue=self.curvalue.floor
|
||||
end
|
||||
self.changed=(self.curvalue!=oldvalue)
|
||||
self.invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=self.width
|
||||
height=self.height
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.fill_rect(x,y,width,height,Color.new(0,0,0,0))
|
||||
size=bitmap.text_size(self.label).width
|
||||
leftarrows=bitmap.text_size(_INTL(" << "))
|
||||
numbers=bitmap.text_size(" XXXX ").width
|
||||
rightarrows=bitmap.text_size(_INTL(" >> "))
|
||||
bitmap.font.color=color
|
||||
shadowtext(bitmap,x,y,size,height,self.label)
|
||||
x+=size
|
||||
shadowtext(bitmap,x,y,leftarrows.width,height,_INTL(" << "),
|
||||
self.disabled || self.curvalue==self.minvalue)
|
||||
@leftarrow=Rect.new(x,y,leftarrows.width,height)
|
||||
x+=leftarrows.width
|
||||
if !self.disabled
|
||||
bitmap.font.color=color
|
||||
shadowtext(bitmap,x,y,numbers,height," #{self.curvalue} ",false,1)
|
||||
end
|
||||
x+=numbers
|
||||
shadowtext(bitmap,x,y,rightarrows.width,height,_INTL(" >> "),
|
||||
self.disabled || self.curvalue==self.maxvalue)
|
||||
@rightarrow=Rect.new(x,y,rightarrows.width,height)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class OptionalSlider < Slider
|
||||
def initialize(label,minvalue,maxvalue,curvalue)
|
||||
@slider=Slider.new(label,minvalue,maxvalue,curvalue)
|
||||
@checkbox=Checkbox.new("")
|
||||
end
|
||||
|
||||
def curvalue
|
||||
return @checkbox.checked ? @slider.curvalue : nil
|
||||
end
|
||||
|
||||
def curvalue=(value)
|
||||
slider.curvalue=value
|
||||
end
|
||||
|
||||
def checked
|
||||
return @checkbox.checked
|
||||
end
|
||||
|
||||
def checked=(value)
|
||||
@checkbox.checked=value
|
||||
end
|
||||
|
||||
def invalid?
|
||||
return @slider.invalid? || @checkbox.invalid?
|
||||
end
|
||||
|
||||
def invalidate
|
||||
@slider.invalidate
|
||||
@checkbox.invalidate
|
||||
end
|
||||
|
||||
def validate?
|
||||
@slider.validate
|
||||
@checkbox.validate
|
||||
end
|
||||
|
||||
def changed
|
||||
return @slider.changed || @checkbox.changed
|
||||
end
|
||||
|
||||
def minvalue
|
||||
return @slider.minvalue
|
||||
end
|
||||
|
||||
def minvalue=(value)
|
||||
slider.minvalue=value
|
||||
end
|
||||
|
||||
def maxvalue
|
||||
return @slider.maxvalue
|
||||
end
|
||||
|
||||
def maxvalue=(value)
|
||||
slider.maxvalue=value
|
||||
end
|
||||
|
||||
def update
|
||||
updatedefs
|
||||
@slider.update
|
||||
@checkbox.update
|
||||
end
|
||||
|
||||
def refresh
|
||||
updatedefs
|
||||
@slider.refresh
|
||||
@checkbox.refresh
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def updatedefs
|
||||
checkboxwidth=32
|
||||
@slider.bitmap=self.bitmap
|
||||
@slider.parent=self.parent
|
||||
@checkbox.x=self.x
|
||||
@checkbox.y=self.y
|
||||
@checkbox.width=checkboxwidth
|
||||
@checkbox.height=self.height
|
||||
@checkbox.bitmap=self.bitmap
|
||||
@checkbox.parent=self.parent
|
||||
@slider.x=self.x+checkboxwidth+4
|
||||
@slider.y=self.y
|
||||
@slider.width=self.width-checkboxwidth
|
||||
@slider.height=self.height
|
||||
@slider.disabled=!@checkbox.checked
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class ArrayCountSlider < Slider
|
||||
def maxvalue
|
||||
return @array.length-1
|
||||
end
|
||||
|
||||
def initialize(array,label)
|
||||
@array=array
|
||||
super(label,0,canvas.animation.length-1,0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class FrameCountSlider < Slider
|
||||
def maxvalue
|
||||
return @canvas.animation.length
|
||||
end
|
||||
|
||||
def initialize(canvas)
|
||||
@canvas=canvas
|
||||
super(_INTL("Frame:"),1,canvas.animation.length,0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class FrameCountButton < Button
|
||||
def label
|
||||
return _INTL("Total Frames: {1}",@canvas.animation.length)
|
||||
end
|
||||
|
||||
def initialize(canvas)
|
||||
@canvas=canvas
|
||||
super(self.label)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class TextSlider < UIControl
|
||||
attr_reader :minvalue
|
||||
attr_reader :maxvalue
|
||||
attr_reader :curvalue
|
||||
attr_accessor :label
|
||||
attr_accessor :options
|
||||
attr_accessor :maxoptionwidth
|
||||
|
||||
def curvalue=(value)
|
||||
@curvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def minvalue=(value)
|
||||
@minvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def maxvalue=(value)
|
||||
@maxvalue=value
|
||||
@curvalue=self.minvalue if self.minvalue && @curvalue<self.minvalue
|
||||
@curvalue=self.maxvalue if self.maxvalue && @curvalue>self.maxvalue
|
||||
self.invalidate
|
||||
end
|
||||
|
||||
def initialize(label,options,curval)
|
||||
super(label)
|
||||
@label=label
|
||||
@options=options
|
||||
@minvalue=0
|
||||
@maxvalue=options.length-1
|
||||
@curvalue=curval
|
||||
@leftarrow=Rect.new(0,0,0,0)
|
||||
@rightarrow=Rect.new(0,0,0,0)
|
||||
self.minvalue=@minvalue
|
||||
self.maxvalue=@maxvalue
|
||||
self.curvalue=@curvalue
|
||||
end
|
||||
|
||||
def update
|
||||
mousepos=Mouse::getMousePos
|
||||
self.changed=false
|
||||
if self.minvalue<self.maxvalue && self.curvalue<self.minvalue
|
||||
self.curvalue=self.minvalue
|
||||
end
|
||||
return false if self.disabled
|
||||
return false if !Input.repeat?(Input::MOUSELEFT)
|
||||
return false if !mousepos
|
||||
left=toAbsoluteRect(@leftarrow)
|
||||
right=toAbsoluteRect(@rightarrow)
|
||||
oldvalue=self.curvalue
|
||||
repeattime = Input.time?(Input::MOUSELEFT) / 1000
|
||||
# Left arrow
|
||||
if left.contains(mousepos[0],mousepos[1])
|
||||
if repeattime>2500
|
||||
self.curvalue-=10
|
||||
elsif repeattime>1250
|
||||
self.curvalue-=5
|
||||
else
|
||||
self.curvalue-=1
|
||||
end
|
||||
self.changed=(self.curvalue!=oldvalue)
|
||||
self.invalidate
|
||||
end
|
||||
# Right arrow
|
||||
if right.contains(mousepos[0],mousepos[1])
|
||||
if repeattime>2500
|
||||
self.curvalue+=10
|
||||
elsif repeattime>1250
|
||||
self.curvalue+=5
|
||||
else
|
||||
self.curvalue+=1
|
||||
end
|
||||
self.changed=(self.curvalue!=oldvalue)
|
||||
self.invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def refresh
|
||||
bitmap=self.bitmap
|
||||
if @maxoptionwidth==nil
|
||||
for i in 0...@options.length
|
||||
w=self.bitmap.text_size(" "+@options[i]+" ").width
|
||||
@maxoptionwidth=w if !@maxoptionwidth || @maxoptionwidth<w
|
||||
end
|
||||
end
|
||||
x=self.x
|
||||
y=self.y
|
||||
width=self.width
|
||||
height=self.height
|
||||
color=Color.new(120,120,120)
|
||||
bitmap.fill_rect(x,y,width,height,Color.new(0,0,0,0))
|
||||
size=bitmap.text_size(self.label).width
|
||||
leftarrows=bitmap.text_size(_INTL(" << "))
|
||||
rightarrows=bitmap.text_size(_INTL(" >> "))
|
||||
bitmap.font.color=color
|
||||
shadowtext(bitmap,x,y,size,height,self.label)
|
||||
x+=size
|
||||
shadowtext(bitmap,x,y,leftarrows.width,height,_INTL(" << "),
|
||||
self.disabled || self.curvalue==self.minvalue)
|
||||
@leftarrow=Rect.new(x,y,leftarrows.width,height)
|
||||
x+=leftarrows.width
|
||||
if !self.disabled
|
||||
bitmap.font.color=color
|
||||
shadowtext(bitmap,x,y,@maxoptionwidth,height," #{@options[self.curvalue]} ",false,1)
|
||||
end
|
||||
x+=@maxoptionwidth
|
||||
shadowtext(bitmap,x,y,rightarrows.width,height,_INTL(" >> "),
|
||||
self.disabled || self.curvalue==self.maxvalue)
|
||||
@rightarrow=Rect.new(x,y,rightarrows.width,height)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class OptionalTextSlider < TextSlider
|
||||
def initialize(label,options,curval)
|
||||
@slider=TextSlider.new(label,options,curval)
|
||||
@checkbox=Checkbox.new("")
|
||||
end
|
||||
|
||||
def curvalue
|
||||
return @checkbox.checked ? @slider.curvalue : nil
|
||||
end
|
||||
|
||||
def curvalue=(value)
|
||||
slider.curvalue=value
|
||||
end
|
||||
|
||||
def checked
|
||||
return @checkbox.checked
|
||||
end
|
||||
|
||||
def checked=(value)
|
||||
@checkbox.checked=value
|
||||
end
|
||||
|
||||
def invalid?
|
||||
return @slider.invalid? || @checkbox.invalid?
|
||||
end
|
||||
|
||||
def invalidate
|
||||
@slider.invalidate
|
||||
@checkbox.invalidate
|
||||
end
|
||||
|
||||
def validate?
|
||||
@slider.validate
|
||||
@checkbox.validate
|
||||
end
|
||||
|
||||
def changed
|
||||
return @slider.changed || @checkbox.changed
|
||||
end
|
||||
|
||||
def minvalue
|
||||
return @slider.minvalue
|
||||
end
|
||||
|
||||
def minvalue=(value)
|
||||
slider.minvalue=value
|
||||
end
|
||||
|
||||
def maxvalue
|
||||
return @slider.maxvalue
|
||||
end
|
||||
|
||||
def maxvalue=(value)
|
||||
slider.maxvalue=value
|
||||
end
|
||||
|
||||
def update
|
||||
updatedefs
|
||||
@slider.update
|
||||
@checkbox.update
|
||||
end
|
||||
|
||||
def refresh
|
||||
updatedefs
|
||||
@slider.refresh
|
||||
@checkbox.refresh
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def updatedefs
|
||||
checkboxwidth=32
|
||||
@slider.bitmap=self.bitmap
|
||||
@slider.parent=self.parent
|
||||
@checkbox.x=self.x
|
||||
@checkbox.y=self.y
|
||||
@checkbox.width=checkboxwidth
|
||||
@checkbox.height=self.height
|
||||
@checkbox.bitmap=self.bitmap
|
||||
@checkbox.parent=self.parent
|
||||
@slider.x=self.x+checkboxwidth+4
|
||||
@slider.y=self.y
|
||||
@slider.width=self.width-checkboxwidth
|
||||
@slider.height=self.height
|
||||
@slider.disabled=!@checkbox.checked
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class ControlWindow < SpriteWindow_Base
|
||||
attr_reader :controls
|
||||
|
||||
def initialize(x,y,width,height)
|
||||
super(x,y,width,height)
|
||||
self.contents=Bitmap.new(width-32,height-32)
|
||||
pbSetNarrowFont(self.contents)
|
||||
@controls=[]
|
||||
end
|
||||
|
||||
def dispose
|
||||
self.contents.dispose
|
||||
super
|
||||
end
|
||||
|
||||
def refresh
|
||||
for i in 0...@controls.length
|
||||
@controls[i].refresh
|
||||
end
|
||||
end
|
||||
|
||||
def repaint
|
||||
for i in 0...@controls.length
|
||||
@controls[i].repaint
|
||||
end
|
||||
end
|
||||
|
||||
def invalidate
|
||||
for i in 0...@controls.length
|
||||
@controls[i].invalidate
|
||||
end
|
||||
end
|
||||
|
||||
def hittest?(i)
|
||||
mousepos=Mouse::getMousePos
|
||||
return false if !mousepos
|
||||
return false if i<0 || i>=@controls.length
|
||||
rc=Rect.new(
|
||||
@controls[i].parentX,
|
||||
@controls[i].parentY,
|
||||
@controls[i].width,
|
||||
@controls[i].height
|
||||
)
|
||||
return rc.contains(mousepos[0],mousepos[1])
|
||||
end
|
||||
|
||||
def addControl(control)
|
||||
i=@controls.length
|
||||
@controls[i]=control
|
||||
@controls[i].x=0
|
||||
@controls[i].y=i*32
|
||||
@controls[i].width=self.contents.width
|
||||
@controls[i].height=32
|
||||
@controls[i].parent=self
|
||||
@controls[i].bitmap=self.contents
|
||||
@controls[i].invalidate
|
||||
refresh
|
||||
return i
|
||||
end
|
||||
|
||||
def addLabel(label)
|
||||
return addControl(Label.new(label))
|
||||
end
|
||||
|
||||
def addButton(label)
|
||||
return addControl(Button.new(label))
|
||||
end
|
||||
|
||||
def addSlider(label,minvalue,maxvalue,curvalue)
|
||||
return addControl(Slider.new(label,minvalue,maxvalue,curvalue))
|
||||
end
|
||||
|
||||
def addOptionalSlider(label,minvalue,maxvalue,curvalue)
|
||||
return addControl(OptionalSlider.new(label,minvalue,maxvalue,curvalue))
|
||||
end
|
||||
|
||||
def addTextSlider(label,options,curvalue)
|
||||
return addControl(TextSlider.new(label,options,curvalue))
|
||||
end
|
||||
|
||||
def addOptionalTextSlider(label,options,curvalue)
|
||||
return addControl(OptionalTextSlider.new(label,options,curvalue))
|
||||
end
|
||||
|
||||
def addCheckbox(label)
|
||||
return addControl(Checkbox.new(label))
|
||||
end
|
||||
|
||||
def addSpace
|
||||
return addControl(UIControl.new(""))
|
||||
end
|
||||
|
||||
def update
|
||||
super
|
||||
for i in 0...@controls.length
|
||||
@controls[i].update
|
||||
end
|
||||
repaint
|
||||
end
|
||||
|
||||
def changed?(i)
|
||||
return false if i<0
|
||||
return @controls[i].changed
|
||||
end
|
||||
|
||||
def value(i)
|
||||
return false if i<0
|
||||
return @controls[i].curvalue
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,440 @@
|
||||
################################################################################
|
||||
# Paths and interpolation
|
||||
################################################################################
|
||||
class ControlPointSprite < SpriteWrapper
|
||||
attr_accessor :dragging
|
||||
|
||||
def initialize(red,viewport=nil)
|
||||
super(viewport)
|
||||
self.bitmap=Bitmap.new(6,6)
|
||||
self.bitmap.fill_rect(0,0,6,1,Color.new(0,0,0))
|
||||
self.bitmap.fill_rect(0,0,1,6,Color.new(0,0,0))
|
||||
self.bitmap.fill_rect(0,5,6,1,Color.new(0,0,0))
|
||||
self.bitmap.fill_rect(5,0,1,6,Color.new(0,0,0))
|
||||
color=(red) ? Color.new(255,0,0) : Color.new(0,0,0)
|
||||
self.bitmap.fill_rect(2,2,2,2,color)
|
||||
self.x=-6
|
||||
self.y=-6
|
||||
self.visible=false
|
||||
@dragging=false
|
||||
end
|
||||
|
||||
def mouseover
|
||||
if Input.time?(Input::MOUSELEFT)==0 || !@dragging
|
||||
@dragging=false
|
||||
return
|
||||
end
|
||||
mouse=Mouse::getMousePos(true)
|
||||
return if !mouse
|
||||
self.x=[[mouse[0],0].max,512].min
|
||||
self.y=[[mouse[1],0].max,384].min
|
||||
end
|
||||
|
||||
def hittest?
|
||||
return true if !self.visible
|
||||
mouse=Mouse::getMousePos(true)
|
||||
return false if !mouse
|
||||
return mouse[0]>=self.x && mouse[0]<self.x+6 &&
|
||||
mouse[1]>=self.y && mouse[1]<self.y+6
|
||||
end
|
||||
|
||||
def inspect
|
||||
return "[#{self.x},#{self.y}]"
|
||||
end
|
||||
|
||||
def dispose
|
||||
self.bitmap.dispose
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PointSprite < SpriteWrapper
|
||||
def initialize(x,y,viewport=nil)
|
||||
super(viewport)
|
||||
self.bitmap=Bitmap.new(2,2)
|
||||
self.bitmap.fill_rect(0,0,2,2,Color.new(0,0,0))
|
||||
self.x=x
|
||||
self.y=y
|
||||
end
|
||||
|
||||
def dispose
|
||||
self.bitmap.dispose
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
class PointPath
|
||||
include Enumerable
|
||||
|
||||
def initialize
|
||||
@points=[]
|
||||
@distances=[]
|
||||
@totaldist=0
|
||||
end
|
||||
|
||||
def [](x)
|
||||
return @points[x].clone
|
||||
end
|
||||
|
||||
def each
|
||||
@points.each { |o| yield o.clone }
|
||||
end
|
||||
|
||||
def size
|
||||
return @points.size
|
||||
end
|
||||
|
||||
def length
|
||||
return @points.length
|
||||
end
|
||||
|
||||
def totalDistance
|
||||
return @totaldist
|
||||
end
|
||||
|
||||
def inspect
|
||||
p=[]
|
||||
for point in @points
|
||||
p.push([point[0].to_i,point[1].to_i])
|
||||
end
|
||||
return p.inspect
|
||||
end
|
||||
|
||||
def isEndPoint?(x,y)
|
||||
return false if @points.length==0
|
||||
index=@points.length-1
|
||||
return @points[index][0]==x &&
|
||||
@points[index][1]==y
|
||||
end
|
||||
|
||||
def addPoint(x,y)
|
||||
@points.push([x,y])
|
||||
if @points.length>1
|
||||
len=@points.length
|
||||
dx=@points[len-2][0]-@points[len-1][0]
|
||||
dy=@points[len-2][1]-@points[len-1][1]
|
||||
dist=Math.sqrt(dx*dx+dy*dy)
|
||||
@distances.push(dist)
|
||||
@totaldist+=dist
|
||||
end
|
||||
end
|
||||
|
||||
def clear
|
||||
@points.clear
|
||||
@distances.clear
|
||||
@totaldist=0
|
||||
end
|
||||
|
||||
def smoothPointPath(frames,roundValues=false)
|
||||
if frames<0
|
||||
raise ArgumentError.new("frames out of range: #{frames}")
|
||||
end
|
||||
ret=PointPath.new
|
||||
if @points.length==0
|
||||
return ret
|
||||
end
|
||||
step=1.0/frames
|
||||
t=0.0
|
||||
(frames+2).times do
|
||||
point=pointOnPath(t)
|
||||
if roundValues
|
||||
ret.addPoint(point[0].round,point[1].round)
|
||||
else
|
||||
ret.addPoint(point[0],point[1])
|
||||
end
|
||||
t+=step
|
||||
t=[1.0,t].min
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
def pointOnPath(t)
|
||||
if t<0 || t>1
|
||||
raise ArgumentError.new("t out of range for pointOnPath: #{t}")
|
||||
end
|
||||
return nil if @points.length==0
|
||||
ret=@points[@points.length-1].clone
|
||||
if @points.length==1
|
||||
return ret
|
||||
end
|
||||
curdist=0
|
||||
distForT=@totaldist*t
|
||||
i=0
|
||||
for dist in @distances
|
||||
curdist+=dist
|
||||
if dist>0.0
|
||||
if curdist>=distForT
|
||||
distT=1.0-((curdist-distForT)/dist)
|
||||
dx=@points[i+1][0]-@points[i][0]
|
||||
dy=@points[i+1][1]-@points[i][1]
|
||||
ret=[@points[i][0]+dx*distT,
|
||||
@points[i][1]+dy*distT]
|
||||
break
|
||||
end
|
||||
end
|
||||
i+=1
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def catmullRom(p1,p2,p3,p4,t)
|
||||
# p1=prevPoint, p2=startPoint, p3=endPoint, p4=nextPoint, t is from 0 through 1
|
||||
t2=t*t
|
||||
t3=t2*t
|
||||
return 0.5*(2*p2+t*(p3-p1) +
|
||||
t2*(2*p1-5*p2+4*p3-p4)+
|
||||
t3*(p4-3*p3+3*p2-p1))
|
||||
end
|
||||
|
||||
def getCatmullRomPoint(src,t)
|
||||
x=0,y=0
|
||||
t*=3.0
|
||||
if t<1.0
|
||||
x=catmullRom(src[0].x,src[0].x,src[1].x,src[2].x,t)
|
||||
y=catmullRom(src[0].y,src[0].y,src[1].y,src[2].y,t)
|
||||
elsif t<2.0
|
||||
t-=1.0
|
||||
x=catmullRom(src[0].x,src[1].x,src[2].x,src[3].x,t)
|
||||
y=catmullRom(src[0].y,src[1].y,src[2].y,src[3].y,t)
|
||||
else
|
||||
t-=2.0
|
||||
x=catmullRom(src[1].x,src[2].x,src[3].x,src[3].x,t)
|
||||
y=catmullRom(src[1].y,src[2].y,src[3].y,src[3].y,t)
|
||||
end
|
||||
return [x,y]
|
||||
end
|
||||
|
||||
def getCurvePoint(src,t)
|
||||
return getCatmullRomPoint(src,t)
|
||||
end
|
||||
|
||||
def curveToPointPath(curve,numpoints)
|
||||
if numpoints<2
|
||||
return nil
|
||||
end
|
||||
path=PointPath.new
|
||||
step=1.0/(numpoints-1)
|
||||
t=0.0
|
||||
numpoints.times do
|
||||
point=getCurvePoint(curve,t)
|
||||
path.addPoint(point[0],point[1])
|
||||
t+=step
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
def pbDefinePath(canvas)
|
||||
sliderwin2=ControlWindow.new(0,0,320,320)
|
||||
sliderwin2.viewport=canvas.viewport
|
||||
sliderwin2.addSlider(_INTL("Number of frames:"),2,500,20)
|
||||
sliderwin2.opacity=200
|
||||
defcurvebutton=sliderwin2.addButton(_INTL("Define Smooth Curve"))
|
||||
defpathbutton=sliderwin2.addButton(_INTL("Define Freehand Path"))
|
||||
okbutton=sliderwin2.addButton(_INTL("OK"))
|
||||
cancelbutton=sliderwin2.addButton(_INTL("Cancel"))
|
||||
points=[]
|
||||
path=nil
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
sliderwin2.update
|
||||
if sliderwin2.changed?(0) # Number of frames
|
||||
if path
|
||||
path=path.smoothPointPath(sliderwin2.value(0),false)
|
||||
i=0
|
||||
for point in path
|
||||
if i<points.length
|
||||
points[i].x=point[0]
|
||||
points[i].y=point[1]
|
||||
else
|
||||
points.push(PointSprite.new(point[0],point[1],canvas.viewport))
|
||||
end
|
||||
i+=1
|
||||
end
|
||||
for j in i...points.length
|
||||
points[j].dispose
|
||||
points[j]=nil
|
||||
end
|
||||
points.compact!
|
||||
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
|
||||
end
|
||||
elsif sliderwin2.changed?(defcurvebutton)
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
30.times do
|
||||
point=PointSprite.new(0,0,canvas.viewport)
|
||||
point.visible=false
|
||||
points.push(point)
|
||||
end
|
||||
curve=[
|
||||
ControlPointSprite.new(true,canvas.viewport),
|
||||
ControlPointSprite.new(false,canvas.viewport),
|
||||
ControlPointSprite.new(false,canvas.viewport),
|
||||
ControlPointSprite.new(true,canvas.viewport)
|
||||
]
|
||||
showline=false
|
||||
sliderwin2.visible=false
|
||||
# This window displays the mouse's current position
|
||||
window=Window_UnformattedTextPokemon.newWithSize("",
|
||||
0, 320 - 64, 128, 64, canvas.viewport)
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.trigger?(Input::BACK)
|
||||
break
|
||||
end
|
||||
if Input.trigger?(Input::MOUSELEFT)
|
||||
for j in 0...4
|
||||
next if !curve[j].hittest?
|
||||
if j==1||j==2
|
||||
next if !curve[0].visible || !curve[3].visible
|
||||
end
|
||||
curve[j].visible=true
|
||||
for k in 0...4
|
||||
curve[k].dragging=(k==j)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
for j in 0...4
|
||||
curve[j].mouseover
|
||||
end
|
||||
mousepos = Mouse::getMousePos(true)
|
||||
newtext = (mousepos) ? sprintf("(%d,%d)",mousepos[0],mousepos[1]) : "(??,??)"
|
||||
if window.text!=newtext
|
||||
window.text=newtext
|
||||
end
|
||||
if curve[0].visible && curve[3].visible &&
|
||||
!curve[0].dragging && !curve[3].dragging
|
||||
for point in points
|
||||
point.visible=true
|
||||
end
|
||||
if !showline
|
||||
curve[1].visible=true
|
||||
curve[2].visible=true
|
||||
curve[1].x=curve[0].x+0.3333*(curve[3].x-curve[0].x)
|
||||
curve[1].y=curve[0].y+0.3333*(curve[3].y-curve[0].y)
|
||||
curve[2].x=curve[0].x+0.6666*(curve[3].x-curve[0].x)
|
||||
curve[2].y=curve[0].y+0.6666*(curve[3].y-curve[0].y)
|
||||
end
|
||||
showline=true
|
||||
end
|
||||
if showline
|
||||
step=1.0/(points.length-1)
|
||||
t=0.0
|
||||
for i in 0...points.length
|
||||
point=getCurvePoint(curve,t)
|
||||
points[i].x=point[0]
|
||||
points[i].y=point[1]
|
||||
t+=step
|
||||
end
|
||||
end
|
||||
end
|
||||
window.dispose
|
||||
# dispose temporary path
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
if showline
|
||||
path=curveToPointPath(curve,sliderwin2.value(0))
|
||||
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
|
||||
for point in path
|
||||
points.push(PointSprite.new(point[0],point[1],canvas.viewport))
|
||||
end
|
||||
end
|
||||
for point in curve
|
||||
point.dispose
|
||||
end
|
||||
sliderwin2.visible=true
|
||||
next
|
||||
elsif sliderwin2.changed?(defpathbutton)
|
||||
canceled=false
|
||||
pointpath=PointPath.new
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
window=Window_UnformattedTextPokemon.newWithSize("",
|
||||
0, 320-64, 128, 64, canvas.viewport)
|
||||
sliderwin2.visible=false
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.triggerex?(:ESCAPE)
|
||||
canceled=true
|
||||
break
|
||||
end
|
||||
if Input.trigger?(Input::MOUSELEFT)
|
||||
break
|
||||
end
|
||||
mousepos=Mouse::getMousePos(true)
|
||||
window.text = (mousepos) ? sprintf("(%d,%d)",mousepos[0],mousepos[1]) : "(??,??)"
|
||||
end
|
||||
while !canceled
|
||||
mousepos=Mouse::getMousePos(true)
|
||||
if mousepos && !pointpath.isEndPoint?(mousepos[0],mousepos[1])
|
||||
pointpath.addPoint(mousepos[0],mousepos[1])
|
||||
points.push(PointSprite.new(mousepos[0],mousepos[1],canvas.viewport))
|
||||
end
|
||||
window.text = (mousepos) ? sprintf("(%d,%d)",mousepos[0],mousepos[1]) : "(??,??)"
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.triggerex?(:ESCAPE) || Input.time?(Input::MOUSELEFT)==0
|
||||
break
|
||||
end
|
||||
end
|
||||
window.dispose
|
||||
# dispose temporary path
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
# generate smooth path from temporary path
|
||||
path=pointpath.smoothPointPath(sliderwin2.value(0),true)
|
||||
# redraw path from smooth path
|
||||
for point in path
|
||||
points.push(PointSprite.new(point[0],point[1],canvas.viewport))
|
||||
end
|
||||
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
|
||||
sliderwin2.visible=true
|
||||
next
|
||||
elsif sliderwin2.changed?(okbutton) && path
|
||||
# File.open("pointpath.txt","wb") { |f| f.write(path.inspect) }
|
||||
neededsize=canvas.currentframe+sliderwin2.value(0)
|
||||
if neededsize>canvas.animation.length
|
||||
canvas.animation.resize(neededsize)
|
||||
end
|
||||
thiscel=canvas.currentCel
|
||||
celnumber=canvas.currentcel
|
||||
for i in canvas.currentframe...neededsize
|
||||
cel=canvas.animation[i][celnumber]
|
||||
if !canvas.animation[i][celnumber]
|
||||
cel=pbCreateCel(0,0,thiscel[AnimFrame::PATTERN],canvas.animation.position)
|
||||
canvas.animation[i][celnumber]=cel
|
||||
end
|
||||
cel[AnimFrame::X]=path[i-canvas.currentframe][0]
|
||||
cel[AnimFrame::Y]=path[i-canvas.currentframe][1]
|
||||
end
|
||||
break
|
||||
elsif sliderwin2.changed?(cancelbutton) || Input.trigger?(Input::BACK)
|
||||
break
|
||||
end
|
||||
end
|
||||
# dispose all points
|
||||
for point in points
|
||||
point.dispose
|
||||
end
|
||||
points.clear
|
||||
sliderwin2.dispose
|
||||
return
|
||||
end
|
||||
@@ -0,0 +1,144 @@
|
||||
################################################################################
|
||||
# Importing and exporting
|
||||
################################################################################
|
||||
def pbRgssChdir(dir)
|
||||
RTP.eachPathFor(dir) { |path| Dir.chdir(path) { yield } }
|
||||
end
|
||||
|
||||
def tryLoadData(file)
|
||||
begin
|
||||
return load_data(file)
|
||||
rescue
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def dumpBase64Anim(s)
|
||||
return [Zlib::Deflate.deflate(Marshal.dump(s))].pack("m").gsub(/\n/,"\r\n")
|
||||
end
|
||||
|
||||
def loadBase64Anim(s)
|
||||
return Marshal.restore(Zlib::Inflate.inflate(s.unpack("m")[0]))
|
||||
end
|
||||
|
||||
def pbExportAnim(animations)
|
||||
filename=pbMessageFreeText(_INTL("Enter a filename."),"",false,32)
|
||||
if filename!=""
|
||||
begin
|
||||
filename+=".anm"
|
||||
File.open(filename,"wb") { |f|
|
||||
f.write(dumpBase64Anim(animations[animations.selected]))
|
||||
}
|
||||
failed=false
|
||||
rescue
|
||||
pbMessage(_INTL("Couldn't save the animation to {1}.",filename))
|
||||
failed=true
|
||||
end
|
||||
if !failed
|
||||
pbMessage(_INTL("Animation was saved to {1} in the game folder.",filename))
|
||||
pbMessage(_INTL("It's a text file, so it can be transferred to others easily."))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbImportAnim(animations,canvas,animwin)
|
||||
animfiles=[]
|
||||
pbRgssChdir(".") {
|
||||
animfiles.concat(Dir.glob("*.anm"))
|
||||
}
|
||||
cmdwin=pbListWindow(animfiles,320)
|
||||
cmdwin.opacity=200
|
||||
cmdwin.height=480
|
||||
cmdwin.viewport=canvas.viewport
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cmdwin.update
|
||||
if Input.trigger?(Input::USE) && animfiles.length>0
|
||||
begin
|
||||
textdata=loadBase64Anim(IO.read(animfiles[cmdwin.index]))
|
||||
throw "Bad data" if !textdata.is_a?(PBAnimation)
|
||||
textdata.id=-1 # this is not an RPG Maker XP animation
|
||||
pbConvertAnimToNewFormat(textdata)
|
||||
animations[animations.selected]=textdata
|
||||
rescue
|
||||
pbMessage(_INTL("The animation is invalid or could not be loaded."))
|
||||
next
|
||||
end
|
||||
graphic=animations[animations.selected].graphic
|
||||
graphic="Graphics/Animations/#{graphic}"
|
||||
if graphic && graphic!="" && !FileTest.image_exist?(graphic)
|
||||
pbMessage(_INTL("The animation file {1} was not found. The animation will load anyway.",graphic))
|
||||
end
|
||||
canvas.loadAnimation(animations[animations.selected])
|
||||
animwin.animbitmap=canvas.animbitmap
|
||||
break
|
||||
end
|
||||
if Input.trigger?(Input::BACK)
|
||||
break
|
||||
end
|
||||
end
|
||||
cmdwin.dispose
|
||||
return
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# Format conversion
|
||||
################################################################################
|
||||
def pbConvertAnimToNewFormat(textdata)
|
||||
needconverting=false
|
||||
for i in 0...textdata.length
|
||||
next if !textdata[i]
|
||||
for j in 0...PBAnimation::MAX_SPRITES
|
||||
next if !textdata[i][j]
|
||||
needconverting=true if textdata[i][j][AnimFrame::FOCUS]==nil
|
||||
break if needconverting
|
||||
end
|
||||
break if needconverting
|
||||
end
|
||||
if needconverting
|
||||
for i in 0...textdata.length
|
||||
next if !textdata[i]
|
||||
for j in 0...PBAnimation::MAX_SPRITES
|
||||
next if !textdata[i][j]
|
||||
textdata[i][j][AnimFrame::PRIORITY]=1 if textdata[i][j][AnimFrame::PRIORITY]==nil
|
||||
if j==0 # User battler
|
||||
textdata[i][j][AnimFrame::FOCUS]=2
|
||||
textdata[i][j][AnimFrame::X]=PokeBattle_SceneConstants::FOCUSUSER_X
|
||||
textdata[i][j][AnimFrame::Y]=PokeBattle_SceneConstants::FOCUSUSER_Y
|
||||
elsif j==1 # Target battler
|
||||
textdata[i][j][AnimFrame::FOCUS]=1
|
||||
textdata[i][j][AnimFrame::X]=PokeBattle_SceneConstants::FOCUSTARGET_X
|
||||
textdata[i][j][AnimFrame::Y]=PokeBattle_SceneConstants::FOCUSTARGET_Y
|
||||
else
|
||||
textdata[i][j][AnimFrame::FOCUS]=(textdata.position || 4)
|
||||
if textdata.position==1
|
||||
textdata[i][j][AnimFrame::X]+=PokeBattle_SceneConstants::FOCUSTARGET_X
|
||||
textdata[i][j][AnimFrame::Y]+=PokeBattle_SceneConstants::FOCUSTARGET_Y-2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return needconverting
|
||||
end
|
||||
|
||||
def pbConvertAnimsToNewFormat
|
||||
pbMessage(_INTL("Will convert animations now."))
|
||||
count=0
|
||||
animations=pbLoadBattleAnimations
|
||||
if !animations || !animations[0]
|
||||
pbMessage(_INTL("No animations exist."))
|
||||
return
|
||||
end
|
||||
for k in 0...animations.length
|
||||
next if !animations[k]
|
||||
ret=pbConvertAnimToNewFormat(animations[k])
|
||||
count+=1 if ret
|
||||
end
|
||||
if count>0
|
||||
save_data(animations,"Data/PkmnAnimations.rxdata")
|
||||
$PokemonTemp.battleAnims = nil
|
||||
end
|
||||
pbMessage(_INTL("{1} animations converted to new format.",count))
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
1535
Data/Scripts/020_Debug/002_Editor_DataTypes.rb
Normal file
1535
Data/Scripts/020_Debug/002_Editor_DataTypes.rb
Normal file
File diff suppressed because it is too large
Load Diff
185
Data/Scripts/020_Debug/003_Debug menus/001_Debug_Menus.rb
Normal file
185
Data/Scripts/020_Debug/003_Debug menus/001_Debug_Menus.rb
Normal file
@@ -0,0 +1,185 @@
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class CommandMenuList
|
||||
attr_accessor :currentList
|
||||
|
||||
def initialize
|
||||
@commands = []
|
||||
@currentList = "main"
|
||||
end
|
||||
|
||||
def add(option, hash)
|
||||
@commands.push([option, hash["parent"], hash["name"], hash["description"]])
|
||||
end
|
||||
|
||||
def list
|
||||
ret = []
|
||||
@commands.each { |cmd| ret.push(cmd[2]) if cmd[1] == @currentList }
|
||||
return ret
|
||||
end
|
||||
|
||||
def getCommand(index)
|
||||
count = 0
|
||||
@commands.each do |cmd|
|
||||
next if cmd[1] != @currentList
|
||||
return cmd[0] if count == index
|
||||
count += 1
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def getDesc(index)
|
||||
count = 0
|
||||
@commands.each do |cmd|
|
||||
next if cmd[1] != @currentList
|
||||
return cmd[3] if count == index && cmd[3]
|
||||
break if count == index
|
||||
count += 1
|
||||
end
|
||||
return "<No description available>"
|
||||
end
|
||||
|
||||
def hasSubMenu?(check_cmd)
|
||||
@commands.each { |cmd| return true if cmd[1] == check_cmd }
|
||||
return false
|
||||
end
|
||||
|
||||
def getParent
|
||||
ret = nil
|
||||
@commands.each do |cmd|
|
||||
next if cmd[0] != @currentList
|
||||
ret = cmd[1]
|
||||
break
|
||||
end
|
||||
return nil if !ret
|
||||
count = 0
|
||||
@commands.each do |cmd|
|
||||
next if cmd[1] != ret
|
||||
return [ret, count] if cmd[0] == @currentList
|
||||
count += 1
|
||||
end
|
||||
return [ret, 0]
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
def pbDebugMenu(show_all = true)
|
||||
commands = CommandMenuList.new
|
||||
DebugMenuCommands.each do |option, hash|
|
||||
commands.add(option, hash) if show_all || hash["always_show"]
|
||||
end
|
||||
viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
viewport.z = 99999
|
||||
sprites = {}
|
||||
sprites["textbox"] = pbCreateMessageWindow
|
||||
sprites["textbox"].letterbyletter = false
|
||||
sprites["cmdwindow"] = Window_CommandPokemonEx.new(commands.list)
|
||||
cmdwindow = sprites["cmdwindow"]
|
||||
cmdwindow.x = 0
|
||||
cmdwindow.y = 0
|
||||
cmdwindow.width = Graphics.width
|
||||
cmdwindow.height = Graphics.height - sprites["textbox"].height
|
||||
cmdwindow.viewport = viewport
|
||||
cmdwindow.visible = true
|
||||
sprites["textbox"].text = commands.getDesc(cmdwindow.index)
|
||||
pbFadeInAndShow(sprites)
|
||||
ret = -1
|
||||
refresh = true
|
||||
loop do
|
||||
loop do
|
||||
oldindex = cmdwindow.index
|
||||
cmdwindow.update
|
||||
if refresh || cmdwindow.index != oldindex
|
||||
sprites["textbox"].text = commands.getDesc(cmdwindow.index)
|
||||
refresh = false
|
||||
end
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.trigger?(Input::BACK)
|
||||
parent = commands.getParent
|
||||
if parent
|
||||
pbPlayCancelSE
|
||||
commands.currentList = parent[0]
|
||||
cmdwindow.commands = commands.list
|
||||
cmdwindow.index = parent[1]
|
||||
refresh = true
|
||||
else
|
||||
ret = -1
|
||||
break
|
||||
end
|
||||
elsif Input.trigger?(Input::USE)
|
||||
ret = cmdwindow.index
|
||||
break
|
||||
end
|
||||
end
|
||||
break if ret < 0
|
||||
cmd = commands.getCommand(ret)
|
||||
if commands.hasSubMenu?(cmd)
|
||||
pbPlayDecisionSE
|
||||
commands.currentList = cmd
|
||||
cmdwindow.commands = commands.list
|
||||
cmdwindow.index = 0
|
||||
refresh = true
|
||||
elsif cmd == "warp"
|
||||
return if DebugMenuCommands.call("effect", cmd, sprites, viewport)
|
||||
else
|
||||
DebugMenuCommands.call("effect", cmd)
|
||||
end
|
||||
end
|
||||
pbPlayCloseMenuSE
|
||||
pbFadeOutAndHide(sprites)
|
||||
pbDisposeMessageWindow(sprites["textbox"])
|
||||
pbDisposeSpriteHash(sprites)
|
||||
viewport.dispose
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
module PokemonDebugMixin
|
||||
def pbPokemonDebug(pkmn, pkmnid, heldpoke = nil, settingUpBattle = false)
|
||||
command = 0
|
||||
commands = CommandMenuList.new
|
||||
PokemonDebugMenuCommands.each do |option, hash|
|
||||
commands.add(option, hash) if !settingUpBattle || hash["always_show"]
|
||||
end
|
||||
loop do
|
||||
command = pbShowCommands(_INTL("Do what with {1}?", pkmn.name), commands.list, command)
|
||||
if command < 0
|
||||
parent = commands.getParent
|
||||
if parent
|
||||
commands.currentList = parent[0]
|
||||
command = parent[1]
|
||||
else
|
||||
break
|
||||
end
|
||||
else
|
||||
cmd = commands.getCommand(command)
|
||||
if commands.hasSubMenu?(cmd)
|
||||
commands.currentList = cmd
|
||||
command = 0
|
||||
elsif PokemonDebugMenuCommands.call("effect", cmd, pkmn, pkmnid, heldpoke, settingUpBattle, self)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class PokemonPartyScreen
|
||||
include PokemonDebugMixin
|
||||
end
|
||||
|
||||
class PokemonStorageScreen
|
||||
include PokemonDebugMixin
|
||||
end
|
||||
|
||||
class PokemonDebugPartyScreen
|
||||
include PokemonDebugMixin
|
||||
end
|
||||
1053
Data/Scripts/020_Debug/003_Debug menus/002_Debug_MenuCommands.rb
Normal file
1053
Data/Scripts/020_Debug/003_Debug menus/002_Debug_MenuCommands.rb
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,904 @@
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
def pbDefaultMap
|
||||
return $game_map.map_id if $game_map
|
||||
return $data_system.edit_map_id if $data_system
|
||||
return 0
|
||||
end
|
||||
|
||||
def pbWarpToMapId
|
||||
params = ChooseNumberParams.new
|
||||
params.setRange(1,999) #pbMapTree().length)
|
||||
params.setDefaultValue($game_map.map_id)
|
||||
map_id = pbMessageChooseNumber("map id?",params)
|
||||
return [map_id,0,0]
|
||||
end
|
||||
|
||||
def pbWarpToMapFly
|
||||
return pbBetterRegionMap(-1, true, true,false,nil,true)
|
||||
end
|
||||
|
||||
def pbWarpToMap
|
||||
choice = pbMessage("type", [_INTL("List"),_INTL("Map id"), _INTL("Town map")], 0)
|
||||
if choice == 0
|
||||
map = pbWarpToMapList
|
||||
elsif choice == 1
|
||||
map = pbWarpToMapId
|
||||
elsif choice == 2
|
||||
map = pbWarpToMapFly
|
||||
end
|
||||
return map
|
||||
end
|
||||
|
||||
def pbWarpToMapList
|
||||
mapid = pbListScreen(_INTL("WARP TO MAP"),MapLister.new(pbDefaultMap))
|
||||
if mapid>0
|
||||
map = Game_Map.new
|
||||
map.setup(mapid)
|
||||
success = false
|
||||
x = 0
|
||||
y = 0
|
||||
100.times do
|
||||
x = rand(map.width)
|
||||
y = rand(map.height)
|
||||
next if !map.passableStrict?(x,y,0,$game_player)
|
||||
blocked = false
|
||||
for event in map.events.values
|
||||
if event.at_coordinate?(x, y) && !event.through
|
||||
blocked = true if event.character_name != ""
|
||||
end
|
||||
end
|
||||
next if blocked
|
||||
success = true
|
||||
break
|
||||
end
|
||||
if !success
|
||||
x = rand(map.width)
|
||||
y = rand(map.height)
|
||||
end
|
||||
return [mapid,x,y]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Debug Variables screen
|
||||
#===============================================================================
|
||||
class SpriteWindow_DebugVariables < Window_DrawableCommand
|
||||
attr_reader :mode
|
||||
|
||||
def initialize(viewport)
|
||||
super(0,0,Graphics.width,Graphics.height,viewport)
|
||||
end
|
||||
|
||||
def itemCount
|
||||
return (@mode==0) ? $data_system.switches.size-1 : $data_system.variables.size-1
|
||||
end
|
||||
|
||||
def mode=(mode)
|
||||
@mode = mode
|
||||
refresh
|
||||
end
|
||||
|
||||
def shadowtext(x,y,w,h,t,align=0,colors=0)
|
||||
width = self.contents.text_size(t).width
|
||||
if align==1 # Right aligned
|
||||
x += (w-width)
|
||||
elsif align==2 # Centre aligned
|
||||
x += (w/2)-(width/2)
|
||||
end
|
||||
base = Color.new(12*8,12*8,12*8)
|
||||
if colors==1 # Red
|
||||
base = Color.new(168,48,56)
|
||||
elsif colors==2 # Green
|
||||
base = Color.new(0,144,0)
|
||||
end
|
||||
pbDrawShadowText(self.contents,x,y,[width,w].max,h,t,base,Color.new(26*8,26*8,25*8))
|
||||
end
|
||||
|
||||
def drawItem(index,_count,rect)
|
||||
pbSetNarrowFont(self.contents)
|
||||
colors = 0; codeswitch = false
|
||||
if @mode==0
|
||||
name = $data_system.switches[index+1]
|
||||
codeswitch = (name[/^s\:/])
|
||||
val = (codeswitch) ? (eval($~.post_match) rescue nil) : $game_switches[index+1]
|
||||
if val.nil?
|
||||
status = "[-]"
|
||||
colors = 0
|
||||
codeswitch = true
|
||||
elsif val # true
|
||||
status = "[ON]"
|
||||
colors = 2
|
||||
else # false
|
||||
status = "[OFF]"
|
||||
colors = 1
|
||||
end
|
||||
else
|
||||
name = $data_system.variables[index+1]
|
||||
status = $game_variables[index+1].to_s
|
||||
status = "\"__\"" if nil_or_empty?(status)
|
||||
end
|
||||
name = '' if name==nil
|
||||
id_text = sprintf("%04d:",index+1)
|
||||
rect = drawCursor(index,rect)
|
||||
totalWidth = rect.width
|
||||
idWidth = totalWidth*15/100
|
||||
nameWidth = totalWidth*65/100
|
||||
statusWidth = totalWidth*20/100
|
||||
self.shadowtext(rect.x,rect.y,idWidth,rect.height,id_text)
|
||||
self.shadowtext(rect.x+idWidth,rect.y,nameWidth,rect.height,name,0,(codeswitch) ? 1 : 0)
|
||||
self.shadowtext(rect.x+idWidth+nameWidth,rect.y,statusWidth,rect.height,status,1,colors)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def pbDebugSetVariable(id,diff)
|
||||
$game_variables[id] = 0 if $game_variables[id]==nil
|
||||
if $game_variables[id].is_a?(Numeric)
|
||||
pbPlayCursorSE
|
||||
$game_variables[id] = [$game_variables[id]+diff,99999999].min
|
||||
$game_variables[id] = [$game_variables[id],-99999999].max
|
||||
$game_map.need_refresh = true
|
||||
end
|
||||
end
|
||||
|
||||
def pbDebugVariableScreen(id)
|
||||
if $game_variables[id].is_a?(Numeric)
|
||||
value = $game_variables[id]
|
||||
params = ChooseNumberParams.new
|
||||
params.setDefaultValue(value)
|
||||
params.setMaxDigits(8)
|
||||
params.setNegativesAllowed(true)
|
||||
value = pbMessageChooseNumber(_INTL("Set variable {1}.",id),params)
|
||||
$game_variables[id] = [value,99999999].min
|
||||
$game_variables[id] = [$game_variables[id],-99999999].max
|
||||
$game_map.need_refresh = true
|
||||
elsif $game_variables[id].is_a?(String)
|
||||
value = pbMessageFreeText(_INTL("Set variable {1}.",id),
|
||||
$game_variables[id],false,250,Graphics.width)
|
||||
$game_variables[id] = value
|
||||
$game_map.need_refresh = true
|
||||
end
|
||||
end
|
||||
|
||||
def pbDebugVariables(mode)
|
||||
viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
|
||||
viewport.z = 99999
|
||||
sprites = {}
|
||||
sprites["right_window"] = SpriteWindow_DebugVariables.new(viewport)
|
||||
right_window = sprites["right_window"]
|
||||
right_window.mode = mode
|
||||
right_window.active = true
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
pbUpdateSpriteHash(sprites)
|
||||
if Input.trigger?(Input::BACK)
|
||||
pbPlayCancelSE
|
||||
break
|
||||
end
|
||||
current_id = right_window.index+1
|
||||
if mode==0 # Switches
|
||||
if Input.trigger?(Input::USE)
|
||||
pbPlayDecisionSE
|
||||
$game_switches[current_id] = !$game_switches[current_id]
|
||||
right_window.refresh
|
||||
$game_map.need_refresh = true
|
||||
end
|
||||
elsif mode==1 # Variables
|
||||
if Input.repeat?(Input::LEFT)
|
||||
pbDebugSetVariable(current_id,-1)
|
||||
right_window.refresh
|
||||
elsif Input.repeat?(Input::RIGHT)
|
||||
pbDebugSetVariable(current_id,1)
|
||||
right_window.refresh
|
||||
elsif Input.trigger?(Input::ACTION)
|
||||
if $game_variables[current_id]==0
|
||||
$game_variables[current_id] = ""
|
||||
elsif $game_variables[current_id]==""
|
||||
$game_variables[current_id] = 0
|
||||
elsif $game_variables[current_id].is_a?(Numeric)
|
||||
$game_variables[current_id] = 0
|
||||
elsif $game_variables[current_id].is_a?(String)
|
||||
$game_variables[current_id] = ""
|
||||
end
|
||||
right_window.refresh
|
||||
$game_map.need_refresh = true
|
||||
elsif Input.trigger?(Input::USE)
|
||||
pbPlayDecisionSE
|
||||
pbDebugVariableScreen(current_id)
|
||||
right_window.refresh
|
||||
end
|
||||
end
|
||||
end
|
||||
pbDisposeSpriteHash(sprites)
|
||||
viewport.dispose
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Debug Day Care screen
|
||||
#===============================================================================
|
||||
def pbDebugDayCare
|
||||
commands = [_INTL("Withdraw Pokémon 1"),
|
||||
_INTL("Withdraw Pokémon 2"),
|
||||
_INTL("Deposit Pokémon"),
|
||||
_INTL("Generate egg"),
|
||||
_INTL("Collect egg")]
|
||||
viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
|
||||
viewport.z = 99999
|
||||
sprites = {}
|
||||
addBackgroundPlane(sprites,"background","hatchbg",viewport)
|
||||
sprites["overlay"] = BitmapSprite.new(Graphics.width,Graphics.height,viewport)
|
||||
pbSetSystemFont(sprites["overlay"].bitmap)
|
||||
sprites["cmdwindow"] = Window_CommandPokemonEx.new(commands)
|
||||
cmdwindow = sprites["cmdwindow"]
|
||||
cmdwindow.x = 0
|
||||
cmdwindow.y = Graphics.height-128
|
||||
cmdwindow.width = Graphics.width
|
||||
cmdwindow.height = 128
|
||||
cmdwindow.viewport = viewport
|
||||
cmdwindow.columns = 2
|
||||
base = Color.new(248,248,248)
|
||||
shadow = Color.new(104,104,104)
|
||||
refresh = true
|
||||
loop do
|
||||
if refresh
|
||||
if pbEggGenerated?
|
||||
commands[3] = _INTL("Discard egg")
|
||||
else
|
||||
commands[3] = _INTL("Generate egg")
|
||||
end
|
||||
cmdwindow.commands = commands
|
||||
sprites["overlay"].bitmap.clear
|
||||
textpos = []
|
||||
for i in 0...2
|
||||
textpos.push([_INTL("Pokémon {1}",i+1),Graphics.width/4+i*Graphics.width/2,2,2,base,shadow])
|
||||
end
|
||||
for i in 0...pbDayCareDeposited
|
||||
next if !$PokemonGlobal.daycare[i][0]
|
||||
y = 34
|
||||
pkmn = $PokemonGlobal.daycare[i][0]
|
||||
initlevel = $PokemonGlobal.daycare[i][1]
|
||||
leveldiff = pkmn.level-initlevel
|
||||
textpos.push(["#{pkmn.name} (#{pkmn.speciesName})",8+i*Graphics.width/2,y,0,base,shadow])
|
||||
y += 32
|
||||
if pkmn.male?
|
||||
textpos.push([_INTL("Male ♂"),8+i*Graphics.width/2,y,0,Color.new(128,192,248),shadow])
|
||||
elsif pkmn.female?
|
||||
textpos.push([_INTL("Female ♀"),8+i*Graphics.width/2,y,0,Color.new(248,96,96),shadow])
|
||||
else
|
||||
textpos.push([_INTL("Genderless"),8+i*Graphics.width/2,y,0,base,shadow])
|
||||
end
|
||||
y += 32
|
||||
if initlevel>=GameData::GrowthRate.max_level
|
||||
textpos.push(["Lv. #{initlevel} (max)",8+i*Graphics.width/2,y,0,base,shadow])
|
||||
elsif leveldiff>0
|
||||
textpos.push(["Lv. #{initlevel} -> #{pkmn.level} (+#{leveldiff})",
|
||||
8+i*Graphics.width/2,y,0,base,shadow])
|
||||
else
|
||||
textpos.push(["Lv. #{initlevel} (no change)",8+i*Graphics.width/2,y,0,base,shadow])
|
||||
end
|
||||
y += 32
|
||||
if pkmn.level<GameData::GrowthRate.max_level
|
||||
endexp = pkmn.growth_rate.minimum_exp_for_level(pkmn.level + 1)
|
||||
textpos.push(["To next Lv.: #{endexp-pkmn.exp}",8+i*Graphics.width/2,y,0,base,shadow])
|
||||
y += 32
|
||||
end
|
||||
cost = pbDayCareGetCost(i)
|
||||
textpos.push(["Cost: $#{cost}",8+i*Graphics.width/2,y,0,base,shadow])
|
||||
end
|
||||
if pbEggGenerated?
|
||||
textpos.push(["Egg waiting for collection",Graphics.width/2,210,2,Color.new(248,248,0),shadow])
|
||||
elsif pbDayCareDeposited==2
|
||||
if pbDayCareGetCompat==0
|
||||
textpos.push(["Pokémon cannot breed",Graphics.width/2,210,2,Color.new(248,96,96),shadow])
|
||||
else
|
||||
textpos.push(["Pokémon can breed",Graphics.width/2,210,2,Color.new(64,248,64),shadow])
|
||||
end
|
||||
end
|
||||
pbDrawTextPositions(sprites["overlay"].bitmap,textpos)
|
||||
refresh = false
|
||||
end
|
||||
pbUpdateSpriteHash(sprites)
|
||||
Graphics.update
|
||||
Input.update
|
||||
if Input.trigger?(Input::BACK)
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
case cmdwindow.index
|
||||
when 0 # Withdraw Pokémon 1
|
||||
if !$PokemonGlobal.daycare[0][0]
|
||||
pbPlayBuzzerSE
|
||||
elsif $Trainer.party_full?
|
||||
pbPlayBuzzerSE
|
||||
pbMessage(_INTL("Party is full, can't withdraw Pokémon."))
|
||||
else
|
||||
pbPlayDecisionSE
|
||||
pbDayCareGetDeposited(0,3,4)
|
||||
pbDayCareWithdraw(0)
|
||||
refresh = true
|
||||
end
|
||||
when 1 # Withdraw Pokémon 2
|
||||
if !$PokemonGlobal.daycare[1][0]
|
||||
pbPlayBuzzerSE
|
||||
elsif $Trainer.party_full?
|
||||
pbPlayBuzzerSE
|
||||
pbMessage(_INTL("Party is full, can't withdraw Pokémon."))
|
||||
else
|
||||
pbPlayDecisionSE
|
||||
pbDayCareGetDeposited(1,3,4)
|
||||
pbDayCareWithdraw(1)
|
||||
refresh = true
|
||||
end
|
||||
when 2 # Deposit Pokémon
|
||||
if pbDayCareDeposited==2
|
||||
pbPlayBuzzerSE
|
||||
elsif $Trainer.party.length==0
|
||||
pbPlayBuzzerSE
|
||||
pbMessage(_INTL("Party is empty, can't deposit Pokémon."))
|
||||
else
|
||||
pbPlayDecisionSE
|
||||
pbChooseNonEggPokemon(1,3)
|
||||
if pbGet(1)>=0
|
||||
pbDayCareDeposit(pbGet(1))
|
||||
refresh = true
|
||||
end
|
||||
end
|
||||
when 3 # Generate/discard egg
|
||||
if pbEggGenerated?
|
||||
pbPlayDecisionSE
|
||||
$PokemonGlobal.daycareEgg = 0
|
||||
$PokemonGlobal.daycareEggSteps = 0
|
||||
refresh = true
|
||||
else
|
||||
if pbDayCareDeposited!=2 || pbDayCareGetCompat==0
|
||||
pbPlayBuzzerSE
|
||||
else
|
||||
pbPlayDecisionSE
|
||||
$PokemonGlobal.daycareEgg = 1
|
||||
refresh = true
|
||||
end
|
||||
end
|
||||
when 4 # Collect egg
|
||||
if $PokemonGlobal.daycareEgg!=1
|
||||
pbPlayBuzzerSE
|
||||
elsif $Trainer.party_full?
|
||||
pbPlayBuzzerSE
|
||||
pbMessage(_INTL("Party is full, can't collect the egg."))
|
||||
else
|
||||
pbPlayDecisionSE
|
||||
pbDayCareGenerateEgg
|
||||
$PokemonGlobal.daycareEgg = 0
|
||||
$PokemonGlobal.daycareEggSteps = 0
|
||||
pbMessage(_INTL("Collected the {1} egg.", $Trainer.last_party.speciesName))
|
||||
refresh = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
pbDisposeSpriteHash(sprites)
|
||||
viewport.dispose
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Debug roaming Pokémon screen
|
||||
#===============================================================================
|
||||
class SpriteWindow_DebugRoamers < Window_DrawableCommand
|
||||
def initialize(viewport)
|
||||
super(0,0,Graphics.width,Graphics.height,viewport)
|
||||
end
|
||||
|
||||
def roamerCount
|
||||
return Settings::ROAMING_SPECIES.length
|
||||
end
|
||||
|
||||
def itemCount
|
||||
return self.roamerCount+2
|
||||
end
|
||||
|
||||
def shadowtext(t,x,y,w,h,align=0,colors=0)
|
||||
width = self.contents.text_size(t).width
|
||||
if align==1 ; x += (w-width) # Right aligned
|
||||
elsif align==2; x += (w/2)-(width/2) # Centre aligned
|
||||
end
|
||||
base = Color.new(12*8,12*8,12*8)
|
||||
if colors==1; base = Color.new(168,48,56) # Red
|
||||
elsif colors==2; base = Color.new(0,144,0) # Green
|
||||
end
|
||||
pbDrawShadowText(self.contents,x,y,[width,w].max,h,t,base,Color.new(26*8,26*8,25*8))
|
||||
end
|
||||
|
||||
def drawItem(index,_count,rect)
|
||||
pbSetNarrowFont(self.contents)
|
||||
rect = drawCursor(index,rect)
|
||||
nameWidth = rect.width*50/100
|
||||
statusWidth = rect.width*50/100
|
||||
if index==self.itemCount-2
|
||||
# Advance roaming
|
||||
self.shadowtext(_INTL("[All roam to new locations]"),rect.x,rect.y,nameWidth,rect.height)
|
||||
elsif index==self.itemCount-1
|
||||
# Advance roaming
|
||||
self.shadowtext(_INTL("[Clear all current roamer locations]"),rect.x,rect.y,nameWidth,rect.height)
|
||||
else
|
||||
pkmn = Settings::ROAMING_SPECIES[index]
|
||||
name = GameData::Species.get(pkmn[0]).name + " (Lv. #{pkmn[1]})"
|
||||
status = ""
|
||||
statuscolor = 0
|
||||
if pkmn[2]<=0 || $game_switches[pkmn[2]]
|
||||
status = $PokemonGlobal.roamPokemon[index]
|
||||
if status==true
|
||||
if $PokemonGlobal.roamPokemonCaught[index]
|
||||
status = "[CAUGHT]"
|
||||
else
|
||||
status = "[DEFEATED]"
|
||||
end
|
||||
statuscolor = 1
|
||||
else
|
||||
# roaming
|
||||
curmap = $PokemonGlobal.roamPosition[index]
|
||||
if curmap
|
||||
mapinfos = pbLoadMapInfos
|
||||
status = "[ROAMING][#{curmap}: #{mapinfos[curmap].name}]"
|
||||
else
|
||||
status = "[ROAMING][map not set]"
|
||||
end
|
||||
statuscolor = 2
|
||||
end
|
||||
else
|
||||
status = "[NOT ROAMING][Switch #{pkmn[2]} is off]"
|
||||
end
|
||||
self.shadowtext(name,rect.x,rect.y,nameWidth,rect.height)
|
||||
self.shadowtext(status,rect.x+nameWidth,rect.y,statusWidth,rect.height,1,statuscolor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def pbDebugRoamers
|
||||
viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
|
||||
viewport.z = 99999
|
||||
sprites = {}
|
||||
sprites["cmdwindow"] = SpriteWindow_DebugRoamers.new(viewport)
|
||||
cmdwindow = sprites["cmdwindow"]
|
||||
cmdwindow.active = true
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
pbUpdateSpriteHash(sprites)
|
||||
if Input.trigger?(Input::ACTION) && cmdwindow.index<cmdwindow.roamerCount &&
|
||||
(pkmn[2]<=0 || $game_switches[pkmn[2]]) &&
|
||||
$PokemonGlobal.roamPokemon[cmdwindow.index]!=true
|
||||
# Roam selected Pokémon
|
||||
pbPlayDecisionSE
|
||||
if Input.press?(Input::CTRL) # Roam to current map
|
||||
if $PokemonGlobal.roamPosition[cmdwindow.index]==pbDefaultMap
|
||||
$PokemonGlobal.roamPosition[cmdwindow.index] = nil
|
||||
else
|
||||
$PokemonGlobal.roamPosition[cmdwindow.index] = pbDefaultMap
|
||||
end
|
||||
cmdwindow.refresh
|
||||
else # Roam to a random other map
|
||||
oldmap = $PokemonGlobal.roamPosition[cmdwindow.index]
|
||||
pbRoamPokemonOne(cmdwindow.index)
|
||||
if $PokemonGlobal.roamPosition[cmdwindow.index] == oldmap
|
||||
$PokemonGlobal.roamPosition[cmdwindow.index] = nil
|
||||
pbRoamPokemonOne(cmdwindow.index)
|
||||
end
|
||||
$PokemonGlobal.roamedAlready = false
|
||||
cmdwindow.refresh
|
||||
end
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
pbPlayCancelSE
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
if cmdwindow.index<cmdwindow.roamerCount
|
||||
pbPlayDecisionSE
|
||||
# Toggle through roaming, not roaming, defeated
|
||||
pkmn = Settings::ROAMING_SPECIES[cmdwindow.index]
|
||||
if pkmn[2]>0 && !$game_switches[pkmn[2]]
|
||||
# not roaming -> roaming
|
||||
$game_switches[pkmn[2]] = true
|
||||
elsif $PokemonGlobal.roamPokemon[cmdwindow.index]!=true
|
||||
# roaming -> defeated
|
||||
$PokemonGlobal.roamPokemon[cmdwindow.index] = true
|
||||
$PokemonGlobal.roamPokemonCaught[cmdwindow.index] = false
|
||||
elsif $PokemonGlobal.roamPokemon[cmdwindow.index] == true &&
|
||||
!$PokemonGlobal.roamPokemonCaught[cmdwindow.index]
|
||||
# defeated -> caught
|
||||
$PokemonGlobal.roamPokemonCaught[cmdwindow.index] = true
|
||||
elsif pkmn[2]>0
|
||||
# caught -> not roaming (or roaming if Switch ID is 0
|
||||
$game_switches[pkmn[2]] = false if pkmn[2]>0
|
||||
$PokemonGlobal.roamPokemon[cmdwindow.index] = nil
|
||||
$PokemonGlobal.roamPokemonCaught[cmdwindow.index] = false
|
||||
end
|
||||
cmdwindow.refresh
|
||||
elsif cmdwindow.index==cmdwindow.itemCount-2 # All roam
|
||||
if Settings::ROAMING_SPECIES.length==0
|
||||
pbPlayBuzzerSE
|
||||
else
|
||||
pbPlayDecisionSE
|
||||
pbRoamPokemon
|
||||
$PokemonGlobal.roamedAlready = false
|
||||
cmdwindow.refresh
|
||||
end
|
||||
else # Clear all roaming locations
|
||||
if Settings::ROAMING_SPECIES.length==0
|
||||
pbPlayBuzzerSE
|
||||
else
|
||||
pbPlayDecisionSE
|
||||
for i in 0...Settings::ROAMING_SPECIES.length
|
||||
$PokemonGlobal.roamPosition[i] = nil
|
||||
end
|
||||
$PokemonGlobal.roamedAlready = false
|
||||
cmdwindow.refresh
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
pbDisposeSpriteHash(sprites)
|
||||
viewport.dispose
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Text import/export for localisation
|
||||
#===============================================================================
|
||||
def pbExtractText
|
||||
msgwindow = pbCreateMessageWindow
|
||||
if safeExists?("intl.txt") &&
|
||||
!pbConfirmMessageSerious(_INTL("intl.txt already exists. Overwrite it?"))
|
||||
pbDisposeMessageWindow(msgwindow)
|
||||
return
|
||||
end
|
||||
pbMessageDisplay(msgwindow,_INTL("Please wait.\\wtnp[0]"))
|
||||
MessageTypes.extract("intl.txt")
|
||||
pbMessageDisplay(msgwindow,_INTL("All text in the game was extracted and saved to intl.txt.\1"))
|
||||
pbMessageDisplay(msgwindow,_INTL("To localize the text for a particular language, translate every second line in the file.\1"))
|
||||
pbMessageDisplay(msgwindow,_INTL("After translating, choose \"Compile Text.\""))
|
||||
pbDisposeMessageWindow(msgwindow)
|
||||
end
|
||||
|
||||
def pbCompileTextUI
|
||||
msgwindow = pbCreateMessageWindow
|
||||
pbMessageDisplay(msgwindow,_INTL("Please wait.\\wtnp[0]"))
|
||||
begin
|
||||
pbCompileText
|
||||
pbMessageDisplay(msgwindow,_INTL("Successfully compiled text and saved it to intl.dat.\1"))
|
||||
pbMessageDisplay(msgwindow,_INTL("To use the file in a game, place the file in the Data folder under a different name, and edit the Settings::LANGUAGES array in the scripts."))
|
||||
rescue RuntimeError
|
||||
pbMessageDisplay(msgwindow,_INTL("Failed to compile text: {1}",$!.message))
|
||||
end
|
||||
pbDisposeMessageWindow(msgwindow)
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Battle animations import/export
|
||||
#===============================================================================
|
||||
def pbExportAllAnimations
|
||||
begin
|
||||
Dir.mkdir("Animations") rescue nil
|
||||
animations = pbLoadBattleAnimations
|
||||
if animations
|
||||
msgwindow = pbCreateMessageWindow
|
||||
for anim in animations
|
||||
next if !anim || anim.length==0 || anim.name==""
|
||||
pbMessageDisplay(msgwindow,anim.name,false)
|
||||
Graphics.update
|
||||
safename = anim.name.gsub(/\W/,"_")
|
||||
Dir.mkdir("Animations/#{safename}") rescue nil
|
||||
File.open("Animations/#{safename}/#{safename}.anm","wb") { |f|
|
||||
f.write(dumpBase64Anim(anim))
|
||||
}
|
||||
if anim.graphic && anim.graphic!=""
|
||||
graphicname = RTP.getImagePath("Graphics/Animations/"+anim.graphic)
|
||||
pbSafeCopyFile(graphicname,"Animations/#{safename}/"+File.basename(graphicname))
|
||||
end
|
||||
for timing in anim.timing
|
||||
if !timing.timingType || timing.timingType==0
|
||||
if timing.name && timing.name!=""
|
||||
audioName = RTP.getAudioPath("Audio/SE/Anim/"+timing.name)
|
||||
pbSafeCopyFile(audioName,"Animations/#{safename}/"+File.basename(audioName))
|
||||
end
|
||||
elsif timing.timingType==1 || timing.timingType==3
|
||||
if timing.name && timing.name!=""
|
||||
graphicname = RTP.getImagePath("Graphics/Animations/"+timing.name)
|
||||
pbSafeCopyFile(graphicname,"Animations/#{safename}/"+File.basename(graphicname))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
pbDisposeMessageWindow(msgwindow)
|
||||
pbMessage(_INTL("All animations were extracted and saved to the Animations folder."))
|
||||
else
|
||||
pbMessage(_INTL("There are no animations to export."))
|
||||
end
|
||||
rescue
|
||||
p $!.message,$!.backtrace
|
||||
pbMessage(_INTL("The export failed."))
|
||||
end
|
||||
end
|
||||
|
||||
def pbImportAllAnimations
|
||||
animationFolders = []
|
||||
if safeIsDirectory?("Animations")
|
||||
Dir.foreach("Animations") { |fb|
|
||||
f = "Animations/"+fb
|
||||
if safeIsDirectory?(f) && fb!="." && fb!=".."
|
||||
animationFolders.push(f)
|
||||
end
|
||||
}
|
||||
end
|
||||
if animationFolders.length==0
|
||||
pbMessage(_INTL("There are no animations to import. Put each animation in a folder within the Animations folder."))
|
||||
else
|
||||
msgwindow = pbCreateMessageWindow
|
||||
animations = pbLoadBattleAnimations
|
||||
animations = PBAnimations.new if !animations
|
||||
for folder in animationFolders
|
||||
pbMessageDisplay(msgwindow,folder,false)
|
||||
Graphics.update
|
||||
audios = []
|
||||
files = Dir.glob(folder+"/*.*")
|
||||
%w( wav ogg mid wma mp3 ).each { |ext|
|
||||
upext = ext.upcase
|
||||
audios.concat(files.find_all { |f| f[f.length-3,3]==ext })
|
||||
audios.concat(files.find_all { |f| f[f.length-3,3]==upext })
|
||||
}
|
||||
for audio in audios
|
||||
pbSafeCopyFile(audio,RTP.getAudioPath("Audio/SE/Anim/"+File.basename(audio)),"Audio/SE/Anim/"+File.basename(audio))
|
||||
end
|
||||
images = []
|
||||
%w( png gif ).each { |ext| # jpg jpeg bmp
|
||||
upext = ext.upcase
|
||||
images.concat(files.find_all { |f| f[f.length-3,3]==ext })
|
||||
images.concat(files.find_all { |f| f[f.length-3,3]==upext })
|
||||
}
|
||||
for image in images
|
||||
pbSafeCopyFile(image,RTP.getImagePath("Graphics/Animations/"+File.basename(image)),"Graphics/Animations/"+File.basename(image))
|
||||
end
|
||||
Dir.glob(folder+"/*.anm") { |f|
|
||||
textdata = loadBase64Anim(IO.read(f)) rescue nil
|
||||
if textdata && textdata.is_a?(PBAnimation)
|
||||
index = pbAllocateAnimation(animations,textdata.name)
|
||||
missingFiles = []
|
||||
textdata.name = File.basename(folder) if textdata.name==""
|
||||
textdata.id = -1 # This is not an RPG Maker XP animation
|
||||
pbConvertAnimToNewFormat(textdata)
|
||||
if textdata.graphic && textdata.graphic!=""
|
||||
if !safeExists?(folder+"/"+textdata.graphic) &&
|
||||
!FileTest.image_exist?("Graphics/Animations/"+textdata.graphic)
|
||||
textdata.graphic = ""
|
||||
missingFiles.push(textdata.graphic)
|
||||
end
|
||||
end
|
||||
for timing in textdata.timing
|
||||
if timing.name && timing.name!=""
|
||||
if !safeExists?(folder+"/"+timing.name) &&
|
||||
!FileTest.audio_exist?("Audio/SE/Anim/"+timing.name)
|
||||
timing.name = ""
|
||||
missingFiles.push(timing.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
animations[index] = textdata
|
||||
end
|
||||
}
|
||||
end
|
||||
save_data(animations,"Data/PkmnAnimations.rxdata")
|
||||
$PokemonTemp.battleAnims = nil
|
||||
pbDisposeMessageWindow(msgwindow)
|
||||
pbMessage(_INTL("All animations were imported."))
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
# Properly erases all non-existent tiles in maps (including event graphics)
|
||||
#===============================================================================
|
||||
def pbDebugFixInvalidTiles
|
||||
num_errors = 0
|
||||
num_error_maps = 0
|
||||
tilesets = $data_tilesets
|
||||
mapData = Compiler::MapData.new
|
||||
t = Time.now.to_i
|
||||
Graphics.update
|
||||
for id in mapData.mapinfos.keys.sort
|
||||
if Time.now.to_i - t >= 5
|
||||
Graphics.update
|
||||
t = Time.now.to_i
|
||||
end
|
||||
changed = false
|
||||
map = mapData.getMap(id)
|
||||
next if !map || !mapData.mapinfos[id]
|
||||
pbSetWindowText(_INTL("Processing map {1} ({2})", id, mapData.mapinfos[id].name))
|
||||
passages = mapData.getTilesetPassages(map, id)
|
||||
# Check all tiles in map for non-existent tiles
|
||||
for x in 0...map.data.xsize
|
||||
for y in 0...map.data.ysize
|
||||
for i in 0...map.data.zsize
|
||||
tile_id = map.data[x, y, i]
|
||||
next if pbCheckTileValidity(tile_id, map, tilesets, passages)
|
||||
map.data[x, y, i] = 0
|
||||
changed = true
|
||||
num_errors += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
# Check all events in map for page graphics using a non-existent tile
|
||||
for key in map.events.keys
|
||||
event = map.events[key]
|
||||
for page in event.pages
|
||||
next if page.graphic.tile_id <= 0
|
||||
next if pbCheckTileValidity(page.graphic.tile_id, map, tilesets, passages)
|
||||
page.graphic.tile_id = 0
|
||||
changed = true
|
||||
num_errors += 1
|
||||
end
|
||||
end
|
||||
next if !changed
|
||||
# Map was changed; save it
|
||||
num_error_maps += 1
|
||||
mapData.saveMap(id)
|
||||
end
|
||||
if num_error_maps == 0
|
||||
pbMessage(_INTL("No invalid tiles were found."))
|
||||
else
|
||||
pbMessage(_INTL("{1} error(s) were found across {2} map(s) and fixed.", num_errors, num_error_maps))
|
||||
pbMessage(_INTL("Close RPG Maker XP to ensure the changes are applied properly."))
|
||||
end
|
||||
end
|
||||
|
||||
def pbCheckTileValidity(tile_id, map, tilesets, passages)
|
||||
return false if !tile_id
|
||||
if tile_id > 0 && tile_id < 384
|
||||
# Check for defined autotile
|
||||
autotile_id = tile_id / 48 - 1
|
||||
autotile_name = tilesets[map.tileset_id].autotile_names[autotile_id]
|
||||
return true if autotile_name && autotile_name != ""
|
||||
else
|
||||
# Check for tileset data
|
||||
return true if passages[tile_id]
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Pseudo-party screen for editing Pokémon being set up for a wild battle
|
||||
#===============================================================================
|
||||
class PokemonDebugPartyScreen
|
||||
def initialize
|
||||
@viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
|
||||
@viewport.z = 99999
|
||||
@messageBox = Window_AdvancedTextPokemon.new("")
|
||||
@messageBox.viewport = @viewport
|
||||
@messageBox.visible = false
|
||||
@messageBox.letterbyletter = true
|
||||
pbBottomLeftLines(@messageBox,2)
|
||||
@helpWindow = Window_UnformattedTextPokemon.new("")
|
||||
@helpWindow.viewport = @viewport
|
||||
@helpWindow.visible = true
|
||||
pbBottomLeftLines(@helpWindow,1)
|
||||
end
|
||||
|
||||
def pbEndScreen
|
||||
@messageBox.dispose
|
||||
@helpWindow.dispose
|
||||
@viewport.dispose
|
||||
end
|
||||
|
||||
def pbDisplay(text)
|
||||
@messageBox.text = text
|
||||
@messageBox.visible = true
|
||||
@helpWindow.visible = false
|
||||
pbPlayDecisionSE
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
pbUpdate
|
||||
if @messageBox.busy?
|
||||
if Input.trigger?(Input::USE)
|
||||
pbPlayDecisionSE if @messageBox.pausing?
|
||||
@messageBox.resume
|
||||
end
|
||||
else
|
||||
if Input.trigger?(Input::BACK) || Input.trigger?(Input::USE)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
@messageBox.visible = false
|
||||
@helpWindow.visible = true
|
||||
end
|
||||
|
||||
def pbConfirm(text)
|
||||
ret = -1
|
||||
@messageBox.text = text
|
||||
@messageBox.visible = true
|
||||
@helpWindow.visible = false
|
||||
using(cmdwindow = Window_CommandPokemon.new([_INTL("Yes"),_INTL("No")])) {
|
||||
cmdwindow.visible = false
|
||||
pbBottomRight(cmdwindow)
|
||||
cmdwindow.y -= @messageBox.height
|
||||
cmdwindow.z = @viewport.z+1
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cmdwindow.visible = true if !@messageBox.busy?
|
||||
cmdwindow.update
|
||||
pbUpdate
|
||||
if !@messageBox.busy?
|
||||
if Input.trigger?(Input::BACK)
|
||||
ret = false
|
||||
break
|
||||
elsif Input.trigger?(Input::USE) && @messageBox.resume
|
||||
ret = (cmdwindow.index==0)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
@messageBox.visible = false
|
||||
@helpWindow.visible = true
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbShowCommands(text,commands,index=0)
|
||||
ret = -1
|
||||
@helpWindow.visible = true
|
||||
using(cmdwindow = Window_CommandPokemonColor.new(commands)) {
|
||||
cmdwindow.z = @viewport.z+1
|
||||
cmdwindow.index = index
|
||||
pbBottomRight(cmdwindow)
|
||||
@helpWindow.resizeHeightToFit(text,Graphics.width-cmdwindow.width)
|
||||
@helpWindow.text = text
|
||||
pbBottomLeft(@helpWindow)
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
cmdwindow.update
|
||||
pbUpdate
|
||||
if Input.trigger?(Input::BACK)
|
||||
pbPlayCancelSE
|
||||
ret = -1
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
pbPlayDecisionSE
|
||||
ret = cmdwindow.index
|
||||
break
|
||||
end
|
||||
end
|
||||
}
|
||||
return ret
|
||||
end
|
||||
|
||||
def pbChooseMove(pkmn,text,index=0)
|
||||
moveNames = []
|
||||
for i in pkmn.moves
|
||||
if i.total_pp<=0
|
||||
moveNames.push(_INTL("{1} (PP: ---)",i.name))
|
||||
else
|
||||
moveNames.push(_INTL("{1} (PP: {2}/{3})",i.name,i.pp,i.total_pp))
|
||||
end
|
||||
end
|
||||
return pbShowCommands(text,moveNames,index)
|
||||
end
|
||||
|
||||
def pbRefreshSingle(index); end
|
||||
|
||||
def update
|
||||
@messageBox.update
|
||||
@helpWindow.update
|
||||
end
|
||||
alias pbUpdate update
|
||||
end
|
||||
@@ -0,0 +1,311 @@
|
||||
class File
|
||||
# Copies the source file to the destination path.
|
||||
def self.copy(source, destination)
|
||||
data = ""
|
||||
t = Time.now
|
||||
File.open(source, 'rb') do |f|
|
||||
while r = f.read(4096)
|
||||
if Time.now - t > 1
|
||||
Graphics.update
|
||||
t = Time.now
|
||||
end
|
||||
data += r
|
||||
end
|
||||
end
|
||||
File.delete(destination) if File.file?(destination)
|
||||
f = File.new(destination, 'wb')
|
||||
f.write data
|
||||
f.close
|
||||
end
|
||||
|
||||
# Copies the source to the destination and deletes the source.
|
||||
def self.move(source, destination)
|
||||
File.copy(source, destination)
|
||||
File.delete(source)
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
module SpriteRenamer
|
||||
module_function
|
||||
|
||||
def readDirectoryFiles(directory, formats)
|
||||
files = []
|
||||
Dir.chdir(directory) {
|
||||
for i in 0...formats.length
|
||||
Dir.glob(formats[i]) { |f| files.push(f) }
|
||||
end
|
||||
}
|
||||
return files
|
||||
end
|
||||
|
||||
def convert_pokemon_filename(full_name, default_prefix = "")
|
||||
name = full_name
|
||||
extension = ".png"
|
||||
if full_name[/^(.+)\.([^\.]+)$/] # Of the format something.abc
|
||||
name = $~[1]
|
||||
extension = "." + $~[2]
|
||||
end
|
||||
prefix = default_prefix
|
||||
form = female = shadow = crack = ""
|
||||
if default_prefix == ""
|
||||
if name[/s/] && !name[/shadow/]
|
||||
prefix = (name[/b/]) ? "Back shiny/" : "Front shiny/"
|
||||
else
|
||||
prefix = (name[/b/]) ? "Back/" : "Front/"
|
||||
end
|
||||
elsif default_prefix == "Icons/"
|
||||
prefix = "Icons shiny/" if name[/s/] && !name[/shadow/]
|
||||
end
|
||||
if name[/000/]
|
||||
species = "000"
|
||||
elsif name[/^(\d+)$/] || name[/^(\d+)\D/]
|
||||
species_number = $~[1].to_i
|
||||
species_data = GameData::Species.try_get(species_number)
|
||||
raise _INTL("Species {1} is not defined (trying to rename Pokémon graphic {2}).", species_number, full_name) if !species_data
|
||||
species = species_data.id.to_s
|
||||
form = "_" + $~[1].to_s if name[/_(\d+)$/] || name[/_(\d+)\D/]
|
||||
female = "_female" if name[/f/]
|
||||
shadow = "_shadow" if name[/_shadow/]
|
||||
if name[/egg/]
|
||||
prefix = "Eggs/"
|
||||
crack = "_icon" if default_prefix == "Icons/"
|
||||
crack = "_cracks" if name[/eggCracks/]
|
||||
end
|
||||
end
|
||||
return prefix + species + form + female + shadow + crack + extension
|
||||
end
|
||||
|
||||
def convert_pokemon_sprites(src_dir, dest_dir)
|
||||
return if !FileTest.directory?(src_dir)
|
||||
# generates a list of all graphic files
|
||||
files = readDirectoryFiles(src_dir, ["*.png"])
|
||||
# starts automatic renaming
|
||||
files.each_with_index do |file, i|
|
||||
Graphics.update if i % 100 == 0
|
||||
pbSetWindowText(_INTL("Converting Pokémon sprites {1}/{2}...", i, files.length)) if i % 50 == 0
|
||||
case file
|
||||
when "battlers.png"
|
||||
File.delete(src_dir + file)
|
||||
when "egg.png"
|
||||
File.move(src_dir + file, dest_dir + "Eggs/000.png")
|
||||
when "eggCracks.png"
|
||||
File.move(src_dir + file, dest_dir + "Eggs/000_cracks.png")
|
||||
else
|
||||
next if !file[/^\d+[^\.]*\.[^\.]*$/]
|
||||
new_filename = convert_pokemon_filename(file)
|
||||
# moves the files into their appropriate folders
|
||||
File.move(src_dir + file, dest_dir + new_filename)
|
||||
end
|
||||
end
|
||||
Dir.delete(src_dir) rescue nil
|
||||
end
|
||||
|
||||
def convert_pokemon_icons(src_dir, dest_dir)
|
||||
return if !FileTest.directory?(src_dir)
|
||||
# generates a list of all graphic files
|
||||
files = readDirectoryFiles(src_dir, ["*.png"])
|
||||
# starts automatic renaming
|
||||
files.each_with_index do |file, i|
|
||||
Graphics.update if i % 100 == 0
|
||||
pbSetWindowText(_INTL("Converting Pokémon icons {1}/{2}...", i, files.length)) if i % 50 == 0
|
||||
case file
|
||||
when "iconEgg.png"
|
||||
File.move(src_dir + file, dest_dir + "Eggs/000_egg.png")
|
||||
else
|
||||
next if !file[/^icon\d+[^\.]*\.[^\.]*$/]
|
||||
new_filename = convert_pokemon_filename(file.sub(/^icon/, ''), "Icons/")
|
||||
# moves the files into their appropriate folders
|
||||
File.move(src_dir + file, dest_dir + new_filename)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def convert_pokemon_footprints(src_dir, dest_dir)
|
||||
return if !FileTest.directory?(src_dir)
|
||||
# generates a list of all graphic files
|
||||
files = readDirectoryFiles(src_dir, ["*.png"])
|
||||
# starts automatic renaming
|
||||
files.each_with_index do |file, i|
|
||||
Graphics.update if i % 100 == 0
|
||||
pbSetWindowText(_INTL("Converting footprints {1}/{2}...", i, files.length)) if i % 50 == 0
|
||||
next if !file[/^footprint\d+[^\.]*\.[^\.]*$/]
|
||||
new_filename = convert_pokemon_filename(file.sub(/^footprint/, ''), "Footprints/")
|
||||
# moves the files into their appropriate folders
|
||||
File.move(src_dir + file, dest_dir + new_filename)
|
||||
end
|
||||
Dir.delete(src_dir) rescue nil
|
||||
end
|
||||
|
||||
def convert_item_icons(src_dir, dest_dir)
|
||||
return if !FileTest.directory?(src_dir)
|
||||
# generates a list of all graphic files
|
||||
files = readDirectoryFiles(src_dir, ["*.png"])
|
||||
# starts automatic renaming
|
||||
files.each_with_index do |file, i|
|
||||
Graphics.update if i % 100 == 0
|
||||
pbSetWindowText(_INTL("Converting item icons {1}/{2}...", i, files.length)) if i % 50 == 0
|
||||
case file
|
||||
when "item000.png"
|
||||
File.move(src_dir + file, dest_dir + "000.png")
|
||||
when "itemBack.png"
|
||||
File.move(src_dir + file, dest_dir + "back.png")
|
||||
else
|
||||
if file[/^itemMachine(.+)\.([^\.]*)$/]
|
||||
type = $~[1]
|
||||
extension = $~[2]
|
||||
File.move(src_dir + file, dest_dir + "machine_" + type + "." + extension)
|
||||
elsif file[/^item(\d+)\.([^\.]*)$/]
|
||||
item_number = $~[1].to_i
|
||||
extension = $~[2]
|
||||
item_data = GameData::Item.try_get(item_number)
|
||||
raise _INTL("Item {1} is not defined (trying to rename item icon {2}).", item_number, file) if !item_data
|
||||
item = item_data.id.to_s
|
||||
# moves the files into their appropriate folders
|
||||
File.move(src_dir + file, dest_dir + item + "." + extension)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def convert_pokemon_cries(src_dir)
|
||||
return if !FileTest.directory?(src_dir)
|
||||
# generates a list of all audio files
|
||||
files = readDirectoryFiles(src_dir, ["*.wav", "*.mp3", "*.ogg"])
|
||||
# starts automatic renaming
|
||||
files.each_with_index do |file, i|
|
||||
Graphics.update if i % 100 == 0
|
||||
pbSetWindowText(_INTL("Converting Pokémon cries {1}/{2}...", i, files.length)) if i % 50 == 0
|
||||
if file[/^(\d+)Cry[^\.]*\.([^\.]*)$/]
|
||||
species_number = $~[1].to_i
|
||||
extension = $~[2]
|
||||
form = (file[/Cry_(\d+)\./]) ? sprintf("_%s", $~[1]) : ""
|
||||
species_data = GameData::Species.try_get(species_number)
|
||||
raise _INTL("Species {1} is not defined (trying to rename species cry {2}).", species_number, file) if !species_data
|
||||
species = species_data.id.to_s
|
||||
File.move(src_dir + file, src_dir + species + form + "." + extension)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def convert_trainer_sprites(src_dir)
|
||||
return if !FileTest.directory?(src_dir)
|
||||
# generates a list of all graphic files
|
||||
if src_dir == "Graphics/Characters/"
|
||||
files = readDirectoryFiles(src_dir, ["trchar*.png"])
|
||||
else
|
||||
files = readDirectoryFiles(src_dir, ["*.png"])
|
||||
end
|
||||
# starts automatic renaming
|
||||
files.each_with_index do |file, i|
|
||||
Graphics.update if i % 100 == 0
|
||||
pbSetWindowText(_INTL("Converting trainer sprites {1}/{2}...", i, files.length)) if i % 50 == 0
|
||||
if src_dir == "Graphics/Characters/"
|
||||
if file[/^trchar(\d+)\.([^\.]*)$/]
|
||||
tr_type_number = $~[1].to_i
|
||||
extension = $~[2]
|
||||
tr_type_data = GameData::TrainerType.try_get(tr_type_number)
|
||||
raise _INTL("Trainer type {1} is not defined (trying to rename trainer charset {2}).", tr_type_number, file) if !tr_type_data
|
||||
tr_type = tr_type_data.id.to_s
|
||||
File.move(src_dir + file, src_dir + "trainer_" + tr_type + "." + extension)
|
||||
end
|
||||
else
|
||||
if file[/^trainer(\d+)\.([^\.]*)$/]
|
||||
tr_type_number = $~[1].to_i
|
||||
extension = $~[2]
|
||||
tr_type_data = GameData::TrainerType.try_get(tr_type_number)
|
||||
raise _INTL("Trainer type {1} is not defined (trying to rename trainer sprite {2}).", tr_type_number, file) if !tr_type_data
|
||||
tr_type = tr_type_data.id.to_s
|
||||
File.move(src_dir + file, src_dir + tr_type + "." + extension)
|
||||
elsif file[/^trback(\d+)\.([^\.]*)$/]
|
||||
tr_type_number = $~[1].to_i
|
||||
extension = $~[2]
|
||||
tr_type_data = GameData::TrainerType.try_get(tr_type_number)
|
||||
raise _INTL("Trainer type {1} is not defined (trying to rename trainer sprite {2}).", tr_type_number, file) if !tr_type_data
|
||||
tr_type = tr_type_data.id.to_s
|
||||
File.move(src_dir + file, src_dir + tr_type + "_back." + extension)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def convert_player_metadata_charsets
|
||||
changed = false
|
||||
for i in 0...8
|
||||
metadata = GameData::Metadata.get_player(i)
|
||||
next if !metadata
|
||||
if metadata[1][/^trchar(\d+)$/]
|
||||
tr_type_number = $~[1].to_i
|
||||
tr_type_data = GameData::TrainerType.try_get(tr_type_number)
|
||||
raise _INTL("Trainer type {1} is not defined (trying to rename player metadata filename {2}).", tr_type_number, metadata[1]) if !tr_type_data
|
||||
metadata[1] = "trainer_" + tr_type_data.id.to_s
|
||||
changed = true
|
||||
end
|
||||
end
|
||||
return if !changed
|
||||
# Save changes to metadata and rewrite PBS file
|
||||
GameData::Metadata.save
|
||||
Compiler.write_metadata
|
||||
end
|
||||
|
||||
def convert_files
|
||||
return if !pbConfirmMessage("Check for Pokémon/item/trainer files in their old folders that need renaming and moving?")
|
||||
any_changed = false
|
||||
# Rename and move Pokémon sprites/icons
|
||||
dest_dir = "Graphics/Pokemon/"
|
||||
Dir.mkdir(dest_dir) if !FileTest.directory?(dest_dir)
|
||||
for ext in ["Front/", "Back/", "Icons/", "Front shiny/", "Back shiny/", "Icons shiny/",
|
||||
"Eggs/", "Footprints/", "Shadow/"]
|
||||
Dir.mkdir(dest_dir + ext) if !FileTest.directory?(dest_dir + ext)
|
||||
end
|
||||
convert_pokemon_sprites("Graphics/Battlers/", dest_dir)
|
||||
convert_pokemon_icons("Graphics/Icons/", dest_dir)
|
||||
convert_pokemon_footprints("Graphics/Icons/Footprints/", dest_dir)
|
||||
# Rename and move item icons
|
||||
dest_dir = "Graphics/Items/"
|
||||
Dir.mkdir(dest_dir) if !FileTest.directory?(dest_dir)
|
||||
convert_item_icons("Graphics/Icons/", dest_dir)
|
||||
# Rename Pokémon cries
|
||||
convert_pokemon_cries("Audio/SE/Cries/")
|
||||
# Rename trainer sprites
|
||||
convert_trainer_sprites("Graphics/Trainers/")
|
||||
pbSetWindowText(nil)
|
||||
if pbConfirmMessage("Rename all trainer charsets? This will also edit map data to change events' charsets accordingly.")
|
||||
convert_trainer_sprites("Graphics/Characters/")
|
||||
convert_player_metadata_charsets
|
||||
pbSetWindowText(nil)
|
||||
# Edit all maps to replace used charsets
|
||||
mapData = Compiler::MapData.new
|
||||
t = Time.now.to_i
|
||||
Graphics.update
|
||||
for id in mapData.mapinfos.keys.sort
|
||||
map = mapData.getMap(id)
|
||||
next if !map || !mapData.mapinfos[id]
|
||||
changed = false
|
||||
for key in map.events.keys
|
||||
if Time.now.to_i - t >= 5
|
||||
Graphics.update
|
||||
t = Time.now.to_i
|
||||
end
|
||||
map.events[key].pages.each do |page|
|
||||
next if nil_or_empty?(page.graphic.character_name)
|
||||
next if !page.graphic.character_name[/^trchar(.+)$/]
|
||||
tr_type = $~[1]
|
||||
tr_type = tr_type.to_i if tr_type[/^\d+$/]
|
||||
tr_type_data = GameData::TrainerType.try_get(tr_type)
|
||||
raise _INTL("Trainer type {1} is not defined (trying to rename event's charset {2}).", tr_type, file) if !tr_type_data
|
||||
page.graphic.character_name = "trainer_" + tr_type_data.id.to_s
|
||||
changed = true
|
||||
end
|
||||
end
|
||||
mapData.saveMap(id) if changed
|
||||
any_changed = true if changed
|
||||
end
|
||||
end
|
||||
pbMessage(_INTL("All found sprites and icons were renamed and moved."))
|
||||
pbMessage(_INTL("Some map data was edited. Close and reopen RPG Maker XP to see the changes.")) if any_changed
|
||||
pbUpdateVehicle if $game_player
|
||||
end
|
||||
end
|
||||
1316
Data/Scripts/020_Debug/003_Debug menus/005_Debug_PokemonCommands.rb
Normal file
1316
Data/Scripts/020_Debug/003_Debug menus/005_Debug_PokemonCommands.rb
Normal file
File diff suppressed because it is too large
Load Diff
609
Data/Scripts/020_Debug/003_Editor_Listers.rb
Normal file
609
Data/Scripts/020_Debug/003_Editor_Listers.rb
Normal file
@@ -0,0 +1,609 @@
|
||||
#===============================================================================
|
||||
# Core lister script
|
||||
#===============================================================================
|
||||
def pbListWindow(cmds, width = Graphics.width / 2)
|
||||
list = Window_CommandPokemon.newWithSize(cmds, 0, 0, width, Graphics.height)
|
||||
list.setAllowArrowsJump(true)
|
||||
list.index = 0
|
||||
list.rowHeight = 24
|
||||
pbSetSmallFont(list.contents)
|
||||
list.refresh
|
||||
return list
|
||||
end
|
||||
|
||||
def pbListScreen(title,lister)
|
||||
viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
|
||||
viewport.z = 99999
|
||||
list = pbListWindow([])
|
||||
list.viewport = viewport
|
||||
list.z = 2
|
||||
title = Window_UnformattedTextPokemon.newWithSize(title,
|
||||
Graphics.width / 2, 0, Graphics.width / 2, 64, viewport)
|
||||
title.z = 2
|
||||
lister.setViewport(viewport)
|
||||
selectedmap = -1
|
||||
commands = lister.commands
|
||||
selindex = lister.startIndex
|
||||
if commands.length==0
|
||||
value = lister.value(-1)
|
||||
lister.dispose
|
||||
title.dispose
|
||||
list.dispose
|
||||
viewport.dispose
|
||||
return value
|
||||
end
|
||||
list.commands = commands
|
||||
list.index = selindex
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
list.update
|
||||
if list.index!=selectedmap
|
||||
lister.refresh(list.index)
|
||||
selectedmap = list.index
|
||||
end
|
||||
if Input.trigger?(Input::BACK)
|
||||
selectedmap = -1
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
break
|
||||
end
|
||||
end
|
||||
value = lister.value(selectedmap)
|
||||
lister.dispose
|
||||
title.dispose
|
||||
list.dispose
|
||||
viewport.dispose
|
||||
Input.update
|
||||
return value
|
||||
end
|
||||
|
||||
def pbListScreenBlock(title,lister)
|
||||
viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
viewport.z = 99999
|
||||
list = pbListWindow([], Graphics.width / 2)
|
||||
list.viewport = viewport
|
||||
list.z = 2
|
||||
title = Window_UnformattedTextPokemon.newWithSize(title,
|
||||
Graphics.width / 2, 0, Graphics.width / 2, 64, viewport)
|
||||
title.z = 2
|
||||
lister.setViewport(viewport)
|
||||
selectedmap = -1
|
||||
commands = lister.commands
|
||||
selindex = lister.startIndex
|
||||
if commands.length==0
|
||||
value = lister.value(-1)
|
||||
lister.dispose
|
||||
title.dispose
|
||||
list.dispose
|
||||
viewport.dispose
|
||||
return value
|
||||
end
|
||||
list.commands = commands
|
||||
list.index = selindex
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
list.update
|
||||
if list.index!=selectedmap
|
||||
lister.refresh(list.index)
|
||||
selectedmap = list.index
|
||||
end
|
||||
if Input.trigger?(Input::ACTION)
|
||||
yield(Input::ACTION, lister.value(selectedmap))
|
||||
list.commands = lister.commands
|
||||
if list.index==list.commands.length
|
||||
list.index = list.commands.length
|
||||
end
|
||||
lister.refresh(list.index)
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
break
|
||||
elsif Input.trigger?(Input::USE)
|
||||
yield(Input::USE, lister.value(selectedmap))
|
||||
list.commands = lister.commands
|
||||
if list.index==list.commands.length
|
||||
list.index = list.commands.length
|
||||
end
|
||||
lister.refresh(list.index)
|
||||
end
|
||||
end
|
||||
lister.dispose
|
||||
title.dispose
|
||||
list.dispose
|
||||
viewport.dispose
|
||||
Input.update
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class GraphicsLister
|
||||
def initialize(folder,selection)
|
||||
@sprite = IconSprite.new(0,0)
|
||||
@sprite.bitmap = nil
|
||||
@sprite.x = Graphics.width * 3 / 4
|
||||
@sprite.y = (Graphics.height - 64) / 2 + 64
|
||||
@sprite.z = 2
|
||||
@folder = folder
|
||||
@selection = selection
|
||||
@commands = []
|
||||
@index = 0
|
||||
end
|
||||
|
||||
def dispose
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
@sprite.dispose
|
||||
end
|
||||
|
||||
def setViewport(viewport)
|
||||
@sprite.viewport = viewport
|
||||
end
|
||||
|
||||
def startIndex
|
||||
return @index
|
||||
end
|
||||
|
||||
def commands
|
||||
@commands.clear
|
||||
Dir.chdir(@folder) {
|
||||
Dir.glob("*.png") { |f| @commands.push(f) }
|
||||
Dir.glob("*.PNG") { |f| @commands.push(f) }
|
||||
Dir.glob("*.gif") { |f| @commands.push(f) }
|
||||
Dir.glob("*.GIF") { |f| @commands.push(f) }
|
||||
# Dir.glob("*.jpg") { |f| @commands.push(f) }
|
||||
# Dir.glob("*.JPG") { |f| @commands.push(f) }
|
||||
# Dir.glob("*.jpeg") { |f| @commands.push(f) }
|
||||
# Dir.glob("*.JPEG") { |f| @commands.push(f) }
|
||||
# Dir.glob("*.bmp") { |f| @commands.push(f) }
|
||||
# Dir.glob("*.BMP") { |f| @commands.push(f) }
|
||||
}
|
||||
@commands.sort!
|
||||
@commands.length.times do |i|
|
||||
@index = i if @commands[i]==@selection
|
||||
end
|
||||
pbMessage(_INTL("There are no files.")) if @commands.length==0
|
||||
return @commands
|
||||
end
|
||||
|
||||
def value(index)
|
||||
return (index<0) ? "" : @commands[index]
|
||||
end
|
||||
|
||||
def refresh(index)
|
||||
return if index<0
|
||||
@sprite.setBitmap(@folder+@commands[index])
|
||||
sprite_width = @sprite.bitmap.width
|
||||
sprite_height = @sprite.bitmap.height
|
||||
@sprite.ox = sprite_width/2
|
||||
@sprite.oy = sprite_height/2
|
||||
scale_x = (Graphics.width/2).to_f/sprite_width
|
||||
scale_y = (Graphics.height-64).to_f/sprite_height
|
||||
if scale_x<1.0 || scale_y<1.0
|
||||
min_scale = [scale_x, scale_y].min
|
||||
@sprite.zoom_x = @sprite.zoom_y = min_scale
|
||||
else
|
||||
@sprite.zoom_x = @sprite.zoom_y = 1.0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class MusicFileLister
|
||||
def initialize(bgm,setting)
|
||||
@oldbgm = getPlayingBGM
|
||||
@commands = []
|
||||
@bgm = bgm
|
||||
@setting = setting
|
||||
@index = 0
|
||||
end
|
||||
|
||||
def dispose
|
||||
pbPlayBGM(@oldbgm)
|
||||
end
|
||||
|
||||
def setViewport(viewport)
|
||||
end
|
||||
|
||||
def getPlayingBGM
|
||||
($game_system) ? $game_system.getPlayingBGM : nil
|
||||
end
|
||||
|
||||
def pbPlayBGM(bgm)
|
||||
(bgm) ? pbBGMPlay(bgm) : pbBGMStop
|
||||
end
|
||||
|
||||
def startIndex
|
||||
return @index
|
||||
end
|
||||
|
||||
def commands
|
||||
folder = (@bgm) ? "Audio/BGM/" : "Audio/ME/"
|
||||
@commands.clear
|
||||
Dir.chdir(folder) {
|
||||
Dir.glob("*.mp3") { |f| @commands.push(f) }
|
||||
Dir.glob("*.MP3") { |f| @commands.push(f) }
|
||||
Dir.glob("*.ogg") { |f| @commands.push(f) }
|
||||
Dir.glob("*.OGG") { |f| @commands.push(f) }
|
||||
Dir.glob("*.wav") { |f| @commands.push(f) }
|
||||
Dir.glob("*.WAV") { |f| @commands.push(f) }
|
||||
Dir.glob("*.mid") { |f| @commands.push(f) }
|
||||
Dir.glob("*.MID") { |f| @commands.push(f) }
|
||||
Dir.glob("*.midi") { |f| @commands.push(f) }
|
||||
Dir.glob("*.MIDI") { |f| @commands.push(f) }
|
||||
}
|
||||
@commands.sort!
|
||||
@commands.length.times do |i|
|
||||
@index = i if @commands[i]==@setting
|
||||
end
|
||||
pbMessage(_INTL("There are no files.")) if @commands.length==0
|
||||
return @commands
|
||||
end
|
||||
|
||||
def value(index)
|
||||
return (index<0) ? "" : @commands[index]
|
||||
end
|
||||
|
||||
def refresh(index)
|
||||
return if index<0
|
||||
if @bgm
|
||||
pbPlayBGM(@commands[index])
|
||||
else
|
||||
pbPlayBGM("../../Audio/ME/"+@commands[index])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class MapLister
|
||||
def initialize(selmap,addGlobal=false)
|
||||
@sprite = SpriteWrapper.new
|
||||
@sprite.bitmap = nil
|
||||
@sprite.x = Graphics.width * 3 / 4
|
||||
@sprite.y = (Graphics.height - 64) / 2 + 64
|
||||
@sprite.z = -2
|
||||
@commands = []
|
||||
@maps = pbMapTree
|
||||
@addGlobalOffset = (addGlobal) ? 1 : 0
|
||||
@index = 0
|
||||
for i in 0...@maps.length
|
||||
@index = i+@addGlobalOffset if @maps[i][0]==selmap
|
||||
end
|
||||
end
|
||||
|
||||
def dispose
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
@sprite.dispose
|
||||
end
|
||||
|
||||
def setViewport(viewport)
|
||||
@sprite.viewport = viewport
|
||||
end
|
||||
|
||||
def startIndex
|
||||
return @index
|
||||
end
|
||||
|
||||
def commands
|
||||
@commands.clear
|
||||
if @addGlobalOffset==1
|
||||
@commands.push(_INTL("[GLOBAL]"))
|
||||
end
|
||||
for i in 0...@maps.length
|
||||
@commands.push(sprintf("%s%03d %s",(" "*@maps[i][2]),@maps[i][0],@maps[i][1]))
|
||||
end
|
||||
return @commands
|
||||
end
|
||||
|
||||
def value(index)
|
||||
if @addGlobalOffset==1
|
||||
return 0 if index==0
|
||||
end
|
||||
return (index<0) ? -1 : @maps[index-@addGlobalOffset][0]
|
||||
end
|
||||
|
||||
def refresh(index)
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
return if index<0
|
||||
return if index==0 && @addGlobalOffset==1
|
||||
@sprite.bitmap = createMinimap(@maps[index-@addGlobalOffset][0])
|
||||
@sprite.ox = @sprite.bitmap.width/2
|
||||
@sprite.oy = @sprite.bitmap.height/2
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class SpeciesLister
|
||||
def initialize(selection = 0, includeNew = false)
|
||||
@selection = selection
|
||||
@commands = []
|
||||
@ids = []
|
||||
@includeNew = includeNew
|
||||
@index = 0
|
||||
end
|
||||
|
||||
def dispose; end
|
||||
def setViewport(viewport); end
|
||||
|
||||
def startIndex
|
||||
return @index
|
||||
end
|
||||
|
||||
def commands # Sorted alphabetically
|
||||
@commands.clear
|
||||
@ids.clear
|
||||
cmds = []
|
||||
GameData::Species.each do |species|
|
||||
next if species.form != 0
|
||||
cmds.push([species.id_number, species.id, species.real_name])
|
||||
end
|
||||
cmds.sort! { |a, b| a[2].downcase <=> b[2].downcase }
|
||||
if @includeNew
|
||||
@commands.push(_INTL("[NEW SPECIES]"))
|
||||
@ids.push(true)
|
||||
end
|
||||
for i in cmds
|
||||
@commands.push(sprintf("%03d: %s", i[0], i[2]))
|
||||
@ids.push(i[1])
|
||||
end
|
||||
@index = @selection
|
||||
@index = @commands.length - 1 if @index >= @commands.length
|
||||
@index = 0 if @index < 0
|
||||
return @commands
|
||||
end
|
||||
|
||||
def value(index)
|
||||
return nil if index < 0
|
||||
return @ids[index]
|
||||
end
|
||||
|
||||
def refresh(index); end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class ItemLister
|
||||
def initialize(selection = 0, includeNew = false)
|
||||
@sprite = ItemIconSprite.new(Graphics.width * 3 / 4, Graphics.height / 2, nil)
|
||||
@sprite.z = 2
|
||||
@selection = selection
|
||||
@commands = []
|
||||
@ids = []
|
||||
@includeNew = includeNew
|
||||
@index = 0
|
||||
end
|
||||
|
||||
def dispose
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
@sprite.dispose
|
||||
end
|
||||
|
||||
def setViewport(viewport)
|
||||
@sprite.viewport = viewport
|
||||
end
|
||||
|
||||
def startIndex
|
||||
return @index
|
||||
end
|
||||
|
||||
def commands # Sorted alphabetically
|
||||
@commands.clear
|
||||
@ids.clear
|
||||
cmds = []
|
||||
GameData::Item.each do |item|
|
||||
cmds.push([item.id_number, item.id, item.real_name])
|
||||
end
|
||||
cmds.sort! { |a, b| a[2].downcase <=> b[2].downcase }
|
||||
if @includeNew
|
||||
@commands.push(_INTL("[NEW ITEM]"))
|
||||
@ids.push(true)
|
||||
end
|
||||
for i in cmds
|
||||
@commands.push(sprintf("%03d: %s", i[0], i[2]))
|
||||
@ids.push(i[1])
|
||||
end
|
||||
@index = @selection
|
||||
@index = @commands.length - 1 if @index >= @commands.length
|
||||
@index = 0 if @index < 0
|
||||
return @commands
|
||||
end
|
||||
|
||||
def value(index)
|
||||
return nil if index < 0
|
||||
return @ids[index]
|
||||
end
|
||||
|
||||
def refresh(index)
|
||||
@sprite.item = (@ids[index].is_a?(Symbol)) ? @ids[index] : nil
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class TrainerTypeLister
|
||||
def initialize(selection = 0, includeNew = false)
|
||||
@sprite = IconSprite.new(Graphics.width * 3 / 4, (Graphics.height - 64) / 2 + 64)
|
||||
@sprite.z = 2
|
||||
@selection = selection
|
||||
@commands = []
|
||||
@ids = []
|
||||
@includeNew = includeNew
|
||||
@index = 0
|
||||
end
|
||||
|
||||
def dispose
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
@sprite.dispose
|
||||
end
|
||||
|
||||
def setViewport(viewport)
|
||||
@sprite.viewport = viewport
|
||||
end
|
||||
|
||||
def startIndex
|
||||
return @index
|
||||
end
|
||||
|
||||
def commands
|
||||
@commands.clear
|
||||
@ids.clear
|
||||
cmds = []
|
||||
GameData::TrainerType.each do |tr_type|
|
||||
cmds.push([tr_type.id_number, tr_type.id, tr_type.real_name])
|
||||
end
|
||||
cmds.sort! { |a, b| a[2] == b[2] ? a[0] <=> b[0] : a[2].downcase <=> b[2].downcase }
|
||||
if @includeNew
|
||||
@commands.push(_INTL("[NEW TRAINER TYPE]"))
|
||||
@ids.push(true)
|
||||
end
|
||||
for t in cmds
|
||||
@commands.push(sprintf("%03d: %s", t[0], t[2]))
|
||||
@ids.push(t[1])
|
||||
end
|
||||
@index = @selection
|
||||
@index = @commands.length - 1 if @index >= @commands.length
|
||||
@index = 0 if @index < 0
|
||||
return @commands
|
||||
end
|
||||
|
||||
def value(index)
|
||||
return nil if index < 0
|
||||
return @ids[index]
|
||||
end
|
||||
|
||||
def refresh(index)
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
return if index < 0
|
||||
begin
|
||||
if @ids[index].is_a?(Symbol)
|
||||
@sprite.setBitmap(GameData::TrainerType.front_sprite_filename(@ids[index]), 0)
|
||||
else
|
||||
@sprite.setBitmap(nil)
|
||||
end
|
||||
rescue
|
||||
@sprite.setBitmap(nil)
|
||||
end
|
||||
if @sprite.bitmap
|
||||
@sprite.ox = @sprite.bitmap.width / 2
|
||||
@sprite.oy = @sprite.bitmap.height / 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class TrainerBattleLister
|
||||
def initialize(selection,includeNew)
|
||||
@sprite = IconSprite.new(Graphics.width * 3 / 4, (Graphics.height / 2) + 32)
|
||||
@sprite.z = 2
|
||||
@pkmnList = Window_UnformattedTextPokemon.newWithSize("",
|
||||
Graphics.width / 2, Graphics.height - 64, Graphics.width / 2, 64)
|
||||
@pkmnList.z = 3
|
||||
@selection = selection
|
||||
@commands = []
|
||||
@ids = []
|
||||
@includeNew = includeNew
|
||||
@index = 0
|
||||
end
|
||||
|
||||
def dispose
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
@sprite.dispose
|
||||
@pkmnList.dispose
|
||||
end
|
||||
|
||||
def setViewport(viewport)
|
||||
@sprite.viewport = viewport
|
||||
@pkmnList.viewport = viewport
|
||||
end
|
||||
|
||||
def startIndex
|
||||
return @index
|
||||
end
|
||||
|
||||
def commands
|
||||
@commands.clear
|
||||
@ids.clear
|
||||
cmds = []
|
||||
GameData::Trainer.each do |trainer|
|
||||
cmds.push([trainer.id_number, trainer.trainer_type, trainer.real_name, trainer.version])
|
||||
end
|
||||
cmds.sort! { |a, b|
|
||||
if a[1] == b[1]
|
||||
if a[2] == b[2]
|
||||
(a[3] == b[3]) ? a[0] <=> b[0] : a[3] <=> b[3]
|
||||
else
|
||||
a[2].downcase <=> b[2].downcase
|
||||
end
|
||||
else
|
||||
a[1].to_s.downcase <=> b[1].to_s.downcase
|
||||
end
|
||||
}
|
||||
if @includeNew
|
||||
@commands.push(_INTL("[NEW TRAINER BATTLE]"))
|
||||
@ids.push(true)
|
||||
end
|
||||
for t in cmds
|
||||
if t[3] > 0
|
||||
@commands.push(_INTL("{1} {2} ({3}) x{4}",
|
||||
GameData::TrainerType.get(t[1]).name, t[2], t[3],
|
||||
GameData::Trainer.get(t[1], t[2], t[3]).pokemon.length))
|
||||
else
|
||||
@commands.push(_INTL("{1} {2} x{3}",
|
||||
GameData::TrainerType.get(t[1]).name, t[2],
|
||||
GameData::Trainer.get(t[1], t[2], t[3]).pokemon.length))
|
||||
end
|
||||
@ids.push([t[1], t[2], t[3]])
|
||||
end
|
||||
@index = @selection
|
||||
@index = @commands.length - 1 if @index >= @commands.length
|
||||
@index = 0 if @index < 0
|
||||
return @commands
|
||||
end
|
||||
|
||||
def value(index)
|
||||
return nil if index < 0
|
||||
return @ids[index]
|
||||
end
|
||||
|
||||
def refresh(index)
|
||||
# Refresh trainer sprite
|
||||
@sprite.bitmap.dispose if @sprite.bitmap
|
||||
return if index < 0
|
||||
begin
|
||||
if @ids[index].is_a?(Array)
|
||||
@sprite.setBitmap(GameData::TrainerType.front_sprite_filename(@ids[index][0]), 0)
|
||||
else
|
||||
@sprite.setBitmap(nil)
|
||||
end
|
||||
rescue
|
||||
@sprite.setBitmap(nil)
|
||||
end
|
||||
if @sprite.bitmap
|
||||
@sprite.ox = @sprite.bitmap.width / 2
|
||||
@sprite.oy = @sprite.bitmap.height
|
||||
end
|
||||
# Refresh list of Pokémon
|
||||
text = ""
|
||||
if !@includeNew || index > 0
|
||||
tr_data = GameData::Trainer.get(@ids[index][0], @ids[index][1], @ids[index][2])
|
||||
if tr_data
|
||||
tr_data.pokemon.each_with_index do |pkmn, i|
|
||||
text += "\r\n" if i > 0
|
||||
text += sprintf("%s Lv.%d", GameData::Species.get(pkmn[:species]).real_name, pkmn[:level])
|
||||
end
|
||||
end
|
||||
end
|
||||
@pkmnList.text = text
|
||||
@pkmnList.resizeHeightToFit(text,Graphics.width / 2)
|
||||
@pkmnList.y = Graphics.height - @pkmnList.height
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user