diff --git a/.gitignore b/.gitignore index cf3bef523..c780db20f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ mono_crash.*.json # Android ignores android/ + +addons/godotsteam diff --git a/src/Autoload/OpenSave.gd b/src/Autoload/OpenSave.gd index 112038558..037fe503c 100644 --- a/src/Autoload/OpenSave.gd +++ b/src/Autoload/OpenSave.gd @@ -354,14 +354,14 @@ func open_v0_pxo_file(path: String, empty_project: bool) -> Project: func save_pxo_file( path: String, autosave: bool, include_blended := false, project := Global.current_project ) -> bool: - if !autosave: + if not autosave: project.name = path.get_file().trim_suffix(".pxo") var serialized_data := project.serialize() - if !serialized_data: + if not serialized_data: Global.popup_error(tr("File failed to save. Converting project data to dictionary failed.")) return false var to_save := JSON.stringify(serialized_data) - if !to_save: + if not to_save: Global.popup_error(tr("File failed to save. Converting dictionary to JSON failed.")) return false @@ -450,6 +450,7 @@ func save_pxo_file( Global.FileMenu.SAVE, tr("Save") + " %s" % path.get_file() ) project_saved.emit() + SteamManager.set_achievement("ACH_SAVE") save_project_to_recent_list(path) return true diff --git a/src/Classes/Drawers.gd b/src/Classes/Drawers.gd index 1989572e2..669ab0bd7 100644 --- a/src/Classes/Drawers.gd +++ b/src/Classes/Drawers.gd @@ -77,3 +77,4 @@ func set_pixel(image: Image, position: Vector2i, color: Color, ignore_mirroring var mirror_pos := mirrored_positions[i] if project.can_pixel_get_drawn(mirror_pos) && not Tools.check_alpha_lock(image, mirror_pos): drawers[i + 1].set_pixel(image, mirror_pos, color, color_op) + SteamManager.set_achievement("ACH_FIRST_PIXEL") diff --git a/src/Classes/SteamManager.gd b/src/Classes/SteamManager.gd new file mode 100644 index 000000000..5771897eb --- /dev/null +++ b/src/Classes/SteamManager.gd @@ -0,0 +1,45 @@ +class_name SteamManager +extends Node + +## A class that manages Steam-specific functionalities. Currently only unlocks achievements. +## On non-Steam builds, this node gets automatically freed. + +## The Steam app id of Pixelorama. +const APP_ID := 2779170 +## We are using a variable instead of the `Steam` singleton directly, +## because it is not available in non-Steam builds. +static var steam_class + + +func _init() -> void: + if not ClassDB.class_exists(&"Steam"): + queue_free() + return + steam_class = ClassDB.instantiate(&"Steam") + OS.set_environment("SteamAppID", str(APP_ID)) + OS.set_environment("SteamGameID", str(APP_ID)) + + +func _ready() -> void: + if not is_instance_valid(steam_class): + return + var response: Dictionary = steam_class.steamInitEx(true, APP_ID) + print(response) + if not steam_class.isSteamRunning(): + print("Steam is not running!") + return + #var id: int = steam_class.getSteamID() + #var username: String = steam_class.getFriendPersonaName(id) + + +## Unlocks an achievement on Steam based on its [param achievement_name]. +static func set_achievement(achievement_name: String) -> void: + if not is_instance_valid(steam_class): + return + if not steam_class.isSteamRunning(): + return + var status: Dictionary = steam_class.getAchievement(achievement_name) + if status["achieved"]: + return + steam_class.setAchievement(achievement_name) + steam_class.storeStats() diff --git a/src/Main.tscn b/src/Main.tscn index 41fbeca46..0ab12774d 100644 --- a/src/Main.tscn +++ b/src/Main.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=17 format=3 uid="uid://dbylw5k04ulp8"] +[gd_scene load_steps=18 format=3 uid="uid://dbylw5k04ulp8"] [ext_resource type="Theme" uid="uid://bkb4syj8110el" path="res://assets/themes/dark/theme.tres" id="1"] [ext_resource type="Script" path="res://src/Main.gd" id="2"] @@ -14,6 +14,7 @@ [ext_resource type="PackedScene" uid="uid://c0nuukjakmai2" path="res://src/UI/Dialogs/TileModeOffsetsDialog.tscn" id="14"] [ext_resource type="PackedScene" uid="uid://c6fyrnyt3663o" path="res://src/UI/Timeline/TagProperties.tscn" id="14_fw6cf"] [ext_resource type="Script" path="res://src/HandleExtensions.gd" id="15_v0k2h"] +[ext_resource type="Script" path="res://src/Classes/SteamManager.gd" id="17_k1xhp"] [ext_resource type="PackedScene" uid="uid://clbjfkdupw52l" path="res://src/UI/Timeline/CelProperties.tscn" id="17_ucs64"] [ext_resource type="PackedScene" uid="uid://clgu8wb5o6oup" path="res://src/UI/Dialogs/ExportDialog.tscn" id="39"] @@ -110,11 +111,14 @@ visible = false [node name="ImageRequest" type="HTTPRequest" parent="."] +[node name="SteamManager" type="Node" parent="."] +script = ExtResource("17_k1xhp") + [connection signal="files_selected" from="Dialogs/OpenSprite" to="." method="_on_OpenSprite_files_selected"] [connection signal="visibility_changed" from="Dialogs/OpenSprite" to="." method="_on_open_sprite_visibility_changed"] [connection signal="file_selected" from="Dialogs/SaveSprite" to="." method="_on_SaveSprite_file_selected"] -[connection signal="visibility_changed" from="Dialogs/SaveSprite" to="." method="_on_save_sprite_visibility_changed"] [connection signal="visibility_changed" from="Dialogs/SaveSprite" to="." method="_can_draw_true"] +[connection signal="visibility_changed" from="Dialogs/SaveSprite" to="." method="_on_save_sprite_visibility_changed"] [connection signal="confirmed" from="Dialogs/SaveSpriteHTML5" to="." method="save_project" binds= [""]] [connection signal="visibility_changed" from="Dialogs/SaveSpriteHTML5" to="." method="_can_draw_true"] [connection signal="visibility_changed" from="Dialogs/ExportDialog" to="." method="_can_draw_true"] diff --git a/src/Preferences/PreferencesDialog.gd b/src/Preferences/PreferencesDialog.gd index a2458d75c..827243408 100644 --- a/src/Preferences/PreferencesDialog.gd +++ b/src/Preferences/PreferencesDialog.gd @@ -328,6 +328,7 @@ func _ready() -> void: if typeof(value) == TYPE_VECTOR2 or typeof(value) == TYPE_COLOR: is_default = value.is_equal_approx(pref.default_value) disable_restore_default_button(restore_default_button, is_default) + SteamManager.set_achievement("ACH_PREFERENCES") func _on_Preference_value_changed(value, pref: Preference, button: RestoreDefaultButton) -> void: diff --git a/src/Tools/DesignTools/Eraser.gd b/src/Tools/DesignTools/Eraser.gd index e5870e8ab..754b1200a 100644 --- a/src/Tools/DesignTools/Eraser.gd +++ b/src/Tools/DesignTools/Eraser.gd @@ -106,6 +106,7 @@ func draw_end(pos: Vector2i) -> void: _draw_line = false commit_undo() + SteamManager.set_achievement("ACH_ERASE_PIXEL") cursor_text = "" update_random_image() diff --git a/src/UI/TopMenuContainer/TopMenuContainer.gd b/src/UI/TopMenuContainer/TopMenuContainer.gd index a45630c5d..bbfeae307 100644 --- a/src/UI/TopMenuContainer/TopMenuContainer.gd +++ b/src/UI/TopMenuContainer/TopMenuContainer.gd @@ -834,6 +834,7 @@ func help_menu_id_pressed(id: int) -> void: _popup_dialog(Global.control.splash_dialog) Global.HelpMenu.ONLINE_DOCS: OS.shell_open(DOCS_URL) + SteamManager.set_achievement("ACH_ONLINE_DOCS") Global.HelpMenu.ISSUE_TRACKER: OS.shell_open(ISSUES_URL) Global.HelpMenu.OPEN_EDITOR_DATA_FOLDER: @@ -844,5 +845,6 @@ func help_menu_id_pressed(id: int) -> void: about_dialog.popup() Global.HelpMenu.SUPPORT_PIXELORAMA: OS.shell_open(SUPPORT_URL) + SteamManager.set_achievement("ACH_SUPPORT_DEVELOPMENT") _: _handle_metadata(id, help_menu)