Compare commits
5
Commits
46cee744d1
...
27460be0ea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27460be0ea | ||
|
|
a47d01632d | ||
|
|
8118100a95 | ||
|
|
a6f5f24420 | ||
|
|
d784045214 |
@@ -28,7 +28,8 @@ func _ready() -> void:
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
||||
var sens = SettingsManager.mouse_sensitivity
|
||||
var is_ads = camera and camera.fov < params.base_fov - 5.0
|
||||
var sens = SettingsManager.ads_sensitivity if is_ads else SettingsManager.mouse_sensitivity
|
||||
# Yaw: rotate the player (parent)
|
||||
get_parent().rotate_y(-event.relative.x * sens)
|
||||
# Pitch: rotate this pivot
|
||||
|
||||
@@ -25,6 +25,7 @@ var default_bindings = {
|
||||
var current_bindings = {}
|
||||
var show_debug_ui: bool = false
|
||||
var mouse_sensitivity: float = 0.002
|
||||
var ads_sensitivity: float = 0.001
|
||||
|
||||
# Video Settings
|
||||
var display_mode: int = DisplayServer.WINDOW_MODE_WINDOWED
|
||||
@@ -32,6 +33,12 @@ var resolution_index: int = 2 # Default to 1920x1080
|
||||
var fps_cap: int = 0
|
||||
var show_fps: bool = false
|
||||
|
||||
# Audio Settings
|
||||
var vol_master: float = 100.0
|
||||
var vol_sfx: float = 100.0
|
||||
var vol_music: float = 100.0
|
||||
var vol_wind: float = 100.0
|
||||
|
||||
var resolutions = [
|
||||
Vector2i(640, 480), # 480p
|
||||
Vector2i(1280, 720), # 720p
|
||||
@@ -54,6 +61,31 @@ func _ready() -> void:
|
||||
|
||||
# Apply Video Settings
|
||||
apply_video_settings()
|
||||
|
||||
# Setup & Apply Audio Settings
|
||||
_setup_audio_buses()
|
||||
apply_audio_settings()
|
||||
|
||||
func _setup_audio_buses() -> void:
|
||||
if AudioServer.bus_count < 4:
|
||||
# Assuming bus 0 is Master
|
||||
if AudioServer.get_bus_name(0) != "Master":
|
||||
AudioServer.set_bus_name(0, "Master")
|
||||
|
||||
# SFX
|
||||
if AudioServer.bus_count <= 1:
|
||||
AudioServer.add_bus(1)
|
||||
AudioServer.set_bus_name(1, "SFX")
|
||||
|
||||
# Music
|
||||
if AudioServer.bus_count <= 2:
|
||||
AudioServer.add_bus(2)
|
||||
AudioServer.set_bus_name(2, "Music")
|
||||
|
||||
# Wind
|
||||
if AudioServer.bus_count <= 3:
|
||||
AudioServer.add_bus(3)
|
||||
AudioServer.set_bus_name(3, "Wind")
|
||||
|
||||
func _apply_all_bindings() -> void:
|
||||
for action in current_bindings:
|
||||
@@ -98,10 +130,15 @@ func _save_settings() -> void:
|
||||
"bindings": current_bindings,
|
||||
"show_debug_ui": show_debug_ui,
|
||||
"mouse_sensitivity": mouse_sensitivity,
|
||||
"ads_sensitivity": ads_sensitivity,
|
||||
"display_mode": display_mode,
|
||||
"resolution_index": resolution_index,
|
||||
"fps_cap": fps_cap,
|
||||
"show_fps": show_fps
|
||||
"show_fps": show_fps,
|
||||
"vol_master": vol_master,
|
||||
"vol_sfx": vol_sfx,
|
||||
"vol_music": vol_music,
|
||||
"vol_wind": vol_wind
|
||||
}
|
||||
var json_string = JSON.stringify(save_data)
|
||||
var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
|
||||
@@ -130,10 +167,32 @@ func _load_settings() -> void:
|
||||
show_debug_ui = data["show_debug_ui"]
|
||||
if data.has("mouse_sensitivity"):
|
||||
mouse_sensitivity = data["mouse_sensitivity"]
|
||||
if data.has("ads_sensitivity"):
|
||||
ads_sensitivity = data["ads_sensitivity"]
|
||||
if data.has("display_mode"): display_mode = data["display_mode"]
|
||||
if data.has("resolution_index"): resolution_index = data["resolution_index"]
|
||||
if data.has("fps_cap"): fps_cap = data["fps_cap"]
|
||||
if data.has("show_fps"): show_fps = data["show_fps"]
|
||||
if data.has("vol_master"): vol_master = data["vol_master"]
|
||||
if data.has("vol_sfx"): vol_sfx = data["vol_sfx"]
|
||||
if data.has("vol_music"): vol_music = data["vol_music"]
|
||||
if data.has("vol_wind"): vol_wind = data["vol_wind"]
|
||||
|
||||
func apply_audio_settings() -> void:
|
||||
_set_bus_volume("Master", vol_master)
|
||||
_set_bus_volume("SFX", vol_sfx)
|
||||
_set_bus_volume("Music", vol_music)
|
||||
_set_bus_volume("Wind", vol_wind)
|
||||
|
||||
func _set_bus_volume(bus_name: String, vol_100: float) -> void:
|
||||
var bus_idx = AudioServer.get_bus_index(bus_name)
|
||||
if bus_idx >= 0:
|
||||
var linear = clampf(vol_100 / 100.0, 0.0001, 1.0)
|
||||
if vol_100 <= 0.1:
|
||||
AudioServer.set_bus_mute(bus_idx, true)
|
||||
else:
|
||||
AudioServer.set_bus_mute(bus_idx, false)
|
||||
AudioServer.set_bus_volume_db(bus_idx, linear_to_db(linear))
|
||||
|
||||
func apply_video_settings() -> void:
|
||||
if display_mode == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN:
|
||||
|
||||
@@ -74,55 +74,67 @@ func _ready() -> void:
|
||||
|
||||
func _setup_audio() -> void:
|
||||
footstep_player = AudioStreamPlayer.new()
|
||||
footstep_player.bus = "SFX"
|
||||
footstep_player.stream = load("res://assets/sounds/footstep.wav")
|
||||
add_child(footstep_player)
|
||||
|
||||
jump_player = AudioStreamPlayer.new()
|
||||
jump_player.bus = "SFX"
|
||||
jump_player.stream = load("res://assets/sounds/jump.wav")
|
||||
add_child(jump_player)
|
||||
|
||||
double_jump_player = AudioStreamPlayer.new()
|
||||
double_jump_player.bus = "SFX"
|
||||
jump_player.bus = "SFX"
|
||||
double_jump_player.stream = load("res://assets/sounds/double_jump.wav")
|
||||
add_child(double_jump_player)
|
||||
|
||||
dash_player = AudioStreamPlayer.new()
|
||||
dash_player.bus = "SFX"
|
||||
dash_player.stream = load("res://assets/sounds/dash.wav")
|
||||
dash_player.volume_db = -5.0
|
||||
add_child(dash_player)
|
||||
|
||||
hit_player = AudioStreamPlayer.new()
|
||||
hit_player.bus = "SFX"
|
||||
hit_player.stream = load("res://assets/sounds/hit_confirm.wav")
|
||||
hit_player.max_polyphony = 8
|
||||
add_child(hit_player)
|
||||
|
||||
slide_player = AudioStreamPlayer.new()
|
||||
slide_player.bus = "SFX"
|
||||
slide_player.stream = load("res://assets/sounds/slide.wav")
|
||||
slide_player.volume_db = -10.0
|
||||
add_child(slide_player)
|
||||
|
||||
wallrun_player = AudioStreamPlayer.new()
|
||||
wallrun_player.bus = "SFX"
|
||||
wallrun_player.stream = load("res://assets/sounds/wallrun.wav")
|
||||
wallrun_player.volume_db = -10.0
|
||||
add_child(wallrun_player)
|
||||
|
||||
wind_player = AudioStreamPlayer.new()
|
||||
wind_player.bus = "Wind"
|
||||
wind_player.stream = load("res://assets/sounds/wind.wav")
|
||||
wind_player.volume_db = -80.0 # Start silent
|
||||
add_child(wind_player)
|
||||
wind_player.play()
|
||||
|
||||
grapple_shoot_player = AudioStreamPlayer.new()
|
||||
grapple_shoot_player.bus = "SFX"
|
||||
grapple_shoot_player.stream = load("res://assets/sounds/dash.wav")
|
||||
grapple_shoot_player.volume_db = -5.0
|
||||
grapple_shoot_player.pitch_scale = 1.5
|
||||
add_child(grapple_shoot_player)
|
||||
|
||||
grapple_latch_player = AudioStreamPlayer.new()
|
||||
grapple_latch_player.bus = "SFX"
|
||||
grapple_latch_player.stream = load("res://assets/sounds/hit_confirm.wav")
|
||||
grapple_latch_player.pitch_scale = 0.8
|
||||
add_child(grapple_latch_player)
|
||||
|
||||
grapple_swing_player = AudioStreamPlayer.new()
|
||||
grapple_swing_player.bus = "SFX"
|
||||
grapple_swing_player.stream = load("res://assets/sounds/wind.wav")
|
||||
grapple_swing_player.pitch_scale = 1.5
|
||||
grapple_swing_player.volume_db = -80.0
|
||||
@@ -173,10 +185,10 @@ func spawn_damage_number(amount: float, hit_pos: Vector3) -> void:
|
||||
|
||||
var label = load("res://ui/floating_damage_text.gd").new()
|
||||
label.text = str(round(amount))
|
||||
label.add_theme_font_size_override("font_size", 32)
|
||||
label.add_theme_font_size_override("font_size", 24)
|
||||
label.add_theme_color_override("font_color", Color(1.0, 0.6, 0.1))
|
||||
label.add_theme_color_override("font_outline_color", Color(0, 0, 0, 0.8))
|
||||
label.add_theme_constant_override("outline_size", 6)
|
||||
label.add_theme_constant_override("outline_size", 4)
|
||||
|
||||
# Small random offset in 3D space so multiple pellets don't perfectly overlap
|
||||
var offset = Vector3(randf_range(-0.4, 0.4), randf_range(-0.4, 0.4), randf_range(-0.4, 0.4))
|
||||
|
||||
+142
-4
@@ -26,11 +26,21 @@ var settings_back_btn: Button
|
||||
var _debug_ui_checkbox: CheckButton
|
||||
var _mouse_sens_slider: HSlider
|
||||
var _mouse_sens_input: LineEdit
|
||||
var _ads_sens_slider: HSlider
|
||||
var _ads_sens_input: LineEdit
|
||||
var _display_mode_opt: OptionButton
|
||||
var _resolution_opt: OptionButton
|
||||
var _fps_slider: HSlider
|
||||
var _fps_input: LineEdit
|
||||
var _show_fps_checkbox: CheckButton
|
||||
var _vol_master_slider: HSlider
|
||||
var _vol_master_input: LineEdit
|
||||
var _vol_sfx_slider: HSlider
|
||||
var _vol_sfx_input: LineEdit
|
||||
var _vol_music_slider: HSlider
|
||||
var _vol_music_input: LineEdit
|
||||
var _vol_wind_slider: HSlider
|
||||
var _vol_wind_input: LineEdit
|
||||
var keybind_vbox: VBoxContainer
|
||||
var rebind_overlay: ColorRect
|
||||
var rebind_label: Label
|
||||
@@ -325,16 +335,51 @@ func _build_ui() -> void:
|
||||
# Audio Tab
|
||||
var audio_tab = VBoxContainer.new()
|
||||
audio_tab.name = "Audio"
|
||||
audio_tab.add_theme_constant_override("separation", 10)
|
||||
tab_container.add_child(audio_tab)
|
||||
var aud_label = Label.new()
|
||||
aud_label.text = "Settings coming soon..."
|
||||
audio_tab.add_child(aud_label)
|
||||
|
||||
# Master
|
||||
var master_arr = _build_vol_control(audio_tab, "Master Volume")
|
||||
_vol_master_slider = master_arr[0]
|
||||
_vol_master_input = master_arr[1]
|
||||
_vol_master_slider.value_changed.connect(func(v): _on_vol_changed("vol_master", v, _vol_master_input))
|
||||
_vol_master_input.text_submitted.connect(func(t): _on_vol_text_changed("vol_master", t, _vol_master_slider, _vol_master_input))
|
||||
|
||||
# SFX
|
||||
var sfx_arr = _build_vol_control(audio_tab, "Sound Effects")
|
||||
_vol_sfx_slider = sfx_arr[0]
|
||||
_vol_sfx_input = sfx_arr[1]
|
||||
_vol_sfx_slider.value_changed.connect(func(v): _on_vol_changed("vol_sfx", v, _vol_sfx_input))
|
||||
_vol_sfx_input.text_submitted.connect(func(t): _on_vol_text_changed("vol_sfx", t, _vol_sfx_slider, _vol_sfx_input))
|
||||
|
||||
# Music
|
||||
var music_arr = _build_vol_control(audio_tab, "Music")
|
||||
_vol_music_slider = music_arr[0]
|
||||
_vol_music_input = music_arr[1]
|
||||
_vol_music_slider.value_changed.connect(func(v): _on_vol_changed("vol_music", v, _vol_music_input))
|
||||
_vol_music_input.text_submitted.connect(func(t): _on_vol_text_changed("vol_music", t, _vol_music_slider, _vol_music_input))
|
||||
|
||||
# Wind
|
||||
var wind_arr = _build_vol_control(audio_tab, "Wind")
|
||||
_vol_wind_slider = wind_arr[0]
|
||||
_vol_wind_input = wind_arr[1]
|
||||
_vol_wind_slider.value_changed.connect(func(v): _on_vol_changed("vol_wind", v, _vol_wind_input))
|
||||
_vol_wind_input.text_submitted.connect(func(t): _on_vol_text_changed("vol_wind", t, _vol_wind_slider, _vol_wind_input))
|
||||
|
||||
var spacer_aud = Control.new()
|
||||
spacer_aud.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
audio_tab.add_child(spacer_aud)
|
||||
var reset_aud_btn = Button.new()
|
||||
reset_aud_btn.text = "Reset to Defaults"
|
||||
reset_aud_btn.pressed.connect(func(): pass)
|
||||
reset_aud_btn.pressed.connect(func():
|
||||
SettingsManager.vol_master = 100.0
|
||||
SettingsManager.vol_sfx = 100.0
|
||||
SettingsManager.vol_music = 100.0
|
||||
SettingsManager.vol_wind = 100.0
|
||||
SettingsManager._save_settings()
|
||||
SettingsManager.apply_audio_settings()
|
||||
_populate_audio_ui()
|
||||
)
|
||||
audio_tab.add_child(reset_aud_btn)
|
||||
|
||||
# Mouse Tab
|
||||
@@ -380,6 +425,43 @@ func _build_ui() -> void:
|
||||
SettingsManager._save_settings()
|
||||
)
|
||||
|
||||
var ads_sens_hbox = HBoxContainer.new()
|
||||
mouse_tab.add_child(ads_sens_hbox)
|
||||
|
||||
var ads_sens_title = Label.new()
|
||||
ads_sens_title.text = "ADS Sensitivity"
|
||||
ads_sens_title.custom_minimum_size = Vector2(150, 0)
|
||||
ads_sens_hbox.add_child(ads_sens_title)
|
||||
|
||||
_ads_sens_slider = HSlider.new()
|
||||
_ads_sens_slider.min_value = 1.0
|
||||
_ads_sens_slider.max_value = 100.0
|
||||
_ads_sens_slider.step = 1.0
|
||||
_ads_sens_slider.value = SettingsManager.ads_sensitivity * 10000.0
|
||||
_ads_sens_slider.custom_minimum_size = Vector2(200, 0)
|
||||
_ads_sens_slider.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
ads_sens_hbox.add_child(_ads_sens_slider)
|
||||
|
||||
_ads_sens_input = LineEdit.new()
|
||||
_ads_sens_input.text = str(round(SettingsManager.ads_sensitivity * 10000.0))
|
||||
_ads_sens_input.custom_minimum_size = Vector2(60, 0)
|
||||
ads_sens_hbox.add_child(_ads_sens_input)
|
||||
|
||||
_ads_sens_slider.value_changed.connect(func(value: float):
|
||||
_ads_sens_input.text = str(round(value))
|
||||
SettingsManager.ads_sensitivity = value / 10000.0
|
||||
SettingsManager._save_settings()
|
||||
)
|
||||
|
||||
_ads_sens_input.text_submitted.connect(func(new_text: String):
|
||||
var val = new_text.to_float()
|
||||
val = clampf(val, 1.0, 100.0)
|
||||
_ads_sens_slider.value = val
|
||||
_ads_sens_input.text = str(round(val))
|
||||
SettingsManager.ads_sensitivity = val / 10000.0
|
||||
SettingsManager._save_settings()
|
||||
)
|
||||
|
||||
var spacer_mouse = Control.new()
|
||||
spacer_mouse.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
mouse_tab.add_child(spacer_mouse)
|
||||
@@ -388,7 +470,9 @@ func _build_ui() -> void:
|
||||
reset_mouse_btn.text = "Reset to Defaults"
|
||||
reset_mouse_btn.pressed.connect(func():
|
||||
_mouse_sens_slider.value = 20.0
|
||||
_ads_sens_slider.value = 10.0
|
||||
SettingsManager.mouse_sensitivity = 0.002
|
||||
SettingsManager.ads_sensitivity = 0.001
|
||||
SettingsManager._save_settings()
|
||||
)
|
||||
mouse_tab.add_child(reset_mouse_btn)
|
||||
@@ -481,6 +565,43 @@ func _build_ui() -> void:
|
||||
quit_dialog.dialog_text = "Are you sure you want to close the game?"
|
||||
add_child(quit_dialog)
|
||||
|
||||
func _build_vol_control(parent: Node, label_name: String) -> Array:
|
||||
var hbox = HBoxContainer.new()
|
||||
parent.add_child(hbox)
|
||||
|
||||
var lbl = Label.new()
|
||||
lbl.text = label_name
|
||||
lbl.custom_minimum_size = Vector2(150, 0)
|
||||
hbox.add_child(lbl)
|
||||
|
||||
var slider = HSlider.new()
|
||||
slider.min_value = 0.0
|
||||
slider.max_value = 100.0
|
||||
slider.step = 1.0
|
||||
slider.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
slider.custom_minimum_size = Vector2(150, 0)
|
||||
hbox.add_child(slider)
|
||||
|
||||
var input = LineEdit.new()
|
||||
input.custom_minimum_size = Vector2(60, 0)
|
||||
hbox.add_child(input)
|
||||
|
||||
return [slider, input]
|
||||
|
||||
func _on_vol_changed(setting_name: String, value: float, input_node: LineEdit) -> void:
|
||||
SettingsManager.set(setting_name, value)
|
||||
input_node.text = str(value)
|
||||
SettingsManager._save_settings()
|
||||
SettingsManager.apply_audio_settings()
|
||||
|
||||
func _on_vol_text_changed(setting_name: String, text: String, slider_node: HSlider, input_node: LineEdit) -> void:
|
||||
var val = clampf(text.to_float(), 0.0, 100.0)
|
||||
SettingsManager.set(setting_name, val)
|
||||
slider_node.value = val
|
||||
input_node.text = str(val)
|
||||
SettingsManager._save_settings()
|
||||
SettingsManager.apply_audio_settings()
|
||||
|
||||
func _create_label(text: String) -> Label:
|
||||
var l = Label.new()
|
||||
l.text = text
|
||||
@@ -525,12 +646,23 @@ func _populate_video_ui() -> void:
|
||||
_fps_slider.value = float(SettingsManager.fps_cap)
|
||||
_fps_input.text = str(SettingsManager.fps_cap)
|
||||
|
||||
func _populate_audio_ui() -> void:
|
||||
if _vol_master_slider: _vol_master_slider.value = SettingsManager.vol_master
|
||||
if _vol_master_input: _vol_master_input.text = str(SettingsManager.vol_master)
|
||||
if _vol_sfx_slider: _vol_sfx_slider.value = SettingsManager.vol_sfx
|
||||
if _vol_sfx_input: _vol_sfx_input.text = str(SettingsManager.vol_sfx)
|
||||
if _vol_music_slider: _vol_music_slider.value = SettingsManager.vol_music
|
||||
if _vol_music_input: _vol_music_input.text = str(SettingsManager.vol_music)
|
||||
if _vol_wind_slider: _vol_wind_slider.value = SettingsManager.vol_wind
|
||||
if _vol_wind_input: _vol_wind_input.text = str(SettingsManager.vol_wind)
|
||||
|
||||
func _show_settings() -> void:
|
||||
main_vbox.visible = false
|
||||
loadout_editor.visible = false
|
||||
settings_editor.visible = true
|
||||
_populate_keybindings()
|
||||
_populate_video_ui()
|
||||
_populate_audio_ui()
|
||||
if _debug_ui_checkbox:
|
||||
_debug_ui_checkbox.button_pressed = SettingsManager.show_debug_ui
|
||||
if _show_fps_checkbox:
|
||||
@@ -538,6 +670,12 @@ func _show_settings() -> void:
|
||||
if _mouse_sens_slider:
|
||||
var display_val = round(SettingsManager.mouse_sensitivity * 10000.0)
|
||||
_mouse_sens_slider.value = display_val
|
||||
_mouse_sens_input.text = str(display_val)
|
||||
|
||||
var ads_display_val = round(SettingsManager.ads_sensitivity * 10000.0)
|
||||
_ads_sens_slider.value = ads_display_val
|
||||
_ads_sens_input.text = str(ads_display_val)
|
||||
_mouse_sens_slider.value = display_val
|
||||
if _mouse_sens_input:
|
||||
_mouse_sens_input.text = str(display_val)
|
||||
|
||||
|
||||
@@ -70,11 +70,13 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
fire_sound.stream = load("res://assets/sounds/ak47_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.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav") # generic reload
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
+12
-4
@@ -62,11 +62,13 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
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.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav") # Reusing for now
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
@@ -74,16 +76,22 @@ 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 _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 = not is_ads
|
||||
target_fov = ads_fov if is_ads else default_fov
|
||||
|
||||
func _start_reload() -> void:
|
||||
super._start_reload()
|
||||
is_ads = false # Drop out of ADS on reload
|
||||
|
||||
@@ -73,12 +73,14 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
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.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav")
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
|
||||
@@ -66,12 +66,14 @@ func _build_model() -> void:
|
||||
|
||||
# Audio Players
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
fire_sound.stream = load("res://assets/sounds/shotgun_fire.wav")
|
||||
fire_sound.position = muzzle_flash.position
|
||||
fire_sound.volume_db = -20.0
|
||||
add_child(fire_sound)
|
||||
|
||||
reload_sound = AudioStreamPlayer3D.new()
|
||||
reload_sound.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav")
|
||||
add_child(reload_sound)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ var explosion_radius: float = 2.5
|
||||
var explosion_knockback: float = 20.0
|
||||
var can_self_damage: bool = false
|
||||
var falloff_curve: float = 1.0 # 1.0 is linear, 2.0 is quadratic (steep drop)
|
||||
var explosion_pitch: float = 1.0 # Audio pitch for explosion
|
||||
var flight_sound: AudioStreamPlayer3D
|
||||
var smoke_sys: GPUParticles3D
|
||||
var jet_sys: GPUParticles3D
|
||||
@@ -59,6 +60,7 @@ func destroy() -> void:
|
||||
func _setup_effects() -> void:
|
||||
# Audio
|
||||
flight_sound = AudioStreamPlayer3D.new()
|
||||
flight_sound.bus = "SFX"
|
||||
flight_sound.stream = load("res://assets/sounds/rocket_flight.wav")
|
||||
flight_sound.autoplay = true
|
||||
if flight_sound.stream is AudioStreamWAV:
|
||||
@@ -220,3 +222,14 @@ func _explode(pos: Vector3) -> void:
|
||||
tween.tween_property(mat, "albedo_color:a", 0.0, 0.3)
|
||||
tween.parallel().tween_property(visual, "scale", Vector3(1.1, 1.1, 1.1), 0.3)
|
||||
tween.tween_callback(visual.queue_free)
|
||||
|
||||
# Audio Effect
|
||||
var audio = AudioStreamPlayer3D.new()
|
||||
audio.stream = load("res://assets/sounds/shotgun_fire.wav") # using shotgun fire for a crash explosion
|
||||
audio.bus = "SFX"
|
||||
audio.pitch_scale = explosion_pitch
|
||||
audio.max_distance = 150.0
|
||||
get_tree().current_scene.add_child(audio)
|
||||
audio.global_position = pos
|
||||
audio.play()
|
||||
audio.finished.connect(audio.queue_free)
|
||||
|
||||
@@ -19,6 +19,7 @@ func _start_homing_effects() -> void:
|
||||
|
||||
# Audio
|
||||
flight_sound = AudioStreamPlayer3D.new()
|
||||
flight_sound.bus = "SFX"
|
||||
flight_sound.stream = load("res://assets/sounds/swarm_flight.wav")
|
||||
flight_sound.autoplay = true
|
||||
if flight_sound.stream is AudioStreamWAV:
|
||||
|
||||
@@ -61,11 +61,13 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
fire_sound.stream = load("res://assets/sounds/m4_fire.wav")
|
||||
fire_sound.position = muzzle_flash.position
|
||||
fire_sound.volume_db = -8.0
|
||||
model_root.add_child(fire_sound)
|
||||
|
||||
reload_sound = AudioStreamPlayer3D.new()
|
||||
reload_sound.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav")
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
+4
-1
@@ -35,10 +35,12 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
fire_sound.stream = load("res://assets/sounds/mortar_fire.wav")
|
||||
model_root.add_child(fire_sound)
|
||||
|
||||
reload_sound = AudioStreamPlayer3D.new()
|
||||
reload_sound.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav") # Reusing
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
@@ -61,7 +63,7 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
proj.logical_source = origin
|
||||
proj.velocity = fire_dir * projectile_speed
|
||||
if player:
|
||||
proj.velocity += fire_dir * player.velocity.dot(fire_dir)
|
||||
proj.velocity += fire_dir * max(0.0, player.velocity.dot(fire_dir))
|
||||
proj.damage = base_damage
|
||||
proj.min_damage = min_damage
|
||||
proj.falloff_start = falloff_start
|
||||
@@ -81,5 +83,6 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
proj.falloff_curve = 2.0 # Steep dropoff: "Should be an instant kill in closest 50%"
|
||||
# (0-50% = dist<6. 6/12 = 0.5. 1.0 - 0.5^2 = 0.75 multiplier. 200 * 0.75 = 150 damage -> 1 shot kill)
|
||||
proj.can_self_damage = true # Can self damage
|
||||
proj.explosion_pitch = 0.4 # Deepest explosion
|
||||
|
||||
get_tree().current_scene.add_child(proj)
|
||||
|
||||
@@ -70,11 +70,13 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
fire_sound.stream = load("res://assets/sounds/mp7_fire.wav")
|
||||
fire_sound.position = muzzle_flash.position
|
||||
fire_sound.volume_db = -10.0
|
||||
model_root.add_child(fire_sound)
|
||||
|
||||
reload_sound = AudioStreamPlayer3D.new()
|
||||
reload_sound.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav")
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
+3
-1
@@ -76,12 +76,14 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
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.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav")
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
@@ -115,7 +117,7 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
|
||||
proj.velocity = fire_dir * projectile_speed
|
||||
if player:
|
||||
proj.velocity += fire_dir * player.velocity.dot(fire_dir)
|
||||
proj.velocity += fire_dir * max(0.0, player.velocity.dot(fire_dir))
|
||||
proj.damage = base_damage
|
||||
proj.min_damage = min_damage
|
||||
proj.falloff_start = falloff_start
|
||||
|
||||
@@ -58,12 +58,14 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
fire_sound.stream = load("res://assets/sounds/plasma_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.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav")
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
@@ -86,8 +88,6 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
|
||||
var light = OmniLight3D.new()
|
||||
light.light_color = Color(0.2, 0.6, 1.0)
|
||||
light.light_energy = 2.0
|
||||
light.omni_range = 4.0
|
||||
proj.add_child(light)
|
||||
|
||||
proj.position = muzzle_flash.global_position if muzzle_flash else origin
|
||||
@@ -95,13 +95,15 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
|
||||
proj.velocity = fire_dir * projectile_speed
|
||||
if player:
|
||||
proj.velocity += fire_dir * player.velocity.dot(fire_dir)
|
||||
proj.velocity += fire_dir * max(0.0, player.velocity.dot(fire_dir))
|
||||
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
|
||||
light.light_energy = 2.0
|
||||
light.omni_range = 4.0
|
||||
proj.impact_type = "plasma"
|
||||
|
||||
# Spawn in the world
|
||||
|
||||
@@ -55,10 +55,12 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
fire_sound.stream = load("res://assets/sounds/rocket_fire.wav")
|
||||
model_root.add_child(fire_sound)
|
||||
|
||||
reload_sound = AudioStreamPlayer3D.new()
|
||||
reload_sound.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav") # Reusing
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
@@ -89,7 +91,7 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
proj.logical_source = origin
|
||||
proj.velocity = fire_dir * projectile_speed
|
||||
if player:
|
||||
proj.velocity += fire_dir * player.velocity.dot(fire_dir)
|
||||
proj.velocity += fire_dir * max(0.0, player.velocity.dot(fire_dir))
|
||||
proj.damage = base_damage
|
||||
proj.min_damage = min_damage
|
||||
proj.falloff_start = falloff_start
|
||||
@@ -101,5 +103,6 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
proj.explosion_radius = 4.0 # Moderate AoE
|
||||
proj.explosion_knockback = 45.0 # Strong knockback!
|
||||
proj.can_self_damage = false # As requested
|
||||
proj.explosion_pitch = 0.7 # Fairly deep
|
||||
|
||||
get_tree().current_scene.add_child(proj)
|
||||
|
||||
@@ -52,16 +52,21 @@ func _build_model() -> void:
|
||||
|
||||
# Audio
|
||||
fire_sound = AudioStreamPlayer3D.new()
|
||||
fire_sound.bus = "SFX"
|
||||
fire_sound.stream = load("res://assets/sounds/swarm_fire.wav")
|
||||
model_root.add_child(fire_sound)
|
||||
|
||||
reload_sound = AudioStreamPlayer3D.new()
|
||||
reload_sound.bus = "SFX"
|
||||
reload_sound.stream = load("res://assets/sounds/shotgun_reload.wav") # Reusing
|
||||
model_root.add_child(reload_sound)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
super._process(delta)
|
||||
|
||||
if not visible:
|
||||
return
|
||||
|
||||
if camera:
|
||||
is_targeting = Input.is_action_pressed("fire_alt")
|
||||
targeting_laser.visible = is_targeting
|
||||
@@ -163,14 +168,13 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
# Logic
|
||||
proj.weapon_source = self
|
||||
proj.turn_speed = 6.5 # Slower turn radius so they sweep nicely
|
||||
|
||||
proj.position = origin # Start at origin to spread outward around camera
|
||||
proj.logical_source = origin
|
||||
|
||||
# Initial pop-up speed
|
||||
proj.velocity = fire_dir * 5.0
|
||||
if player:
|
||||
proj.velocity += fire_dir * player.velocity.dot(fire_dir)
|
||||
proj.velocity += fire_dir * max(0.0, player.velocity.dot(fire_dir))
|
||||
|
||||
proj.initial_aim_dir = _current_aim_dir
|
||||
proj.cruise_speed = 65.0
|
||||
@@ -187,5 +191,6 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||
proj.explosion_radius = 1.5 # Tiny AoE effect
|
||||
proj.explosion_knockback = 5.0
|
||||
proj.can_self_damage = false
|
||||
proj.explosion_pitch = 1.2 # Less deep but still explosion
|
||||
|
||||
get_tree().current_scene.add_child(proj)
|
||||
|
||||
Reference in New Issue
Block a user