diff --git a/core/biome_generator/rails.gd b/core/biome_generator/rails.gd index 9e63577..b6ee959 100644 --- a/core/biome_generator/rails.gd +++ b/core/biome_generator/rails.gd @@ -1,6 +1,5 @@ extends Path3D -const STEAM_DISTANCE_STAT: String = "stat_distance_km" const DISTANCE_KM_PER_UNIT: float = 0.01 const STATION_STOP_GROUP: StringName = &"railway_station" const TRACK_ZERO_SPACING_FIX_DISTANCE: float = 45.0 @@ -102,7 +101,6 @@ var is_restarting: bool = false var tween_restart: Tween var wagon_instances: Array[Node3D] = [] var wagon_progress_offsets: Array[float] = [] -var _pending_steam_distance_km: float = 0.0 var _initial_is_inmotion: bool = true var _is_photo_mode_active: bool = false @@ -493,28 +491,7 @@ func _track_steam_distance(distance_units: float) -> void: # Always track the global distance in our save file (for UI and persistency) GameState.save_data.total_distance_km += distance_units * DISTANCE_KM_PER_UNIT - - # Steam specific logic - if not SteamManager.is_on_steam: - return - - _pending_steam_distance_km += distance_units * DISTANCE_KM_PER_UNIT - var whole_km: int = int(floor(_pending_steam_distance_km)) - if whole_km <= 0: - return - - _pending_steam_distance_km -= float(whole_km) - var total_distance_km: int = StatsManager.get_int(STEAM_DISTANCE_STAT) + whole_km - StatsManager.set_int(STEAM_DISTANCE_STAT, total_distance_km) - _check_distance_achievements(total_distance_km) - StatsManager.store() - -#Check achievements -func _check_distance_achievements(total_distance_km: int) -> void: - if total_distance_km >= 100: - AchievementManager.unlock("ACH_DISTANCE_100") - if total_distance_km >= 200: - AchievementManager.unlock("ACH_DISTANCE_200") + StatsManager.add_distance_km(distance_units * DISTANCE_KM_PER_UNIT) func _execute_stop(go_forward: bool = true) -> void: if not _find_next_valid_stop(go_forward): @@ -522,12 +499,14 @@ func _execute_stop(go_forward: bool = true) -> void: return stop_ongoing = true - stop_multiply = 0.0 - + stop_multiply = 0.0 + var current_stop_index = next_stop_index - + StatsManager.add_int("stat_stop_number", 1) + StatsManager.store() + _advance_next_stop_index(go_forward) - + if fireworks_scene != null: var marker_position = stops_position[current_stop_index] var firework_number = randi_range(5, 8) diff --git a/core/game_menu/train_selector.gd b/core/game_menu/train_selector.gd index 71dd3b1..0040001 100644 --- a/core/game_menu/train_selector.gd +++ b/core/game_menu/train_selector.gd @@ -40,6 +40,7 @@ func _on_color_selected(selected_color_picker: TrainColorPicker, material_index: for i in range(color_pickers.size()): if color_pickers[i] == selected_color_picker: _set_selected_color(i, material_index) + AchievementManager.unlock("ACH_CHANGE_TRAIN_COLOR") break func _apply_train_color(color: Color, material_index: int, color_index: int = 0) -> void: diff --git a/core/main_scene_ui/main_scene_ui.gd b/core/main_scene_ui/main_scene_ui.gd index 8bbfeb0..94a402c 100644 --- a/core/main_scene_ui/main_scene_ui.gd +++ b/core/main_scene_ui/main_scene_ui.gd @@ -113,6 +113,7 @@ func _on_time_of_day_row_on_option_changed(data: String) -> void: pass func _on_weather_row_on_option_changed(data: String) -> void: + var weather_changed: bool = true match data: "Snow": _snow = !_snow @@ -129,9 +130,10 @@ func _on_weather_row_on_option_changed(data: String) -> void: "Random": pick_random_weather() _: - pass + weather_changed = false - AchievementManager.is_unlocked("ACH_CHANGE_METEO") + if weather_changed: + AchievementManager.unlock("ACH_CHANGE_METEO") func pick_random_weather() -> void: var valid_buttons = [] @@ -214,7 +216,6 @@ func _on_photo_taken_finished() -> void: func _on_choo_choo_button_pressed() -> void: UIEvents.toot_toot.emit(true) - AchievementManager.is_unlocked("ACH_CHANGE_TRAIN_COLOR") func _set_buttons_mouse_filter(ignore: bool) -> void: var filter = Control.MOUSE_FILTER_IGNORE if ignore else Control.MOUSE_FILTER_STOP diff --git a/core/steam_manager/achievement_manager.gd b/core/steam_manager/achievement_manager.gd index abd7392..75785c6 100644 --- a/core/steam_manager/achievement_manager.gd +++ b/core/steam_manager/achievement_manager.gd @@ -6,6 +6,11 @@ extends Node const KNOWN := [ "ACH_CHANGE_METEO", "ACH_CHANGE_TRAIN_COLOR", + "ACH_DISTANCE_100", + "ACH_DISTANCE_200", + "ACH_10_PHOTOS", + "ACH_10_TOOTTOOT", + "ACH_DISTANCE_1000" ] #how it works: diff --git a/core/steam_manager/stats_manager.gd b/core/steam_manager/stats_manager.gd index e9c4916..caa164a 100644 --- a/core/steam_manager/stats_manager.gd +++ b/core/steam_manager/stats_manager.gd @@ -13,6 +13,13 @@ const KNOWN := [ "stat_photo_number", "stat_toottoot_number", ] +const TIME_PLAYED_STAT: String = "stat_time_played" +const DISTANCE_KM_STAT: String = "stat_distance_km" +const STATS_STORE_INTERVAL_SECONDS: int = 60 + +var _pending_time_played_seconds: float = 0.0 +var _pending_distance_km: float = 0.0 +var _stats_store_timer: float = 0.0 #how it works: #func _on_match_finished(score: int) -> void: @@ -25,10 +32,20 @@ const KNOWN := [ func _ready() -> void: if not SteamManager.is_on_steam: + set_process(false) return Steam.user_stats_stored.connect(_on_stats_stored) +func _process(delta: float) -> void: + _pending_time_played_seconds += delta + _stats_store_timer += delta + if _stats_store_timer >= STATS_STORE_INTERVAL_SECONDS: + _flush_periodic_stats(false) + +func _exit_tree() -> void: + _flush_periodic_stats(true) + func get_int(stat: String) -> int: if not SteamManager.is_on_steam: return 0 @@ -62,6 +79,14 @@ func add_int(stat: String, amount: int = 1) -> void: return set_int(stat, get_int(stat) + amount) +func add_distance_km(distance_km: float) -> void: + if not SteamManager.is_on_steam: + return + if distance_km <= 0.0: + return + + _pending_distance_km += distance_km + func update_avg_rate(stat: String, count_this_session: float, session_length: float) -> void: if not SteamManager.is_on_steam: return @@ -74,6 +99,32 @@ func store() -> void: if not Steam.storeStats(): push_error("storeStats failed; data saved locally") +#periodic stats incrementation; store data every 60 secs +func _flush_periodic_stats(force_store: bool) -> void: + if not SteamManager.is_on_steam: + _pending_time_played_seconds = 0.0 + _pending_distance_km = 0.0 + _stats_store_timer = 0.0 + return + + var has_changes: bool = false + + var whole_seconds: int = int(floor(_pending_time_played_seconds)) + if whole_seconds > 0: + _pending_time_played_seconds -= float(whole_seconds) + add_int(TIME_PLAYED_STAT, whole_seconds) + has_changes = true + + var whole_km: int = int(floor(_pending_distance_km)) + if whole_km > 0: + _pending_distance_km -= float(whole_km) + add_int(DISTANCE_KM_STAT, whole_km) + has_changes = true + + _stats_store_timer = 0.0 + if has_changes and (force_store or whole_seconds > 0 or whole_km > 0): + store() + #Development only: reset stats func reset_all(include_achievements: bool = false) -> void: if not SteamManager.is_on_steam: diff --git a/tgcc/main_scene.tscn b/tgcc/main_scene.tscn index 6ff2423..98a35e8 100644 --- a/tgcc/main_scene.tscn +++ b/tgcc/main_scene.tscn @@ -250,7 +250,6 @@ wagon_count = 5 wagon_gap = 0.8 wagon_spacing_scale = 0.9 cameras = NodePath("../cameras") -train_start_mode = 2 sleepers_model = ExtResource("46_lbmv2") fireworks_scene = ExtResource("47_q7p65")