WIP Character
This commit is contained in:
@ -1,8 +1,10 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://didt2nsdtbmra"]
|
||||
[gd_scene load_steps=6 format=3 uid="uid://didt2nsdtbmra"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://6co67nfy8ngb" path="res://scenes/ship/builder/module.gd" id="1_nqe0s"]
|
||||
[ext_resource type="PackedScene" uid="uid://bho8x10x4oab7" path="res://scenes/ship/builder/pieces/hullplate.tscn" id="2_foqop"]
|
||||
[ext_resource type="PackedScene" uid="uid://d3hitk62fice4" path="res://scenes/ship/builder/pieces/bulkhead.tscn" id="4_dmrms"]
|
||||
[ext_resource type="PackedScene" uid="uid://chgycmkkaf7jv" path="res://scenes/characters/pilot_ball.tscn" id="4_i3kos"]
|
||||
[ext_resource type="PackedScene" uid="uid://2n42nstcj1n0" path="res://scenes/ship/components/station_component.tscn" id="5_nqe0s"]
|
||||
|
||||
[node name="Module" type="Node2D"]
|
||||
script = ExtResource("1_nqe0s")
|
||||
@ -47,3 +49,8 @@ position = Vector2(50, 100)
|
||||
|
||||
[node name="@StaticBody2D@30642" parent="." instance=ExtResource("4_dmrms")]
|
||||
position = Vector2(50, 0)
|
||||
|
||||
[node name="PilotBall" parent="." instance=ExtResource("4_i3kos")]
|
||||
|
||||
[node name="Station" parent="." instance=ExtResource("5_nqe0s")]
|
||||
position = Vector2(0, -100)
|
||||
|
||||
@ -57,13 +57,40 @@ time_reset={
|
||||
"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":82,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_up={
|
||||
"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":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_down={
|
||||
"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":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_left={
|
||||
"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":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"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":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
interact={
|
||||
"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":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[layer_names]
|
||||
|
||||
2d_physics/layer_1="ship_hull"
|
||||
2d_physics/layer_1="hullplates"
|
||||
2d_physics/layer_2="ship_components"
|
||||
2d_physics/layer_3="celestial_bodies"
|
||||
2d_physics/layer_4="projectiles"
|
||||
2d_physics/layer_5="bulkheads"
|
||||
2d_physics/layer_6="characters"
|
||||
|
||||
[physics]
|
||||
|
||||
|
||||
@ -7,11 +7,17 @@ const EXTERIOR_DRAG_FACTOR: float = 0.05
|
||||
|
||||
# When pushing off hullplates (low friction, slow acceleration)
|
||||
const INTERIOR_SLUGGISH_SPEED: float = 100.0
|
||||
const INTERIOR_SLUGGISH_ACCEL: float = 0.15 # Low acceleration, simulating mass and small push
|
||||
const INTERIOR_SLUGGISH_ACCEL: float = 5 # Low acceleration, simulating mass and small push
|
||||
|
||||
# When gripping a ladder (high friction, direct control)
|
||||
const LADDER_SPEED: float = 350.0
|
||||
const LADDER_ACCEL: float = 0.9 # High acceleration, simulating direct grip
|
||||
const LADDER_SPEED: float = 100.0
|
||||
const LADDER_ACCEL: float = 20 # High acceleration, simulating direct grip
|
||||
|
||||
@onready var camera: Camera2D = $Camera2D
|
||||
@onready var overlap_area: Area2D = $OverlapDetector
|
||||
|
||||
var nearby_station: StationComponent = null
|
||||
var current_station: StationComponent = null
|
||||
|
||||
# --- State Variables ---
|
||||
enum MovementState {
|
||||
@ -38,15 +44,33 @@ func _ready():
|
||||
# You must have an Area2D child on PilotBall to detect overlaps.
|
||||
|
||||
# Placeholder: Assuming the PilotBall has an Area2D named 'OverlapChecker'
|
||||
var overlap_checker = find_child("OverlapChecker")
|
||||
if overlap_checker:
|
||||
overlap_checker.body_entered.connect(on_body_entered)
|
||||
overlap_checker.body_exited.connect(on_body_exited)
|
||||
|
||||
#var overlap_checker = find_child("OverlapChecker")
|
||||
#if overlap_checker:
|
||||
overlap_area.body_entered.connect(on_body_entered)
|
||||
overlap_area.body_exited.connect(on_body_exited)
|
||||
overlap_area.area_entered.connect(_on_station_area_entered)
|
||||
overlap_area.area_exited.connect(_on_station_area_exited)
|
||||
# Ensure this action is set in project settings: "interact" mapped to Space.
|
||||
if !InputMap.has_action("interact"):
|
||||
push_error("Missing 'interact' input action for ladder logic.")
|
||||
|
||||
camera.make_current()
|
||||
|
||||
# New function to handle global inputs
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
# --- Map Toggling ---
|
||||
if event.is_action_pressed("ui_map_mode"):
|
||||
SignalBus.emit_signal("map_mode_toggled")
|
||||
|
||||
# --- Time Scale Controls ---
|
||||
if event.is_action_pressed("time_increase"):
|
||||
Engine.time_scale = min(Engine.time_scale * 1.2, 1000)
|
||||
|
||||
elif event.is_action_pressed("time_decrease"):
|
||||
Engine.time_scale = max(Engine.time_scale * 0.833, 0.1)
|
||||
|
||||
elif event.is_action_pressed("time_reset"):
|
||||
Engine.time_scale = 1.0
|
||||
|
||||
func on_body_entered(body: Node2D):
|
||||
# Detect Modules (which all inherit OrbitalBody2D via StructuralPiece)
|
||||
@ -74,10 +98,9 @@ func _physics_process(delta):
|
||||
var input_dir = Input.get_vector("move_left", "move_right", "move_up", "move_down")
|
||||
|
||||
match current_state:
|
||||
MovementState.NO_CONTROL:
|
||||
# Apply heavy drag to simulate floating in space without external push
|
||||
_apply_drag(EXTERIOR_DRAG_FACTOR)
|
||||
|
||||
#MovementState.NO_CONTROL:
|
||||
## Apply heavy drag to simulate floating in space without external push
|
||||
#_sluggish_movement(input_dir, delta)
|
||||
MovementState.ZERO_G_INTERIOR:
|
||||
# Sluggish movement: player is pushing off nearby walls/hullplates
|
||||
_sluggish_movement(input_dir, delta)
|
||||
@ -86,8 +109,9 @@ func _physics_process(delta):
|
||||
# Snappy movement: direct control and high acceleration
|
||||
_ladder_movement(input_dir, delta)
|
||||
|
||||
# 2. Handle Ladder Grab/Launch Input
|
||||
_handle_ladder_input(input_dir)
|
||||
# --- Update Ladder/Station Input Handling ---
|
||||
# We'll replace the old _handle_ladder_input with a more general one
|
||||
_handle_interaction_input(input_dir)
|
||||
|
||||
move_and_slide()
|
||||
|
||||
@ -119,26 +143,35 @@ func _update_movement_state():
|
||||
|
||||
# --- Movement Implementations ---
|
||||
|
||||
func _apply_drag(factor: float):
|
||||
# Gently slow down the velocity (simulating environmental drag)
|
||||
velocity = velocity.lerp(Vector2.ZERO, factor)
|
||||
|
||||
func _sluggish_movement(input_dir: Vector2, delta: float):
|
||||
# Simulates pushing off the wall: slow acceleration, but minimal drag
|
||||
var target_velocity = input_dir * INTERIOR_SLUGGISH_SPEED
|
||||
velocity = velocity.lerp(target_velocity, INTERIOR_SLUGGISH_ACCEL)
|
||||
var target_velocity = input_dir * INTERIOR_SLUGGISH_ACCEL
|
||||
velocity = velocity + target_velocity * delta
|
||||
#velocity.lerp(velocity + interi, INTERIOR_SLUGGISH_ACCEL)
|
||||
|
||||
func _ladder_movement(input_dir: Vector2, delta: float):
|
||||
# Simulates direct grip: fast acceleration, perfect control
|
||||
var target_velocity = input_dir * LADDER_SPEED
|
||||
velocity = velocity.lerp(target_velocity, LADDER_ACCEL)
|
||||
velocity = velocity.lerp(target_velocity, LADDER_ACCEL * delta)
|
||||
|
||||
|
||||
# --- Ladder Input and Launch Logic ---
|
||||
|
||||
func _handle_ladder_input(input_dir: Vector2):
|
||||
# If currently grabbing, SPACE press is handled in _update_movement_state
|
||||
func _handle_interaction_input(input_dir: Vector2):
|
||||
# If we are currently using a station
|
||||
if current_station:
|
||||
if Input.is_action_just_pressed("interact"):
|
||||
current_station.disengage()
|
||||
current_station = null
|
||||
return # Do nothing else while in a station
|
||||
|
||||
# If we are near a station and press interact
|
||||
if is_instance_valid(nearby_station) and Input.is_action_just_pressed("interact"):
|
||||
current_station = nearby_station
|
||||
current_station.occupy(self)
|
||||
return
|
||||
|
||||
# If currently grabbing, SPACE press is handled in _update_movement_state
|
||||
if current_state == MovementState.LADDER_GRIP:
|
||||
if Input.is_action_just_released("interact"):
|
||||
# Launch the player away from the ladder
|
||||
@ -154,3 +187,13 @@ func _handle_ladder_input(input_dir: Vector2):
|
||||
# Immediately switch to zero-G interior state
|
||||
is_grabbing_ladder = false
|
||||
current_state = MovementState.ZERO_G_INTERIOR
|
||||
|
||||
# --- New Functions for Station Interaction ---
|
||||
func _on_station_area_entered(area: Area2D):
|
||||
if area.get_parent() is StationComponent:
|
||||
nearby_station = area.get_parent()
|
||||
print("Near station: ", nearby_station.name)
|
||||
|
||||
func _on_station_area_exited(area: Area2D):
|
||||
if area.get_parent() == nearby_station:
|
||||
nearby_station = null
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://chgycmkkaf7jv"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://chgycmkkaf7jv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dxngvoommn5f1" path="res://scenes/characters/pilot_ball.gd" id="1_rhbna"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_6jclb"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_rhbna"]
|
||||
|
||||
[node name="PilotBall" type="CharacterBody2D"]
|
||||
collision_layer = 32
|
||||
collision_mask = 16
|
||||
script = ExtResource("1_rhbna")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
@ -12,3 +16,11 @@ shape = SubResource("CircleShape2D_6jclb")
|
||||
debug_color = Color(0.61528, 0.358023, 1, 1)
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
zoom = Vector2(3, 3)
|
||||
|
||||
[node name="OverlapDetector" type="Area2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="OverlapDetector"]
|
||||
shape = SubResource("CircleShape2D_rhbna")
|
||||
|
||||
@ -2,7 +2,9 @@
|
||||
class_name Module
|
||||
extends OrbitalBody2D
|
||||
|
||||
# REMOVED: @onready vars for containers are no longer needed.
|
||||
# --- New properties inherited from Spaceship ---
|
||||
@export var ship_name: String = "Unnamed Ship" # Only relevant for the root module
|
||||
@export var hull_integrity: float = 100.0 # This could also be a calculated property later
|
||||
|
||||
const COMPONENT_GRID_SIZE = 64.0
|
||||
|
||||
@ -92,3 +94,22 @@ func clear_module():
|
||||
component.queue_free()
|
||||
|
||||
_recalculate_collision_shape()
|
||||
|
||||
# --- New function inherited from Spaceship ---
|
||||
# Damage can have a position for breach effects.
|
||||
func take_damage(amount: float, damage_position: Vector2):
|
||||
hull_integrity -= amount
|
||||
print("%s hull integrity at %.1f%%" % [ship_name, hull_integrity])
|
||||
|
||||
if hull_integrity <= 0:
|
||||
destroy_ship()
|
||||
else:
|
||||
# Find the LifeSupport component and check for a breach
|
||||
for child in get_children():
|
||||
if child is LifeSupport: # Assuming LifeSupport becomes a Component class
|
||||
child.check_for_breach(damage_position, self)
|
||||
|
||||
func destroy_ship():
|
||||
print("%s has been destroyed!" % ship_name)
|
||||
# Add explosion/destruction effects here
|
||||
queue_free()
|
||||
|
||||
@ -6,7 +6,8 @@
|
||||
size = Vector2(10, 100)
|
||||
|
||||
[node name="Bulkhead" type="StaticBody2D"]
|
||||
collision_layer = 5
|
||||
collision_layer = 16
|
||||
collision_mask = 60
|
||||
script = ExtResource("1_1wp2n")
|
||||
metadata/_custom_type_script = "uid://b7f8x2qimvn37"
|
||||
|
||||
|
||||
8
scenes/ship/components/databank.gd
Normal file
8
scenes/ship/components/databank.gd
Normal file
@ -0,0 +1,8 @@
|
||||
@tool
|
||||
class_name Databank
|
||||
extends Resource
|
||||
|
||||
## The name displayed in the UI (e.g., "Flight Helm MK1").
|
||||
@export var display_name: String = "Unnamed Databank"
|
||||
## The UI scene this databank provides when installed.
|
||||
@export var ui_scene: PackedScene
|
||||
1
scenes/ship/components/databank.gd.uid
Normal file
1
scenes/ship/components/databank.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://osk1l75vlikn
|
||||
82
scenes/ship/components/station_component.gd
Normal file
82
scenes/ship/components/station_component.gd
Normal file
@ -0,0 +1,82 @@
|
||||
@tool
|
||||
class_name StationComponent
|
||||
extends Component
|
||||
|
||||
signal occupancy_changed(is_occupied: bool)
|
||||
|
||||
## The "software" currently installed in this station.
|
||||
@export var installed_databanks: Array[Databank]
|
||||
|
||||
var occupant: PilotBall = null
|
||||
var active_ui_instances: Array[Control] = []
|
||||
@onready var interaction_area: Area2D = $InteractionArea
|
||||
|
||||
func _process(delta):
|
||||
# NEW: The station now checks for the disengage input.
|
||||
if is_occupied() and Input.is_action_just_pressed("interact"):
|
||||
disengage()
|
||||
|
||||
func is_occupied() -> bool:
|
||||
return is_instance_valid(occupant)
|
||||
|
||||
func occupy(character: PilotBall):
|
||||
print("foo")
|
||||
if is_occupied(): return
|
||||
|
||||
occupant = character
|
||||
#occupant.process_mode = Node.PROCESS_MODE_DISABLED
|
||||
|
||||
# Position character at the station (no reparenting needed)
|
||||
occupant.global_position = global_position
|
||||
|
||||
# Launch the UIs from the installed databanks
|
||||
launch_interfaces()
|
||||
|
||||
occupancy_changed.emit(true)
|
||||
|
||||
func disengage():
|
||||
if not is_occupied(): return
|
||||
|
||||
# Close all open UIs
|
||||
close_interfaces()
|
||||
|
||||
#occupant.process_mode = Node.PROCESS_MODE_INHERIT
|
||||
occupant = null
|
||||
|
||||
occupancy_changed.emit(false)
|
||||
|
||||
func launch_interfaces():
|
||||
var root_module = get_root_module()
|
||||
if not is_instance_valid(root_module): return
|
||||
|
||||
# Find the main game UI to add these to.
|
||||
# This assumes you have a CanvasLayer with the name "MainGameUI" in your main scene.
|
||||
var main_ui = get_tree().get_first_node_in_group("main_ui_container")
|
||||
if not main_ui:
|
||||
push_error("No main UI container found for station interfaces!")
|
||||
return
|
||||
|
||||
for db in installed_databanks:
|
||||
if not db or not db.ui_scene: continue
|
||||
|
||||
var ui_instance = db.ui_scene.instantiate()
|
||||
active_ui_instances.append(ui_instance)
|
||||
main_ui.add_child(ui_instance)
|
||||
|
||||
# VERY IMPORTANT: Give the UI a reference to the ship it needs to control.
|
||||
if ui_instance.has_method("initialize"):
|
||||
ui_instance.initialize(root_module)
|
||||
|
||||
func close_interfaces():
|
||||
for ui in active_ui_instances:
|
||||
if is_instance_valid(ui):
|
||||
ui.queue_free()
|
||||
active_ui_instances.clear()
|
||||
# Helper to find the main ship/module this station belongs to
|
||||
func get_root_module() -> Module:
|
||||
var current_node = self
|
||||
while is_instance_valid(current_node):
|
||||
if current_node is Module and current_node.is_sim_root:
|
||||
return current_node
|
||||
current_node = current_node.get_parent()
|
||||
return null
|
||||
1
scenes/ship/components/station_component.gd.uid
Normal file
1
scenes/ship/components/station_component.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://2reyxkr78ra0
|
||||
14
scenes/ship/components/station_component.tscn
Normal file
14
scenes/ship/components/station_component.tscn
Normal file
@ -0,0 +1,14 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://2n42nstcj1n0"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://2reyxkr78ra0" path="res://scenes/ship/components/station_component.gd" id="1_8usqu"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_8usqu"]
|
||||
|
||||
[node name="Station" type="Node2D"]
|
||||
script = ExtResource("1_8usqu")
|
||||
|
||||
[node name="InteractionArea" type="Area2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="InteractionArea"]
|
||||
shape = SubResource("CircleShape2D_8usqu")
|
||||
debug_color = Color(0, 0.551549, 0.918484, 0.42)
|
||||
@ -69,7 +69,7 @@ func turn_off():
|
||||
is_firing = false
|
||||
|
||||
# --- Godot Physics Callback ---
|
||||
func _physics_process(delta: float):
|
||||
func _physics_process(_delta: float):
|
||||
if not enabled:
|
||||
is_firing = false
|
||||
|
||||
|
||||
@ -75,10 +75,11 @@ func destroy_ship():
|
||||
#update_total_mass()
|
||||
|
||||
func _on_hull_breach(breach_position: Vector2, force_vector: Vector2):
|
||||
pass
|
||||
# A hull breach applies a continuous force at a specific point
|
||||
# For simplicity, we can apply it as a central force and torque here
|
||||
var force = force_vector * 100 # Scale the force
|
||||
|
||||
# Calculate torque: Torque = r x F (cross product of position vector and force)
|
||||
var position_relative_to_center = breach_position - self.global_position
|
||||
var torque = position_relative_to_center.cross(force)
|
||||
#var force = force_vector * 100 # Scale the force
|
||||
#
|
||||
## Calculate torque: Torque = r x F (cross product of position vector and force)
|
||||
#var position_relative_to_center = breach_position - self.global_position
|
||||
#var torque = position_relative_to_center.cross(force)
|
||||
|
||||
@ -289,11 +289,7 @@ func apply_rotational_thrust(desired_torque: float):
|
||||
# ... (your existing calculation for produced_torque is correct)
|
||||
var thruster_local_pos = thruster.position
|
||||
var thruster_data: ThrusterData = thruster_data_map.get(thruster)
|
||||
thruster_data.measured_torque
|
||||
#var force_local_vec = thruster.thrust_direction * thruster.max_thrust
|
||||
#var produced_torque = thruster_local_pos.cross(force_local_vec)
|
||||
|
||||
# --- THE FIX ---
|
||||
# If this thruster can help, turn it on. Otherwise, explicitly turn it off.
|
||||
if sign(thruster_data.measured_torque) == sign(desired_torque) and desired_torque != 0:
|
||||
thruster.turn_on()
|
||||
|
||||
@ -69,7 +69,7 @@ func _update_mass_and_inertia():
|
||||
print("Node: %s, Mass: %f" % [self, mass])
|
||||
|
||||
func _physics_process(delta):
|
||||
if is_sim_root:
|
||||
if is_sim_root and not Engine.is_editor_hint():
|
||||
|
||||
# FIX 2: Safety Check for Division by Zero
|
||||
var sim_mass = mass
|
||||
|
||||
@ -51,11 +51,11 @@ var has_generated: bool = false
|
||||
# Constants for real-world physics calculations.
|
||||
#const G = 6.67430e-11 # Gravitational constant (N·m²/kg²)
|
||||
#const SUN_MASS = 1.989e30 # Mass of the sun (kg)
|
||||
const SUN_MASS = 10000000
|
||||
const PLANETARY_MASS = SUN_MASS / 300000
|
||||
const MOON_MASS = PLANETARY_MASS / 100
|
||||
const ASTEROID_MASS = MOON_MASS / 5
|
||||
const STATION_MASS = MOON_MASS / 1000
|
||||
const SUN_MASS: float = 10000000.0
|
||||
const PLANETARY_MASS: float = SUN_MASS / 300000.0
|
||||
const MOON_MASS: float = PLANETARY_MASS / 100.0
|
||||
const ASTEROID_MASS: float = MOON_MASS / 5.0
|
||||
const STATION_MASS: float = MOON_MASS / 1000.0
|
||||
|
||||
var system_data : SystemData
|
||||
|
||||
|
||||
Reference in New Issue
Block a user