Add string loading

Required for party menu changes
Also move menu colour to a new Manager
Common is now a Manager too
Rename the loaders from snake_case
This commit is contained in:
Luke Hubmayer-Werner 2023-08-04 18:17:08 +09:30
parent 0514011cd2
commit c76d00bc3c
28 changed files with 2126 additions and 158 deletions

2
PC.gd
View File

@ -50,6 +50,8 @@ func _process(_delta):
# pass # pass
func _draw(): func _draw():
if self.texture == null:
return
var frames = Animation_Frames[animation] var frames = Animation_Frames[animation]
var frame = frames[int(globals.time*4) % len(frames)] var frame = frames[int(globals.time*4) % len(frames)]
var y = 0 var y = 0

View File

@ -0,0 +1,256 @@
\n
"
'
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
il
it
li
ll
'
"
:
;
,
(
)
/
!
?
.
ti
fi
pe
l
'
"
if
lt
tl
ir
tt
%
/
:
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
°C

View File

@ -0,0 +1,256 @@
 
\n
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
%
/
:
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
°C
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

View File

@ -0,0 +1,426 @@
使
殿
姿
西
宿
 

View File

@ -0,0 +1,256 @@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[stone]
[toad]
[mini]
[float]
[poison]
[KO]
[blind]
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
il
it
li
ll
'
"
:
;
,
(
)
/
!
?
.
ti
fi
Bl
a
pe
l
'
"
if
lt
tl
ir
tt
[key]
[shoe]
[hammer]
[ribbon]
[potion]
[shirt]
-
[shuriken]
[scroll]
!
[claw]
?
[glove]
%
/
:
.
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
[sword]
[wh.mag]
[blk.mag]
🕒
[knife]
[spear]
[axe]
[katana]
[rod]
[staff]
[bow]
[harp]
[whip]
[bell]
[shield]
[helmet]
[armor]
[ring]

View File

@ -0,0 +1,256 @@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[stone]
[toad]
[mini]
[float]
[poison]
[KO]
[blind]
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
%
/
:
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
[洋剣]
[wh.mag]
[blk.mag]
🕒
[刂]
[槍]
[鉞]
[刀]
[棒]
[杖]
[弓]
[鞭]
[bell]
[shield]
[helmet]
[armor]
[ring]

View File

@ -0,0 +1,256 @@
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
%
/
:
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
[洋剣]
[wh.mag]
[blk.mag]
🕒
[刂]
[槍]
[鉞]
[刀]
[棒]
[杖]
[弓]
[鞭]
[bell]
[shield]
[helmet]
[armor]
[ring]

12
data/string_blocks.tsv Normal file
View File

@ -0,0 +1,12 @@
name num_entries address snes_address bytes snes_bytes rpge_ptr_offset snes_ptr_offset dialog null_terminated
ability_names 33 0x116200 8
battle_commands 96 0x201150 0x115800 7 5
character_names 5 0x115500 6
dialogue 0x900 0x2013F0 0x082220 3 2 0x000000 0x0A0000 True
enemy_names 384 0x200050 0x105C00 10 8
items 0x100 0x111380 9
job_names 22 0x115600 8
magics 87 0x111C80 6
magics2 73 0x111E8A 9
menu_strings 139 0x00F987 2 0x270000 0x000000 True
zone_names 0x100 0x107000 2 0x270000 0x107200 True
1 name num_entries address snes_address bytes snes_bytes rpge_ptr_offset snes_ptr_offset dialog null_terminated
2 ability_names 33 0x116200 8
3 battle_commands 96 0x201150 0x115800 7 5
4 character_names 5 0x115500 6
5 dialogue 0x900 0x2013F0 0x082220 3 2 0x000000 0x0A0000 True
6 enemy_names 384 0x200050 0x105C00 10 8
7 items 0x100 0x111380 9
8 job_names 22 0x115600 8
9 magics 87 0x111C80 6
10 magics2 73 0x111E8A 9
11 menu_strings 139 0x00F987 2 0x270000 0x000000 True
12 zone_names 0x100 0x107000 2 0x270000 0x107200 True

View File

@ -4,7 +4,7 @@
[ext_resource path="res://theme/menu_theme.tres" type="Theme" id=2] [ext_resource path="res://theme/menu_theme.tres" type="Theme" id=2]
[ext_resource path="res://widgets/ColorMenu.tscn" type="PackedScene" id=3] [ext_resource path="res://widgets/ColorMenu.tscn" type="PackedScene" id=3]
[ext_resource path="res://theme/border_imagetexture.tres" type="Texture" id=4] [ext_resource path="res://theme/border_imagetexture.tres" type="Texture" id=4]
[ext_resource path="res://party_menu.tscn" type="PackedScene" id=5] [ext_resource path="res://widgets/PartyMenu.tscn" type="PackedScene" id=5]
[ext_resource path="res://widgets/RomSelect.tscn" type="PackedScene" id=6] [ext_resource path="res://widgets/RomSelect.tscn" type="PackedScene" id=6]
[node name="main_menu" type="Control"] [node name="main_menu" type="Control"]
@ -58,7 +58,5 @@ From here"
[node name="RomSelect" parent="." instance=ExtResource( 6 )] [node name="RomSelect" parent="." instance=ExtResource( 6 )]
[node name="ColorMenu" parent="." instance=ExtResource( 3 )] [node name="ColorMenu" parent="." instance=ExtResource( 3 )]
margin_left = 548.0 margin_left = 384.0
margin_top = 288.0 margin_right = 469.0
margin_right = 633.0
margin_bottom = 352.0

