Wrote a generalised data property editor that deals with a list of things from a GameData module, allowed the WildItem properties for species to contain multiple items each

This commit is contained in:
Maruno17
2021-11-21 22:24:58 +00:00
parent c8b574ed7c
commit d93d73caa8
9 changed files with 170 additions and 354 deletions

View File

@@ -1010,23 +1010,23 @@ def pbPokemonEditor
[_INTL("GenderRatio"), GameDataProperty.new(:GenderRatio), _INTL("Proportion of males to females for this species.")],
[_INTL("CatchRate"), LimitProperty.new(255), _INTL("Catch rate of this species (0-255).")],
[_INTL("Happiness"), LimitProperty.new(255), _INTL("Base happiness of this species (0-255).")],
[_INTL("Moves"), MovePoolProperty, _INTL("Moves which the Pokémon learns while levelling up.")],
[_INTL("TutorMoves"), EggMovesProperty, _INTL("Moves which the Pokémon can be taught by TM/HM/Move Tutor.")],
[_INTL("EggMoves"), EggMovesProperty, _INTL("Moves which the Pokémon can learn via breeding.")],
[_INTL("Moves"), LevelUpMovesProperty, _INTL("Moves which the Pokémon learns while levelling up.")],
[_INTL("TutorMoves"), EggMovesProperty.new, _INTL("Moves which the Pokémon can be taught by TM/HM/Move Tutor.")],
[_INTL("EggMoves"), EggMovesProperty.new, _INTL("Moves which the Pokémon can learn via breeding.")],
[_INTL("Ability 1"), AbilityProperty, _INTL("One ability which the Pokémon can have.")],
[_INTL("Ability 2"), AbilityProperty, _INTL("Another ability which the Pokémon can have.")],
[_INTL("HiddenAbility 1"), AbilityProperty, _INTL("A secret ability which the Pokémon can have.")],
[_INTL("HiddenAbility 2"), AbilityProperty, _INTL("A secret ability which the Pokémon can have.")],
[_INTL("HiddenAbility 3"), AbilityProperty, _INTL("A secret ability which the Pokémon can have.")],
[_INTL("HiddenAbility 4"), AbilityProperty, _INTL("A secret ability which the Pokémon can have.")],
[_INTL("WildItemCommon"), ItemProperty, _INTL("Item commonly held by wild Pokémon of this species.")],
[_INTL("WildItemUncommon"), ItemProperty, _INTL("Item uncommonly held by wild Pokémon of this species.")],
[_INTL("WildItemRare"), ItemProperty, _INTL("Item rarely held by wild Pokémon of this species.")],
[_INTL("WildItemCommon"), GameDataPoolProperty.new(:Item), _INTL("Item(s) commonly held by wild Pokémon of this species.")],
[_INTL("WildItemUncommon"), GameDataPoolProperty.new(:Item), _INTL("Item(s) uncommonly held by wild Pokémon of this species.")],
[_INTL("WildItemRare"), GameDataPoolProperty.new(:Item), _INTL("Item(s) rarely held by wild Pokémon of this species.")],
[_INTL("EggGroup 1"), GameDataProperty.new(:EggGroup), _INTL("Compatibility group (egg group) for breeding purposes.")],
[_INTL("EggGroup 2"), GameDataProperty.new(:EggGroup), _INTL("Compatibility group (egg group) for breeding purposes.")],
[_INTL("HatchSteps"), LimitProperty.new(99999), _INTL("Number of steps until an egg of this species hatches.")],
[_INTL("Incense"), ItemProperty, _INTL("Item needed to be held by a parent to produce an egg of this species.")],
[_INTL("Offspring"), SpeciesPoolProperty, _INTL("All possible species that an egg can be when breeding for an egg of this species (if blank, the egg can only be this species).")],
[_INTL("Offspring"), GameDataPoolProperty.new(:Species), _INTL("All possible species that an egg can be when breeding for an egg of this species (if blank, the egg can only be this species).")],
[_INTL("Evolutions"), EvolutionsProperty.new, _INTL("Evolution paths of this species.")],
[_INTL("Height"), NonzeroLimitProperty.new(999), _INTL("Height of the Pokémon in 0.1 metres (e.g. 42 = 4.2m).")],
[_INTL("Weight"), NonzeroLimitProperty.new(9999), _INTL("Weight of the Pokémon in 0.1 kilograms (e.g. 42 = 4.2kg).")],
@@ -1080,9 +1080,9 @@ def pbPokemonEditor
spec.hidden_abilities[1],
spec.hidden_abilities[2],
spec.hidden_abilities[3],
spec.wild_item_common,
spec.wild_item_uncommon,
spec.wild_item_rare,
spec.wild_item_common.clone,
spec.wild_item_uncommon.clone,
spec.wild_item_rare.clone,
spec.egg_groups[0],
spec.egg_groups[1],
spec.hatch_steps,

