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
+97
View File
@@ -0,0 +1,97 @@
extends BaseHitscanWeapon
class_name AWP
var default_fov: float = 75.0
var target_fov: float = 75.0
var ads_fov: float = 20.0 # Extremely high zoom
var is_ads: bool = false
func _init() -> void:
weapon_name = "AWP"
fire_rate = 1.5 # Slow
max_ammo = 3
reload_time = 3.0
base_damage = 150.0 # 1 hit kill
min_damage = 130.0 # Long falloff still kills
falloff_start = 100.0
max_range = 300.0
automatic = false
spread_angle = 0.0
penetration_count = 1
penetration_damage_penalty = 0.5
func _build_model() -> void:
position = Vector3(0.3, -0.3, -0.8)
var mat_green = StandardMaterial3D.new()
mat_green.albedo_color = Color(0.1, 0.4, 0.1)
var mat_black = StandardMaterial3D.new()
mat_black.albedo_color = Color(0.1, 0.1, 0.1)
# Body
var body = MeshInstance3D.new()
var b_mesh = BoxMesh.new()
b_mesh.size = Vector3(0.06, 0.12, 0.6)
b_mesh.material = mat_green
body.mesh = b_mesh
model_root.add_child(body)
# Scope
var scope = MeshInstance3D.new()
var s_mesh = CylinderMesh.new()
s_mesh.top_radius = 0.03
s_mesh.bottom_radius = 0.03
s_mesh.height = 0.25
s_mesh.material = mat_black
scope.mesh = s_mesh
scope.rotation.x = deg_to_rad(90)
scope.position = Vector3(0, 0.09, -0.1)
model_root.add_child(scope)
# Long Barrel
var barrel = MeshInstance3D.new()
var bar_mesh = CylinderMesh.new()
bar_mesh.top_radius = 0.015
bar_mesh.bottom_radius = 0.02
bar_mesh.height = 0.6
bar_mesh.material = mat_black
barrel.mesh = bar_mesh
barrel.rotation.x = deg_to_rad(90)
barrel.position = Vector3(0, 0.04, -0.6)
model_root.add_child(barrel)
# Audio
fire_sound = AudioStreamPlayer3D.new()
fire_sound.stream = load("res://assets/sounds/awp_fire.wav")
fire_sound.volume_db = 0.0
model_root.add_child(fire_sound)
reload_sound = AudioStreamPlayer3D.new()
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav") # Reusing for now
model_root.add_child(reload_sound)
func _process(delta: float) -> void:
super._process(delta)
if camera:
if Input.is_action_just_pressed("fire_alt"):
is_ads = not is_ads
target_fov = ads_fov if is_ads else default_fov
camera.fov = lerpf(camera.fov, target_fov, 15.0 * delta)
# Move model slightly based on ADS
var target_pos = Vector3(0.0, -0.15, -0.6) if is_ads else Vector3(0.3, -0.3, -0.8)
position = position.lerp(target_pos, 15.0 * delta)
func _start_reload() -> void:
super._start_reload()
is_ads = false # Drop out of ADS on reload
target_fov = default_fov
func unequip() -> void:
is_ads = false
if camera:
camera.fov = default_fov
target_fov = default_fov
position = Vector3(0.3, -0.3, -0.8)