manage stats and achievements
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
extends Path3D
|
extends Path3D
|
||||||
|
|
||||||
const STEAM_DISTANCE_STAT: String = "stat_distance_km"
|
|
||||||
const DISTANCE_KM_PER_UNIT: float = 0.01
|
const DISTANCE_KM_PER_UNIT: float = 0.01
|
||||||
const STATION_STOP_GROUP: StringName = &"railway_station"
|
const STATION_STOP_GROUP: StringName = &"railway_station"
|
||||||
const TRACK_ZERO_SPACING_FIX_DISTANCE: float = 45.0
|
const TRACK_ZERO_SPACING_FIX_DISTANCE: float = 45.0
|
||||||
@@ -102,7 +101,6 @@ var is_restarting: bool = false
|
|||||||
var tween_restart: Tween
|
var tween_restart: Tween
|
||||||
var wagon_instances: Array[Node3D] = []
|
var wagon_instances: Array[Node3D] = []
|
||||||
var wagon_progress_offsets: Array[float] = []
|
var wagon_progress_offsets: Array[float] = []
|
||||||
var _pending_steam_distance_km: float = 0.0
|
|
||||||
var _initial_is_inmotion: bool = true
|
var _initial_is_inmotion: bool = true
|
||||||
var _is_photo_mode_active: bool = false
|
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)
|
# 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
|
GameState.save_data.total_distance_km += distance_units * DISTANCE_KM_PER_UNIT
|
||||||
|
StatsManager.add_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")
|
|
||||||
|
|
||||||
func _execute_stop(go_forward: bool = true) -> void:
|
func _execute_stop(go_forward: bool = true) -> void:
|
||||||
if not _find_next_valid_stop(go_forward):
|
if not _find_next_valid_stop(go_forward):
|
||||||
@@ -525,6 +502,8 @@ func _execute_stop(go_forward: bool = true) -> void:
|
|||||||
stop_multiply = 0.0
|
stop_multiply = 0.0
|
||||||
|
|
||||||
var current_stop_index = next_stop_index
|
var current_stop_index = next_stop_index
|
||||||
|
StatsManager.add_int("stat_stop_number", 1)
|
||||||
|
StatsManager.store()
|
||||||
|
|
||||||
_advance_next_stop_index(go_forward)
|
_advance_next_stop_index(go_forward)
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ func _on_color_selected(selected_color_picker: TrainColorPicker, material_index:
|
|||||||
for i in range(color_pickers.size()):
|
for i in range(color_pickers.size()):
|
||||||
if color_pickers[i] == selected_color_picker:
|
if color_pickers[i] == selected_color_picker:
|
||||||
_set_selected_color(i, material_index)
|
_set_selected_color(i, material_index)
|
||||||
|
AchievementManager.unlock("ACH_CHANGE_TRAIN_COLOR")
|
||||||
break
|
break
|
||||||
|
|
||||||
func _apply_train_color(color: Color, material_index: int, color_index: int = 0) -> void:
|
func _apply_train_color(color: Color, material_index: int, color_index: int = 0) -> void:
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ func _on_time_of_day_row_on_option_changed(data: String) -> void:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
func _on_weather_row_on_option_changed(data: String) -> void:
|
func _on_weather_row_on_option_changed(data: String) -> void:
|
||||||
|
var weather_changed: bool = true
|
||||||
match data:
|
match data:
|
||||||
"Snow":
|
"Snow":
|
||||||
_snow = !_snow
|
_snow = !_snow
|
||||||
@@ -129,9 +130,10 @@ func _on_weather_row_on_option_changed(data: String) -> void:
|
|||||||
"Random":
|
"Random":
|
||||||
pick_random_weather()
|
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:
|
func pick_random_weather() -> void:
|
||||||
var valid_buttons = []
|
var valid_buttons = []
|
||||||
@@ -214,7 +216,6 @@ func _on_photo_taken_finished() -> void:
|
|||||||
|
|
||||||
func _on_choo_choo_button_pressed() -> void:
|
func _on_choo_choo_button_pressed() -> void:
|
||||||
UIEvents.toot_toot.emit(true)
|
UIEvents.toot_toot.emit(true)
|
||||||
AchievementManager.is_unlocked("ACH_CHANGE_TRAIN_COLOR")
|
|
||||||
|
|
||||||
func _set_buttons_mouse_filter(ignore: bool) -> void:
|
func _set_buttons_mouse_filter(ignore: bool) -> void:
|
||||||
var filter = Control.MOUSE_FILTER_IGNORE if ignore else Control.MOUSE_FILTER_STOP
|
var filter = Control.MOUSE_FILTER_IGNORE if ignore else Control.MOUSE_FILTER_STOP
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ extends Node
|
|||||||
const KNOWN := [
|
const KNOWN := [
|
||||||
"ACH_CHANGE_METEO",
|
"ACH_CHANGE_METEO",
|
||||||
"ACH_CHANGE_TRAIN_COLOR",
|
"ACH_CHANGE_TRAIN_COLOR",
|
||||||
|
"ACH_DISTANCE_100",
|
||||||
|
"ACH_DISTANCE_200",
|
||||||
|
"ACH_10_PHOTOS",
|
||||||
|
"ACH_10_TOOTTOOT",
|
||||||
|
"ACH_DISTANCE_1000"
|
||||||
]
|
]
|
||||||
|
|
||||||
#how it works:
|
#how it works:
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ const KNOWN := [
|
|||||||
"stat_photo_number",
|
"stat_photo_number",
|
||||||
"stat_toottoot_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:
|
#how it works:
|
||||||
#func _on_match_finished(score: int) -> void:
|
#func _on_match_finished(score: int) -> void:
|
||||||
@@ -25,10 +32,20 @@ const KNOWN := [
|
|||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if not SteamManager.is_on_steam:
|
if not SteamManager.is_on_steam:
|
||||||
|
set_process(false)
|
||||||
return
|
return
|
||||||
|
|
||||||
Steam.user_stats_stored.connect(_on_stats_stored)
|
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:
|
func get_int(stat: String) -> int:
|
||||||
if not SteamManager.is_on_steam:
|
if not SteamManager.is_on_steam:
|
||||||
return 0
|
return 0
|
||||||
@@ -62,6 +79,14 @@ func add_int(stat: String, amount: int = 1) -> void:
|
|||||||
return
|
return
|
||||||
set_int(stat, get_int(stat) + amount)
|
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:
|
func update_avg_rate(stat: String, count_this_session: float, session_length: float) -> void:
|
||||||
if not SteamManager.is_on_steam:
|
if not SteamManager.is_on_steam:
|
||||||
return
|
return
|
||||||
@@ -74,6 +99,32 @@ func store() -> void:
|
|||||||
if not Steam.storeStats():
|
if not Steam.storeStats():
|
||||||
push_error("storeStats failed; data saved locally")
|
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
|
#Development only: reset stats
|
||||||
func reset_all(include_achievements: bool = false) -> void:
|
func reset_all(include_achievements: bool = false) -> void:
|
||||||
if not SteamManager.is_on_steam:
|
if not SteamManager.is_on_steam:
|
||||||
|
|||||||
@@ -250,7 +250,6 @@ wagon_count = 5
|
|||||||
wagon_gap = 0.8
|
wagon_gap = 0.8
|
||||||
wagon_spacing_scale = 0.9
|
wagon_spacing_scale = 0.9
|
||||||
cameras = NodePath("../cameras")
|
cameras = NodePath("../cameras")
|
||||||
train_start_mode = 2
|
|
||||||
sleepers_model = ExtResource("46_lbmv2")
|
sleepers_model = ExtResource("46_lbmv2")
|
||||||
fireworks_scene = ExtResource("47_q7p65")
|
fireworks_scene = ExtResource("47_q7p65")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user