Files
Papay-Shooter/weapons/dmr.gd
Nicholas ButzkeandClaude Fable 5 6c8b0ddd28 feat: cel-shaded look & feel overhaul — real audio, comic UI, themed VFX
Audio (all CC0 — Kenney packs + OpenGameArt, see assets/sounds/SOURCES.md):
- Replace every procedural synth WAV with forged sounds (ffmpeg pitch/layer
  mixes): distinct fire sounds per weapon with 2-3 variations, explosions,
  footsteps x5, land/jump/dash/vault, knife swing, hit/kill confirms,
  bullet impacts, reload, flight loops, UI hover/click/confirm/error,
  match jingles, menu music
- AudioManager.stream_for(): AudioStreamRandomizer per sound id — every
  weapon now gets variation + pitch randomization on each shot
- Explosions and bullet impacts play positional audio; landing has its own
  sound instead of a pitched footstep; ambient wind bed on every map

Visuals:
- ExplosionVFX: shared cel-shaded burst (white-hot stepped core, ink
  shockwave ring, star spikes, flat smoke puffs) replaces the orange
  sphere in both local and remote-replay paths
- Comic star muzzle flashes on all weapons; unified cel tracer bolts with
  ink outlines across hitscan/shotgun/remote paths
- Impact decals: hard-stepped ink-splat gradients instead of soft airbrush
- Toon shading on first-person view models + arms, third-person weapons,
  and the procedural humanoid fallback (no hull outlines on FBX weapons —
  their hard normals tear the inverted hull)
- Fix: giant soft "blob" highlight on floors — toon rim/specular disabled
  on level-geometry materials (pre-existing artifact since the cel commit)
- Fix: own third-person weapon rendered into the first-person camera
  (shadows-only now covers first_person_mode)

UI:
- UITheme: comic theme on the root window — Bangers display font (OFL),
  paper panels with thick ink borders + hard drop shadows, papaya accent,
  themed buttons/inputs/popups; hover/click sounds on all menu buttons
- Main menu: tilted comic wordmark, sunset toon diorama, looping menu music
- Match HUD: themed scoreboard/killfeed/kill counter

Viewports:
- 4x MSAA project-wide + viewmodel/diorama viewports (crisp ink lines)
- Viewmodel camera near plane 0.01; third-person camera FOV syncs settings
- debug/visual_capture.gd: dev tool to screenshot menu + level for review

Verified: 11/11 movement tests, spawn smoke test 0 failures, before/after
screenshot comparison of menu and level.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-17 18:15:42 -04:00

99 lines
2.7 KiB
GDScript

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.49)
var model_scene = load("res://assets/weapons/dmr/source/M14 .blend")
if model_scene:
var model = model_scene.instantiate()
model_root.add_child(model)
model.scale = Vector3(0.1875, 0.1875, 0.1875)
model.rotation_degrees.y = 90
for light in model.find_children("*", "Light3D", true, false):
light.queue_free()
# 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.bus = "SFX"
fire_sound.stream = AudioManager.stream_for("dmr_fire", "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.bus = "SFX"
reload_sound.stream = AudioManager.stream_for("shotgun_reload", "res://assets/sounds/shotgun_reload.wav")
model_root.add_child(reload_sound)
func _process(delta: float) -> void:
super._process(delta)
if not visible:
return
if camera:
var target_fov = ads_fov if is_ads else -1.0
var rig = camera.get_parent()
if rig and rig.has_method("set_weapon_fov"):
rig.set_weapon_fov(target_fov)
# 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
func unequip() -> void:
is_ads = false
if camera:
var rig = camera.get_parent()
if rig and rig.has_method("set_weapon_fov"):
rig.set_weapon_fov(-1.0)
position = Vector3(0.3, -0.3, -0.49)