diff --git a/characters/player/collision_shape.res b/characters/player/collision_shape.res index bb30465..fa2512c 100644 Binary files a/characters/player/collision_shape.res and b/characters/player/collision_shape.res differ diff --git a/characters/player/player.gd b/characters/player/player.gd index a82f088..9fdb39c 100644 --- a/characters/player/player.gd +++ b/characters/player/player.gd @@ -1,4 +1,5 @@ extends RigidBody3D +class_name Player # constants const max_energy : float = 100.0 @@ -28,7 +29,9 @@ var gravity : Vector3 = g * ProjectSettings.get_setting("physics/3d/default_gra @onready var shape_cast = $ShapeCast3D @onready var weapon = $SpringArm3D/Inventory/SpaceGun -# signals +@onready var spring_arm_height = $SpringArm3D.position.y + +signal died(player) signal energy_changed(energy) func _ready(): @@ -96,3 +99,17 @@ func _physics_process(delta): input.jumping = false +func die(): + $PlayerInput.disable() + var tween = create_tween() + tween.tween_property(input, "camera_rotation:y", -PI/2, 0.25) + tween.tween_property($SpringArm3D, "position:y", 0, 0.25) + tween.tween_interval(2) + tween.tween_callback(func(): died.emit(self)) + +func respawn(location): + $SpringArm3D.position.y = spring_arm_height + input.camera_rotation.y = 0 + linear_velocity = Vector3() + position = location + $PlayerInput.enable() diff --git a/characters/player/player.tscn b/characters/player/player.tscn index 02d4322..f01f6ec 100644 --- a/characters/player/player.tscn +++ b/characters/player/player.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=10 format=3 uid="uid://cbhx1xme0sb7k"] +[gd_scene load_steps=11 format=3 uid="uid://cbhx1xme0sb7k"] [ext_resource type="Script" path="res://characters/player/player.gd" id="1_ymjub"] [ext_resource type="PackedScene" uid="uid://bcv81ku26xo" path="res://interfaces/hud/hud.tscn" id="2_5qvi2"] [ext_resource type="PackedScene" uid="uid://c8co0qa2omjmh" path="res://weapons/space_gun/space_gun.tscn" id="2_ka38u"] [ext_resource type="Shape3D" uid="uid://dkwljsgaflf31" path="res://characters/player/collision_shape.res" id="2_y6kgj"] +[ext_resource type="PackedScene" uid="uid://bof3mg7wgxrmn" path="res://components/health_component.tscn" id="5_dlsxj"] [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_clur0"] resource_local_to_scene = true @@ -40,22 +41,20 @@ properties/3/replication_mode = 2 [sub_resource type="GDScript" id="GDScript_uy24w"] script/source = "extends MultiplayerSynchronizer +class_name PlayerInput @export var jumping = false @export var jetting = false @export var skiing = false @export var direction = Vector2.ZERO -@export var camera_rotation : Vector3 +@export var camera_rotation : Vector2 @export var MOUSE_SENSITIVITY : float = 0.5 var _mouse_position: Vector2 func _ready(): - var has_authority = get_multiplayer_authority() == multiplayer.get_unique_id() - set_process(has_authority) - set_process_unhandled_input(has_authority) - if has_authority: - Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + enable() + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED func _unhandled_input(event: InputEvent) -> void: var mouse_mode = Input.get_mouse_mode() @@ -93,6 +92,15 @@ func _update_camera(delta): camera_rotation.x = wrapf(camera_rotation.x, deg_to_rad(0.0),deg_to_rad(360.0)) # reset mouse motion until next input event _mouse_position = Vector2.ZERO + +func disable(): + set_process(false) + set_process_unhandled_input(false) + +func enable(): + var has_authority = get_multiplayer_authority() == multiplayer.get_unique_id() + set_process(has_authority) + set_process_unhandled_input(has_authority) " [node name="Player" type="RigidBody3D"] @@ -132,6 +140,8 @@ near = 0.1 [node name="SpaceGun" parent="SpringArm3D/Inventory" instance=ExtResource("2_ka38u")] transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 0.281712, -0.095, -0.353461) +[node name="HealthComponent" parent="." instance=ExtResource("5_dlsxj")] + [node name="ServerSynchronizer" type="MultiplayerSynchronizer" parent="."] replication_config = SubResource("SceneReplicationConfig_rqdp6") @@ -139,3 +149,5 @@ replication_config = SubResource("SceneReplicationConfig_rqdp6") root_path = NodePath(".") replication_config = SubResource("SceneReplicationConfig_5j4ew") script = SubResource("GDScript_uy24w") + +[connection signal="health_zeroed" from="HealthComponent" to="." method="die"] diff --git a/components/area_damage_component.gd b/components/area_damage_component.gd new file mode 100644 index 0000000..f54dd04 --- /dev/null +++ b/components/area_damage_component.gd @@ -0,0 +1,4 @@ +extends Area3D +class_name AreaDamageComponent + +@export var damage : int = 100 diff --git a/components/area_damage_component.tscn b/components/area_damage_component.tscn new file mode 100644 index 0000000..129ac1e --- /dev/null +++ b/components/area_damage_component.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=3 uid="uid://ds1hekx1dq1bg"] + +[ext_resource type="Script" path="res://components/area_damage_component.gd" id="1_hn2e3"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_080vi"] +radius = 5.0 + +[node name="AreaDamage" type="Area3D"] +collision_layer = 4 +script = ExtResource("1_hn2e3") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("SphereShape3D_080vi") diff --git a/components/health_component.gd b/components/health_component.gd new file mode 100644 index 0000000..f2e2a4b --- /dev/null +++ b/components/health_component.gd @@ -0,0 +1,20 @@ +extends Area3D +class_name HealthComponent + +@export var max_health : int = 100 +@export var health : int + +signal health_zeroed + +func _ready(): + health = max_health + area_entered.connect(_on_area_entered) + +func damage(amount : int): + health -= amount + if health <= 0: + health_zeroed.emit() + +func _on_area_entered(area): + if area is AreaDamageComponent: + damage(area.damage) diff --git a/components/health_component.tscn b/components/health_component.tscn new file mode 100644 index 0000000..2c8e486 --- /dev/null +++ b/components/health_component.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=3 format=3 uid="uid://bof3mg7wgxrmn"] + +[ext_resource type="Script" path="res://components/health_component.gd" id="1_00xis"] +[ext_resource type="Shape3D" uid="uid://dkwljsgaflf31" path="res://characters/player/collision_shape.res" id="2_sgbmt"] + +[node name="HealthComponent" type="Area3D"] +collision_layer = 0 +collision_mask = 4 +script = ExtResource("1_00xis") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = ExtResource("2_sgbmt") diff --git a/game_modes/demo.gd b/game_modes/demo.gd new file mode 100644 index 0000000..23041ae --- /dev/null +++ b/game_modes/demo.gd @@ -0,0 +1,11 @@ +extends Node + +@onready var player : Player = $Player + +@onready var respawn_location = player.position + +func _ready(): + player.died.connect(respawn_player) + +func respawn_player(player): + player.respawn(respawn_location) diff --git a/game_modes/demo.tscn b/game_modes/demo.tscn index 77a8cf8..22afcb9 100644 --- a/game_modes/demo.tscn +++ b/game_modes/demo.tscn @@ -1,11 +1,19 @@ -[gd_scene load_steps=3 format=3 uid="uid://boviiugcnfyrj"] +[gd_scene load_steps=5 format=3 uid="uid://boviiugcnfyrj"] +[ext_resource type="Script" path="res://game_modes/demo.gd" id="1_gytim"] [ext_resource type="PackedScene" uid="uid://chbno00ugl6te" path="res://maps/genesis/genesis.tscn" id="2_lsep7"] [ext_resource type="PackedScene" uid="uid://cbhx1xme0sb7k" path="res://characters/player/player.tscn" id="3_j1li7"] +[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_c5jqv"] +resource_local_to_scene = true +bounce = 1.0 +absorbent = true + [node name="Demo" type="Node"] +script = ExtResource("1_gytim") [node name="Map" parent="." instance=ExtResource("2_lsep7")] [node name="Player" parent="." instance=ExtResource("3_j1li7")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 92.7007, 0) +physics_material_override = SubResource("PhysicsMaterial_c5jqv") diff --git a/game_modes/multiplayer.tscn b/game_modes/multiplayer.tscn index 618c2b8..1888e68 100644 --- a/game_modes/multiplayer.tscn +++ b/game_modes/multiplayer.tscn @@ -29,13 +29,17 @@ func join_server(peer): func load_map(scene : PackedScene): map.add_child(scene.instantiate()) +func respawn_player(player): + player.respawn(Vector3(0.0, 150.0, 0.0)) + func add_player(peer_id : int): var node_name = str(peer_id) - var player_scene_instance = PLAYER.instantiate() + var player_scene_instance : Player = PLAYER.instantiate() player_scene_instance.name = node_name player_scene_instance.player_id = peer_id player_scene_instance.position = Vector3(0.0, 150.0, 0.0) players.add_child(player_scene_instance) + player_scene_instance.died.connect(respawn_player) print(\"Peer `%s` connected\" % node_name) func remove_player(peer_id : int): diff --git a/project.godot b/project.godot index ae92077..252ddcb 100644 --- a/project.godot +++ b/project.godot @@ -76,6 +76,10 @@ fire_primary={ ] } +[layer_names] + +3d_physics/layer_3="Damage" + [physics] 3d/physics_engine="JoltPhysics3D" diff --git a/weapons/space_gun/projectile_explosion.gd b/weapons/space_gun/projectile_explosion.gd index ec01e87..b7c4158 100644 --- a/weapons/space_gun/projectile_explosion.gd +++ b/weapons/space_gun/projectile_explosion.gd @@ -1,7 +1,7 @@ extends Node3D @onready var fire = $Fire -@onready var explosion_area = $Area3D +@onready var explosion_area : AreaDamageComponent = $AreaDamageComponent var explosion_effect_pending : bool = false const impulse_force = 1000; @@ -9,16 +9,16 @@ const impulse_force = 1000; func explode(): explosion_effect_pending = true fire.emitting = true - + func _physics_process(_delta): if explosion_effect_pending: var bodies = explosion_area.get_overlapping_bodies() - + for body in bodies: if body is RigidBody3D: var direction = (body.global_position - global_position).normalized() body.apply_central_impulse(direction * impulse_force) - + explosion_effect_pending = false await get_tree().create_timer(1.0).timeout queue_free() diff --git a/weapons/space_gun/projectile_explosion.tscn b/weapons/space_gun/projectile_explosion.tscn index 1d82735..a041461 100644 --- a/weapons/space_gun/projectile_explosion.tscn +++ b/weapons/space_gun/projectile_explosion.tscn @@ -1,6 +1,7 @@ [gd_scene load_steps=6 format=3 uid="uid://8atq41j7wd55"] [ext_resource type="Script" path="res://weapons/space_gun/projectile_explosion.gd" id="1_fp5td"] +[ext_resource type="PackedScene" uid="uid://ds1hekx1dq1bg" path="res://components/area_damage_component.tscn" id="2_reyvo"] [sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_3mf41"] spread = 180.0 @@ -16,9 +17,6 @@ emission_energy_multiplier = 4.0 [sub_resource type="SphereMesh" id="SphereMesh_k3pnh"] material = SubResource("StandardMaterial3D_wpu51") -[sub_resource type="SphereShape3D" id="SphereShape3D_ou8x6"] -radius = 5.0 - [node name="ProjectileExplosion" type="Node3D"] script = ExtResource("1_fp5td") @@ -32,8 +30,4 @@ fixed_fps = 60 process_material = SubResource("ParticleProcessMaterial_3mf41") draw_pass_1 = SubResource("SphereMesh_k3pnh") -[node name="Area3D" type="Area3D" parent="."] -input_ray_pickable = false - -[node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D"] -shape = SubResource("SphereShape3D_ou8x6") +[node name="AreaDamageComponent" parent="." instance=ExtResource("2_reyvo")]