Autosave: 20260225-201502

This commit is contained in:
Flatlogic Bot 2026-02-25 20:15:02 +00:00
parent 2c4e1bc5b5
commit f4b47f36bc
4 changed files with 577 additions and 577 deletions

View File

@ -401,8 +401,6 @@ if ($tab === 'users') {
$lb['items'] = $stmt_i->fetchAll(); $lb['items'] = $stmt_i->fetchAll();
} }
unset($lb); unset($lb);
} elseif ($tab === "project_logs") {
$project_logs_list = $db->query("SELECT * FROM project_logs ORDER BY created_at DESC")->fetchAll();
} }
?> ?>
@ -562,7 +560,7 @@ if ($tab === 'users') {
</div> </div>
<div style="flex: 1; display: flex; align-items: center; gap: 10px;"> <div style="flex: 1; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="terrestrial_control_enabled" id="obj_terrestrial_enabled" checked style="width: auto;"> <input type="checkbox" name="terrestrial_control_enabled" id="obj_terrestrial_enabled" checked style="width: auto;">
<label for="obj_terrestrial_enabled" style="margin-bottom: 0; cursor: pointer;">Contrôle Terrestre activé</label> <label for="obj_terrestrial_enabled" style="margin-bottom: 0; cursor: pointer;">Contrôle Terrestre (Villes) activé</label>
</div> </div>
</div> </div>
@ -906,17 +904,6 @@ if ($tab === 'users') {
<input type="file" name="image" accept="image/*"> <input type="file" name="image" accept="image/*">
</div> </div>
</div> </div>
<div style="display: flex; gap: 20px; margin-bottom: 15px; background: rgba(0,0,0,0.2); padding: 10px; border-radius: 4px; border: 1px solid #334155;">
<div style="flex: 1; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="orbital_control_enabled" id="obj_orbital_enabled" checked style="width: auto;">
<label for="obj_orbital_enabled" style="margin-bottom: 0; cursor: pointer;">Contrôle Orbital activé</label>
</div>
<div style="flex: 1; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="terrestrial_control_enabled" id="obj_terrestrial_enabled" checked style="width: auto;">
<label for="obj_terrestrial_enabled" style="margin-bottom: 0; cursor: pointer;">Contrôle Terrestre activé</label>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label>Description</label> <label>Description</label>
<textarea name="description" id="res_desc" rows="2"></textarea> <textarea name="description" id="res_desc" rows="2"></textarea>

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

View File

@ -41,14 +41,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
$type = $_POST['type'] ?? 'empty'; $type = $_POST['type'] ?? 'empty';
$manual_status = $_POST['manual_status'] ?? ''; $manual_status = $_POST['manual_status'] ?? '';
// Orbital control is now detailed by faction // Orbital control
$orbital_controls = $_POST['orbital_controls'] ?? []; $orbital_controls = $_POST['orbital_controls'] ?? [];
$dominant_orbital_val = 0; $dominant_orbital_val = 0;
$dominant_orbital_faction = null;
foreach($orbital_controls as $fid => $val) { foreach($orbital_controls as $fid => $val) {
if ((int)$val > $dominant_orbital_val && (int)$fid != 1) { // Not "Aucune" if ((int)$val > $dominant_orbital_val && (int)$fid != 1) { // Not "Aucune"
$dominant_orbital_val = (int)$val; $dominant_orbital_val = (int)$val;
$dominant_orbital_faction = (int)$fid; }
}
// 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;
} }
} }
@ -58,7 +65,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
$total_non_aucun = 0; $total_non_aucun = 0;
$active_factions = []; $active_factions = [];
$num_cities = 0; $num_cities = 0;
$avg_terrestrial_control = 0;
if (isset($_POST['cities']) && is_array($_POST['cities'])) { if (isset($_POST['cities']) && is_array($_POST['cities'])) {
foreach ($_POST['cities'] as $city_data) { foreach ($_POST['cities'] as $city_data) {
@ -70,17 +76,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
if ($lvl > 0 && $f_id != 1) { // 1 is "Aucune" if ($lvl > 0 && $f_id != 1) { // 1 is "Aucune"
$total_non_aucun += $lvl; $total_non_aucun += $lvl;
$active_factions[$f_id] = ($active_factions[$f_id] ?? 0) + $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) { if ($num_cities > 0 && $total_non_aucun > 0) {
arsort($active_factions); arsort($active_factions);
$faction_id = (int)key($active_factions); $faction_id = (int)key($active_factions);
@ -108,16 +109,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
if ($slot_id > 0) { if ($slot_id > 0) {
$db->prepare("DELETE FROM cities WHERE planet_id = ?")->execute([$slot_id]); $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_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]); $db->prepare("DELETE FROM planets WHERE id = ?")->execute([$slot_id]);
} }
} else { } else {
if ($slot_id > 0) { if ($slot_id > 0) {
$stmt = $db->prepare("UPDATE planets SET name = ?, type = ?, status = ?, faction_id = ?, orbital_control = ?, terrestrial_control = ? WHERE id = ?"); $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, $avg_terrestrial_control, $slot_id]); $stmt->execute([$name, $type, $status, $faction_id, $dominant_orbital_val, $dominant_terrestrial_val, $slot_id]);
$planet_id = $slot_id; $planet_id = $slot_id;
} else { } else {
$stmt = $db->prepare("INSERT INTO planets (galaxy_id, sector_id, slot, name, type, status, faction_id, orbital_control, terrestrial_control) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); $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, $avg_terrestrial_control]); $stmt->execute([$galaxy_id, $sector_id, $slot_num, $name, $type, $status, $faction_id, $dominant_orbital_val, $dominant_terrestrial_val]);
$planet_id = $db->lastInsertId(); $planet_id = $db->lastInsertId();
} }
@ -129,6 +131,14 @@ 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 // Handle Multiple Settlements
$sent_city_ids = []; $sent_city_ids = [];
if (isset($_POST['cities']) && is_array($_POST['cities'])) { if (isset($_POST['cities']) && is_array($_POST['cities'])) {
@ -209,11 +219,13 @@ if ($view === 'sector') {
$planet_ids[] = $obj['id']; $planet_ids[] = $obj['id'];
$grid[$obj['slot']]['cities'] = []; $grid[$obj['slot']]['cities'] = [];
$grid[$obj['slot']]['orbital_controls'] = []; $grid[$obj['slot']]['orbital_controls'] = [];
$grid[$obj['slot']]['terrestrial_controls'] = [];
} }
if (!empty($planet_ids)) { if (!empty($planet_ids)) {
// Fetch Orbital Controls
$placeholders = implode(',', array_fill(0, count($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 = $db->prepare("SELECT * FROM planet_faction_control WHERE planet_id IN ($placeholders)");
$stmt->execute($planet_ids); $stmt->execute($planet_ids);
$orb_controls_raw = $stmt->fetchAll(PDO::FETCH_ASSOC); $orb_controls_raw = $stmt->fetchAll(PDO::FETCH_ASSOC);
@ -225,6 +237,18 @@ 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 // Fetch Cities
unset($slot_data); unset($slot_data);
$stmt = $db->prepare("SELECT * FROM cities WHERE planet_id IN ($placeholders)"); $stmt = $db->prepare("SELECT * FROM cities WHERE planet_id IN ($placeholders)");
@ -552,7 +576,15 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
</div> </div>
</div> </div>
<!-- Terrestrial Faction Control Section -->
<div id="terrestrialSectionWrapper" style="background: rgba(0,0,0,0.1); padding: 15px; border-radius: 6px; border: 1px solid #334155; margin-bottom: 20px;"> <div id="terrestrialSectionWrapper" style="background: rgba(0,0,0,0.1); padding: 15px; border-radius: 6px; border: 1px solid #334155; margin-bottom: 20px;">
<label style="font-size: 11px; color: #88c0d0; font-weight: bold; display: block; margin-bottom: 15px; text-align: center; border-bottom: 1px solid #334155; padding-bottom: 8px;">CONTRÔLE TERRESTRE PAR FACTION (%)</label>
<div id="terrestrialControlContainer" class="control-bars">
<!-- Terrestrial sliders injected by JS -->
</div>
</div>
<div id="settlementsSectionWrapper" style="background: rgba(0,0,0,0.1); padding: 15px; border-radius: 6px; border: 1px solid #334155; margin-bottom: 20px;">
<label style="font-size: 11px; color: #88c0d0; font-weight: bold; display: block; margin-bottom: 15px; text-align: center; border-bottom: 1px solid #334155; padding-bottom: 8px;">ÉTABLISSEMENTS & PROGRESSIONS</label> <label style="font-size: 11px; color: #88c0d0; font-weight: bold; display: block; margin-bottom: 15px; text-align: center; border-bottom: 1px solid #334155; padding-bottom: 8px;">ÉTABLISSEMENTS & PROGRESSIONS</label>
<div id="settlementsContainer"> <div id="settlementsContainer">
<!-- Settlements will be injected here --> <!-- Settlements will be injected here -->
@ -603,16 +635,19 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
const allFactions = <?php echo json_encode($factions_db); ?>; const allFactions = <?php echo json_encode($factions_db); ?>;
const AUCUN_ID = 1; // ID for "Aucune" faction const AUCUN_ID = 1; // ID for "Aucune" faction
function initOrbitalSliders(orbitalData = null) { function initSlidersGeneric(containerId, data = null, prefix = 'orbital') {
const container = document.getElementById('orbitalControlContainer'); const container = document.getElementById(containerId);
container.innerHTML = ''; container.innerHTML = '';
const hasExisting = orbitalData && Object.keys(orbitalData).length > 0; const hasExisting = data && Object.keys(data).length > 0;
const className = prefix + '-slider';
const displayPrefix = 'val_' + prefix;
const inputName = prefix + '_controls';
allFactions.forEach(f => { allFactions.forEach(f => {
let val = 0; let val = 0;
if (hasExisting) { if (hasExisting) {
val = orbitalData[f.id] !== undefined ? parseInt(orbitalData[f.id]) : 0; val = data[f.id] !== undefined ? parseInt(data[f.id]) : 0;
} else { } else {
val = (f.id == AUCUN_ID ? 100 : 0); val = (f.id == AUCUN_ID ? 100 : 0);
} }
@ -624,12 +659,12 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
<span class="faction-dot" style="background: ${f.color || '#808080'}"></span> <span class="faction-dot" style="background: ${f.color || '#808080'}"></span>
${f.name} ${f.name}
</div> </div>
<input type="range" name="orbital_controls[${f.id}]" <input type="range" name="${inputName}[${f.id}]"
class="control-bar-input orbital-slider" class="control-bar-input ${className}"
data-faction-id="${f.id}" data-faction-id="${f.id}"
min="0" max="100" value="${val}" min="0" max="100" value="${val}"
oninput="handleSliderChangeGeneric('orbital-slider', ${f.id}, this.value)"> oninput="handleSliderChangeGeneric('${className}', ${f.id}, this.value, null, '${displayPrefix}')">
<div class="control-bar-value" id="val_orbital_${f.id}">${val}%</div> <div class="control-bar-value" id="${displayPrefix}_${f.id}">${val}%</div>
`; `;
container.appendChild(div); container.appendChild(div);
}); });
@ -693,7 +728,7 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
container.appendChild(div); container.appendChild(div);
} }
function handleSliderChangeGeneric(className, changedFid, newVal, rowIdx = null) { function handleSliderChangeGeneric(className, changedFid, newVal, rowIdx = null, displayPrefix = null) {
newVal = parseInt(newVal); newVal = parseInt(newVal);
const sliders = Array.from(document.querySelectorAll(`.${className}`)); const sliders = Array.from(document.querySelectorAll(`.${className}`));
@ -748,8 +783,9 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
} }
sliders.forEach(s => { sliders.forEach(s => {
const displayId = rowIdx !== null ? `val_${rowIdx}_${s.dataset.factionId}` : `val_orbital_${s.dataset.factionId}`; const dId = displayPrefix ? `${displayPrefix}_${s.dataset.factionId}` : `val_${rowIdx}_${s.dataset.factionId}`;
document.getElementById(displayId).innerText = s.value + '%'; const el = document.getElementById(dId);
if (el) el.innerText = s.value + '%';
}); });
} }
@ -759,13 +795,16 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
const orbWrapper = document.getElementById('orbitalSectionWrapper'); const orbWrapper = document.getElementById('orbitalSectionWrapper');
const terrWrapper = document.getElementById('terrestrialSectionWrapper'); const terrWrapper = document.getElementById('terrestrialSectionWrapper');
const setlWrapper = document.getElementById("settlementsSectionWrapper");
orbWrapper.style.display = (typeInfo.orbital_control_enabled == 1) ? 'block' : 'none'; orbWrapper.style.display = (typeInfo.orbital_control_enabled == 1) ? 'block' : 'none';
terrWrapper.style.display = (typeInfo.terrestrial_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 // 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)); orbWrapper.querySelectorAll('input, select, textarea').forEach(el => el.disabled = (typeInfo.orbital_control_enabled != 1));
terrWrapper.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').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));
} }
function editSlot(num, data) { function editSlot(num, data) {
@ -778,8 +817,9 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
document.getElementById('form_type').value = data.type; document.getElementById('form_type').value = data.type;
document.getElementById('form_status').value = data.status; document.getElementById('form_status').value = data.status;
// Load orbital sliders // Load sliders
initOrbitalSliders(data.orbital_controls); initSlidersGeneric('orbitalControlContainer', data.orbital_controls, 'orbital');
initSlidersGeneric('terrestrialControlContainer', data.terrestrial_controls, 'terrestrial');
// Load settlements // Load settlements
document.getElementById('settlementsContainer').innerHTML = ''; document.getElementById('settlementsContainer').innerHTML = '';
@ -791,7 +831,8 @@ function getStatusColor($status, $type, $statuses_map, $object_types_map) {
document.getElementById('form_name').value = ''; document.getElementById('form_name').value = '';
document.getElementById('form_type').value = 'empty'; document.getElementById('form_type').value = 'empty';
document.getElementById('form_status').value = ''; document.getElementById('form_status').value = '';
initOrbitalSliders(null); initSlidersGeneric('orbitalControlContainer', null, 'orbital');
initSlidersGeneric('terrestrialControlContainer', null, 'terrestrial');
document.getElementById('settlementsContainer').innerHTML = ''; document.getElementById('settlementsContainer').innerHTML = '';
} }

1030
index.php

File diff suppressed because it is too large Load Diff