View File

@ -22,13 +22,15 @@ config/icon="res://icon.png"
[autoload] [autoload]
globals="*res://globals.gd" globals="*res://globals.gd"
Common="*res://scripts/loaders/common.gd" Common="*res://scripts/managers/Common.gd"
CommonGBA="*res://scripts/loaders/common_gba.gd" CommonGBA="*res://scripts/loaders/gba/common.gd"
SoundLoader="*res://scripts/loaders/sound_loader.gd" SoundLoader="*res://scripts/loaders/SoundLoader.gd"
SpriteLoader="*res://scripts/loaders/sprite_loader.gd" SpriteLoader="*res://scripts/loaders/SpriteLoader.gd"
MapLoader="*res://scripts/loaders/map_loader.gd" MapLoader="*res://scripts/loaders/MapLoader.gd"
RomLoader="*res://scripts/loaders/rom_loader.gd" RomLoader="*res://scripts/loaders/RomLoader.gd"
SaveLoader="*res://scripts/loaders/save_loader.gd" SaveLoader="*res://scripts/loaders/SaveLoader.gd"
ThemeManager="*res://scripts/managers/ThemeManager.gd"
StringLoader="*res://scripts/loaders/StringLoader.gd"
[debug] [debug]

View File

@ -20,6 +20,7 @@ func load_snes_rom(filename: String):
if error == OK: if error == OK:
SpriteLoader.load_snes_rom(rom_snes) SpriteLoader.load_snes_rom(rom_snes)
MapLoader.load_snes_rom(rom_snes) MapLoader.load_snes_rom(rom_snes)
StringLoader.load_snes_rom(rom_snes, true)
var _thread_error = thread.start(SoundLoader, 'parse_rom', rom_snes) var _thread_error = thread.start(SoundLoader, 'parse_rom', rom_snes)
func load_psx_folder(_dirname: String): func load_psx_folder(_dirname: String):

View File

@ -57,6 +57,12 @@ func put_struct(buffer: StreamPeer, struct_name: String, data: Dictionary):
func deserialize_save_slot(buffer: StreamPeerBuffer) -> Dictionary: func deserialize_save_slot(buffer: StreamPeerBuffer) -> Dictionary:
return struct_types['Save_slot'].get_value(buffer, [0, 0]) return struct_types['Save_slot'].get_value(buffer, [0, 0])
func load_save_slot(buffer: StreamPeerBuffer) -> Dictionary:
# Like deserialize_save_slot, but also decodes strings and maybe other postprocessing later
var data = deserialize_save_slot(buffer)
data.character_names_decoded = StringLoader.decode_array(data.character_names, 'RPGe_small')
return data
func serialize_save_slot(data: Dictionary) -> StreamPeerBuffer: func serialize_save_slot(data: Dictionary) -> StreamPeerBuffer:
var buffer := StreamPeerBuffer.new() var buffer := StreamPeerBuffer.new()
struct_types['Save_slot'].put_value(buffer, data, [0, 0]) struct_types['Save_slot'].put_value(buffer, data, [0, 0])

View File

