add steam overlay, achievements and stats managers
This commit is contained in:
@@ -4,12 +4,12 @@ importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://bvrn4woiabto5"
|
||||
path="res://.godot/imported/gathering.fbx-8cf29bfb4073eff7f1a8c8f2f1200637.scn"
|
||||
path="res://.godot/imported/Gathering.fbx-010ce6eb774e1ef5173d7b91f43194c4.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/ai/agents/human/gathering.fbx"
|
||||
dest_files=["res://.godot/imported/gathering.fbx-8cf29bfb4073eff7f1a8c8f2f1200637.scn"]
|
||||
source_file="res://core/ai/agents/human/Gathering.fbx"
|
||||
dest_files=["res://.godot/imported/Gathering.fbx-010ce6eb774e1ef5173d7b91f43194c4.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://cfe0ylyx1lfaa"
|
||||
path="res://.godot/imported/idle.fbx-e84be0400dfd82eeca47497734059eba.scn"
|
||||
path="res://.godot/imported/Idle.fbx-55b141029a6b8b2285a4fdfb57ee0c93.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/ai/agents/human/idle.fbx"
|
||||
dest_files=["res://.godot/imported/idle.fbx-e84be0400dfd82eeca47497734059eba.scn"]
|
||||
source_file="res://core/ai/agents/human/Idle.fbx"
|
||||
dest_files=["res://.godot/imported/Idle.fbx-55b141029a6b8b2285a4fdfb57ee0c93.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://cuphreeff7ihw"
|
||||
path="res://.godot/imported/sitting.fbx-28ba14b5efd99e4f9dac90f909835595.scn"
|
||||
path="res://.godot/imported/Sitting.fbx-83aa57848ecefeeaff20ef595a19a7b3.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/ai/agents/human/sitting.fbx"
|
||||
dest_files=["res://.godot/imported/sitting.fbx-28ba14b5efd99e4f9dac90f909835595.scn"]
|
||||
source_file="res://core/ai/agents/human/Sitting.fbx"
|
||||
dest_files=["res://.godot/imported/Sitting.fbx-83aa57848ecefeeaff20ef595a19a7b3.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://o8dn1hc1lyly"
|
||||
path="res://.godot/imported/walking.fbx-2ef52b3a6cd770e898c2eff1dbd7eecc.scn"
|
||||
path="res://.godot/imported/Walking.fbx-280a67ae546347dd1478504ff6b11a6e.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/ai/agents/human/walking.fbx"
|
||||
dest_files=["res://.godot/imported/walking.fbx-2ef52b3a6cd770e898c2eff1dbd7eecc.scn"]
|
||||
source_file="res://core/ai/agents/human/Walking.fbx"
|
||||
dest_files=["res://.godot/imported/Walking.fbx-280a67ae546347dd1478504ff6b11a6e.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -5,6 +5,7 @@ extends CanvasLayer
|
||||
@onready var loading_screen = $LoadingScreen
|
||||
@export var transition_duration: float = 1
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
color_rect.color.a = 0.0
|
||||
color_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
|
||||
73
core/steam_manager/achievement_manager.gd
Normal file
73
core/steam_manager/achievement_manager.gd
Normal file
@@ -0,0 +1,73 @@
|
||||
extends Node
|
||||
|
||||
#Achievement e statistiche devono essere pubblicati live nel backend
|
||||
#Steamworks anche se il gioco non è ancora uscito altrimenti le chiamate ritornano errore
|
||||
const KNOWN := [
|
||||
"ACH_FIRST_WIN",
|
||||
"ACH_PLAY_10_GAMES",
|
||||
"ACH_REACH_LEVEL_5",
|
||||
]
|
||||
|
||||
#how it works:
|
||||
#func _on_player_won() -> void:
|
||||
# Achievements.unlock("ACH_FIRST_WIN") #unlock the achievement at first win
|
||||
|
||||
#func _on_match_finished(coins_collected: int) -> void:
|
||||
#update stats
|
||||
#...
|
||||
#check thresholds and unlock achievements
|
||||
# if Stats.get_int("stat_games_played") >= 10:
|
||||
# Achievements.unlock("ACH_PLAY_10_GAMES")
|
||||
# if Stats.get_int("stat_total_coins") >= 100:
|
||||
# Achievements.unlock("ACH_COLLECT_100_COINS")
|
||||
|
||||
signal unlocked(api_name: String)
|
||||
|
||||
func _ready() -> void:
|
||||
if not SteamManager.is_on_steam:
|
||||
return
|
||||
|
||||
Steam.user_achievement_stored.connect(_on_achievement_stored)
|
||||
Steam.global_achievement_percentages_ready.connect(_on_global_percentages_ready)
|
||||
Steam.requestGlobalAchievementPercentages() # asincrona
|
||||
|
||||
func _on_global_percentages_ready(_game: int, _result: int) -> void:
|
||||
pass
|
||||
|
||||
func unlock(api_name: String) -> void:
|
||||
if not KNOWN.has(api_name):
|
||||
push_warning("Achievement unknown: %s" % api_name)
|
||||
return
|
||||
if is_unlocked(api_name):
|
||||
return
|
||||
if not Steam.setAchievement(api_name):
|
||||
push_error("setAchievement failed (is published on Steam?): %s" % api_name)
|
||||
return
|
||||
Steam.storeStats()
|
||||
unlocked.emit(api_name)
|
||||
|
||||
func is_unlocked(api_name: String) -> bool:
|
||||
var data: Dictionary = Steam.getAchievement(api_name)
|
||||
return data.get("achieved", false)
|
||||
|
||||
func get_display_name(api_name: String) -> String:
|
||||
return Steam.getAchievementDisplayAttribute(api_name, "name")
|
||||
|
||||
func get_description(api_name: String) -> String:
|
||||
return Steam.getAchievementDisplayAttribute(api_name, "desc")
|
||||
|
||||
#Global percentage of player who have unlocked the achievement
|
||||
func get_global_percent(api_name: String) -> float:
|
||||
var data: Dictionary = Steam.getAchievementAchievedPercent(api_name)
|
||||
if not data.get("ret", false):
|
||||
return -1.0 #global percentage not yet available
|
||||
return data.get("percent", 0.0)
|
||||
|
||||
#for development only: reset an achievement
|
||||
func clear(api_name: String) -> void:
|
||||
Steam.clearAchievement(api_name)
|
||||
Steam.storeStats()
|
||||
|
||||
func _on_achievement_stored(_game: int, _group: bool, api_name: String,
|
||||
current: int, maximum: int) -> void:
|
||||
print("Achievement confirmed by server: %s (%d/%d)" % [api_name, current, maximum])
|
||||
1
core/steam_manager/achievement_manager.gd.uid
Normal file
1
core/steam_manager/achievement_manager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://vcuh547okpvj
|
||||
62
core/steam_manager/stats_manager.gd
Normal file
62
core/steam_manager/stats_manager.gd
Normal file
@@ -0,0 +1,62 @@
|
||||
extends Node
|
||||
|
||||
#Achievement e statistiche devono essere pubblicati live nel backend
|
||||
#Steamworks anche se il gioco non è ancora uscito altrimenti le chiamate ritornano errore
|
||||
const KNOWN := [
|
||||
"stat_games_played",
|
||||
"stat_total_score",
|
||||
"stat_distance_km",
|
||||
]
|
||||
|
||||
#how it works:
|
||||
#func _on_match_finished(score: int) -> void:
|
||||
# Stats.add_int("stat_games_played", 1)
|
||||
# Stats.set_int("stat_total_score", Stats.get_int("stat_total_score") + score)
|
||||
# Stats.store() #only one push at the end of the game
|
||||
# if Stats.get_int("stat_games_played") >= 10:
|
||||
# Achievements.unlock("ACH_PLAY_10_GAMES") #it call storeStats()
|
||||
|
||||
func _ready() -> void:
|
||||
if not SteamManager.is_on_steam:
|
||||
return
|
||||
|
||||
Steam.user_stats_stored.connect(_on_stats_stored)
|
||||
|
||||
func get_int(stat: String) -> int:
|
||||
return Steam.getStatInt(stat)
|
||||
|
||||
func get_float(stat: String) -> float:
|
||||
return Steam.getStatFloat(stat)
|
||||
|
||||
func set_int(stat: String, value: int) -> void:
|
||||
if not KNOWN.has(stat):
|
||||
push_warning("Stat not found: %s" % stat)
|
||||
return
|
||||
if not Steam.setStatInt(stat, value):
|
||||
push_error("setStatInt failed (incremental with value less than current value? is published on steam?): %s" % stat)
|
||||
|
||||
func set_float(stat: String, value: float) -> void:
|
||||
if not KNOWN.has(stat):
|
||||
push_warning("Stat not found: %s" % stat)
|
||||
return
|
||||
if not Steam.setStatFloat(stat, value):
|
||||
push_error("setStatFloat failed: %s" % stat)
|
||||
|
||||
func add_int(stat: String, amount: int = 1) -> void:
|
||||
set_int(stat, get_int(stat) + amount)
|
||||
|
||||
func update_avg_rate(stat: String, count_this_session: float, session_length: float) -> void:
|
||||
Steam.updateAvgRateStat(stat, count_this_session, session_length)
|
||||
|
||||
#Send all data to server; call it at the end of the game of when exit
|
||||
func store() -> void:
|
||||
if not Steam.storeStats():
|
||||
push_error("storeStats failed; data saved locally")
|
||||
|
||||
#Development only: reset stats
|
||||
func reset_all(include_achievements: bool = false) -> void:
|
||||
Steam.resetAllStats(include_achievements)
|
||||
Steam.storeStats()
|
||||
|
||||
func _on_stats_stored(_game: int, result: int) -> void:
|
||||
print("Stats save on server, result=%d" % result)
|
||||
1
core/steam_manager/stats_manager.gd.uid
Normal file
1
core/steam_manager/stats_manager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bc3w8330cgc53
|
||||
27
core/steam_manager/steam_manager.gd
Normal file
27
core/steam_manager/steam_manager.gd
Normal file
@@ -0,0 +1,27 @@
|
||||
extends Node
|
||||
|
||||
const APP_ID: int = 4809260 #Train Goes Choo Choo
|
||||
|
||||
var is_on_steam: bool = false
|
||||
|
||||
func _init() -> void:
|
||||
OS.set_environment("SteamAppId", str(APP_ID))
|
||||
OS.set_environment("SteamGameId", str(APP_ID))
|
||||
|
||||
func _ready() -> void:
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
|
||||
var init := Steam.steamInitEx()
|
||||
if init['status'] != Steam.STEAM_API_INIT_RESULT_OK:
|
||||
push_error("Steam not initialized: %s" % init['verbal'])
|
||||
return
|
||||
|
||||
is_on_steam = true
|
||||
Steam.overlay_toggled.connect(_on_overlay_toggled)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if is_on_steam:
|
||||
Steam.run_callbacks() # every frame, always
|
||||
|
||||
func _on_overlay_toggled(active: bool, _user_initiated: bool, _app_id: int) -> void:
|
||||
get_tree().paused = active
|
||||
1
core/steam_manager/steam_manager.gd.uid
Normal file
1
core/steam_manager/steam_manager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b8u4wynp6d6so
|
||||
Reference in New Issue
Block a user