/** * Adaptive Tactics - Content Loader * Fetches and parses all JSON content files */ import { Weapon, Unit, MapData } from './models.js'; /** * Fetch and parse a JSON file */ async function fetchJSON(path) { console.log(`Loading: ${path}`); try { const response = await fetch(path); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log(`Loaded: ${path}`); return data; } catch (error) { console.error(`Failed to load ${path}:`, error); throw error; } } /** * Load all game content */ export async function loadAllContent() { const content = { weapons: {}, playerUnits: [], ephraimForms: {}, enemyTemplates: {}, map: null, majorPackages: {}, minorModifiers: {}, transitionLines: {}, gameRules: {} }; // Load all content files in parallel const [ weaponsData, playerUnitsData, ephraimFormsData, enemyTemplatesData, mapData, majorPackagesData, minorModifiersData, transitionLinesData, gameRulesData ] = await Promise.all([ fetchJSON('content/items/weapons.json'), fetchJSON('content/units/player_units.json'), fetchJSON('content/units/ephraim_forms.json'), fetchJSON('content/units/forced_servitude_templates.json'), fetchJSON('content/maps/fortress_map_01.json'), fetchJSON('content/adaptation/major_packages.json'), fetchJSON('content/adaptation/minor_modifiers.json'), fetchJSON('content/text/cycle_transition_lines.json'), fetchJSON('content/balance/game_rules.json') ]); // Process weapons for (const [id, data] of Object.entries(weaponsData.weapons)) { content.weapons[id] = new Weapon(data); } // Process player units for (const data of playerUnitsData.player_units) { // Build weapon references for the unit const unitWeapons = {}; for (const weaponId of data.weapons) { if (content.weapons[weaponId]) { unitWeapons[weaponId] = content.weapons[weaponId]; } } content.playerUnits.push({ template: data, weapons: unitWeapons }); } // Process Ephraim forms content.ephraimForms = ephraimFormsData.ephraim_forms; // Process enemy templates content.enemyTemplates = enemyTemplatesData.enemy_templates; // Process map content.map = new MapData(mapData); // Process adaptation packages content.majorPackages = majorPackagesData.major_packages; content.minorModifiers = minorModifiersData.minor_modifiers; // Process transition lines content.transitionLines = transitionLinesData.transition_lines; // Process game rules content.gameRules = gameRulesData.rules; return content; } /** * Create a player unit instance from template */ export function createPlayerUnit(template, weapons, playerName = null) { const data = { ...template }; data.faction = 'player'; // Set player name for Oathbearer if (data.id === 'oathbearer' && playerName) { data.name = playerName; } return new Unit(data, weapons); } /** * Create an enemy unit instance from template */ export function createEnemyUnit(templateId, templates, weapons, cycle, weaponId = null) { const template = templates[templateId]; if (!template) { console.error(`Unknown enemy template: ${templateId}`); return null; } // Determine scaling band let scalingKey; if (templateId === 'dark_mount') { if (cycle === 2) scalingKey = 'cycle_2'; else if (cycle <= 4) scalingKey = 'cycles_3_4'; else if (cycle <= 6) scalingKey = 'cycles_5_6'; else scalingKey = 'cycles_7_plus'; } else { if (cycle <= 2) scalingKey = 'cycles_1_2'; else if (cycle <= 4) scalingKey = 'cycles_3_4'; else if (cycle <= 6) scalingKey = 'cycles_5_6'; else scalingKey = 'cycles_7_plus'; } const stats = template.scaling[scalingKey]; if (!stats) { console.error(`No scaling data for ${templateId} at ${scalingKey}`); return null; } // Determine weapon const equippedWeapon = weaponId || template.weapons[0]; // Build unit data const unitData = { id: `${templateId}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, name: template.name, title: '', sprite: template.sprite, faction: 'enemy', stats: { hp: stats.hp, maxHp: stats.hp, power: stats.power, skill: stats.skill, speed: stats.speed, def: stats.def, res: stats.res, mov: stats.mov }, weapons: [equippedWeapon], equippedWeapon: equippedWeapon }; // Build weapon references const unitWeapons = {}; unitWeapons[equippedWeapon] = weapons[equippedWeapon]; return new Unit(unitData, unitWeapons); } /** * Create Ephraim unit instance */ export function createEphraim(forms, weapons, formId) { const form = forms[formId]; if (!form) { console.error(`Unknown Ephraim form: ${formId}`); return null; } const unitData = { id: 'ephraim', name: form.name, title: form.title, sprite: form.sprite, portrait: form.portrait, faction: 'enemy', stats: { hp: form.stats.hp, maxHp: form.stats.maxHp, power: form.stats.power, skill: form.stats.skill, speed: form.stats.speed, def: form.stats.def, res: form.stats.res, mov: form.stats.mov }, weapons: form.weapons, equippedWeapon: form.equippedWeapon, behavior: form.behavior }; // Build weapon references const unitWeapons = {}; for (const weaponId of form.weapons) { if (weapons[weaponId]) { unitWeapons[weaponId] = weapons[weaponId]; } } const unit = new Unit(unitData, unitWeapons); unit.behavior = form.behavior; unit.portrait = form.portrait; return unit; }