Files
Currency-War-SR/tools/gridfight-extract-node/petpal.mjs
T
2026-10-30 23:54:07 +07:00

74 lines
2.7 KiB
JavaScript

import * as s from './stages.mjs';
const e=s.primitive;
export const TABLES={
GridFightPetPalConfigRow:['', 'GridFightPetPal'],
GridFightPetPalEffRow:['', 'GridFightPetPalEff'],
GridFightCampConfigRow:['', 'GridFightCamp'],
GridFightCampSeasonConfigRow:['', 'GridFightCampSeason'],
GridFightMonsterConfigRow:['GameCore', 'GridFightMonster']
};
export function contracts(t){
const effects=new Map(t.GridFightPetPalEffRow.map(r=>[r.ID, r])),
partners=[];
for(const row of t.GridFightPetPalConfigRow.toSorted((a, b)=>a.ID-b.ID)){
if(!(row.HeadImage??'').includes('/Season2/'))continue;
const ids=row.EffIDList??[];
if(!row.ID||ids.some(i=>!effects.has(i)))e.fail('Invalid partner/effect reference');
partners.push({
id:row.ID,
season_id:2,
head_image:row.HeadImage,
effect_ids:ids,
raw:row
});
}
if(!partners.length||!e.uniqueValues(partners, r=>r.id))e.fail('Missing or duplicate season-2 partners');
const monsters=new Map(t.GridFightMonsterConfigRow.map(r=>[r.MonsterID, r])),
campRows=new Map(t.GridFightCampConfigRow.map(r=>[r.ID, r])),
camps=[];
for(const row of t.GridFightCampSeasonConfigRow){
const ids=row.MonsterList??[];
if(row.SeasonID!==2)continue;
if(!campRows.has(row.CampID)||ids.some(i=>!monsters.has(i)))e.fail('Invalid season-2 camp/monster reference');
camps.push({
id:row.CampID,
season_id:2,
monsters:ids.map(i=>({
id:i,
tier:monsters.get(i).MonsterTier??0
})),
raw:{
GridFightCampConfigRow:campRows.get(row.CampID),
GridFightCampSeasonConfigRow:row
}
});
}
if(!camps.length)e.fail('Missing season-2 preview camps');
return {
'petpal.json':partners,
'petpal.raw.json':Object.fromEntries(['GridFightPetPalConfigRow', 'GridFightPetPalEffRow'].map(n=>[n, t[n]])),
'preparation.json':{
camps,
raw:{
GridFightMonsterConfigRow:t.GridFightMonsterConfigRow
}
}
};
}
export function main(){
const a=e.cli(['client', 'dump', 'identity', 'output']),
ctx=s.extractionContext(a),
[t, p]=s.collect(a, TABLES, ctx);
s.publish(a, ctx, t, p, contracts(t), 'petpal', {
mapping:{
season_id:'Season2 portrait paths; table has no SeasonID',
effect_ids:'EffIDList, validated against GridFightPetPalEff',
empty_effects:'Partner 1 has no effect; send effect ID 0 inactive',
preparation:'Native camp membership and MonsterTier, not battle wave generation'
},
unresolved:['Dynamic camp/monster selection from node-template ParamList', 'Per-node battle wave, formation, difficulty and reward rules'],
gameplay_verified:false
});
}
e.runMain(import.meta.url, main);