Files
2025-09-18 17:55:52 -04:00

262 lines
7.6 KiB
Lua

-- Written by Kip Turner, Copyright ROBLOX 2015
-- Achievement Manager
local PlatformService = nil
pcall(function() PlatformService = game:GetService('PlatformService') end)
local CoreGui = Game:GetService("CoreGui")
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
local Modules = GuiRoot:FindFirstChild("Modules")
local EventHub = require(Modules:FindFirstChild('EventHub'))
local Http = require(Modules:FindFirstChild('Http'))
local UserData = require(Modules:FindFirstChild('UserData'))
local PlatformInterface = require(Modules:FindFirstChild('PlatformInterface'))
local GameCollection = require(Modules:FindFirstChild('GameCollection'))
--[[ ACHIEVEMENT NAMES --]]
-- "Award10DayRoll"
-- "Award20DayRoll"
-- "Award3DayRoll"
-- "AwardDeepDiver"
-- "AwardFoursCompany"
-- "AwardOneNameManyFaces"
-- "AwardPollster"
-- "AwardSampler"
-- "AwardStrengthInNumbers"
-- "AwardWorldTraveler"
-- "AwardYouDidIt"
-- "GameProgress"
-- "MultiplayerRoundEnd"
-- "MultiplayerRoundStart"
-- "PlayerSessionEnd"
-- "PlayerSessionPause"
-- "PlayerSessionResume"
-- "PlayerSessionStart"
-- "Test_XPresses"
--[[ END OF ACHIEVEMENT NAMES --]]
local VIEW_GAMETYPE_ENUM =
{
AppShell = 0;
Game = 1;
}
local GAMES_FOR_YOU_DID_IT = 1
local GAMES_FOR_AWARD_SAMPLER = 5
local DAYS_FOR_3DAYROLL = 3
local DAYS_FOR_10DAYROLL = 10
local DAYS_FOR_20DAYROLL = 20
local GAMES_RATED_FOR_POLLSTER = 5
local PLAY_SECONDS_FOR_DEEP_DIVER = 60 * 60
local NUMBER_OF_FRIENDS_REQUIRED_FOR_FOURS_COMPANY = 3
local SECONDS_BETWEEN_FOURS_COMPANY_CHECKS = 30
local AchievementManager = {}
local CurrentView = VIEW_GAMETYPE_ENUM['AppShell']
local function GetTotalNumberOfGamesOnXbox()
-- TODO: is there a programmatic way of figuring this out?
-- local SortData = require(SortDataModule)
-- local recentlyPlayedSortData = SortData.GetSort(1, false)
return 15
end
local function FilterInGameFriends(onlineFriends, playersInGame)
local result = {}
if onlineFriends and playersInGame then
-- Create reverse lookup for speed
local playersInGameReverseLookup = {}
for _, playerInGame in pairs(playersInGame) do
-- TODO: Figure out what the actual lookup
if playerInGame['robloxuid'] then
playersInGameReverseLookup[playerInGame['robloxuid']] = true
end
end
for _, friend in pairs(onlineFriends) do
if playersInGameReverseLookup[friend['robloxuid']] then
table.insert(result, friend)
end
end
end
return result
end
local function OnPlayedGamesChanged()
spawn(function()
local myUserId = UserData:GetRbxUserId()
if myUserId then
local recentCollection = GameCollection:GetUserRecent()
-- TODO: is this the right way of getting num of played games?
local recentlyPage1 = recentCollection and recentCollection:GetSortAsync(0, GetTotalNumberOfGamesOnXbox())
local gamesPlayed = recentlyPage1 and #recentlyPage1:GetPagePlaceIds() or 0
print("You have played:" , gamesPlayed , "games" )
if gamesPlayed >= GAMES_FOR_YOU_DID_IT then
AchievementManager:SendAchievementEventAsync("AwardYouDidIt")
end
if gamesPlayed >= GAMES_FOR_AWARD_SAMPLER then
AchievementManager:SendAchievementEventAsync("AwardSampler")
end
if gamesPlayed >= GetTotalNumberOfGamesOnXbox() then
AchievementManager:SendAchievementEventAsync("AwardWorldTraveler")
end
end
end)
end
local function OnJoinedGame()
spawn(function()
print("OnJoinGame: AwardStrengthInNumbers check")
local partyMembers = PlatformInterface:GetPartyMembersAsync()
if partyMembers then
if PlatformInterface:IsInAParty(partyMembers) then
AchievementManager:SendAchievementEventAsync("AwardStrengthInNumbers")
end
end
end)
spawn(function()
print("OnJoinGame: Fours Company check")
if PlatformService then
local lastCheck = 0
while CurrentView == VIEW_GAMETYPE_ENUM['Game'] do
local now = tick()
if now - lastCheck > SECONDS_BETWEEN_FOURS_COMPANY_CHECKS then
local friendsData = require(Modules:FindFirstChild('FriendsData'))
local onlineFriends = friendsData.GetOnlineFriendsAsync()
-- TODO: add actually API
local inGamePlayers = PlatformService:GetInGamePlayers()
if inGamePlayers and onlineFriends then
local inGameFriends = FilterInGameFriends(onlineFriends, inGamePlayers)
if #inGameFriends >= NUMBER_OF_FRIENDS_REQUIRED_FOR_FOURS_COMPANY then
AchievementManager:SendAchievementEventAsync("AwardFoursCompany")
return
end
end
lastCheck = now
end
wait(1)
end
end
end)
spawn(function()
local startTime = tick()
while tick() - startTime < PLAY_SECONDS_FOR_DEEP_DIVER do
if CurrentView ~= VIEW_GAMETYPE_ENUM['Game'] then
return
end
wait(1)
end
if CurrentView == VIEW_GAMETYPE_ENUM['Game'] then
AchievementManager:SendAchievementEventAsync("AwardDeepDiver")
end
end)
end
function AchievementManager:SendAchievementEventAsync(achievementName)
print("Achievement Manager - Awarding achievement:" , achievementName)
local achievementStatus = nil
local success, msg = pcall(function()
-- NOTE: Yielding function
if not UserSettings().GameSettings:InStudioMode() then
achievementStatus = PlatformService:BeginAwardAchievement(achievementName)
end
end)
if not success then
-- NOTE: very likely this function ever throws an error but returns error codes
print("Achievement Manager - Unable to award achievement:" , achievementName , "for reason:" , msg)
end
print("Achievement Manager - Achievement:" , achievementName , "event status:" , achievementStatus)
end
EventHub:addEventListener(EventHub.Notifications["TestXButtonPressed"], "AchievementManager",
function()
-- AchievementManager:SendAchievementEventAsync("Test_XPresses")
end)
EventHub:addEventListener(EventHub.Notifications["AuthenticationSuccess"], "AchievementManager",
function()
spawn(function()
local myUserId = UserData:GetRbxUserId()
local function stillLoggedIn()
local newUserId = UserData:GetRbxUserId()
return newUserId ~= nil and myUserId == newUserId
end
if myUserId ~= nil then
local daysLoggedIn = 7
-- local Utility = require(Modules:FindFirstChild('Utility'))
-- print("AchievementManager - Checking number of days Logged in:" , Utility.PrettyPrint(loggedInResult))
if daysLoggedIn then
if daysLoggedIn >= DAYS_FOR_3DAYROLL and stillLoggedIn() then
AchievementManager:SendAchievementEventAsync("Award3DayRoll")
end
if daysLoggedIn >= DAYS_FOR_10DAYROLL and stillLoggedIn() then
AchievementManager:SendAchievementEventAsync("Award10DayRoll")
end
if daysLoggedIn >= DAYS_FOR_20DAYROLL and stillLoggedIn() then
AchievementManager:SendAchievementEventAsync("Award20DayRoll")
end
end
OnPlayedGamesChanged()
end
end)
end)
EventHub:addEventListener(EventHub.Notifications["DonnedDifferentPackage"], "AchievementManager",
function(assetId)
AchievementManager:SendAchievementEventAsync("AwardOneNameManyFaces")
end)
EventHub:addEventListener(EventHub.Notifications["VotedOnPlace"], "AchievementManager",
function()
spawn(function()
local voteCount = UserData:GetVoteCount()
print("Vote Check: with vote count" , voteCount)
if voteCount >= GAMES_RATED_FOR_POLLSTER then
AchievementManager:SendAchievementEventAsync("AwardPollster")
end
end)
end)
if PlatformService then
PlatformService.ViewChanged:connect(function(newView)
print("ViewChanged:" , newView)
CurrentView = newView
if newView == VIEW_GAMETYPE_ENUM['AppShell'] then
print("New view is appshell")
OnPlayedGamesChanged()
elseif newView == VIEW_GAMETYPE_ENUM['Game'] then
print("New view is game")
OnJoinedGame()
end
end)
end
return AchievementManager