t_p2_buy: add buy menu and economy system
Creates the full buy/economy subsystem for a tactical FPS: - EconomyManager (server/scripts/economy/economy_manager.gd): per-player money tracking with starting 00, kill/round/objective rewards, spending validation, escalating loss bonuses, and money_changed signal. - BuyMenuHandler (server/scripts/economy/buy_menu_handler.gd): server-side RPC validation of purchase requests — checks weapon validity, buy-zone membership (scans BuyZone nodes in scene tree), affordability, then deducts money and grants weapon via WeaponServer.give_weapon(). - BuyMenu (client/characters/weapon/buy_menu.gd): client-side Control UI with styled panel, money display, weapon grid (name/cost/stats), numeric key (1-4) and mouse-click purchase, server-driven affordability, and auto-close after purchase. - GameServer integration: creates EconomyManager + BuyMenuHandler in _ready(), registers players for economy on spawn, awards kill rewards via DamageProcessor.player_killed signal, and unregisters on despawn. Economy rules: win=+,250, loss=,900 (+00/streak, cap ,900), kill=+00, bomb_plant/defuse=+00. Weapon costs: pistol=00, smg=,200, rifle=,700, shotgun=,900.
This commit is contained in:
@@ -55,6 +55,12 @@ var team_manager: TeamManager = null
|
||||
## RoundManager — match lifecycle (warmup → prep → live → post).
|
||||
var round_manager: RoundManager = null
|
||||
|
||||
## EconomyManager — per-player money tracking and earnings.
|
||||
var economy_manager: EconomyManager = null
|
||||
|
||||
## BuyMenuHandler — server-side buy request validation and processing.
|
||||
var buy_menu_handler: BuyMenuHandler = null
|
||||
|
||||
## Current server tick counter, incremented each time tick() is called.
|
||||
var _current_tick: int = 0
|
||||
|
||||
@@ -122,6 +128,18 @@ func _ready() -> void:
|
||||
round_manager.team_manager = team_manager
|
||||
round_manager.damage_processor = damage_processor
|
||||
|
||||
# --- Economy system ---
|
||||
economy_manager = EconomyManager.new()
|
||||
add_child(economy_manager)
|
||||
|
||||
buy_menu_handler = BuyMenuHandler.new()
|
||||
add_child(buy_menu_handler)
|
||||
buy_menu_handler.initialise(economy_manager, weapon_server, team_manager)
|
||||
|
||||
# Wire kill rewards: when DamageProcessor detects a kill, award money to the shooter
|
||||
# Note: shooter_id is an entity_id; we map it to peer_id for economy lookup.
|
||||
damage_processor.player_killed.connect(_on_kill_for_economy)
|
||||
|
||||
# --- RCON command handling ---
|
||||
var rcon_handler = get_node_or_null("/root/RconServer/RconCommandHandler")
|
||||
if rcon_handler and rcon_handler.has_signal("rcon_command"):
|
||||
@@ -241,6 +259,11 @@ func register_player_node(entity_id: int, node: Node3D, max_health: float = 100.
|
||||
lag_compensation.register_player_node(entity_id, node)
|
||||
if damage_processor:
|
||||
damage_processor.register_player(entity_id, max_health)
|
||||
# Register peer ID for economy tracking
|
||||
var peer_id: int = entity_to_peer.get(entity_id, -1)
|
||||
if peer_id >= 0 and economy_manager:
|
||||
economy_manager.register_player(peer_id)
|
||||
print("[GameServer] Registered player peer=%d with economy manager" % peer_id)
|
||||
print("[GameServer] Registered player node entity=%d with lag compensation + damage processor" % entity_id)
|
||||
|
||||
## Unregister a player node from LagCompensation and DamageProcessor.
|
||||
@@ -249,6 +272,10 @@ func unregister_player_node(entity_id: int) -> void:
|
||||
lag_compensation.unregister_player_node(entity_id)
|
||||
if damage_processor:
|
||||
damage_processor.unregister_player(entity_id)
|
||||
# Unregister from economy tracking
|
||||
var peer_id: int = entity_to_peer.get(entity_id, -1)
|
||||
if peer_id >= 0 and economy_manager:
|
||||
economy_manager.unregister_player(peer_id)
|
||||
print("[GameServer] Unregistered player node entity=%d" % entity_id)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -260,6 +287,17 @@ func _on_player_killed(victim_id: int, shooter_id: int) -> void:
|
||||
player_damaged.emit(victim_id, shooter_id, 0.0, true)
|
||||
print("[GameServer] Kill: victim_entity=%d, shooter_entity=%d (peer=%d)" % [victim_id, shooter_id, shooter_peer])
|
||||
|
||||
## Economy kill reward — award money to the shooter when they get a kill.
|
||||
## Connected from DamageProcessor.player_killed in _ready().
|
||||
func _on_kill_for_economy(victim_id: int, shooter_id: int) -> void:
|
||||
if economy_manager == null:
|
||||
return
|
||||
# Map entity_id → peer_id for economy lookup
|
||||
var shooter_peer: int = entity_to_peer.get(shooter_id, -1)
|
||||
if shooter_peer < 0:
|
||||
return
|
||||
economy_manager.award_kill_reward(shooter_peer)
|
||||
|
||||
## Round-level kill handler — tracks kills for round stats and checks elimination.
|
||||
## Connected from DamageProcessor.player_killed.
|
||||
func _on_kill_for_round(victim_id: int, shooter_id: int) -> void:
|
||||
|
||||
Reference in New Issue
Block a user