More struct data
This commit is contained in:
parent
e9cf2c112e
commit
3a35eb73f0
|
@ -10,13 +10,13 @@ character_battle_sprite_layouts 0x14B997 /btl/ff5_btl.bin 0x028997 11 of 6 of u8
|
||||||
character_battle_sprite_disabled_palette 0x00F867 /mnu/memsave.bin 0x000034 Palette16Of555
|
character_battle_sprite_disabled_palette 0x00F867 /mnu/memsave.bin 0x000034 Palette16Of555
|
||||||
character_battle_sprite_stone_palette 0x00F807 N/A N/A Palette16Of555 Also 0x199835
|
character_battle_sprite_stone_palette 0x00F807 N/A N/A Palette16Of555 Also 0x199835
|
||||||
tiles_fist 0x11D710 /btl/ff5_btl.bin 0x021D10 TileSNES3bpp Also /mnu/men_bin.eng:0x00D910
|
tiles_fist 0x11D710 /btl/ff5_btl.bin 0x021D10 TileSNES3bpp Also /mnu/men_bin.eng:0x00D910
|
||||||
tbl_weapons 0x110000 128 of 12 of u8 length 0x600
|
tbl_weapons 0x110000 128 of WeaponData length 0x600
|
||||||
tbl_armors 0x110600 96 of 12 of u8 length 0x480
|
tbl_armors 0x110600 96 of ArmorData length 0x480
|
||||||
tbl_items 0x110A80 32 of 8 of u8 length 0x100
|
tbl_items 0x110A80 32 of ItemData length 0x100
|
||||||
tbl_magic 0x110B80 256 of 8 of u8 length 0x800
|
tbl_magic 0x110B80 256 of MagicData length 0x800
|
||||||
tbl_equip_types 0x112480 64 of 4 of u8 length 0x100 - Item Equipment type definitions (64x4 bytes, 2B weapon, 2B armor)
|
tbl_equip_types 0x112480 64 of 4 of u8 length 0x100 - Item Equipment type definitions (64x4 bytes, 2B weapon, 2B armor)
|
||||||
tbl_armors_elem_def 0x112580 64 of 5 of u8 length 0x140 - Item Armor Element defense 64x(5B - absorb, evade, immunity, half, weakness)
|
tbl_armors_elem_def 0x112580 64 of ElemDef length 0x140 - Item Armor Element defense 64x(5B - absorb, evade, immunity, half, weakness)
|
||||||
tbl_armors_status 0x1126C0 64 of 7 of u8 length 0x1C0 - Item Armor Status defense 64x(7B - 4B Initial, 3B Immune)
|
tbl_armors_status 0x1126C0 64 of StatusEffect length 0x1C0 - Item Armor Status defense 64x(7B - 4B Initial, 3B Immune)
|
||||||
tbl_prices_items 0x112A00 256 of ItemCost length 0x200
|
tbl_prices_items 0x112A00 256 of ItemCost length 0x200
|
||||||
tbl_prices_magic 0x112C00 128 of ItemCost length 0x100
|
tbl_prices_magic 0x112C00 128 of ItemCost length 0x100
|
||||||
tbl_charlevels_exp 0x115000 99 of u24
|
tbl_charlevels_exp 0x115000 99 of u24
|
||||||
|
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
struct AttackType
|
||||||
|
u1 is_blue_magic
|
||||||
|
u1 is_white_magic
|
||||||
|
u1 is_black_magic
|
||||||
|
u1 is_dimension_magic
|
||||||
|
u1 is_summon
|
||||||
|
u1 is_sound
|
||||||
|
u1 is_longrange
|
||||||
|
u1 is_physical
|
||||||
|
|
||||||
|
struct AttackProperties
|
||||||
|
u2 action_delay
|
||||||
|
u1 roulette
|
||||||
|
u1 target_enemy_by_default
|
||||||
|
u1 can_target_either_side
|
||||||
|
u1 can_select_target
|
||||||
|
u1 always_target_all
|
||||||
|
u1 can_target_all
|
||||||
|
|
||||||
|
struct WeaponData
|
||||||
|
AttackProperties attack_properties
|
||||||
|
AttackType attack_type
|
||||||
|
u6 item_type
|
||||||
|
u1 is_unthrowable
|
||||||
|
u1 byte_2_leftover
|
||||||
|
EquipStatBonus bonus
|
||||||
|
u6 description
|
||||||
|
u1 can_double_grip
|
||||||
|
u1 only_double_grip
|
||||||
|
u1 is_wonder_rod
|
||||||
|
u1 is_action_on_use
|
||||||
|
u1 can_magic_sword
|
||||||
|
u1 is_action_on_hit
|
||||||
|
u1 is_5.4
|
||||||
|
u1 is_initiative
|
||||||
|
u1 is_knife_parry
|
||||||
|
u1 is_sword_parry
|
||||||
|
u7 spell_cast
|
||||||
|
u1 is_break_after_use
|
||||||
|
u8 attack_power
|
||||||
|
u7 attack_effect
|
||||||
|
u1 byte_8_leftover
|
||||||
|
u8 param0 # accuracy_percent for sub-100 weapons, crit rate on katanas, element on Flametongue/Icebrand/Excalibur/AirKnife/Trident/WindSpear
|
||||||
|
u8 param1 # on_hit_effect_percent for weapons that cast actions on hit, also Rune weapons bonus attack power
|
||||||
|
u8 param2 # action_on_hit for weapons that cast actions on hit, Also Rune weapons 5 mana cost on attack, also element of attack for rods
|
||||||
|
|
||||||
|
struct ArmorData
|
||||||
|
u8 slot # b0 - 0x01 acc, 0x02 body, 0x04 head, 0x08 shield, 0xF0 unused
|
||||||
|
u8 weight # b1
|
||||||
|
u6 item_type
|
||||||
|
u1 is_unthrowable
|
||||||
|
u1 byte_2_leftover
|
||||||
|
EquipStatBonus bonus # b3
|
||||||
|
u6 description # b4
|
||||||
|
u2 byte_4_leftovers
|
||||||
|
u1 is_improve_catch # b5
|
||||||
|
u1 is_become_undead
|
||||||
|
u1 is_improve_dance
|
||||||
|
u1 is_halve_mp_cost
|
||||||
|
u1 is_improve_steal
|
||||||
|
u1 is_improve_brawl
|
||||||
|
u1 is_elf_cape_dodge
|
||||||
|
u1 is_block_all_magic # b5
|
||||||
|
u8 evasion # b6
|
||||||
|
u8 defense
|
||||||
|
u8 m_evasion
|
||||||
|
u8 m_def # b9
|
||||||
|
u8 elem_effect # b10 - 01 ½ lightning, 02 ½ all, 03 immune poison damage, 04 absorb fire+immune ice+weak water, 05 absorb water+immune fire+weak lightning, 06 Bone Mail (absorb poison, halve ice, weak fire/holy), 07 absorb fire, 08 absorb ice
|
||||||
|
u8 status_effect # b11 - 01 auto-regen, 02 auto-doom, 03 auto-haste + immune slow/stop/paralyse/sleep, 04 immune petrify, 05 Ribbon, 06 immune confuse, 07 immune silence, 08 immune blind, 09 immune poison, 0A bone mail, 0B auto-reflect, 0C immune mini, 0D immune old/zombie, 0E auto-sap + immune sleep, 0F auto-blink, 10 immune mini/paralyse, 11 immune confuse/mini, 12 immune confuse/toad, 13 immune toad/paralyse
|
||||||
|
|
||||||
|
|
||||||
|
struct ItemData
|
||||||
|
AttackProperties attack_properties
|
||||||
|
u8 attack_type
|
||||||
|
u1 unk0
|
||||||
|
u1 is_unmixable
|
||||||
|
u1 unk1
|
||||||
|
u1 is_magic_lamp
|
||||||
|
u1 is_undrinkable
|
||||||
|
u1 is_unusable_in_battle
|
||||||
|
u1 is_unthrowable
|
||||||
|
u1 unk2
|
||||||
|
u6 description # b3
|
||||||
|
u2 byte_3_leftovers
|
||||||
|
u7 attack_formula
|
||||||
|
u1 is_unavoidable
|
||||||
|
u8 param_0
|
||||||
|
u8 param_1
|
||||||
|
u8 param_2
|
||||||
|
|
||||||
|
|
||||||
|
struct MagicData
|
||||||
|
AttackProperties attack_properties
|
||||||
|
u8 attack_type
|
||||||
|
u4 meteo_extra_hits
|
||||||
|
u2 unk
|
||||||
|
u1 is_learnable
|
||||||
|
u1 is_monster_bit
|
||||||
|
u7 mp_cost
|
||||||
|
u1 is_unreflectable
|
||||||
|
u7 attack_formula
|
||||||
|
u1 is_unavoidable
|
||||||
|
u8 param_0
|
||||||
|
u8 param_1
|
||||||
|
u8 param_2
|
||||||
|
|
||||||
|
|
||||||
|
struct ElemDef
|
||||||
|
u8 absorb
|
||||||
|
u8 evade
|
||||||
|
u8 immune
|
||||||
|
u8 half
|
||||||
|
u8 weak
|
||||||
|
|
||||||
|
struct StatusEffect
|
||||||
|
4 of u8 initial
|
||||||
|
3 of u8 immune
|
Can't render this file because it has a wrong number of fields in line 43.
|
|
@ -31,7 +31,7 @@ func load_snes_rom(filename: String):
|
||||||
MapLoader.load_snes_rom(rom_snes)
|
MapLoader.load_snes_rom(rom_snes)
|
||||||
StringLoader.load_snes_rom(rom_snes, true)
|
StringLoader.load_snes_rom(rom_snes, true)
|
||||||
# Don't do this concurrently, avoid file pointer conflicts
|
# Don't do this concurrently, avoid file pointer conflicts
|
||||||
var _thread_error = thread.start(SoundLoader, 'parse_rom', rom_snes)
|
#var _thread_error = thread.start(SoundLoader, 'parse_rom', rom_snes)
|
||||||
# Can concurrently work with the preloaded StreamPeerBuffer though
|
# Can concurrently work with the preloaded StreamPeerBuffer though
|
||||||
for key in Common.SNES_PSX_addresses:
|
for key in Common.SNES_PSX_addresses:
|
||||||
var d = Common.SNES_PSX_addresses[key]
|
var d = Common.SNES_PSX_addresses[key]
|
||||||
|
@ -69,8 +69,29 @@ func _ready():
|
||||||
structdefs.merge(STRUCT.get_base_structarraytypes())
|
structdefs.merge(STRUCT.get_base_structarraytypes())
|
||||||
structdefs.merge(STRUCT_SNES.get_structtypes())
|
structdefs.merge(STRUCT_SNES.get_structtypes())
|
||||||
STRUCT.parse_struct_definitions_from_tsv_filename('res://data/SNES_save.tsv', structdefs)
|
STRUCT.parse_struct_definitions_from_tsv_filename('res://data/SNES_save.tsv', structdefs)
|
||||||
|
STRUCT.parse_struct_definitions_from_tsv_filename('res://data/SNES_other.tsv', structdefs)
|
||||||
var _error := psx_productcode_regex.compile('(S[A-Z]{3}_\\d{3}\\.\\d{2});(\\d)')
|
var _error := psx_productcode_regex.compile('(S[A-Z]{3}_\\d{3}\\.\\d{2});(\\d)')
|
||||||
load_snes_rom(ROM_filename)
|
load_snes_rom(ROM_filename)
|
||||||
|
# Debugging breakpoint
|
||||||
|
for i in 128:
|
||||||
|
var weapon = snes_data.tbl_weapons[i]
|
||||||
|
if weapon.byte_2_leftover:
|
||||||
|
print('Weapon %d ($%02X) has byte_2_leftover set' % [i, i])
|
||||||
|
if weapon.byte_8_leftover:
|
||||||
|
print('Weapon %d ($%02X) has byte_8_leftover set' % [i, i])
|
||||||
|
if weapon['is_5.4']:
|
||||||
|
print('Weapon %d ($%02X) has 5.4 set' % [i, i])
|
||||||
|
for i in 96:
|
||||||
|
var armor = snes_data.tbl_armors[i]
|
||||||
|
if armor.byte_0_leftover:
|
||||||
|
print('Armor %d ($%02X) "%s" has byte_0_leftover set' % [i, i, StringLoader.tables.items[i+0x80]])
|
||||||
|
if armor.byte_4_leftovers:
|
||||||
|
print('Armor %d ($%02X) "%s" has byte_4_leftovers set' % [i, i, StringLoader.tables.items[i+0x80]])
|
||||||
|
if armor.byte_2_leftovers:
|
||||||
|
print('Armor %d ($%02X) "%s" has byte_2_leftovers set to %d ($%02X)' % [i, i, StringLoader.tables.items[i+0x80], armor.byte_2_leftovers, armor.byte_2_leftovers])
|
||||||
|
if armor.gear_special:
|
||||||
|
print('Armor %d ($%02X) "%s" has gear_special set to %d ($%02X)' % [i, i, StringLoader.tables.items[i+0x80], armor.gear_special, armor.gear_special])
|
||||||
|
pass
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
func _exit_tree() -> void:
|
||||||
thread.wait_to_finish()
|
thread.wait_to_finish()
|
||||||
|
|
|
@ -53,6 +53,47 @@ class ItemCost extends STRUCT.StructType:
|
||||||
var sell_price := -1 if not is_sellable else (5 if is_sellprice_5gil else buy_price/2)
|
var sell_price := -1 if not is_sellable else (5 if is_sellprice_5gil else buy_price/2)
|
||||||
return {'buy_price': buy_price, 'sell_price': sell_price}
|
return {'buy_price': buy_price, 'sell_price': sell_price}
|
||||||
|
|
||||||
|
# Unions aren't covered by my DSL yet
|
||||||
|
class EquipStatBonus extends STRUCT.StructType:
|
||||||
|
static func get_stat_bonuses(affected_stats: int, bonus: int, base: int = 0) -> Dictionary:
|
||||||
|
var stats := {Common.STAT_STR: base, Common.STAT_SPD: base, Common.STAT_VIT: base, Common.STAT_MAG: base}
|
||||||
|
if affected_stats & 0x1:
|
||||||
|
stats[Common.STAT_MAG] += bonus
|
||||||
|
if affected_stats & 0x2:
|
||||||
|
stats[Common.STAT_VIT] += bonus
|
||||||
|
if affected_stats & 0x4:
|
||||||
|
stats[Common.STAT_SPD] += bonus
|
||||||
|
if affected_stats & 0x8:
|
||||||
|
stats[Common.STAT_STR] += bonus
|
||||||
|
return stats
|
||||||
|
|
||||||
|
func get_value(buffer: StreamPeer, leftover_bits: Array):
|
||||||
|
var b0 := buffer.get_u8()
|
||||||
|
var is_stat_bonus = b0 >> 7
|
||||||
|
if is_stat_bonus:
|
||||||
|
var affected_stats := (b0 >> 3) & 0x0F # "0" maryoku, "1": tairyoku, "2": subayasa, "3": chikara
|
||||||
|
var stats := [{}, {}]
|
||||||
|
var bonus := b0 & 0x07
|
||||||
|
match bonus:
|
||||||
|
0:
|
||||||
|
return get_stat_bonuses(affected_stats, 1)
|
||||||
|
1:
|
||||||
|
return get_stat_bonuses(affected_stats, 2)
|
||||||
|
2:
|
||||||
|
return get_stat_bonuses(affected_stats, 3)
|
||||||
|
3: # unused? "+1/-1/+1/-1"
|
||||||
|
return {Common.STAT_STR: 1, Common.STAT_SPD: -1, Common.STAT_VIT: 1, Common.STAT_MAG: -1}
|
||||||
|
4: # unused? "-1 (to unselected stats)"
|
||||||
|
return get_stat_bonuses(affected_stats, 1, -1)
|
||||||
|
5: # Giant's Glove: +5 -5 +5 -5
|
||||||
|
return {Common.STAT_STR: 5, Common.STAT_SPD: -5, Common.STAT_VIT: 5, Common.STAT_MAG: -5}
|
||||||
|
6: # Bone Mail: -5 to unselected stats
|
||||||
|
return get_stat_bonuses(affected_stats, 5, -5)
|
||||||
|
7:
|
||||||
|
return get_stat_bonuses(affected_stats, 5)
|
||||||
|
else: # is Element bitfield
|
||||||
|
return {'elemental_bonus': b0 & 0x7F}
|
||||||
|
|
||||||
static func get_structtypes() -> Dictionary:
|
static func get_structtypes() -> Dictionary:
|
||||||
return {
|
return {
|
||||||
'TileSNESMode7': TileSNESMode7.new(),
|
'TileSNESMode7': TileSNESMode7.new(),
|
||||||
|
@ -65,4 +106,5 @@ static func get_structtypes() -> Dictionary:
|
||||||
'Palette16Of555': PaletteOf555.new(16),
|
'Palette16Of555': PaletteOf555.new(16),
|
||||||
'Palette128Of555': PaletteOf555.new(128),
|
'Palette128Of555': PaletteOf555.new(128),
|
||||||
'ItemCost': ItemCost.new(),
|
'ItemCost': ItemCost.new(),
|
||||||
|
'EquipStatBonus': EquipStatBonus.new(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,20 @@ var last_resolution_pre_shrink := Vector2.ZERO
|
||||||
|
|
||||||
var SNES_PSX_addresses := load_tsv('res://data/SNES_PSX_addresses.tsv')
|
var SNES_PSX_addresses := load_tsv('res://data/SNES_PSX_addresses.tsv')
|
||||||
|
|
||||||
|
# Canonicalize english stat names within the codebase
|
||||||
|
# This is based off of FF8, and is more or less RPGe but with Speed instead of Agility
|
||||||
|
# I don't like Vigor or Stamina, Agility could go either way but I side with FF8 and FF9 rather than FF10
|
||||||
|
enum {
|
||||||
|
STAT_STRENGTH = 0,
|
||||||
|
STAT_STR = 0,
|
||||||
|
STAT_SPEED = 1,
|
||||||
|
STAT_SPD = 1,
|
||||||
|
STAT_VITALITY = 2,
|
||||||
|
STAT_VIT = 2,
|
||||||
|
STAT_MAGIC = 3,
|
||||||
|
STAT_MAG = 3,
|
||||||
|
}
|
||||||
|
|
||||||
static func eval(expression: String):
|
static func eval(expression: String):
|
||||||
var ex = Expression.new()
|
var ex = Expression.new()
|
||||||
match ex.parse(expression):
|
match ex.parse(expression):
|
||||||
|
|
Loading…
Reference in New Issue