From 8b5649440062e49c00f0c538870b74f9b71b7cf0 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 25 Feb 2026 21:39:10 +0000 Subject: [PATCH] Alpha v1.0 --- admin.php | 15 +- gm_console.php | 99 ++--- index.php | 1097 +++++++++++++++++++++++++----------------------- 3 files changed, 625 insertions(+), 586 deletions(-) diff --git a/admin.php b/admin.php index 3027e3c..bfbddf3 100644 --- a/admin.php +++ b/admin.php @@ -401,6 +401,8 @@ if ($tab === 'users') { $lb['items'] = $stmt_i->fetchAll(); } unset($lb); +} elseif ($tab === "project_logs") { + $project_logs_list = $db->query("SELECT * FROM project_logs ORDER BY created_at DESC")->fetchAll(); } ?> @@ -560,7 +562,7 @@ if ($tab === 'users') {
- +
@@ -904,6 +906,17 @@ if ($tab === 'users') { + +
+
+ + +
+
+ + +
+
diff --git a/gm_console.php b/gm_console.php index 5ea71fc..ef19e62 100644 --- a/gm_console.php +++ b/gm_console.php @@ -41,21 +41,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' $type = $_POST['type'] ?? 'empty'; $manual_status = $_POST['manual_status'] ?? ''; - // Orbital control + // Orbital control is now detailed by faction $orbital_controls = $_POST['orbital_controls'] ?? []; $dominant_orbital_val = 0; + $dominant_orbital_faction = null; foreach($orbital_controls as $fid => $val) { if ((int)$val > $dominant_orbital_val && (int)$fid != 1) { // Not "Aucune" $dominant_orbital_val = (int)$val; - } - } - - // Terrestrial control - $terrestrial_controls = $_POST['terrestrial_controls'] ?? []; - $dominant_terrestrial_val = 0; - foreach($terrestrial_controls as $fid => $val) { - if ((int)$val > $dominant_terrestrial_val && (int)$fid != 1) { - $dominant_terrestrial_val = (int)$val; + $dominant_orbital_faction = (int)$fid; } } @@ -65,6 +58,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' $total_non_aucun = 0; $active_factions = []; $num_cities = 0; + $avg_terrestrial_control = 0; if (isset($_POST['cities']) && is_array($_POST['cities'])) { foreach ($_POST['cities'] as $city_data) { @@ -76,12 +70,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' if ($lvl > 0 && $f_id != 1) { // 1 is "Aucune" $total_non_aucun += $lvl; $active_factions[$f_id] = ($active_factions[$f_id] ?? 0) + $lvl; + $avg_terrestrial_control += $lvl; } } } } } + if ($num_cities > 0) { + $avg_terrestrial_control = round($avg_terrestrial_control / $num_cities); + } + if ($num_cities > 0 && $total_non_aucun > 0) { arsort($active_factions); $faction_id = (int)key($active_factions); @@ -109,17 +108,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' if ($slot_id > 0) { $db->prepare("DELETE FROM cities WHERE planet_id = ?")->execute([$slot_id]); $db->prepare("DELETE FROM planet_faction_control WHERE planet_id = ?")->execute([$slot_id]); - $db->prepare("DELETE FROM planet_terrestrial_control WHERE planet_id = ?")->execute([$slot_id]); $db->prepare("DELETE FROM planets WHERE id = ?")->execute([$slot_id]); } } else { if ($slot_id > 0) { $stmt = $db->prepare("UPDATE planets SET name = ?, type = ?, status = ?, faction_id = ?, orbital_control = ?, terrestrial_control = ? WHERE id = ?"); - $stmt->execute([$name, $type, $status, $faction_id, $dominant_orbital_val, $dominant_terrestrial_val, $slot_id]); + $stmt->execute([$name, $type, $status, $faction_id, $dominant_orbital_val, $avg_terrestrial_control, $slot_id]); $planet_id = $slot_id; } else { $stmt = $db->prepare("INSERT INTO planets (galaxy_id, sector_id, slot, name, type, status, faction_id, orbital_control, terrestrial_control) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); - $stmt->execute([$galaxy_id, $sector_id, $slot_num, $name, $type, $status, $faction_id, $dominant_orbital_val, $dominant_terrestrial_val]); + $stmt->execute([$galaxy_id, $sector_id, $slot_num, $name, $type, $status, $faction_id, $dominant_orbital_val, $avg_terrestrial_control]); $planet_id = $db->lastInsertId(); } @@ -131,14 +129,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' } } - // Handle Terrestrial Faction Control - $db->prepare("DELETE FROM planet_terrestrial_control WHERE planet_id = ?")->execute([$planet_id]); - foreach($terrestrial_controls as $fid => $lvl) { - if ((int)$lvl > 0) { - $db->prepare("INSERT INTO planet_terrestrial_control (planet_id, faction_id, control_level) VALUES (?, ?, ?)")->execute([$planet_id, (int)$fid, (int)$lvl]); - } - } - // Handle Multiple Settlements $sent_city_ids = []; if (isset($_POST['cities']) && is_array($_POST['cities'])) { @@ -219,13 +209,11 @@ if ($view === 'sector') { $planet_ids[] = $obj['id']; $grid[$obj['slot']]['cities'] = []; $grid[$obj['slot']]['orbital_controls'] = []; - $grid[$obj['slot']]['terrestrial_controls'] = []; } if (!empty($planet_ids)) { - $placeholders = implode(',', array_fill(0, count($planet_ids), '?')); - // Fetch Orbital Controls + $placeholders = implode(',', array_fill(0, count($planet_ids), '?')); $stmt = $db->prepare("SELECT * FROM planet_faction_control WHERE planet_id IN ($placeholders)"); $stmt->execute($planet_ids); $orb_controls_raw = $stmt->fetchAll(PDO::FETCH_ASSOC); @@ -237,20 +225,8 @@ if ($view === 'sector') { } } - // Fetch Terrestrial Controls - $stmt = $db->prepare("SELECT * FROM planet_terrestrial_control WHERE planet_id IN ($placeholders)"); - $stmt->execute($planet_ids); - $terr_controls_raw = $stmt->fetchAll(PDO::FETCH_ASSOC); - foreach ($terr_controls_raw as $tcr) { - foreach ($grid as &$slot_data) { - if ($slot_data && $slot_data['id'] == $tcr['planet_id']) { - $slot_data['terrestrial_controls'][$tcr['faction_id']] = $tcr['control_level']; - } - } - } - // Fetch Cities - unset($slot_data); + unset($slot_data); $stmt = $db->prepare("SELECT * FROM cities WHERE planet_id IN ($placeholders)"); $stmt->execute($planet_ids); $all_cities = $stmt->fetchAll(PDO::FETCH_ASSOC); @@ -576,15 +552,7 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
-
- -
- -
-
- -
@@ -635,19 +603,16 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { const allFactions = ; const AUCUN_ID = 1; // ID for "Aucune" faction - function initSlidersGeneric(containerId, data = null, prefix = 'orbital') { - const container = document.getElementById(containerId); + function initOrbitalSliders(orbitalData = null) { + const container = document.getElementById('orbitalControlContainer'); container.innerHTML = ''; - const hasExisting = data && Object.keys(data).length > 0; - const className = prefix + '-slider'; - const displayPrefix = 'val_' + prefix; - const inputName = prefix + '_controls'; - + const hasExisting = orbitalData && Object.keys(orbitalData).length > 0; + allFactions.forEach(f => { let val = 0; if (hasExisting) { - val = data[f.id] !== undefined ? parseInt(data[f.id]) : 0; + val = orbitalData[f.id] !== undefined ? parseInt(orbitalData[f.id]) : 0; } else { val = (f.id == AUCUN_ID ? 100 : 0); } @@ -659,12 +624,12 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { ${f.name}
- -
${val}%
+ oninput="handleSliderChangeGeneric('orbital-slider', ${f.id}, this.value)"> +
${val}%
`; container.appendChild(div); }); @@ -728,7 +693,7 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { container.appendChild(div); } - function handleSliderChangeGeneric(className, changedFid, newVal, rowIdx = null, displayPrefix = null) { + function handleSliderChangeGeneric(className, changedFid, newVal, rowIdx = null) { newVal = parseInt(newVal); const sliders = Array.from(document.querySelectorAll(`.${className}`)); @@ -783,9 +748,8 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { } sliders.forEach(s => { - const dId = displayPrefix ? `${displayPrefix}_${s.dataset.factionId}` : `val_${rowIdx}_${s.dataset.factionId}`; - const el = document.getElementById(dId); - if (el) el.innerText = s.value + '%'; + const displayId = rowIdx !== null ? `val_${rowIdx}_${s.dataset.factionId}` : `val_orbital_${s.dataset.factionId}`; + document.getElementById(displayId).innerText = s.value + '%'; }); } @@ -795,16 +759,13 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { const orbWrapper = document.getElementById('orbitalSectionWrapper'); const terrWrapper = document.getElementById('terrestrialSectionWrapper'); - const setlWrapper = document.getElementById("settlementsSectionWrapper"); orbWrapper.style.display = (typeInfo.orbital_control_enabled == 1) ? 'block' : 'none'; terrWrapper.style.display = (typeInfo.terrestrial_control_enabled == 1) ? 'block' : 'none'; - setlWrapper.style.display = (typeInfo.terrestrial_control_enabled == 1) ? "block" : "none"; // Disable inputs in hidden sections to prevent them from being submitted orbWrapper.querySelectorAll('input, select, textarea').forEach(el => el.disabled = (typeInfo.orbital_control_enabled != 1)); - terrWrapper.querySelectorAll('input, select, textarea').forEach(el => el.disabled = (typeInfo.terrestrial_control_enabled != 1)); - setlWrapper.querySelectorAll("input, select, textarea, button:not(.btn-cancel):not(.btn-save)").forEach(el => el.disabled = (typeInfo.terrestrial_control_enabled != 1)); + terrWrapper.querySelectorAll('input, select, textarea, button:not(.btn-cancel):not(.btn-save)').forEach(el => el.disabled = (typeInfo.terrestrial_control_enabled != 1)); } function editSlot(num, data) { @@ -817,9 +778,8 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { document.getElementById('form_type').value = data.type; document.getElementById('form_status').value = data.status; - // Load sliders - initSlidersGeneric('orbitalControlContainer', data.orbital_controls, 'orbital'); - initSlidersGeneric('terrestrialControlContainer', data.terrestrial_controls, 'terrestrial'); + // Load orbital sliders + initOrbitalSliders(data.orbital_controls); // Load settlements document.getElementById('settlementsContainer').innerHTML = ''; @@ -831,8 +791,7 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { document.getElementById('form_name').value = ''; document.getElementById('form_type').value = 'empty'; document.getElementById('form_status').value = ''; - initSlidersGeneric('orbitalControlContainer', null, 'orbital'); - initSlidersGeneric('terrestrialControlContainer', null, 'terrestrial'); + initOrbitalSliders(null); document.getElementById('settlementsContainer').innerHTML = ''; } diff --git a/index.php b/index.php index cefa4d2..9be12e8 100644 --- a/index.php +++ b/index.php @@ -1,32 +1,46 @@ query("SELECT * FROM celestial_object_statuses ORDER BY id")->fetchAll(); -$statuses_map = []; foreach($statuses_db as $s) $statuses_map[$s['id']] = $s; - -$object_types_db = $db->query("SELECT * FROM celestial_object_types ORDER BY id")->fetchAll(); -$object_types_map = []; foreach($object_types_db as $ot) $object_types_map[$ot['slug']] = $ot; - -$factions_db = $db->query("SELECT * FROM factions ORDER BY id")->fetchAll(); -$factions_map = []; foreach($factions_db as $f) $factions_map[$f['id']] = $f; - -function getStatusColor($status_id, $map) { - return $map[$status_id]['color'] ?? '#fff'; +$user_role = 'user'; +if (isset($_SESSION['user_id'])) { + $stmt = $db->prepare("SELECT role FROM users WHERE id = ?"); + $stmt->execute([$_SESSION['user_id']]); + $u_data = $stmt->fetch(); + $user_role = $u_data['role'] ?? 'user'; } -$sector_data = []; -$grid = array_fill(1, $grid_size, null); -$active_sectors = $db->query("SELECT DISTINCT sector_id FROM planets WHERE galaxy_id = $galaxy_id")->fetchAll(PDO::FETCH_COLUMN); +$view = isset($_GET['view']) ? $_GET['view'] : 'sector'; +$galaxy_id = isset($_GET['galaxy_id']) ? (int)$_GET['galaxy_id'] : 1; +$sector_id = isset($_GET['sector_id']) ? (int)$_GET['sector_id'] : 1; + +// Fetch Dynamic Types, Statuses and Factions +$object_types_db = $db->query("SELECT * FROM celestial_object_types")->fetchAll(PDO::FETCH_ASSOC); +$statuses_db = $db->query("SELECT * FROM celestial_object_statuses")->fetchAll(PDO::FETCH_ASSOC); +$factions_db = $db->query("SELECT * FROM factions")->fetchAll(PDO::FETCH_ASSOC); + +$object_types_map = []; +foreach($object_types_db as $ot) { + // Get modifiers for this type + $stmt = $db->prepare("SELECT m.* FROM modifiers m JOIN celestial_object_type_modifiers cotm ON m.id = cotm.modifier_id WHERE cotm.celestial_object_type_id = ?"); + $stmt->execute([$ot['id']]); + $ot['modifiers'] = $stmt->fetchAll(PDO::FETCH_ASSOC); + $object_types_map[$ot['slug']] = $ot; +} + +$statuses_map = []; foreach($statuses_db as $s) $statuses_map[$s['slug']] = $s; +$factions_map = []; foreach($factions_db as $f) $factions_map[$f['id']] = $f; + +// Grid size: 6x6 = 36 slots per sector +$grid_size = 36; + +// Mock Resources +$header_resources = $db->query("SELECT * FROM game_resources WHERE show_in_header = 1 ORDER BY CASE WHEN name = 'Crédits' THEN 1 WHEN name = 'Materials' THEN 2 WHEN name = 'Energie' THEN 3 WHEN name = 'Données' THEN 4 ELSE 5 END ASC, name ASC")->fetchAll(PDO::FETCH_ASSOC); +$resources = []; foreach($header_resources as $hr) { $resources[$hr["name"]] = ["val" => "0", "prod" => "", "icon" => $hr["icon"] ?: "fa-gem", "image" => $hr["image_url"]]; } if ($view === 'sector') { - $stmt = $db->prepare("SELECT p.*, cot.orbital_control_enabled, cot.terrestrial_control_enabled FROM planets p LEFT JOIN celestial_object_types cot ON p.type = cot.slug WHERE galaxy_id = ? AND sector_id = ? AND slot BETWEEN 1 AND ?"); + $stmt = $db->prepare("SELECT * FROM planets WHERE galaxy_id = ? AND sector_id = ? AND slot BETWEEN 1 AND ?"); $stmt->execute([$galaxy_id, $sector_id, $grid_size]); $objects_raw = $stmt->fetchAll(); @@ -55,521 +69,520 @@ if ($view === 'sector') { } } - // Fetch Terrestrial Controls - $stmt = $db->prepare("SELECT * FROM planet_terrestrial_control WHERE planet_id IN ($placeholders)"); - $stmt->execute($planet_ids); - $terr_controls_raw = $stmt->fetchAll(PDO::FETCH_ASSOC); - foreach ($terr_controls_raw as $tcr) { - foreach ($grid as &$slot_data) { - if ($slot_data && $slot_data['id'] == $tcr['planet_id']) { - $slot_data['terrestrial_controls'][$tcr['faction_id']] = $tcr['control_level']; - } - } - } - // Fetch Cities - unset($slot_data); + unset($slot_data); $stmt = $db->prepare("SELECT c.*, st.name as type_name FROM cities c LEFT JOIN settlement_types st ON c.settlement_type_id = st.id WHERE c.planet_id IN ($placeholders)"); $stmt->execute($planet_ids); - $cities_raw = $stmt->fetchAll(PDO::FETCH_ASSOC); - foreach ($cities_raw as $city) { + $all_cities = $stmt->fetchAll(PDO::FETCH_ASSOC); + + $city_ids = array_column($all_cities, 'id'); + $city_controls = []; + if (!empty($city_ids)) { + $c_placeholders = implode(',', array_fill(0, count($city_ids), '?')); + $c_stmt = $db->prepare("SELECT * FROM city_faction_control WHERE city_id IN ($c_placeholders)"); + $c_stmt->execute($city_ids); + $controls_raw = $c_stmt->fetchAll(PDO::FETCH_ASSOC); + foreach ($controls_raw as $cr) { + $city_controls[$cr['city_id']][$cr['faction_id']] = $cr['control_level']; + } + } + + $planet_terrestrial_agg = []; + foreach ($all_cities as $city) { + $pid = $city['planet_id']; + $city['controls'] = $city_controls[$city['id']] ?? []; + foreach ($city['controls'] as $fid => $lvl) { + $planet_terrestrial_agg[$pid][$fid] = ($planet_terrestrial_agg[$pid][$fid] ?? 0) + $lvl; + } + foreach ($grid as &$slot_data) { - if ($slot_data && $slot_data['id'] == $city['planet_id']) { + if ($slot_data && $slot_data['id'] == $pid) { $slot_data['cities'][] = $city; } } } + + // Calculate average terrestrial control per faction + foreach ($grid as &$slot_data) { + if ($slot_data && !empty($slot_data['cities'])) { + $num_cities = count($slot_data['cities']); + $pid = $slot_data['id']; + if (isset($planet_terrestrial_agg[$pid])) { + foreach ($planet_terrestrial_agg[$pid] as $fid => $total_lvl) { + $slot_data['terrestrial_controls'][$fid] = round($total_lvl / $num_cities); + } + } + } + } } + unset($slot_data); + + $stmt = $db->prepare("SELECT name FROM sectors WHERE id = ?"); + $stmt->execute([$sector_id]); + $sector_info = $stmt->fetch(); + $sector_display_name = $sector_info['name'] ?? "Secteur $sector_id"; + $page_title = "$sector_display_name [G$galaxy_id]"; } else { - $all_planets = $db->query("SELECT sector_id, slot, status FROM planets WHERE galaxy_id = $galaxy_id")->fetchAll(PDO::FETCH_ASSOC); - foreach($all_planets as $p) { $sector_data[$p['sector_id']][$p['slot']] = $p; } + $stmt = $db->prepare("SELECT sector_id, slot, status, type FROM planets WHERE galaxy_id = ? ORDER BY sector_id, slot ASC"); + $stmt->execute([$galaxy_id]); + $all_planets = $stmt->fetchAll(); + $sector_data = []; + $active_sectors = []; + foreach ($all_planets as $p) { + $sector_data[$p['sector_id']][$p['slot']] = ['status' => $p['status'], 'type' => $p['type']]; + if (!in_array($p['sector_id'], $active_sectors)) { $active_sectors[] = (int)$p['sector_id']; } + } + $page_title = "Galaxie $galaxy_id"; } -// SEO Tags -$page_title = "Galaxy Map - Flatlogic Game"; -if ($view === 'sector') $page_title = "Sector $sector_id - Galaxy Map"; -$page_desc = "Explore the galaxy, monitor faction control and planetary settlements in this deep space simulation."; - +function getStatusColor($status, $statuses_map) { + return $statuses_map[$status]['color'] ?? 'rgba(255,255,255,0.05)'; +} ?> - <?php echo $page_title; ?> - - - - - - - - + Nexus - <?php echo $page_title; ?> + + -
-
- -
- -
- - -
- +
+
+ -
- - +
+ $res): ?> +
+
+ + ?v="> + + "> + +
+
+
+
+ + +
+
+
+
-
-