feat: implement weapon system, loadout manager, and specialized projectile behaviors with associated assets

This commit is contained in:
DottsGit
2026-06-04 18:14:50 -04:00
parent c32f45a8aa
commit e6a2199777
36 changed files with 700 additions and 4 deletions
+103
View File
@@ -0,0 +1,103 @@
extends BaseProjectileWeapon
class_name RocketLauncher
func _init() -> void:
weapon_name = "Rocket Launcher"
fire_rate = 1.0 # Moderate, but you only have 1 in the chamber anyway
max_ammo = 1
reload_time = 2.5 # Extremely long reload time
base_damage = 120.0 # High damage
min_damage = 120.0
falloff_start = 0.0
max_range = 300.0
automatic = false
spread_angle = 0.0
projectile_speed = 35.0 # Moderate speed
projectile_gravity = 0.0 # Flies straight
func _build_model() -> void:
position = Vector3(0.4, -0.4, -0.6)
var mat_grey = StandardMaterial3D.new()
mat_grey.albedo_color = Color(0.3, 0.3, 0.3)
# Main Tube
var body = MeshInstance3D.new()
var b_mesh = CylinderMesh.new()
b_mesh.top_radius = 0.08
b_mesh.bottom_radius = 0.08
b_mesh.height = 0.8
b_mesh.material = mat_grey
body.mesh = b_mesh
body.rotation.x = deg_to_rad(90)
model_root.add_child(body)
# Back cone
var cone = MeshInstance3D.new()
var c_mesh = CylinderMesh.new()
c_mesh.top_radius = 0.08
c_mesh.bottom_radius = 0.04
c_mesh.height = 0.2
c_mesh.material = mat_grey
cone.mesh = c_mesh
cone.rotation.x = deg_to_rad(90)
cone.position = Vector3(0, 0, 0.5)
model_root.add_child(cone)
# Muzzle Flash
muzzle_flash = OmniLight3D.new()
muzzle_flash.light_color = Color(1.0, 0.6, 0.2)
muzzle_flash.light_energy = 0.0
muzzle_flash.omni_range = 5.0
muzzle_flash.position = Vector3(0, 0, -0.4)
model_root.add_child(muzzle_flash)
# Audio
fire_sound = AudioStreamPlayer3D.new()
fire_sound.stream = load("res://assets/sounds/rocket_fire.wav")
model_root.add_child(fire_sound)
reload_sound = AudioStreamPlayer3D.new()
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav") # Reusing
model_root.add_child(reload_sound)
func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
var proj = load("res://weapons/explosive_projectile.gd").new()
# Mesh
var mesh_instance = MeshInstance3D.new()
var p_mesh = CylinderMesh.new()
p_mesh.top_radius = 0.0
p_mesh.bottom_radius = 0.05
p_mesh.height = 0.2
var mat = StandardMaterial3D.new()
mat.albedo_color = Color(0.8, 0.2, 0.2) # Red rocket
p_mesh.material = mat
mesh_instance.mesh = p_mesh
mesh_instance.rotation.x = deg_to_rad(-90)
proj.add_child(mesh_instance)
# Rotation
var up_vec = Vector3.UP
if abs(fire_dir.dot(up_vec)) > 0.99:
up_vec = Vector3.RIGHT
proj.transform.basis = Basis.looking_at(fire_dir, up_vec)
# Logic
proj.position = muzzle_flash.global_position if muzzle_flash else origin
proj.logical_source = origin
proj.velocity = fire_dir * projectile_speed
proj.damage = base_damage
proj.min_damage = min_damage
proj.falloff_start = falloff_start
proj.max_range = max_range
proj.drop_gravity = projectile_gravity
proj.owner_player = player
# Explosive stats
proj.explosion_radius = 8.0 # Moderate AoE
proj.explosion_knockback = 45.0 # Strong knockback!
proj.can_self_damage = false # As requested
get_tree().current_scene.add_child(proj)