Added Flags property to types, abilities, species and map metadata. Added LocationFlag evolution method.

This commit is contained in:
Maruno17
2021-09-02 19:01:16 +01:00
parent cfbefceb00
commit 86cbcad382
39 changed files with 1200 additions and 1183 deletions

View File

@@ -400,206 +400,221 @@ module Compiler
repeat = true
start = 1
end
subarrays = repeat && schema[1].length > 2
begin
subrecord = []
for i in start...schema[1].length
chr = schema[1][i,1]
case chr
when "i" # Integer
record.push(csvInt!(rec,lineno))
subrecord.push(csvInt!(rec,lineno))
when "I" # Optional integer
field = csvfield!(rec)
if nil_or_empty?(field)
record.push(nil)
subrecord.push(nil)
elsif !field[/^\-?\d+$/]
raise _INTL("Field {1} is not an integer\r\n{2}",field,FileLineData.linereport)
else
record.push(field.to_i)
subrecord.push(field.to_i)
end
when "u" # Positive integer or zero
record.push(csvPosInt!(rec,lineno))
subrecord.push(csvPosInt!(rec,lineno))
when "U" # Optional positive integer or zero
field = csvfield!(rec)
if nil_or_empty?(field)
record.push(nil)
subrecord.push(nil)
elsif !field[/^\d+$/]
raise _INTL("Field '{1}' must be 0 or greater\r\n{2}",field,FileLineData.linereport)
else
record.push(field.to_i)
subrecord.push(field.to_i)
end
when "v" # Positive integer
field = csvPosInt!(rec,lineno)
raise _INTL("Field '{1}' must be greater than 0\r\n{2}",field,FileLineData.linereport) if field==0
record.push(field)
subrecord.push(field)
when "V" # Optional positive integer
field = csvfield!(rec)
if nil_or_empty?(field)
record.push(nil)
subrecord.push(nil)
elsif !field[/^\d+$/]
raise _INTL("Field '{1}' must be greater than 0\r\n{2}",field,FileLineData.linereport)
elsif field.to_i==0
raise _INTL("Field '{1}' must be greater than 0\r\n{2}",field,FileLineData.linereport)
else
record.push(field.to_i)
subrecord.push(field.to_i)
end
when "x" # Hexadecimal number
field = csvfield!(rec)
if !field[/^[A-Fa-f0-9]+$/]
raise _INTL("Field '{1}' is not a hexadecimal number\r\n{2}",field,FileLineData.linereport)
end
record.push(field.hex)
subrecord.push(field.hex)
when "X" # Optional hexadecimal number
field = csvfield!(rec)
if nil_or_empty?(field)
record.push(nil)
subrecord.push(nil)
elsif !field[/^[A-Fa-f0-9]+$/]
raise _INTL("Field '{1}' is not a hexadecimal number\r\n{2}",field,FileLineData.linereport)
else
record.push(field.hex)
subrecord.push(field.hex)
end
when "f" # Floating point number
record.push(csvFloat!(rec,lineno))
subrecord.push(csvFloat!(rec,lineno))
when "F" # Optional floating point number
field = csvfield!(rec)
if nil_or_empty?(field)
record.push(nil)
subrecord.push(nil)
elsif !field[/^\-?^\d*\.?\d*$/]
raise _INTL("Field {1} is not a floating point number\r\n{2}",field,FileLineData.linereport)
else
record.push(field.to_f)
subrecord.push(field.to_f)
end
when "b" # Boolean
record.push(csvBoolean!(rec,lineno))
subrecord.push(csvBoolean!(rec,lineno))
when "B" # Optional Boolean
field = csvfield!(rec)
if nil_or_empty?(field)
record.push(nil)
subrecord.push(nil)
elsif field[/^1|[Tt][Rr][Uu][Ee]|[Yy][Ee][Ss]|[Tt]|[Yy]$/]
record.push(true)
subrecord.push(true)
else
record.push(false)
subrecord.push(false)
end
when "n" # Name
field = csvfield!(rec)
if !field[/^(?![0-9])\w+$/]
raise _INTL("Field '{1}' must contain only letters, digits, and\r\nunderscores and can't begin with a number.\r\n{2}",field,FileLineData.linereport)
end
record.push(field)
subrecord.push(field)
when "N" # Optional name
field = csvfield!(rec)
if nil_or_empty?(field)
record.push(nil)
subrecord.push(nil)
elsif !field[/^(?![0-9])\w+$/]
raise _INTL("Field '{1}' must contain only letters, digits, and\r\nunderscores and can't begin with a number.\r\n{2}",field,FileLineData.linereport)
else
record.push(field)
subrecord.push(field)
end
when "s" # String
record.push(csvfield!(rec))
subrecord.push(csvfield!(rec))
when "S" # Optional string
field = csvfield!(rec)
record.push((nil_or_empty?(field)) ? nil : field)
subrecord.push((nil_or_empty?(field)) ? nil : field)
when "q" # Unformatted text
record.push(rec)
subrecord.push(rec)
rec = ""
when "Q" # Optional unformatted text
if nil_or_empty?(rec)
record.push(nil)
subrecord.push(nil)
else
record.push(rec)
subrecord.push(rec)
rec = ""
end
when "e" # Enumerable
record.push(csvEnumField!(rec,schema[2+i-start],"",FileLineData.linereport))
subrecord.push(csvEnumField!(rec,schema[2+i-start],"",FileLineData.linereport))
when "E" # Optional enumerable
field = csvfield!(rec)
record.push(checkEnumFieldOrNil(field,schema[2+i-start]))
subrecord.push(checkEnumFieldOrNil(field,schema[2+i-start]))
when "y" # Enumerable or integer
field = csvfield!(rec)
record.push(csvEnumFieldOrInt!(field,schema[2+i-start],"",FileLineData.linereport))
subrecord.push(csvEnumFieldOrInt!(field,schema[2+i-start],"",FileLineData.linereport))
when "Y" # Optional enumerable or integer
field = csvfield!(rec)
if nil_or_empty?(field)
record.push(nil)
subrecord.push(nil)
elsif field[/^\-?\d+$/]
record.push(field.to_i)
subrecord.push(field.to_i)
else
record.push(checkEnumFieldOrNil(field,schema[2+i-start]))
subrecord.push(checkEnumFieldOrNil(field,schema[2+i-start]))
end
end
end
if !subrecord.empty?
if subarrays
record.push(subrecord)
else
record.concat(subrecord)
end
end
break if repeat && nil_or_empty?(rec)
end while repeat
return (schema[1].length==1) ? record[0] : record
return (schema[1].length == 1) ? record[0] : record
end
#=============================================================================
# Write values to a file using a schema
#=============================================================================
def pbWriteCsvRecord(record,file,schema)
rec = (record.is_a?(Array)) ? record.clone : [record]
for i in 0...schema[1].length
chr = schema[1][i,1]
file.write(",") if i>0
if rec[i].nil?
# do nothing
elsif rec[i].is_a?(String)
file.write(csvQuote(rec[i]))
elsif rec[i].is_a?(Symbol)
file.write(csvQuote(rec[i].to_s))
elsif rec[i]==true
file.write("true")
elsif rec[i]==false
file.write("false")
elsif rec[i].is_a?(Numeric)
case chr
when "e", "E" # Enumerable
enumer = schema[2+i]
if enumer.is_a?(Array)
file.write(enumer[rec[i]])
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
mod = Object.const_get(enumer.to_sym)
file.write(getConstantName(mod,rec[i]))
elsif enumer.is_a?(Module)
file.write(getConstantName(enumer,rec[i]))
elsif enumer.is_a?(Hash)
for key in enumer.keys
if enumer[key]==rec[i]
file.write(key)
break
rec = (record.is_a?(Array)) ? record.flatten : [record]
start = (schema[1][0, 1] == "*") ? 1 : 0
index = 0
begin
for i in start...schema[1].length
index += 1
file.write(",") if index > 1
value = rec[index]
if value.nil?
# do nothing
elsif value.is_a?(String)
file.write(csvQuote(value))
elsif value.is_a?(Symbol)
file.write(csvQuote(value.to_s))
elsif value==true
file.write("true")
elsif value==false
file.write("false")
elsif value.is_a?(Numeric)
case schema[1][i, 1]
when "e", "E" # Enumerable
enumer = schema[2+i]
if enumer.is_a?(Array)
file.write(enumer[value])
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
mod = Object.const_get(enumer.to_sym)
file.write(getConstantName(mod,value))
elsif enumer.is_a?(Module)
file.write(getConstantName(enumer,value))
elsif enumer.is_a?(Hash)
for key in enumer.keys
if enumer[key]==value
file.write(key)
break
end
end
end
end
when "y", "Y" # Enumerable or integer
enumer = schema[2+i]
if enumer.is_a?(Array)
if enumer[rec[i]]!=nil
file.write(enumer[rec[i]])
else
file.write(rec[i])
end
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
mod = Object.const_get(enumer.to_sym)
file.write(getConstantNameOrValue(mod,rec[i]))
elsif enumer.is_a?(Module)
file.write(getConstantNameOrValue(enumer,rec[i]))
elsif enumer.is_a?(Hash)
hasenum = false
for key in enumer.keys
if enumer[key]==rec[i]
file.write(key)
hasenum = true
break
when "y", "Y" # Enumerable or integer
enumer = schema[2+i]
if enumer.is_a?(Array)
if enumer[value]!=nil
file.write(enumer[value])
else
file.write(value)
end
elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
mod = Object.const_get(enumer.to_sym)
file.write(getConstantNameOrValue(mod,value))
elsif enumer.is_a?(Module)
file.write(getConstantNameOrValue(enumer,value))
elsif enumer.is_a?(Hash)
hasenum = false
for key in enumer.keys
if enumer[key]==value
file.write(key)
hasenum = true
break
end
end
file.write(value) unless hasenum
end
file.write(rec[i]) unless hasenum
else # Any other record type
file.write(value.inspect)
end
else # Any other record type
file.write(rec[i].inspect)
else
file.write(value.inspect)
end
else
file.write(rec[i].inspect)
end
end
break if start > 0 && index >= rec.length
end while start > 0
return record
end

