File size: 4,990 Bytes
b6a38d7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
if FirstLoad then
s_AchievementReceivedSignals = {}
s_AchievementUnlockedSignals = {}
_AchievementsToUnlock = {}
_UnlockThread = false
g_SteamIdToAchievementName = {}
g_AchievementNameToSteamId = {}
end
function OnMsg.DataLoaded()
g_SteamIdToAchievementName = {}
g_AchievementNameToSteamId = {}
ForEachPreset(Achievement, function(achievement, group_list)
local steam_id = achievement.steam_id ~= "" and achievement.steam_id or achievement.id
g_SteamIdToAchievementName[steam_id] = achievement.id
g_AchievementNameToSteamId[achievement.id] = steam_id
end)
end
-- Steam account -> AccountStorage sync policy
TransferUnlockedAchievementsFromSteam = true
function OnSteamAchievementsReceived()
Msg(s_AchievementReceivedSignals)
end
function OnSteamAchievementUnlocked(unlock_status)
if unlock_status == "success" then
Msg(s_AchievementUnlockedSignals)
end
end
local function WaitGetAchievements()
if IsSteamLoggedIn() and SteamQueryAchievements(table.values(table.map(AchievementPresets, "steam_id"))) then
local ok, data
if WaitMsg( s_AchievementReceivedSignals, 5 * 1000 ) then
data = SteamGetAchievements()
if data then
return true, table.map(data, g_SteamIdToAchievementName)
end
end
end
return false
end
local function GetSteamAchievementIds(achievements)
local steam_achievements = { }
for i, name in ipairs(achievements) do
if AchievementPresets[name] then
local steam_id = g_AchievementNameToSteamId[name]
if not steam_id then
print("Achievement", name, "doesn't have a Steam ID!")
else
table.insert(steam_achievements, steam_id)
end
end
end
return steam_achievements
end
local function WaitAchievementUnlock(achievements)
if not Platform.steam or not IsSteamLoggedIn() then
return true
end
local steam_achievements = GetSteamAchievementIds(achievements)
local steam_unlocked = SteamUnlockAchievements(steam_achievements) and WaitMsg(s_AchievementUnlockedSignals, 5*1000)
if not steam_unlocked then
-- Currently our publisher wants to test if achievements work even if they haven't been
-- created in the steam backend.
-- To do this we unlock all achievements in AccountStorage even if they haven't been unlocked in steam.
-- We also pop a notification if steam failed to unlock the achievement.
Msg("SteamUnlockAchievementsFailed", steam_achievements)
end
return true
end
-------------------------------------------[ Higher level functions ]-----------------------------------------------
-- Asynchronous version, launches a thread
function AsyncAchievementUnlock(achievement)
_AchievementsToUnlock[achievement] = true
if not IsValidThread(_UnlockThread) then
_UnlockThread = CreateRealTimeThread( function()
local achievement = next(_AchievementsToUnlock)
while achievement do
if WaitAchievementUnlock{achievement} then
Msg("AchievementUnlocked", achievement)
else
AccountStorage.achievements.unlocked[achievement] = false
end
_AchievementsToUnlock[achievement] = nil
achievement = next(_AchievementsToUnlock)
end
end)
end
end
function SynchronizeAchievements()
if not IsSteamLoggedIn() then return end
-- check progress, auto-unlock if sufficient progress is made
for k, v in pairs(AccountStorage.achievements.progress) do
_CheckAchievementProgress(k, "don't unlock in provider")
end
local account_storage_unlocked = AccountStorage.achievements.unlocked
CreateRealTimeThread(function()
if account_storage_unlocked ~= AccountStorage.achievements.unlocked then
print("Synchronize achievements aborted!")
return
end
-- transfer unlocked achievements to Steam account
WaitAchievementUnlock(table.keys(account_storage_unlocked))
if not TransferUnlockedAchievementsFromSteam then
return
end
if account_storage_unlocked ~= AccountStorage.achievements.unlocked then
print("Synchronize achievements aborted!")
return
end
-- transfer unlocked achievements to AccountStorage
local ok, steam_unlocked = WaitGetAchievements()
if account_storage_unlocked ~= AccountStorage.achievements.unlocked then
print("Synchronize achievements aborted!")
return
end
if not ok then
print("Synchronize achievements failed!")
return
end
local save = false
for i = 1, #steam_unlocked do
local id = steam_unlocked[i]
if not account_storage_unlocked[id] then
save = true
end
account_storage_unlocked[id] = true
end
if save then
SaveAccountStorage(5000)
end
end)
end
function CheatPlatformUnlockAllAchievements()
if not Platform.steam or not IsSteamLoggedIn() then end
local steam_achievements = GetSteamAchievementIds(table.keys(AchievementPresets, true))
SteamUnlockAchievements(steam_achievements)
end
function CheatPlatformResetAllAchievements()
if not Platform.steam or not IsSteamLoggedIn() then end
local steam_achievements = GetSteamAchievementIds(table.keys(AchievementPresets, true))
SteamResetAchievements(steam_achievements)
end
|