Add SFX
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://eus0u884fbx0"
|
||||||
|
path="res://.godot/imported/attack_mode.mp3-0b135ca9e2806fb808e84a27495143a5.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/attack_mode.mp3"
|
||||||
|
dest_files=["res://.godot/imported/attack_mode.mp3-0b135ca9e2806fb808e84a27495143a5.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://c6fpsw4tpjw1q"
|
||||||
|
path="res://.godot/imported/complete_mission.mp3-cb0f023b70f39023e3479885699ef187.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/complete_mission.mp3"
|
||||||
|
dest_files=["res://.godot/imported/complete_mission.mp3-cb0f023b70f39023e3479885699ef187.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://pygys4jw3su5"
|
||||||
|
path="res://.godot/imported/freeze.mp3-3b15793bd5b06d0cac66fb3ec33dc577.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/freeze.mp3"
|
||||||
|
dest_files=["res://.godot/imported/freeze.mp3-3b15793bd5b06d0cac66fb3ec33dc577.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://dneck8vnrnile"
|
||||||
|
path="res://.godot/imported/generate_tile.mp3-4ed133faf48f1eb79df726744beaa7cf.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/generate_tile.mp3"
|
||||||
|
dest_files=["res://.godot/imported/generate_tile.mp3-4ed133faf48f1eb79df726744beaa7cf.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://de43014odrwp3"
|
||||||
|
path="res://.godot/imported/ghost.mp3-bd8b4d0f9a077f1b19cffed2cae4c5ab.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/ghost.mp3"
|
||||||
|
dest_files=["res://.godot/imported/ghost.mp3-bd8b4d0f9a077f1b19cffed2cae4c5ab.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://nlec4kxa0p48"
|
||||||
|
path="res://.godot/imported/pick_up_power_tile.mp3-b6e12284e41b442fab8687001c2a15d1.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/pick_up_power_tile.mp3"
|
||||||
|
dest_files=["res://.godot/imported/pick_up_power_tile.mp3-b6e12284e41b442fab8687001c2a15d1.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://8ctpkvemgvmt"
|
||||||
|
path="res://.godot/imported/pick_up_tekton_roaming.mp3-fcbc7bdfbf724091b491495057817c9b.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/pick_up_tekton_roaming.mp3"
|
||||||
|
dest_files=["res://.godot/imported/pick_up_tekton_roaming.mp3-fcbc7bdfbf724091b491495057817c9b.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://cilkb27sd2431"
|
||||||
|
path="res://.godot/imported/speed.mp3-476d426c4b0e9131451d3b90adb24b49.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/speed.mp3"
|
||||||
|
dest_files=["res://.godot/imported/speed.mp3-476d426c4b0e9131451d3b90adb24b49.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://cpgg54uaogaaq"
|
||||||
|
path="res://.godot/imported/tile_scatter.mp3-73bb39bcbdf43b4782c4b8f6a040f991.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/tile_scatter.mp3"
|
||||||
|
dest_files=["res://.godot/imported/tile_scatter.mp3-73bb39bcbdf43b4782c4b8f6a040f991.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://wf533jrlmq74"
|
||||||
|
path="res://.godot/imported/wall.mp3-bb14cf5f4b11510e8b6a52b9795ed55d.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sfx/wall.mp3"
|
||||||
|
dest_files=["res://.godot/imported/wall.mp3-bb14cf5f4b11510e8b6a52b9795ed55d.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[gd_resource type="AudioBusLayout" format=3 uid="uid://c6xk1v1m4o5r4"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
bus/1/name = &"Music"
|
||||||
|
bus/1/solo = false
|
||||||
|
bus/1/mute = false
|
||||||
|
bus/1/bypass_fx = false
|
||||||
|
bus/1/volume_db = 0.0
|
||||||
|
bus/1/send = &"Master"
|
||||||
|
bus/2/name = &"SFX"
|
||||||
|
bus/2/solo = false
|
||||||
|
bus/2/mute = false
|
||||||
|
bus/2/bypass_fx = false
|
||||||
|
bus/2/volume_db = 0.0
|
||||||
|
bus/2/send = &"Master"
|
||||||
@@ -12,6 +12,10 @@ config_version=5
|
|||||||
|
|
||||||
compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
||||||
|
|
||||||
|
[audio]
|
||||||
|
|
||||||
|
buses/default_bus_layout="res://default_bus_layout.tres"
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="tekton-local"
|
config/name="tekton-local"
|
||||||
@@ -33,6 +37,7 @@ PlayerManager="*res://scripts/managers/player_manager.gd"
|
|||||||
GoalsCycleManager="*res://scripts/managers/goals_cycle_manager.gd"
|
GoalsCycleManager="*res://scripts/managers/goals_cycle_manager.gd"
|
||||||
Satori="*uid://b8vev00s34b7"
|
Satori="*uid://b8vev00s34b7"
|
||||||
SettingsManager="*uid://c1ouaaqnn0lrc"
|
SettingsManager="*uid://c1ouaaqnn0lrc"
|
||||||
|
SfxManager="*res://scripts/managers/sfx_manager.gd"
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
|
|||||||
+12
-2
@@ -238,19 +238,29 @@ func _on_server_option_selected(index: int) -> void:
|
|||||||
if server_ip_input: server_ip_input.visible = false
|
if server_ip_input: server_ip_input.visible = false
|
||||||
NakamaManager.set_server("localhost")
|
NakamaManager.set_server("localhost")
|
||||||
LobbyManager.is_lan_mode = false
|
LobbyManager.is_lan_mode = false
|
||||||
|
connection_status.text = "Mode: Local Testing (Nakama)"
|
||||||
elif index == 1:
|
elif index == 1:
|
||||||
# Nakama Remote
|
# Nakama Remote
|
||||||
if server_ip_input: server_ip_input.visible = true
|
if server_ip_input:
|
||||||
|
server_ip_input.visible = true
|
||||||
|
server_ip_input.placeholder_text = "IP (100.x) or Tailscale Funnel URL..."
|
||||||
if server_ip_input: NakamaManager.set_server(server_ip_input.text)
|
if server_ip_input: NakamaManager.set_server(server_ip_input.text)
|
||||||
LobbyManager.is_lan_mode = false
|
LobbyManager.is_lan_mode = false
|
||||||
|
connection_status.text = "Mode: Online (Nakama Remote)"
|
||||||
else:
|
else:
|
||||||
# LAN Direct
|
# LAN Direct
|
||||||
if server_ip_input: server_ip_input.visible = false
|
if server_ip_input: server_ip_input.visible = false
|
||||||
LobbyManager.is_lan_mode = true
|
LobbyManager.is_lan_mode = true
|
||||||
|
connection_status.text = "Mode: LAN Direct (No Server)"
|
||||||
|
|
||||||
func _on_server_ip_submitted(new_text: String) -> void:
|
func _on_server_ip_submitted(new_text: String) -> void:
|
||||||
if server_option and server_option.selected == 1:
|
if server_option and server_option.selected == 1:
|
||||||
NakamaManager.set_server(new_text.strip_edges())
|
var host = new_text.strip_edges()
|
||||||
|
NakamaManager.set_server(host)
|
||||||
|
if host.ends_with(".ts.net"):
|
||||||
|
connection_status.text = "Using Tailscale Funnel: " + host
|
||||||
|
else:
|
||||||
|
connection_status.text = "Server IP updated: " + host
|
||||||
|
|
||||||
func _setup_game_modes() -> void:
|
func _setup_game_modes() -> void:
|
||||||
if not game_mode_option: return
|
if not game_mode_option: return
|
||||||
|
|||||||
@@ -2099,6 +2099,7 @@ func sync_grab_tekton(tekton_path: NodePath):
|
|||||||
if is_attack_mode:
|
if is_attack_mode:
|
||||||
is_attack_mode = false
|
is_attack_mode = false
|
||||||
|
|
||||||
|
SfxManager.play("pick_up_tekton_roaming")
|
||||||
print("[Player %s] Grabbed Tekton %s" % [name, tekton.name])
|
print("[Player %s] Grabbed Tekton %s" % [name, tekton.name])
|
||||||
|
|
||||||
func throw_tekton():
|
func throw_tekton():
|
||||||
@@ -2333,6 +2334,7 @@ func sync_knock_tekton(tekton_path: NodePath):
|
|||||||
# Intensity 2.0 for knock (drops 200% tiles) + Shrink/Recover
|
# Intensity 2.0 for knock (drops 200% tiles) + Shrink/Recover
|
||||||
# Use on_thrown_landing to trigger shrink animation and floor freeze
|
# Use on_thrown_landing to trigger shrink animation and floor freeze
|
||||||
tekton.on_thrown_landing(self , 2.0)
|
tekton.on_thrown_landing(self , 2.0)
|
||||||
|
SfxManager.play("attack_mode")
|
||||||
print("[Player %s] Knocked Tekton %s" % [name, tekton.name])
|
print("[Player %s] Knocked Tekton %s" % [name, tekton.name])
|
||||||
|
|
||||||
# Visual feedback (Juice)
|
# Visual feedback (Juice)
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ func on_goal_completed(player: Node, time_remaining: float):
|
|||||||
# Randomize 9 tiles around player
|
# Randomize 9 tiles around player
|
||||||
_randomize_tiles_around_player(player)
|
_randomize_tiles_around_player(player)
|
||||||
|
|
||||||
|
SfxManager.rpc("play_rpc", "complete_mission")
|
||||||
print("[GoalsCycle] Player %d completed goal! +%d points (base: %d, time bonus: %d)" % [peer_id, score_earned, BASE_SCORE, time_bonus])
|
print("[GoalsCycle] Player %d completed goal! +%d points (base: %d, time bonus: %d)" % [peer_id, score_earned, BASE_SCORE, time_bonus])
|
||||||
|
|
||||||
@rpc("authority", "call_local", "reliable")
|
@rpc("authority", "call_local", "reliable")
|
||||||
|
|||||||
@@ -211,8 +211,10 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
|
|||||||
# Visual Feedback: Attack Bump
|
# Visual Feedback: Attack Bump
|
||||||
if _can_rpc():
|
if _can_rpc():
|
||||||
player.rpc("sync_bump", target_pos, false) # Attack bump
|
player.rpc("sync_bump", target_pos, false) # Attack bump
|
||||||
|
SfxManager.rpc("play_rpc", "attack_mode")
|
||||||
elif player.has_method("sync_bump"):
|
elif player.has_method("sync_bump"):
|
||||||
player.sync_bump(target_pos, false)
|
player.sync_bump(target_pos, false)
|
||||||
|
SfxManager.play("attack_mode")
|
||||||
|
|
||||||
# 1. 3-Floor Knockback towards Starting Line (X=0)
|
# 1. 3-Floor Knockback towards Starting Line (X=0)
|
||||||
var push_direction = Vector2i(-1, 0) # Backwards
|
var push_direction = Vector2i(-1, 0) # Backwards
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ func grab_item(grid_position: Vector2i) -> bool:
|
|||||||
if special_tiles_manager:
|
if special_tiles_manager:
|
||||||
special_tiles_manager.add_powerup_from_item(item)
|
special_tiles_manager.add_powerup_from_item(item)
|
||||||
|
|
||||||
|
SfxManager.play("pick_up_power_tile")
|
||||||
# Animation for powerup?
|
# Animation for powerup?
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
# SFXManager - Global singleton for playing sound effects
|
||||||
|
# Autoloaded as "SfxManager"
|
||||||
|
|
||||||
|
var sounds: Dictionary = {}
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
_load_sounds()
|
||||||
|
|
||||||
|
func _load_sounds():
|
||||||
|
var sfx_path = "res://assets/sfx/"
|
||||||
|
var dir = DirAccess.open(sfx_path)
|
||||||
|
if dir:
|
||||||
|
dir.list_dir_begin()
|
||||||
|
var file_name = dir.get_next()
|
||||||
|
while file_name != "":
|
||||||
|
if not dir.current_is_dir() and (file_name.ends_with(".mp3") or file_name.ends_with(".wav") or file_name.ends_with(".ogg")):
|
||||||
|
var base_name = file_name.get_basename()
|
||||||
|
sounds[base_name] = load(sfx_path + file_name)
|
||||||
|
# print("[SfxManager] Loaded: ", base_name)
|
||||||
|
file_name = dir.get_next()
|
||||||
|
dir.list_dir_end()
|
||||||
|
else:
|
||||||
|
push_error("[SfxManager] Could not open sfx directory: " + sfx_path)
|
||||||
|
|
||||||
|
func play(sound_name: String, pitch_range: float = 0.0):
|
||||||
|
if not sounds.has(sound_name):
|
||||||
|
# push_warning("[SfxManager] Sound not found: " + sound_name)
|
||||||
|
return
|
||||||
|
|
||||||
|
var player = AudioStreamPlayer.new()
|
||||||
|
add_child(player)
|
||||||
|
player.stream = sounds[sound_name]
|
||||||
|
player.bus = "SFX"
|
||||||
|
|
||||||
|
if pitch_range > 0:
|
||||||
|
player.pitch_scale = 1.0 + randf_range(-pitch_range, pitch_range)
|
||||||
|
|
||||||
|
player.play()
|
||||||
|
player.finished.connect(player.queue_free)
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local", "unreliable")
|
||||||
|
func play_rpc(sound_name: String, pitch_range: float = 0.0):
|
||||||
|
play(sound_name, pitch_range)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dqq36uawrnpwd
|
||||||
@@ -262,6 +262,7 @@ func _execute_faster_speed():
|
|||||||
if player.movement_manager:
|
if player.movement_manager:
|
||||||
player.movement_manager.set_speed_multiplier(1.5) # 50% faster
|
player.movement_manager.set_speed_multiplier(1.5) # 50% faster
|
||||||
active_buffs[SpecialEffect.FASTER_SPEED] = FASTER_DURATION
|
active_buffs[SpecialEffect.FASTER_SPEED] = FASTER_DURATION
|
||||||
|
SfxManager.rpc("play_rpc", "speed")
|
||||||
NotificationManager.send_message(player, "Speed Boost! (5s)", NotificationManager.MessageType.POWERUP)
|
NotificationManager.send_message(player, "Speed Boost! (5s)", NotificationManager.MessageType.POWERUP)
|
||||||
|
|
||||||
func _execute_area_freeze(target_pos: Vector2i = Vector2i.ZERO):
|
func _execute_area_freeze(target_pos: Vector2i = Vector2i.ZERO):
|
||||||
@@ -317,6 +318,8 @@ func _execute_area_freeze(target_pos: Vector2i = Vector2i.ZERO):
|
|||||||
NotificationManager.send_message(p, "Caught in Freeze Zone!", NotificationManager.MessageType.WARNING)
|
NotificationManager.send_message(p, "Caught in Freeze Zone!", NotificationManager.MessageType.WARNING)
|
||||||
if p != player: # Don't score for freezing self (unless desired?) - Assuming enemies
|
if p != player: # Don't score for freezing self (unless desired?) - Assuming enemies
|
||||||
hit_count += 1
|
hit_count += 1
|
||||||
|
|
||||||
|
SfxManager.rpc("play_rpc", "freeze")
|
||||||
|
|
||||||
if hit_count > 0 and player.is_multiplayer_authority():
|
if hit_count > 0 and player.is_multiplayer_authority():
|
||||||
var is_sng = LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO)
|
var is_sng = LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO)
|
||||||
@@ -418,6 +421,7 @@ func _execute_block_floor(target_pos: Vector2i = Vector2i.ZERO):
|
|||||||
main.rpc("sync_grid_items_batch", batch_data)
|
main.rpc("sync_grid_items_batch", batch_data)
|
||||||
|
|
||||||
# Notify
|
# Notify
|
||||||
|
SfxManager.rpc("play_rpc", "wall")
|
||||||
NotificationManager.send_message(player, "Defensive Wall Deployed!", NotificationManager.MessageType.POWERUP)
|
NotificationManager.send_message(player, "Defensive Wall Deployed!", NotificationManager.MessageType.POWERUP)
|
||||||
|
|
||||||
func _execute_invisible_mode(target: Node3D):
|
func _execute_invisible_mode(target: Node3D):
|
||||||
@@ -428,6 +432,7 @@ func _execute_invisible_mode(target: Node3D):
|
|||||||
if target.has_method("sync_modulate"):
|
if target.has_method("sync_modulate"):
|
||||||
target.rpc("sync_modulate", Color(1.0, 1.0, 1.0, 0.4)) # 40% Opacity
|
target.rpc("sync_modulate", Color(1.0, 1.0, 1.0, 0.4)) # 40% Opacity
|
||||||
|
|
||||||
|
SfxManager.rpc("play_rpc", "ghost")
|
||||||
NotificationManager.send_message(target, "Invisible Mode!", NotificationManager.MessageType.POWERUP)
|
NotificationManager.send_message(target, "Invisible Mode!", NotificationManager.MessageType.POWERUP)
|
||||||
|
|
||||||
|
|
||||||
@@ -438,6 +443,7 @@ func _execute_invisible_mode(target: Node3D):
|
|||||||
func spawn_powerups_around(center: Vector2i, force_powerups: bool = true, only_common: bool = false, full_density: bool = false):
|
func spawn_powerups_around(center: Vector2i, force_powerups: bool = true, only_common: bool = false, full_density: bool = false):
|
||||||
# "spawn / replace your nearby tiles into power up ( special tiles )"
|
# "spawn / replace your nearby tiles into power up ( special tiles )"
|
||||||
# New PowerUp Tiles are 11, 12, 13, 14
|
# New PowerUp Tiles are 11, 12, 13, 14
|
||||||
|
SfxManager.rpc("play_rpc", "generate_tile")
|
||||||
var radius = 2
|
var radius = 2
|
||||||
for x in range(-radius, radius + 1):
|
for x in range(-radius, radius + 1):
|
||||||
for y in range(-radius, radius + 1):
|
for y in range(-radius, radius + 1):
|
||||||
|
|||||||
@@ -586,6 +586,7 @@ func _scatter_player_tiles(player_node: Node):
|
|||||||
main.rpc("sync_playerboard", peer_id, playerboard)
|
main.rpc("sync_playerboard", peer_id, playerboard)
|
||||||
|
|
||||||
# Notify the player
|
# Notify the player
|
||||||
|
SfxManager.rpc("play_rpc", "tile_scatter")
|
||||||
NotificationManager.send_message(player_node, "Not in Safe Zone! Tiles scattered!", NotificationManager.MessageType.WARNING)
|
NotificationManager.send_message(player_node, "Not in Safe Zone! Tiles scattered!", NotificationManager.MessageType.WARNING)
|
||||||
|
|
||||||
# Screen shake
|
# Screen shake
|
||||||
|
|||||||
+39
-20
@@ -32,29 +32,48 @@ func _init_client():
|
|||||||
client = Nakama.create_client(nakama_server_key, nakama_host, nakama_port, nakama_scheme)
|
client = Nakama.create_client(nakama_server_key, nakama_host, nakama_port, nakama_scheme)
|
||||||
|
|
||||||
func set_server(host: String, port: int = 7350):
|
func set_server(host: String, port: int = 7350):
|
||||||
nakama_host = host
|
# Clean up the host string
|
||||||
|
var clean_host = host.strip_edges()
|
||||||
|
|
||||||
# Auto-detect secure tunnels (Tailscale, ngrok, playit, cloudflare)
|
# Extract protocol if present (override everything else)
|
||||||
if host.ends_with(".ts.net") or host.ends_with(".gg") or host.begins_with("https://"):
|
var forced_scheme = ""
|
||||||
if host.begins_with("https://"):
|
if clean_host.begins_with("https://"):
|
||||||
nakama_host = host.replace("https://", "")
|
forced_scheme = "https"
|
||||||
if host.begins_with("http://"):
|
clean_host = clean_host.replace("https://", "")
|
||||||
nakama_host = host.replace("http://", "")
|
elif clean_host.begins_with("http://"):
|
||||||
if nakama_host.ends_with("/"):
|
forced_scheme = "http"
|
||||||
nakama_host = nakama_host.substr(0, nakama_host.length() - 1)
|
clean_host = clean_host.replace("http://", "")
|
||||||
|
|
||||||
nakama_port = 443
|
# Handle trailing slashes
|
||||||
|
if clean_host.ends_with("/"):
|
||||||
|
clean_host = clean_host.substr(0, clean_host.length() - 1)
|
||||||
|
|
||||||
|
# Extract port if explicitly provided in host string (e.g. host:port)
|
||||||
|
var explicit_port = -1
|
||||||
|
if ":" in clean_host:
|
||||||
|
var parts = clean_host.split(":")
|
||||||
|
clean_host = parts[0]
|
||||||
|
explicit_port = parts[1].to_int()
|
||||||
|
|
||||||
|
# DETECT SETTINGS
|
||||||
|
nakama_host = clean_host
|
||||||
|
|
||||||
|
if forced_scheme != "":
|
||||||
|
nakama_scheme = forced_scheme
|
||||||
|
nakama_port = explicit_port if explicit_port != -1 else (443 if forced_scheme == "https" else port)
|
||||||
|
elif clean_host.ends_with(".ts.net") and explicit_port == -1:
|
||||||
|
# Tailscale Funnel Case (No port provided, .ts.net domain)
|
||||||
nakama_scheme = "https"
|
nakama_scheme = "https"
|
||||||
else:
|
nakama_port = 443
|
||||||
# Extract port if they typed something like 192.168.1.1:7350
|
elif clean_host.begins_with("100."):
|
||||||
if ":" in host and not host.begins_with("http"):
|
# Standard Tailscale IP Case
|
||||||
var parts = host.split(":")
|
|
||||||
nakama_host = parts[0]
|
|
||||||
nakama_port = parts[1].to_int()
|
|
||||||
else:
|
|
||||||
nakama_port = port
|
|
||||||
nakama_scheme = "http"
|
nakama_scheme = "http"
|
||||||
|
nakama_port = explicit_port if explicit_port != -1 else port
|
||||||
|
else:
|
||||||
|
# Generic Case (e.g. localhost, public IP)
|
||||||
|
nakama_scheme = "http"
|
||||||
|
nakama_port = explicit_port if explicit_port != -1 else port
|
||||||
|
|
||||||
_init_client()
|
_init_client()
|
||||||
print("[NakamaManager] Server updated to: ", nakama_scheme, "://", nakama_host, ":", nakama_port)
|
print("[NakamaManager] Server updated to: ", nakama_scheme, "://", nakama_host, ":", nakama_port)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user