View File

@@ -158,11 +158,10 @@ module Compiler
end
# Compile value for key
value = pbGetCsvRecord(contents[key], key, schema[key])
value = nil if value.is_a?(Array) && value.length == 0
value = nil if value.is_a?(Array) && value.empty?
contents[key] = value
# Ensure weaknesses/resistances/immunities are in arrays and are symbols
if value && ["Weaknesses", "Resistances", "Immunities"].include?(key)
contents[key] = [contents[key]] if !contents[key].is_a?(Array)
contents[key].map! { |x| x.to_sym }
contents[key].uniq!
end
@@ -173,6 +172,7 @@ module Compiler
:name => contents["Name"],
:pseudo_type => contents["IsPseudoType"],
:special_type => contents["IsSpecialType"],
:flags => contents["Flags"],
:weaknesses => contents["Weaknesses"],
:resistances => contents["Resistances"],
:immunities => contents["Immunities"],
@@ -461,6 +461,8 @@ module Compiler
consumable = !([3, 4, 5].include?(line[7]) || line[8] >= 6)
line[7] = 1 if line[7] == 5
line[8] -= 5 if line[8] > 5
flags = []
flags.push(line[9]) if !nil_or_empty?(line[9])
# Construct item hash
item_hash = {
:id => item_id,
@@ -472,7 +474,7 @@ module Compiler
:field_use => line[7],
:battle_use => line[8],
:consumable => consumable,
:type => line[9],
:flags => flags,
:move => line[10]
}
# Add item's data to records
@@ -559,7 +561,7 @@ module Compiler
FileLineData.setSection(species_id, key, contents[key]) # For error reporting
# Compile value for key
value = pbGetCsvRecord(contents[key], key, schema[key])
value = nil if value.is_a?(Array) && value.length == 0
value = nil if value.is_a?(Array) && value.empty?
contents[key] = value
# Sanitise data
case key
@@ -576,23 +578,8 @@ module Compiler
raise _INTL("Value for '{1}' can't be less than or close to 0 (section {2}, {3})", key, species_id, path)
end
contents[key] = value
when "Moves"
move_array = []
for i in 0...value.length / 2
move_array.push([value[i * 2], value[i * 2 + 1], i])
end
move_array.sort! { |a, b| (a[0] == b[0]) ? a[2] <=> b[2] : a[0] <=>b [0] }
move_array.each { |arr| arr.pop }
contents[key] = move_array
when "TutorMoves", "EggMoves", "Abilities", "HiddenAbilities", "HiddenAbility", "EggGroups", "Compatibility"
contents[key] = [contents[key]] if !contents[key].is_a?(Array)
contents[key].compact!
when "Evolutions"
evo_array = []
for i in 0...value.length / 3
evo_array.push([value[i * 3], value[i * 3 + 1], value[i * 3 + 2], false])
end
contents[key] = evo_array
contents[key].each { |evo| evo[3] = false }
end
end
# Construct species hash
@@ -629,6 +616,7 @@ module Compiler
:shape => contents["Shape"],
:habitat => contents["Habitat"],
:generation => contents["Generation"],
:flags => contents["Flags"],
:back_sprite_x => contents["BattlerPlayerX"],
:back_sprite_y => contents["BattlerPlayerY"],
:front_sprite_x => contents["BattlerEnemyX"],
@@ -655,7 +643,7 @@ module Compiler
evo[2] = nil
elsif param_type == Integer
evo[2] = csvPosInt!(evo[2])
else
elsif param_type != String
evo[2] = csvEnumField!(evo[2], param_type, "Evolutions", species.id)
end
end
@@ -743,32 +731,18 @@ module Compiler
raise _INTL("Value for '{1}' can't be less than or close to 0 (section {2}, {3})", key, section_name, path)
end
contents[key] = value
when "Moves"
move_array = []
for i in 0...value.length / 2
move_array.push([value[i * 2], value[i * 2 + 1], i])
end
move_array.sort! { |a, b| (a[0] == b[0]) ? a[2] <=> b[2] : a[0] <=>b [0] }
move_array.each { |arr| arr.pop }
contents[key] = move_array
when "TutorMoves", "EggMoves", "Abilities", "HiddenAbilities", "HiddenAbility", "EggGroups", "Compatibility"
contents[key] = [contents[key]] if !contents[key].is_a?(Array)
contents[key].compact!
when "Evolutions"
evo_array = []
for i in 0...value.length / 3
param_type = GameData::Evolution.get(value[i * 3 + 1]).parameter
param = value[i * 3 + 2]
contents[key].each do |evo|
evo[3] = false
param_type = GameData::Evolution.get(evo[1]).parameter
if param_type.nil?
param = nil
evo[2] = nil
elsif param_type == Integer
param = csvPosInt!(param)
else
param = csvEnumField!(param, param_type, "Evolutions", section_name)
evo[2] = csvPosInt!(evo[2])
elsif param_type != String
evo[2] = csvEnumField!(evo[2], param_type, "Evolutions", section_name)
end
evo_array.push([value[i * 3], value[i * 3 + 1], param, false])
end
contents[key] = evo_array
end
end
# Construct species hash
@@ -819,6 +793,7 @@ module Compiler
:shape => contents["Shape"] || base_data.shape,
:habitat => contents["Habitat"] || base_data.habitat,
:generation => contents["Generation"] || base_data.generation,
:flags => contents["Flags"] || base_data.flags.clone,
:mega_stone => contents["MegaStone"],
:mega_move => contents["MegaMove"],
:unmega_form => contents["UnmegaForm"],
@@ -1165,7 +1140,7 @@ module Compiler
:intro_ME => line[6],
:gender => line[7],
:skill_level => line[8],
:skill_flags => line[9]
:flags => line[9]
}
# Add trainer type's data to records
GameData::TrainerType.register(tr_type_hash)
@@ -1225,9 +1200,6 @@ module Compiler
property_value = pbGetCsvRecord($~[2], line_no, line_schema)
# Error checking in XXX=YYY lines
case property_name
when "Items"
property_value = [property_value] if !property_value.is_a?(Array)
property_value.compact!
when "Pokemon"
if property_value[1] > max_level
raise _INTL("Bad level: {1} (must be 1-{2}).\r\n{3}", property_value[1], max_level, FileLineData.linereport)
@@ -1237,19 +1209,13 @@ module Compiler
raise _INTL("Bad nickname: {1} (must be 1-{2} characters).\r\n{3}", property_value, Pokemon::MAX_NAME_SIZE, FileLineData.linereport)
end
when "Moves"
property_value = [property_value] if !property_value.is_a?(Array)
property_value.uniq!
property_value.compact!
when "IV"
property_value = [property_value] if !property_value.is_a?(Array)
property_value.compact!
property_value.each do |iv|
next if iv <= Pokemon::IV_STAT_LIMIT
raise _INTL("Bad IV: {1} (must be 0-{2}).\r\n{3}", iv, Pokemon::IV_STAT_LIMIT, FileLineData.linereport)
end
when "EV"
property_value = [property_value] if !property_value.is_a?(Array)
property_value.compact!
property_value.each do |ev|
next if ev <= Pokemon::EV_STAT_LIMIT
raise _INTL("Bad EV: {1} (must be 0-{2}).\r\n{3}", ev, Pokemon::EV_STAT_LIMIT, FileLineData.linereport)
@@ -1502,7 +1468,8 @@ module Compiler
:trainer_victory_ME => contents["TrainerVictoryME"],
:wild_capture_ME => contents["WildCaptureME"],
:town_map_size => contents["MapSize"],
:battle_environment => contents["Environment"]
:battle_environment => contents["Environment"],
:flags => contents["Flags"]
}
# Add metadata's data to records
GameData::MapMetadata.register(metadata_hash)

