From 4c8197932727da9303f092a47c879728bb21ad4c Mon Sep 17 00:00:00 2001 From: Jeferson Daniel Date: Sat, 6 Jan 2024 22:49:03 -0300 Subject: [PATCH] chore: Upgrade to Godot 3.5 --- .github/workflows/build-android.yml | 4 +- .github/workflows/build-html5.yml | 7 +- .github/workflows/build-linux.yml | 4 +- .github/workflows/build-macos.yml | 4 +- .github/workflows/build-windows.yml | 4 +- source/gdscript/nodes/character.gd | 258 +++---------- .../gdscript/nodes/character/attack_state.gd | 66 ++++ .../gdscript/nodes/character/defense_state.gd | 112 ++++++ .../gdscript/nodes/character/state_manager.gd | 76 ++-- .../nodes/character/user_command_manager.gd | 199 ---------- source/gdscript/nodes/fight/fight.gd | 59 +-- source/gdscript/nodes/screens/fight_screen.gd | 6 +- source/gdscript/system/fight_configuration.gd | 4 +- source/native/Cargo.lock | 360 +++++++++++++----- source/native/Cargo.toml | 4 +- source/native/src/character/constants.rs | 59 +++ source/native/src/character/mod.rs | 2 + .../src/character/user_command_manager.rs | 355 +++++++++++++++++ source/native/src/expressions/context.rs | 2 +- .../src/expressions/mugen_expression.rs | 20 +- source/native/src/expressions/value.rs | 8 +- source/native/src/fnt/fnt_parser.rs | 8 +- source/native/src/lib.rs | 2 + source/native/src/sff/data.rs | 2 +- source/native/src/sff/image.rs | 4 +- source/native/src/sff/sff_common.rs | 8 +- source/native/src/sff/sff_parser.rs | 32 +- source/native/src/sff/sffv1.rs | 4 +- source/native/src/sff/sffv2.rs | 4 +- source/native/src/snd/mod.rs | 1 + source/native/src/snd/snd_parser.rs | 12 +- source/native/user_command_manager.gdns | 8 + 32 files changed, 1061 insertions(+), 637 deletions(-) create mode 100644 source/gdscript/nodes/character/attack_state.gd create mode 100644 source/gdscript/nodes/character/defense_state.gd delete mode 100644 source/gdscript/nodes/character/user_command_manager.gd create mode 100644 source/native/src/character/constants.rs create mode 100644 source/native/src/character/mod.rs create mode 100644 source/native/src/character/user_command_manager.rs create mode 100644 source/native/user_command_manager.gdns diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml index ceb8591..8959be7 100644 --- a/.github/workflows/build-android.yml +++ b/.github/workflows/build-android.yml @@ -3,7 +3,7 @@ name: Build for Android on: workflow_dispatch env: - GODOT_VERSION: 3.3.4 + GODOT_VERSION: 3.5.2 EXPORT_NAME: neomugen CARGO_TERM_COLOR: always JAVA_VERSION: 1.8 @@ -19,7 +19,7 @@ jobs: name: Android export runs-on: ubuntu-latest container: - image: ghcr.io/jefersondaniel/neo-mugen-ci:3.3.4 + image: barichello/godot-ci:3.5.2 credentials: username: jefersondaniel password: ${{ secrets.GHCR_TOKEN }} diff --git a/.github/workflows/build-html5.yml b/.github/workflows/build-html5.yml index d1e88fd..6b53743 100644 --- a/.github/workflows/build-html5.yml +++ b/.github/workflows/build-html5.yml @@ -3,7 +3,7 @@ name: Build for HTML5 on: workflow_dispatch env: - GODOT_VERSION: 3.3.4 + GODOT_VERSION: 3.5.2 EXPORT_NAME: neomugen CARGO_TERM_COLOR: always EMSDK_VERSION: 2.0.17 @@ -13,7 +13,7 @@ jobs: name: HTML5 export runs-on: ubuntu-latest container: - image: ghcr.io/jefersondaniel/neo-mugen-ci:3.3.4 + image: barichello/godot-ci:3.5.2 credentials: username: jefersondaniel password: ${{ secrets.GHCR_TOKEN }} @@ -67,10 +67,7 @@ jobs: CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_LINKER: ${{github.workspace}}/source/native/emcc/emcc-test - name: Build - env: - SCRIPT_AES256_ENCRYPTION_KEY: ${{ secrets.SCRIPT_AES256_ENCRYPTION_KEY }} run: | - sed -i "s/script_encryption_key=\"\"/script_encryption_key=\"${SCRIPT_AES256_ENCRYPTION_KEY}\"/g; s/script_export_mode=1/script_export_mode=2/g" export_presets.cfg mkdir -v -p exports/web godot -v --export "HTML5" exports/web/${EXPORT_NAME}.html diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index b60f8ec..e88e06b 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -3,7 +3,7 @@ name: Build for Linux on: workflow_dispatch env: - GODOT_VERSION: 3.3.4 + GODOT_VERSION: 3.5.2 EXPORT_NAME: neomugen CARGO_TERM_COLOR: always @@ -12,7 +12,7 @@ jobs: name: Linux export runs-on: ubuntu-latest container: - image: ghcr.io/jefersondaniel/neo-mugen-ci:3.3.4 + image: barichello/godot-ci:3.5.2 credentials: username: jefersondaniel password: ${{ secrets.GHCR_TOKEN }} diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index f43466e..2ba106e 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -3,7 +3,7 @@ name: Build for MacOS on: workflow_dispatch env: - GODOT_VERSION: 3.3.4 + GODOT_VERSION: 3.5.2 EXPORT_NAME: neomugen CARGO_TERM_COLOR: always MACOS_SDK_TAR: https://s3.dockerproject.org/darwin/v2/MacOSX10.10.sdk.tar.xz @@ -15,7 +15,7 @@ jobs: name: MacOSX export runs-on: ubuntu-latest container: - image: ghcr.io/jefersondaniel/neo-mugen-ci:3.3.4 + image: barichello/godot-ci:3.5.2 credentials: username: jefersondaniel password: ${{ secrets.GHCR_TOKEN }} diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 4132aac..8b581ce 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -3,7 +3,7 @@ name: Build for Windows on: workflow_dispatch env: - GODOT_VERSION: 3.3.4 + GODOT_VERSION: 3.5.2 EXPORT_NAME: neomugen CARGO_TERM_COLOR: always @@ -12,7 +12,7 @@ jobs: name: Windows export runs-on: ubuntu-latest container: - image: ghcr.io/jefersondaniel/neo-mugen-ci:3.3.4 + image: barichello/godot-ci:3.5.2 credentials: username: jefersondaniel password: ${{ secrets.GHCR_TOKEN }} diff --git a/source/gdscript/nodes/character.gd b/source/gdscript/nodes/character.gd index 868530e..11c50a7 100644 --- a/source/gdscript/nodes/character.gd +++ b/source/gdscript/nodes/character.gd @@ -5,8 +5,9 @@ var AnimationSprite = load('res://source/gdscript/nodes/sprite/animation_sprite. var StateManager = load('res://source/gdscript/nodes/character/state_manager.gd') var SoundManager = load('res://source/gdscript/nodes/character/sound_manager.gd') var HitAttribute = load('res://source/gdscript/nodes/character/hit_attribute.gd') -var HitOverride = load('res://source/gdscript/nodes/character/hit_override.gd') var Bind = load('res://source/gdscript/nodes/character/bind.gd') +var AttackState = load('res://source/gdscript/nodes/character/attack_state.gd') +var DefenseState = load('res://source/gdscript/nodes/character/defense_state.gd') # Nodes and managers var character_sprite = null @@ -20,6 +21,9 @@ var fight_ref: WeakRef var definition = null var data = null var state_defs = null +var attack_state = null +var defense_state = null +var bind = null var info_localcoord: Vector2 = Vector2(320, 240) var int_vars: PoolIntArray var float_vars: PoolRealArray @@ -31,31 +35,8 @@ var special_flags = {} var push_flag: bool = true var in_hit_pause: bool = false var is_facing_right: bool = true -var hit_def = null -var received_hit_def = null -var hit_by_1 = null -var hit_by_2 = null -var bind = null -var is_hit_def_active: bool = false -var hit_count: int = 0 -var unique_hit_count: int = 0 -var attacker = null -var targets: Array = [] -var blocked: bool = false -var killed: bool = false var remaining_juggle_points: int = 15 var required_juggle_points: int = 0 -var hit_pause_time: int = 0 -var move_contact: int = 0 -var move_guarded: int = 0 -var move_hit: int = 0 -var move_reversed: int = 0 -var hit_overrides: Array = [] -var hit_time: int = 0 -var hit_shake_time: int = 0 -var hit_state_type: int = 0 -var defense_multiplier: float = 1 -var attack_multiplier: float = 1 var string_variable_regex: RegEx var base_z_index = 100 var posfreeze: int = 0 @@ -91,6 +72,8 @@ func setup(_definition, _data, _state_defs, sprite_bundle, animations, sounds, _ state_manager = StateManager.new(self) sound_manager = SoundManager.new(sounds) bind = Bind.new(self) + attack_state = AttackState.new(self) + defense_state = DefenseState.new(self) info_localcoord = definition.info.localcoord velocity = Vector2(0, 0) @@ -129,11 +112,6 @@ func setup_vars(): sys_int_vars[i] = 0 sys_float_vars[i] = 0 - self.hit_overrides = [] - - for i in range(0, 8): - self.hit_overrides.append(HitOverride.new()) - func _ready(): self.add_child(character_sprite) self.add_child(sound_manager) @@ -150,8 +128,8 @@ func reset_round_state(): # Meant to reset state between rounds ctrl = 0 life = data.data.life - hit_def = null - received_hit_def = null + attack_state.reset() + defense_state.reset() remaining_juggle_points = 15 required_juggle_points = 0 special_flags.clear() @@ -163,82 +141,79 @@ func get_const(fullname): return data.get_value(fullname) func is_falling(): - return movetype == constants.FLAG_H and received_hit_def and received_hit_def.fall + return movetype == constants.FLAG_H and defense_state.hit_def.fall func get_hit_var(key): - if not received_hit_def: - return -1 - match key: 'fall.envshake.time': - return received_hit_def.fall_envshake_time + return defense_state.hit_def.fall_envshake_time 'fall.envshake.freq': - return received_hit_def.fall_envshake_freq + return defense_state.hit_def.fall_envshake_freq 'fall.envshake.ampl': - return received_hit_def.fall_envshake_ampl + return defense_state.hit_def.fall_envshake_ampl 'fall.envshake.phase': - return received_hit_def.fall_envshake_phase + return defense_state.hit_def.fall_envshake_phase 'guarded': - return blocked + return defense_state.blocked 'chainid': - return received_hit_def.chainid + return defense_state.hit_def.chainid 'fall': return is_falling() 'fall.damage': - return received_hit_def.fall_damage + return defense_state.hit_def.fall_damage 'fall.recover': - return received_hit_def.fall_recover + return defense_state.hit_def.fall_recover 'fall.kill': - return received_hit_def.fall_kill + return defense_state.hit_def.fall_kill 'fall.recovertime': - return received_hit_def.fall_recovertime + return defense_state.hit_def.fall_recovertime 'fall.xvel': - return received_hit_def.fall_xvelocity + return defense_state.hit_def.fall_xvelocity 'fall.yvel': - return received_hit_def.fall_yvelocity + return defense_state.hit_def.fall_yvelocity 'recovertime': - return 0 # implement this + return 0 # TODO: implement this 'hitcount': - return hit_count + return defense_state.hit_count 'xvel': - return get_hit_velocity().x + return defense_state.get_hit_velocity().x 'yvel': - return get_hit_velocity().y + return defense_state.get_hit_velocity().y 'type': if life == 0: return 3 - return get_hit_var('airtype') if hit_state_type == constants.FLAG_A else get_hit_var('groundtype') + return get_hit_var('airtype') if defense_state.hit_state_type == constants.FLAG_A else get_hit_var('groundtype') 'airtype': - var airtype: String = received_hit_def.air_type + var airtype: String = defense_state.hit_def.air_type return constants.HIT_TYPE_ID[airtype] if constants.HIT_TYPE_ID.has(airtype) else 4 'groundtype': - var groundtype: String = received_hit_def.ground_type + var groundtype: String = defense_state.hit_def.ground_type return constants.HIT_TYPE_ID[groundtype] if constants.HIT_TYPE_ID.has(groundtype) else 0 'animtype': var animtype: String = '' if is_falling(): - animtype = received_hit_def.fall_animtype - elif hit_state_type == constants.FLAG_A: - animtype = received_hit_def.air_animtype + animtype = defense_state.hit_def.fall_animtype + elif defense_state.hit_state_type == constants.FLAG_A: + animtype = defense_state.hit_def.air_animtype else: - animtype = received_hit_def.animtype + animtype = defense_state.hit_def.animtype return constants.ANIM_TYPE_ID[animtype] if constants.ANIM_TYPE_ID.has(animtype) else null 'damage': - return received_hit_def.hit_damage if not blocked else received_hit_def.guard_damage + return defense_state.hit_def.hit_damage if not defense_state.blocked else defense_state.hit_def.guard_damage 'hitshaketime': - return hit_shake_time + return defense_state.hit_shake_time 'hittime': - return hit_time + return defense_state.hit_time 'slidetime': - return received_hit_def.ground_slidetime if not blocked else received_hit_def.guard_slidetime + return defense_state.hit_def.ground_slidetime if not defense_state.blocked else defense_state.hit_def.guard_slidetime 'ctrltime': - return received_hit_def.airguard_ctrltime if hit_state_type == constants.FLAG_A else received_hit_def.guard_ctrltime + return defense_state.hit_def.airguard_ctrltime if defense_state.hit_state_type == constants.FLAG_A else defense_state.hit_def.guard_ctrltime 'xoff': - return received_hit_def.snap.x if received_hit_def.snap else null + return defense_state.hit_def.snap.x if defense_state.hit_def.snap else null 'yoff': - return received_hit_def.snap.y if received_hit_def.snap else null + return defense_state.hit_def.snap.y if defense_state.hit_def.snap else null 'yaccel': - return received_hit_def.yaccel + return defense_state.hit_def.yaccel 'isbound': return bind.is_active and bind.is_target_bind _: @@ -351,13 +326,13 @@ func get_context_variable(key): if key == "sprpriority": return z_index if key == "hitshakeover": - return hit_shake_time <= 0 + return defense_state.hit_shake_time <= 0 if key == "hitfall": return is_falling() if key == "hitover": - return hit_time <= 0 + return defense_state.hit_time <= 0 if key == "canrecover": - return is_falling() and received_hit_def and received_hit_def.fall_recover + return is_falling() and defense_state.hit_def.fall_recover if key == "e": return 2.718281828 if key == "pi": @@ -510,26 +485,13 @@ func mul_velocity(_velocity): velocity.x *= _velocity.x velocity.y *= _velocity.y -func get_hit_velocity() -> Vector2: - var hit_velocity: Vector2 = Vector2(0, 0) +func add_power(input_power): + power = max(0, min(power + input_power, get_max_power())) - if blocked: - hit_velocity = received_hit_def.airguard_velocity if hit_state_type == constants.FLAG_A else Vector2(received_hit_def.guard_velocity, 0) - else: - hit_velocity = received_hit_def.air_velocity if hit_state_type == constants.FLAG_A else received_hit_def.ground_velocity - if killed: - hit_velocity.x = hit_velocity.x * 0.66 # TODO: Put this constant in global file - hit_velocity.y = -6 - - return hit_velocity - -func add_power(power): - self.power = max(0, min(self.power + power, get_max_power())) - -func add_life(life: int, kill: bool = true): - self.life = max(0, min(self.life + life, get_max_life())) - if not kill and self.life == 0: - self.life = 1 +func add_life(input_life: int, kill: bool = true): + life = max(0, min(life + input_life, get_max_life())) + if not kill and life == 0: + life = 1 func get_attack_power() -> float: var result = get_const('data.attack') @@ -551,7 +513,7 @@ func check_command(name: String) -> bool: func check_hit_def_attr(args: Array) -> bool: var operator: String = args.pop_front() var attribute = HitAttribute.parse(args) - var result = received_hit_def.attribute.satisfy(attribute) + var result = defense_state.hit_def.attribute.satisfy(attribute) return result if operator == "=" else not result @@ -588,12 +550,12 @@ func draw_debug_text(): get_node('/root/Node2D/debug/text').text = text func cleanup(): - if hit_pause_time > 1: + if attack_state.hit_pause_time > 1: in_hit_pause = true - hit_pause_time = hit_pause_time - 1 + attack_state.hit_pause_time = attack_state.hit_pause_time - 1 else: in_hit_pause = false - hit_pause_time = 0 + attack_state.hit_pause_time = 0 if not in_hit_pause: posfreeze = false @@ -619,54 +581,19 @@ func update_state(): state_manager.update() if not in_hit_pause: - update_hit_state() + attack_state.handle_tick() + defense_state.handle_tick() update_ko_state() -func update_hit_state(): - if move_contact > 0: - move_contact += 1 - - if move_hit > 0: - move_hit += 1 - - if move_guarded > 0: - move_guarded += 1 - - if move_reversed > 0: - move_reversed += 1 - - if hit_by_1: - hit_by_1.handle_tick() - - if hit_by_2: - hit_by_2.handle_tick() - - if hit_shake_time > 0: - hit_shake_time = hit_shake_time - 1 - elif hit_time > -1: - hit_time = hit_time - 1 - - if hit_shake_time < 0: - hit_shake_time = 0 - - if hit_time < 0: - hit_time = -1 - - if received_hit_def and stateno == constants.STATE_HIT_GET_UP and time == 0: - received_hit_def.fall = 0 - - for hit_override in hit_overrides: - hit_override.handle_tick() - func update_ko_state(): - if life > 0 or killed or assert_special(constants.ASSERTION_NOKO): + if life > 0 or defense_state.killed or assert_special(constants.ASSERTION_NOKO): return if not assert_special(constants.ASSERTION_NOKOSOUND): play_sound({"value": [11, 0]}) - killed = true + defense_state.killed = true func update_physics(): - if in_hit_pause or hit_shake_time > 0: + if in_hit_pause or defense_state.hit_shake_time > 0: return handle_physics() @@ -838,60 +765,10 @@ func handle_pushing(): enemy.handle_movement_restriction() # TODO: Fix scale -func handle_hit_target(hit_def, attacker, blocked): - self.received_hit_def = hit_def.duplicate() - self.attacker = attacker - self.blocked = blocked - - if self.is_falling(): - self.received_hit_def.fall = 1 - else: - self.remaining_juggle_points = int(self.get_const('data.airjuggle')) - - self.hit_count = self.hit_count + 1 if self.movetype == constants.FLAG_H else 1 - self.hit_state_type = self.statetype - - self.update_z_index(self.received_hit_def.p2sprpriority) - self.ctrl = 0 - self.movetype = constants.FLAG_H - - if self.blocked: - self.hit_shake_time = self.received_hit_def.guard_shaketime - self.add_power(self.received_hit_def.p2_guard_power) - else: - self.hit_shake_time = self.received_hit_def.shaketime - self.add_power(self.received_hit_def.p2_power) - - # TODO: Apply pallete fx - - if is_falling(): - self.remaining_juggle_points -= attacker.required_juggle_points - -func handle_hit_attacker(hit_def, target, blocked): - self.z_index = hit_def.p1sprpriority - - if not self.targets.has(target): - self.targets.append(target) - - if blocked: - self.add_power(hit_def.p1_guard_power) - hit_pause_time = hit_def.guard_pausetime - move_contact = 1 - move_guarded = 1 - move_hit = 0 - move_reversed = 0 - else: - self.add_power(hit_def.p1_power) - hit_pause_time = hit_def.pausetime - move_contact = 1 - move_guarded = 0 - move_hit = 1 - move_reversed = 0 - func find_targets(target_id: int): var results = [] - for target in targets: - if target_id == -1 or target_id == target.received_hit_def.id: + for target in attack_state.targets: + if target_id == -1 or target_id == target.defense_state.hit_def.id: results.append(target) return results @@ -902,17 +779,8 @@ func remove_check(): # TODO: Implement helper remove check pass -func find_hit_override(hit_def): - for hit_override in hit_overrides: - if not hit_override.is_active: - continue - if not hit_override.attribute.satisfy(hit_def.attribute): - continue - return hit_override - return null - -func set_fight(fight): - fight_ref = weakref(fight) +func set_fight(input_fight): + fight_ref = weakref(input_fight) func get_fight(): return fight_ref.get_ref() diff --git a/source/gdscript/nodes/character/attack_state.gd b/source/gdscript/nodes/character/attack_state.gd new file mode 100644 index 0000000..00cbb80 --- /dev/null +++ b/source/gdscript/nodes/character/attack_state.gd @@ -0,0 +1,66 @@ +class_name AttackState +extends Reference + +var HitDef = load('res://source/gdscript/nodes/character/hit_def.gd') + +var character = null +var hit_def = null +var hit_pause_time: int = 0 +var is_active: float = false +var move_contact: int = 0 +var move_guarded: int = 0 +var move_hit: int = 0 +var move_reversed: int = 0 +var attack_multiplier: float = 1 +var hit_count: int = 0 +var unique_hit_count: int = 0 +var targets: Array = [] + +func _init(input_character): + character = input_character + reset() + +func reset(): + hit_def = HitDef.new() + hit_pause_time = 0 + is_active = false + move_contact = 0 + move_guarded = 0 + move_hit = 0 + move_reversed = 0 + attack_multiplier = 1 + hit_count = 0 + unique_hit_count = 0 + targets = [] + +func handle_tick(): + if move_contact > 0: + move_contact += 1 + if move_hit > 0: + move_hit += 1 + if move_guarded > 0: + move_guarded += 1 + if move_reversed > 0: + move_reversed += 1 + +func on_hit(input_hit_def, target, blocked: bool): + hit_def = input_hit_def + character.z_index = hit_def.p1sprpriority + + if not targets.has(target): + targets.append(target) + + if blocked: + character.add_power(hit_def.p1_guard_power) + hit_pause_time = hit_def.guard_pausetime + move_contact = 1 + move_guarded = 1 + move_hit = 0 + move_reversed = 0 + else: + character.add_power(hit_def.p1_power) + hit_pause_time = hit_def.pausetime + move_contact = 1 + move_guarded = 0 + move_hit = 1 + move_reversed = 0 diff --git a/source/gdscript/nodes/character/defense_state.gd b/source/gdscript/nodes/character/defense_state.gd new file mode 100644 index 0000000..6f29f6c --- /dev/null +++ b/source/gdscript/nodes/character/defense_state.gd @@ -0,0 +1,112 @@ +var HitDef = load('res://source/gdscript/nodes/character/hit_def.gd') +var HitOverride = load('res://source/gdscript/nodes/character/hit_override.gd') + +var character = null +var hit_def = null +var blocked: bool = false +var killed: bool = false +var hit_state_type: int = 0 +var hit_shake_time = 0 +var defense_multiplier = 1 +var attacker = null +var hit_time = 0 +var hit_by_1 = null +var hit_by_2 = null +var is_falling = false +var hit_overrides: Array = [] +var hit_count: int = 0 + +func _init(input_character): + character = input_character + reset() + +func reset(): + hit_def = HitDef.new() + blocked = false + killed = false + hit_state_type = 0 + hit_shake_time = 0 + defense_multiplier = 1 + attacker = null + hit_time = 0 + hit_by_1 = null + hit_by_2 = null + is_falling = false + hit_count = 0 + hit_overrides = [] + for i in range(0, 8): + hit_overrides.append(HitOverride.new()) + +func handle_tick(): + if hit_by_1: + hit_by_1.handle_tick() + + if hit_by_2: + hit_by_2.handle_tick() + + if hit_shake_time > 0: + hit_shake_time -= 1 + elif hit_time > -1: + hit_time -= 1 + + if hit_shake_time < 0: + hit_shake_time = 0 + + if hit_time < 0: + hit_time = 0 + + if hit_def and character.stateno == constants.STATE_HIT_GET_UP && character.time == 0: + hit_def.fall = false + + for hit_override in hit_overrides: + hit_override.handle_tick() + +func on_hit(input_hit_def, input_attacker, input_blocked): + hit_def = input_hit_def.duplicate() + attacker = input_attacker + blocked = input_blocked + + if character.is_falling(): + hit_def.fall = 1 + else: + character.remaining_juggle_points = int(character.get_const('data.airjuggle')) + + hit_count = hit_count + 1 if character.movetype == constants.FLAG_H else 1 + hit_state_type = character.statetype + + character.update_z_index(hit_def.p2sprpriority) + character.ctrl = 0 + character.movetype = constants.FLAG_H + + if blocked: + hit_shake_time = hit_def.guard_shaketime + character.add_power(hit_def.p2_guard_power) + else: + hit_shake_time = hit_def.shaketime + character.add_power(hit_def.p2_power) + + # TODO: Apply pallete fx + + if character.is_falling(): + character.remaining_juggle_points -= attacker.required_juggle_points + +func find_hit_override(input_hit_def): + for hit_override in hit_overrides: + if not hit_override.is_active: + continue + if not hit_override.attribute.satisfy(input_hit_def.attribute): + continue + return hit_override + return null + +func get_hit_velocity() -> Vector2: + var hit_velocity: Vector2 = Vector2(0, 0) + + if blocked: + hit_velocity = hit_def.airguard_velocity if hit_state_type == constants.FLAG_A else Vector2(hit_def.guard_velocity, 0) + else: + hit_velocity = hit_def.air_velocity if hit_state_type == constants.FLAG_A else hit_def.ground_velocity + if killed: + hit_velocity.x = hit_velocity.x * 0.66 # TODO: Put this constant in global file + hit_velocity.y = -6 + return hit_velocity diff --git a/source/gdscript/nodes/character/state_manager.gd b/source/gdscript/nodes/character/state_manager.gd index df80c3b..d003cf8 100644 --- a/source/gdscript/nodes/character/state_manager.gd +++ b/source/gdscript/nodes/character/state_manager.gd @@ -116,18 +116,18 @@ func activate_state(statedef): hitcountpersist = int(statedef['hitcountpersist']) if not hitdefpersist: - character.is_hit_def_active = false - character.hit_pause_time = 0 + character.attack_state.is_active = false + character.attack_state.hit_pause_time = 0 if not movehitpersist: - character.move_reversed = 0 - character.move_hit = 0 - character.move_guarded = 0 - character.move_contact = 0 + character.attack_state.move_reversed = 0 + character.attack_state.move_hit = 0 + character.attack_state.move_guarded = 0 + character.attack_state.move_contact = 0 if not hitcountpersist: - character.hit_count = 0 - character.unique_hit_count = 0 + character.attack_state.hit_count = 0 + character.attack_state.unique_hit_count = 0 # TODO: Implement facep2 @@ -397,19 +397,19 @@ func handle_defencemulset(controller): if value == null: printerr("defencemulset: invalid value") return - character.defense_multiplier = float(value) + character.defense_state.defense_multiplier = float(value) func handle_attackmulset(controller): var character = get_character() var value = controller['value'].execute(character) - character.attack_multiplier = float(value) + character.attack_state.attack_multiplier = float(value) func handle_hitdef(controller): var character = get_character() var hit_def = HitDef.new() hit_def.parse(controller, character) - character.hit_def = hit_def - character.is_hit_def_active = true + character.attack_state.hit_def = hit_def + character.attack_state.is_active = true func handle_hitvelset(controller): var character = get_character() @@ -422,9 +422,9 @@ func handle_hitvelset(controller): if controller.has('y'): yflag = controller['y'].execute(character) - var new_velocity = character.get_hit_velocity() + var new_velocity = character.defense_state.get_hit_velocity() - if character.attacker.is_facing_right == character.is_facing_right: + if character.defense_state.attacker.is_facing_right == character.is_facing_right: new_velocity.x = -new_velocity.x if not xflag: @@ -439,10 +439,10 @@ func handle_hitvelset(controller): func handle_hitfallvel(controller): var character = get_character() - if not character.received_hit_def or not character.is_falling(): + if not character.defense_state.hit_def or not character.is_falling(): return - var hitdef = character.received_hit_def + var hitdef = character.defense_state.hit_def if hitdef.fall_xvelocity: character.set_velocity_x(hitdef.fall_xvelocity) @@ -452,7 +452,7 @@ func handle_hitfallvel(controller): func handle_hitfallset(controller): var character = get_character() - if not character.received_hit_def: + if not character.defense_state.hit_def: return var value = -1 @@ -469,17 +469,17 @@ func handle_hitfallset(controller): xvel = controller['xvel'].execute(character) if value == 1 or value == 0: - character.received_hit_def.fall = value + character.defense_state.hit_def.fall = value if xvel != null: - character.received_hit_def.fall_xvelocity = xvel + character.defense_state.hit_def.fall_xvelocity = xvel if yvel != null: - character.received_hit_def.fall_yvelocity = yvel + character.defense_state.hit_def.fall_yvelocity = yvel func handle_movecontact(controller): var character = get_character() - return character.move_contact if character.movetype == constants.FLAG_A else 0 + return character.attack_state.move_contact if character.movetype == constants.FLAG_A else 0 func handle_sprpriority(controller): var character = get_character() @@ -507,7 +507,7 @@ func handle_playsnd(controller): func handle_fallenvshake(_controller): var character = get_character() - var hit_def = character.received_hit_def + var hit_def = character.defense_state.hit_def var stage = character.get_stage() if not hit_def: @@ -532,8 +532,8 @@ func handle_envshake(controller): func handle_hitfalldamage(_controller): var character = get_character() - var hit_def = character.received_hit_def - var attacker = character.attacker + var hit_def = character.defense_state.hit_def + var attacker = character.defense_state.attacker var fight = character.get_fight() if not hit_def or not attacker: @@ -562,9 +562,9 @@ func apply_hit_by(controller, is_negation: bool): hit_by.setup(hit_attribute, time, is_negation) if slot == 1: - character.hit_by_1 = hit_by + character.defense_state.hit_by_1 = hit_by else: - character.hit_by_2 = hit_by + character.defense_state.hit_by_2 = hit_by func handle_nothitby(controller): self.apply_hit_by(controller, true) @@ -584,7 +584,7 @@ func handle_hitoverride(controller): printerr("hitoverride: invalid attr: %s" + attr) return - character.hit_overrides[slot].setup( + character.defense_state.hit_overrides[slot].setup( attr, stateno, time, @@ -615,7 +615,7 @@ func handle_targetdrop(controller): var excluded = [] for target in character.targets: - if id != -1 and target.received_hit_def.id == id: + if id != -1 and target.defense_state.hit_def.id == id: continue excluded.append(target) @@ -671,8 +671,8 @@ func handle_targetlifeadd(controller): for target in character.find_targets(target_id): var new_value = value if not absolute and new_value < 0: - new_value = int(new_value * character.attack_multiplier) - new_value = int(new_value / target.defense_multiplier) + new_value = int(new_value * character.attack_state.attack_multiplier) + new_value = int(new_value / target.defense_state.defense_multiplier) target.add_life(new_value, kill) func handle_targetpoweradd(controller): @@ -742,11 +742,11 @@ func handle_attackdist(controller): var character = get_character() var value = controller['value'].execute(character) - if not value or not character.hit_def: - printerr("attackdist: invalid value or missing hitdef") + if not value: + printerr("attackdist: invalid value") return - character.hit_def.guard_dist = value + character.attack_state.hit_def.guard_dist = value func handle_lifeadd(controller): var character = get_character() @@ -759,7 +759,7 @@ func handle_lifeadd(controller): return if not absolute: - value = int(value / character.defense_multiplier) + value = int(value / character.defense_state.defense_multiplier) character.add_life(value, kill) @@ -780,10 +780,10 @@ func handle_poweradd(controller): func handle_movehitreset(controller): var character = get_character() - character.move_contact = 0 - character.move_guarded = 0 - character.move_hit = 0 - character.move_reversed = 0 + character.attack_state.move_contact = 0 + character.attack_state.move_guarded = 0 + character.attack_state.move_hit = 0 + character.attack_state.move_reversed = 0 func handle_playerpush(controller): var character = get_character() diff --git a/source/gdscript/nodes/character/user_command_manager.gd b/source/gdscript/nodes/character/user_command_manager.gd deleted file mode 100644 index 0e0d4a1..0000000 --- a/source/gdscript/nodes/character/user_command_manager.gd +++ /dev/null @@ -1,199 +0,0 @@ -var input_prefix: String = '' -var input_map: Dictionary = { - 'U': constants.KEY_U, - 'D': constants.KEY_D, - 'a': constants.KEY_a, - 'b': constants.KEY_b, - 'c': constants.KEY_c, - 'x': constants.KEY_x, - 'y': constants.KEY_y, - 'z': constants.KEY_z, - 's': constants.KEY_s, -} - -var buffer: Array -var buffer_size: int = 120 -var buffer_index: int = -1 -var command_countdown: Dictionary = {} -var commands: Array = [] -var active_commands: Array = [] -var is_facing_right: bool = true -var code: int = 0 - -func _init(_input_prefix): - input_prefix = _input_prefix - buffer = [] - buffer.resize(buffer_size) - for i in range(0, buffer_size): - buffer[i] = 0 - -func set_commands(_commands: Array) -> void: - commands = _commands - - for command in commands: - command_countdown[command['name']] = 0 - -func update(in_hit_pause: bool) -> void: - update_input_buffer() - update_command_countdown(in_hit_pause) - check_commands(in_hit_pause) - update_active_commands() - -func update_input_buffer() -> void: - buffer_index = buffer_index + 1 - - if buffer_index >= buffer_size: - buffer_index = 0 - - code = 0 - - if Input.is_action_pressed(input_prefix + 'F'): - code += constants.KEY_F if is_facing_right else constants.KEY_B - if Input.is_action_pressed(input_prefix + 'B'): - code += constants.KEY_B if is_facing_right else constants.KEY_F - - for input in ['U', 'D', 'a', 'b', 'c', 'x', 'y', 'z', 's']: - if Input.is_action_pressed(input_prefix + input): - code += input_map[input] - - buffer[buffer_index] = code - -func update_command_countdown(in_hit_pause: bool) -> void: - if in_hit_pause: - return - - for key in command_countdown: - command_countdown[key] = max(0, command_countdown[key] - 1) - -func check_commands(in_hit_pause: bool) -> void: - for command in commands: - if not check_command(command): - continue - - var time: int = command['buffer_time'] - - if in_hit_pause: - time = time + 1 - - command_countdown[command['name']] = time - -func update_active_commands() -> void: - active_commands = [] - - for key in command_countdown: - if command_countdown[key] <= 0: - continue - active_commands.push_back(key) - -func check_command(command) -> bool: - var element_index: int = len(command['cmd']) - 1 - var input_index: int = 0 - - while input_index != buffer_size: - var match_index: int = scan_for_match(command, element_index, input_index) - - if match_index == -1: - return false - - if element_index > 0: - if match_index > command['time']: - return false - element_index -= 1 - input_index = match_index - elif element_index == 0: - return match_index <= command['time'] - else: - return false - - input_index += 1 - - return false - -func scan_for_match(command: Dictionary, element_index: int, input_index: int) -> int: - var element: Dictionary = command['cmd'][element_index] - var element_count: int = len(command['cmd']) - var scan_length: int = min(buffer_size, command['time']) - - for i in range(input_index, input_index + scan_length): - if element_index == element_count - 1: - if element['ticks'] == -1: - if i != input_index: - return -1 - elif i - 1 != input_index and i != input_index: - return -1 - - if element_match(element, i): - if element_index < element_count - 1: - var next_element = command['cmd'][element_index + 1] - var nothing_else = (next_element['modifier'] & constants.KEY_MODIFIER_BAN_OTHER_INPUT) != 0 - if nothing_else and not check_identical_input(input_index, i): - continue - - return i - - return -1 - -func element_match(element: Dictionary, input_index: int) -> bool: - var state: int = get_input_state(input_index, element) - var must_be_held = (element['modifier'] & constants.KEY_MODIFIER_MUST_BE_HELD) != 0 - - if must_be_held: - return state == constants.INPUT_STATE_DOWN or state == constants.INPUT_STATE_PRESSED - - if element['ticks'] != -1: - if input_index >= buffer_size: - return false - - if input_index == 0 or get_input_state(input_index - 1, element) != constants.INPUT_STATE_RELEASED: - return false - - var hold_count: int = 1 - - for i in range(input_index + 1, buffer_size): - if get_input_state(i, element) != constants.INPUT_STATE_DOWN: - break - hold_count += 1 - - if hold_count < element['ticks']: - return false - elif state != constants.INPUT_STATE_PRESSED: - return false - - return true - -func get_input_value(index: int) -> int: - return buffer[(buffer_index - index + buffer_size) % buffer_size] - -func get_input_state(index: int, element: Dictionary) -> int: - var current: int = get_input_value(index) - var previous: int = get_input_value(index + 1) if index != buffer_size - 1 else 0 - - var current_state: int = check_element_state(current, element) - var previous_state: int = check_element_state(previous, element) - - if current_state: - return constants.INPUT_STATE_DOWN if previous_state else constants.INPUT_STATE_PRESSED - - return constants.INPUT_STATE_RELEASED if previous_state else constants.INPUT_STATE_UP - -func check_identical_input(start_index: int, end_index: int) -> bool: - var input_value: int = get_input_value(start_index) - - for i in range(start_index + 1, end_index): - if input_value != get_input_value(i): - return false - - return true - -func check_element_state(input_code: int, element: Dictionary) -> bool: - var element_code: int = element['code'] - var use4_way: bool = (element['modifier'] & constants.KEY_MODIFIER_DETECT_AS_4WAY) != 0 - var key_down: bool = (input_code & element_code) == element_code - - if key_down && !use4_way: - var input_direction: int = input_code & constants.ALL_DIRECTION_KEYS - var element_direction: int = element_code & constants.ALL_DIRECTION_KEYS - - key_down = !element_direction || (input_direction == element_direction) - - return key_down diff --git a/source/gdscript/nodes/fight/fight.gd b/source/gdscript/nodes/fight/fight.gd index 1dcda7d..9033104 100644 --- a/source/gdscript/nodes/fight/fight.gd +++ b/source/gdscript/nodes/fight/fight.gd @@ -190,10 +190,10 @@ func run_character_contacts(): var hit_count: int = count_contacts(character, CONTACT_HIT) var block_count: int = count_contacts(character, CONTACT_BLOCK) if hit_count: - character.hit_count += 1 - character.unique_hit_count += hit_count + character.attack_state.hit_count += 1 + character.attack_state.unique_hit_count += hit_count if block_count or hit_count: - character.is_hit_def_active = false + character.attack_state.is_active = false func count_contacts(attacker, type): var count: int = 0 @@ -238,7 +238,7 @@ func priority_check(a, b): func check_move_contacts(): for attacker in self.active_characters: - if attacker.in_hit_pause or not attacker.is_hit_def_active: + if attacker.in_hit_pause or not attacker.attack_state.is_active: continue for target in self.active_characters: if attacker == target: @@ -251,36 +251,37 @@ func check_move_contact(attacker, target): self.contacts.append({ 'attacker': attacker, 'target': target, - 'hit_def': attacker.hit_def, + 'hit_def': attacker.attack_state.hit_def, 'type': CONTACT_BLOCK }) elif can_hit(attacker, target): self.contacts.append({ 'attacker': attacker, 'target': target, - 'hit_def': attacker.hit_def, + 'hit_def': attacker.attack_state.hit_def, 'type': CONTACT_HIT }) elif can_block(attacker, target, false): self.contacts.append({ 'attacker': attacker, 'target': target, - 'hit_def': attacker.hit_def, + 'hit_def': attacker.attack_state.hit_def, 'type': CONTACT_MISS_BLOCK }) func can_block(attacker, target, collision_check: bool) -> bool: - var hit_def = attacker.hit_def + var hit_def = attacker.attack_state.hit_def if collision_check and not attacker.check_attack_collision(target): return false - if attacker.hit_def.affectteam == 'e' and target.team_number == attacker.team_number: + if hit_def.affectteam == 'e' and target.team_number == attacker.team_number: return false - if attacker.hit_def.affectteam == 'f' and target.team_number != attacker.team_number: + if hit_def.affectteam == 'f' and target.team_number != attacker.team_number: return false if not target.check_command('holdback'): return false - if abs(attacker.position.x - target.position.x) <= attacker.hit_def.guard_dist: + # TODO: Check position scale here + if abs(attacker.position.x - target.position.x) <= hit_def.guard_dist: return false if target.statetype == constants.FLAG_A and (not hit_def.allow_guard_air() or target.check_assert_special('noairguard')): return false @@ -295,13 +296,13 @@ func can_block(attacker, target, collision_check: bool) -> bool: return true func can_hit(attacker, target) -> bool: - var hit_def = attacker.hit_def + var hit_def = attacker.attack_state.hit_def if not attacker.check_attack_collision(target): return false - if attacker.hit_def.affectteam == 'e' and target.team_number == attacker.team_number: + if attacker.attack_state.hit_def.affectteam == 'e' and target.team_number == attacker.team_number: return false - if attacker.hit_def.affectteam == 'f' and target.team_number != attacker.team_number: + if attacker.attack_state.hit_def.affectteam == 'f' and target.team_number != attacker.team_number: return false if target.statetype == constants.FLAG_S and not hit_def.allow_hit_high(): return false @@ -315,9 +316,9 @@ func can_hit(attacker, target) -> bool: return false if target.movetype == constants.FLAG_H and hit_def.hitflag_sign == '+': return false - if target.hit_by_1 and not target.hit_by_1.can_hit(hit_def.attribute): + if target.defense_state.hit_by_1 and not target.defense_state.hit_by_1.can_hit(hit_def.attribute): return false - if target.hit_by_2 and not target.hit_by_2.can_hit(hit_def.attribute): + if target.defense_state.hit_by_2 and not target.defense_state.hit_by_2.can_hit(hit_def.attribute): return false # TODO: Implement juggle points @@ -344,11 +345,11 @@ func run_character_attack(attack): out_of_range_block(attack['target']) func on_character_attack(attacker, target, hit_def, blocked): - target.handle_hit_target(hit_def, attacker, blocked) - attacker.handle_hit_attacker(target.received_hit_def, target, blocked) - set_facing(attacker, target, target.received_hit_def) + target.defense_state.on_hit(hit_def, attacker, blocked) + attacker.attack_state.on_hit(target.defense_state.hit_def, target, blocked) + set_facing(attacker, target, target.defense_state.hit_def) - var received_hit_def = target.received_hit_def + var received_hit_def = target.defense_state.hit_def # TODO: implement hit sound and sparks using global data # if not blocked: @@ -359,7 +360,7 @@ func on_character_attack(attacker, target, hit_def, blocked): # play_sound(attacker, target, received_hit_def.guardsound, received_hit_def.guardsound_source); # make_spark(attacker, target, received_hit_def.guard_sparkno, received_hit_def.sparkxy, received_hit_def.guard_sparkno_source) - var hitoverride = target.find_hit_override(received_hit_def) + var hitoverride = target.defense_state.find_hit_override(received_hit_def) if hitoverride: if hitoverride.force_air: @@ -378,13 +379,13 @@ func on_attack_hit(attacker, target, hit_def): if target.life == 0: hit_def.fall = 1 - match target.hit_state_type: + match target.defense_state.hit_state_type: constants.FLAG_S, constants.FLAG_C, constants.FLAG_L: - target.hit_time = hit_def.ground_hittime + target.defense_state.hit_time = hit_def.ground_hittime constants.FLAG_A: - target.hit_time = hit_def.air_hittime + target.defense_state.hit_time = hit_def.air_hittime _: - printerr("Invalid hit state type: " % [target.hit_state_type]) + printerr("Invalid hit state type: " % [target.defense_state.hit_state_type]) if hit_def.p1stateno > 0: attacker.change_state(hit_def.p1stateno) @@ -401,7 +402,7 @@ func on_attack_hit(attacker, target, hit_def): if hit_def.ground_type == 'trip': target.change_state(constants.STATE_HIT_TRIP) else: - match target.hit_state_type: + match target.defense_state.hit_state_type: constants.FLAG_S: target.change_state(constants.STATE_STANDING_HIT_SHAKING) constants.FLAG_C: @@ -411,7 +412,7 @@ func on_attack_hit(attacker, target, hit_def): constants.FLAG_L: target.change_state(constants.STATE_HIT_PRONE_SHAKING) _: - printerr("Invalid hit state type: " % [target.hit_state_type]) + printerr("Invalid hit state type: " % [target.defense_state.hit_state_type]) func on_attack_block(attacker, target, hit_def): target.hit_time = hit_def.guard_hittime; @@ -426,8 +427,8 @@ func on_attack_block(attacker, target, hit_def): target.change_state(constants.STATE_CROUCHING_GUARD_HIT_SHAKING) func apply_damage(attacker, target, amount, kill): - var offensive_multiplier = attacker.attack_multiplier * (attacker.get_attack_power() / 100.0) - var defensive_multiplier = target.defense_multiplier * (target.get_defence_power() / 100.0) + var offensive_multiplier = attacker.attack_state.attack_multiplier * (attacker.get_attack_power() / 100.0) + var defensive_multiplier = target.defense_state.defense_multiplier * (target.get_defence_power() / 100.0) amount = int(amount * offensive_multiplier / defensive_multiplier) target.add_life(-amount, kill) diff --git a/source/gdscript/nodes/screens/fight_screen.gd b/source/gdscript/nodes/screens/fight_screen.gd index 746347c..f5a7014 100644 --- a/source/gdscript/nodes/screens/fight_screen.gd +++ b/source/gdscript/nodes/screens/fight_screen.gd @@ -2,7 +2,7 @@ extends Node2D var Fight = load("res://source/gdscript/nodes/fight/fight.gd") var Team = load("res://source/gdscript/nodes/fight/team.gd") -var UserCommandManager = load("res://source/gdscript/nodes/character/user_command_manager.gd") +var UserCommandManager = load('res://source/native/user_command_manager.gdns') var AiCommandManager = load("res://source/gdscript/nodes/character/ai_command_manager.gd") var CharacterLoader = load("res://source/gdscript/loaders/character_loader.gd").new() var StageLoader = load("res://source/gdscript/loaders/stage_loader.gd").new() @@ -36,7 +36,9 @@ func _physics_process(_delta: float): fight.update_tick() func load_character(index: int, path: String, palette: int): - var command_manager = UserCommandManager.new('P%s_' % [index]) + var command_manager = UserCommandManager.new() + command_manager.set_input_prefix('P%s_' % [index]) + command_manager.set_constants(constants) var character = CharacterLoader.load(path, palette, command_manager) return character diff --git a/source/gdscript/system/fight_configuration.gd b/source/gdscript/system/fight_configuration.gd index 8154494..9166d89 100644 --- a/source/gdscript/system/fight_configuration.gd +++ b/source/gdscript/system/fight_configuration.gd @@ -149,7 +149,7 @@ class TurnsName: var p1: NamePlayer = NamePlayer.new() var p2: NamePlayer = NamePlayer.new() -class Time: +class TimeConfiguration: var pos: Vector2 = Vector2(0 ,0) # Example: 160,23 var bg_spr: PoolIntArray = PoolIntArray([]) var counter: LabelConfiguration = LabelConfiguration.new() @@ -277,7 +277,7 @@ var turnsface: TurnsFace = TurnsFace.new() var name: Name = Name.new() var simulname: SimulName = SimulName.new() var turnsname: TurnsName = TurnsName.new() -var time: Time = Time.new() +var time: TimeConfiguration = TimeConfiguration.new() var combo: Combo = Combo.new() var round_info: Round = Round.new() var winicon: WinIcon = WinIcon.new() diff --git a/source/native/Cargo.lock b/source/native/Cargo.lock index d7808ac..effab94 100644 --- a/source/native/Cargo.lock +++ b/source/native/Cargo.lock @@ -1,36 +1,46 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "ahash" -version = "0.7.2" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f200cbb1e856866d9eade941cf3aa0c5d7dd36f74311c4273b494f4ef036957" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ + "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "approx" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" dependencies = [ "num-traits", ] +[[package]] +name = "atomic-take" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ab6b55fe97976e46f91ddbed8d147d966475dc29b2032757ba47e02376fbc3" + [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bindgen" -version = "0.56.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239" +checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" dependencies = [ "bitflags", "cexpr", @@ -43,6 +53,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", + "syn 1.0.109", ] [[package]] @@ -59,9 +70,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cexpr" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ "nom", ] @@ -84,13 +95,10 @@ dependencies = [ ] [[package]] -name = "euclid" -version = "0.22.3" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "536d206ede9fae5a338a1576623b04fd2459f6086e551d374ebf10e9b78bb4df" -dependencies = [ - "num-traits", -] +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "game" @@ -102,9 +110,9 @@ dependencies = [ [[package]] name = "gdnative" -version = "0.9.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff5b6474bfe306c35ecb0cae47291e9af8af2f72e98d65cba7b76b2a52bf82b" +checksum = "21b885c325e7da56848ff9c6c2fbbe791f425e112e215a92235f1ed89f2f4219" dependencies = [ "gdnative-bindings", "gdnative-core", @@ -113,96 +121,105 @@ dependencies = [ [[package]] name = "gdnative-bindings" -version = "0.9.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b520f9b48e89d45852907b1acf0f25bc4bc8e8ee31148d351070096d00c761" +checksum = "59efc7c33ede9ef56a60cf2cb6c388b2ea57e7f14c12c2f82d6f648a2e9c121c" dependencies = [ - "bitflags", "gdnative-core", - "gdnative-sys", "gdnative_bindings_generator", - "heck", "libc", ] [[package]] name = "gdnative-core" -version = "0.9.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d26a9076a40e568e6a29180985a111290e060f33581f37cb7695b1187d3bb7" +checksum = "52d41ed51b3d4106ca8c11d177397fb9eb0fe7969475304c00b28985e1c8b38d" dependencies = [ "ahash", "approx", + "atomic-take", "bitflags", - "euclid", + "gdnative-derive", "gdnative-impl-proc-macros", "gdnative-sys", - "indexmap", + "glam", + "indexmap 1.6.2", "libc", + "once_cell", "parking_lot", ] [[package]] name = "gdnative-derive" -version = "0.9.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a0fc3c7dcadb3d2c2df567f80b12d872363bf3298a97f1b7a668150cd2f1cd" +checksum = "fa9a77e4523e2d3ce735fb22a11fe521c424ebcd5b80b1419622ab8a1af745f0" dependencies = [ + "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "gdnative-impl-proc-macros" -version = "0.9.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2483f2b4038c2efb4fb22742a779201eb0bb1d4fb1d5dca3666e124281af86" +checksum = "9f186ea463ebbe3d9e1db18dcbdc3c73f028bdc9aec09354af0ae734b444508d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "gdnative-sys" -version = "0.9.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97911fe633877345ce7788cf19febb322dc7a7ffd585098fea7e5cef11edf7f2" +checksum = "0f3b65cf3c2470004fd839135fb98d19d8a893633a21aa3070b4b56d27084d7c" dependencies = [ "bindgen", "libc", "miniserde", "proc-macro2", "quote", + "semver", ] [[package]] name = "gdnative_bindings_generator" -version = "0.9.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef6014ab49e58445894633f8a01b321ed86337150b6f1024ffea923e4499b91" +checksum = "5f0c00ae865df87a0f6fa1e90e0651460b17d763e4da905a78f6a871bc2737a2" dependencies = [ "heck", "miniserde", "proc-macro2", "quote", + "regex", "roxmltree", - "syn", + "syn 1.0.109", "unindent", ] [[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", "wasi", ] +[[package]] +name = "glam" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774" + [[package]] name = "glob" version = "0.3.0" @@ -215,14 +232,17 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "heck" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" -dependencies = [ - "unicode-segmentation", -] +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "indexmap" @@ -231,23 +251,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.9.1", ] [[package]] -name = "instant" -version = "0.1.9" +name = "indexmap" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ - "cfg-if", + "equivalent", + "hashbrown 0.14.3", ] [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "lazy_static" @@ -263,9 +284,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.94" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libloading" @@ -279,10 +300,11 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ + "autocfg", "scopeguard", ] @@ -294,20 +316,26 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "mini-internal" -version = "0.1.13" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b3fb39c72c84ffbed14f8ee8b1a0e52ecd323df2ee69499fd3400a95d7269aa" +checksum = "e3b19bf92dbca5c00606fac80965f7a3dd8c83017838a689b9c07aec8fa34f50" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniserde" -version = "0.1.13" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e021d8031f6e224438f402d4c59d26c997e6e13498bd34da1aa1f858bd3b2f43" +checksum = "17df340718635130feb462c31fa21e5243a144576df2452e2ce90753d42e61e7" dependencies = [ "itoa", "mini-internal", @@ -316,12 +344,12 @@ dependencies = [ [[package]] name = "nom" -version = "5.1.2" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", - "version_check", + "minimal-lexical", ] [[package]] @@ -335,33 +363,31 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.7.2" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", - "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-targets", ] [[package]] @@ -370,53 +396,63 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.2.8" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "roxmltree" -version = "0.14.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" +checksum = "461c9b944cd1481b793aeef26d1008b5d1fdeb00e01296cb4ff08aed511c7383" dependencies = [ "xmlparser", ] @@ -439,11 +475,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" + [[package]] name = "shlex" -version = "0.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" [[package]] name = "smallvec" @@ -453,44 +495,66 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "syn" -version = "1.0.72" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] -name = "unicode-segmentation" -version = "1.7.1" +name = "toml_datetime" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unindent" -version = "0.1.7" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" +checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "winapi" @@ -514,8 +578,94 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +dependencies = [ + "memchr", +] + [[package]] name = "xmlparser" -version = "0.13.3" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + +[[package]] +name = "zerocopy" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] diff --git a/source/native/Cargo.toml b/source/native/Cargo.toml index 9147f71..f3f02fe 100644 --- a/source/native/Cargo.toml +++ b/source/native/Cargo.toml @@ -2,7 +2,7 @@ name = "game" version = "0.1.0" authors = ["Jeferson Daniel "] -edition = "2018" +edition = "2021" [lib] crate-type = ["cdylib"] @@ -13,5 +13,5 @@ opt-level = 3 lto = true [dependencies] -gdnative = "0.9" +gdnative = "0.11.3" byteorder = "1.4.3" diff --git a/source/native/src/character/constants.rs b/source/native/src/character/constants.rs new file mode 100644 index 0000000..dcb99f8 --- /dev/null +++ b/source/native/src/character/constants.rs @@ -0,0 +1,59 @@ +use gdnative::prelude::*; + +#[derive(Default)] +pub struct Constants { + pub all_direction_keys: i64, + pub input_state_down: i64, + pub input_state_pressed: i64, + pub input_state_released: i64, + pub input_state_up: i64, + pub key_modifier_ban_other_input: i64, + pub key_modifier_detect_as_4way: i64, + pub key_modifier_must_be_held: i64, + pub key_direction_f: i64, + pub key_direction_b: i64, + pub key_direction_u: i64, + pub key_direction_d: i64, + pub key_a: i64, + pub key_b: i64, + pub key_c: i64, + pub key_x: i64, + pub key_y: i64, + pub key_z: i64, + pub key_s: i64, +} + +impl From<&Variant> for Constants { + fn from(variant: &Variant) -> Self { + let object_ref = variant.try_to_object::(); + + if !object_ref.is_ok() { + godot_error!("invalid constants value"); + return Self::default(); + } + + let object = unsafe { object_ref.expect("invalid object ref").assume_safe() }; + + Constants { + all_direction_keys: i64::from_variant(&object.get("ALL_DIRECTION_KEYS")).unwrap(), + input_state_down: i64::from_variant(&object.get("INPUT_STATE_DOWN")).unwrap(), + input_state_pressed: i64::from_variant(&object.get("INPUT_STATE_PRESSED")).unwrap(), + input_state_released: i64::from_variant(&object.get("INPUT_STATE_RELEASED")).unwrap(), + input_state_up: i64::from_variant(&object.get("INPUT_STATE_UP")).unwrap(), + key_modifier_ban_other_input: i64::from_variant(&object.get("KEY_MODIFIER_BAN_OTHER_INPUT")).unwrap(), + key_modifier_detect_as_4way: i64::from_variant(&object.get("KEY_MODIFIER_DETECT_AS_4WAY")).unwrap(), + key_modifier_must_be_held: i64::from_variant(&object.get("KEY_MODIFIER_MUST_BE_HELD")).unwrap(), + key_direction_f: i64::from_variant(&object.get("KEY_F")).unwrap(), + key_direction_b: i64::from_variant(&object.get("KEY_B")).unwrap(), + key_direction_u: i64::from_variant(&object.get("KEY_U")).unwrap(), + key_direction_d: i64::from_variant(&object.get("KEY_D")).unwrap(), + key_a: i64::from_variant(&object.get("KEY_a")).unwrap(), + key_b: i64::from_variant(&object.get("KEY_b")).unwrap(), + key_c: i64::from_variant(&object.get("KEY_c")).unwrap(), + key_x: i64::from_variant(&object.get("KEY_x")).unwrap(), + key_y: i64::from_variant(&object.get("KEY_y")).unwrap(), + key_z: i64::from_variant(&object.get("KEY_z")).unwrap(), + key_s: i64::from_variant(&object.get("KEY_s")).unwrap(), + } + } +} diff --git a/source/native/src/character/mod.rs b/source/native/src/character/mod.rs new file mode 100644 index 0000000..017451b --- /dev/null +++ b/source/native/src/character/mod.rs @@ -0,0 +1,2 @@ +pub mod user_command_manager; +pub mod constants; diff --git a/source/native/src/character/user_command_manager.rs b/source/native/src/character/user_command_manager.rs new file mode 100644 index 0000000..5e24ec1 --- /dev/null +++ b/source/native/src/character/user_command_manager.rs @@ -0,0 +1,355 @@ +use gdnative::prelude::*; +use super::constants::Constants; +use std::collections::HashMap; + +#[derive(Default, Copy, Clone)] +struct CommandElement { + ticks: i64, + modifier: i64, + code: i64, +} + +impl From<&Variant> for CommandElement { + fn from(variant: &Variant) -> Self { + let dict_ref = Dictionary::from_variant(variant); + + if !dict_ref.is_ok() { + godot_error!("invalid command element value"); + return Self::default(); + } + + let dict = dict_ref.unwrap(); + + CommandElement { + ticks: i64::from_variant(&dict.get("ticks").unwrap_or(Variant::nil())).unwrap(), + modifier: i64::from_variant(&dict.get("modifier").unwrap_or(Variant::nil())).unwrap(), + code: i64::from_variant(&dict.get("code").unwrap_or(Variant::nil())).unwrap(), + } + } +} + +#[derive(Default, Clone)] +struct Command { + name: String, + buffer_time: i64, + time: i64, + cmd: Vec, +} + +impl From<&Variant> for Command { + fn from(variant: &Variant) -> Self { + let dict_ref = Dictionary::from_variant(variant); + + if !dict_ref.is_ok() { + godot_error!("invalid command element value"); + return Self::default(); + } + + let dict = dict_ref.unwrap(); + + let variant_array = VariantArray::from_variant(&dict.get("cmd").unwrap_or(Variant::nil())).unwrap(); + let mut cmd: Vec = Vec::new(); + for command_element_variant in variant_array.iter() { + cmd.push(CommandElement::from(&command_element_variant)); + } + + + Command { + name: String::from_variant(&dict.get("name").unwrap_or(Variant::nil())).unwrap(), + buffer_time: i64::from_variant(&dict.get("buffer_time").unwrap_or(Variant::nil())).unwrap(), + time: i64::from_variant(&dict.get("time").unwrap_or(Variant::nil())).unwrap(), + cmd: cmd, + } + } +} + +#[derive(NativeClass, Default)] +#[inherit(Reference)] +pub struct UserCommandManager { + input_prefix: String, + constants: Constants, + input_map: HashMap, + buffer_size: usize, + buffer_index: usize, + buffer: Vec, + command_countdown: HashMap, + commands: Vec, + #[property] + active_commands: VariantArray, + #[property] + is_facing_right: bool, +} + +#[methods] +impl UserCommandManager { + pub fn new( + _owner: &Reference + ) -> Self { + let buffer_size = 120; + + UserCommandManager { + buffer_size: buffer_size, + buffer_index: 0, + buffer: vec![0; buffer_size], + is_facing_right: true, + ..Default::default() + } + } + + #[method] + pub fn set_input_prefix(&mut self, input_prefix: String) { + self.input_prefix = input_prefix; + } + + #[method] + pub fn set_constants(&mut self, variant: Variant) { + self.constants = Constants::from(&variant); + self.input_map.insert("U".to_string(), self.constants.key_direction_u); + self.input_map.insert("D".to_string(), self.constants.key_direction_d); + self.input_map.insert("a".to_string(), self.constants.key_a); + self.input_map.insert("b".to_string(), self.constants.key_b); + self.input_map.insert("c".to_string(), self.constants.key_c); + self.input_map.insert("x".to_string(), self.constants.key_x); + self.input_map.insert("y".to_string(), self.constants.key_y); + self.input_map.insert("z".to_string(), self.constants.key_z); + self.input_map.insert("s".to_string(), self.constants.key_s); + } + + #[method] + pub fn set_commands(&mut self, variant_array: VariantArray) { + let mut commands: Vec = Vec::new(); + let mut command_countdown: HashMap = HashMap::new(); + for variant in variant_array.iter() { + let command = Command::from(&variant); + command_countdown.insert(command.name.to_string(), 0); + commands.push(command); + } + self.commands = commands; + self.command_countdown = command_countdown; + } + + #[method] + pub fn update(&mut self, in_hit_pause: bool) { + self.update_input_buffer(); + self.update_command_countdown(in_hit_pause); + self.check_commands(in_hit_pause); + self.update_active_commands(); + } + + fn update_input_buffer(&mut self) { + self.buffer_index += 1; + + if self.buffer_index >= self.buffer_size { + self.buffer_index = 0; + } + + let mut code = 0i64; + + let input = Input::godot_singleton(); + + if Input::is_action_pressed(input, format!("{}F", self.input_prefix), false) { + if self.is_facing_right { + code += self.constants.key_direction_f; + } else { + code += self.constants.key_direction_b; + } + } + + if Input::is_action_pressed(input, format!("{}B", self.input_prefix), false) { + if self.is_facing_right { + code += self.constants.key_direction_b; + } else { + code += self.constants.key_direction_f; + } + } + + for action in vec!["U", "D", "a", "b", "c", "x", "y", "z", "s"].iter() { + if Input::is_action_pressed(input, format!("{}{}", self.input_prefix, action), false) { + code += self.input_map.get(&action.to_string()).unwrap_or(&0); + } + } + + self.buffer[self.buffer_index] = code; + } + + fn update_command_countdown(&mut self, in_hit_pause: bool) { + if in_hit_pause { + return; + } + + for value in self.command_countdown.values_mut() { + *value = i64::max(*value - 1, 0); + } + } + + fn check_commands(&mut self, in_hit_pause: bool) { + for command in self.commands.iter() { + if !self.check_command(command) { + continue; + } + + let mut time = command.buffer_time; + + if in_hit_pause { + time += 1; + } + + self.command_countdown.insert(command.name.clone(), time); + } + } + + fn update_active_commands(&mut self) { + let active_commands = VariantArray::new(); + for (key, value) in self.command_countdown.iter() { + if *value <= 0 { + continue; + } + active_commands.push(GodotString::from(key)); + } + self.active_commands = active_commands.into_shared(); + } + + fn check_command(&self, command: &Command) -> bool { + let mut element_index = command.cmd.len() - 1; + let mut input_index = 0usize; + + while input_index != self.buffer_size { + let match_index = self.scan_for_match(command, element_index, input_index); + + if match_index < 0 { + return false + } + + if element_index > 0 { + if match_index > command.time { + return false; + } + + element_index -= 1; + input_index = match_index as usize; + } else if element_index == 0 { + return match_index <= command.time; + } else { + return false; + } + + input_index += 1; + } + + false + } + + fn scan_for_match(&self, command: &Command, element_index: usize, input_index: usize) -> i64 { + let element = command.cmd[element_index]; + let scan_length = usize::min(self.buffer_size, command.time as usize); + + for i in input_index..(input_index + scan_length) { + if element_index == command.cmd.len() - 1 { + if element.ticks == -1 { + if i != input_index { + return -1 + } + } else if i - 1 != input_index && i != input_index { + return -1; + } + } + + if self.element_match(&element, i) { + if element_index < command.cmd.len() - 1 { + let next_element = command.cmd[element_index + 1]; + let nothing_else = (next_element.modifier & self.constants.key_modifier_ban_other_input) != 0; + if nothing_else && !self.check_identical_input(input_index, i) { + continue + } + } + + return i as i64 + } + } + + -1 + } + + fn element_match(&self, element: &CommandElement, input_index: usize) -> bool { + let state = self.get_input_state(input_index, element); + let must_be_held = (element.modifier & self.constants.key_modifier_must_be_held) != 0; + + if must_be_held { + return state == self.constants.input_state_down || state == self.constants.input_state_pressed; + } + + if element.ticks != -1 { + if input_index >= self.buffer_size { + return false; + } + + if input_index == 0 || self.get_input_state(input_index - 1, element) != self.constants.input_state_released { + return false; + } + + let mut hold_count = 1i64; + + for i in (input_index + 1)..self.buffer_size { + if self.get_input_state(i, element) != self.constants.input_state_down { + break; + } + hold_count += 1; + } + + if hold_count < element.ticks { + return false; + } + } else if state != self.constants.input_state_pressed { + return false; + } + + true + } + + fn get_input_value(&self, index: usize) -> i64 { + let aux_buffer_index = self.buffer_index as i64; + let aux_buffer_size = self.buffer_size as i64; + let aux_index = index as i64; + let aux_result = (aux_buffer_index - aux_index + aux_buffer_size) % aux_buffer_size; + + self.buffer[aux_result as usize] + } + + fn get_input_state(&self, index: usize, element: &CommandElement) -> i64 { + let current = self.get_input_value(index); + let previous = if index != self.buffer_size -1 { self.get_input_value(index + 1) } else { 0i64 }; + let current_state = self.check_element_state(current, element); + let previous_state = self.check_element_state(previous, element); + + if current_state { + return if previous_state { self.constants.input_state_down } else { self.constants.input_state_pressed } + } + + if previous_state { self.constants.input_state_released } else { self.constants.input_state_up } + } + + fn check_identical_input(&self, start_index: usize, end_index: usize) -> bool { + let input_value = self.get_input_value(start_index); + + for i in (start_index + 1)..end_index { + if input_value != self.get_input_value(i) { + return false; + } + } + + true + } + + fn check_element_state(&self, input_code: i64, element: &CommandElement) -> bool { + let use_4_way = (element.modifier & self.constants.key_modifier_detect_as_4way) != 0; + let mut key_down = (input_code & element.code) == element.code; + + if key_down && !use_4_way { + let input_direction = input_code & self.constants.all_direction_keys; + let element_direction = element.code & self.constants.all_direction_keys; + key_down = element_direction == 0 || (input_direction == element_direction); + } + + key_down + } +} diff --git a/source/native/src/expressions/context.rs b/source/native/src/expressions/context.rs index b4ae01e..4212f59 100644 --- a/source/native/src/expressions/context.rs +++ b/source/native/src/expressions/context.rs @@ -15,7 +15,7 @@ impl Context { pub fn godot_call(&self, name: &str, arguments: &[Variant]) -> Option { let object_ref = self.object.try_to_object::(); - if object_ref.is_none() { + if !object_ref.is_ok() { godot_print!("invalid_context"); return Option::None; } diff --git a/source/native/src/expressions/mugen_expression.rs b/source/native/src/expressions/mugen_expression.rs index 99df25d..ada73ad 100644 --- a/source/native/src/expressions/mugen_expression.rs +++ b/source/native/src/expressions/mugen_expression.rs @@ -24,31 +24,31 @@ impl MugenExpression { } } - #[export] - fn parse(&mut self, _owner: &Reference, text: String) { + #[method] + fn parse(&mut self, text: String) { self.expression = parse(Rc::clone(&self.state_ref), text); self.error = self.state_ref.borrow().error.to_string(); } - #[export] - fn execute(&self, _owner: &Reference, context: Variant) -> Variant { + #[method] + fn execute(&self, context: Variant) -> Variant { let context_object = Context::new(context); self.expression.evaluate(&context_object).to_variant() } - #[export] - fn get_error_text(&self, _owner: &Reference) -> String { + #[method] + fn get_error_text(&self) -> String { self.error.to_string() } - #[export] - fn has_error(&self, _owner: &Reference) -> bool { + #[method] + fn has_error(&self) -> bool { !self.error.is_empty() } - #[export] - fn to_string(&self, _owner: &Reference) -> String { + #[method] + fn to_string(&self) -> String { self.expression.to_string() } } diff --git a/source/native/src/expressions/value.rs b/source/native/src/expressions/value.rs index a1b294b..740e499 100644 --- a/source/native/src/expressions/value.rs +++ b/source/native/src/expressions/value.rs @@ -48,9 +48,9 @@ impl From for Value { impl ToVariant for Value { fn to_variant(&self) -> Variant { match self { - Value::IntValue(x) => Variant::from_i64(*x), - Value::FloatValue(x) => Variant::from_f64(*x), - Value::StringValue(x) => Variant::from_str(x), + Value::IntValue(x) => Variant::new(*x), + Value::FloatValue(x) => Variant::new(*x), + Value::StringValue(x) => Variant::new(x), Value::ArrayValue(x) => { let array = VariantArray::new(); for val in x.iter() { @@ -58,7 +58,7 @@ impl ToVariant for Value { } array.into_shared().to_variant() } - _ => Variant::new(), + _ => Variant::nil(), } } } diff --git a/source/native/src/fnt/fnt_parser.rs b/source/native/src/fnt/fnt_parser.rs index c15fa33..b88396a 100644 --- a/source/native/src/fnt/fnt_parser.rs +++ b/source/native/src/fnt/fnt_parser.rs @@ -1,6 +1,6 @@ use crate::sff::data::{BufferReader, DataError, DataReader, FileReader}; use crate::sff::pcx::read_pcx; -use gdnative::api::file::File; +use gdnative::api::File; use gdnative::prelude::*; #[allow(dead_code)] @@ -44,8 +44,8 @@ impl FntParser { FntParser {} } - #[export] - pub fn get_font_data(&self, _owner: &Reference, path: String) -> Variant { + #[method] + pub fn get_font_data(&self, path: String) -> Variant { let result = self.read_file(path); if let Ok(dict) = result { @@ -54,7 +54,7 @@ impl FntParser { godot_print!("error: {}", message); } - Variant::new() + Variant::nil() } pub fn read_file(&self, path: String) -> Result { diff --git a/source/native/src/lib.rs b/source/native/src/lib.rs index 51b4ffc..3f8c552 100644 --- a/source/native/src/lib.rs +++ b/source/native/src/lib.rs @@ -3,6 +3,7 @@ mod expressions; mod fnt; mod sff; mod snd; +mod character; // Function that registers all exposed classes to Godot fn init(handle: InitHandle) { @@ -10,6 +11,7 @@ fn init(handle: InitHandle) { handle.add_class::(); handle.add_class::(); handle.add_class::(); + handle.add_class::(); } // Macro that creates the entry-points of the dynamic library. diff --git a/source/native/src/sff/data.rs b/source/native/src/sff/data.rs index 069e4c7..35e9646 100644 --- a/source/native/src/sff/data.rs +++ b/source/native/src/sff/data.rs @@ -1,5 +1,5 @@ use byteorder::{LittleEndian, ReadBytesExt}; -use gdnative::api::file::File; +use gdnative::api::File; use std::fmt; use std::io::Cursor; use std::io::Read; diff --git a/source/native/src/sff/image.rs b/source/native/src/sff/image.rs index 256b593..f12d63b 100644 --- a/source/native/src/sff/image.rs +++ b/source/native/src/sff/image.rs @@ -1,4 +1,4 @@ -use gdnative::api::image::Image; +use gdnative::api::Image; use gdnative::prelude::*; use std::rc::Rc; @@ -95,7 +95,7 @@ impl RawImage { my_byte_array.push(color.a); } - let dest = ByteArray::from_slice(my_byte_array.as_slice()); + let dest = PoolArray::from_slice(my_byte_array.as_slice()); let image = Image::new(); image.create_from_data( diff --git a/source/native/src/sff/sff_common.rs b/source/native/src/sff/sff_common.rs index 44c13cf..13f5abc 100644 --- a/source/native/src/sff/sff_common.rs +++ b/source/native/src/sff/sff_common.rs @@ -53,11 +53,11 @@ impl ToVariant for SffMetadata { } } -pub fn export_palette(source: Rc) -> ColorArray { - let mut result = ColorArray::new(); +pub fn export_palette(source: Rc) -> PoolArray { + let mut result = PoolArray::new(); for raw_color in source.colors.iter() { - result.push(Color::rgba( + result.push(Color::from_rgba( raw_color.r as f32 / 255.0, raw_color.g as f32 / 255.0, raw_color.b as f32 / 255.0, @@ -68,7 +68,7 @@ pub fn export_palette(source: Rc) -> ColorArray { result } -pub fn import_palette(source: ColorArray) -> Rc { +pub fn import_palette(source: PoolArray) -> Rc { let mut raw_colors: Vec = Vec::new(); for i in 0..source.len() { diff --git a/source/native/src/sff/sff_parser.rs b/source/native/src/sff/sff_parser.rs index 8585560..42eef15 100644 --- a/source/native/src/sff/sff_parser.rs +++ b/source/native/src/sff/sff_parser.rs @@ -18,8 +18,8 @@ impl SffParser { } } - #[export] - pub fn read_metadata(&mut self, _owner: &Reference, path: String) -> Variant { + #[method] + pub fn read_metadata(&mut self, path: String) -> Variant { let result_v2 = sffv2::read_metadata(&path); if result_v2.is_err() { @@ -33,18 +33,18 @@ impl SffParser { godot_error!("error: sffv1: {}", message); } - return Variant::new(); + return Variant::nil(); } if let Ok(metadata) = result_v2 { return metadata.to_variant() } - Variant::new() + Variant::nil() } - #[export] - pub fn read_palette(&mut self, _owner: &Reference, path: String) -> Variant { + #[method] + pub fn read_palette(&mut self, path: String) -> Variant { let result = sffv1::read_palette(&path); match result { @@ -52,13 +52,13 @@ impl SffParser { Err(error) => { godot_error!("error: read_palette: {}", error); - Variant::new() + Variant::nil() } } } - #[export] - pub fn read_palettes(&mut self, _owner: &Reference, path: String) -> Variant { + #[method] + pub fn read_palettes(&mut self, path: String) -> Variant { let result = sffv2::read_palettes(&path); match result { @@ -74,13 +74,13 @@ impl SffParser { Err(error) => { godot_error!("error: read_palette: {}", error); - Variant::new() + Variant::nil() } } } - #[export] - pub fn read_images(&mut self, _owner: &Reference, path: String, palette: Variant, groups: Variant) -> Variant { + #[method] + pub fn read_images(&mut self, path: String, palette: Variant, groups: Variant) -> Variant { let palette_import = self.parse_palette_argument(palette); let groups_vector: Vec = self.parse_groups_argument(groups); let result_v2 = sffv2::read_images(&path, &groups_vector); @@ -96,14 +96,14 @@ impl SffParser { godot_error!("error: {}", message); } - return Variant::new(); + return Variant::nil(); } if let Ok(mut sffdata) = result_v2 { return self.export_images(&mut sffdata, palette_import); } - Variant::new() + Variant::nil() } fn export_images(&self, sffdata: &mut Vec, maybe_palette: Option>) -> Variant { @@ -136,7 +136,7 @@ impl SffParser { pub fn parse_palette_argument(&self, variant: Variant) -> Option> { match variant.get_type() { - VariantType::ColorArray => Option::Some(import_palette(ColorArray::from_variant(&variant).unwrap())), + VariantType::ColorArray => Option::Some(import_palette(PoolArray::from_variant(&variant).unwrap())), _ => Option::None } } @@ -145,7 +145,7 @@ impl SffParser { match variant.get_type() { VariantType::Int32Array => { let mut result: Vec = Vec::new(); - let values = Int32Array::from_variant(&variant).unwrap(); + let values: PoolArray = PoolArray::from_variant(&variant).unwrap(); for i in 0..values.len() { result.push(values.get(i) as i16); } diff --git a/source/native/src/sff/sffv1.rs b/source/native/src/sff/sffv1.rs index af05025..5f772e4 100644 --- a/source/native/src/sff/sffv1.rs +++ b/source/native/src/sff/sffv1.rs @@ -2,8 +2,8 @@ use crate::sff::data::{BufferAccess, BufferReader, DataError, DataReader, FileRe use crate::sff::image::{Palette, RawColor, RawImage}; use crate::sff::pcx::read_pcx; use crate::sff::sff_common::{SffData, SffPal, SffMetadata, SffReference}; -use gdnative::Ref; -use gdnative::api::file::File; +use gdnative::object::Ref; +use gdnative::api::File; use gdnative::prelude::Unique; use std::cell::RefCell; use std::collections::HashMap; diff --git a/source/native/src/sff/sffv2.rs b/source/native/src/sff/sffv2.rs index 749d46d..05b7269 100644 --- a/source/native/src/sff/sffv2.rs +++ b/source/native/src/sff/sffv2.rs @@ -3,8 +3,8 @@ use crate::sff::image::{Palette, RawColor, RawImage}; use crate::sff::lz5::decode_lz5; use crate::sff::rle5::{decode_rle5, decode_rle8}; use crate::sff::sff_common::{SffData, SffPal, SffMetadata, SffReference}; -use gdnative::Ref; -use gdnative::api::file::File; +use gdnative::object::Ref; +use gdnative::api::File; use gdnative::prelude::Unique; use std::cell::RefCell; use std::collections::HashMap; diff --git a/source/native/src/snd/mod.rs b/source/native/src/snd/mod.rs index a2cdd96..be7cd10 100644 --- a/source/native/src/snd/mod.rs +++ b/source/native/src/snd/mod.rs @@ -1,2 +1,3 @@ pub mod snd_parser; pub mod structs; + diff --git a/source/native/src/snd/snd_parser.rs b/source/native/src/snd/snd_parser.rs index 33637bb..4832efe 100644 --- a/source/native/src/snd/snd_parser.rs +++ b/source/native/src/snd/snd_parser.rs @@ -1,7 +1,7 @@ use crate::sff::data::{BufferReader, DataError, DataReader, FileReader}; use crate::snd::structs::{FileHeader, SubHeader, WavHeader}; -use gdnative::api::file::File; -use gdnative::api::audio_stream_sample::AudioStreamSample; +use gdnative::api::File; +use gdnative::api::AudioStreamSample; use gdnative::prelude::*; #[derive(NativeClass)] @@ -14,8 +14,8 @@ impl SndParser { SndParser {} } - #[export] - pub fn read_sounds(&self, _owner: &Reference, path: String) -> Variant { + #[method] + pub fn read_sounds(&self, path: String) -> Variant { let result = self.read_file(path); if let Ok(dict) = result { @@ -24,7 +24,7 @@ impl SndParser { godot_error!("{}", message); } - Variant::new() + Variant::nil() } pub fn read_file(&self, path: String) -> Result { @@ -96,7 +96,7 @@ impl SndParser { } } -fn to_signed(source: &[u8]) -> ByteArray { +fn to_signed(source: &[u8]) -> PoolArray { source .iter() .map(|value| ((*value as i16) - 128) as u8) diff --git a/source/native/user_command_manager.gdns b/source/native/user_command_manager.gdns new file mode 100644 index 0000000..842f799 --- /dev/null +++ b/source/native/user_command_manager.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://source/native/game.gdnlib" type="GDNativeLibrary" id=1] + +[resource] + +class_name = "UserCommandManager" +library = ExtResource( 1 )