feat: scaffold mvp shell and content runtime
This commit is contained in:
24
js/content/registry/bundle-resolver.js
Normal file
24
js/content/registry/bundle-resolver.js
Normal file
@@ -0,0 +1,24 @@
|
||||
export function createBundleResolver(cityRegistry) {
|
||||
return {
|
||||
resolveCityBundle(cityId) {
|
||||
const city = cityRegistry.getCity(cityId)
|
||||
|
||||
return city ? city.bundle : null
|
||||
},
|
||||
ensureCityBundle(cityId) {
|
||||
const bundle = this.resolveCityBundle(cityId)
|
||||
|
||||
if (!bundle) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
cityId,
|
||||
...bundle,
|
||||
status: 'ready',
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default createBundleResolver
|
||||
30
js/content/registry/city-registry.js
Normal file
30
js/content/registry/city-registry.js
Normal file
@@ -0,0 +1,30 @@
|
||||
export function createCityRegistry(cities) {
|
||||
const cityMap = new Map(
|
||||
[...cities]
|
||||
.sort((left, right) => left.sortOrder - right.sortOrder)
|
||||
.map((city) => [city.id, city]),
|
||||
)
|
||||
|
||||
return {
|
||||
getAllCities() {
|
||||
return [...cityMap.values()]
|
||||
},
|
||||
getCity(cityId) {
|
||||
return cityMap.get(cityId) ?? null
|
||||
},
|
||||
listCitiesByContinent(continentId) {
|
||||
return [...cityMap.values()].filter((city) => city.continentId === continentId)
|
||||
},
|
||||
getLevelPreset(cityId, levelId) {
|
||||
const city = cityMap.get(cityId)
|
||||
|
||||
if (!city) {
|
||||
return null
|
||||
}
|
||||
|
||||
return city.levelPresets.find((preset) => preset.id === levelId) ?? null
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default createCityRegistry
|
||||
21
js/content/registry/continent-registry.js
Normal file
21
js/content/registry/continent-registry.js
Normal file
@@ -0,0 +1,21 @@
|
||||
export function createContinentRegistry(continents) {
|
||||
const continentMap = new Map(
|
||||
[...continents]
|
||||
.sort((left, right) => left.sortOrder - right.sortOrder)
|
||||
.map((continent) => [continent.id, continent]),
|
||||
)
|
||||
|
||||
return {
|
||||
getContinentList() {
|
||||
return [...continentMap.values()]
|
||||
},
|
||||
getContinent(continentId) {
|
||||
return continentMap.get(continentId) ?? null
|
||||
},
|
||||
hasContinent(continentId) {
|
||||
return continentMap.has(continentId)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default createContinentRegistry
|
||||
45
js/content/registry/progress-projector.js
Normal file
45
js/content/registry/progress-projector.js
Normal file
@@ -0,0 +1,45 @@
|
||||
function getLevelEntries(levelProgress = {}) {
|
||||
return Object.values(levelProgress)
|
||||
}
|
||||
|
||||
export function projectCityProgress(city, playerState) {
|
||||
const levelProgress = playerState.levelProgress[city.id] ?? {}
|
||||
const levels = getLevelEntries(levelProgress)
|
||||
const completedLevels = levels.filter((level) => level.completed).length
|
||||
const totalStars = levels.reduce((sum, level) => sum + (level.stars ?? 0), 0)
|
||||
const totalLevels = city.levelPresets.length
|
||||
const isUnlocked = playerState.unlockedCities.includes(city.id)
|
||||
const isCompleted = totalLevels > 0 && completedLevels >= totalLevels
|
||||
|
||||
return {
|
||||
cityId: city.id,
|
||||
completedLevels,
|
||||
totalLevels,
|
||||
totalStars,
|
||||
isUnlocked,
|
||||
isCompleted,
|
||||
isCollected: playerState.collectedCats.includes(city.id),
|
||||
hasPassportStamp: playerState.passportStamps.includes(city.id),
|
||||
}
|
||||
}
|
||||
|
||||
export function projectCityCardView(city, playerState) {
|
||||
const progress = projectCityProgress(city, playerState)
|
||||
|
||||
return {
|
||||
cityId: city.id,
|
||||
name: city.display.name,
|
||||
nameEn: city.display.nameEn,
|
||||
bgColor: city.display.bgColor,
|
||||
catImage: city.cover.catImage,
|
||||
catThumb: city.cover.catThumb,
|
||||
isUnlocked: progress.isUnlocked,
|
||||
isCompleted: progress.isCompleted,
|
||||
isCollected: progress.isCollected,
|
||||
completedLevels: progress.completedLevels,
|
||||
totalLevels: progress.totalLevels,
|
||||
totalStars: progress.totalStars,
|
||||
}
|
||||
}
|
||||
|
||||
export default projectCityCardView
|
||||
Reference in New Issue
Block a user