What a mess
This commit is contained in:
@@ -252,7 +252,7 @@ function populateForm(location) {
|
||||
renderInteractablesList(location.interactables || {});
|
||||
|
||||
// Render connections
|
||||
renderConnectionsList(location.id, location.exits);
|
||||
renderConnectionsList(location.id);
|
||||
}
|
||||
|
||||
function updateImagePreview(imagePath) {
|
||||
@@ -282,26 +282,63 @@ function renderSpawnList(spawns) {
|
||||
});
|
||||
}
|
||||
|
||||
function renderConnectionsList(locationId, exits) {
|
||||
const list = document.getElementById('connectionsList');
|
||||
if (!list) return;
|
||||
function renderConnectionsList(locationId) {
|
||||
const list = document.getElementById('connectionList');
|
||||
|
||||
if (!list) {
|
||||
console.error('connectionList element not found!');
|
||||
return;
|
||||
}
|
||||
|
||||
list.innerHTML = '';
|
||||
|
||||
for (const [direction, destId] of Object.entries(exits)) {
|
||||
const destLocation = currentLocations.find(l => l.id === destId);
|
||||
// Get connections from the global connections array
|
||||
const locationConnections = connections.filter(conn => conn.from === locationId);
|
||||
|
||||
if (!locationConnections || locationConnections.length === 0) {
|
||||
list.innerHTML = '<div style="padding: 10px; text-align: center; opacity: 0.5;">No connections</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
locationConnections.forEach(conn => {
|
||||
const destLocation = currentLocations.find(l => l.id === conn.to);
|
||||
|
||||
if (destLocation) {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'connection-item';
|
||||
item.innerHTML = `
|
||||
<div class="connection-info">
|
||||
<div class="connection-direction">${direction} → ${destLocation.name}</div>
|
||||
<div class="connection-direction" style="font-weight: 500; color: #ffa726;">
|
||||
${getDirectionEmoji(conn.direction)} ${conn.direction}
|
||||
</div>
|
||||
<div style="font-size: 0.85em; opacity: 0.7; margin-top: 4px;">
|
||||
→ ${destLocation.name}
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-remove" onclick="deleteConnection('${locationId}', '${destId}')">×</button>
|
||||
<button class="btn btn-remove" onclick="deleteConnection('${locationId}', '${conn.to}')"
|
||||
style="width: 32px; height: 32px; padding: 0; font-size: 20px; line-height: 1;">×</button>
|
||||
`;
|
||||
list.appendChild(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getDirectionEmoji(direction) {
|
||||
const emojiMap = {
|
||||
'north': '⬆️',
|
||||
'south': '⬇️',
|
||||
'east': '➡️',
|
||||
'west': '⬅️',
|
||||
'northeast': '↗️',
|
||||
'northwest': '↖️',
|
||||
'southeast': '↘️',
|
||||
'southwest': '↙️',
|
||||
'up': '⬆️',
|
||||
'down': '⬇️',
|
||||
'inside': '🚪',
|
||||
'outside': '🚪'
|
||||
};
|
||||
return emojiMap[direction.toLowerCase()] || '🔀';
|
||||
}
|
||||
|
||||
// ==================== CANVAS DRAWING ====================
|
||||
@@ -837,11 +874,103 @@ function filterNPCList() {
|
||||
});
|
||||
}
|
||||
|
||||
async function promptAddConnection(fromId, toId) {
|
||||
const direction = prompt('Enter direction (north, south, east, west, northeast, etc.):');
|
||||
if (!direction) return;
|
||||
// Store connection data temporarily
|
||||
let pendingConnection = null;
|
||||
|
||||
function promptAddConnection(fromId, toId) {
|
||||
// Store the connection data
|
||||
pendingConnection = { fromId, toId };
|
||||
|
||||
// Get location names
|
||||
const fromLocation = currentLocations.find(loc => loc.id === fromId);
|
||||
const toLocation = currentLocations.find(loc => loc.id === toId);
|
||||
|
||||
// Update modal
|
||||
document.getElementById('fromLocationName').textContent = fromLocation ? fromLocation.name : fromId;
|
||||
document.getElementById('toLocationName').textContent = toLocation ? toLocation.name : toId;
|
||||
|
||||
// Reset selection
|
||||
document.getElementById('directionSelect').value = '';
|
||||
document.getElementById('autoReverseConnection').checked = true;
|
||||
|
||||
// Close location list modal and open direction modal
|
||||
closeAddConnectionModal();
|
||||
document.getElementById('selectDirectionModal').style.display = 'flex';
|
||||
|
||||
// Update reverse connection text based on selection
|
||||
updateReverseConnectionText();
|
||||
}
|
||||
|
||||
function updateReverseConnectionText() {
|
||||
const directionSelect = document.getElementById('directionSelect');
|
||||
const reverseText = document.getElementById('reverseConnectionText');
|
||||
const checkbox = document.getElementById('autoReverseConnection');
|
||||
|
||||
if (!directionSelect || !reverseText || !checkbox) return;
|
||||
|
||||
const direction = directionSelect.value;
|
||||
|
||||
if (!direction) {
|
||||
reverseText.textContent = 'Will also create a connection back from destination to source';
|
||||
return;
|
||||
}
|
||||
|
||||
const reverseDirection = getReverseDirection(direction);
|
||||
const fromLocation = currentLocations.find(loc => loc.id === pendingConnection.fromId);
|
||||
const toLocation = currentLocations.find(loc => loc.id === pendingConnection.toId);
|
||||
|
||||
if (checkbox.checked) {
|
||||
reverseText.innerHTML = `Will create: <strong>${toLocation?.name || 'destination'}</strong> → ${reverseDirection} → <strong>${fromLocation?.name || 'source'}</strong>`;
|
||||
} else {
|
||||
reverseText.textContent = 'Only one-way connection will be created';
|
||||
}
|
||||
}
|
||||
|
||||
// Listen to direction changes
|
||||
if (document.getElementById('directionSelect')) {
|
||||
document.getElementById('directionSelect').addEventListener('change', updateReverseConnectionText);
|
||||
document.getElementById('autoReverseConnection').addEventListener('change', updateReverseConnectionText);
|
||||
}
|
||||
|
||||
function getReverseDirection(direction) {
|
||||
const reverseMap = {
|
||||
'north': 'south',
|
||||
'south': 'north',
|
||||
'east': 'west',
|
||||
'west': 'east',
|
||||
'northeast': 'southwest',
|
||||
'northwest': 'southeast',
|
||||
'southeast': 'northwest',
|
||||
'southwest': 'northeast',
|
||||
'up': 'down',
|
||||
'down': 'up',
|
||||
'inside': 'outside',
|
||||
'outside': 'inside'
|
||||
};
|
||||
|
||||
return reverseMap[direction] || direction;
|
||||
}
|
||||
|
||||
function closeSelectDirectionModal() {
|
||||
document.getElementById('selectDirectionModal').style.display = 'none';
|
||||
pendingConnection = null;
|
||||
}
|
||||
|
||||
async function confirmAddConnection() {
|
||||
if (!pendingConnection) return;
|
||||
|
||||
const direction = document.getElementById('directionSelect').value;
|
||||
const autoReverse = document.getElementById('autoReverseConnection').checked;
|
||||
|
||||
if (!direction) {
|
||||
alert('Please select a direction');
|
||||
return;
|
||||
}
|
||||
|
||||
const { fromId, toId } = pendingConnection;
|
||||
|
||||
try {
|
||||
// Add the main connection
|
||||
const response = await fetch('/api/editor/connection', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
@@ -850,24 +979,99 @@ async function promptAddConnection(fromId, toId) {
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
showSuccess('Connection added!');
|
||||
await loadConnections();
|
||||
await selectLocation(fromId); // Refresh form
|
||||
drawMap();
|
||||
closeAddConnectionModal();
|
||||
} else {
|
||||
if (!data.success) {
|
||||
alert('Failed to add connection: ' + data.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add reverse connection if enabled
|
||||
if (autoReverse) {
|
||||
const reverseDirection = getReverseDirection(direction);
|
||||
const reverseResponse = await fetch('/api/editor/connection', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({from: toId, to: fromId, direction: reverseDirection})
|
||||
});
|
||||
|
||||
const reverseData = await reverseResponse.json();
|
||||
|
||||
if (reverseData.success) {
|
||||
showSuccess(`Connection added! (bidirectional: ${direction} ⇄ ${reverseDirection})`);
|
||||
} else {
|
||||
showSuccess(`Connection added (${direction}), but reverse failed: ${reverseData.error}`);
|
||||
}
|
||||
} else {
|
||||
showSuccess(`Connection added! (one-way: ${direction})`);
|
||||
}
|
||||
|
||||
// Refresh the view
|
||||
await loadConnections();
|
||||
await selectLocation(fromId); // Refresh form
|
||||
drawMap();
|
||||
closeSelectDirectionModal();
|
||||
|
||||
} catch (error) {
|
||||
alert('Failed to add connection: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteConnection(fromId, toId) {
|
||||
if (!confirm('Delete this connection?')) return;
|
||||
// Store pending deletion data
|
||||
let pendingDeletion = null;
|
||||
|
||||
function deleteConnection(fromId, toId) {
|
||||
// Get location information
|
||||
const fromLocation = currentLocations.find(loc => loc.id === fromId);
|
||||
const toLocation = currentLocations.find(loc => loc.id === toId);
|
||||
|
||||
if (!fromLocation || !toLocation) {
|
||||
alert('Location not found');
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the direction of this connection
|
||||
const direction = Object.entries(fromLocation.exits || {}).find(([dir, dest]) => dest === toId)?.[0];
|
||||
|
||||
// Check if reverse connection exists
|
||||
const reverseDirection = getReverseDirection(direction);
|
||||
const hasReverseConnection = toLocation.exits && toLocation.exits[reverseDirection] === fromId;
|
||||
|
||||
// Store deletion data
|
||||
pendingDeletion = { fromId, toId, direction, hasReverseConnection, reverseDirection };
|
||||
|
||||
// Update modal content
|
||||
document.getElementById('deleteFromLocationName').textContent = fromLocation.name;
|
||||
document.getElementById('deleteToLocationName').textContent = toLocation.name;
|
||||
document.getElementById('deleteDirectionText').textContent = direction || 'unknown';
|
||||
|
||||
// Show/hide reverse connection option
|
||||
const reverseOption = document.getElementById('deleteReverseOption');
|
||||
if (hasReverseConnection) {
|
||||
reverseOption.style.display = 'block';
|
||||
document.getElementById('deleteReverseText').innerHTML =
|
||||
`Also delete: <strong>${toLocation.name}</strong> → ${reverseDirection} → <strong>${fromLocation.name}</strong>`;
|
||||
document.getElementById('deleteBothConnections').checked = true;
|
||||
} else {
|
||||
reverseOption.style.display = 'none';
|
||||
document.getElementById('deleteBothConnections').checked = false;
|
||||
}
|
||||
|
||||
// Show modal
|
||||
document.getElementById('deleteConnectionModal').style.display = 'flex';
|
||||
}
|
||||
|
||||
function closeDeleteConnectionModal() {
|
||||
document.getElementById('deleteConnectionModal').style.display = 'none';
|
||||
pendingDeletion = null;
|
||||
}
|
||||
|
||||
async function confirmDeleteConnection() {
|
||||
if (!pendingDeletion) return;
|
||||
|
||||
const { fromId, toId, hasReverseConnection, reverseDirection } = pendingDeletion;
|
||||
const deleteBoth = document.getElementById('deleteBothConnections').checked;
|
||||
|
||||
try {
|
||||
// Delete the main connection
|
||||
const response = await fetch('/api/editor/connection', {
|
||||
method: 'DELETE',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
@@ -876,14 +1080,36 @@ async function deleteConnection(fromId, toId) {
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
showSuccess('Connection deleted!');
|
||||
await loadConnections();
|
||||
await selectLocation(fromId); // Refresh form
|
||||
drawMap();
|
||||
} else {
|
||||
if (!data.success) {
|
||||
alert('Failed to delete connection: ' + data.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete reverse connection if requested and exists
|
||||
if (deleteBoth && hasReverseConnection) {
|
||||
const reverseResponse = await fetch('/api/editor/connection', {
|
||||
method: 'DELETE',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({from: toId, to: fromId})
|
||||
});
|
||||
|
||||
const reverseData = await reverseResponse.json();
|
||||
|
||||
if (reverseData.success) {
|
||||
showSuccess('Both connections deleted!');
|
||||
} else {
|
||||
showSuccess(`Connection deleted, but reverse failed: ${reverseData.error}`);
|
||||
}
|
||||
} else {
|
||||
showSuccess('Connection deleted!');
|
||||
}
|
||||
|
||||
// Refresh the view
|
||||
await loadConnections();
|
||||
await selectLocation(fromId); // Refresh form
|
||||
drawMap();
|
||||
closeDeleteConnectionModal();
|
||||
|
||||
} catch (error) {
|
||||
alert('Failed to delete connection: ' + error.message);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user