mortar + mini gun cannot hit weak points

This commit is contained in:
Michael Campbell 2026-02-19 01:01:39 -05:00
parent f73f093ae2
commit 045faf2333
10 changed files with 77 additions and 1 deletions

View file

@ -8,6 +8,7 @@ func _ready() -> void:
func hit(projectile: PlayerProjectile, _damage: float) -> bool: func hit(projectile: PlayerProjectile, _damage: float) -> bool:
if projectile == null: return false if projectile == null: return false
if not projectile.can_hit_weak_points: return false
var angle := projectile.velocity.angle_to(-parent.velocity) var angle := projectile.velocity.angle_to(-parent.velocity)
var weak_point_hit := rad_to_deg(angle) < 25. var weak_point_hit := rad_to_deg(angle) < 25.

View file

@ -6,6 +6,7 @@ func fire(aim_angle: float) -> void:
var player_projectile: PlayerProjectile = preload("res://player/projectile/player_projectile.tscn").instantiate() var player_projectile: PlayerProjectile = preload("res://player/projectile/player_projectile.tscn").instantiate()
player_projectile.init(dir) player_projectile.init(dir)
player_projectile.damage = 5 player_projectile.damage = 5
player_projectile.can_hit_weak_points = false
player_projectile.global_position = global_position + Vector3.UP * 0.5 player_projectile.global_position = global_position + Vector3.UP * 0.5
get_tree().current_scene.add_child(player_projectile) get_tree().current_scene.add_child(player_projectile)
fire_clock = 60. / fire_rate fire_clock = 60. / fire_rate

37
player/guns/mortar.gd Normal file
View file

@ -0,0 +1,37 @@
class_name Mortar
extends Gun
func calculate_projectile_velocity(source: Vector3, target: Vector3, max_height: float) -> Vector3:
assert(is_equal_approx(source.y, target.y), "Source and target must be at the same height.")
assert(max_height > 0.0, "Max height must be positive.")
# Flatten to the horizontal plane and get range + direction
var horizontal_offset := Vector3(target.x - source.x, 0.0, target.z - source.z)
var R := horizontal_offset.length()
assert(R > 0.0, "Source and target must not be the same point.")
var direction := horizontal_offset / R
var g := MortarProjectile.GRAVITY
# Angle whose tangent is 4H/R — peaks exactly at max_height
var angle := atan(4.0 * max_height / R)
# Speed derived from v = sqrt(2gH + gR²/8H)
var speed := sqrt(2.0 * g * max_height + (g * R * R) / (8.0 * max_height))
var horizontal_speed := speed * cos(angle)
var vertical_speed := speed * sin(angle)
return direction * horizontal_speed + Vector3.UP * vertical_speed
func fire(_aim_angle: float) -> void:
var pos: Vector3 = Player.instance.get_node("%Reticle").global_position
pos.y = global_position.y
var vel := calculate_projectile_velocity(global_position, pos, 10.)
var proj := preload("res://player/projectile/mortar_projectile.tscn").instantiate()
proj.velocity = vel
proj.global_position = global_position
get_tree().current_scene.add_child(proj)
fire_clock = 60. / fire_rate

View file

@ -0,0 +1 @@
uid://ftrngxkkycl1

View file

@ -28,7 +28,7 @@ var state := State.NORMAL
var dash_direction: Vector2 var dash_direction: Vector2
var stamina := 1.0 var stamina := 1.0
@onready var gun: Gun = %MiniGun @onready var gun: Gun = %Mortar
func _init() -> void: func _init() -> void:
instance = self instance = self

View file

@ -4,6 +4,7 @@
[ext_resource type="Script" uid="uid://cjdxibg3pnans" path="res://player/score_label.gd" id="2_onrkg"] [ext_resource type="Script" uid="uid://cjdxibg3pnans" path="res://player/score_label.gd" id="2_onrkg"]
[ext_resource type="Script" uid="uid://fv1n5noqdfg2" path="res://player/guns/basic_gun.gd" id="3_g1dw6"] [ext_resource type="Script" uid="uid://fv1n5noqdfg2" path="res://player/guns/basic_gun.gd" id="3_g1dw6"]
[ext_resource type="Script" uid="uid://b87cyvu2m5b1k" path="res://player/guns/mini_gun.gd" id="4_yw30f"] [ext_resource type="Script" uid="uid://b87cyvu2m5b1k" path="res://player/guns/mini_gun.gd" id="4_yw30f"]
[ext_resource type="Script" uid="uid://ftrngxkkycl1" path="res://player/guns/mortar.gd" id="5_qjkh3"]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_onrkg"] [sub_resource type="FastNoiseLite" id="FastNoiseLite_onrkg"]
@ -99,3 +100,8 @@ script = ExtResource("3_g1dw6")
unique_name_in_owner = true unique_name_in_owner = true
script = ExtResource("4_yw30f") script = ExtResource("4_yw30f")
fire_rate = 800.0 fire_rate = 800.0
[node name="Mortar" type="Node3D" parent="Guns" unique_id=1321220525]
unique_name_in_owner = true
script = ExtResource("5_qjkh3")
fire_rate = 250.0

View file

@ -0,0 +1,17 @@
class_name MortarProjectile
extends Node3D
var velocity: Vector3
const GRAVITY := 40.
func _process(delta: float) -> void:
position += velocity * delta
velocity += GRAVITY * Vector3.DOWN * delta
if position.y <= 0.:
var explosion := preload("res://player/explosion/explosion.tscn").instantiate()
explosion.position = position
add_sibling(explosion)
queue_free()

View file

@ -0,0 +1 @@
uid://dgnyxjs1f61lc

View file

@ -0,0 +1,11 @@
[gd_scene format=3 uid="uid://i5lihai81ec1"]
[ext_resource type="Script" uid="uid://dgnyxjs1f61lc" path="res://player/projectile/mortar_projectile.gd" id="1_7aq8w"]
[sub_resource type="SphereMesh" id="SphereMesh_7aq8w"]
[node name="MortarProjectile" type="Node3D" unique_id=1380191443]
script = ExtResource("1_7aq8w")
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=380266621]
mesh = SubResource("SphereMesh_7aq8w")

View file

@ -10,6 +10,7 @@ var health: int = 1:
if v == 0: if v == 0:
queue_free() queue_free()
var damage := 10. var damage := 10.
var can_hit_weak_points := true
func _on_collision(node: Node3D): func _on_collision(node: Node3D):
if node.has_method("hit"): if node.has_method("hit"):