@ -0,0 +1,97 @@
extends Node
var SNES_block_addresses := Common.load_tsv('res://data/string_blocks.tsv')
var tables_raw = {}
var tables = {}
var glyph_tables := {
'RPGe_dialog': Common.load_glyph_table('res://data/glyph_tables/Glyphs_dialog_RPGe.txt'),
'RPGe_small': Common.load_glyph_table('res://data/glyph_tables/Glyphs_small_RPGe.txt'),
'SNES_dialog': Common.load_glyph_table('res://data/glyph_tables/Glyphs_dialog_SNES.txt'),
'SNES_kanji': Common.load_glyph_table('res://data/glyph_tables/Glyphs_dialog_kanji_SNES.txt'),
'SNES_small': Common.load_glyph_table('res://data/glyph_tables/Glyphs_small_SNES.txt'),
}
static func decode_string(bytes, glyph_table: PoolStringArray, trim_trailing_whitespace: bool = true) -> String:
# Trivial conversion for small text
# Dialog requires multibyte handling including kanji and other macros
var output = ''
for c in bytes:
output += glyph_table[c]
return output.trim_suffix(' ') if trim_trailing_whitespace else output
func decode_array(array, glyph_table, trim_trailing_whitespace: bool = true) -> PoolStringArray:
if glyph_table is String:
glyph_table = glyph_tables[glyph_table]
var output = PoolStringArray()
for s in array:
output.append(decode_string(s, glyph_table, trim_trailing_whitespace))
return output
func load_snes_rom(rom: File, is_RPGe: bool = false) -> void:
for block_name in SNES_block_addresses:
var block: Dictionary = SNES_block_addresses[block_name]
var glyph_table_small: PoolStringArray = glyph_tables.RPGe_small if is_RPGe else glyph_tables.SNES_small
var raw_strings := []
var strings := PoolStringArray()
var num_entries: int = block.num_entries
var l1_width: int = block.bytes
if (not is_RPGe) and block.snes_bytes:
l1_width = block.snes_bytes
var l1_address: int = block.address
if (not is_RPGe) and block.snes_address:
l1_address = block.snes_address
rom.seek(l1_address)
var ptr_offset = block.rpge_ptr_offset if is_RPGe else block.snes_ptr_offset
if ptr_offset is int:
var ptrs = PoolIntArray()
match l1_width:
1:
for i in num_entries:
ptrs.append((ptr_offset + rom.get_8()) & 0x3FFFFF) # Bank wrapping
2:
for i in num_entries:
ptrs.append((ptr_offset + rom.get_16()) & 0x3FFFFF) # Bank wrapping
3:
for i in num_entries:
ptrs.append((ptr_offset + rom.get_16() + (rom.get_8() << 16)) & 0x3FFFFF) # Bank wrapping
_:
assert(false, 'Indirect l1_width of %d is not possible' % l1_width)
if block.null_terminated:
for i in num_entries:
rom.seek(ptrs[i])
var bytes = PoolByteArray()
while true:
var b = rom.get_8()
if b == 0:
break
bytes.append(b)
raw_strings.append(bytes)
else:
for i in num_entries-1:
rom.seek(ptrs[i])
raw_strings.append(rom.get_buffer(ptrs[i+1] - ptrs[i]))
else:
# Get first level of data
for i in num_entries:
raw_strings.append(rom.get_buffer(l1_width))
# Decode
if block.dialog:
pass # TODO
else:
for raw in raw_strings:
strings.append(decode_string(raw, glyph_table_small))
tables_raw[block_name] = raw_strings
tables[block_name] = strings
func get_ability_name(id: int) -> String:
var l = 128
if id < l:
return tables.battle_commands[id]
else:
return tables.ability_names[id-l]
func _ready() -> void:
pass

View File

