summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2024-12-13 14:53:38 +0100
committerDaniel Weipert <git@mail.dweipert.de>2024-12-13 14:53:38 +0100
commitca4d1945598863d0ce297f4272317e5dd5797f88 (patch)
treec2675b394140a71c7eee04034f087c107dcd7c9c
parenta22381eff3bf2286ee27f4d15ddf4c431ea063be (diff)
next commit
-rw-r--r--chat_window.gd2
-rw-r--r--client.gd7
-rw-r--r--constants.gd16
-rw-r--r--cursor.gd1
-rw-r--r--extractor/gat_format.gd89
-rw-r--r--extractor/sprite_layer_resource.gd10
-rw-r--r--extractor/sprite_resource.gd5
-rw-r--r--login.gd48
-rw-r--r--packets/equippable_item_information.gd101
-rw-r--r--packets/equippable_item_list_packet.gd32
-rw-r--r--packets/inventory_end_packet.gd26
-rw-r--r--packets/inventory_start_packet.gd32
-rw-r--r--packets/item_option.gd40
-rw-r--r--packets/map_loaded_packet.gd12
-rw-r--r--packets/regular_item_information.gd65
-rw-r--r--packets/regular_item_list_packet.gd32
-rw-r--r--packets/sprite_change_packet.gd37
-rw-r--r--sprite.gd92
-rw-r--r--sprite.tscn11
19 files changed, 512 insertions, 146 deletions
diff --git a/chat_window.gd b/chat_window.gd
index cbf9d6f..b8636c7 100644
--- a/chat_window.gd
+++ b/chat_window.gd
@@ -15,5 +15,5 @@ func _on_line_edit_text_submitted(new_text: String) -> void:
#add_message(new_text)
var send_chat_message_packet := SendChatMessagePacket.new()
- send_chat_message_packet.message = "%s : %s" % ["secondi", new_text]
+ send_chat_message_packet.message = "%s : %s" % [Client.character.name, new_text]
Network.map_server.send(send_chat_message_packet)
diff --git a/client.gd b/client.gd
index 308532a..5348117 100644
--- a/client.gd
+++ b/client.gd
@@ -10,7 +10,7 @@ var character: Dictionary = {
}
-#func _ready() -> void:
+func _ready() -> void:
#var grf = GRF.open("res://data/data.grf")
#grf.convert()#"user://data")
@@ -20,3 +20,8 @@ var character: Dictionary = {
#FileAccess.get_file_as_bytes("res://data/extracted/data/sprite/cursors.act")
#)
#)
+ GATFormat.from_bytes(
+ ByteStream.from_bytes(
+ FileAccess.get_file_as_bytes("res://data/extracted/data/int_land02.gat")
+ )
+ )
diff --git a/constants.gd b/constants.gd
index 61fa1b2..9a66b6d 100644
--- a/constants.gd
+++ b/constants.gd
@@ -30,20 +30,20 @@ enum StatusType {
}
static var PacketDB = {
- LoginServerLoginPacket.HEADER: LoginServerLoginPacket,
+ #LoginServerLoginPacket.HEADER: LoginServerLoginPacket,
LoginServerLoginSuccessPacket.HEADER: LoginServerLoginSuccessPacket,
- CharacterServerLoginPacket.HEADER: CharacterServerLoginPacket,
+ #CharacterServerLoginPacket.HEADER: CharacterServerLoginPacket,
CharacterServerLoginSuccessPacket.HEADER: CharacterServerLoginSuccessPacket,
CharacterServerLoginSuccessCharacterListPacket.HEADER: CharacterServerLoginSuccessCharacterListPacket,
CharacterListSizePacket.HEADER: CharacterListSizePacket,
BlockCharacterPacket.HEADER: BlockCharacterPacket,
PinCodeStatePacket.HEADER: PinCodeStatePacket,
- RequestCharacterListPacket.HEADER: RequestCharacterListPacket,
+ #RequestCharacterListPacket.HEADER: RequestCharacterListPacket,
RequestCharacterListSuccessPacket.HEADER: RequestCharacterListSuccessPacket,
- SelectCharacterPacket.HEADER: SelectCharacterPacket,
+ #SelectCharacterPacket.HEADER: SelectCharacterPacket,
CharacterSelectionSuccessPacket.HEADER: CharacterSelectionSuccessPacket,
CharacterSelectionFailedPacket.HEADER: CharacterSelectionFailedPacket,
- MapServerLoginPacket.HEADER: MapServerLoginPacket,
+ #MapServerLoginPacket.HEADER: MapServerLoginPacket,
MapServerLoginSuccessPacket.HEADER: MapServerLoginSuccessPacket,
FriendListPacket.HEADER: FriendListPacket,
ServerMessagePacket.HEADER: ServerMessagePacket,
@@ -56,4 +56,10 @@ static var PacketDB = {
AchievementUpdatePacket.HEADER: AchievementUpdatePacket,
AchievementListPacket.HEADER: AchievementListPacket,
UpdateCriticalWeightPacket.HEADER: UpdateCriticalWeightPacket,
+ #MapLoadedPacket.HEADER: MapLoadedPacket,
+ SpriteChangePacket.HEADER: SpriteChangePacket,
+ InventoryStartPacket.HEADER: InventoryStartPacket,
+ RegularItemListPacket.HEADER: RegularItemListPacket,
+ EquippableItemListPacket.HEADER: EquippableItemListPacket,
+ InventoryEndPacket.HEADER: InventoryEndPacket,
}
diff --git a/cursor.gd b/cursor.gd
index aa5eaad..947356e 100644
--- a/cursor.gd
+++ b/cursor.gd
@@ -18,6 +18,7 @@ func _process(_delta: float) -> void:
elif Input.get_current_cursor_shape() == Input.CURSOR_POINTING_HAND:
current_action_idx = 2
else:
+ # use default OS cursor
current_action_idx = -1
if current_action_idx != last_action_idx:
diff --git a/extractor/gat_format.gd b/extractor/gat_format.gd
new file mode 100644
index 0000000..213972a
--- /dev/null
+++ b/extractor/gat_format.gd
@@ -0,0 +1,89 @@
+class_name GATFormat
+
+
+## Byte Length: 4 [br]
+## GRAT
+var signature: String = "GRAT"
+
+## Byte Type: u8 [br]
+## Byte Length: 2
+var version: Version
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var map_width: int
+
+## Byte Type: i32 [br]
+## Byte Length: 4
+var map_height: int
+
+## Byte Length: [member map_width] * [member map_height]
+var tiles: Array[Tile]
+
+
+static func from_bytes(bytes: ByteStream) -> GATFormat:
+ var gat_format = GATFormat.new()
+
+ bytes.advance(gat_format.signature.length())
+
+ @warning_ignore("shadowed_variable")
+ var version = Version.new()
+ version.major = bytes.decode_u8()
+ version.minor = bytes.decode_u8()
+ gat_format.version = version
+
+ gat_format.map_width = bytes.decode_s32()
+ gat_format.map_height = bytes.decode_s32()
+
+ gat_format.tiles = [] as Array[Tile]
+ for _n in gat_format.map_width * gat_format.map_height:
+ gat_format.tiles.append(Tile.from_bytes(bytes))
+
+ return gat_format
+
+
+class Tile:
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4 [br]
+ ## Orignal Coordinates_ (0, 0)
+ var bottom_left_altitude: int
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4 [br]
+ ## Orignal Coordinates_ (1, 0)
+ var bottom_right_altitude: int
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4 [br]
+ ## Orignal Coordinates_ (0, 1)
+ var top_left_altitude: int
+
+ ## Byte Type: f32 [br]
+ ## Byte Length: 4 [br]
+ ## Orignal Coordinates_ (1, 1)
+ var top_right_altitude: int
+
+ ## Byte Type: u32 ?[br]
+ ## Byte Length: 4 ?
+ var terrain_type: int
+
+
+ func get_height_map() -> Dictionary: # Dictionary[Vector2, int]
+ return {
+ Vector2(0, 0): top_left_altitude,
+ Vector2(1, 0): top_right_altitude,
+ Vector2(0, 1): bottom_left_altitude,
+ Vector2(1, 1): bottom_right_altitude,
+ }
+
+
+ static func from_bytes(bytes: ByteStream) -> Tile:
+ var tile = Tile.new()
+
+ tile.bottom_left_altitude = bytes.decode_float()
+ tile.bottom_right_altitude = bytes.decode_float()
+ tile.top_left_altitude = bytes.decode_float()
+ tile.top_right_altitude = bytes.decode_float()
+ tile.terrain_type = bytes.decode_u32()
+
+ return tile
diff --git a/extractor/sprite_layer_resource.gd b/extractor/sprite_layer_resource.gd
deleted file mode 100644
index d67707e..0000000
--- a/extractor/sprite_layer_resource.gd
+++ /dev/null
@@ -1,10 +0,0 @@
-class_name SpriteLayerResource
-extends Resource
-
-
-@export var index: int
-@export var position: Vector2
-@export var color: Color
-@export var scale: Vector2
-@export var rotation_degrees: float
-@export var flip_h: bool
diff --git a/extractor/sprite_resource.gd b/extractor/sprite_resource.gd
deleted file mode 100644
index 380fac4..0000000
--- a/extractor/sprite_resource.gd
+++ /dev/null
@@ -1,5 +0,0 @@
-class_name SpriteResource
-extends Resource
-
-
-@export var images: Array[Texture2D]
diff --git a/login.gd b/login.gd
index 231756f..1b7ccb7 100644
--- a/login.gd
+++ b/login.gd
@@ -9,12 +9,9 @@ var current_character_information: CharacterInformation
func _ready() -> void:
switch_screen(%Login)
- #$BackgroundMusic.play()
+ $BackgroundMusic.play()
- # TODO: check why TextureRect doesn't work
- #get_tree().root.size_changed.connect(func():
- #$Background.scale = get_viewport_rect().size / $Background.get_rect().size
- #)
+ %ChatWindow.visible = false
func switch_screen(screen: Node):
@@ -92,25 +89,34 @@ func _on_character_selected_pressed(slot_idx: int):
Network.character_server.select_character(slot_idx)
var selected_character = await Network.character_server.selected_character
- if selected_character is CharacterSelectionSuccessPacket:
- Network.map_server = MapServer.new(
- selected_character.get_map_server_ip(),
- selected_character.map_server_port
- )
-
- Network.map_server.login(
- account_information.account_id,
- current_character_information.character_id,
- account_information.login_id1,
- account_information.gender
- )
- var _response = await Network.map_server.logged_in
-
- Client.character.name = current_character_information.name
+
+ if selected_character is CharacterSelectionFailedPacket:
+ # TODO: show error
+ return
+
+ Client.character.name = current_character_information.name
+
+ Network.map_server = MapServer.new(
+ selected_character.get_map_server_ip(),
+ selected_character.map_server_port
+ )
+
+ Network.map_server.login(
+ account_information.account_id,
+ current_character_information.character_id,
+ account_information.login_id1,
+ account_information.gender
+ )
+ var _logged_in = await Network.map_server.logged_in
# TODO: switch to game :)
- # TODO: check next packages to sent to server, most probably to map server
+
+ %ChatWindow.visible = true
Network.map_server.received_packet.connect(func(packet: Packet):
if packet is ServerMessagePacket:
%ChatWindow.add_message(packet.message)
)
+
+ # TODO: load map
+ var map_loaded_packet := MapLoadedPacket.new()
+ Network.map_server.send(map_loaded_packet)
diff --git a/packets/equippable_item_information.gd b/packets/equippable_item_information.gd
new file mode 100644
index 0000000..8ba0629
--- /dev/null
+++ b/packets/equippable_item_information.gd
@@ -0,0 +1,101 @@
+## rAthena References:
+## - EQUIPITEM_INFO
+## - clif_item_equip
+class_name EquippableItemInformation
+extends PacketChunk
+
+
+const BYTE_LENGTH := 22
+
+
+## Byte Type: u16
+## Byte Length: 2
+var index: int
+
+## Byte Type: u32
+## Byte Length: 4
+var item_id: int
+
+## Byte Type: u8
+## Byte Length: 1
+var item_type: int
+
+## Byte Type: u32
+## Byte Length: 4
+var equip_position: int
+
+## Byte Type: u32
+## Byte Length: 4
+var equipped_position: int
+
+## Byte Type: u32
+## Byte Length: 4
+var slot: int
+
+## Byte Type: u32
+## Byte Length: 4
+var hire_expiration_date: int
+
+## Byte Type: u16
+## Byte Length: 2
+var bind_on_equip_type: int
+
+## Byte Type: u16
+## Byte Length: 2
+var w_item_sprite_number: int
+
+## Byte Type: u8
+## Byte Length: 1
+## always 0 ?
+var option_count: int
+
+## Byte Length: 5 * ItemOption.BYTE_LENGTH
+var option_data: Array[ItemOption]
+
+## Byte Type: u8
+## Byte Length: 1
+var refinement_level: int
+
+## Byte Type: u8
+## Byte Length: 1
+var enchantment_level: int
+
+## Byte Type: u8
+## Byte Length: 1
+var flags: int
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var info = EquippableItemInformation.new()
+
+ info.index = bytes.decode_u16(0)
+ info.item_id = bytes.decode_u32(2)
+ info.item_type = bytes.decode_u8(6)
+ info.equipped_position = bytes.decode_u32(7)
+ info.equipped_position = bytes.decode_u32(11)
+ info.slot = bytes.decode_u32(15)
+ info.hire_expiration_date = bytes.decode_u32(19)
+ info.bind_on_equip_type = bytes.decode_u16(23)
+ info.w_item_sprite_number = bytes.decode_u16(25)
+ info.option_count = bytes.decode_u8(27)
+
+ var option_data_end = 28 + (5 * ItemOption.BYTE_LENGTH)
+ info.option_data = ItemOption.array_from_bytes(bytes.slice(28, option_data_end))
+
+ info.refinement_level = bytes.decode_u8(option_data_end)
+ info.enchantment_level = bytes.decode_u8(option_data_end + 1)
+ info.flags = bytes.decode_u8(option_data_end + 2)
+
+ return info
+
+
+static func array_from_bytes(bytes: PackedByteArray) -> Array[EquippableItemInformation]:
+ var array: Array[EquippableItemInformation] = []
+
+ var offset = 0
+ while offset < bytes.size():
+ var chunk = from_bytes(bytes.slice(offset))
+ array.append(chunk)
+ offset += chunk.byte_length
+
+ return array
diff --git a/packets/equippable_item_list_packet.gd b/packets/equippable_item_list_packet.gd
new file mode 100644
index 0000000..9b47202
--- /dev/null
+++ b/packets/equippable_item_list_packet.gd
@@ -0,0 +1,32 @@
+## rAthena References:
+## - clif_inventorylist
+## - packet_itemlist_equip
+class_name EquippableItemListPacket
+extends Packet
+
+
+const HEADER := 0x0b39
+const BYTE_LENGTH := 0
+
+
+
+## Byte Type: u16
+## Byte Length: 2
+var packet_length: int
+
+## Byte Type: u8
+## Byte Length: 1
+var inventory_type: int
+
+## Byte Type: u8
+var item_information: Array[EquippableItemInformation]
+
+
+static func from_bytes(bytes: PackedByteArray) -> EquippableItemListPacket:
+ var packet = EquippableItemListPacket.new()
+
+ packet.packet_length = bytes.decode_u16(2)
+ packet.inventory_type = bytes.decode_u8(4)
+ packet.item_information = EquippableItemInformation.array_from_bytes(bytes.slice(5))
+
+ return packet
diff --git a/packets/inventory_end_packet.gd b/packets/inventory_end_packet.gd
new file mode 100644
index 0000000..d8d313b
--- /dev/null
+++ b/packets/inventory_end_packet.gd
@@ -0,0 +1,26 @@
+## rAthena References:
+## - PACKET_ZC_INVENTORY_END
+## - clif_inventoryEnd
+class_name InventoryEndPacket
+extends Packet
+
+
+const HEADER := 0x0b0b
+const BYTE_LENGTH := 4
+
+
+## Byte Type: u8
+## Byte Length: 1
+var inventory_type: int
+
+## Byte Type: u8
+var flag: int
+
+
+static func from_bytes(bytes: PackedByteArray) -> InventoryEndPacket:
+ var packet = InventoryEndPacket.new()
+
+ packet.inventory_type = bytes.decode_u8(2)
+ packet.flag = bytes.decode_u8(3)
+
+ return packet
diff --git a/packets/inventory_start_packet.gd b/packets/inventory_start_packet.gd
new file mode 100644
index 0000000..2a02731
--- /dev/null
+++ b/packets/inventory_start_packet.gd
@@ -0,0 +1,32 @@
+## rAthena References:
+## - PACKET_ZC_INVENTORY_START
+## - clif_inventoryStart
+class_name InventoryStartPacket
+extends Packet
+
+
+const HEADER := 0x0b08
+const BYTE_LENGTH := 0
+
+
+
+## Byte Type: u16
+## Byte Length: 2
+var packet_length: int
+
+## Byte Type: u8
+## Byte Length: 1
+var inventory_type: int
+
+## Byte Type: u8
+var inventory_name: String
+
+
+static func from_bytes(bytes: PackedByteArray) -> InventoryStartPacket:
+ var packet = InventoryStartPacket.new()
+
+ packet.packet_length = bytes.decode_u16(2)
+ packet.inventory_type = bytes.decode_u8(4)
+ packet.inventory_name = bytes.slice(5).get_string_from_utf8()
+
+ return packet
diff --git a/packets/item_option.gd b/packets/item_option.gd
new file mode 100644
index 0000000..8f59166
--- /dev/null
+++ b/packets/item_option.gd
@@ -0,0 +1,40 @@
+class_name ItemOption
+extends PacketChunk
+
+
+const BYTE_LENGTH := 5
+
+
+## Byte Type: u16
+## Byte Length: 2
+var index: int
+
+## Byte Type: u16
+## Byte Length: 2
+var value: int
+
+## Byte Type: u8
+## Byte Length: 1
+var parameter: int
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var option = ItemOption.new()
+
+ option.index = bytes.decode_u16(0)
+ option.value = bytes.decode_u16(2)
+ option.parameter = bytes.decode_u8(3)
+
+ return option
+
+
+static func array_from_bytes(bytes: PackedByteArray) -> Array[ItemOption]:
+ var array: Array[ItemOption] = []
+
+ var offset = 0
+ while offset < bytes.size():
+ var chunk = from_bytes(bytes.slice(offset))
+ array.append(chunk)
+ offset += chunk.byte_length
+
+ return array
diff --git a/packets/map_loaded_packet.gd b/packets/map_loaded_packet.gd
new file mode 100644
index 0000000..e0f0967
--- /dev/null
+++ b/packets/map_loaded_packet.gd
@@ -0,0 +1,12 @@
+## rAthena References:
+## - clif_parse_LoadEndAck
+class_name MapLoadedPacket
+extends Packet
+
+
+const HEADER := 0x007d
+const BYTE_LENGTH := 2
+
+
+func to_bytes():
+ return get_header()
diff --git a/packets/regular_item_information.gd b/packets/regular_item_information.gd
new file mode 100644
index 0000000..212b341
--- /dev/null
+++ b/packets/regular_item_information.gd
@@ -0,0 +1,65 @@
+class_name RegularItemInformation
+extends PacketChunk
+
+
+const BYTE_LENGTH := 22
+
+
+## Byte Type: u16
+## Byte Length: 2
+var index: int
+
+## Byte Type: u32
+## Byte Length: 4
+var item_id: int
+
+## Byte Type: u8
+## Byte Length: 1
+var item_type: int
+
+## Byte Type: u16
+## Byte Length: 2
+var amount: int
+
+## Byte Type: u32
+## Byte Length: 4
+var equipped_position: int
+
+## Byte Type: u32
+## Byte Length: 4
+var slot: int
+
+## Byte Type: u32
+## Byte Length: 4
+var hire_expiration_date: int
+
+## Byte Type: u8
+## Byte Length: 1
+var flags: int
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var info = RegularItemInformation.new()
+
+ info.index = bytes.decode_u16(0)
+ info.item_id = bytes.decode_u32(2)
+ info.item_type = bytes.decode_u8(6)
+ info.amount = bytes.decode_u16(7)
+ info.equipped_position = bytes.decode_u32(9)
+ info.slot = bytes.decode_u32(13)
+ info.hire_expiration_date = bytes.decode_u32(17)
+ info.flags = bytes.decode_u8(21)
+
+ return info
+
+
+static func array_from_bytes(bytes: PackedByteArray) -> Array[RegularItemInformation]:
+ var array: Array[RegularItemInformation] = []
+
+ var offset = 0
+ while offset < bytes.size():
+ var chunk = from_bytes(bytes.slice(offset))
+ array.append(chunk)
+ offset += chunk.byte_length
+
+ return array
diff --git a/packets/regular_item_list_packet.gd b/packets/regular_item_list_packet.gd
new file mode 100644
index 0000000..3f64d1f
--- /dev/null
+++ b/packets/regular_item_list_packet.gd
@@ -0,0 +1,32 @@
+## rAthena References:
+## - clif_inventorylist
+## - packet_itemlist_normal
+class_name RegularItemListPacket
+extends Packet
+
+
+const HEADER := 0x0b09
+const BYTE_LENGTH := 0
+
+
+
+## Byte Type: u16
+## Byte Length: 2
+var packet_length: int
+
+## Byte Type: u8
+## Byte Length: 1
+var inventory_type: int
+
+## Byte Type: u8
+var item_information: Array[RegularItemInformation]
+
+
+static func from_bytes(bytes: PackedByteArray) -> RegularItemListPacket:
+ var packet = RegularItemListPacket.new()
+
+ packet.packet_length = bytes.decode_u16(2)
+ packet.inventory_type = bytes.decode_u8(4)
+ packet.item_information = RegularItemInformation.array_from_bytes(bytes.slice(5))
+
+ return packet
diff --git a/packets/sprite_change_packet.gd b/packets/sprite_change_packet.gd
new file mode 100644
index 0000000..af6d934
--- /dev/null
+++ b/packets/sprite_change_packet.gd
@@ -0,0 +1,37 @@
+## rAthena References:
+## - PACKET_ZC_SPRITE_CHANGE
+## - clif_sprite_change
+class_name SpriteChangePacket
+extends Packet
+
+
+const HEADER := 0x01d7
+const BYTE_LENGTH := 15
+
+
+## Byte Type: u32
+## Byte Length: 4
+var account_id: int
+
+## Byte Type: u8
+## Byte Length: 1
+var sprite_type: int
+
+## Byte Type: u32
+## Byte Length: 4
+var value: int
+
+## Byte Type: u32
+## Byte Length: 4
+var value2: int
+
+
+static func from_bytes(bytes: PackedByteArray) -> SpriteChangePacket:
+ var packet = SpriteChangePacket.new()
+
+ packet.account_id = bytes.decode_u32(2)
+ packet.sprite_type = bytes.decode_u32(6)
+ packet.value = bytes.decode_u32(7)
+ packet.value2 = bytes.decode_u32(11)
+
+ return packet
diff --git a/sprite.gd b/sprite.gd
deleted file mode 100644
index 745a86d..0000000
--- a/sprite.gd
+++ /dev/null
@@ -1,92 +0,0 @@
-class_name Sprite
-extends Node2D
-
-
-@export var sprite_data: SpriteResource
-var action_data: ActionFormat
-
-var current_action_idx := 0
-var current_frame := 0
-var current_start_time := 0.0
-var accumulator := 0.0
-
-var cache: Dictionary
-
-
-func _ready() -> void:
- if not sprite_data or not action_data:
- set_process(false)
-
-
-func load_file(path: String):
- var basename = path.get_basename()
-
- sprite_data = load("%s/sprite.tres" % basename)
-
- var act = FileAccess.open("%s.act" % basename, FileAccess.READ)
- action_data = ActionFormat.from_bytes(ByteStream.from_bytes(
- act.get_buffer(act.get_length())
- ))
-
- set_process(true)
- set_current_action(0)
-
-
-func set_current_action(idx: int):
- current_action_idx = idx
- current_frame = 0
- current_start_time = 0
- accumulator = 0
-
- update(action_data.actions[current_action_idx].motions[current_frame].sprite_layers)
-
-
-func _process(delta: float) -> void:
- var action = action_data.actions[current_action_idx]
- var frame_time = ((action_data.frame_times[current_action_idx] * 24) / 1000)
-
- accumulator += delta
- if accumulator > current_start_time + frame_time:
- var motion: ActionFormat.Motion = action.motions[current_frame]
- update(motion.sprite_layers)
-
- current_start_time = accumulator
- current_frame += 1
- if current_frame >= action.motions.size():
- set_current_action(current_action_idx) # reset current action
-
-
-func update(sprite_layers: Array[ActionFormat.SpriteLayer]):
- if not is_processing():
- return
-
- var has_different_layer_count = %SpriteLayers.get_child_count() != sprite_layers.size()
-
- if has_different_layer_count:
- for node in %SpriteLayers.get_children():
- node.queue_free()
-
- for idx in sprite_layers.size():
- var sprite_layer = sprite_layers[idx]
- var image = sprite_data.images[sprite_layer.sprite_index]
-
- var sprite: Sprite2D
- if has_different_layer_count:
- sprite = Sprite2D.new()
- sprite.centered = false # 必要!!
- sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
- else:
- sprite = %SpriteLayers.get_child(idx)
-
- sprite.texture = image
- sprite.position = sprite_layer.get_position() - ceil(sprite_layer.get_size() / 2) # for fixing half pixel drawing
- sprite.self_modulate = sprite_layer.get_color()
- sprite.scale = sprite_layer.get_scale()
- sprite.rotation_degrees = sprite_layer.rotation_degrees
- sprite.flip_h = sprite_layer.flip_h
-
- # TODO: use sprite and action together to generate AnimatedSprite2D with SpriteFrame Resources?
- # TODO: no. needs AnimationPlayer with config for different sprite positions in the animation
-
- if has_different_layer_count:
- %SpriteLayers.add_child(sprite)
diff --git a/sprite.tscn b/sprite.tscn
deleted file mode 100644
index d88f18e..0000000
--- a/sprite.tscn
+++ /dev/null
@@ -1,11 +0,0 @@
-[gd_scene load_steps=2 format=3 uid="uid://b8etnr5ebvrp3"]
-
-[ext_resource type="Script" path="res://sprite.gd" id="1_dohbv"]
-
-[node name="Sprite" type="Node2D"]
-top_level = true
-z_index = 1337
-script = ExtResource("1_dohbv")
-
-[node name="SpriteLayers" type="CanvasGroup" parent="."]
-unique_name_in_owner = true