<?php /** * UPGRADE 2 – ENGINE BOOTSTRAP (FIXED) * ✅ No SQL * ✅ No escaping issues * ✅ Safe overwrite * Run once after install */ /* ========================= ENGINE ========================= */ file_put_contents("engine/TargetingLogic.php", <<<PHP <?php class TargetingLogic { public static function pickTarget(array \$unit, array \$enemies) { if (empty(\$enemies)) return null; usort(\$enemies, function(\$a, \$b) { return \$a['current_hp'] <=> \$b['current_hp']; }); return \$enemies[0]; } } PHP); file_put_contents("engine/CombatResolver.php", <<<PHP <?php class CombatResolver { public static function resolve(array &\$units) { foreach (\$units as &\$unit) { if (!isset(\$unit['target'])) continue; \$unit['current_hp'] -= max(1, \$unit['damage'] - \$unit['armor']); } } } PHP); file_put_contents("engine/MovementResolver.php", <<<PHP <?php class MovementResolver { public static function move(array &\$unit, int \$dir) { \$unit['x'] += \$dir * max(1, (int)\$unit['speed']); } } PHP); file_put_contents("engine/TurnResolver.php", <<<PHP <?php require_once __DIR__.'/MovementResolver.php'; require_once __DIR__.'/CombatResolver.php'; require_once __DIR__.'/TargetingLogic.php'; class TurnResolver { public static function resolve(PDO \$pdo, int \$matchId) { \$stmt = \$pdo->prepare("SELECT * FROM unit_instances WHERE match_id=?"); \$stmt->execute([\$matchId]); \$units = \$stmt->fetchAll(PDO::FETCH_ASSOC); foreach (\$units as &\$u) { \$dir = \$u['owner_id'] == 1 ? 1 : -1; MovementResolver::move(\$u, \$dir); } foreach (\$units as &\$u) { \$update = \$pdo->prepare( "UPDATE unit_instances SET x=?, current_hp=? WHERE id=?" ); \$update->execute([\$u['x'], \$u['current_hp'], \$u['id']]); } } } PHP); file_put_contents("engine/EventResolver.php", <<<PHP <?php class EventResolver { public static function roll(int \$turn) { if (!in_array(\$turn, [5,10,15,20])) return null; return ['type' => 'gold', 'value' => 100]; } } PHP); /* ========================= API ========================= */ file_put_contents("api/getGameState.php", <<<PHP <?php require '../data/db.php'; \$match = \$pdo->query("SELECT * FROM matches WHERE status='active' LIMIT 1") ->fetch(PDO::FETCH_ASSOC); if (!\$match) { echo json_encode(['match'=>null,'units'=>[]]); exit; } \$stmt = \$pdo->prepare("SELECT * FROM unit_instances WHERE match_id=?"); \$stmt->execute([\$match['id']]); \$units = \$stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['match'=>\$match,'units'=>\$units]); PHP); file_put_contents("api/submitTurn.php", <<<PHP <?php require '../data/db.php'; \$data = json_decode(file_get_contents('php://input'), true); \$stmt = \$pdo->prepare( "INSERT INTO turns (match_id, turn_number, player_id, turn_payload) VALUES (?, ?, ?, ?)" ); \$stmt->execute([ \$data['match_id'], \$data['turn_number'], \$data['player_id'], json_encode(\$data) ]); echo json_encode(['ok'=>true]); PHP); file_put_contents("api/resolveTurn.php", <<<PHP <?php require '../data/db.php'; require '../engine/TurnResolver.php'; \$matchId = (int)\$_GET['match']; TurnResolver::resolve(\$pdo, \$matchId); echo json_encode(['resolved'=>true]); PHP); /* ========================= FRONTEND ========================= */ file_put_contents("public/assets/js/game.js", <<<JS const board = document.getElementById('game-board'); function draw(units) { board.innerHTML = ''; for (let y = 0; y < 8; y++) { for (let x = 0; x < 12; x++) { const tile = document.createElement('div'); tile.className = 'tile'; const u = units.find(u => u.x == x && u.y == y); if (u) tile.textContent = u.owner_id == 1 ? 'A' : 'B'; board.appendChild(tile); } } } setInterval(() => { fetch('/api/getGameState.php') .then(r => r.json()) .then(d => draw(d.units || [])); }, 1000); JS); file_put_contents("public/game.php", <<<HTML <!DOCTYPE html> <html> <head> assets/css/style.css assets/js/game.jsscript> </head> <body> <div id="game-board"></div> </body> </html> HTML); echo "✅ UPGRADE 2 COMPLETE – ENGINE STABLE"; 