@ -4,6 +4,16 @@ var base_resolution: Vector2 = Vector2(ProjectSettings.get_setting('display/wind
var shrink_timer := Timer.new() var shrink_timer := Timer.new()
var last_resolution_pre_shrink := Vector2.ZERO var last_resolution_pre_shrink := Vector2.ZERO
var SNES_PSX_addresses := load_tsv('res://data/SNES_PSX_addresses.tsv')
static func eval(expression: String):
var ex = Expression.new()
match ex.parse(expression):
OK:
return ex.execute()
var error:
print_debug(ex.get_error_text(), error)
static func load_json(filename: String): # Valid JSON will return Array or Dictionary. int error code for anything else. static func load_json(filename: String): # Valid JSON will return Array or Dictionary. int error code for anything else.
var file := File.new() var file := File.new()
match file.open(filename, File.READ): match file.open(filename, File.READ):
@ -49,6 +59,18 @@ static func save_json(filename: String, data) -> int: # Returns error code but
file.store_line(_to_json(data, 0)) file.store_line(_to_json(data, 0))
return OK return OK
static func load_glyph_table(filename: String) -> PoolStringArray:
var output = PoolStringArray()
var file = File.new()
match file.open(filename, File.READ):
OK:
var l: int = file.get_len()
while file.get_position() < l:
output.append(file.get_line())
var error:
print_debug('Failed to open glyph table "%s" - %d' % [filename, error])
return output
static func genericize_type(type: int) -> int: static func genericize_type(type: int) -> int:
match type: match type:
TYPE_RAW_ARRAY, TYPE_INT_ARRAY, TYPE_REAL_ARRAY, TYPE_STRING_ARRAY: TYPE_RAW_ARRAY, TYPE_INT_ARRAY, TYPE_REAL_ARRAY, TYPE_STRING_ARRAY:
@ -103,6 +125,28 @@ static func are_arrays_equal(a1: Array, a2: Array, fuzzy_types: bool = true) ->
return false return false
return true return true
static func limited_eval(token: String):
# Try hexadecimal literal
if token.begins_with('0x'):
var hex := token.hex_to_int()
if hex > 0:
return hex
# Try int literal
if token.is_valid_integer():
return int(token)
# Try float literal
if token.is_valid_float():
return float(token)
# Try bool literal
match token.to_lower():
'true':
return true
'false':
return false
# It's just a string
return token
static func load_tsv(filename: String, delimiter: String = '\t') -> Dictionary: static func load_tsv(filename: String, delimiter: String = '\t') -> Dictionary:
var file := File.new() var file := File.new()
var error := file.open(filename, File.READ) var error := file.open(filename, File.READ)
@ -115,19 +159,12 @@ static func load_tsv(filename: String, delimiter: String = '\t') -> Dictionary:
var entry := {} var entry := {}
for i in range(1, n): for i in range(1, n):
if line.size() > i: if line.size() > i:
var token := line[i] entry[headers[i]] = limited_eval(line[i])
entry[headers[i]] = token
if token.begins_with('0x'):
var hex := token.hex_to_int()
if hex > 0:
entry[headers[i]] = hex
output[line[0]] = entry output[line[0]] = entry
return output return output
print_debug(error) print_debug(error)
return {} return {}
var SNES_PSX_addresses := load_tsv('res://data/SNES_PSX_addresses.tsv')
func shrink_to_integer(): func shrink_to_integer():
var size := OS.get_window_size() var size := OS.get_window_size()
var scale_vec := size / base_resolution var scale_vec := size / base_resolution
@ -160,6 +197,12 @@ func update_window_scale():
shrink_timer.start(1) shrink_timer.start(1)
get_tree().set_screen_stretch(SceneTree.STRETCH_MODE_VIEWPORT, SceneTree.STRETCH_ASPECT_KEEP, base_resolution*scale, scale) get_tree().set_screen_stretch(SceneTree.STRETCH_MODE_VIEWPORT, SceneTree.STRETCH_ASPECT_KEEP, base_resolution*scale, scale)
static func game_time_frames_to_hhmm(game_time_frames: int) -> String:
var game_seconds = game_time_frames / 60
var game_minutes = game_seconds / 60
var game_hours = game_minutes / 60
return '%d:%02d' % [game_hours, game_minutes % 60]
func _ready(): func _ready():
shrink_timer.connect('timeout', self, 'shrink_to_integer') shrink_timer.connect('timeout', self, 'shrink_to_integer')
shrink_timer.one_shot = true shrink_timer.one_shot = true

View File

@ -0,0 +1,33 @@
extends Node
var menu_r5 := 0
var menu_g5 := 0
var menu_b5 := 16
var border_image: Image = preload('res://theme/border.png')
var border_texture := preload('res://theme/border_imagetexture.tres')
var border_stylebox := preload('res://theme/border_stylebox.tres')
const r1 := Rect2(4, 3, 2, 4)
const r2 := Rect2(3, 4, 4, 2)
func update_menu_color() -> void:
var c := Color(menu_r5/31.0, menu_g5/31.0, menu_b5/31.0)
# print(c)
border_image.fill_rect(r1, c)
border_image.fill_rect(r2, c)
border_texture.set_data(border_image)
func set_menu_color_555(r5: int, g5: int, b5: int) -> void:
self.menu_r5 = r5
self.menu_g5 = g5
self.menu_b5 = b5
self.update_configuration_warning()
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
border_texture.create_from_image(border_image, 0)
self.update_menu_color()
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta: float) -> void:
# pass

View File

@ -191,7 +191,8 @@ static func get_structarraytype(type: String, existing_structs: Dictionary):
static func parse_struct_definitions_from_tsv_file(tsv_file: File, existing_structs: Dictionary) -> void: static func parse_struct_definitions_from_tsv_file(tsv_file: File, existing_structs: Dictionary) -> void:
var current_struct: Struct var current_struct: Struct
var line_num := 0 # Currently only used for step-through debugging var line_num := 0 # Currently only used for step-through debugging
while tsv_file.get_position() < tsv_file.get_len(): var l := tsv_file.get_len()
while tsv_file.get_position() < l:
var line := tsv_file.get_csv_line('\t') var line := tsv_file.get_csv_line('\t')
line_num += 1 line_num += 1
var size = line.size() var size = line.size()

View File

@ -1,4 +1,4 @@
extends Node2D extends Control
var save_slots = [] var save_slots = []
var save_slot_dicts = [] var save_slot_dicts = []
@ -10,7 +10,7 @@ func _ready():
if error == OK: if error == OK:
for i in 4: for i in 4:
save_slots.append(SaveLoader.get_save_slot(save_file, i)) save_slots.append(SaveLoader.get_save_slot(save_file, i))
save_slot_dicts.append(SaveLoader.get_struct(save_slots[i], 'Save_slot')) save_slot_dicts.append(SaveLoader.load_save_slot(save_slots[i]))
print('Loaded test save file') print('Loaded test save file')
save_file.close() save_file.close()
# error = save_file.open('downloaded_saves/psx_world1.gme', File.READ) # error = save_file.open('downloaded_saves/psx_world1.gme', File.READ)
@ -19,3 +19,4 @@ func _ready():
# save_file.seek(0x2FA0) # save_file.seek(0x2FA0)
# buffer.data_array = save_file.get_buffer(0x600) # buffer.data_array = save_file.get_buffer(0x600)
# save_slot_dicts.append(SaveLoader.get_struct(buffer, 'Save_slot')) # save_slot_dicts.append(SaveLoader.get_struct(buffer, 'Save_slot'))
$PartyMenu.update_labels(save_slot_dicts[0])

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=7 format=2] [gd_scene load_steps=7 format=2]
[ext_resource path="res://palette_mat.tres" type="Material" id=1] [ext_resource path="res://widgets/PartyMenu.tscn" type="PackedScene" id=1]
[ext_resource path="res://test/worldmap_system.tscn" type="PackedScene" id=2] [ext_resource path="res://test/worldmap_system.tscn" type="PackedScene" id=2]
[ext_resource path="res://test_scene.gd" type="Script" id=3] [ext_resource path="res://test_scene.gd" type="Script" id=3]
[ext_resource path="res://test/battle_sprites.tscn" type="PackedScene" id=4] [ext_resource path="res://test/battle_sprites.tscn" type="PackedScene" id=4]
@ -11,15 +11,16 @@
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
theme = ExtResource( 6 ) theme = ExtResource( 6 )
[node name="Node2D" type="Node2D" parent="."]
material = ExtResource( 1 )
position = Vector2( 16, 16 )
script = ExtResource( 3 ) script = ExtResource( 3 )
[node name="audio_system" parent="." instance=ExtResource( 5 )] [node name="audio_system" parent="." instance=ExtResource( 5 )]
position = Vector2( 0, 400 ) visible = false
position = Vector2( 0, 160 )
[node name="worldmap_system" parent="." instance=ExtResource( 2 )] [node name="worldmap_system" parent="." instance=ExtResource( 2 )]
visible = false
[node name="battle_sprites" parent="." instance=ExtResource( 4 )] [node name="battle_sprites" parent="." instance=ExtResource( 4 )]
visible = false
[node name="PartyMenu" parent="." instance=ExtResource( 1 )]

