23 lines
1.8 KiB
JavaScript
23 lines
1.8 KiB
JavaScript
export const RESUME_KEY='variant:campaign-200-r2:v1:resume';
|
|
export function readResume(storage){try{const value=JSON.parse(storage.getItem(RESUME_KEY)||'null');return value?.version===1&&typeof value.levelId==='string'?value:null;}catch{return null;}}
|
|
export function resumeTarget(levels,completed,saved,legacyId){
|
|
const done=new Set(completed),savedIndex=levels.findIndex(l=>l.id===saved?.levelId),legacy=levels.findIndex(l=>l.id===legacyId);
|
|
if(savedIndex>=0&&!done.has(levels[savedIndex].id))return {index:savedIndex,path:Array.isArray(saved.path)?saved.path:[]};
|
|
const from=savedIndex>=0?savedIndex:legacy;
|
|
if(from>=0&&!done.has(levels[from].id))return {index:from,path:[]};
|
|
for(let step=1;step<=levels.length;step++){const i=(Math.max(-1,from)+step)%levels.length;if(!done.has(levels[i].id))return {index:i,path:[]};}
|
|
return {index:Math.max(0,from),path:[]};
|
|
}
|
|
export function validResumePath(level,route,canAppend){
|
|
if(!Array.isArray(route)||route.length>level.cells.length)return [];
|
|
const restored=[];for(const id of route){if(typeof id!=='string'||!canAppend(level,restored,id))return [];restored.push(id);}return restored;
|
|
}
|
|
export function writeResume(storage,levels,completed,current,path,cleared){
|
|
const previous=readResume(storage),done=new Set(completed);
|
|
// Replaying a completed level must not replace the last unfinished level.
|
|
if(done.has(current.id)&&!cleared&&previous&&!done.has(previous.levelId)&&levels.some(l=>l.id===previous.levelId))return;
|
|
const next=cleared||done.has(current.id)?resumeTarget(levels,completed,null,current.id):{index:levels.indexOf(current),path:[...path]};
|
|
const value=JSON.stringify({version:1,levelId:levels[next.index].id,path:next.path});
|
|
try{if(storage.getItem(RESUME_KEY)!==value)storage.setItem(RESUME_KEY,value);}catch{}
|
|
}
|