537 lines
30 KiB
PHP
537 lines
30 KiB
PHP
<?php
|
|
require_once 'db/config.php';
|
|
session_start();
|
|
$db = db();
|
|
|
|
$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';
|
|
}
|
|
|
|
$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 * 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();
|
|
|
|
$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 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);
|
|
$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'] == $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 {
|
|
$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";
|
|
}
|
|
|
|
function getStatusColor($status, $statuses_map) {
|
|
return $statuses_map[$status]['color'] ?? 'rgba(255,255,255,0.05)';
|
|
}
|
|
|
|
function isStatusBlinking($status, $statuses_map) {
|
|
return ($statuses_map[$status]["is_blinking"] ?? 0) == 1;
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Nexus - <?php echo $page_title; ?></title>
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
|
<link href="assets/css/custom.css?v=<?php echo time(); ?>" rel="stylesheet">
|
|
<style>
|
|
.blink { animation: blinker 1s linear infinite; } @keyframes blinker { 50% { opacity: 0; } }
|
|
body { background: #000; color: #fff; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; }
|
|
#main-wrapper { display: flex; flex-direction: column; min-height: 100vh; }
|
|
.user-auth-bar { display: flex; justify-content: flex-end; gap: 20px; font-size: 11px; color: #8c92a3; margin-bottom: 10px; }
|
|
.user-auth-bar a { color: #88c0d0; text-decoration: none; font-weight: bold; }
|
|
.user-auth-bar .username { color: #ebcb8b; }
|
|
|
|
#game-container { flex: 1; padding: 30px; display: flex; flex-direction: column; align-items: center; }
|
|
.nav-panel { background: rgba(10, 15, 30, 0.95); border: 1px solid #2d3545; padding: 20px; width: 180px; }
|
|
.nav-panel h3 { margin: 0 0 15px 0; color: #88c0d0; font-size: 14px; text-transform: uppercase; border-bottom: 1px solid #2d3545; padding-bottom: 10px; }
|
|
.nav-panel label { display: block; font-size: 10px; color: #8c92a3; margin-top: 10px; }
|
|
.nav-panel input { width: 100%; background: #000; border: 1px solid #3b4252; color: #fff; padding: 5px; margin-top: 3px; font-size: 12px; }
|
|
.nav-panel button { width: 100%; margin-top: 15px; background: #88c0d0; border: none; padding: 8px; color: #000; font-weight: bold; cursor: pointer; border-radius: 2px; }
|
|
|
|
.galaxy-map {
|
|
display: grid;
|
|
grid-template-columns: repeat(6, 140px);
|
|
grid-template-rows: repeat(6, 140px);
|
|
gap: 10px;
|
|
padding: 15px;
|
|
background: rgba(10, 15, 30, 0.5);
|
|
border: 1px solid #2d3545;
|
|
box-shadow: 0 0 30px rgba(0,0,0,0.5);
|
|
}
|
|
.slot {
|
|
width: 140px;
|
|
height: 140px;
|
|
background: rgba(46, 52, 64, 0.3);
|
|
border: 1px solid #3b4252;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
}
|
|
.slot:hover { border-color: #88c0d0; background: rgba(136, 192, 208, 0.1); }
|
|
.slot.empty { cursor: default; }
|
|
.slot.empty:hover { border-color: #3b4252; background: rgba(46, 52, 64, 0.3); }
|
|
|
|
.object-image { width: 100%; height: 100%; object-fit: contain; }
|
|
.object-icon-container { font-size: 40px; margin-bottom: 10px; width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; position: relative; }
|
|
.object-name { font-size: 12px; font-weight: bold; text-align: center; padding: 0 5px; color: #d8dee9; }
|
|
|
|
.sector-grid { display: grid; grid-template-columns: repeat(6, 140px); grid-template-rows: repeat(6, 140px); gap: 10px; }
|
|
.sector-card { background: rgba(46, 52, 64, 0.4); border: 1px solid #3b4252; display: flex; flex-direction: column; align-items: center; justify-content: center; text-decoration: none; color: #fff; transition: all 0.2s; }
|
|
.sector-card:hover { border-color: #88c0d0; background: rgba(136, 192, 208, 0.1); transform: translateY(-2px); }
|
|
.sector-card.empty { opacity: 0.6; }
|
|
.mini-map { display: grid; grid-template-columns: repeat(6, 4px); grid-template-rows: repeat(6, 4px); gap: 1px; margin-bottom: 10px; }
|
|
.mini-dot { width: 4px; height: 4px; border-radius: 50%; }
|
|
|
|
.legend { margin-top: 30px; display: flex; gap: 20px; flex-wrap: wrap; justify-content: center; background: rgba(0,0,0,0.5); padding: 15px; border-radius: 5px; border: 1px solid #2d3545; }
|
|
.legend-item { display: flex; align-items: center; gap: 8px; font-size: 11px; color: #8c92a3; }
|
|
.dot { width: 10px; height: 10px; border-radius: 50%; }
|
|
|
|
.admin-footer { position: fixed; bottom: 20px; right: 20px; display: flex; gap: 10px; }
|
|
.btn-mj { background: #bf616a; color: #fff; padding: 10px 15px; border-radius: 5px; text-decoration: none; font-weight: bold; font-size: 12px; display: flex; align-items: center; gap: 8px; box-shadow: 0 4px 15px rgba(191, 97, 106, 0.3); transition: all 0.2s; }
|
|
.btn-adm { background: #5e81ac; color: #fff; padding: 10px 15px; border-radius: 5px; text-decoration: none; font-weight: bold; font-size: 12px; display: flex; align-items: center; gap: 8px; box-shadow: 0 4px 15px rgba(94, 129, 172, 0.3); transition: all 0.2s; }
|
|
.btn-mj:hover, .btn-adm:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,0.4); filter: brightness(1.1); }
|
|
|
|
/* Modal Styles */
|
|
.modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); backdrop-filter: blur(5px); display: none; align-items: center; justify-content: center; z-index: 1000; }
|
|
.modal-container { background: #1a202c; border: 1px solid #2d3545; width: 600px; max-width: 90%; border-radius: 8px; box-shadow: 0 20px 50px rgba(0,0,0,0.5); overflow: hidden; }
|
|
.modal-header { padding: 20px; border-bottom: 1px solid #2d3545; display: flex; justify-content: space-between; align-items: flex-start; background: #242c3d; }
|
|
.modal-header h2 { margin: 0; color: #ebcb8b; font-size: 24px; }
|
|
.modal-close { background: none; border: none; color: #8c92a3; font-size: 30px; cursor: pointer; line-height: 1; }
|
|
.modal-close:hover { color: #fff; }
|
|
.modal-body { padding: 25px; max-height: 80vh; overflow-y: auto; }
|
|
|
|
.planet-hero { display: flex; gap: 20px; margin-bottom: 25px; }
|
|
.planet-preview-img { width: 120px; height: 120px; object-fit: contain; background: rgba(0,0,0,0.3); border-radius: 10px; padding: 10px; border: 1px solid #3b4252; }
|
|
.planet-meta { flex: 1; }
|
|
.planet-status-badge { display: inline-block; padding: 4px 12px; border-radius: 20px; font-size: 11px; font-weight: bold; margin-bottom: 10px; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
|
|
.control-section { margin-bottom: 25px; padding: 15px; background: rgba(0,0,0,0.2); border-radius: 6px; border: 1px solid #2d3545; }
|
|
.control-title { font-size: 13px; font-weight: bold; color: #88c0d0; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; text-transform: uppercase; }
|
|
.multi-control-bar { height: 12px; background: #2e3440; border-radius: 6px; display: flex; overflow: hidden; margin-bottom: 10px; border: 1px solid #3b4252; }
|
|
.control-segment { height: 100%; transition: width 0.3s; }
|
|
.control-legend { display: flex; flex-wrap: wrap; gap: 15px; font-size: 11px; }
|
|
.legend-tag { display: flex; align-items: center; gap: 5px; color: #d8dee9; }
|
|
.legend-tag .color-box { width: 8px; height: 8px; border-radius: 2px; }
|
|
|
|
.city-item { display: flex; justify-content: space-between; align-items: center; padding: 12px; background: #242c3d; border: 1px solid #3b4252; border-radius: 5px; margin-bottom: 10px; }
|
|
.city-info { display: flex; flex-direction: column; gap: 4px; }
|
|
.city-name { font-weight: bold; color: #eceff4; font-size: 14px; }
|
|
.city-type { font-size: 11px; color: #88c0d0; opacity: 0.8; }
|
|
|
|
.mod-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
|
|
.mod-badge { font-size: 9px; padding: 2px 6px; border-radius: 3px; background: rgba(136, 192, 208, 0.1); color: #88c0d0; border: 1px solid rgba(136, 192, 208, 0.3); }
|
|
|
|
.resource-header { background: rgba(10, 15, 30, 0.9); border-bottom: 1px solid #2d3545; padding: 10px 30px; display: flex; justify-content: center; gap: 30px; position: sticky; top: 0; z-index: 100; backdrop-filter: blur(10px); }
|
|
.res-item { display: flex; align-items: center; gap: 10px; }
|
|
.res-item img { width: 24px; height: 24px; object-fit: contain; }
|
|
.res-item i { font-size: 18px; width: 24px; text-align: center; }
|
|
.res-val { font-family: 'Courier New', monospace; font-weight: bold; color: #eceff4; font-size: 15px; }
|
|
.res-prod { font-size: 10px; color: #a3be8c; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="main-wrapper">
|
|
<header class="resource-header">
|
|
<?php foreach($resources as $name => $r): ?>
|
|
<div class="res-item" title="<?php echo $name; ?>">
|
|
<?php if (!empty($r['image'])): ?>
|
|
<img src="<?php echo htmlspecialchars($r['image']); ?>?v=<?php echo time(); ?>" alt="<?php echo $name; ?>">
|
|
<?php else: ?>
|
|
<i class="fa-solid <?php echo $r['icon']; ?>" style="color: #88c0d0;"></i>
|
|
<?php endif; ?>
|
|
<div style="display: flex; flex-direction: column;">
|
|
<span class="res-val"><?php echo $r['val']; ?></span>
|
|
<span class="res-prod"><?php echo $r['prod']; ?></span>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</header>
|
|
|
|
<main id="game-container">
|
|
<div class="user-auth-bar">
|
|
<?php if (isset($_SESSION['user_id'])): ?>
|
|
<span>Connecté en tant que <span class="username"><?php echo htmlspecialchars($_SESSION['username'] ?? 'Utilisateur'); ?></span></span>
|
|
<a href="profile.php"><i class="fa-solid fa-user-gear"></i> Profil</a>
|
|
<a href="auth.php?action=logout"><i class="fa-solid fa-right-from-bracket"></i> Déconnexion</a>
|
|
<?php else: ?>
|
|
<a href="auth.php?page=login">Connexion</a>
|
|
<a href="auth.php?page=register">S'inscrire</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 40px; align-items: flex-start; width: 100%; max-width: 1200px; justify-content: center;">
|
|
<div class="nav-panel">
|
|
<h3>Navigation</h3>
|
|
<form method="GET">
|
|
<input type="hidden" name="view" value="<?php echo $view; ?>">
|
|
<label>Galaxie</label>
|
|
<input type="number" name="galaxy_id" value="<?php echo $galaxy_id; ?>" min="1" max="10">
|
|
<?php if($view === 'sector'): ?>
|
|
<label>Secteur</label>
|
|
<input type="number" name="sector_id" value="<?php echo $sector_id; ?>" min="1" max="36">
|
|
<?php endif; ?>
|
|
<button type="submit">Sauter</button>
|
|
</form>
|
|
|
|
<div style="margin-top: 20px; border-top: 1px solid #2d3545; padding-top: 15px;">
|
|
<?php if($view === 'sector'): ?>
|
|
<a href="?view=galaxy&galaxy_id=<?php echo $galaxy_id; ?>" style="color: #88c0d0; text-decoration: none; font-size: 12px; display: block; text-align: center;">
|
|
<i class="fa-solid fa-arrow-left"></i> Vue Galaxie
|
|
</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if($view === 'sector'): ?>
|
|
<div class="galaxy-map">
|
|
<?php for($i=1; $i<=$grid_size; $i++): $obj = $grid[$i]; ?>
|
|
<div class="slot <?php echo $obj ? '' : 'empty'; ?>"
|
|
onclick='<?php echo $obj ? "openPlanetModal(".json_encode($obj).")" : ""; ?>'>
|
|
<?php if($obj):
|
|
$type_info = $object_types_map[$obj['type']] ?? [];
|
|
?>
|
|
<div class="object-icon-container">
|
|
<?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; ?> <?php echo isStatusBlinking($obj['status'], $statuses_map) ? 'blink' : ''; ?>" 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 <?php echo isStatusBlinking($sector_data[$s][$p]['status'] ?? '', $statuses_map) ? 'blink' : ''; ?>" 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 <?php echo ($s['is_blinking'] ?? 0) ? 'blink' : ''; ?>" 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 style="display: flex; flex-direction: column; align-items: flex-start;"><h2 id="m-planet-name">Planet Name</h2><div id="m-planet-type" style="font-style: italic; font-size: 13px; color: #88c0d0; opacity: 0.8; margin-top: 2px;"></div></div>
|
|
<button class="modal-close" onclick="closePlanetModal()">×</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="planet-hero">
|
|
<img id="m-planet-img" src="" class="planet-preview-img">
|
|
<div class="planet-meta">
|
|
<div id="m-planet-status" class="planet-status-badge">Status</div>
|
|
<div id="m-planet-faction" style="font-size: 13px; font-weight: bold; margin-bottom: 8px;">Faction: None</div>
|
|
<div id="m-planet-mods" class="mod-list"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="m-orbital-section" class="control-section">
|
|
<div class="control-title"><i class="fa-solid fa-satellite-dish"></i> Contrôle Orbital</div>
|
|
<div id="m-orbital-bar" class="multi-control-bar"></div>
|
|
<div id="m-orbital-legend" class="control-legend"></div>
|
|
</div>
|
|
|
|
<div id="m-terrestrial-section" class="control-section">
|
|
<div class="control-title"><i class="fa-solid fa-person-military-pointing"></i> Contrôle Terrestre</div>
|
|
<div id="m-terrestrial-bar" class="multi-control-bar"></div>
|
|
<div id="m-terrestrial-legend" class="control-legend"></div>
|
|
</div>
|
|
|
|
<div id="m-cities-section">
|
|
<div class="control-title"><i class="fa-solid fa-city"></i> Établissements & Villes</div>
|
|
<div id="m-cities-container"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($user_role === 'admin' || $user_role === 'gm'): ?>
|
|
<div class="admin-footer">
|
|
<a href="gm_console.php" class="btn-mj"><i class="fa-solid fa-headset"></i> CONSOLE MG</a>
|
|
<?php if ($user_role === 'admin'): ?>
|
|
<a href="admin.php" class="btn-adm"><i class="fa-solid fa-shield-halved"></i> CONSOLE ADMIN</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<script>
|
|
const factionsMap = <?php echo json_encode($factions_map); ?>;
|
|
const typesMap = <?php echo json_encode($object_types_map); ?>;
|
|
const statusesMap = <?php echo json_encode($statuses_map); ?>;
|
|
|
|
function openPlanetModal(data) {
|
|
document.getElementById('m-planet-name').innerText = data.name;
|
|
const typeInfo = typesMap[data.type] || {};
|
|
document.getElementById('m-planet-type').innerText = typeInfo.name || data.type;
|
|
|
|
const statusInfo = statusesMap[data.status] || {};
|
|
const statusBadge = document.getElementById('m-planet-status');
|
|
statusBadge.innerText = statusInfo.name || data.status;
|
|
statusBadge.style.background = statusInfo.color || '#4c566a';
|
|
if (statusInfo.is_blinking == 1) statusBadge.classList.add('blink');
|
|
else statusBadge.classList.remove('blink');
|
|
|
|
const img = document.getElementById('m-planet-img');
|
|
img.src = typeInfo.image_url ? typeInfo.image_url + '?v=' + Date.now() : '';
|
|
img.style.display = typeInfo.image_url ? 'block' : 'none';
|
|
|
|
// Faction (Simple logic: majority control)
|
|
let dominantFaction = 'Aucune';
|
|
let maxOrb = 0;
|
|
for (let fid in data.orbital_controls) {
|
|
if (data.orbital_controls[fid] > maxOrb) {
|
|
maxOrb = data.orbital_controls[fid];
|
|
dominantFaction = factionsMap[fid] ? factionsMap[fid].name : 'Inconnue';
|
|
}
|
|
}
|
|
document.getElementById('m-planet-faction').innerText = 'Faction dominante (Orbital): ' + dominantFaction;
|
|
|
|
// Modifiers
|
|
const modContainer = document.getElementById('m-planet-mods');
|
|
modContainer.innerHTML = '';
|
|
if (typeInfo.modifiers) {
|
|
typeInfo.modifiers.forEach(mod => {
|
|
const span = document.createElement('span');
|
|
span.className = 'mod-badge';
|
|
span.innerText = mod.name;
|
|
modContainer.appendChild(span);
|
|
});
|
|
}
|
|
|
|
// Orbital Bar
|
|
renderControlBar('m-orbital-bar', 'm-orbital-legend', data.orbital_controls);
|
|
// Terrestrial Bar
|
|
renderControlBar('m-terrestrial-bar', 'm-terrestrial-legend', data.terrestrial_controls);
|
|
|
|
// Cities
|
|
const cityContainer = document.getElementById('m-cities-container');
|
|
cityContainer.innerHTML = '';
|
|
if (data.cities && data.cities.length > 0) {
|
|
data.cities.forEach(city => {
|
|
const div = document.createElement('div');
|
|
div.className = 'city-item';
|
|
let controlDesc = '';
|
|
for (let fid in city.controls) {
|
|
if (factionsMap[fid]) {
|
|
controlDesc += `<span style="color:${factionsMap[fid].color || '#fff'}">${factionsMap[fid].name}: ${city.controls[fid]}%</span> `;
|
|
}
|
|
}
|
|
div.innerHTML = `
|
|
<div class="city-info">
|
|
<span class="city-name">${city.name}</span>
|
|
<span class="city-type">${city.type_name || 'Établissement'}</span>
|
|
</div>
|
|
<div style="font-size: 10px; text-align: right;">${controlDesc}</div>
|
|
`;
|
|
cityContainer.appendChild(div);
|
|
});
|
|
} else {
|
|
cityContainer.innerHTML = '<div style="font-size: 11px; color: #4c566a; font-style: italic;">Aucun établissement répertorié.</div>';
|
|
}
|
|
|
|
document.getElementById('planetModal').style.display = 'flex';
|
|
}
|
|
|
|
function renderControlBar(barId, legendId, controls) {
|
|
const bar = document.getElementById(barId);
|
|
const legend = document.getElementById(legendId);
|
|
bar.innerHTML = '';
|
|
legend.innerHTML = '';
|
|
|
|
let total = 0;
|
|
for (let fid in controls) {
|
|
const val = parseInt(controls[fid]);
|
|
if (val > 0) {
|
|
total += val;
|
|
const faction = factionsMap[fid] || { name: 'Inconnue', color: '#4c566a' };
|
|
const segment = document.createElement('div');
|
|
segment.className = 'control-segment';
|
|
segment.style.width = val + '%';
|
|
segment.style.backgroundColor = faction.color;
|
|
segment.title = `${faction.name}: ${val}%`;
|
|
bar.appendChild(segment);
|
|
|
|
const tag = document.createElement('div');
|
|
tag.className = 'legend-tag';
|
|
tag.innerHTML = `<span class="color-box" style="background:${faction.color}"></span> ${faction.name}: ${val}%`;
|
|
legend.appendChild(tag);
|
|
}
|
|
}
|
|
|
|
if (total < 100) {
|
|
const remain = 100 - total;
|
|
const segment = document.createElement('div');
|
|
segment.className = 'control-segment';
|
|
segment.style.width = remain + '%';
|
|
segment.style.backgroundColor = '#2e3440';
|
|
segment.title = `Incontesté: ${remain}%`;
|
|
bar.appendChild(segment);
|
|
|
|
const tag = document.createElement('div');
|
|
tag.className = 'legend-tag';
|
|
tag.innerHTML = `<span class="color-box" style="background:#2e3440"></span> Incontesté: ${remain}%`;
|
|
legend.appendChild(tag);
|
|
}
|
|
}
|
|
|
|
function closePlanetModal() {
|
|
document.getElementById('planetModal').style.display = 'none';
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|