feat: add plasma gun weapon implementation and new pause menu system with loadout management
This commit is contained in:
+112
@@ -0,0 +1,112 @@
|
||||
extends BaseHitscanWeapon
|
||||
class_name DMR
|
||||
|
||||
var is_ads: bool = false
|
||||
var default_fov: float = 90.0
|
||||
var ads_fov: float = 40.0
|
||||
|
||||
func _init() -> void:
|
||||
weapon_name = "DMR"
|
||||
fire_rate = 0.3 # Cooldown to prevent autoclicker spam
|
||||
max_ammo = 15
|
||||
reload_time = 2.2
|
||||
base_damage = 75.0
|
||||
min_damage = 60.0
|
||||
falloff_start = 50.0
|
||||
max_range = 300.0
|
||||
automatic = false
|
||||
spread_angle = 0.002 # Extremely accurate
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
if camera:
|
||||
default_fov = camera.fov
|
||||
|
||||
func _build_model() -> void:
|
||||
position = Vector3(0.3, -0.3, -0.7)
|
||||
|
||||
var body_mat = StandardMaterial3D.new()
|
||||
body_mat.albedo_color = Color(0.15, 0.25, 0.15) # Olive drab
|
||||
var black_mat = StandardMaterial3D.new()
|
||||
black_mat.albedo_color = Color(0.05, 0.05, 0.05)
|
||||
|
||||
# Receiver
|
||||
var receiver = MeshInstance3D.new()
|
||||
var rec_mesh = BoxMesh.new()
|
||||
rec_mesh.size = Vector3(0.05, 0.12, 0.4)
|
||||
rec_mesh.material = body_mat
|
||||
receiver.mesh = rec_mesh
|
||||
receiver.position = Vector3(0, 0, 0.1)
|
||||
model_root.add_child(receiver)
|
||||
|
||||
# Barrel
|
||||
var barrel = MeshInstance3D.new()
|
||||
var b_mesh = CylinderMesh.new()
|
||||
b_mesh.top_radius = 0.01
|
||||
b_mesh.bottom_radius = 0.01
|
||||
b_mesh.height = 0.6
|
||||
b_mesh.material = black_mat
|
||||
barrel.mesh = b_mesh
|
||||
barrel.rotation.x = deg_to_rad(90)
|
||||
barrel.position = Vector3(0, 0.03, -0.3)
|
||||
model_root.add_child(barrel)
|
||||
|
||||
# Scope
|
||||
var scope = MeshInstance3D.new()
|
||||
var scope_mesh = CylinderMesh.new()
|
||||
scope_mesh.top_radius = 0.02
|
||||
scope_mesh.bottom_radius = 0.02
|
||||
scope_mesh.height = 0.2
|
||||
scope_mesh.material = black_mat
|
||||
scope.mesh = scope_mesh
|
||||
scope.rotation.x = deg_to_rad(90)
|
||||
scope.position = Vector3(0, 0.08, 0.05)
|
||||
model_root.add_child(scope)
|
||||
|
||||
# Muzzle Flash
|
||||
muzzle_flash = OmniLight3D.new()
|
||||
muzzle_flash.light_color = Color(1.0, 0.8, 0.4)
|
||||
muzzle_flash.light_energy = 0.0
|
||||
muzzle_flash.omni_range = 6.0
|
||||
muzzle_flash.position = Vector3(0, 0.03, -0.6)
|
||||
model_root.add_child(muzzle_flash)
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.stream = load("res://assets/sounds/dmr_fire.wav")
|
||||
fire_sound.position = muzzle_flash.position
|
||||
fire_sound.volume_db = -3.0
|
||||
model_root.add_child(fire_sound)
|
||||
|
||||
reload_sound = AudioStreamPlayer3D.new()
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav")
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
super._process(delta)
|
||||
|
||||
if camera:
|
||||
var target_fov = ads_fov if is_ads else default_fov
|
||||
camera.fov = lerpf(camera.fov, target_fov, 15.0 * delta)
|
||||
|
||||
# Move model to center when ADS
|
||||
var target_pos = Vector3(0.0, -0.2, -0.5) if is_ads else Vector3(0.3, -0.3, -0.7)
|
||||
position = position.lerp(target_pos, 15.0 * delta)
|
||||
|
||||
# Adjust sensitivity if player has a way to modify it (we can modify the camera rig later)
|
||||
# For now, FOV alone gives the zoom effect.
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
super._input(event)
|
||||
|
||||
if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
|
||||
return
|
||||
|
||||
if event.is_action_pressed("fire_alt"):
|
||||
is_ads = true
|
||||
elif event.is_action_released("fire_alt"):
|
||||
is_ads = false
|
||||
|
||||
func _start_reload() -> void:
|
||||
super._start_reload()
|
||||
is_ads = false # Drop out of ADS on reload
|
||||
Reference in New Issue
Block a user