diff --git a/game/project.godot b/game/project.godot index a3fc8f9..1de6628 100644 --- a/game/project.godot +++ b/game/project.godot @@ -105,6 +105,11 @@ player_light={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"location":0,"echo":false,"script":null) ] } +player_fireball={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":66,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} player_phone={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194306,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) diff --git a/game/scenes/Characters/location_player.gd b/game/scenes/Characters/location_player.gd index 36ad8df..9948e22 100644 --- a/game/scenes/Characters/location_player.gd +++ b/game/scenes/Characters/location_player.gd @@ -14,6 +14,8 @@ const MAX_NUMBER_OF_JUMPS := 2 const MIN_FOV := 10.0 const MAX_FOV := 179.0 const ZOOM_FACTOR := 1.1 # Zoom out when >1, in when < 1 +const FIREBALL_SPAWN_FORWARD_OFFSET := 1.5 +const FIREBALL_SPAWN_UP_OFFSET := 1.2 var mouse_sensitivity := 0.005 var rotation_x := 0.0 var rotation_y := 0.0 @@ -45,6 +47,7 @@ var _jump_triggered := false @export var anim_sprint_speed_threshold := 10.0 var jump_sound = preload("res://assets/audio/jump.ogg") +var fireball_scene = preload("res://scenes/Projectiles/fireball.tscn") var audio_player = AudioStreamPlayer.new() @export var camera_path: NodePath @@ -175,6 +178,10 @@ func _input(event): elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN: zoom_camera(ZOOM_FACTOR) + if event.is_action_pressed("player_fireball"): + shoot_fireball() + return + if event.is_action_pressed("player_light"): _flashlight.visible = !_flashlight.visible @@ -184,6 +191,13 @@ func zoom_camera(factor): var new_fov = cam.fov * factor cam.fov = clamp(new_fov, MIN_FOV, MAX_FOV) +func shoot_fireball() -> void: + var direction := get_look_direction() + var origin := get_look_origin() + direction * FIREBALL_SPAWN_FORWARD_OFFSET + var fireball := fireball_scene.instantiate() + get_tree().current_scene.add_child(fireball) + fireball.launch(origin, direction) + func _update_animation(on_floor: bool, velocity: Vector3) -> void: if _anim_player == null: return @@ -247,3 +261,17 @@ func exit_vehicle(exit_point: Node3D, vehicle_camera: Camera3D) -> void: if cam: cam.current = true vehicle_exited.emit(null) + + +func is_in_vehicle() -> bool: + return _in_vehicle + + +func get_look_origin() -> Vector3: + return global_position + Vector3.UP * FIREBALL_SPAWN_UP_OFFSET + + +func get_look_direction() -> Vector3: + if cam: + return (-cam.global_transform.basis.z).normalized() + return (-global_basis.z).normalized() diff --git a/game/scenes/Projectiles/fireball.gd b/game/scenes/Projectiles/fireball.gd new file mode 100644 index 0000000..2b5c47f --- /dev/null +++ b/game/scenes/Projectiles/fireball.gd @@ -0,0 +1,41 @@ +extends Area3D + +@export var initial_speed := 24.0 +@export var minimum_speed := 4.0 +@export var deceleration := 9.0 +@export var lifetime := 3.0 + +var _direction := Vector3.FORWARD +var _speed := initial_speed +var _age := 0.0 + + +func launch(origin: Vector3, direction: Vector3) -> void: + global_position = origin + if direction.length() > 0.0001: + _direction = direction.normalized() + look_at(global_position + _direction, Vector3.UP) + _speed = initial_speed + + +func _ready() -> void: + body_entered.connect(_on_body_entered) + area_entered.connect(_on_area_entered) + + +func _physics_process(delta: float) -> void: + _age += delta + if _age >= lifetime: + queue_free() + return + + global_position += _direction * _speed * delta + _speed = move_toward(_speed, minimum_speed, deceleration * delta) + + +func _on_body_entered(_body: Node3D) -> void: + queue_free() + + +func _on_area_entered(_area: Area3D) -> void: + queue_free() diff --git a/game/scenes/Projectiles/fireball.gd.uid b/game/scenes/Projectiles/fireball.gd.uid new file mode 100644 index 0000000..dfebd69 --- /dev/null +++ b/game/scenes/Projectiles/fireball.gd.uid @@ -0,0 +1 @@ +uid://bm0h12cdnatgh diff --git a/game/scenes/Projectiles/fireball.tscn b/game/scenes/Projectiles/fireball.tscn new file mode 100644 index 0000000..d40b5a0 --- /dev/null +++ b/game/scenes/Projectiles/fireball.tscn @@ -0,0 +1,89 @@ +[gd_scene format=3 uid="uid://cnqyidky3strc"] + +[ext_resource type="Script" uid="uid://bm0h12cdnatgh" path="res://scenes/Projectiles/fireball.gd" id="1_fireball_script"] +[ext_resource type="Texture2D" uid="uid://b2dmnrm3ubjon" path="res://assets/textures/stolenFire.png" id="2_fire_texture"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_fireball"] +radius = 0.35 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fireball"] +transparency = 1 +cull_mode = 2 +albedo_color = Color(1, 0.48, 0.12, 1) +albedo_texture = ExtResource("2_fire_texture") +emission_enabled = true +emission = Color(1, 0.32, 0.08, 1) +emission_energy_multiplier = 3.0 +billboard_mode = 1 + +[sub_resource type="SphereMesh" id="SphereMesh_fireball"] +material = SubResource("StandardMaterial3D_fireball") +radius = 0.35 +height = 0.7 +radial_segments = 32 +rings = 16 + +[sub_resource type="Curve" id="Curve_fireball_alpha"] +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.2, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_fireball_alpha"] +curve = SubResource("Curve_fireball_alpha") + +[sub_resource type="Gradient" id="Gradient_mhwgj"] +offsets = PackedFloat32Array(0, 0.45, 0.78, 1) +colors = PackedColorArray(1, 0.95, 0.55, 1, 1, 0.29, 0.05, 1, 0.42, 0.42, 0.42, 0.75, 0.16, 0.16, 0.16, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_fireball"] +gradient = SubResource("Gradient_mhwgj") + +[sub_resource type="Curve" id="Curve_fireball_scale"] +_data = [Vector2(0, 0.35), 0.0, 0.0, 0, 0, Vector2(0.35, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.15), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_fireball_scale"] +curve = SubResource("Curve_fireball_scale") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_fireball"] +emission_shape = 1 +emission_sphere_radius = 0.25 +angle_min = -180.0 +angle_max = 180.0 +direction = Vector3(0, 0, 1) +spread = 180.0 +initial_velocity_min = 0.3 +initial_velocity_max = 1.8 +gravity = Vector3(0, 1.5, 0) +scale_min = 0.35 +scale_max = 0.9 +scale_curve = SubResource("CurveTexture_fireball_scale") +color = Color(1, 0.47, 0.12, 1) +color_ramp = SubResource("GradientTexture1D_fireball") +alpha_curve = SubResource("CurveTexture_fireball_alpha") + +[sub_resource type="QuadMesh" id="QuadMesh_fireball_particle"] +material = SubResource("StandardMaterial3D_fireball") +size = Vector2(0.75, 0.75) + +[node name="Fireball" type="Area3D" unique_id=1503468252] +collision_layer = 8 +collision_mask = 7 +monitorable = false +script = ExtResource("1_fireball_script") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1304632772] +shape = SubResource("SphereShape3D_fireball") + +[node name="Core" type="MeshInstance3D" parent="." unique_id=1406426055] +mesh = SubResource("SphereMesh_fireball") + +[node name="Glow" type="OmniLight3D" parent="." unique_id=844333466] +light_color = Color(1, 0.42, 0.12, 1) +light_energy = 2.5 + +[node name="Trail" type="GPUParticles3D" parent="." unique_id=890543085] +amount = 36 +lifetime = 0.45 +preprocess = 0.2 +process_material = SubResource("ParticleProcessMaterial_fireball") +draw_pass_1 = SubResource("QuadMesh_fireball_particle") diff --git a/game/scenes/player.gd b/game/scenes/player.gd index beac417..99923a4 100644 --- a/game/scenes/player.gd +++ b/game/scenes/player.gd @@ -14,6 +14,8 @@ const MAX_NUMBER_OF_JUMPS := 2 const MIN_FOV := 10.0 const MAX_FOV := 179.0 const ZOOM_FACTOR := 1.1 # Zoom out when >1, in when < 1 +const FIREBALL_SPAWN_FORWARD_OFFSET := 1.5 +const FIREBALL_SPAWN_UP_OFFSET := 1.2 var mouse_sensitivity := 0.005 var rotation_x := 0.0 var rotation_y := 0.0 @@ -45,6 +47,7 @@ var _jump_triggered := false @export var anim_sprint_speed_threshold := 10.0 var jump_sound = preload("res://assets/audio/jump.ogg") +var fireball_scene = preload("res://scenes/Projectiles/fireball.tscn") var audio_player = AudioStreamPlayer.new() @export var camera_path: NodePath @@ -183,6 +186,10 @@ func _input(event): elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN: zoom_camera(ZOOM_FACTOR) # Zoom out + if event.is_action_pressed("player_fireball"): + shoot_fireball() + return + if event.is_action_pressed("player_light"): _flashlight.visible = !_flashlight.visible @@ -192,6 +199,13 @@ func zoom_camera(factor): var new_fov = cam.fov * factor cam.fov = clamp(new_fov, MIN_FOV, MAX_FOV) +func shoot_fireball() -> void: + var direction := get_look_direction() + var origin := get_look_origin() + direction * FIREBALL_SPAWN_FORWARD_OFFSET + var fireball := fireball_scene.instantiate() + get_tree().current_scene.add_child(fireball) + fireball.launch(origin, direction) + func _update_animation(on_floor: bool, velocity: Vector3) -> void: if _anim_player == null: return @@ -266,4 +280,6 @@ func get_look_origin() -> Vector3: func get_look_direction() -> Vector3: + if cam: + return (-cam.global_transform.basis.z).normalized() return (-global_basis.z).normalized()