feat: implement multiplayer network manager and player movement controller with base game entities and UI
This commit is contained in:
+28
-10
@@ -6,7 +6,7 @@ signal connection_failed
|
||||
signal connection_succeeded
|
||||
signal match_state_updated
|
||||
signal stats_updated
|
||||
signal killfeed_event(victim: String, killer: String, weapon: String)
|
||||
signal killfeed_event(victim: String, killer: String, weapon: String, v_color: String, k_color: String)
|
||||
|
||||
const DEFAULT_PORT = 31415
|
||||
|
||||
@@ -77,12 +77,16 @@ func start_singleplayer_match(gamemode: String = "Deathmatch") -> void:
|
||||
rpc("sync_match_state", match_active, match_time_remaining, current_gamemode)
|
||||
|
||||
func _init_player_stats(id: int, username: String) -> void:
|
||||
# Keep existing color if player re-joins, or generate new
|
||||
var p_color = Color(randf_range(0.2, 1.0), randf_range(0.2, 1.0), randf_range(0.2, 1.0)).to_html(false)
|
||||
|
||||
player_stats[id] = {
|
||||
"username": username,
|
||||
"kills": 0,
|
||||
"deaths": 0,
|
||||
"assists": 0,
|
||||
"ping": 0
|
||||
"ping": 0,
|
||||
"color": p_color
|
||||
}
|
||||
stats_updated.emit()
|
||||
|
||||
@@ -191,26 +195,40 @@ func receive_ping_response(server_time: int) -> void:
|
||||
|
||||
# --- GAMEPLAY EVENTS ---
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func register_kill(victim_id: int, killer_id: int, weapon_name: String, custom_victim_name: String = "") -> void:
|
||||
func register_kill(victim_id: int, killer_id: int, weapon_name: String, custom_victim_name: String = "", assist_ids: Array = []) -> void:
|
||||
if multiplayer.is_server():
|
||||
if player_stats.has(victim_id):
|
||||
player_stats[victim_id]["deaths"] += 1
|
||||
if player_stats.has(killer_id) and killer_id != victim_id:
|
||||
player_stats[killer_id]["kills"] += 1
|
||||
if killer_id != 0 and killer_id != victim_id:
|
||||
if player_stats.has(killer_id):
|
||||
player_stats[killer_id]["kills"] += 1
|
||||
|
||||
if victim_id != -1:
|
||||
if player_stats.has(victim_id):
|
||||
player_stats[victim_id]["deaths"] += 1
|
||||
|
||||
for aid in assist_ids:
|
||||
if player_stats.has(aid) and aid != killer_id and aid != victim_id:
|
||||
player_stats[aid]["assists"] += 1
|
||||
|
||||
var v_name = player_stats[victim_id]["username"] if player_stats.has(victim_id) else (custom_victim_name if custom_victim_name != "" else "Unknown")
|
||||
var k_name = player_stats[killer_id]["username"] if player_stats.has(killer_id) else "Unknown"
|
||||
|
||||
var v_color = player_stats[victim_id].get("color", "cccccc") if player_stats.has(victim_id) else "cccccc"
|
||||
var k_color = player_stats[killer_id].get("color", "cccccc") if player_stats.has(killer_id) else "cccccc"
|
||||
|
||||
# Auto-fallback for singleplayer testing where player_stats might not be initialized
|
||||
if not player_stats.has(killer_id) and killer_id == 1:
|
||||
k_name = SettingsManager.username
|
||||
k_color = "55aaff" # Default blueish for uninitialized local player
|
||||
|
||||
if victim_id == -1 and "Dummy" in custom_victim_name:
|
||||
v_color = "ff5555" # Red for dummies
|
||||
|
||||
if killer_id == 0 or killer_id == victim_id:
|
||||
k_name = "" # Suicide or world death
|
||||
|
||||
broadcast_killfeed.rpc(v_name, k_name, weapon_name)
|
||||
broadcast_killfeed.rpc(v_name, k_name, weapon_name, v_color, k_color)
|
||||
sync_player_stats.rpc(player_stats)
|
||||
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func broadcast_killfeed(victim: String, killer: String, weapon: String) -> void:
|
||||
killfeed_event.emit(victim, killer, weapon)
|
||||
func broadcast_killfeed(victim: String, killer: String, weapon: String, v_color: String = "cccccc", k_color: String = "cccccc") -> void:
|
||||
killfeed_event.emit(victim, killer, weapon, v_color, k_color)
|
||||
|
||||
Reference in New Issue
Block a user