View File

@@ -141,8 +141,9 @@ module Compiler
f.write("[#{type.id}]\r\n")
f.write("Name = #{type.real_name}\r\n")
f.write("IconPosition = #{type.icon_position}\r\n")
f.write("IsPseudoType = true\r\n") if type.pseudo_type
f.write("IsSpecialType = true\r\n") if type.special?
f.write("IsPseudoType = true\r\n") if type.pseudo_type
f.write(sprintf("Flags = %s\r\n", type.flags.join(","))) if type.flags.length > 0
f.write("Weaknesses = #{type.weaknesses.join(",")}\r\n") if type.weaknesses.length > 0
f.write("Resistances = #{type.resistances.join(",")}\r\n") if type.resistances.length > 0
f.write("Immunities = #{type.immunities.join(",")}\r\n") if type.immunities.length > 0
@@ -163,6 +164,7 @@ module Compiler
f.write("[#{ability.id}]\r\n")
f.write("Name = #{ability.real_name}\r\n")
f.write("Description = #{ability.real_description}\r\n")
f.write(sprintf("Flags = %s\r\n", ability.flags.join(","))) if ability.flags.length > 0
end
}
Graphics.update
@@ -188,7 +190,7 @@ module Compiler
f.write("Target = #{move.target}\r\n")
f.write("Priority = #{move.priority}\r\n") if move.priority != 0
f.write("FunctionCode = #{move.function_code}\r\n")
f.write("Flags = #{move.flags.join(",")}\r\n") if move.flags && move.flags.length > 0
f.write("Flags = #{move.flags.join(",")}\r\n") if move.flags.length > 0
f.write("EffectChance = #{move.effect_chance}\r\n") if move.effect_chance > 0
f.write("Description = #{move.real_description}\r\n")
end
@@ -214,9 +216,8 @@ module Compiler
f.write(sprintf("FieldUse = %s\r\n", field_use)) if field_use
battle_use = GameData::Item::SCHEMA["BattleUse"][2].key(item.battle_use)
f.write(sprintf("BattleUse = %s\r\n", battle_use)) if battle_use
type = GameData::Item::SCHEMA["Type"][2].key(item.type)
f.write(sprintf("Consumable = false\r\n")) if !item.is_important? && !item.consumable
f.write(sprintf("Type = %s\r\n", type)) if type
f.write(sprintf("Flags = %s\r\n", item.flags.join(","))) if item.flags.length > 0
f.write(sprintf("Move = %s\r\n", item.move)) if item.move
f.write(sprintf("Description = %s\r\n", item.real_description))
end
@@ -303,6 +304,7 @@ module Compiler
f.write(sprintf("Pokedex = %s\r\n", species.real_pokedex_entry))
f.write(sprintf("FormName = %s\r\n", species.real_form_name)) if species.real_form_name && !species.real_form_name.empty?
f.write(sprintf("Generation = %d\r\n", species.generation)) if species.generation != 0
f.write(sprintf("Flags = %s\r\n", species.flags.join(","))) if species.flags.length > 0
f.write(sprintf("WildItemCommon = %s\r\n", species.wild_item_common)) if species.wild_item_common
f.write(sprintf("WildItemUncommon = %s\r\n", species.wild_item_uncommon)) if species.wild_item_uncommon
f.write(sprintf("WildItemRare = %s\r\n", species.wild_item_rare)) if species.wild_item_rare
@@ -324,7 +326,7 @@ module Compiler
param_type = evo_type_data.parameter
f.write(sprintf("%s,%s,", evo[0], evo_type_data.id.to_s))
if !param_type.nil?
if !GameData.const_defined?(param_type.to_sym) && param_type.is_a?(Symbol)
if param_type.is_a?(Symbol) && !GameData.const_defined?(param_type)
f.write(getConstantName(param_type, evo[2]))
else
f.write(evo[2].to_s)
@@ -405,6 +407,7 @@ module Compiler
f.write(sprintf("Category = %s\r\n", species.real_category)) if species.real_category != base_species.real_category
f.write(sprintf("Pokedex = %s\r\n", species.real_pokedex_entry)) if species.real_pokedex_entry != base_species.real_pokedex_entry
f.write(sprintf("Generation = %d\r\n", species.generation)) if species.generation != base_species.generation
f.write(sprintf("Flags = %s\r\n", species.flags.join(","))) if species.flags.length > 0 && species.flags != base_species.flags
if species.wild_item_common != base_species.wild_item_common ||
species.wild_item_uncommon != base_species.wild_item_uncommon ||
species.wild_item_rare != base_species.wild_item_rare
@@ -430,7 +433,7 @@ module Compiler
param_type = evo_type_data.parameter
f.write(sprintf("%s,%s,", evo[0], evo_type_data.id.to_s))
if !param_type.nil?
if !GameData.const_defined?(param_type.to_sym) && param_type.is_a?(Symbol)
if param_type.is_a?(Symbol) && !GameData.const_defined?(param_type)
f.write(getConstantName(param_type, evo[2]))
else
f.write(evo[2].to_s)
@@ -559,7 +562,7 @@ module Compiler
f.write(sprintf("Gender = %s\r\n", gender))
f.write(sprintf("BaseMoney = %d\r\n", t.base_money))
f.write(sprintf("SkillLevel = %d\r\n", t.skill_level)) if t.skill_level != t.base_money
f.write(sprintf("SkillFlags = %s\r\n", t.skill_flags.join(","))) if t.skill_flags.length > 0
f.write(sprintf("Flags = %s\r\n", t.flags.join(","))) if t.flags.length > 0
f.write(sprintf("IntroME = %s\r\n", t.intro_ME)) if !nil_or_empty?(t.intro_ME)
f.write(sprintf("BattleBGM = %s\r\n", t.battle_BGM)) if !nil_or_empty?(t.battle_BGM)
f.write(sprintf("VictoryME = %s\r\n", t.victory_ME)) if !nil_or_empty?(t.victory_ME)