742 lines
30 KiB
PHP
742 lines
30 KiB
PHP
<?php
|
|
require_once 'db/config.php';
|
|
|
|
$db = db();
|
|
$view = $_GET['view'] ?? 'galaxy';
|
|
$galaxy_id = (int)($_GET['galaxy_id'] ?? 1);
|
|
$sector_id = (int)($_GET['sector_id'] ?? 1);
|
|
$grid_size = 36; // 6x6
|
|
|
|
// Fetch metadata
|
|
$statuses_db = $db->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';
|
|
}
|
|
|
|
$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);
|
|
|
|
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->execute([$galaxy_id, $sector_id, $grid_size]);
|
|
$objects_raw = $stmt->fetchAll();
|
|
|
|
$grid = array_fill(1, $grid_size, null);
|
|
$planet_ids = [];
|
|
foreach ($objects_raw as $obj) {
|
|
$grid[$obj['slot']] = $obj;
|
|
$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
|
|
$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 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);
|
|
$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) {
|
|
foreach ($grid as &$slot_data) {
|
|
if ($slot_data && $slot_data['id'] == $city['planet_id']) {
|
|
$slot_data['cities'][] = $city;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} 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; }
|
|
}
|
|
|
|
// 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.";
|
|
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title><?php echo $page_title; ?></title>
|
|
<meta name="description" content="<?php echo $page_desc; ?>">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<!-- Platform managed meta tags for images -->
|
|
<meta property="og:image" content="<?php echo $_SERVER['PROJECT_IMAGE_URL'] ?? ''; ?>">
|
|
<meta name="twitter:image" content="<?php echo $_SERVER['PROJECT_IMAGE_URL'] ?? ''; ?>">
|
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Rajdhani:wght@300;500;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--bg-dark: #0b0e14;
|
|
--bg-card: #1b212c;
|
|
--accent-blue: #88c0d0;
|
|
--accent-green: #a3be8c;
|
|
--text-main: #e5e9f0;
|
|
--text-dim: #949fb1;
|
|
--border: rgba(136, 192, 208, 0.2);
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
background-color: var(--bg-dark);
|
|
color: var(--text-main);
|
|
font-family: 'Rajdhani', sans-serif;
|
|
background-image:
|
|
radial-gradient(circle at 20% 30%, rgba(136, 192, 208, 0.05) 0%, transparent 40%),
|
|
radial-gradient(circle at 80% 70%, rgba(163, 190, 140, 0.05) 0%, transparent 40%);
|
|
min-height: 100vh;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.layout {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
header {
|
|
padding: 20px 40px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
border-bottom: 1px solid var(--border);
|
|
background: rgba(11, 14, 20, 0.8);
|
|
backdrop-filter: blur(10px);
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
}
|
|
|
|
.logo {
|
|
font-family: 'Orbitron', sans-serif;
|
|
font-size: 24px;
|
|
font-weight: 700;
|
|
letter-spacing: 4px;
|
|
color: var(--accent-blue);
|
|
text-decoration: none;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.view-container {
|
|
flex: 1;
|
|
padding: 40px;
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.navigation-path {
|
|
margin-bottom: 30px;
|
|
font-size: 14px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 2px;
|
|
color: var(--text-dim);
|
|
}
|
|
|
|
.navigation-path a {
|
|
color: var(--accent-blue);
|
|
text-decoration: none;
|
|
transition: color 0.3s;
|
|
}
|
|
|
|
.navigation-path a:hover { color: #fff; }
|
|
|
|
/* GRID STYLES */
|
|
.sector-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(6, 1fr);
|
|
gap: 15px;
|
|
width: 100%;
|
|
perspective: 1000px;
|
|
}
|
|
|
|
.slot {
|
|
aspect-ratio: 1/1;
|
|
background: var(--bg-card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
|
overflow: visible;
|
|
}
|
|
|
|
.slot:hover {
|
|
background: rgba(136, 192, 208, 0.1);
|
|
border-color: var(--accent-blue);
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 10px 20px rgba(0,0,0,0.5), 0 0 15px rgba(136, 192, 208, 0.2);
|
|
z-index: 10;
|
|
}
|
|
|
|
.object-icon {
|
|
font-size: 32px;
|
|
margin-bottom: 8px;
|
|
filter: drop-shadow(0 0 10px rgba(0,0,0,0.5));
|
|
}
|
|
|
|
.object-image {
|
|
width: 60px;
|
|
height: 60px;
|
|
object-fit: contain;
|
|
filter: drop-shadow(0 0 10px rgba(0,0,0,0.8));
|
|
}
|
|
|
|
.object-name {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
text-align: center;
|
|
padding: 0 5px;
|
|
}
|
|
|
|
.slot-coord {
|
|
position: absolute;
|
|
top: 5px;
|
|
left: 8px;
|
|
font-size: 9px;
|
|
color: #4c566a;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.slot-indicator {
|
|
position: absolute;
|
|
top: 8px;
|
|
right: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-end;
|
|
gap: 6px;
|
|
z-index: 5;
|
|
}
|
|
|
|
.indicator-dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.indicator-icon {
|
|
font-size: 14px;
|
|
color: var(--accent-blue);
|
|
filter: drop-shadow(0 0 3px rgba(136, 192, 208, 0.5));
|
|
}
|
|
|
|
.faction-mini-icon {
|
|
width: 18px;
|
|
height: 18px;
|
|
border-radius: 50%;
|
|
overflow: hidden;
|
|
border: 1px solid rgba(255,255,255,0.2);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: rgba(0,0,0,0.3);
|
|
}
|
|
|
|
/* TOOLTIP / HOVER INFO */
|
|
.slot-overlay {
|
|
position: absolute;
|
|
bottom: 0; left: 0; width: 100%;
|
|
background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);
|
|
padding: 20px 10px 10px;
|
|
border-bottom-left-radius: 12px;
|
|
border-bottom-right-radius: 12px;
|
|
opacity: 0;
|
|
transition: opacity 0.3s;
|
|
pointer-events: none;
|
|
z-index: 2;
|
|
}
|
|
|
|
.slot:hover .slot-overlay { opacity: 1; }
|
|
|
|
.control-bars-mini {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
width: 100%;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.mini-progress {
|
|
height: 3px;
|
|
background: rgba(255,255,255,0.1);
|
|
border-radius: 2px;
|
|
overflow: hidden;
|
|
display: flex;
|
|
}
|
|
|
|
.mini-progress-bar { height: 100%; }
|
|
|
|
/* MODAL */
|
|
.modal-overlay {
|
|
position: fixed;
|
|
top: 0; left: 0; width: 100%; height: 100%;
|
|
background: rgba(0,0,0,0.85);
|
|
backdrop-filter: blur(8px);
|
|
display: none;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.modal-container {
|
|
background: var(--bg-card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 20px;
|
|
width: 90%;
|
|
max-width: 900px;
|
|
max-height: 90vh;
|
|
overflow-y: auto;
|
|
position: relative;
|
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
}
|
|
|
|
.modal-header {
|
|
padding: 30px;
|
|
border-bottom: 1px solid var(--border);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.modal-body { padding: 30px; }
|
|
|
|
.control-section {
|
|
background: rgba(0,0,0,0.2);
|
|
border-radius: 12px;
|
|
padding: 20px;
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
.progress-stacked {
|
|
height: 24px;
|
|
display: flex;
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
background: rgba(255,255,255,0.05);
|
|
margin: 15px 0;
|
|
}
|
|
|
|
.progress-segment {
|
|
height: 100%;
|
|
transition: width 0.5s ease;
|
|
position: relative;
|
|
}
|
|
|
|
.progress-segment:hover::after {
|
|
content: attr(data-label);
|
|
position: absolute;
|
|
top: -30px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
background: #000;
|
|
color: #fff;
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
font-size: 10px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.city-card {
|
|
background: rgba(136, 192, 208, 0.05);
|
|
border: 1px solid rgba(136, 192, 208, 0.1);
|
|
border-radius: 10px;
|
|
padding: 15px;
|
|
margin-bottom: 10px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.close-btn {
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-dim);
|
|
font-size: 24px;
|
|
cursor: pointer;
|
|
transition: color 0.3s;
|
|
}
|
|
|
|
.close-btn:hover { color: #fff; }
|
|
|
|
/* SECTOR CARD */
|
|
.sector-card {
|
|
background: var(--bg-card);
|
|
border: 1px solid var(--border);
|
|
border-radius: 15px;
|
|
padding: 20px;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
transition: all 0.3s;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.sector-card:hover {
|
|
transform: scale(1.05);
|
|
border-color: var(--accent-blue);
|
|
background: rgba(136, 192, 208, 0.05);
|
|
}
|
|
|
|
.sector-card.empty { opacity: 0.6; }
|
|
|
|
.mini-map {
|
|
display: grid;
|
|
grid-template-columns: repeat(6, 1fr);
|
|
gap: 2px;
|
|
width: 60px;
|
|
height: 60px;
|
|
}
|
|
|
|
.mini-dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.legend {
|
|
margin-top: 40px;
|
|
display: flex;
|
|
gap: 20px;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
}
|
|
|
|
.legend-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 12px;
|
|
color: var(--text-dim);
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
}
|
|
|
|
.legend-item .dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
/* Scrollbar */
|
|
::-webkit-scrollbar { width: 8px; }
|
|
::-webkit-scrollbar-track { background: var(--bg-dark); }
|
|
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
|
|
::-webkit-scrollbar-thumb:hover { background: var(--accent-blue); }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="layout">
|
|
<header>
|
|
<a href="index.php" class="logo">
|
|
<i class="fa-solid fa-shuttle-space"></i>
|
|
<span>GALAXY MAP</span>
|
|
</a>
|
|
<div style="display: flex; gap: 20px;">
|
|
<?php foreach($factions_db as $f): ?>
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<span style="width: 10px; height: 10px; border-radius: 50%; background: <?php echo $f['color']; ?>;"></span>
|
|
<span style="font-size: 11px; font-weight: bold; text-transform: uppercase;"><?php echo $f['name']; ?></span>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<div style="display: flex; gap: 15px; align-items: center;">
|
|
<span style="font-size: 12px; color: #81a1c1;"><i class="fa-solid fa-clock me-1"></i> <?php echo date('H:i'); ?></span>
|
|
<a href="profile.php" style="color: #fff;"><i class="fa-solid fa-user-circle fa-lg"></i></a>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="view-container">
|
|
<div class="navigation-path">
|
|
<a href="index.php">GALAXY [G1]</a>
|
|
<?php if ($view === 'sector'): ?>
|
|
<i class="fa-solid fa-chevron-right mx-1 small"></i>
|
|
<span>SECTEUR ALPHA [<?php echo $sector_id; ?>]</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div style="width: 100%; display: flex; justify-content: center;">
|
|
<?php if ($view === 'sector'): ?>
|
|
<div class="sector-grid">
|
|
<?php for ($i = 1; $i <= $grid_size; $i++):
|
|
$obj = $grid[$i] ?? null;
|
|
$type_info = $obj ? ($object_types_map[$obj['type']] ?? null) : null;
|
|
$json_data = $obj ? json_encode($obj) : 'null';
|
|
$fac_info = ($obj && isset($obj['faction_id'])) ? ($factions_map[$obj['faction_id']] ?? null) : null;
|
|
?>
|
|
<div class="slot" onclick="openPlanetModal(<?php echo htmlspecialchars($json_data); ?>)">
|
|
<div class="slot-coord"><?php echo str_pad($i, 2, '0', STR_PAD_LEFT); ?></div>
|
|
<?php if ($obj): ?>
|
|
<div class="slot-indicator">
|
|
<div class="indicator-dot" style="background: <?php echo getStatusColor($obj['status'], $statuses_map); ?>; box-shadow: 0 0 5px <?php echo getStatusColor($obj['status'], $statuses_map); ?>;" title="Status: <?php echo $statuses_map[$obj['status']]['name'] ?? 'Inconnu'; ?>"></div>
|
|
|
|
<?php if ($fac_info && $obj['faction_id'] != 1): // 1 is usually 'Aucune' ?>
|
|
<div class="faction-mini-icon" title="Contrôlé par: <?php echo htmlspecialchars($fac_info['name']); ?>">
|
|
<?php if (!empty($fac_info['image_url'])): ?>
|
|
<img src="<?php echo htmlspecialchars($fac_info['image_url']); ?>?v=<?php echo time(); ?>" style="width: 100%; height: 100%; object-fit: contain;">
|
|
<?php elseif (!empty($fac_info['fa_icon'])): ?>
|
|
<i class="fa-solid <?php echo htmlspecialchars($fac_info['fa_icon']); ?>" style="color: <?php echo htmlspecialchars($fac_info['color'] ?? '#fff'); ?>; font-size: 10px;"></i>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!empty($obj['cities'])): ?>
|
|
<div class="indicator-icon" title="Établissements présents">
|
|
<i class="fa-solid fa-city" style="font-size: 10px;"></i>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="slot-overlay">
|
|
<div class="control-bars-mini">
|
|
<?php if ($obj['orbital_control_enabled']): ?>
|
|
<div class="mini-progress">
|
|
<?php
|
|
$orb = $obj['orbital_controls'] ?? [];
|
|
if (empty($orb)) $orb = [1 => 100];
|
|
foreach($orb as $fid => $lvl):
|
|
$c = $factions_map[$fid]['color'] ?? '#88c0d0';
|
|
?>
|
|
<div class="mini-progress-bar" style="width: <?php echo $lvl; ?>%; background: <?php echo $c; ?>;"></div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($obj['terrestrial_control_enabled']): ?>
|
|
<div class="mini-progress">
|
|
<?php
|
|
$terr = $obj['terrestrial_controls'] ?? [];
|
|
if (empty($terr)) $terr = [1 => 100];
|
|
foreach($terr as $fid => $lvl):
|
|
$c = $factions_map[$fid]['color'] ?? '#a3be8c';
|
|
?>
|
|
<div class="mini-progress-bar" style="width: <?php echo $lvl; ?>%; background: <?php echo $c; ?>;"></div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="object-icon">
|
|
<?php
|
|
$icon = $type_info['icon'] ?? 'fa-earth-europe';
|
|
$color = getStatusColor($obj['status'], $statuses_map);
|
|
$imageUrl = $type_info['image_url'] ?? null;
|
|
?>
|
|
<?php if ($imageUrl): ?>
|
|
<img src="<?php echo htmlspecialchars($imageUrl); ?>?v=<?php echo time(); ?>" class="object-image">
|
|
<?php else: ?>
|
|
<i class="fa-solid <?php echo $icon; ?>" style="color: <?php echo $color; ?>;"></i>
|
|
<?php endif; ?>
|
|
</div>
|
|
<span class="object-name"><?php echo htmlspecialchars($obj['name']); ?></span>
|
|
<?php else: ?>
|
|
<div style="opacity: 0.05;"><i class="fa-solid fa-circle fa-sm"></i></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endfor; ?>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="sector-grid">
|
|
<?php for($s=1; $s<=$grid_size; $s++): $isActive = in_array($s, $active_sectors); ?>
|
|
<a href="?view=sector&galaxy_id=<?php echo $galaxy_id; ?>§or_id=<?php echo $s; ?>" class="sector-card <?php echo $isActive ? '' : 'empty'; ?>">
|
|
<div class="mini-map">
|
|
<?php for($p=1; $p<=$grid_size; $p++):
|
|
$dotColor = 'rgba(255,255,255,0.05)';
|
|
if (isset($sector_data[$s][$p])) { $dotColor = getStatusColor($sector_data[$s][$p]['status'], $statuses_map); }
|
|
?>
|
|
<div class="mini-dot" style="background-color: <?php echo $dotColor; ?>;"></div>
|
|
<?php endfor; ?>
|
|
</div>
|
|
<div style="font-size: 10px; color: #88c0d0;">SECTEUR</div>
|
|
<div style="font-size: 20px; font-weight: bold;"><?php echo $s; ?></div>
|
|
<?php if($isActive): ?><div style="font-size: 8px; color: #a3be8c; margin-top: 5px;"><i class="fa-solid fa-check"></i> Actif</div>
|
|
<?php else: ?><div style="font-size: 8px; color: #4c566a; margin-top: 5px;">Inexploré</div><?php endif; ?>
|
|
</a>
|
|
<?php endfor; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="legend">
|
|
<?php foreach($statuses_db as $s): ?>
|
|
<div class="legend-item"><span class="dot" style="background: <?php echo $s['color']; ?>;"></span> <?php echo $s['name']; ?></div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<!-- MODAL OVERLAY -->
|
|
<div id="planetModal" class="modal-overlay" onclick="if(event.target === this) closePlanetModal()">
|
|
<div class="modal-container">
|
|
<div class="modal-header">
|
|
<div>
|
|
<h2 id="modalPlanetName" style="margin: 0; font-family: 'Orbitron', sans-serif; color: var(--accent-blue); letter-spacing: 2px;"></h2>
|
|
<span id="modalPlanetType" style="font-size: 12px; text-transform: uppercase; color: var(--text-dim);"></span>
|
|
</div>
|
|
<button class="close-btn" onclick="closePlanetModal()">×</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div id="modalOrbitalControl" class="control-section">
|
|
<h4 style="margin-top: 0; text-transform: uppercase; letter-spacing: 1px;"><i class="fa-solid fa-satellite-dish me-2"></i> Contrôle Orbital</h4>
|
|
<div id="orbitalBars" class="progress-stacked"></div>
|
|
<div id="orbitalLegend" style="display: flex; gap: 15px; font-size: 11px; flex-wrap: wrap;"></div>
|
|
</div>
|
|
|
|
<div id="modalTerrestrialControl" class="control-section" style="display: none;">
|
|
<h4 style="margin-top: 0; text-transform: uppercase; letter-spacing: 1px;"><i class="fa-solid fa-person-military-pointing me-2"></i> Contrôle Terrestre</h4>
|
|
<div id="terrestrialBars" class="progress-stacked"></div>
|
|
<div id="terrestrialLegend" style="display: flex; gap: 15px; font-size: 11px; flex-wrap: wrap;"></div>
|
|
</div>
|
|
|
|
<div id="modalCities" class="control-section">
|
|
<h4 style="margin-top: 0; text-transform: uppercase; letter-spacing: 1px;"><i class="fa-solid fa-city me-2"></i> Établissements & Villes</h4>
|
|
<div id="citiesList"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const factionsMap = <?php echo json_encode($factions_map); ?>;
|
|
|
|
function openPlanetModal(data) {
|
|
if (!data) return;
|
|
document.getElementById('modalPlanetName').innerText = data.name;
|
|
document.getElementById('modalPlanetType').innerText = data.type.replace('_', ' ');
|
|
|
|
// Orbital Control
|
|
renderControlBars('orbitalBars', 'orbitalLegend', data.orbital_controls);
|
|
|
|
// Terrestrial Control
|
|
const terrSection = document.getElementById('modalTerrestrialControl');
|
|
if (data.terrestrial_control_enabled == 1) {
|
|
terrSection.style.display = 'block';
|
|
let terrData = data.terrestrial_controls;
|
|
// If empty, default to "Aucune" (ID 1)
|
|
if (!terrData || Object.keys(terrData).length === 0) {
|
|
terrData = { 1: 100 };
|
|
}
|
|
renderControlBars('terrestrialBars', 'terrestrialLegend', terrData);
|
|
} else {
|
|
terrSection.style.display = 'none';
|
|
}
|
|
|
|
// Cities
|
|
const citiesList = document.getElementById('citiesList');
|
|
citiesList.innerHTML = '';
|
|
if (data.cities && data.cities.length > 0) {
|
|
data.cities.forEach(city => {
|
|
const card = document.createElement('div');
|
|
card.className = 'city-card';
|
|
card.innerHTML = `
|
|
<div>
|
|
<div style="font-weight: bold; font-size: 14px;">${city.name}</div>
|
|
<div style="font-size: 10px; color: #81a1c1; text-transform: uppercase;">${city.type_name}</div>
|
|
</div>
|
|
<div style="text-align: right;">
|
|
<div style="font-size: 11px; font-weight: bold; color: ${factionsMap[city.faction_id]?.color || '#fff'}">${factionsMap[city.faction_id]?.name || 'Indépendant'}</div>
|
|
</div>
|
|
`;
|
|
citiesList.appendChild(card);
|
|
});
|
|
} else {
|
|
citiesList.innerHTML = '<div style="color: #4c566a; font-style: italic; font-size: 13px;">Aucun établissement majeur détecté.</div>';
|
|
}
|
|
|
|
document.getElementById('planetModal').style.display = 'flex';
|
|
}
|
|
|
|
function renderControlBars(barId, legendId, controls) {
|
|
const barContainer = document.getElementById(barId);
|
|
const legendContainer = document.getElementById(legendId);
|
|
barContainer.innerHTML = '';
|
|
legendContainer.innerHTML = '';
|
|
|
|
if (!controls || Object.keys(controls).length === 0) {
|
|
// Default to neutral if nothing
|
|
controls = { 1: 100 };
|
|
}
|
|
|
|
Object.entries(controls).forEach(([fid, lvl]) => {
|
|
const faction = factionsMap[fid] || { name: 'Inconnu', color: '#4c566a' };
|
|
const segment = document.createElement('div');
|
|
segment.className = 'progress-segment';
|
|
segment.style.width = lvl + '%';
|
|
segment.style.backgroundColor = faction.color;
|
|
segment.setAttribute('data-label', `${faction.name}: ${lvl}%`);
|
|
barContainer.appendChild(segment);
|
|
|
|
const leg = document.createElement('div');
|
|
leg.innerHTML = `<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background:${faction.color}; margin-right:5px;"></span> ${faction.name}: ${lvl}%`;
|
|
legendContainer.appendChild(leg);
|
|
});
|
|
}
|
|
|
|
function closePlanetModal() {
|
|
document.getElementById('planetModal').style.display = 'none';
|
|
}
|
|
|
|
window.onclick = function(event) {
|
|
const modal = document.getElementById('planetModal');
|
|
if (event.target == modal) {
|
|
closePlanetModal();
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|