This commit is contained in:
michi 2025-09-05 10:50:28 +02:00
parent e934e234b5
commit b740ae4626
3 changed files with 28 additions and 50 deletions

53
main.js
View File

@ -206,7 +206,6 @@ function updateInventoryDisplay() {
<p>${itemData.description}</p>
`;
// Add hover events for dynamic tooltip positioning
itemElement.addEventListener('mouseenter', (e) => {
positionTooltip(tooltipElement, itemElement);
});
@ -229,7 +228,6 @@ function toggleInventory() {
// Professional Tooltip Positioning System
// ==================================================================
function positionTooltip(tooltip, item) {
// Reset positioning and classes
tooltip.style.top = '';
tooltip.style.bottom = '';
tooltip.style.left = '';
@ -237,15 +235,13 @@ function positionTooltip(tooltip, item) {
tooltip.style.transform = '';
tooltip.className = tooltip.className.replace(/tooltip-(top|bottom|left|right)/g, '');
// Show tooltip temporarily to measure dimensions
tooltip.style.display = 'flex';
tooltip.style.visibility = 'hidden';
// Get actual dimensions
const tooltipRect = tooltip.getBoundingClientRect();
const itemRect = item.getBoundingClientRect();
// Get viewport boundaries
const viewport = {
top: 0,
left: 0,
@ -253,14 +249,14 @@ function positionTooltip(tooltip, item) {
bottom: window.innerHeight
};
// Check if we're in a modal
const modalContent = item.closest('.modal-content');
const containerRect = modalContent ? modalContent.getBoundingClientRect() : viewport;
const margin = 16;
const arrowSize = 8;
// Calculate available space in each direction
const spaces = {
top: itemRect.top - containerRect.top,
bottom: containerRect.bottom - itemRect.bottom,
@ -268,8 +264,8 @@ function positionTooltip(tooltip, item) {
right: containerRect.right - itemRect.right
};
// Determine best position based on available space
let position = 'bottom'; // default: show above item
let position = 'bottom';
let maxSpace = spaces.top;
if (spaces.bottom > maxSpace && spaces.bottom >= tooltipRect.height + margin + arrowSize) {
@ -287,7 +283,7 @@ function positionTooltip(tooltip, item) {
maxSpace = spaces.right;
}
// Apply positioning based on determined position
tooltip.classList.add(`tooltip-${position}`);
switch (position) {
@ -320,7 +316,7 @@ function positionTooltip(tooltip, item) {
break;
}
// Ensure tooltip stays within viewport bounds
const finalRect = tooltip.getBoundingClientRect();
if (finalRect.left < viewport.left + margin) {
@ -336,7 +332,6 @@ function positionTooltip(tooltip, item) {
tooltip.style.top = `${viewport.bottom - tooltipRect.height - margin}px`;
}
// Make tooltip visible
tooltip.style.visibility = 'visible';
}
@ -366,19 +361,16 @@ function openBasebuildingModal() {
}
function initializeBasebuilding() {
// Initialize cabin size buttons
const sizeButtons = document.querySelectorAll('.size-btn');
sizeButtons.forEach(btn => {
btn.addEventListener('click', () => changeCabinSize(btn.dataset.size));
});
// Initialize building item buttons
const buildingItems = document.querySelectorAll('.building-item');
buildingItems.forEach(btn => {
btn.addEventListener('click', () => selectBuildingItem(btn.dataset.item));
});
// Set current cabin size
currentCabinSize = playerState.baseBuilding.cabinSize || 'm';
updateCabinDisplay();
}
@ -387,7 +379,7 @@ function changeCabinSize(size) {
currentCabinSize = size;
playerState.baseBuilding.cabinSize = size;
// Update active button
document.querySelectorAll('.size-btn').forEach(btn => btn.classList.remove('active'));
document.querySelector(`[data-size="${size}"]`).classList.add('active');
@ -398,7 +390,6 @@ function changeCabinSize(size) {
function selectBuildingItem(item) {
selectedBuildingItem = item;
// Update selected button
document.querySelectorAll('.building-item').forEach(btn => btn.classList.remove('selected'));
document.querySelector(`[data-item="${item}"]`).classList.add('selected');
}
@ -406,14 +397,12 @@ function selectBuildingItem(item) {
function updateCabinDisplay() {
const cabinGrid = document.getElementById('cabin-grid');
if (!cabinGrid) return;
// Update grid class
cabinGrid.className = `cabin-grid cabin-${currentCabinSize}`;
// Clear existing cells
cabinGrid.innerHTML = '';
// Get grid dimensions
const dimensions = {
'm': { cols: 6, rows: 4 },
'l': { cols: 8, rows: 6 },
@ -422,7 +411,7 @@ function updateCabinDisplay() {
const { cols, rows } = dimensions[currentCabinSize];
// Create cells
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const cell = document.createElement('div');
@ -452,12 +441,12 @@ function placeBuildingItem(row, col) {
const cellKey = `${row}-${col}`;
// Check if cell is already occupied
if (playerState.baseBuilding.placedItems[cellKey]) {
// Remove item if clicking on occupied cell
delete playerState.baseBuilding.placedItems[cellKey];
} else {
// Place new item
playerState.baseBuilding.placedItems[cellKey] = selectedBuildingItem;
}
@ -578,7 +567,7 @@ function showStoryNode(storyNodeId) {
bodyStyle.backgroundAttachment = "fixed";
bodyStyle.backgroundRepeat = "no-repeat";
// Display story text (support for dynamic text functions)
const storyText = typeof storyNode.text === 'function' ? storyNode.text(playerState) : storyNode.text;
storyTextElement.innerText = storyText;
@ -589,7 +578,7 @@ function showStoryNode(storyNodeId) {
optionsButtonsElement.removeChild(optionsButtonsElement.firstChild);
}
// Clear and populate options (support for dynamic options functions)
const options = typeof storyNode.options === 'function' ? storyNode.options(playerState) : storyNode.options;
options.forEach((option) => {
@ -700,23 +689,17 @@ function selectOption(option) {
}
}
// Anzeigen aktualisieren
updateStatsDisplay();
updateInventoryDisplay();
// Fortschritt speichern
const nextStoryNodeId = option.nextText;
if (nextStoryNodeId) {
playerState.currentSceneId = nextStoryNodeId;
}
saveGame();
// Game-Over-Check
// if (checkGameOver()) {
// return;
// }
// Nächste Szene laden
if (nextStoryNodeId) {
showStoryNode(nextStoryNodeId);
}

View File

@ -40,7 +40,6 @@ export default [
}
];
// Only show leg examination if not already examined
if (!playerState.storyFlags || !playerState.storyFlags.bein_examined) {
baseOptions.unshift({
text: "Mein Bein erneut ansehen.",
@ -83,7 +82,6 @@ export default [
options: [
{
text: "Wasser trinken.",
// Hier könntest du eine Zufalls-Chance auf Krankheit einbauen
setState: (currentState) => ({ ...currentState, thirst: 100 }),
nextText: "bach_getrunken"
},
@ -128,12 +126,11 @@ export default [
options: [
{
text: "Kämpfen!",
// Kampf führt wahrscheinlich zu Schaden oder Tod
nextText: "kampf_stiller_1"
},
{
text: "Wegrennen!",
nextText: "absturzstelle_hub" // Du entkommst, aber hast gelernt, dass Schreien gefährlich ist
nextText: "absturzstelle_hub"
}
]
},
@ -196,7 +193,6 @@ export default [
image: "images/bein_verbunden.png",
soundEffect: "verbandSfx",
setState: (currentState) => {
// Set flag that leg has been examined and treated
if (!currentState.storyFlags) currentState.storyFlags = {};
currentState.storyFlags.bein_examined = true;
return currentState;
@ -381,7 +377,7 @@ export default [
options: [
{
text: "In den Frachtraum klettern und suchen.",
nextText: "frachtraum_suchen" // Nächster großer Bereich
nextText: "frachtraum_suchen"
},
{
text: "Erstmal zurück.",

View File

@ -307,7 +307,7 @@ body {
}
/* Professional Tooltip System */
.item-tooltip {
display: none;
position: fixed;
@ -341,7 +341,6 @@ body {
}
}
/* Tooltip content layout */
.item-tooltip {
display: flex;
flex-direction: column;
@ -370,7 +369,7 @@ body {
hyphens: auto;
}
/* Tooltip arrow */
.item-tooltip::before {
content: '';
position: absolute;
@ -408,7 +407,7 @@ body {
border-right-color: rgba(52, 152, 219, 0.3);
}
/* Modal content overflow handling */
.modal-content {
position: relative;
overflow: visible;
@ -418,7 +417,7 @@ body {
overflow: visible;
}
/* Hover states */
.inventory-item:hover .item-tooltip {
display: flex;
}
@ -427,7 +426,7 @@ body {
display: flex;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.item-tooltip {
min-width: 240px;
@ -475,7 +474,7 @@ body {
}
/* Modal Base Styles */
.modal {
position: fixed;
z-index: 1000;
@ -570,7 +569,7 @@ body {
transform: none;
}
/* Base Building Styles */
.basebuilding-content {
width: 800px;
max-width: 95%;