feat: add plasma gun weapon implementation and new pause menu system with loadout management
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
extends BaseProjectileWeapon
|
||||
class_name NailGun
|
||||
|
||||
func _init() -> void:
|
||||
weapon_name = "Nail Gun"
|
||||
fire_rate = 0.06 # Very fast (1000 RPM)
|
||||
max_ammo = 60
|
||||
reload_time = 2.0
|
||||
base_damage = 18.0
|
||||
min_damage = 10.0
|
||||
falloff_start = 20.0
|
||||
max_range = 100.0
|
||||
automatic = true
|
||||
spread_angle = 0.02
|
||||
|
||||
projectile_speed = 60.0 # Fast but requires lead
|
||||
projectile_gravity = 5.0 # Slight drop
|
||||
|
||||
func _build_model() -> void:
|
||||
position = Vector3(0.3, -0.3, -0.6)
|
||||
|
||||
var yellow_mat = StandardMaterial3D.new()
|
||||
yellow_mat.albedo_color = Color(0.8, 0.7, 0.1) # Construction yellow
|
||||
var dark_mat = StandardMaterial3D.new()
|
||||
dark_mat.albedo_color = Color(0.2, 0.2, 0.2)
|
||||
|
||||
# Body
|
||||
var body = MeshInstance3D.new()
|
||||
var b_mesh = BoxMesh.new()
|
||||
b_mesh.size = Vector3(0.06, 0.16, 0.25)
|
||||
b_mesh.material = yellow_mat
|
||||
body.mesh = b_mesh
|
||||
body.position = Vector3(0, 0.02, 0)
|
||||
model_root.add_child(body)
|
||||
|
||||
# Handle
|
||||
var handle = MeshInstance3D.new()
|
||||
var h_mesh = BoxMesh.new()
|
||||
h_mesh.size = Vector3(0.04, 0.1, 0.04)
|
||||
h_mesh.material = dark_mat
|
||||
handle.mesh = h_mesh
|
||||
handle.position = Vector3(0, -0.1, 0.05)
|
||||
model_root.add_child(handle)
|
||||
|
||||
# Mag (Nail Drum)
|
||||
var drum = MeshInstance3D.new()
|
||||
var d_mesh = CylinderMesh.new()
|
||||
d_mesh.top_radius = 0.05
|
||||
d_mesh.bottom_radius = 0.05
|
||||
d_mesh.height = 0.1
|
||||
d_mesh.material = dark_mat
|
||||
drum.mesh = d_mesh
|
||||
drum.rotation.z = deg_to_rad(90)
|
||||
drum.position = Vector3(0, -0.06, -0.05)
|
||||
model_root.add_child(drum)
|
||||
|
||||
# Barrel
|
||||
var barrel = MeshInstance3D.new()
|
||||
var bar_mesh = CylinderMesh.new()
|
||||
bar_mesh.top_radius = 0.01
|
||||
bar_mesh.bottom_radius = 0.01
|
||||
bar_mesh.height = 0.15
|
||||
bar_mesh.material = dark_mat
|
||||
barrel.mesh = bar_mesh
|
||||
barrel.rotation.x = deg_to_rad(90)
|
||||
barrel.position = Vector3(0, 0.05, -0.2)
|
||||
model_root.add_child(barrel)
|
||||
|
||||
# Muzzle Flash (Sparks)
|
||||
muzzle_flash = OmniLight3D.new()
|
||||
muzzle_flash.light_color = Color(1.0, 0.9, 0.6)
|
||||
muzzle_flash.light_energy = 0.0
|
||||
muzzle_flash.omni_range = 3.0
|
||||
muzzle_flash.position = Vector3(0, 0.05, -0.3)
|
||||
model_root.add_child(muzzle_flash)
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.stream = load("res://assets/sounds/nailgun_fire.wav")
|
||||
fire_sound.position = muzzle_flash.position
|
||||
fire_sound.volume_db = -5.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 _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
var proj = load("res://weapons/projectile.gd").new()
|
||||
|
||||
# Give it a nail/spike mesh
|
||||
var mesh_instance = MeshInstance3D.new()
|
||||
var p_mesh = CylinderMesh.new()
|
||||
p_mesh.top_radius = 0.0
|
||||
p_mesh.bottom_radius = 0.01
|
||||
p_mesh.height = 0.1
|
||||
var mat = StandardMaterial3D.new()
|
||||
mat.albedo_color = Color(0.7, 0.7, 0.7) # Shiny metal
|
||||
mat.metallic = 1.0
|
||||
mat.roughness = 0.3
|
||||
p_mesh.material = mat
|
||||
mesh_instance.mesh = p_mesh
|
||||
# Rotate it so it points forward
|
||||
mesh_instance.rotation.x = deg_to_rad(-90)
|
||||
proj.add_child(mesh_instance)
|
||||
|
||||
# Projectile rotation so it faces velocity
|
||||
# (Basis looking towards fire_dir)
|
||||
var up = Vector3.UP
|
||||
if abs(fire_dir.dot(up)) > 0.99:
|
||||
up = Vector3.RIGHT
|
||||
proj.transform.basis = Basis.looking_at(fire_dir, up)
|
||||
|
||||
proj.global_position = muzzle_flash.global_position if muzzle_flash else 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
|
||||
|
||||
# Spawn in the world
|
||||
get_tree().current_scene.add_child(proj)
|
||||
Reference in New Issue
Block a user