View File

@ -3,24 +3,11 @@ var r := 0
var g := 0 var g := 0
var b := 16 var b := 16
var border_image: Image = preload('res://theme/border.png')
var border_texture := preload('res://theme/border_imagetexture.tres')
var border_stylebox := preload('res://theme/border_stylebox.tres')
const r1 := Rect2(4, 3, 2, 4)
const r2 := Rect2(3, 4, 4, 2)
func update_menu_color() -> void: func update_menu_color() -> void:
var c := Color(r/31.0, g/31.0, b/31.0)
# print(c)
$label_nums.text = '\n%d\n%d\n%d' % [r, g, b] $label_nums.text = '\n%d\n%d\n%d' % [r, g, b]
border_image.fill_rect(r1, c) ThemeManager.set_menu_color_555(r, g, b)
border_image.fill_rect(r2, c)
border_texture.set_data(border_image)
# border_stylebox.texture = border_texture
# update()
func _ready() -> void: func _ready() -> void:
border_texture.create_from_image(border_image, 0)
$slider_r.value = r $slider_r.value = r
$slider_g.value = g $slider_g.value = g
$slider_b.value = b $slider_b.value = b

21
widgets/PartyMenu.gd Normal file
View File

@ -0,0 +1,21 @@
extends Panel
func update_labels(data: Dictionary):
var characters = data.characters
var character_panels = $characters.get_children()
for i in len(characters):
var p = character_panels[i]
p.visible = not characters[i].is_absent
p.update_labels(data, i)
$rightside/panel_time/VBoxContainer/lbl_time.text = Common.game_time_frames_to_hhmm(data.game_time_frames)
$rightside/panel_gil/VBoxContainer/lbl_gilcount.text = '%d' % data.current_gil
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta: float) -> void:
# pass

View File

