Files
tekton/scripts/managers/goal_manager.gd
T

109 lines
3.1 KiB
GDScript

extends Node
# GoalManager - Manages goal generation, synchronization, and speed tracking
var preset_goals: Array = []
# Speed Tracking
var player_completion_times: Dictionary = {} # { player_id: [time_taken, time_taken, ...] }
var player_start_times: Dictionary = {} # { player_id: timestamp_msec }
func initialize_random_goals(size: int, min_value: int, max_value: int, null_count: float) -> Array:
var goals = []
var rng = RandomNumberGenerator.new()
rng.randomize()
var null_val = 0
var max_nulls = 3
const SPECIAL_VALUES = {1: 7, 2: 8, 3: 9, 4: 10}
for i in range(size):
if null_val < max_nulls and rng.randf() < null_count:
goals.append(-1)
null_val += 1
else:
var val = rng.randi_range(min_value, max_value)
goals.append(val if not val in SPECIAL_VALUES else SPECIAL_VALUES[val])
return goals
func generate_preset_goals(count: int) -> Array:
preset_goals.clear()
for i in range(count):
var goals = initialize_random_goals(9, 7, 10, 1.0)
var int_goals: Array[int] = []
for g in goals:
int_goals.append(g)
preset_goals.append(int_goals)
return preset_goals
func get_goals_for_player(player_index: int) -> Array:
if player_index >= 0 and player_index < preset_goals.size():
return preset_goals[player_index].duplicate()
return []
# =============================================================================
# Speed Tracking Logic
# =============================================================================
func mark_goal_start(player_id: int):
player_start_times[player_id] = Time.get_ticks_msec()
func mark_goal_complete(player_id: int):
if not player_start_times.has(player_id):
return
var duration_sec = (Time.get_ticks_msec() - player_start_times[player_id]) / 1000.0
if not player_completion_times.has(player_id):
player_completion_times[player_id] = []
player_completion_times[player_id].append(duration_sec)
# Reset start time for next goal
player_start_times[player_id] = Time.get_ticks_msec()
# print("Player %s completed goal in %.2fs" % [player_id, duration_sec])
func get_player_average_time(player_id: int) -> float:
if not player_completion_times.has(player_id) or player_completion_times[player_id].is_empty():
return 10.0 # Default baseline (10 seconds)
var total = 0.0
for t in player_completion_times[player_id]:
total += t
return total / player_completion_times[player_id].size()
func get_global_average_time() -> float:
var total_avg = 0.0
var count = 0
for pid in player_completion_times:
var p_avg = get_player_average_time(pid)
total_avg += p_avg
count += 1
if count == 0:
return 10.0
return total_avg / count
func get_boost_multiplier(player_id: int) -> float:
var p_avg = get_player_average_time(player_id)
var g_avg = get_global_average_time()
if p_avg > g_avg:
# Player is slower than average -> Boost fills faster
# Scale up to 1.5x based on how much slower (capped)
var ratio = p_avg / max(g_avg, 0.1)
return min(ratio, 1.5)
else:
# Player is faster than average -> Boost fills slower
# Scale down to 0.8x
return 0.8
func reset():
preset_goals.clear()
player_completion_times.clear()
player_start_times.clear()