View File

@@ -111,29 +111,64 @@ end
#===============================================================================
# List all members of a class
#===============================================================================
def pbChooseFromGameDataList(game_data, default = nil)
if !GameData.const_defined?(game_data.to_sym)
raise _INTL("Couldn't find class {1} in module GameData.", game_data.to_s)
end
game_data_module = GameData.const_get(game_data.to_sym)
commands = []
game_data_module.each do |data|
name = data.real_name
name = yield(data) if block_given?
next if !name
index = commands.length + 1
index = data.id_number if data.respond_to?("id_number")
commands.push([commands.length + 1, name, data.id])
end
return pbChooseList(commands, default, nil, -1)
end
# 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)
commands = []
index = 1
GameData::Species.each_species do |s|
commands.push([index, s.real_name, s.id])
index += 1
end
return pbChooseList(commands, default, nil, -1)
return pbChooseFromGameDataList(:Species, default) { |data|
next (data.form > 0) ? nil : data.real_name
}
end
def pbChooseSpeciesFormList(default = nil)
commands = []
index = 1
GameData::Species.each do |s|
name = (s.form == 0) ? s.real_name : sprintf("%s_%d", s.real_name, s.form)
commands.push([index, name, s.id])
index += 1
end
return pbChooseList(commands, default, nil, -1)
return pbChooseFromGameDataList(:Species, default) { |data|
next (data.form > 0) ? sprintf("%s_%d", data.real_name, data.form) : data.real_name
}
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)
return pbChooseFromGameDataList(:Type, default) { |data|
next (data.pseudo_type) ? nil : data.real_name
}
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)
return pbChooseFromGameDataList(:Item, default)
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)
return pbChooseFromGameDataList(:Ability, default)
end
# Displays a list of all moves, and returns the ID of the move selected (or nil
@@ -141,13 +176,7 @@ end
# to initially select. Pressing Input::ACTION will toggle the list sorting
# between numerical and alphabetical.
def pbChooseMoveList(default = nil)
commands = []
index = 1
GameData::Move.each do |m|
commands.push([index, m.real_name, m.id])
index += 1
end
return pbChooseList(commands, default, nil, -1)
return pbChooseFromGameDataList(:Move, default)
end
def pbChooseMoveListForSpecies(species, defaultMoveID = nil)
@@ -189,49 +218,6 @@ def pbChooseMoveListForSpecies(species, defaultMoveID = nil)
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 = []
index = 0
GameData::Type.each do |t|
next if t.pseudo_type
commands.push([index, t.name, t.id])
index += 1
end
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 = []
index = 1
GameData::Item.each do |i|
commands.push([index, i.name, i.id])
index += 1
end
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 = []
index = 1
GameData::Ability.each do |a|
commands.push([index, a.name, a.id])
index += 1
end
return pbChooseList(commands, default, nil, -1)
end
def pbChooseBallList(defaultMoveID = nil)
cmdwin = pbListWindow([], 200)
commands = []

View File