@ -1,12 +1,14 @@
[gd_scene load_steps=3 format=2] [gd_scene load_steps=4 format=2]
[ext_resource path="res://theme/menu_theme.tres" type="Theme" id=1] [ext_resource path="res://theme/menu_theme.tres" type="Theme" id=1]
[ext_resource path="res://widgets/PartyMenuCharacter.tscn" type="PackedScene" id=2] [ext_resource path="res://widgets/PartyMenu.gd" type="Script" id=2]
[ext_resource path="res://widgets/PartyMenuCharacter.tscn" type="PackedScene" id=3]
[node name="Panel" type="Panel"] [node name="PartyMenu" type="Panel"]
margin_right = 264.0 margin_right = 264.0
margin_bottom = 240.0 margin_bottom = 240.0
theme = ExtResource( 1 ) theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="characters" type="VBoxContainer" parent="."] [node name="characters" type="VBoxContainer" parent="."]
anchor_right = 1.0 anchor_right = 1.0
@ -16,18 +18,22 @@ margin_top = 8.0
margin_right = -8.0 margin_right = -8.0
margin_bottom = -8.0 margin_bottom = -8.0
[node name="PartyMenuCharacter" parent="characters" instance=ExtResource( 2 )] [node name="PartyMenuCharacter" parent="characters" instance=ExtResource( 3 )]
margin_right = 240.0
[node name="PartyMenuCharacter2" parent="characters" instance=ExtResource( 2 )] [node name="PartyMenuCharacter2" parent="characters" instance=ExtResource( 3 )]
margin_top = 58.0 margin_top = 58.0
margin_right = 240.0
margin_bottom = 108.0 margin_bottom = 108.0
[node name="PartyMenuCharacter3" parent="characters" instance=ExtResource( 2 )] [node name="PartyMenuCharacter3" parent="characters" instance=ExtResource( 3 )]
margin_top = 116.0 margin_top = 116.0
margin_right = 240.0
margin_bottom = 166.0 margin_bottom = 166.0
[node name="PartyMenuCharacter4" parent="characters" instance=ExtResource( 2 )] [node name="PartyMenuCharacter4" parent="characters" instance=ExtResource( 3 )]
margin_top = 174.0 margin_top = 174.0
margin_right = 240.0
margin_bottom = 224.0 margin_bottom = 224.0
[node name="rightside" type="VBoxContainer" parent="."] [node name="rightside" type="VBoxContainer" parent="."]
@ -136,16 +142,16 @@ margin_right = 60.0
margin_bottom = 32.0 margin_bottom = 32.0
custom_constants/separation = 0 custom_constants/separation = 0
[node name="lbl_time" type="Label" parent="rightside/panel_time/VBoxContainer"] [node name="TIME" type="Label" parent="rightside/panel_time/VBoxContainer"]
margin_right = 56.0 margin_right = 56.0
margin_bottom = 14.0 margin_bottom = 14.0
text = "Time" text = "Time"
[node name="lbl_ability" type="Label" parent="rightside/panel_time/VBoxContainer"] [node name="lbl_time" type="Label" parent="rightside/panel_time/VBoxContainer"]
margin_top = 14.0 margin_top = 14.0
margin_right = 56.0 margin_right = 56.0
margin_bottom = 28.0 margin_bottom = 28.0
text = "9:42" text = "0:00"
align = 2 align = 2
[node name="panel_gil" type="PanelContainer" parent="rightside"] [node name="panel_gil" type="PanelContainer" parent="rightside"]
@ -164,10 +170,10 @@ custom_constants/separation = 0
[node name="lbl_gilcount" type="Label" parent="rightside/panel_gil/VBoxContainer"] [node name="lbl_gilcount" type="Label" parent="rightside/panel_gil/VBoxContainer"]
margin_right = 64.0 margin_right = 64.0
margin_bottom = 14.0 margin_bottom = 14.0
text = "36988" text = "0"
align = 2 align = 2
[node name="lbl_gil" type="Label" parent="rightside/panel_gil/VBoxContainer"] [node name="GIL" type="Label" parent="rightside/panel_gil/VBoxContainer"]
margin_top = 14.0 margin_top = 14.0
margin_right = 64.0 margin_right = 64.0
margin_bottom = 28.0 margin_bottom = 28.0

View File

@ -1,24 +1,38 @@
extends ReferenceRect extends ReferenceRect
func update_labels(data: Dictionary): onready var rect_frontrow := Rect2($ref0/ref_frontrow.rect_position, $ref0/ref_frontrow.rect_size)
var character = data.character_id onready var rect_backrow := Rect2($ref0/ref_backrow.rect_position, $ref0/ref_backrow.rect_size)
$lbl_lv_cur.text = data.level onready var row_rects := [rect_frontrow, rect_backrow]
$lbl_abp_lv_cur.text = data.current_job_level + '-'
$lbl_abp_progress.text = data.current_job_abp + '/' func update_labels(data: Dictionary, i: int):
$lbl_abp_next.text = data.current_job_abp # Revisit var c = data.characters[i]
$lbl_hp_cur.text = data.hp_current + '/' var character = c.character_id
$lbl_hp_max.text = data.hp_max var job = c.current_job_id
$lbl_mp_cur.text = data.mp_current + '/' var cj_idx = character*22 + job
$lbl_mp_max.text = data.mp_max $ref0/lbl_name.text = data.character_names_decoded[character]
$lbl_lv_cur.text = data.level $ref0/lbl_lv_cur.text = '%d' % c.level
$ref1/lbl_job.text = StringLoader.tables.job_names[job]
$ref1/lbl_abp_lv_cur.text = '%d-' % c.current_job_level
$ref1/lbl_abp_progress.text = '%d/' % c.current_job_abp
$ref1/lbl_abp_next.text = '%d' % c.current_job_abp # Revisit
$ref1/lbl_hp_cur.text = '%d/' % c.hp_current
$ref1/lbl_hp_max.text = '%d' % c.hp_max
$ref1/lbl_mp_cur.text = '%d/' % c.mp_current
$ref1/lbl_mp_max.text = '%d' % c.mp_max
$'ref_commands/1'.text = StringLoader.get_ability_name(c.ability_1)
$'ref_commands/2'.text = StringLoader.get_ability_name(c.ability_2)
$'ref_commands/3'.text = StringLoader.get_ability_name(c.ability_3)
$'ref_commands/4'.text = StringLoader.get_ability_name(c.ability_4)
# Draw character battle sprite in either ref_frontrow or ref_backrow # Draw character battle sprite in either ref_frontrow or ref_backrow
# THink about status icons $ref0/PC.position = row_rects[c.is_back_row].position
$ref0/PC.material.set_shader_param('palette', SpriteLoader.character_battle_sprite_palette_textures[cj_idx])
$ref0/PC.texture = SpriteLoader.strip_textures[cj_idx]
# Think about status icons
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready() -> void: func _ready() -> void:
pass # Replace with function body. pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame. # Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta: float) -> void: #func _process(delta: float) -> void:
# pass # pass

