diff --git a/main.tscn b/main.tscn index e12978e..6f7666d 100644 --- a/main.tscn +++ b/main.tscn @@ -53,6 +53,7 @@ shape = SubResource("BoxShape_seabed") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3, 0) [node name="CameraRig" type="Node3D" parent="." unique_id=2139913829 node_paths=PackedStringArray("cam") groups=["shift_with_origin"]] +physics_interpolation_mode = 2 transform = Transform3D(1, 0, 0, 0, 0.9396926, 0.34202012, 0, -0.34202012, 0.9396926, 0, 0, 0) script = ExtResource("4_1bvp3") cam = NodePath("PlayerCamera") diff --git a/project.godot b/project.godot index a79f228..0c1b05d 100644 --- a/project.godot +++ b/project.godot @@ -60,6 +60,16 @@ fire={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":49,"key_label":0,"unicode":49,"location":0,"echo":false,"script":null) ] } +debug_spawn_boat={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194333,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +debug_possess_next={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194334,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} [layer_names] diff --git a/scripts/boat.gd b/scripts/boat.gd index ffbc48c..c456eb9 100644 --- a/scripts/boat.gd +++ b/scripts/boat.gd @@ -7,27 +7,41 @@ extends FloatingBody @export var throttle_response := 1.5 # how fast the engine spools up/down @export var rudder_strength := 2.5 # turning torque at speed @export var keel_grip := 3.0 # resistance to sliding sideways -@export var loadout: Dictionary[StringName, WeaponDef] = {} +@export var loadout: Dictionary[StringName, WeaponDef] = {} # WeaponSlot Name -> WeaponDef +@export var weapon_groups: Dictionary[int, Array] = {} # group id -> slot names; group 0 is auto-built (all slots), editor value ignored var desired_throttle := 0.0 # move_toward target for actual throttle var steer_input := 0.0 var throttle := 0.0 # current throttle state of ship var _slots: Array[WeaponSlot] = [] +var _slots_by_name: Dictionary[StringName, WeaponSlot] = {} +var fire_intents: Dictionary[int, bool] = {} # written by controllers, like steer_input func _ready() -> void: super() + add_to_group(&"boats") for child in get_children(): if child is WeaponSlot: _slots.append(child) + _slots_by_name[child.name] = child var def: WeaponDef = loadout.get(child.name) if def != null: child.mount(def) + # Weapon group 0 should always be all weapons, regardless + # TODO: If ever weapon slots would dynamically be added during a scene, change + var all_names: Array = [] + for slot in _slots: + all_names.append(slot.name) + weapon_groups[0] = all_names + func _physics_process(delta: float) -> void: super(delta) throttle = move_toward(throttle, desired_throttle, throttle_response * delta) + _process_fire() + if submerged_ratio <= 0.0: return # airborne: no thrust, no rudder, no keel @@ -51,8 +65,12 @@ func _physics_process(delta: float) -> void: right = right.normalized() var lateral_speed := linear_velocity.dot(right) apply_central_force(-right * lateral_speed * keel_grip * mass * submerged_ratio) - -func fire_weapons() -> void: - for slot in _slots: - if slot.weapon != null: - slot.weapon.try_fire() + +func _process_fire() -> void: + for group_id in weapon_groups: + if not fire_intents.get(group_id, false): + continue + for slot_name in weapon_groups[group_id]: + var slot: WeaponSlot = _slots_by_name.get(slot_name) + if slot != null and slot.weapon != null: + slot.weapon.try_fire() diff --git a/scripts/game.gd b/scripts/game.gd index 71d7c9e..6cc77a7 100644 --- a/scripts/game.gd +++ b/scripts/game.gd @@ -1,6 +1,20 @@ # scripts/game.gd — autoloaded as "Game" extends Node +const BOAT_SCENE := preload("res://boat.tscn") + func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("restart"): get_tree().reload_current_scene() + if event.is_action_pressed(&"debug_spawn_boat"): + _debug_spawn_boat() + +func _debug_spawn_boat() -> void: + var focus := get_tree().get_first_node_in_group(&"boats") as Node3D + var boat: Boat = BOAT_SCENE.instantiate() + + if focus != null: + boat.position = focus.global_position + focus.global_basis.x * 10.0 + Vector3.UP * 2.0 + else: + boat.position = Vector3(0, 3, 0) + get_tree().current_scene.add_child(boat, true) diff --git a/scripts/player_controller.gd b/scripts/player_controller.gd index 73547ff..757d0cc 100644 --- a/scripts/player_controller.gd +++ b/scripts/player_controller.gd @@ -6,6 +6,7 @@ extends Node if current_controlled != null and current_controlled != value: current_controlled.desired_throttle = 0.0 current_controlled.steer_input = 0.0 + current_controlled.fire_intents.clear() current_controlled = value if is_node_ready(): if current_controlled != null: @@ -56,9 +57,12 @@ func _process(delta: float) -> void: current_controlled.desired_throttle = desired_throttle current_controlled.steer_input = steer_input - if Input.is_action_pressed("fire"): - current_controlled.fire_weapons() + current_controlled.fire_intents[0] = Input.is_action_pressed("fire") +func _unhandled_input(event: InputEvent) -> void: + if event.is_action_pressed(&"debug_possess_next"): + _possess_next() + func _possess() -> void: if camera_rig != null: camera_rig.target = current_controlled @@ -66,3 +70,11 @@ func _possess() -> void: world_manager.focus = current_controlled if hud != null: hud.boat = current_controlled + +func _possess_next() -> void: + var boats := get_tree().get_nodes_in_group(&"boats") + if boats.is_empty(): + current_controlled = null + return + var idx := boats.find(current_controlled) + current_controlled = boats[(idx + 1) % boats.size()]