diff --git a/App/Don_t_Deploy/2026-07-11-tourismustal-glossar-sozial.sql b/App/Don_t_Deploy/2026-07-11-tourismustal-glossar-sozial.sql new file mode 100644 index 0000000..55f60ad --- /dev/null +++ b/App/Don_t_Deploy/2026-07-11-tourismustal-glossar-sozial.sql @@ -0,0 +1,23 @@ +-- ============================================================ +-- Tourismustal: Glossar-Begriff "Soziale Verantwortung" (+ Zuordnung) +-- Stand: 2026-07-11 · Atlas · idempotent +-- Mechanik in der Sim: Personalhaus-Ausbau → Wohnqualität → Personal- +-- zufriedenheit → freundlicherer Service → Gäste-Zufriedenheit (Win-win). +-- ============================================================ + +INSERT INTO glossar (key_slug, title, short, text, short_easy, text_easy, category, sort_order, image_path) VALUES +('soziale-verantwortung', 'Soziale Verantwortung', + 'Unternehmen tragen Verantwortung für ihre Beschäftigten – gute Arbeits- und Wohnbedingungen zahlen sich doppelt aus.', + 'Soziale Verantwortung (Corporate Social Responsibility) heißt: Ein Betrieb kümmert sich nicht nur um Gewinn, sondern auch um Menschen und Umwelt. Im Alpentourismus betrifft das besonders die Saisonarbeitskräfte – real wohnen sie oft in engen, schlechten Personalunterkünften. Wer in gute Personalhäuser, faire Löhne und gutes Arbeitsklima investiert, bekommt zufriedenes, loyales Personal – und Gäste spüren freundlichen Service sofort. Soziale Verantwortung ist damit kein Kostenfaktor, sondern eine Investition: ein Win-win für Beschäftigte, Gäste und Betrieb.', + 'Ein Betrieb kümmert sich gut um seine Mitarbeiter:innen.', + 'Soziale Verantwortung heißt: Ein Betrieb schaut auch auf seine Leute, nicht nur aufs Geld. Zum Beispiel: gute Wohnungen für das Personal. Zufriedene Mitarbeiter sind freundlich. Das freut auch die Gäste. Alle gewinnen.', + 'gesellschaft', 214, + 'assets/img/glossar/soziale-verantwortung.webp') +ON DUPLICATE KEY UPDATE + title=VALUES(title), short=VALUES(short), text=VALUES(text), + short_easy=VALUES(short_easy), text_easy=VALUES(text_easy), + category=VALUES(category), sort_order=VALUES(sort_order), image_path=VALUES(image_path); + +INSERT INTO glossar_modules (glossar_id, module_id) +SELECT id, 'tourismustal' FROM glossar WHERE key_slug = 'soziale-verantwortung' +ON DUPLICATE KEY UPDATE module_id=VALUES(module_id); diff --git a/App/assets/img/glossar/soziale-verantwortung.webp b/App/assets/img/glossar/soziale-verantwortung.webp new file mode 100644 index 0000000..6a51399 Binary files /dev/null and b/App/assets/img/glossar/soziale-verantwortung.webp differ diff --git a/App/sims/tourismustal/assets/audio-info/bi-staffhouse.mp3 b/App/sims/tourismustal/assets/audio-info/bi-staffhouse.mp3 index 07a78c3..3aa9601 100644 Binary files a/App/sims/tourismustal/assets/audio-info/bi-staffhouse.mp3 and b/App/sims/tourismustal/assets/audio-info/bi-staffhouse.mp3 differ diff --git a/App/sims/tourismustal/editor.html b/App/sims/tourismustal/editor.html index b929cfb..ae43370 100644 --- a/App/sims/tourismustal/editor.html +++ b/App/sims/tourismustal/editor.html @@ -89,10 +89,10 @@
- +
- + diff --git a/App/sims/tourismustal/js/data.js b/App/sims/tourismustal/js/data.js index b1c2071..ede59e9 100644 --- a/App/sims/tourismustal/js/data.js +++ b/App/sims/tourismustal/js/data.js @@ -416,9 +416,11 @@ export const BUILD_INFO = { icon: '🏠', title: 'Wohnraum für dein Personal!', text: '12 Angestellte finden hier ein Zuhause. Betriebe ohne Personal ' + 'laufen nur mit halber Kraft – die Personal-Zeile links zeigt, ob ' - + 'alle Stellen besetzt sind.\n\n📍 LAGE ZÄHLT: Baue es nahe bei den ' - + 'Betrieben (max. 4 Felder, Kreis beim Bauen) – liegt es weiter weg, ' - + 'wirkt es nur zu zwei Dritteln.', + + 'alle Stellen besetzt sind.\n\n🤝 SOZIALE VERANTWORTUNG: Baust du das ' + + 'Personalhaus später aus, wohnt dein Personal besser – zufriedene ' + + 'Mitarbeiter:innen sind freundlicher, und das merken die Gäste.\n\n' + + '📍 LAGE ZÄHLT: Baue es nahe bei den Betrieben (max. 4 Felder, Kreis ' + + 'beim Bauen) – liegt es weiter weg, wirkt es nur zu zwei Dritteln.', }, snow: { icon: '❄️', title: 'Die Beschneiung steht bereit!', @@ -714,6 +716,7 @@ export const KNOWLEDGE = { ], staffhouse: [ { term: 'Saisonarbeit & Wohnraum', text: 'Tourismus braucht viele Arbeitskräfte, oft in Saisonarbeit. Ohne leistbaren Wohnraum finden die Betriebe kein Personal.' }, + { term: 'Soziale Verantwortung', text: 'Real wohnen Saisonkräfte oft in engen, schlechten Unterkünften. Wer in gute Personalhäuser investiert, bekommt zufriedenes Personal – und das spüren die Gäste: freundlicher Service, bessere Bewertungen. Ein Win-win.' }, ], snow: [ { term: 'Klimawandel-Anpassung', text: 'Beschneiung sichert die Saison, wenn die Winter wärmer werden – braucht aber viel Wasser und Energie.' }, diff --git a/App/sims/tourismustal/js/iso.js b/App/sims/tourismustal/js/iso.js index a667f26..de161df 100644 --- a/App/sims/tourismustal/js/iso.js +++ b/App/sims/tourismustal/js/iso.js @@ -1716,10 +1716,13 @@ export class IsoRenderer { _sprite(name, x, y, scale = 1, flip = false) { const s = this.sprites[name]; if (!s) return false; - const w = s.w * scale; + // w/bottom IMMER live aus SPRITE_DEFS lesen – so wirken Editor- + // Justierungen sofort (die geladene Kopie wäre eingefroren). + const def = SPRITE_DEFS[name] || s; + const w = def.w * scale; this._shadow(x, y + 2, w * 0.38, w * 0.16); // Motiv endet im 1024er-Bild bei ~88 % der Höhe - const top = y + s.bottom - w * 0.88; + const top = y + def.bottom - w * 0.88; if (flip) { const ctx = this.ctx; ctx.save(); ctx.translate(x, 0); ctx.scale(-1, 1); diff --git a/App/sims/tourismustal/js/main.js b/App/sims/tourismustal/js/main.js index 7473a7d..3c472cf 100644 --- a/App/sims/tourismustal/js/main.js +++ b/App/sims/tourismustal/js/main.js @@ -98,7 +98,9 @@ function inspectBuilding(c, r) { audio.build(); renderer.addFloat('🏗️ Umbau …', '#e8892b', c + 0.5, r - 0.5, true); ui.updateKPIs(); - ui.toast(`🏗️ ${res.name} wird auf Stufe ${roman} umgebaut (−${res.cost.toLocaleString('de-AT')} €) – schau zu!`); + ui.toast(rep.type === 'staffhouse' + ? `🤝 ${res.name} wird auf Stufe ${roman} ausgebaut (−${res.cost.toLocaleString('de-AT')} €) – dein Personal wohnt besser, der Service wird freundlicher!` + : `🏗️ ${res.name} wird auf Stufe ${roman} umgebaut (−${res.cost.toLocaleString('de-AT')} €) – schau zu!`, 6000); telemetry.log('upgrade', { c, r, cost: res.cost, level: res.level }); ui._closeBuilding(); // Karte schließen → man sieht die Baustelle }, diff --git a/App/sims/tourismustal/js/model.js b/App/sims/tourismustal/js/model.js index f5efe62..184b75c 100644 --- a/App/sims/tourismustal/js/model.js +++ b/App/sims/tourismustal/js/model.js @@ -506,7 +506,12 @@ export function buildingReport(state, c, r) { if (def.cap) lines.push(`Förderleistung: ${effVal(b, 'cap')} Gäste/Tag`); if (def.beds) lines.push(`Betten: ${effVal(b, 'beds')}`); if (def.access) lines.push(`Anreise: +${effVal(b, 'access')} Gäste/Tag`); - if (def.housing) lines.push(`Wohnraum: ${effVal(b, 'housing')} Angestellte`); + if (def.housing) { + lines.push(`Wohnraum: ${effVal(b, 'housing')} Angestellte`); + lines.push((b.level || 1) > 1 + ? `🤝 Wohnqualität Stufe ${['', 'I', 'II', 'III', 'IV'][b.level || 1]}: zufriedenes Personal, freundlicherer Service (+${((b.level - 1) * 2)} Zufriedenheit)` + : '🤝 Ausbau verbessert die Wohnqualität – soziale Verantwortung zahlt sich in Zufriedenheit aus'); + } if (def.summerCap) lines.push(`Sommergäste: bis ${effVal(b, 'summerCap')}/Tag`); if (def.spendBonus) lines.push(`Mehrumsatz: +${effVal(b, 'spendBonus')} €/Gast`); if (def.snowPower) lines.push(`Beschneiung: +${effVal(b, 'snowPower').toFixed(1)} cm/Tag`); @@ -826,6 +831,18 @@ export function simulateDay(state) { let satTarget = 70; if (count(state, 'restaurant') > 0) satTarget += 12; satTarget += Math.min(8, sum(state, 'satBonus')); + // Soziale Verantwortung: gut ausgebaute Personalhäuser = bessere Wohn- + // qualität = zufriedenes Personal = freundlicherer Service. Wirkt nur, + // wenn überhaupt Personal beschäftigt ist. (Ø-Ausbaustufe → 0…+6) + const shLevels = state.buildings + .filter(b => b.type === 'staffhouse').map(b => b.level || 1); + if (shLevels.length && state.staffNeeded > 0) { + const avg = shLevels.reduce((a, v) => a + v, 0) / shLevels.length; + state.staffCare = Math.round((avg - 1) * 20) / 10; // Stufe II=+2 … IV=+6 + satTarget += state.staffCare; + } else { + state.staffCare = 0; + } if (crowding > 0.9) satTarget -= 20; if (staffFactor < 1) satTarget -= 15; if (winter) {