Yes, under the hood it ultimately just loops the associated achievement, sorry I forgot that step. But at least this way you're only looping zones with stories, and only checking achievements that we already know has Skyshards. It's better than looping thousands of achievements or hundreds of zones looking for the ones that matter, or worse, hard coding ids.
Also you can do this:
Code:
local function GetNextZoneStoryZoneIdIter(_, lastZoneId)
return GetNextZoneStoryZoneId(lastZoneId)
end
for zoneId in GetNextZoneStoryZoneIdIter do
end
You can also use GetActivityCompletionProgressValues instead of GetActivityCompletionProgressValuesAndText since you don't need the text.