@@ -975,81 +975,103 @@ end
module SpeciesPoolProperty
def self.set(_settingname, oldsetting)
# Get all species in the pool
realcmds = []
realcmds.push([nil, "-", -1]) # Species ID, index in this list, name
for i in 0...oldsetting.length
realcmds.push([oldsetting[i], GameData::Species.get(oldsetting[i]).real_name, i])
class GameDataPoolProperty
def initialize(game_data, allow_multiple = true, auto_sort = false)
if !GameData.const_defined?(game_data.to_sym)
raise _INTL("Couldn't find class {1} in module GameData.", game_data.to_s)
end
# Edit species pool
cmdwin = pbListWindow([], 200)
oldsel = -1
ret = oldsetting
cmd = [0, 0]
@game_data = game_data
@game_data_module = GameData.const_get(game_data.to_sym)
@allow_multiple = allow_multiple
@auto_sort = auto_sort # Alphabetically
end
def set(setting_name, old_setting)
ret = old_setting
old_setting.uniq! if !@allow_multiple
old_setting.sort! if @auto_sort
# Get all values already in the pool
values = []
values.push([nil, _INTL("[ADD VALUE]")]) # Value ID, name
old_setting.each do |value|
values.push([value, @game_data_module.get(value).real_name])
end
# Set things up
command_window = pbListWindow([], 200)
cmd = [0, 0] # [input type, list index] (input type: 0=select, 1=swap up, 2=swap down)
commands = []
refreshlist = true
need_refresh = true
# Edit value pool
loop do
if refreshlist
realcmds.sort! { |a, b| a[2] <=> b[2] }
commands = []
realcmds.each_with_index do |entry, i|
commands.push((entry[0].nil?) ? _INTL("[ADD SPECIES]") : entry[1])
if need_refresh
if @auto_sort
values.sort! { |a, b| (a[0].nil?) ? -1 : b[0].nil? ? 1 : a[1] <=> b[1] }
end
commands = values.map { |entry| entry[1] }
need_refresh = false
end
refreshlist = false
oldsel = -1
cmd = pbCommands3(cmdwin, commands, -1, cmd[1], true)
case cmd[0]
when 1 # Swap species up
if cmd[1] > 0 && cmd[1] < realcmds.length - 1
realcmds[cmd[1] + 1][2], realcmds[cmd[1]][2] = realcmds[cmd[1]][2], realcmds[cmd[1] + 1][2]
refreshlist = true
# Choose a value
cmd = pbCommands3(command_window, commands, -1, cmd[1], true)
case cmd[0] # 0=selected/cancelled, 1=pressed Action+Up, 2=pressed Action+Down
when 1 # Swap value up
if cmd[1] > 0 && cmd[1] < values.length - 1
values[cmd[1] + 1], values[cmd[1]] = values[cmd[1]], values[cmd[1] + 1]
need_refresh = true
end
when 2 # Swap species down
when 2 # Swap value down
if cmd[1] > 1
realcmds[cmd[1] - 1][2], realcmds[cmd[1]][2] = realcmds[cmd[1]][2], realcmds[cmd[1] - 1][2]
refreshlist = true
values[cmd[1] - 1], values[cmd[1]] = values[cmd[1]], values[cmd[1] - 1]
need_refresh = true
end
when 0
if cmd[1] >= 0 # Chose an entry
entry = realcmds[cmd[1]]
if entry[0].nil? # Add new species
new_species = pbChooseSpeciesList
if new_species
maxid = -1
realcmds.each { |e| maxid = [maxid, e[2]].max }
realcmds.push([new_species, GameData::Species.get(new_species).real_name, maxid + 1])
refreshlist = true
entry = values[cmd[1]]
if entry[0].nil? # Add new value
new_value = pbChooseFromGameDataList(@game_data)
if new_value
if !@allow_multiple && values.any? { |val| val[0] == new_value }
cmd[1] = values.index { |val| val[0] == new_value }
next
end
values.push([new_value, @game_data_module.get(new_value).real_name])
need_refresh = true
end
else # Edit existing species
case pbMessage(_INTL("\\ts[]Do what with this species?"),
[_INTL("Change species"), _INTL("Delete"), _INTL("Cancel")], 3)
when 0 # Change species
new_species = pbChooseSpeciesList(entry[0])
if new_species && new_species != entry[0]
entry[0] = new_species
entry[1] = GameData::Species.get(new_species).real_name
oldsel = entry[2]
refreshlist = true
else # Edit existing value
case pbMessage(_INTL("\\ts[]Do what with this value?"),
[_INTL("Change value"), _INTL("Delete"), _INTL("Cancel")], 3)
when 0 # Change value
new_value = pbChooseFromGameDataList(@game_data, entry[0])
if new_value && new_value != entry[0]
if !@allow_multiple && values.any? { |val| val[0] == new_value }
values.delete_at(cmd[1])
cmd[1] = values.index { |val| val[0] == new_value }
need_refresh = true
next
end
entry[0] = new_value
entry[1] = @game_data_module.get(new_value).real_name
if @auto_sort
values.sort! { |a, b| a[1] <=> b[1] }
cmd[1] = values.index { |val| val[0] == new_value }
end
need_refresh = true
end
when 1 # Delete
realcmds.delete_at(cmd[1])
cmd[1] = [cmd[1], realcmds.length - 1].min
refreshlist = true
values.delete_at(cmd[1])
cmd[1] = [cmd[1], values.length - 1].min
need_refresh = true
end
end
else # Cancel/quit
case pbMessage(_INTL("Save changes?"),
case pbMessage(_INTL("Apply changes?"),
[_INTL("Yes"), _INTL("No"), _INTL("Cancel")], 3)
when 0
realcmds.shift
for i in 0...realcmds.length
realcmds[i] = realcmds[i][0]
values.shift # Remove the "add value" option
for i in 0...values.length
values[i] = values[i][0]
end
realcmds.compact!
ret = realcmds
values.compact!
ret = values
break
when 1
break
@@ -1057,129 +1079,30 @@ module SpeciesPoolProperty
end
end
end
cmdwin.dispose
command_window.dispose
return ret
end
def self.defaultValue
def defaultValue
return []
end
def self.format(value)
ret = ""
for i in 0...value.length
ret << "," if i > 0
ret << GameData::Species.get(value[i]).real_name
end
return ret
def format(value)
return value.map { |val| @game_data_module.get(val).real_name }.join(",")
end
end
module ItemPoolProperty
def self.set(_settingname, oldsetting)
# Get all items in the pool
realcmds = []
realcmds.push([nil, "-", -1]) # Item ID, index in this list, name
for i in 0...oldsetting.length
realcmds.push([oldsetting[i], GameData::Item.get(oldsetting[i]).real_name, i])
end
# Edit item pool
cmdwin = pbListWindow([], 200)
oldsel = -1
ret = oldsetting
cmd = [0, 0]
commands = []
refreshlist = true
loop do
if refreshlist
realcmds.sort! { |a, b| a[2] <=> b[2] }
commands = []
realcmds.each_with_index do |entry, i|
commands.push((entry[0].nil?) ? _INTL("[ADD ITEM]") : entry[1])
end
end
refreshlist = false
oldsel = -1
cmd = pbCommands3(cmdwin, commands, -1, cmd[1], true)
case cmd[0]
when 1 # Swap item up
if cmd[1] > 0 && cmd[1] < realcmds.length - 1
realcmds[cmd[1] + 1][2], realcmds[cmd[1]][2] = realcmds[cmd[1]][2], realcmds[cmd[1] + 1][2]
refreshlist = true
end
when 2 # Swap item down
if cmd[1] > 1
realcmds[cmd[1] - 1][2], realcmds[cmd[1]][2] = realcmds[cmd[1]][2], realcmds[cmd[1] - 1][2]
refreshlist = true
end
when 0
if cmd[1] >= 0 # Chose an entry
entry = realcmds[cmd[1]]
if entry[0].nil? # Add new item
new_item = pbChooseItemList
if new_item
maxid = -1
realcmds.each { |e| maxid = [maxid, e[2]].max }
realcmds.push([new_item, GameData::Item.get(new_item).real_name, maxid + 1])
refreshlist = true
end
else # Edit existing item
case pbMessage(_INTL("\\ts[]Do what with this item?"),
[_INTL("Change item"), _INTL("Delete"), _INTL("Cancel")], 3)
when 0 # Change item
new_item = pbChooseItemList(entry[0])
if new_item && new_item != entry[0]
entry[0] = new_item
entry[1] = GameData::Item.get(new_item).real_name
oldsel = entry[2]
refreshlist = true
end
when 1 # Delete
realcmds.delete_at(cmd[1])
cmd[1] = [cmd[1], realcmds.length - 1].min
refreshlist = true
end
end
else # Cancel/quit
case pbMessage(_INTL("Save changes?"),
[_INTL("Yes"), _INTL("No"), _INTL("Cancel")], 3)
when 0
realcmds.shift
for i in 0...realcmds.length
realcmds[i] = realcmds[i][0]
end
realcmds.compact!
ret = realcmds
break
when 1
break
end
end
end
end
cmdwin.dispose
return ret
end
def self.defaultValue
return []
end
def self.format(value)
ret = ""
for i in 0...value.length
ret << "," if i > 0
ret << GameData::Item.get(value[i]).real_name
end
return ret
class EggMovesProperty < GameDataPoolProperty
def initialize
super(:Move, false, true)
end
end
module MovePoolProperty
module LevelUpMovesProperty
def self.set(_settingname, oldsetting)
# Get all moves in move pool
realcmds = []
@@ -1331,101 +1254,6 @@ end
module EggMovesProperty
def self.set(_settingname, oldsetting)
# Get all egg moves
realcmds = []
realcmds.push([nil, _INTL("[ADD MOVE]"), -1])
for i in 0...oldsetting.length
realcmds.push([oldsetting[i], GameData::Move.get(oldsetting[i]).real_name, 0])
end
# Edit egg moves list
cmdwin = pbListWindow([], 200)
oldsel = nil
ret = oldsetting
cmd = 0
commands = []
refreshlist = true
loop do
if refreshlist
realcmds.sort! { |a, b| (a[2] == b[2]) ? a[1] <=> b[1] : a[2] <=> b[2] }
commands = []
realcmds.each_with_index do |entry, i|
commands.push(entry[1])
cmd = i if oldsel && entry[0] == oldsel
end
end
refreshlist = false
oldsel = nil
cmd = pbCommands2(cmdwin, commands, -1, cmd, true)
if cmd >= 0 # Chose an entry
entry = realcmds[cmd]
if entry[2] == -1 # Add new move
newmove = pbChooseMoveList
if newmove
if realcmds.any? { |e| e[0] == newmove }
oldsel = newmove # Already have move; just move cursor to it
else
realcmds.push([newmove, GameData::Move.get(newmove).name, 0])
end
refreshlist = true
end
else # Edit move
case pbMessage(_INTL("\\ts[]Do what with this move?"),
[_INTL("Change move"), _INTL("Delete"), _INTL("Cancel")], 3)
when 0 # Change move
newmove = pbChooseMoveList(entry[0])
if newmove
if realcmds.any? { |e| e[0] == newmove } # Already have move; delete this one
realcmds.delete_at(cmd)
cmd = [cmd, realcmds.length - 1].min
else # Change move
realcmds[cmd] = [newmove, GameData::Move.get(newmove).name, 0]
end
oldsel = newmove
refreshlist = true
end
when 1 # Delete
realcmds.delete_at(cmd)
cmd = [cmd, realcmds.length - 1].min
refreshlist = true
end
end
else # Cancel/quit
case pbMessage(_INTL("Save changes?"),
[_INTL("Yes"), _INTL("No"), _INTL("Cancel")], 3)
when 0
for i in 0...realcmds.length
realcmds[i] = realcmds[i][0]
end
realcmds.compact!
ret = realcmds
break
when 1
break
end
end
end
cmdwin.dispose
return ret
end
def self.defaultValue
return []
end
def self.format(value)
ret = ""
for i in 0...value.length
ret << "," if i > 0
ret << GameData::Move.get(value[i]).real_name
end
return ret
end
end
class EvolutionsProperty
def initialize
@methods = []