From 4698c65f426c3308a7f683eb9d6563864400381b Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 23 Feb 2026 00:18:45 +0000 Subject: [PATCH] Alpha v0.6 --- admin.php | 25 +- .../obj_planet_tempered_01_1771805362.png | Bin 0 -> 9659 bytes db/add_color_to_factions.php | 11 + db/migrate_orbital_control.sql | 9 + gm_console.php | 360 +++++++++++++---- index.php | 382 +++++++++++++++++- 6 files changed, 691 insertions(+), 96 deletions(-) create mode 100644 assets/images/celestial/obj_planet_tempered_01_1771805362.png create mode 100644 db/add_color_to_factions.php create mode 100644 db/migrate_orbital_control.sql diff --git a/admin.php b/admin.php index 68cc25d..51b5060 100644 --- a/admin.php +++ b/admin.php @@ -171,6 +171,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' $name = $_POST['name']; $slug = $_POST['slug']; $fa_icon = $_POST['fa_icon']; + $color = $_POST['color']; $image_url = null; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM factions WHERE id = ?"); @@ -186,11 +187,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' } } if ($id > 0) { - $stmt = $db->prepare("UPDATE factions SET name = ?, slug = ?, image_url = ?, fa_icon = ? WHERE id = ?"); - $stmt->execute([$name, $slug, $image_url, $fa_icon, $id]); + $stmt = $db->prepare("UPDATE factions SET name = ?, slug = ?, image_url = ?, fa_icon = ?, color = ? WHERE id = ?"); + $stmt->execute([$name, $slug, $image_url, $fa_icon, $color, $id]); } else { - $stmt = $db->prepare("INSERT INTO factions (name, slug, image_url, fa_icon) VALUES (?, ?, ?, ?)"); - $stmt->execute([$name, $slug, $image_url, $fa_icon]); + $stmt = $db->prepare("INSERT INTO factions (name, slug, image_url, fa_icon, color) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$name, $slug, $image_url, $fa_icon, $color]); } header("Location: admin.php?tab=factions&success=1"); exit; @@ -410,7 +411,7 @@ if ($tab === 'users') {

CONSOLE ADMIN

@@ -713,6 +714,10 @@ if ($tab === 'users') {
+
+ + +
@@ -728,17 +733,18 @@ if ($tab === 'users') {
- + + @@ -992,10 +998,11 @@ if ($tab === 'users') { document.getElementById('fac_id').value = data.id; document.getElementById('fac_name').value = data.name; document.getElementById('fac_slug').value = data.slug || ''; + document.getElementById('fac_color').value = data.color || '#808080'; document.getElementById('fac_fa_icon').value = data.fa_icon || ''; window.scrollTo(0,0); } - function resetFactionForm() { document.getElementById('factionForm').reset(); document.getElementById('fac_id').value = 0; } + function resetFactionForm() { document.getElementById('factionForm').reset(); document.getElementById('fac_id').value = 0; document.getElementById('fac_color').value = '#808080'; } function editResource(data) { document.getElementById('res_id').value = data.id; diff --git a/assets/images/celestial/obj_planet_tempered_01_1771805362.png b/assets/images/celestial/obj_planet_tempered_01_1771805362.png new file mode 100644 index 0000000000000000000000000000000000000000..10f69c03c5e14da575647895ea643bbc107392c5 GIT binary patch literal 9659 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 literal 0 HcmV?d00001 diff --git a/db/add_color_to_factions.php b/db/add_color_to_factions.php new file mode 100644 index 0000000..a4b2143 --- /dev/null +++ b/db/add_color_to_factions.php @@ -0,0 +1,11 @@ +exec("ALTER TABLE factions ADD COLUMN color VARCHAR(7) DEFAULT '#808080' AFTER fa_icon"); + echo "Successfully added 'color' column to 'factions' table.\n"; +} catch (PDOException $e) { + echo "Error adding column: " . $e->getMessage() . "\n"; +} + diff --git a/db/migrate_orbital_control.sql b/db/migrate_orbital_control.sql new file mode 100644 index 0000000..0de6a9d --- /dev/null +++ b/db/migrate_orbital_control.sql @@ -0,0 +1,9 @@ +-- Create table for orbital faction control +CREATE TABLE IF NOT EXISTS planet_faction_control ( + planet_id INT(11) NOT NULL, + faction_id INT(11) NOT NULL, + control_level INT(11) NOT NULL DEFAULT 0, + PRIMARY KEY (planet_id, faction_id), + CONSTRAINT fk_planet_faction_control_planet FOREIGN KEY (planet_id) REFERENCES planets(id) ON DELETE CASCADE, + CONSTRAINT fk_planet_faction_control_faction FOREIGN KEY (faction_id) REFERENCES factions(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/gm_console.php b/gm_console.php index 5dc6475..2244020 100644 --- a/gm_console.php +++ b/gm_console.php @@ -32,33 +32,96 @@ $factions_map = []; foreach($factions_db as $f) $factions_map[$f['id']] = $f; // Handle Planet/Slot Update if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'update_slot') { - $slot_id = (int)$_POST['slot_id']; - $galaxy_id = (int)$_POST['galaxy_id']; - $sector_id = (int)$_POST['sector_id']; - $slot_num = (int)$_POST['slot_num']; - $name = $_POST['name']; - $type = $_POST['type']; - $status = $_POST['status']; - $faction_id = (int)$_POST['faction_id']; - $orbital = (int)$_POST['orbital_control']; - $terrestrial = (int)$_POST['terrestrial_control']; + $slot_id = (int)($_POST['slot_id'] ?? 0); + $galaxy_id = (int)($_POST['galaxy_id'] ?? 1); + $sector_id = (int)($_POST['sector_id'] ?? 1); + $slot_num = (int)($_POST['slot_num'] ?? 0); + $name = $_POST['name'] ?? 'Inconnu'; + $type = $_POST['type'] ?? 'empty'; + + // 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; + $dominant_orbital_faction = (int)$fid; + } + } + + // Derive Status and Faction from Settlements + $status = 'sta_empty'; + $faction_id = null; + $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) { + if (empty($city_data['name'])) continue; + $num_cities++; + if (isset($city_data['controls']) && is_array($city_data['controls'])) { + foreach ($city_data['controls'] as $f_id => $lvl) { + $lvl = (int)$lvl; + 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); + + if (count($active_factions) > 1) { + $status = 'sta_hostile'; + } else { + if ($total_non_aucun >= ($num_cities * 100)) { + $status = 'sta_controlled'; + } else { + $status = 'sta_contested'; + } + } + } else if ($type !== 'empty') { + $status = 'sta_empty'; + $faction_id = null; + } if ($type === 'empty') { 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 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, $orbital, $terrestrial, $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, $orbital, $terrestrial]); + $stmt->execute([$galaxy_id, $sector_id, $slot_num, $name, $type, $status, $faction_id, $dominant_orbital_val, $avg_terrestrial_control]); $planet_id = $db->lastInsertId(); } + // Handle Orbital Faction Control + $db->prepare("DELETE FROM planet_faction_control WHERE planet_id = ?")->execute([$planet_id]); + foreach($orbital_controls as $fid => $lvl) { + if ((int)$lvl > 0) { + $db->prepare("INSERT INTO planet_faction_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'])) { @@ -67,20 +130,32 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' $c_id = (int)($city_data['id'] ?? 0); $c_name = $city_data['name']; - $c_type_id = (int)$city_data['type_id']; + $c_type_id = !empty($city_data['type_id']) ? (int)$city_data['type_id'] : null; if ($c_id > 0) { $stmt = $db->prepare("UPDATE cities SET name = ?, settlement_type_id = ? WHERE id = ? AND planet_id = ?"); $stmt->execute([$c_name, $c_type_id, $c_id, $planet_id]); - $sent_city_ids[] = $c_id; + $city_id = $c_id; } else { $stmt = $db->prepare("INSERT INTO cities (planet_id, name, settlement_type_id) VALUES (?, ?, ?)"); - $stmt->execute([$c_name, $c_type_id]); - $sent_city_ids[] = $db->lastInsertId(); + $stmt->execute([$planet_id, $c_name, $c_type_id]); + $city_id = $db->lastInsertId(); + } + $sent_city_ids[] = $city_id; + + // Handle Faction Control + $db->prepare("DELETE FROM city_faction_control WHERE city_id = ?")->execute([$city_id]); + if (isset($city_data['controls']) && is_array($city_data['controls'])) { + foreach ($city_data['controls'] as $fac_id => $control_lvl) { + $control_lvl = (int)$control_lvl; + if ($control_lvl > 0) { + $stmt = $db->prepare("INSERT INTO city_faction_control (city_id, faction_id, control_level) VALUES (?, ?, ?)"); + $stmt->execute([$city_id, (int)$fac_id, $control_lvl]); + } + } } } } - // Delete cities that were removed in the UI if ($planet_id > 0) { if (empty($sent_city_ids)) { $db->prepare("DELETE FROM cities WHERE planet_id = ?")->execute([$planet_id]); @@ -100,8 +175,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST[' if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'update_sector') { $sector_id = (int)$_POST['sector_id']; $galaxy_id = (int)$_POST['galaxy_id']; - $s_name = $_POST['sector_name']; - $s_status = $_POST['sector_status']; + $s_name = $_POST['sector_name'] ?? "Secteur $sector_id"; + $s_status = $_POST['sector_status'] ?? 'unexplored'; $stmt = $db->prepare("INSERT INTO sectors (id, galaxy_id, name, status) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE name = ?, status = ?"); $stmt->execute([$sector_id, $galaxy_id, $s_name, $s_status, $s_name, $s_status]); @@ -126,14 +201,42 @@ if ($view === 'sector') { $grid[$obj['slot']] = $obj; $planet_ids[] = $obj['id']; $grid[$obj['slot']]['cities'] = []; + $grid[$obj['slot']]['orbital_controls'] = []; } if (!empty($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); + foreach ($orb_controls_raw as $ocr) { + foreach ($grid as &$slot_data) { + if ($slot_data && $slot_data['id'] == $ocr['planet_id']) { + $slot_data['orbital_controls'][$ocr['faction_id']] = $ocr['control_level']; + } + } + } + + // Fetch Cities $stmt = $db->prepare("SELECT * FROM cities WHERE planet_id IN ($placeholders)"); $stmt->execute($planet_ids); - $all_cities = $stmt->fetchAll(); + $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']; + } + } + foreach ($all_cities as $city) { + $city['controls'] = $city_controls[$city['id']] ?? []; foreach ($grid as &$slot_data) { if ($slot_data && $slot_data['id'] == $city['planet_id']) { $slot_data['cities'][] = $city; @@ -141,7 +244,7 @@ if ($view === 'sector') { } } } - $stmt = $db->prepare("SELECT name FROM sectors WHERE id = ?"); + $stmt = $db->prepare("SELECT name, status FROM sectors WHERE id = ?"); $stmt->execute([$sector_id]); $sector_info = $stmt->fetch(); } else { @@ -263,19 +366,8 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { text-shadow: 0 0 4px rgba(0,0,0,0.8); } - .sector-grid { - display: grid; - grid-template-columns: repeat(6, 180px); - grid-template-rows: repeat(6, 180px); - gap: 15px; - } - .sector-card { background: rgba(10, 15, 30, 0.95); border: 1px solid #2d3545; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-decoration: none; color: #fff; transition: all 0.2s; width: 180px; height: 180px; box-sizing: border-box; } - .sector-card:hover { border-color: #88c0d0; background: #1a202c; transform: translateY(-3px); } - .mini-map { display: grid; grid-template-columns: repeat(6, 12px); gap: 4px; margin-bottom: 10px; background: #000; padding: 6px; } - .mini-dot { width: 12px; height: 12px; border-radius: 1px; } - #editModal, #sectorModal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 1000; align-items: center; justify-content: center; } - .modal-content { background: #1e293b; padding: 30px; border: 1px solid #88c0d0; width: 550px; max-height: 90vh; overflow-y: auto; border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); } + .modal-content { background: #1e293b; padding: 30px; border: 1px solid #88c0d0; width: 650px; max-height: 90vh; overflow-y: auto; border-radius: 8px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); } .form-group { margin-bottom: 20px; } .form-group label { display: block; font-size: 12px; color: #8c92a3; margin-bottom: 8px; font-weight: bold; } .form-group input, .form-group select, .form-group textarea { width: 100%; background: #0f172a; border: 1px solid #334155; color: #fff; padding: 10px; box-sizing: border-box; border-radius: 4px; font-size: 14px; } @@ -287,8 +379,28 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { .btn-remove-settlement { position: absolute; right: 8px; top: 8px; background: #bf616a; color: #fff; border: none; width: 22px; height: 22px; cursor: pointer; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: bold; } .btn-add-settlement { background: #81a1c1; color: #000; border: none; padding: 8px 15px; cursor: pointer; font-size: 11px; font-weight: bold; border-radius: 4px; width: 100%; margin-bottom: 15px; transition: 0.2s; } .btn-add-settlement:hover { background: #88c0d0; } - .compact-row { display: flex; gap: 15px; align-items: flex-end; } + .compact-row { display: flex; gap: 15px; align-items: flex-end; margin-bottom: 15px; } .compact-row .form-group { margin-bottom: 0; } + + .control-bars { margin-top: 15px; display: flex; flex-direction: column; gap: 10px; padding-top: 10px; border-top: 1px dashed #334155; } + .control-bar-row { display: flex; align-items: center; gap: 10px; } + .control-bar-label { width: 100px; font-size: 11px; color: #eceff4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 5px; } + .control-bar-input { flex: 1; -webkit-appearance: none; height: 8px; background: #0f172a; border-radius: 4px; outline: none; } + .control-bar-input::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; background: #88c0d0; border-radius: 50%; cursor: pointer; } + .control-bar-value { width: 35px; text-align: right; font-size: 11px; color: #88c0d0; font-weight: bold; } + + .sector-grid { + display: grid; + grid-template-columns: repeat(6, 180px); + grid-template-rows: repeat(6, 180px); + gap: 15px; + } + .sector-card { background: rgba(10, 15, 30, 0.95); border: 1px solid #2d3545; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-decoration: none; color: #fff; transition: all 0.2s; width: 180px; height: 180px; box-sizing: border-box; } + .sector-card:hover { border-color: #88c0d0; background: #1a202c; transform: translateY(-3px); } + .mini-map { display: grid; grid-template-columns: repeat(6, 12px); gap: 4px; margin-bottom: 10px; background: #000; padding: 6px; } + .mini-dot { width: 12px; height: 12px; border-radius: 1px; } + + .faction-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; } @@ -302,7 +414,7 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { -
Connecté en tant que MJ: @
+
Connecté en tant que MJ: @
@@ -347,7 +459,7 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { - +
@@ -407,45 +519,23 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { - -
-
- - -
-
- - + + +
+ +
+
- +
-
-
- - -
-
- - -
-
- @@ -485,6 +575,40 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) { - + \ No newline at end of file diff --git a/index.php b/index.php index 699e3b5..26fa3e8 100644 --- a/index.php +++ b/index.php @@ -55,17 +55,46 @@ if ($view === 'sector') { $grid[$obj['slot']] = $obj; $planet_ids[] = $obj['id']; $grid[$obj['slot']]['cities'] = []; + $grid[$obj['slot']]['orbital_controls'] = []; } if (!empty($planet_ids)) { $placeholders = implode(',', array_fill(0, count($planet_ids), '?')); + + // Fetch Orbital Controls + $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); + foreach ($orb_controls_raw as $ocr) { + foreach ($grid as &$slot_data) { + if ($slot_data && $slot_data['id'] == $ocr['planet_id']) { + $slot_data['orbital_controls'][$ocr['faction_id']] = $ocr['control_level']; + } + } + } + + // Fetch Cities $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); - $all_cities = $stmt->fetchAll(); + $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']; + } + } + foreach ($all_cities as $city) { + $city['controls'] = $city_controls[$city['id']] ?? []; foreach ($grid as &$slot_data) { if ($slot_data && $slot_data['id'] == $city['planet_id']) { $slot_data['cities'][] = $city; @@ -132,7 +161,7 @@ function getStatusColor($status, $statuses_map) { gap: 10px; padding: 15px; background: rgba(10, 15, 30, 0.5); - border: 1px solid #2d3545; + border: 1px solid #2d3545; box-shadow: 0 0 30px rgba(0,0,0,0.5); } .slot { @@ -229,7 +258,138 @@ function getStatusColor($status, $statuses_map) { .mini-map { display: grid; grid-template-columns: repeat(6, 12px); gap: 4px; margin-bottom: 15px; background: #000; padding: 6px; border-radius: 2px; } .mini-dot { width: 12px; height: 12px; border-radius: 1px; } - .tooltip-box { display: none; position: absolute; top: -10px; left: 105%; width: 220px; background: #1e293b; border: 1px solid #88c0d0; padding: 15px; z-index: 100; pointer-events: none; box-shadow: 10px 10px 20px rgba(0,0,0,0.5); } + /* MODAL STYLES */ + .modal-overlay { + display: none; + position: fixed; + top: 0; left: 0; + width: 100%; height: 100%; + background: rgba(0, 0, 0, 0.85); + backdrop-filter: blur(5px); + z-index: 2000; + align-items: center; + justify-content: center; + } + .modal-container { + background: #0f172a; + border: 1px solid #1e293b; + border-radius: 12px; + width: 600px; + max-height: 90vh; + overflow-y: auto; + position: relative; + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); + } + .modal-header { + padding: 20px; + border-bottom: 1px solid #1e293b; + display: flex; + justify-content: space-between; + align-items: center; + background: rgba(30, 41, 59, 0.5); + } + .modal-header h2 { margin: 0; font-size: 20px; color: #88c0d0; } + .modal-close { + background: none; border: none; color: #8c92a3; font-size: 24px; cursor: pointer; + transition: color 0.2s; + } + .modal-close:hover { color: #fff; } + .modal-body { padding: 25px; } + .planet-hero { + display: flex; + gap: 25px; + margin-bottom: 25px; + align-items: center; + } + .planet-preview-img { + width: 120px; + height: 120px; + object-fit: contain; + filter: drop-shadow(0 0 15px rgba(136, 192, 208, 0.3)); + } + .planet-meta { flex: 1; } + .planet-status-badge { + display: inline-block; + padding: 4px 10px; + border-radius: 20px; + font-size: 11px; + font-weight: bold; + text-transform: uppercase; + margin-bottom: 10px; + } + .planet-description { + font-size: 13px; + color: #94a3b8; + line-height: 1.6; + margin-bottom: 15px; + } + + .control-section { + margin-bottom: 25px; + padding: 15px; + background: rgba(30, 41, 59, 0.3); + border-radius: 8px; + border: 1px solid rgba(136, 192, 208, 0.1); + } + .control-title { + font-size: 12px; + font-weight: bold; + color: #88c0d0; + text-transform: uppercase; + margin-bottom: 15px; + display: flex; + align-items: center; + gap: 10px; + } + .control-title i { font-size: 14px; } + + /* Multi-colored Progress Bar */ + .multi-control-bar { + height: 14px; + background: #1e293b; + border-radius: 7px; + overflow: hidden; + display: flex; + margin-bottom: 10px; + box-shadow: inset 0 2px 4px rgba(0,0,0,0.3); + } + .control-segment { + height: 100%; + transition: width 0.3s ease; + position: relative; + } + .control-legend { + display: flex; + flex-wrap: wrap; + gap: 15px; + margin-top: 10px; + } + .legend-tag { + display: flex; + align-items: center; + gap: 6px; + font-size: 11px; + color: #cbd5e1; + } + .legend-color { width: 10px; height: 10px; border-radius: 2px; } + + .settlement-card { + background: rgba(15, 23, 42, 0.6); + border: 1px solid #1e293b; + border-radius: 8px; + padding: 15px; + margin-bottom: 15px; + } + .settlement-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; + } + .settlement-name { font-weight: bold; font-size: 14px; color: #fff; } + .settlement-type { font-size: 10px; color: #8c92a3; text-transform: uppercase; } + + .tooltip-box { display: none; position: absolute; top: -10px; left: 105%; width: 240px; background: #1e293b; border: 1px solid #88c0d0; padding: 15px; z-index: 100; pointer-events: none; box-shadow: 10px 10px 20px rgba(0,0,0,0.5); } .slot:hover .tooltip-box { display: block; } .tooltip-title { font-size: 14px; color: #88c0d0; font-weight: bold; border-bottom: 1px solid #334155; padding-bottom: 8px; margin-bottom: 8px; } .tooltip-desc { font-size: 11px; color: #d8dee9; line-height: 1.4; font-style: italic; margin-bottom: 10px; } @@ -239,8 +399,12 @@ function getStatusColor($status, $statuses_map) { .mod-malus { background: rgba(191, 97, 106, 0.15); color: #bf616a; border: 1px solid rgba(191, 97, 106, 0.3); } .mod-item i { font-size: 12px; } - .settlement-title { font-size: 10px; color: #ebcb8b; font-weight: bold; border-top: 1px solid #334155; margin-top: 8px; padding-top: 5px; } - .settlement-item-tool { font-size: 9px; color: #fff; margin-bottom: 3px; } + .settlement-title { font-size: 10px; color: #ebcb8b; font-weight: bold; border-top: 1px solid #334155; margin-top: 8px; padding-top: 5px; margin-bottom: 5px; } + .settlement-item-tool { font-size: 9px; color: #fff; margin-bottom: 10px; background: rgba(0,0,0,0.2); padding: 5px; border-radius: 3px; } + .control-bars-mini { margin-top: 5px; display: flex; flex-direction: column; gap: 3px; } + .control-bar-mini { height: 4px; background: #000; border-radius: 2px; overflow: hidden; display: flex; } + .control-fill { height: 100%; } + .control-label-mini { font-size: 7px; color: #8c92a3; display: flex; justify-content: space-between; margin-bottom: 1px; } .legend { margin-top: 20px; background: rgba(10, 15, 30, 0.95); border: 1px solid #2d3545; padding: 10px 20px; display: flex; gap: 15px; font-size: 10px; flex-wrap: wrap; max-width: 1000px; justify-content: center; } .legend-item { display: flex; align-items: center; gap: 5px; } @@ -299,9 +463,13 @@ function getStatusColor($status, $statuses_map) {
-
+ +
- @@ -309,16 +477,60 @@ function getStatusColor($status, $statuses_map) {
-
Faction:
+
Faction:
+ + +
Contrôle Orbital:
+
+
+ $lvl): + if ($lvl <= 0) continue; + $fName = $factions_map[$fid]['name'] ?? 'Inconnue'; + $fColor = $factions_map[$fid]['color'] ?? '#88c0d0'; + ?> +
+ + % +
+
+
+
+ +
+
+ +
Établissements:
- - () +
+ + +
+ + +
+ $lvl): + if ($lvl <= 0) continue; + $fName = $factions_map[$fid]['name'] ?? 'Inconnue'; + $fColor = $factions_map[$fid]['color'] ?? '#88c0d0'; + ?> +
+ + % +
+
+
+
+ +
+
@@ -341,7 +553,7 @@ function getStatusColor($status, $statuses_map) { - +
@@ -402,13 +614,157 @@ function getStatusColor($status, $statuses_map) {
+ + + + + \ No newline at end of file
VisuelNomSlugActions
CouleurVisuelNomSlugActions
- + - +