View File

@ -1,34 +1,124 @@
[gd_scene load_steps=2 format=2] [gd_scene load_steps=3 format=2]
[ext_resource path="res://widgets/PartyMenuCharacter.gd" type="Script" id=1] [ext_resource path="res://widgets/PartyMenuCharacter.gd" type="Script" id=1]
[ext_resource path="res://PC.tscn" type="PackedScene" id=2]
[node name="PartyMenuCharacter" type="ReferenceRect"] [node name="PartyMenuCharacter" type="ReferenceRect"]
margin_right = 180.0 margin_right = 180.0
margin_bottom = 50.0 margin_bottom = 50.0
rect_min_size = Vector2( 180, 50 ) rect_min_size = Vector2( 240, 50 )
size_flags_horizontal = 0 size_flags_horizontal = 0
size_flags_vertical = 0 size_flags_vertical = 0
script = ExtResource( 1 ) script = ExtResource( 1 )
[node name="lbl_name" type="Label" parent="."] [node name="ref1" type="ReferenceRect" parent="."]
margin_right = 40.0 margin_left = 56.0
margin_bottom = 14.0 margin_right = 160.0
text = "Butz" margin_bottom = 50.0
border_color = Color( 0, 0, 1, 1 )
[node name="lbl_job" type="Label" parent="."] [node name="lbl_job" type="Label" parent="ref1"]
margin_left = 72.0 margin_right = 72.0
margin_right = 144.0
margin_bottom = 14.0 margin_bottom = 14.0
text = "Freelancer" text = "Freelancer"
[node name="LV" type="Label" parent="."] [node name="abp_LV" type="Label" parent="ref1"]
margin_left = 8.0 margin_left = 8.0
margin_top = 12.0 margin_top = 12.0
margin_right = 23.0 margin_right = 23.0
margin_bottom = 26.0 margin_bottom = 26.0
text = "LV" text = "LV"
[node name="lbl_lv_cur" type="Label" parent="."] [node name="lbl_abp_lv_cur" type="Label" parent="ref1"]
margin_left = 24.0
margin_top = 12.0
margin_right = 48.0
margin_bottom = 26.0
text = "2-"
align = 2
[node name="lbl_abp_progress" type="Label" parent="ref1"]
margin_left = 36.0
margin_top = 12.0
margin_right = 80.0
margin_bottom = 26.0
text = "76/"
align = 2
[node name="lbl_abp_next" type="Label" parent="ref1"]
margin_left = 60.0
margin_top = 12.0
margin_right = 104.0
margin_bottom = 26.0
text = "135"
align = 2
[node name="HP" type="Label" parent="ref1"]
margin_left = 8.0
margin_top = 25.0
margin_right = 32.0
margin_bottom = 39.0
rect_min_size = Vector2( 24, 0 )
text = "HP"
[node name="lbl_hp_cur" type="Label" parent="ref1"]
margin_left = 32.0
margin_top = 25.0
margin_right = 72.0
margin_bottom = 39.0
rect_min_size = Vector2( 40, 0 )
text = "9999/"
align = 2
[node name="lbl_hp_max" type="Label" parent="ref1"]
margin_left = 72.0
margin_top = 25.0
margin_right = 104.0
margin_bottom = 39.0
rect_min_size = Vector2( 32, 0 )
text = "9999"
align = 2
[node name="MP" type="Label" parent="ref1"]
margin_left = 8.0
margin_top = 36.0
margin_right = 32.0
margin_bottom = 50.0
text = "MP"
[node name="lbl_mp_cur" type="Label" parent="ref1"]
margin_left = 32.0
margin_top = 36.0
margin_right = 72.0
margin_bottom = 50.0
text = "999/"
align = 2
[node name="lbl_mp_max" type="Label" parent="ref1"]
margin_left = 72.0
margin_top = 36.0
margin_right = 104.0
margin_bottom = 50.0
text = "999"
align = 2
[node name="ref0" type="ReferenceRect" parent="."]
margin_right = 56.0
margin_bottom = 50.0
[node name="lbl_name" type="Label" parent="ref0"]
margin_right = 40.0
margin_bottom = 14.0
text = "Butz"
[node name="LV" type="Label" parent="ref0"]
margin_left = 8.0
margin_top = 12.0
margin_right = 23.0
margin_bottom = 26.0
text = "LV"
[node name="lbl_lv_cur" type="Label" parent="ref0"]
margin_left = 32.0 margin_left = 32.0
margin_top = 12.0 margin_top = 12.0
margin_right = 56.0 margin_right = 56.0
@ -36,38 +126,7 @@ margin_bottom = 26.0
text = "26" text = "26"
align = 2 align = 2
[node name="abp_LV" type="Label" parent="."] [node name="ref_frontrow" type="ReferenceRect" parent="ref0"]
margin_left = 84.0
margin_top = 12.0
margin_right = 99.0
margin_bottom = 26.0
text = "LV"
[node name="lbl_abp_lv_cur" type="Label" parent="."]
margin_left = 100.0
margin_top = 12.0
margin_right = 124.0
margin_bottom = 26.0
text = "2-"
align = 2
[node name="lbl_abp_progress" type="Label" parent="."]
margin_left = 112.0
margin_top = 12.0
margin_right = 156.0
margin_bottom = 26.0
text = "76/"
align = 2
[node name="lbl_abp_next" type="Label" parent="."]
margin_left = 136.0
margin_top = 12.0
margin_right = 180.0
margin_bottom = 26.0
text = "135"
align = 2
[node name="ref_frontrow" type="ReferenceRect" parent="."]
anchor_top = 1.0 anchor_top = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = 8.0 margin_left = 8.0
@ -75,7 +134,7 @@ margin_top = -24.0
margin_right = 24.0 margin_right = 24.0
border_color = Color( 1, 0.501961, 0, 1 ) border_color = Color( 1, 0.501961, 0, 1 )
[node name="ref_backrow" type="ReferenceRect" parent="."] [node name="ref_backrow" type="ReferenceRect" parent="ref0"]
anchor_top = 1.0 anchor_top = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = 40.0 margin_left = 40.0
@ -83,51 +142,32 @@ margin_top = -24.0
margin_right = 56.0 margin_right = 56.0
border_color = Color( 0, 1, 0, 1 ) border_color = Color( 0, 1, 0, 1 )
[node name="HP" type="Label" parent="."] [node name="PC" parent="ref0" instance=ExtResource( 2 )]
margin_left = 84.0
margin_top = 25.0
margin_right = 108.0
margin_bottom = 39.0
rect_min_size = Vector2( 24, 0 )
text = "HP"
[node name="lbl_hp_cur" type="Label" parent="."] [node name="ref_commands" type="ReferenceRect" parent="."]
margin_left = 108.0 margin_left = 168.0
margin_top = 25.0 margin_right = 240.0
margin_right = 148.0
margin_bottom = 39.0
rect_min_size = Vector2( 40, 0 )
text = "9999/"
align = 2
[node name="lbl_hp_max" type="Label" parent="."]
margin_left = 148.0
margin_top = 25.0
margin_right = 180.0
margin_bottom = 39.0
rect_min_size = Vector2( 32, 0 )
text = "9999"
align = 2
[node name="MP" type="Label" parent="."]
margin_left = 84.0
margin_top = 36.0
margin_right = 108.0
margin_bottom = 50.0 margin_bottom = 50.0
text = "MP"
[node name="lbl_mp_cur" type="Label" parent="."] [node name="1" type="Label" parent="ref_commands"]
margin_left = 108.0 margin_right = 72.0
margin_top = 36.0 margin_bottom = 14.0
margin_right = 148.0 text = "Fight"
margin_bottom = 50.0
text = "999/"
align = 2
[node name="lbl_mp_max" type="Label" parent="."] [node name="2" type="Label" parent="ref_commands"]
margin_left = 148.0 margin_top = 12.0
margin_right = 72.0
margin_bottom = 26.0
text = "Guard"
[node name="3" type="Label" parent="ref_commands"]
margin_top = 24.0
margin_right = 72.0
margin_bottom = 38.0
text = "DragnSwd"
[node name="4" type="Label" parent="ref_commands"]
margin_top = 36.0 margin_top = 36.0
margin_right = 180.0 margin_right = 72.0
margin_bottom = 50.0 margin_bottom = 50.0
text = "999" text = "Item"
align = 2

View File

@ -32,10 +32,7 @@ func set_data(data: Dictionary):
PCs[i].material.set_shader_param('palette', SpriteLoader.character_battle_sprite_palette_textures[sprite_id]) PCs[i].material.set_shader_param('palette', SpriteLoader.character_battle_sprite_palette_textures[sprite_id])
PCs[i].texture = SpriteLoader.strip_textures[sprite_id] PCs[i].texture = SpriteLoader.strip_textures[sprite_id]
$HBoxContainer/right_labels/HBoxContainer/lbl_level_num.text = '%d' % data.characters[0].level $HBoxContainer/right_labels/HBoxContainer/lbl_level_num.text = '%d' % data.characters[0].level
var game_seconds = data.game_time_frames / 60 $HBoxContainer/left_labels/lbl_gametime.text = Common.game_time_frames_to_hhmm(data.game_time_frames)
var game_minutes = game_seconds / 60
var game_hours = game_minutes / 60
$HBoxContainer/left_labels/lbl_gametime.text = '%d:%02d' % [game_hours, game_minutes % 60]
$HBoxContainer/left_labels/lbl_name.text = data.character_names[data.characters[0].character_id] $HBoxContainer/left_labels/lbl_name.text = data.character_names[data.characters[0].character_id]
$HBoxContainer/right_labels/lbl_hp.text = '%d/%4d' % [data.characters[0].hp_current, data.characters[0].hp_max] $HBoxContainer/right_labels/lbl_hp.text = '%d/%4d' % [data.characters[0].hp_current, data.characters[0].hp_max]