User prompt
Please fix the bug: 'Uncaught TypeError: tween.create is not a function' in or related to this line: 'tween.create(shadow).to({' Line Number: 677
User prompt
Please fix the bug: 'Uncaught TypeError: tween.to is not a function' in or related to this line: 'tween.to(shadow, {' Line Number: 677
User prompt
Please fix the bug: 'Uncaught TypeError: tween.create is not a function' in or related to this line: 'tween.create(shadow).to({' Line Number: 677
User prompt
Çarpıcı Seçimler Modülü – Talimatlar Oyuna, sadece bazı özel düğümlerde (örneğin her 4–6 sahnede bir) rastlanan ve “çarpıcı seçim” olarak adlandırılan bir sistem ekle. Bu seçimler oyuncuya yüksek risk ve yüksek ödül/ceza içeren dramatik kararlar sunar. Normal diyaloglardan farklı olarak, bu seçim ekranında şıklar ekranda büyüyüp küçülerek animasyonla gelir; müzik kısa bir an kesilir ya da karanlık bir gölge ekranı kaplar. Oyuncu hemen bu kararın sıradan bir karar olmadığını hisseder. Bu modülde yapılan seçimler, diğer kararların aksine barları +10 ila +30 veya -30’a kadar etkileyebilir. Aynı zamanda bazı karakterlerin kaderini, ilişkilerin yönünü, bazı sahnelerin kilitlenip açılmasını da doğrudan etkiler. Rebecca ile iş gezisindesiniz. Aynı odada mı kalacaksınız, farklı mı? Aynı odada: Rebecca+15, lust+15, betray+15 Farklı odada: honest+10, Rebecca-5 Lisa seni, iş yerinde Alex ile fazla yakın görünmen konusunda uyarıyor. Tepkin ne olur? Anlar ve saygı gösterirsin: Lisa+20, honest+15 Umursamaz davranırsın: Lisa-20, betray+15 Alex senden gizli bir bilgi istiyor. Paylaşacak mısın? Paylaşırsan: betray+20, Alex+10 Saklarsan: honest+20, Alex-10 Peter sana, Lisa ile ilgili endişelerini paylaşıyor. Ona inanacak mısın? Evet: Peter+15, honest+10 Hayır: Peter-15, betray+10 Rebecca gece seni evine davet ediyor. Gidiyor musun? Evet: Rebecca+20, lust+15, betray+20 Hayır: honest+15 Lisa, seninle ciddi bir konuşma yapmak istiyor. Onu dinleyecek misin? Dinlersen: Lisa+20, honest+10 Dinlemezsen: Lisa-20, happy-15 Alex ile gizli bir anlaşma teklif ediyor. Kabul edecek misin? Evet: Alex+20, betray+20 Hayır: honest+20, Alex-15 Peter, seni büyük bir sırrı hakkında uyarıyor. Güveniyor musun? Evet: Peter+20, honest+10 Hayır: Peter-20, betray+15 Rebecca ile bir gece kulübünde dans ediyorsun. Daha yakın davranacak mısın? Evet: Rebecca+15, lust+15, betray+10 Hayır: honest+10 Lisa seni iş arkadaşlarınla ilgili dedikodulara karışmakla suçluyor. Savunacak mısın? Savun: Lisa+10, honest+15 Kabullen: Lisa-15, betray+10 Alex, seni iş yerinde terfi ile ödüllendiriyor ama bir karşılık bekliyor. Kabul edecek misin? Evet: Alex+25, betray+25 Hayır: honest+20 Peter’in sana yardım etmek için büyük bir fedakarlık yapması gerekiyor. Kabul edecek misin? Evet: Peter+25, happy+15 Hayır: Peter-20, betray+10 Rebecca, iş seyahatinde seni bir restoranda yalnız bırakıyor. Tek başına kalacak mısın yoksa kalabalığa mı karışacaksın? Tek başına: Rebecca+10, lust+10 Kalabalık: honest+10 Lisa sana eski bir anısını anlatıyor ve senden destek bekliyor. Onun yanında olacak mısın? Evet: Lisa+20, happy+15 Hayır: Lisa-15 Alex’in zorlayıcı teklifine karşılık verirken etik dışı bir şey yapman isteniyor. Kabul mü? Evet: Alex+20, betray+25 Hayır: honest+20 Peter seni beklenmedik bir şekilde büyük bir sırrını açıklıyor. Tepkin ne olur? Sırlarınızı paylaşmaya devam edersin: Peter+20, honest+15 Mesafeli olursun: Peter-15, betray+10 Rebecca ile iş sonrası bara gittiniz. Lisa ile yüzleşmeye hazır mısın? Evet: betray+20, lust+15, Rebecca+10 Hayır: honest+15, Lisa+10 Lisa sana, evlilikte bir kriz yaşıyor ve profesyonel yardım almak istiyor. Destek verir misin? Evet: Lisa+25, happy+20 Hayır: Lisa-25 Alex, kariyerin için büyük bir tehlike barındıran bir riski göze almana izin veriyor. Kabul mü? Evet: Alex+30, betray+30 Hayır: honest+20 Peter ile aranızda aniden büyük bir anlaşmazlık çıkıyor. Özür dileyecek misin? Evet: Peter+20, happy+15 Hayır: Peter-20, betray+15 Bu seçimler nadiren ve sürpriz şekilde gelir. Ekranda seçimler animasyonla büyüyüp küçülerek gelir, ses ve görsel efektlerle oyuncunun heyecanını artırır. Barlar bu seçimlerde +15-30 veya -15-30 gibi büyük oranda etkilenir. Böylece oyun hem dramatik hem eğlenceli ve sürükleyici hale gelir.
User prompt
"Dış Etki" Olayları Barları sadece seçimler değil, zaman bazlı olaylar da etkilesin. Örneğin 3 sahne boyunca lust bar çok yüksekse, karakter iradesini kaybetmiş gibi bir karar otomatik alınabilir.
User prompt
"Yalancı Hafıza" Tuzakları Oyuncu daha önce yaptığı bir seçimin etkisini hatırlamıyorsa, sistem ona yanlış bilgi verebilir ("Mike sanki o gün doğruyu söylediğini hatırlıyordu... ama söylememişti."). Bu, barlara dayalı “kendini kandırma” kurgusu oluşturur.
User prompt
Please fix the bug: 'Uncaught TypeError: tween.to is not a function' in or related to this line: 'tween.to(storyText, {' Line Number: 1078
User prompt
"Kriz Anında Durdurma" Mekanizması Bazı sahnelerde oyuncuya zaman ver, örneğin: "Mike birini aramak üzere. 5 saniyen var, ne yapacaksın?" — Seçim yapılmazsa sahne kendiliğinden akar. Bu tür "gerilimli zamanlı seçimler" dinamiklik katar.
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'if (typeof storage.get('playthroughCount') === "number") {' Line Number: 835
User prompt
Please fix the bug: 'storage.getItem is not a function' in or related to this line: 'if (typeof storage.getItem('playthroughCount') === "number") {' Line Number: 835
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'if (typeof storage.get('playthroughCount') === "number") {' Line Number: 835
User prompt
Please fix the bug: 'storage.getItem is not a function' in or related to this line: 'if (typeof storage.getItem('playthroughCount') === "number") {' Line Number: 835
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'if (typeof storage.get('playthroughCount') === "number") {' Line Number: 835
User prompt
"Kilitli Final" Sistemi Oyunda bazı sonlar, ancak daha önce birden fazla oyun turu oynanmışsa erişilebilir olsun. Yani sistem, playthroughCount gibi bir sayaçla tekrar oynanışı tanır ve bazı “gerçek sonları” buna göre açar.
User prompt
"Gizli Bar" Entegrasyonu Dört bar dışında, oyuncunun farkında olmadığı bir shadow bar tanımla. Belirli seçimlerle gizlice artar ya da azalır. Bu bar belirli eşikleri geçtiğinde beklenmedik olaylar (örneğin Mike’ın ani öfke patlamaları ya da ani içsel monologlar) tetikler.
User prompt
"Hatırlatma ve Gölgeli Vicdan" Mekanizması Oyuncu geçmişte verdiği bir karardan pişman olacaksa, ilerleyen bölümlerde karakterin iç sesi olarak veya rüyalarında bu kararı tekrar yaşamasını sağla. Oyuncunun geçmişi, geleceğe gölge düşürsün.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(portraitNode).to({' Line Number: 1204 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(portraitNode).to({' Line Number: 1204 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(portraitNode).to({' Line Number: 1204
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(portraitNode).to({' Line Number: 1204
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(portraitNode).to({' Line Number: 1204
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(portraitNode).to({' Line Number: 1204
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(portraitNode).to({' Line Number: 1204
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(portraitNode).to({' Line Number: 1196
User prompt
Please fix the bug: 'Uncaught TypeError: tween.to is not a function' in or related to this line: 'tween.to(portraitNode, {' Line Number: 1196
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // OptionButton: For displaying a choice var OptionButton = Container.expand(function () { var self = Container.call(this); self.bg = self.attachAsset('option_btn', { anchorX: 0.5, anchorY: 0.5 }); self.text = null; self.callback = null; self.setText = function (str) { if (self.text) self.removeChild(self.text); self.text = new Text2(str, { size: 54, fill: '#222222' }); self.text.anchor.set(0.5, 0.5); self.text.x = 0; self.text.y = 0; self.addChild(self.text); }; self.setCallback = function (cb) { self.callback = cb; }; self.down = function (x, y, obj) { if (self.callback) self.callback(); }; return self; }); // RelationshipBar: For displaying and updating a bar (happiness, honesty, lust, betrayal) var RelationshipBar = Container.expand(function () { var self = Container.call(this); self.bg = self.attachAsset('bar_bg', { anchorX: 0, anchorY: 0 }); self.fill = null; self.label = null; self.value = 100; // 0-100 self.maxWidth = 400; self.type = 'happy'; // 'happy', 'honest', 'lust', 'betray' self.setType = function (type) { self.type = type; var fillId = 'bar_fill_happy'; if (type === 'honest') fillId = 'bar_fill_honest'; if (type === 'lust') fillId = 'bar_fill_lust'; if (type === 'betray') fillId = 'bar_fill_betray'; if (self.fill) self.removeChild(self.fill); self.fill = self.attachAsset(fillId, { anchorX: 0, anchorY: 0 }); self.fill.x = 0; self.fill.y = 0; self.fill.width = self.maxWidth; self.fill.height = 40; self.fill.zIndex = 1; self.bg.zIndex = 0; self.setValue(self.value); }; self.setValue = function (val) { self.value = Math.max(0, Math.min(100, val)); if (self.fill) { self.fill.width = self.maxWidth * (self.value / 100); } if (self.label) { self.label.setText(self.value + '%'); } }; self.setLabel = function (text) { if (self.label) self.removeChild(self.label); self.label = new Text2(text, { size: 36, fill: '#ffffff' }); self.label.anchor.set(1, 0.5); self.label.x = self.maxWidth + 20; self.label.y = 20; self.addChild(self.label); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // --- Dramatic Choice (Çarpıcı Seçim) System --- // Çarpıcı seçimler: her 4-6 sahnede bir, yüksek risk/ödül, animasyonlu, barları büyük oranda etkiler var dramaticChoices = [{ id: "rebecca_room", text: "Rebecca ile iş gezisindesiniz. Aynı odada mı kalacaksınız, farklı mı?", portrait: "rebecca", speaker: "Rebecca", dramatic: true, options: [{ text: "Aynı odada kal", effects: { rebecca: 15, lust: 15, betray: 15 }, meta: { memoryLabel: "rebecca_room_same" } }, { text: "Farklı odada kal", effects: { honest: 10, rebecca: -5 }, meta: { memoryLabel: "rebecca_room_diff" } }] }, { id: "lisa_warns_alex", text: "Lisa seni, iş yerinde Alex ile fazla yakın görünmen konusunda uyarıyor. Tepkin ne olur?", portrait: "lisa", speaker: "Lisa", dramatic: true, options: [{ text: "Anlar ve saygı gösterirsin", effects: { lisa: 20, honest: 15 }, meta: { memoryLabel: "lisa_warns_respect" } }, { text: "Umursamaz davranırsın", effects: { lisa: -20, betray: 15 }, meta: { memoryLabel: "lisa_warns_ignore" } }] }, { id: "alex_secret", text: "Alex senden gizli bir bilgi istiyor. Paylaşacak mısın?", portrait: "alex", speaker: "Alex", dramatic: true, options: [{ text: "Paylaş", effects: { betray: 20, alex: 10 }, meta: { memoryLabel: "alex_secret_share" } }, { text: "Sakla", effects: { honest: 20, alex: -10 }, meta: { memoryLabel: "alex_secret_hide" } }] }, { id: "peter_lisa_fears", text: "Peter sana, Lisa ile ilgili endişelerini paylaşıyor. Ona inanacak mısın?", portrait: "peter", speaker: "Peter", dramatic: true, options: [{ text: "Evet", effects: { peter: 15, honest: 10 }, meta: { memoryLabel: "peter_lisa_believe" } }, { text: "Hayır", effects: { peter: -15, betray: 10 }, meta: { memoryLabel: "peter_lisa_deny" } }] }, { id: "rebecca_night", text: "Rebecca gece seni evine davet ediyor. Gidiyor musun?", portrait: "rebecca", speaker: "Rebecca", dramatic: true, options: [{ text: "Evet", effects: { rebecca: 20, lust: 15, betray: 20 }, meta: { memoryLabel: "rebecca_night_yes" } }, { text: "Hayır", effects: { honest: 15 }, meta: { memoryLabel: "rebecca_night_no" } }] }, { id: "lisa_serious_talk", text: "Lisa, seninle ciddi bir konuşma yapmak istiyor. Onu dinleyecek misin?", portrait: "lisa", speaker: "Lisa", dramatic: true, options: [{ text: "Dinle", effects: { lisa: 20, honest: 10 }, meta: { memoryLabel: "lisa_serious_listen" } }, { text: "Dinleme", effects: { lisa: -20, happy: -15 }, meta: { memoryLabel: "lisa_serious_ignore" } }] }, { id: "alex_secret_deal", text: "Alex ile gizli bir anlaşma teklif ediyor. Kabul edecek misin?", portrait: "alex", speaker: "Alex", dramatic: true, options: [{ text: "Evet", effects: { alex: 20, betray: 20 }, meta: { memoryLabel: "alex_deal_yes" } }, { text: "Hayır", effects: { honest: 20, alex: -15 }, meta: { memoryLabel: "alex_deal_no" } }] }, { id: "peter_big_secret", text: "Peter, seni büyük bir sırrı hakkında uyarıyor. Güveniyor musun?", portrait: "peter", speaker: "Peter", dramatic: true, options: [{ text: "Evet", effects: { peter: 20, honest: 10 }, meta: { memoryLabel: "peter_secret_trust" } }, { text: "Hayır", effects: { peter: -20, betray: 15 }, meta: { memoryLabel: "peter_secret_distrust" } }] }, { id: "rebecca_club", text: "Rebecca ile bir gece kulübünde dans ediyorsun. Daha yakın davranacak mısın?", portrait: "rebecca", speaker: "Rebecca", dramatic: true, options: [{ text: "Evet", effects: { rebecca: 15, lust: 15, betray: 10 }, meta: { memoryLabel: "rebecca_club_yes" } }, { text: "Hayır", effects: { honest: 10 }, meta: { memoryLabel: "rebecca_club_no" } }] }, { id: "lisa_gossip", text: "Lisa seni iş arkadaşlarınla ilgili dedikodulara karışmakla suçluyor. Savunacak mısın?", portrait: "lisa", speaker: "Lisa", dramatic: true, options: [{ text: "Savun", effects: { lisa: 10, honest: 15 }, meta: { memoryLabel: "lisa_gossip_defend" } }, { text: "Kabullen", effects: { lisa: -15, betray: 10 }, meta: { memoryLabel: "lisa_gossip_admit" } }] }, { id: "alex_promotion", text: "Alex, seni iş yerinde terfi ile ödüllendiriyor ama bir karşılık bekliyor. Kabul edecek misin?", portrait: "alex", speaker: "Alex", dramatic: true, options: [{ text: "Evet", effects: { alex: 25, betray: 25 }, meta: { memoryLabel: "alex_promotion_yes" } }, { text: "Hayır", effects: { honest: 20 }, meta: { memoryLabel: "alex_promotion_no" } }] }, { id: "peter_sacrifice", text: "Peter’in sana yardım etmek için büyük bir fedakarlık yapması gerekiyor. Kabul edecek misin?", portrait: "peter", speaker: "Peter", dramatic: true, options: [{ text: "Evet", effects: { peter: 25, happy: 15 }, meta: { memoryLabel: "peter_sacrifice_yes" } }, { text: "Hayır", effects: { peter: -20, betray: 10 }, meta: { memoryLabel: "peter_sacrifice_no" } }] }, { id: "rebecca_restaurant", text: "Rebecca, iş seyahatinde seni bir restoranda yalnız bırakıyor. Tek başına kalacak mısın yoksa kalabalığa mı karışacaksın?", portrait: "rebecca", speaker: "Rebecca", dramatic: true, options: [{ text: "Tek başına", effects: { rebecca: 10, lust: 10 }, meta: { memoryLabel: "rebecca_restaurant_alone" } }, { text: "Kalabalık", effects: { honest: 10 }, meta: { memoryLabel: "rebecca_restaurant_crowd" } }] }, { id: "lisa_memory", text: "Lisa sana eski bir anısını anlatıyor ve senden destek bekliyor. Onun yanında olacak mısın?", portrait: "lisa", speaker: "Lisa", dramatic: true, options: [{ text: "Evet", effects: { lisa: 20, happy: 15 }, meta: { memoryLabel: "lisa_memory_yes" } }, { text: "Hayır", effects: { lisa: -15 }, meta: { memoryLabel: "lisa_memory_no" } }] }, { id: "alex_ethics", text: "Alex’in zorlayıcı teklifine karşılık verirken etik dışı bir şey yapman isteniyor. Kabul mü?", portrait: "alex", speaker: "Alex", dramatic: true, options: [{ text: "Evet", effects: { alex: 20, betray: 25 }, meta: { memoryLabel: "alex_ethics_yes" } }, { text: "Hayır", effects: { honest: 20 }, meta: { memoryLabel: "alex_ethics_no" } }] }, { id: "peter_secret_share", text: "Peter seni beklenmedik bir şekilde büyük bir sırrını açıklıyor. Tepkin ne olur?", portrait: "peter", speaker: "Peter", dramatic: true, options: [{ text: "Sırlarınızı paylaşmaya devam edersin", effects: { peter: 20, honest: 15 }, meta: { memoryLabel: "peter_secret_share_yes" } }, { text: "Mesafeli olursun", effects: { peter: -15, betray: 10 }, meta: { memoryLabel: "peter_secret_share_no" } }] }, { id: "rebecca_bar_lisa", text: "Rebecca ile iş sonrası bara gittiniz. Lisa ile yüzleşmeye hazır mısın?", portrait: "rebecca", speaker: "Rebecca", dramatic: true, options: [{ text: "Evet", effects: { betray: 20, lust: 15, rebecca: 10 }, meta: { memoryLabel: "rebecca_bar_lisa_yes" } }, { text: "Hayır", effects: { honest: 15, lisa: 10 }, meta: { memoryLabel: "rebecca_bar_lisa_no" } }] }, { id: "lisa_crisis", text: "Lisa sana, evlilikte bir kriz yaşıyor ve profesyonel yardım almak istiyor. Destek verir misin?", portrait: "lisa", speaker: "Lisa", dramatic: true, options: [{ text: "Evet", effects: { lisa: 25, happy: 20 }, meta: { memoryLabel: "lisa_crisis_yes" } }, { text: "Hayır", effects: { lisa: -25 }, meta: { memoryLabel: "lisa_crisis_no" } }] }, { id: "alex_risk", text: "Alex, kariyerin için büyük bir tehlike barındıran bir riski göze almana izin veriyor. Kabul mü?", portrait: "alex", speaker: "Alex", dramatic: true, options: [{ text: "Evet", effects: { alex: 30, betray: 30 }, meta: { memoryLabel: "alex_risk_yes" } }, { text: "Hayır", effects: { honest: 20 }, meta: { memoryLabel: "alex_risk_no" } }] }, { id: "peter_conflict", text: "Peter ile aranızda aniden büyük bir anlaşmazlık çıkıyor. Özür dileyecek misin?", portrait: "peter", speaker: "Peter", dramatic: true, options: [{ text: "Evet", effects: { peter: 20, happy: 15 }, meta: { memoryLabel: "peter_conflict_yes" } }, { text: "Hayır", effects: { peter: -20, betray: 15 }, meta: { memoryLabel: "peter_conflict_no" } }] }]; // Dramatic choice frequency: every 4-6 turns, randomize var nextDramaticTurn = 4 + Math.floor(Math.random() * 3); var dramaticHistory = []; // Helper: get a random dramatic choice not recently shown function getDramaticChoice() { var available = []; for (var i = 0; i < dramaticChoices.length; i++) { if (dramaticHistory.indexOf(dramaticChoices[i].id) === -1) { available.push(dramaticChoices[i]); } } // If all have been shown, reset history if (available.length === 0) { dramaticHistory = []; available = dramaticChoices.slice(); } var idx = Math.floor(Math.random() * available.length); return available[idx]; } // Show a dramatic choice with animation, music pause, and shadow overlay function showDramaticChoice() { // Remove old option buttons for (var i = 0; i < optionButtons.length; i++) { game.removeChild(optionButtons[i]); } optionButtons = []; // Pick a dramatic choice var node = getDramaticChoice(); dramaticHistory.push(node.id); // Pause music (if any) if (typeof LK.stopMusic === "function") LK.stopMusic(); // Shadow overlay if (!game._dramaticShadow) { var shadow = LK.getAsset('bar_bg', { anchorX: 0, anchorY: 0 }); shadow.width = 2048; shadow.height = 2732; shadow.x = 0; shadow.y = 0; shadow.alpha = 0.0; shadow.zIndex = 99; game.addChild(shadow); game._dramaticShadow = shadow; tween.create(shadow).to({ alpha: 0.7 }, 400).start(); } // Portrait if (portraitNode && node.portrait && LK.getAsset(node.portrait, {})) { portraitNode.texture = LK.getAsset(node.portrait, {}).texture; portraitNode.tint = 0xffffff; } // Speaker if (speakerText) speakerText.setText(node.speaker ? node.speaker : ''); // Story text if (storyText) { storyText.setText(node.text); storyText.alpha = 0.0; tween.create(storyText).to({ alpha: 1 }, 400).start(); } // Dramatic option buttons: animated grow/shrink for (var i = 0; i < node.options.length; i++) { (function (opt, idx) { var btn = new OptionButton(); btn.setText(opt.text); btn.x = 2048 / 2; btn.y = 1700 + idx * 220; btn.scale.x = 0.7; btn.scale.y = 0.7; btn.alpha = 0.0; btn.bg.tint = 0x222222; btn.text.style.fill = '#fff'; btn.zIndex = 100; game.addChild(btn); optionButtons.push(btn); // Animate: grow in, pulse tween.create(btn).to({ alpha: 1, scaleX: 1.1, scaleY: 1.1 }, 300).start().onComplete(function () { tween.create(btn).to({ scaleX: 1.0, scaleY: 1.0 }, 200).start(); }); btn.setCallback(function () { // Remove shadow overlay if (game._dramaticShadow) { tween.create(game._dramaticShadow).to({ alpha: 0 }, 300).start().onComplete(function () { game.removeChild(game._dramaticShadow); game._dramaticShadow = null; }); } // Remove buttons with fade for (var j = 0; j < optionButtons.length; j++) { (function (b) { tween.create(b).to({ alpha: 0 }, 200).start().onComplete(function () { game.removeChild(b); }); })(optionButtons[j]); } optionButtons = []; // Apply effects (dramatic: +10~+30 or -30) applyDramaticEffects(opt.effects, opt.meta); // Resume music (if any) if (typeof LK.playMusic === "function") LK.playMusic('musicId'); // Next dramatic turn: 4-6 turns later nextDramaticTurn = turnCount + 4 + Math.floor(Math.random() * 3); // Continue with normal story LK.setTimeout(function () { var nextIdx = getNextNode(); currentNode = nextIdx; showStoryNode(currentNode); }, 600); }); })(node.options[i], i); } } // Apply dramatic effects: bar changes are much larger function applyDramaticEffects(effects, meta) { if (!effects) return; // Record memory if (meta && meta.memoryLabel) pastChoices.push(meta.memoryLabel); // Dramatic: apply full effect value (not just +1/-1) if (typeof effects.lisa === 'number') rel_lisa = Math.max(0, Math.min(100, rel_lisa + effects.lisa)); if (typeof effects.rebecca === 'number') rel_rebecca = Math.max(0, Math.min(100, rel_rebecca + effects.rebecca)); if (typeof effects.peter === 'number') rel_peter = Math.max(0, Math.min(100, rel_peter + effects.peter)); if (typeof effects.alex === 'number') rel_alex = Math.max(0, Math.min(100, rel_alex + effects.alex)); if (typeof effects.happy === 'number') bar_happy = Math.max(0, Math.min(100, bar_happy + effects.happy)); if (typeof effects.honest === 'number') bar_honest = Math.max(0, Math.min(100, bar_honest + effects.honest)); if (typeof effects.lust === 'number') bar_lust = Math.max(0, Math.min(100, bar_lust + effects.lust)); if (typeof effects.betray === 'number') bar_betray = Math.max(0, Math.min(100, bar_betray + effects.betray)); // Shadow bar: dramatic choices have bigger impact if (typeof effects.betray === 'number' && effects.betray > 0) bar_shadow = Math.max(0, Math.min(100, bar_shadow + 10)); if (typeof effects.honest === 'number' && effects.honest > 0) bar_shadow = Math.max(0, bar_shadow - 5); updateBars(); turnCount++; // Cross effects applyCrossEffects(effects, meta); // Check for ending if (bar_happy <= 0) { showEnding('Mutluluk sıfırlandı. Mike depresyona girdi.'); return; } if (bar_honest <= 0) { showEnding('Dürüstlük sıfırlandı. Mike yalanlarla dolu bir hayata saplandı.'); return; } if (bar_lust <= 0) { showEnding('Şehvet sıfırlandı. Mike hayattan keyif alamıyor.'); return; } if (bar_betray >= 100) { showEnding('İhanet %100 oldu. Mike ilişkilerini kaybetti.'); return; } } // Each story node: { text, options: [ {text, effects, next} ], portrait, speaker } // --- Story Data --- // Character portraits (simple colored boxes for now) // Bar backgrounds and fills // Option buttons var story = [ // Lisa kahvaltı - düşük ilişki { id: "lisa_breakfast_low", text: "Lisa sabah kahvaltı hazırlamış ama aranız biraz soğuk. Mike ne der?", portrait: 'lisa', speaker: 'Lisa', mood: "sad", barCheck: { key: "lisa", max: 40 }, options: [{ text: "Yine mi aynı şey, biraz değişiklik yap.", effects: { lisa: -10, happy: -5 }, meta: { type: "truth" }, next: null }, { text: "Teşekkür etmeden geçiştir.", effects: { lisa: -5 }, meta: { type: "lie" }, next: null }] }, // Lisa kahvaltı - orta ilişki { id: "lisa_breakfast_mid", text: "Lisa sabah kahvaltı hazırlamış. Mike ne der?", portrait: 'lisa', speaker: 'Lisa', mood: "neutral", barCheck: { key: "lisa", min: 41, max: 80 }, regretTrigger: "lied", options: [{ text: "Çok güzel olmuş, teşekkür ederim.", effects: { lisa: 10, happy: 5 }, next: null }, { text: "Yine mi aynı şey, biraz değişiklik yap.", effects: { lisa: -10, happy: -5 }, meta: { type: "lie" }, next: null }] }, // Lisa kahvaltı - yüksek ilişki { id: "lisa_breakfast_high", text: "Lisa sabah kahvaltı hazırlamış, aranız çok iyi. Mike ne der?", portrait: 'lisa', speaker: 'Lisa', mood: "happy", barCheck: { key: "lisa", min: 81 }, options: [{ text: "Sana her gün teşekkür etsem az, harikasın.", effects: { lisa: 10, happy: 10 }, next: null }, { text: "Bugün de seninle kahvaltı yapmak çok güzel.", effects: { lisa: 5, happy: 5 }, next: null }] }, // Rebecca sabah mesaj - düşük ilişki { id: "rebecca_morning_low", text: "Rebecca sabah mesaj atıyor ama aranız biraz soğuk: 'Günaydın, öğle arasında buluşalım mı?'", portrait: 'rebecca', speaker: 'Rebecca', mood: "sad", barCheck: { key: "rebecca", max: 40 }, options: [{ text: "Şu an yoğunum, sonra konuşuruz.", effects: { rebecca: -5, honest: 5 }, meta: { type: "truth" }, next: null }, { text: "Kısa cevap ver.", effects: { rebecca: -5 }, meta: { type: "lie" }, next: null }] }, // Rebecca sabah mesaj - orta ilişki { id: "rebecca_morning_mid", text: "Rebecca sabah mesaj atıyor: 'Günaydın, öğle arasında buluşalım mı?'", portrait: 'rebecca', speaker: 'Rebecca', mood: "neutral", barCheck: { key: "rebecca", min: 41, max: 80 }, options: [{ text: "Tabii, öğle arasında buluşalım.", effects: { rebecca: 10, lust: 5, betray: 5 }, next: null }, { text: "Şu an yoğunum, sonra konuşuruz.", effects: { rebecca: -5, honest: 5 }, next: null }] }, // Rebecca sabah mesaj - yüksek ilişki { id: "rebecca_morning_high", text: "Rebecca sabah mesaj atıyor, aranız çok iyi: 'Günaydın yakışıklı, öğle arasında buluşalım mı?'", portrait: 'rebecca', speaker: 'Rebecca', mood: "happy", barCheck: { key: "rebecca", min: 81 }, options: [{ text: "Seni görmek için sabırsızlanıyorum.", effects: { rebecca: 10, lust: 10, betray: 10 }, next: null }, { text: "Bugün işim var ama akşam konuşalım.", effects: { rebecca: 5, honest: 5 }, next: null }] }, // ... (diğer orijinal story node'lar buraya eklenebilir, örnek olarak ilk iki olay çoğaltıldı) // 3 { text: "Patronun Alex seni sert bir şekilde eleştiriyor. Ne yaparsın?", portrait: 'alex', speaker: 'Alex', mood: "angry", options: [{ text: "Haklısınız, daha dikkatli olacağım.", effects: { alex: 10, honest: 5, happy: -5 }, next: null }, { text: "Bana fazla yükleniyorsunuz, adil değil.", effects: { alex: -10, happy: -5 }, next: null }] }, // 3 { text: "Patronun Alex seni sert bir şekilde eleştiriyor. Ne yaparsın?", portrait: 'alex', speaker: 'Alex', mood: "angry", options: [{ text: "Haklısınız, daha dikkatli olacağım.", effects: { alex: 10, honest: 5, happy: -5 }, next: null }, { text: "Bana fazla yükleniyorsunuz, adil değil.", effects: { alex: -10, happy: -5 }, next: null }] }, // 4 { text: "Peter zor durumda olduğunu söylüyor. Ne yaparsın?", portrait: 'peter', speaker: 'Peter', mood: "sad", options: [{ text: "Yanındayım, neye ihtiyacın varsa söyle.", effects: { peter: 10, happy: 5 }, next: null }, { text: "Kendi işimle meşgulüm, üzgünüm.", effects: { peter: -10, happy: -5 }, next: null }] }, // 5 { text: "Lisa seninle dürüstçe konuşmak istiyor. Ne yaparsın?", portrait: 'lisa', speaker: 'Lisa', options: [{ text: "Tabii, ne söylemek istiyorsan dinliyorum.", effects: { lisa: 10, honest: 10 }, next: null }, { text: "Bunları konuşmak istemiyorum.", effects: { lisa: -10, honest: -10 }, next: null }] }, // 6 { text: "Rebecca ile ofiste samimi bir an yaşıyorsun. Lisa yanında.", portrait: 'rebecca', speaker: 'Rebecca', options: [{ text: "Lisa burada, sonra konuşalım.", effects: { rebecca: -5, honest: 5 }, next: null }, { text: "Hemen sana geliyorum.", effects: { rebecca: 10, lisa: -10, betray: 10 }, next: null }] }, // 7 { text: "Yorgunsun, Lisa dışarı çıkmak istiyor.", portrait: 'lisa', speaker: 'Lisa', options: [{ text: "Bugün yorgunum, evde kalalım.", effects: { lisa: -5, happy: -5 }, next: null }, { text: "Tamam, seninle dışarı çıkalım.", effects: { lisa: 10, happy: 5 }, next: null }] }, // 8 { text: "Alex önemli bir projeyi sana teslim etti.", portrait: 'alex', speaker: 'Alex', mood: "neutral", options: [{ text: "Gerçekçi zaman verirsek başarı şansı artar.", effects: { alex: 10, honest: 10 }, next: null }, { text: "Mümkün olduğunca hızlı yapacağım, sorun yok.", effects: { alex: -5, happy: 5 }, next: null }] }, // 9 { text: "Peter geçmişte yaptığın bir hatayı hatırlatıyor.", portrait: 'peter', speaker: 'Peter', mood: "angry", regretTrigger: "ignored_peter", options: [{ text: "Haklısın, özür dilerim.", effects: { peter: 10, honest: 10 }, next: null }, { text: "O günler geçti, unutalım.", effects: { peter: -10 }, meta: { ignoreRegret: true }, next: null }] }, // 10 { text: "Lisa bir sır sakladığını düşünüyor.", portrait: 'lisa', speaker: 'Lisa', regretTrigger: "betrayed_lisa", options: [{ text: "Sana her şeyi anlatacağım.", effects: { lisa: 10, honest: 10 }, next: null }, { text: "Beni yanlış anlıyorsun.", effects: { lisa: -10, honest: -10 }, meta: { type: "lie" }, next: null }] }, // 11 { text: "Rebecca ile iş çıkışı kafede buluşuyorsun.", portrait: 'rebecca', speaker: 'Rebecca', options: [{ text: "Rebecca ile samimi bir sohbet et.", effects: { rebecca: 10, lust: 10, betray: 5 }, next: null }, { text: "Kısa kesip eve git.", effects: { rebecca: -5, lisa: 5, honest: 5 }, next: null }] }, // 12 { text: "Alex seni fazla mesaiye bırakmak istiyor.", portrait: 'alex', speaker: 'Alex', mood: "neutral", options: [{ text: "Kabul et, işini bitir.", effects: { alex: 10, happy: -5 }, next: null }, { text: "Reddet, eve git.", effects: { alex: -10, lisa: 5, happy: 5 }, next: null }] }, // 13 { text: "Peter ile eski günlerden konuşuyorsun.", portrait: 'peter', speaker: 'Peter', mood: "happy", options: [{ text: "Duygusal bir anı paylaş.", effects: { peter: 10, happy: 5 }, next: null }, { text: "Geçmişi geçiştir.", effects: { peter: -5 }, next: null }] }, // 14 { text: "Lisa ile romantik bir akşam yemeği.", portrait: 'lisa', speaker: 'Lisa', options: [{ text: "Lisa'ya iltifat et.", effects: { lisa: 10, happy: 10, lust: 5 }, next: null }, { text: "Yemekle ilgilenme, telefona bak.", effects: { lisa: -10, happy: -5, lust: -5 }, next: null }] }, // 15 { text: "Rebecca işte sana yardım ediyor.", portrait: 'rebecca', speaker: 'Rebecca', options: [{ text: "Teşekkür et, birlikte çalış.", effects: { rebecca: 10, honest: 5 }, next: null }, { text: "Yardımı reddet.", effects: { rebecca: -5 }, next: null }] }, // 16 { text: "Alex işte bir hata buldu.", portrait: 'alex', speaker: 'Alex', mood: "angry", options: [{ text: "Hatanı kabul et.", effects: { alex: 5, honest: 10 }, next: null }, { text: "Suçu başkasına at.", effects: { alex: -10, honest: -10, betray: 10 }, next: null }] }, // 17 { text: "Peter ile tartıştın.", portrait: 'peter', speaker: 'Peter', mood: "angry", options: [{ text: "Barışmak için adım at.", effects: { peter: 10, honest: 5 }, next: null }, { text: "Görmezden gel.", effects: { peter: -10, happy: -5 }, next: null }] }, // 18 { text: "Lisa ile hafta sonu planı yapıyorsun.", portrait: 'lisa', speaker: 'Lisa', options: [{ text: "Birlikte sinemaya git.", effects: { lisa: 10, happy: 5 }, next: null }, { text: "Evde kalmayı teklif et.", effects: { lisa: -5, happy: 5 }, next: null }] }, // 19 { text: "Rebecca ile iş gezisine çıkıyorsun.", portrait: 'rebecca', speaker: 'Rebecca', options: [{ text: "Samimi davran.", effects: { rebecca: 10, lust: 10, betray: 5 }, next: null }, { text: "Mesafeni koru.", effects: { rebecca: -5, honest: 5 }, next: null }] }, // 20 { text: "Alex yeni bir görev veriyor.", portrait: 'alex', speaker: 'Alex', mood: "neutral", options: [{ text: "Görevi kabul et.", effects: { alex: 10, happy: 5 }, next: null }, { text: "Görevi reddet.", effects: { alex: -10, happy: -5 }, next: null }] }]; // --- State --- // Relationship values (0-100) var rel_lisa = 50; var rel_rebecca = 50; var rel_peter = 50; var rel_alex = 50; // Bars (0-100) var bar_happy = 50; var bar_honest = 50; var bar_lust = 50; var bar_betray = 50; // --- Shadow bar (0-100, hidden from player) --- var bar_shadow = 0; // Bar-based flags (for special scenes/endings) var flags = {}; // Track important past choices for memory mechanic var pastChoices = []; // Turn counter for time-based triggers var turnCount = 0; // Current story node var currentNode = 0; // --- UI Elements --- // Portrait var portraitNode = null; // Speaker name var speakerText = null; // Story text var storyText = null; // Option buttons var optionButtons = []; // Relationship bars var barNodes = {}; // Karakter portreleri ve ilişki dereceleri için UI var characterPortraits = []; var characterLabels = []; // --- Functions --- // getNextNode: uygun story node'unu bar değerine göre seç function getNextNode() { // Tüm story node'larını karıştır var indices = []; for (var i = 0; i < story.length; i++) { indices.push(i); } // Fisher-Yates shuffle for (var i = indices.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = indices[i]; indices[i] = indices[j]; indices[j] = temp; } // Her bir node'u sırayla kontrol et, barCheck varsa uygun olanı döndür for (var k = 0; k < indices.length; k++) { var idx = indices[k]; var node = story[idx]; if (!node.options || node.options.length === 0) continue; if (node.barCheck) { var key = node.barCheck.key; var min = typeof node.barCheck.min === "number" ? node.barCheck.min : -Infinity; var max = typeof node.barCheck.max === "number" ? node.barCheck.max : Infinity; var val = 0; if (key === "lisa") val = rel_lisa;else if (key === "rebecca") val = rel_rebecca;else if (key === "peter") val = rel_peter;else if (key === "alex") val = rel_alex;else if (key === "happy") val = bar_happy;else if (key === "honest") val = bar_honest;else if (key === "lust") val = bar_lust;else if (key === "betray") val = bar_betray; if (val >= min && val <= max) { return idx; } } else { // barCheck yoksa, her zaman seçilebilir return idx; } } // Hiçbiri uygun değilse ilk node'u döndür return 0; } function resetGameState() { rel_lisa = 50; rel_rebecca = 50; rel_peter = 50; rel_alex = 50; bar_happy = 50; bar_honest = 50; bar_lust = 50; bar_betray = 50; bar_shadow = 0; flags = {}; pastChoices = []; turnCount = 0; currentNode = 0; // Reset dramatic system nextDramaticTurn = 4 + Math.floor(Math.random() * 3); dramaticHistory = []; if (game._dramaticShadow) { game.removeChild(game._dramaticShadow); game._dramaticShadow = null; } } function createUI() { // Portrait if (portraitNode) game.removeChild(portraitNode); portraitNode = LK.getAsset('mike', { anchorX: 0.5, anchorY: 0.5 }); portraitNode.x = 2048 / 2; portraitNode.y = 400; game.addChild(portraitNode); // Speaker if (speakerText) game.removeChild(speakerText); speakerText = new Text2('', { size: 64, fill: '#ffffff' }); speakerText.anchor.set(0.5, 0.5); speakerText.x = 2048 / 2; speakerText.y = 700; game.addChild(speakerText); // Story text if (storyText) game.removeChild(storyText); storyText = new Text2('', { size: 54, fill: '#ffffff', wordWrap: true, wordWrapWidth: 1800 }); storyText.anchor.set(0.5, 0); storyText.x = 2048 / 2; storyText.y = 800; game.addChild(storyText); // Relationship bars var barNames = [{ key: 'happy', label: 'Mutluluk', y: 1100, val: bar_happy }, { key: 'honest', label: 'Dürüstlük', y: 1180, val: bar_honest }, { key: 'lust', label: 'Şehvet', y: 1260, val: bar_lust }, { key: 'betray', label: 'İhanet', y: 1340, val: bar_betray }]; for (var i = 0; i < barNames.length; i++) { var b = barNames[i]; if (barNodes[b.key]) game.removeChild(barNodes[b.key]); var bar = new RelationshipBar(); bar.setType(b.key); bar.setValue(b.val); // Bar ismi ve yüzdeyi birlikte göster if (bar.label) bar.removeChild(bar.label); bar.label = new Text2(b.label + ' (' + b.val + '%)', { size: 36, fill: '#ffffff' }); bar.label.anchor.set(1, 0.5); bar.label.x = bar.maxWidth + 20; bar.label.y = 20; bar.addChild(bar.label); bar.x = 2048 / 2 - 200; bar.y = b.y; game.addChild(bar); barNodes[b.key] = bar; } // Karakter portreleri ve ilişki dereceleri (en altta) for (var i = 0; i < characterPortraits.length; i++) { game.removeChild(characterPortraits[i]); } for (var i = 0; i < characterLabels.length; i++) { game.removeChild(characterLabels[i]); } characterPortraits = []; characterLabels = []; var chars = [{ key: 'lisa', label: 'Lisa', rel: rel_lisa }, { key: 'rebecca', label: 'Rebecca', rel: rel_rebecca }, { key: 'peter', label: 'Peter', rel: rel_peter }, { key: 'alex', label: 'Alex', rel: rel_alex }]; var startX = 2048 / 2 - 400 - 60; var y = 2600; for (var i = 0; i < chars.length; i++) { var c = chars[i]; var portrait = LK.getAsset(c.key, { anchorX: 0.5, anchorY: 1 }); portrait.x = startX + i * 270; portrait.y = y; game.addChild(portrait); characterPortraits.push(portrait); var label = new Text2(c.label + ': ' + c.rel + '%', { size: 44, fill: '#ffffff' }); label.anchor.set(0.5, 0); label.x = portrait.x; label.y = y + 10; game.addChild(label); characterLabels.push(label); } } function updateBars() { barNodes['happy'].setValue(bar_happy); barNodes['honest'].setValue(bar_honest); barNodes['lust'].setValue(bar_lust); barNodes['betray'].setValue(bar_betray); // Bar isimleri ve yüzdeleri birlikte güncellensin barNodes['happy'].label.setText('Mutluluk (' + bar_happy + '%)'); barNodes['honest'].label.setText('Dürüstlük (' + bar_honest + '%)'); barNodes['lust'].label.setText('Şehvet (' + bar_lust + '%)'); barNodes['betray'].label.setText('İhanet (' + bar_betray + '%)'); // Karakter ilişki dereceleri güncellensin var rels = [rel_lisa, rel_rebecca, rel_peter, rel_alex]; for (var i = 0; i < characterLabels.length; i++) { var names = ['Lisa', 'Rebecca', 'Peter', 'Alex']; characterLabels[i].setText(names[i] + ': ' + rels[i] + '%'); } } function showStoryNode(idx) { // Remove old option buttons for (var i = 0; i < optionButtons.length; i++) { game.removeChild(optionButtons[i]); } optionButtons = []; // Dramatic choice injection: if turnCount >= nextDramaticTurn, show dramatic choice instead if (typeof nextDramaticTurn !== "undefined" && turnCount >= nextDramaticTurn) { showDramaticChoice(); return; } var node = story[idx]; // Portrait if (portraitNode) { if (node.portrait && LK.getAsset(node.portrait, {})) { portraitNode.texture = LK.getAsset(node.portrait, {}).texture; } // Mood-based tint or background for Lisa, Rebecca, Mike, Peter, Alex if (node.mood && (node.portrait === "lisa" || node.portrait === "rebecca" || node.portrait === "mike" || node.portrait === "peter" || node.portrait === "alex")) { // Mood to tint mapping var moodTints = { happy: 0x7ed321, sad: 0x4a90e2, angry: 0xd0021b, neutral: 0xffffff }; var tint = moodTints[node.mood] !== undefined ? moodTints[node.mood] : 0xffffff; portraitNode.tint = tint; } else { portraitNode.tint = 0xffffff; } // Remove any previous related character portrait if (game.relatedPortraitNode) { game.removeChild(game.relatedPortraitNode); game.relatedPortraitNode = null; } // If the node is about a character other than Mike, show that character next to Mike if (node.portrait && node.portrait !== "mike" && (node.portrait === "lisa" || node.portrait === "rebecca" || node.portrait === "peter" || node.portrait === "alex")) { var relatedPortrait = LK.getAsset(node.portrait, { anchorX: 0.5, anchorY: 0.5 }); // Place to the right of Mike, with a small gap relatedPortrait.x = portraitNode.x + portraitNode.width / 2 + relatedPortrait.width / 2 + 40; relatedPortrait.y = portraitNode.y; // Mood tint for related portrait if (node.mood) { var moodTints = { happy: 0x7ed321, sad: 0x4a90e2, angry: 0xd0021b, neutral: 0xffffff }; relatedPortrait.tint = moodTints[node.mood] !== undefined ? moodTints[node.mood] : 0xffffff; } else { relatedPortrait.tint = 0xffffff; } game.addChild(relatedPortrait); game.relatedPortraitNode = relatedPortrait; } else { if (game.relatedPortraitNode) { game.removeChild(game.relatedPortraitNode); game.relatedPortraitNode = null; } } } // Speaker if (speakerText) { speakerText.setText(node.speaker ? node.speaker : ''); } // Story text if (storyText) { // --- Hatırlatma ve Gölgeli Vicdan Mekanizması --- // 1. Eğer bu node bir regretTrigger içeriyorsa ve geçmişte ilgili regretLabel ile bir seçim yapıldıysa, iç ses/rüya olarak göster if (node.regretTrigger && pastChoices.indexOf(node.regretTrigger) !== -1) { // Vicdan sahnesi: iç ses veya rüya efektiyle göster var regretTexts = { "lied": "Gece rüyanda, Lisa'nın sana 'Bana neden yalan söyledin?' dediğini duyuyorsun. Vicdanın sızlıyor.", "betrayed_lisa": "Bir an için Lisa'nın gözlerinde hayal kırıklığını görüyorsun. İç sesin: 'Ona ihanet ettin.'", "ignored_peter": "Peter'ın üzgün bakışları aklından çıkmıyor. İç sesin: 'Dostunu yalnız bıraktın.'" }; var regretText = regretTexts[node.regretTrigger] || "Geçmişteki bir kararın gölgesi seni rahatsız ediyor."; storyText.setText(regretText + "\n\n(" + node.text + ")"); // Fade efekt: metni kısa süreliğine yarı saydam göster storyText.alpha = 0.5; tween.create(storyText).to({ alpha: 1 }, 1200).start(); } else if ( // Yalancı Hafıza: Eğer honest bar düşükse ve geçmişte yalan söylendiyse, yanlış hatırlama metni göster bar_honest <= 30 && pastChoices.indexOf("lied") !== -1 && (node.id === "lisa_breakfast_mid" || node.id === "lisa_breakfast_high" || node.id === "lisa_breakfast_low")) { // Yalancı hafıza: Oyuncuya yanlış bilgi ver storyText.setText("Mike sanki o gün Lisa'ya doğruyu söylediğini hatırlıyordu... ama aslında yalan söylemişti.\n\n(" + node.text + ")"); storyText.alpha = 0.7; tween.create(storyText).to({ alpha: 1 }, 1200).start(); } else if (node.id === "lisa_breakfast_mid" && pastChoices.indexOf("lied") !== -1) { storyText.setText("Lisa sana biraz mesafeli bakıyor. Geçmişteki yalanların etkisi sürüyor."); } else { storyText.setText(node.text); } } // Option buttons // --- Timed Choice Mechanism: If node.timedChoice is set, start a timer and auto-select if no choice is made --- var timedChoiceTimeout = null; var timedChoiceBar = null; if (node.options && node.options.length > 0) { // If previous timer exists, clear it if (game._timedChoiceTimeout) { LK.clearTimeout(game._timedChoiceTimeout); game._timedChoiceTimeout = null; } if (game._timedChoiceBar) { game.removeChild(game._timedChoiceBar); game._timedChoiceBar = null; } // If this node is a crisis/timed scene, e.g. node.timedChoice: { seconds: 5, default: 1 } var isTimed = node.timedChoice && typeof node.timedChoice.seconds === "number"; var timedSeconds = isTimed ? node.timedChoice.seconds : 0; var timedDefault = isTimed ? typeof node.timedChoice["default"] === "number" ? node.timedChoice["default"] : 0 : 0; var timedStart = Date.now(); var timedBarWidth = 900; var timedBarHeight = 24; var timedBarY = 1700 + node.options.length * 180 + 40; // Option button creation for (var i = 0; i < node.options.length; i++) { var opt = node.options[i]; // --- Requirements check --- var meetsReq = true; if (opt.requirements) { for (var key in opt.requirements) { var val = opt.requirements[key]; // Check current bar/relationship value var current = 0; if (key === 'lisa') current = rel_lisa;else if (key === 'rebecca') current = rel_rebecca;else if (key === 'peter') current = rel_peter;else if (key === 'alex') current = rel_alex;else if (key === 'happy') current = bar_happy;else if (key === 'honest') current = bar_honest;else if (key === 'lust') current = bar_lust;else if (key === 'betray') current = bar_betray; if (current < val) { meetsReq = false; break; } } } var btn = new OptionButton(); // --- Bilinmeyen Seçim Sistemi: option'a hiddenByBar eklendiyse ve bar yeterli değilse gizle --- var showAsHidden = false; if (opt.hiddenByBar) { // hiddenByBar: { key: 'honest', min: 60 } veya { key: 'betray', min: 40 } var barKey = opt.hiddenByBar.key; var minVal = typeof opt.hiddenByBar.min === "number" ? opt.hiddenByBar.min : 0; var currentVal = 0; if (barKey === 'lisa') currentVal = rel_lisa;else if (barKey === 'rebecca') currentVal = rel_rebecca;else if (barKey === 'peter') currentVal = rel_peter;else if (barKey === 'alex') currentVal = rel_alex;else if (barKey === 'happy') currentVal = bar_happy;else if (barKey === 'honest') currentVal = bar_honest;else if (barKey === 'lust') currentVal = bar_lust;else if (barKey === 'betray') currentVal = bar_betray; if (currentVal < minVal) showAsHidden = true; } if (showAsHidden) { btn.setText("???"); btn.bg.tint = 0x888888; btn.text.style.fill = '#bbbbbb'; btn.setCallback(function () {}); // No-op } else { btn.setText(opt.text); // If requirements not met, disable and gray out if (!meetsReq) { btn.bg.tint = 0x888888; btn.text.style.fill = '#bbbbbb'; btn.setCallback(function () {}); // No-op } else { btn.setCallback(function (opt, btnIdx) { return function () { // If a timed choice is running, clear the timer and bar if (game._timedChoiceTimeout) { LK.clearTimeout(game._timedChoiceTimeout); game._timedChoiceTimeout = null; } if (game._timedChoiceBar) { game.removeChild(game._timedChoiceBar); game._timedChoiceBar = null; } applyEffects(opt.effects, opt.meta); // Her zaman random bir sonraki soru seç, ama bar değerine göre uygun versiyonu seç var available = []; for (var j = 0; j < story.length; j++) { if (story[j].options && story[j].options.length > 0) available.push(j); } if (available.length > 0) { // getNextNode fonksiyonu ile uygun node'u seç var nextIdx = getNextNode(); currentNode = nextIdx; showStoryNode(currentNode); } else { // Oyun bitti, son ekranı göster showEnding(); } }; }(opt, i)); } } btn.x = 2048 / 2; btn.y = 1700 + i * 180; game.addChild(btn); optionButtons.push(btn); } // If this is a timed choice, show a timer bar and auto-select after timeout if (isTimed) { // Create a timer bar (background and fill) var barBg = LK.getAsset('bar_bg', { anchorX: 0.5, anchorY: 0.5 }); barBg.width = timedBarWidth; barBg.height = timedBarHeight; barBg.x = 2048 / 2; barBg.y = timedBarY; var barFill = LK.getAsset('bar_fill_betray', { anchorX: 0.5, anchorY: 0.5 }); barFill.width = timedBarWidth; barFill.height = timedBarHeight; barFill.x = 2048 / 2; barFill.y = timedBarY; // Add to game game.addChild(barBg); game.addChild(barFill); // Store for cleanup game._timedChoiceBar = barBg; game._timedChoiceBarFill = barFill; // Animate the bar fill var updateTimerBar = function updateTimerBar() { var elapsed = (Date.now() - timedStart) / 1000; var remain = Math.max(0, timedSeconds - elapsed); var ratio = remain / timedSeconds; barFill.width = timedBarWidth * ratio; if (ratio <= 0) { barFill.width = 0; } }; // Per-frame update for timer bar var timerBarInterval = LK.setInterval(function () { if (!game._timedChoiceBarFill) { LK.clearInterval(timerBarInterval); return; } updateTimerBar(); }, 50); // Timeout: auto-select default option game._timedChoiceTimeout = LK.setTimeout(function () { // Only trigger if still on this node if (game._timedChoiceBar) { // Simulate click on default option if (optionButtons[timedDefault] && typeof optionButtons[timedDefault].down === "function") { optionButtons[timedDefault].down(); } // Clean up timer bar if (game._timedChoiceBar) { game.removeChild(game._timedChoiceBar); game._timedChoiceBar = null; } if (game._timedChoiceBarFill) { game.removeChild(game._timedChoiceBarFill); game._timedChoiceBarFill = null; } LK.clearInterval(timerBarInterval); game._timedChoiceTimeout = null; } }, timedSeconds * 1000); } } } function applyEffects(effects, meta) { if (!effects) return; // --- Memory mechanic: record important choices --- // Example: If the player kisses Lisa, lies to Rebecca, etc. // We'll record meta.memoryLabel if present, otherwise try to infer from meta/type if (meta && meta.memoryLabel) { pastChoices.push(meta.memoryLabel); } else if (meta && meta.type === "lie") { pastChoices.push("lied"); // Regretful: lying is a regret } else if (meta && meta.type === "truth") { pastChoices.push("told_truth"); } // Regretful: betray Lisa if (typeof effects.lisa === 'number' && effects.lisa < 0 && typeof effects.betray === 'number' && effects.betray > 0) { pastChoices.push("betrayed_lisa"); } // Regretful: ignore Peter if (typeof effects.peter === 'number' && effects.peter < 0 && meta && meta.ignoreRegret) { pastChoices.push("ignored_peter"); } // Sadece yüzde 1 artıp azalsın if (typeof effects.lisa === 'number') rel_lisa = Math.max(0, Math.min(100, rel_lisa + (effects.lisa > 0 ? 1 : effects.lisa < 0 ? -1 : 0))); if (typeof effects.rebecca === 'number') rel_rebecca = Math.max(0, Math.min(100, rel_rebecca + (effects.rebecca > 0 ? 1 : effects.rebecca < 0 ? -1 : 0))); if (typeof effects.peter === 'number') rel_peter = Math.max(0, Math.min(100, rel_peter + (effects.peter > 0 ? 1 : effects.peter < 0 ? -1 : 0))); if (typeof effects.alex === 'number') rel_alex = Math.max(0, Math.min(100, rel_alex + (effects.alex > 0 ? 1 : effects.alex < 0 ? -1 : 0))); if (typeof effects.happy === 'number') bar_happy = Math.max(0, Math.min(100, bar_happy + (effects.happy > 0 ? 1 : effects.happy < 0 ? -1 : 0))); if (typeof effects.honest === 'number') bar_honest = Math.max(0, Math.min(100, bar_honest + (effects.honest > 0 ? 1 : effects.honest < 0 ? -1 : 0))); if (typeof effects.lust === 'number') bar_lust = Math.max(0, Math.min(100, bar_lust + (effects.lust > 0 ? 1 : effects.lust < 0 ? -1 : 0))); if (typeof effects.betray === 'number') bar_betray = Math.max(0, Math.min(100, bar_betray + (effects.betray > 0 ? 1 : effects.betray < 0 ? -1 : 0))); // --- Shadow bar logic: increase/decrease based on hidden triggers --- // Betrayal, repeated lies, or negative choices increase shadow bar if (meta && meta.type === "lie" || typeof effects.betray === 'number' && effects.betray > 0) { bar_shadow = Math.max(0, Math.min(100, bar_shadow + 5)); } // If player is honest or makes a positive choice, shadow bar may decrease if (meta && meta.type === "truth" || typeof effects.honest === 'number' && effects.honest > 0) { bar_shadow = Math.max(0, bar_shadow - 2); } // If player ignores Peter or Lisa (meta.ignoreRegret), shadow bar increases if (meta && meta.ignoreRegret) { bar_shadow = Math.max(0, Math.min(100, bar_shadow + 3)); } // --- Honest bar penalty for repeated lies --- if (meta && meta.type === "lie") { // Lying reduces honest bar by 2 (or 1 if already low) bar_honest = Math.max(0, bar_honest - (bar_honest > 10 ? 2 : 1)); } // --- Relationship Cross Effects --- applyCrossEffects(effects, meta); updateBars(); // --- Turn-based trigger system --- // Increase turn count on every choice turnCount++; // --- Dış Etki Mekanizması: Lust bar 3 tur boyunca yüksekse otomatik karar --- // Son 3 turdaki lust bar değerlerini takip et if (!flags.lustHistory) flags.lustHistory = []; flags.lustHistory.push(bar_lust); if (flags.lustHistory.length > 3) flags.lustHistory.shift(); // Eğer son 3 turda lust barı 70 ve üzeriyse, otomatik bir karar tetiklenir (ör: irade kaybı) if (flags.lustHistory.length === 3 && flags.lustHistory[0] >= 70 && flags.lustHistory[1] >= 70 && flags.lustHistory[2] >= 70 && !flags.lustAutoDecision) { flags.lustAutoDecision = true; // Oyuncunun kontrolü dışında bir olay: Rebecca ile yakınlaşma if (storyText) { storyText.setText("Mike, arzularına yenik düşüyor ve Rebecca'ya karşı koyamıyor. (Dış etki: İrade kaybı)"); storyText.alpha = 0.7; tween.create(storyText).to({ alpha: 1 }, 1200).start(); } // Bar ve ilişkilerde otomatik değişiklikler rel_rebecca = Math.min(100, rel_rebecca + 5); bar_lust = Math.min(100, bar_lust + 5); bar_betray = Math.min(100, bar_betray + 5); updateBars(); // Sonraki node'a otomatik geçiş (Rebecca ile ilgili bir sahneye öncelik ver) var rebeccaIdx = -1; for (var i = 0; i < story.length; i++) { if (story[i].portrait === "rebecca" && story[i].options && story[i].options.length > 0) { rebeccaIdx = i; break; } } if (rebeccaIdx !== -1) { currentNode = rebeccaIdx; LK.setTimeout(function () { showStoryNode(currentNode); }, 1800); return; } } // Zamana bağlı özel rüya sahnesi tetikleyici örneği if (turnCount > 15 && bar_lust > 60 && !flags["specialDreamTriggered"]) { flags["specialDreamTriggered"] = true; showEnding("Mike, arzularının peşinden sürüklendiği özel bir rüya görüyor. (Zamana bağlı özel sahne)"); return; } // --- Bar-based flag system --- // Example: if betrayal bar reaches 80 or more, set betrayalUnlocked flag if (bar_betray >= 80) { flags["betrayalUnlocked"] = true; } if (bar_honest >= 90) { flags["honestyMaster"] = true; } if (bar_lust >= 90) { flags["lustHigh"] = true; } if (bar_happy >= 90) { flags["happinessPeak"] = true; } if (rel_lisa >= 90) { flags["lisaBond"] = true; } if (rel_rebecca >= 90) { flags["rebeccaBond"] = true; } if (rel_peter >= 90) { flags["peterBond"] = true; } if (rel_alex >= 90) { flags["alexBond"] = true; } // --- Shadow bar event triggers (hidden, unexpected events) --- if (!flags.shadow30 && bar_shadow >= 30) { flags.shadow30 = true; // Ani içsel monolog: Mike'ın öfke patlaması if (storyText) { storyText.setText("Mike'ın içinde bir öfke kabarıyor. (İç ses: 'Bazen her şeyi yakıp yıkmak istiyorum...')\n\n" + (storyText.text || "")); storyText.alpha = 0.7; tween.create(storyText).to({ alpha: 1 }, 1000).start(); } } if (!flags.shadow60 && bar_shadow >= 60) { flags.shadow60 = true; // Mike'ın beklenmedik bir şekilde bağırması (oyuncuya yansır) if (storyText) { storyText.setText("Mike aniden bağırıyor: 'YETER ARTIK!'\n\n" + (storyText.text || "")); storyText.alpha = 0.7; tween.create(storyText).to({ alpha: 1 }, 1000).start(); } // Portrait kırmızıya döner, kısa süreliğine if (portraitNode) { var oldTint = portraitNode.tint; portraitNode.tint = 0xd0021b; tween.create(portraitNode).to({ tint: oldTint }, 1200).start(); } } if (!flags.shadow90 && bar_shadow >= 90) { flags.shadow90 = true; // Mike'ın içsel çöküşü: iç ses, portre fade out if (storyText) { storyText.setText("Mike'ın zihni karanlığa gömülüyor. (İç ses: 'Artık kendimi tanıyamıyorum...')\n\n" + (storyText.text || "")); storyText.alpha = 0.5; tween.create(storyText).to({ alpha: 1 }, 1500).start(); } if (portraitNode) { tween.create(portraitNode).to({ alpha: 0.2 }, 1500).start(); } } // Check for fail/win conditions if (bar_happy <= 0) { showEnding('Mutluluk sıfırlandı. Mike depresyona girdi.'); return; } if (bar_honest <= 0) { showEnding('Dürüstlük sıfırlandı. Mike yalanlarla dolu bir hayata saplandı.'); return; } if (bar_lust <= 0) { showEnding('Şehvet sıfırlandı. Mike hayattan keyif alamıyor.'); return; } if (bar_betray >= 100) { showEnding('İhanet %100 oldu. Mike ilişkilerini kaybetti.'); return; } } // İlişki çaprazlama mekanizması: Lisa ile yakınlık artınca Rebecca kıskanır, Rebecca ile yakınlık artınca Lisa üzülür, vs. function applyCrossEffects(effects, meta) { // Lisa ile yakınlık artarsa Rebecca'nın ilişkisi biraz azalır (kıskançlık) if (typeof effects.lisa === 'number' && effects.lisa > 0) { // Lisa ile +1 yakınlık, Rebecca -1 rel_rebecca = Math.max(0, rel_rebecca - 1); } // Rebecca ile yakınlık artarsa Lisa'nın ilişkisi biraz azalır (kıskançlık) if (typeof effects.rebecca === 'number' && effects.rebecca > 0) { rel_lisa = Math.max(0, rel_lisa - 1); } // Lisa ile yakınlık azalırsa Rebecca biraz mutlu olur (rekabet) if (typeof effects.lisa === 'number' && effects.lisa < 0) { rel_rebecca = Math.min(100, rel_rebecca + 1); } // Rebecca ile yakınlık azalırsa Lisa biraz mutlu olur (rekabet) if (typeof effects.rebecca === 'number' && effects.rebecca < 0) { rel_lisa = Math.min(100, rel_lisa + 1); } // Betray (ihanet) barı artarsa Lisa ve Rebecca'nın ilişkisi biraz azalır if (typeof effects.betray === 'number' && effects.betray > 0) { rel_lisa = Math.max(0, rel_lisa - 1); rel_rebecca = Math.max(0, rel_rebecca - 1); } // Lust barı çok artarsa (ör: Rebecca ile), Lisa'nın ilişkisi biraz azalır if (typeof effects.lust === 'number' && effects.lust > 0) { rel_lisa = Math.max(0, rel_lisa - 1); } // Happy barı çok azalırsa, tüm ilişkiler biraz azalır if (typeof effects.happy === 'number' && effects.happy < 0) { rel_lisa = Math.max(0, rel_lisa - 1); rel_rebecca = Math.max(0, rel_rebecca - 1); rel_peter = Math.max(0, rel_peter - 1); rel_alex = Math.max(0, rel_alex - 1); } } function showEnding(msg) { // Remove option buttons for (var i = 0; i < optionButtons.length; i++) { game.removeChild(optionButtons[i]); } optionButtons = []; // --- Animated, bar-specific game over --- // Determine which bar triggered game over var endingType = null; if (typeof msg === "string") { if (msg.indexOf("Mutluluk") !== -1) endingType = "happy";else if (msg.indexOf("Dürüstlük") !== -1) endingType = "honest";else if (msg.indexOf("Şehvet") !== -1) endingType = "lust";else if (msg.indexOf("İhanet") !== -1) endingType = "betray"; } // Default: Mike portrait var portraitKey = "mike"; var endingText = msg; var mood = "sad"; var crossX = null; // Custom portrait and text for each bar if (endingType === "betray") { // Mike gözaltına alınıyor portraitKey = "mike"; endingText = "SON: Mike ihanetin bedelini ödedi ve gözaltına alındı.\n\nYeniden başlamak için ekrana dokunun."; mood = "angry"; crossX = true; } else if (endingType === "lust") { // Lisa uzaklaşıyor portraitKey = "lisa"; endingText = "SON: Lisa, Mike'ın tutkularının sönmesiyle uzaklaştı.\n\nYeniden başlamak için ekrana dokunun."; mood = "sad"; crossX = true; } else if (endingType === "happy") { // Mike depresyona giriyor portraitKey = "mike"; endingText = "SON: Mike mutluluğunu kaybetti ve depresyona girdi.\n\nYeniden başlamak için ekrana dokunun."; mood = "sad"; crossX = false; } else if (endingType === "honest") { // Mike yalanlarla dolu bir hayata saplandı portraitKey = "mike"; endingText = "SON: Mike dürüstlüğünü kaybetti, yalanlarla dolu bir hayata saplandı.\n\nYeniden başlamak için ekrana dokunun."; mood = "angry"; crossX = true; } // Show ending text if (storyText) { if (endingText) { storyText.setText(endingText); } else if (msg) { storyText.setText('SON: ' + msg + '\n\nYeniden başlamak için ekrana dokunun.'); } else { storyText.setText('SON: Mike’ın hikayesi burada bitiyor.\n\nYeniden başlamak için ekrana dokunun.'); } } // Remove speaker if (speakerText) speakerText.setText(''); // Animate portrait: change to relevant character, mood tint, fade out, and cross if needed if (portraitNode) { // Change portrait image if (LK.getAsset(portraitKey, {})) { portraitNode.texture = LK.getAsset(portraitKey, {}).texture; } // Mood-based tint var moodTints = { happy: 0x7ed321, sad: 0x4a90e2, angry: 0xd0021b, neutral: 0xffffff }; var tint = moodTints[mood] !== undefined ? moodTints[mood] : 0xffffff; portraitNode.tint = tint; // Animate: fade out after 1.2s tween.create(portraitNode).to({ alpha: 0.3 }, 1200).start(); // If crossX, show a red cross over portrait if (crossX) { // Create a red cross using two rectangles (since we can't draw lines) var cross1 = LK.getAsset('bar_fill_betray', { anchorX: 0.5, anchorY: 0.5 }); var cross2 = LK.getAsset('bar_fill_betray', { anchorX: 0.5, anchorY: 0.5 }); // Set size and rotation for cross var size = Math.max(portraitNode.width, portraitNode.height) * 0.9; cross1.width = size; cross1.height = 24; cross2.width = size; cross2.height = 24; cross1.rotation = Math.PI / 4; cross2.rotation = -Math.PI / 4; cross1.alpha = 0.85; cross2.alpha = 0.85; cross1.x = portraitNode.x; cross1.y = portraitNode.y; cross2.x = portraitNode.x; cross2.y = portraitNode.y; cross1.zIndex = 100; cross2.zIndex = 100; game.addChild(cross1); game.addChild(cross2); // Animate cross: fade in, then fade out after 1.2s cross1.alpha = 0; cross2.alpha = 0; tween.create(cross1).to({ alpha: 0.85 }, 400).start(); tween.create(cross2).to({ alpha: 0.85 }, 400).start(); // Fade out after 1.2s LK.setTimeout(function () { tween.create(cross1).to({ alpha: 0 }, 600).start(); tween.create(cross2).to({ alpha: 0 }, 600).start(); LK.setTimeout(function () { game.removeChild(cross1); game.removeChild(cross2); }, 700); }, 1200); } } // Add restart handler game.down = function (x, y, obj) { game.down = null; restartGame(); }; } function restartGame() { resetGameState(); updateBars(); showStoryNode(currentNode); // Remove restart handler game.down = null; } // --- Start Game --- resetGameState(); createUI(); updateBars(); showStoryNode(currentNode); // --- No dragging or move events needed for this game --- // --- Game update (not used, but required for LK) --- game.update = function () { // No per-frame logic needed };
===================================================================
--- original.js
+++ change.js
@@ -97,9 +97,673 @@
/****
* Game Code
****/
-// Çok çeşitli, rastgele ilerleyen sorular havuzu
+// --- Dramatic Choice (Çarpıcı Seçim) System ---
+// Çarpıcı seçimler: her 4-6 sahnede bir, yüksek risk/ödül, animasyonlu, barları büyük oranda etkiler
+var dramaticChoices = [{
+ id: "rebecca_room",
+ text: "Rebecca ile iş gezisindesiniz. Aynı odada mı kalacaksınız, farklı mı?",
+ portrait: "rebecca",
+ speaker: "Rebecca",
+ dramatic: true,
+ options: [{
+ text: "Aynı odada kal",
+ effects: {
+ rebecca: 15,
+ lust: 15,
+ betray: 15
+ },
+ meta: {
+ memoryLabel: "rebecca_room_same"
+ }
+ }, {
+ text: "Farklı odada kal",
+ effects: {
+ honest: 10,
+ rebecca: -5
+ },
+ meta: {
+ memoryLabel: "rebecca_room_diff"
+ }
+ }]
+}, {
+ id: "lisa_warns_alex",
+ text: "Lisa seni, iş yerinde Alex ile fazla yakın görünmen konusunda uyarıyor. Tepkin ne olur?",
+ portrait: "lisa",
+ speaker: "Lisa",
+ dramatic: true,
+ options: [{
+ text: "Anlar ve saygı gösterirsin",
+ effects: {
+ lisa: 20,
+ honest: 15
+ },
+ meta: {
+ memoryLabel: "lisa_warns_respect"
+ }
+ }, {
+ text: "Umursamaz davranırsın",
+ effects: {
+ lisa: -20,
+ betray: 15
+ },
+ meta: {
+ memoryLabel: "lisa_warns_ignore"
+ }
+ }]
+}, {
+ id: "alex_secret",
+ text: "Alex senden gizli bir bilgi istiyor. Paylaşacak mısın?",
+ portrait: "alex",
+ speaker: "Alex",
+ dramatic: true,
+ options: [{
+ text: "Paylaş",
+ effects: {
+ betray: 20,
+ alex: 10
+ },
+ meta: {
+ memoryLabel: "alex_secret_share"
+ }
+ }, {
+ text: "Sakla",
+ effects: {
+ honest: 20,
+ alex: -10
+ },
+ meta: {
+ memoryLabel: "alex_secret_hide"
+ }
+ }]
+}, {
+ id: "peter_lisa_fears",
+ text: "Peter sana, Lisa ile ilgili endişelerini paylaşıyor. Ona inanacak mısın?",
+ portrait: "peter",
+ speaker: "Peter",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ peter: 15,
+ honest: 10
+ },
+ meta: {
+ memoryLabel: "peter_lisa_believe"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ peter: -15,
+ betray: 10
+ },
+ meta: {
+ memoryLabel: "peter_lisa_deny"
+ }
+ }]
+}, {
+ id: "rebecca_night",
+ text: "Rebecca gece seni evine davet ediyor. Gidiyor musun?",
+ portrait: "rebecca",
+ speaker: "Rebecca",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ rebecca: 20,
+ lust: 15,
+ betray: 20
+ },
+ meta: {
+ memoryLabel: "rebecca_night_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ honest: 15
+ },
+ meta: {
+ memoryLabel: "rebecca_night_no"
+ }
+ }]
+}, {
+ id: "lisa_serious_talk",
+ text: "Lisa, seninle ciddi bir konuşma yapmak istiyor. Onu dinleyecek misin?",
+ portrait: "lisa",
+ speaker: "Lisa",
+ dramatic: true,
+ options: [{
+ text: "Dinle",
+ effects: {
+ lisa: 20,
+ honest: 10
+ },
+ meta: {
+ memoryLabel: "lisa_serious_listen"
+ }
+ }, {
+ text: "Dinleme",
+ effects: {
+ lisa: -20,
+ happy: -15
+ },
+ meta: {
+ memoryLabel: "lisa_serious_ignore"
+ }
+ }]
+}, {
+ id: "alex_secret_deal",
+ text: "Alex ile gizli bir anlaşma teklif ediyor. Kabul edecek misin?",
+ portrait: "alex",
+ speaker: "Alex",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ alex: 20,
+ betray: 20
+ },
+ meta: {
+ memoryLabel: "alex_deal_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ honest: 20,
+ alex: -15
+ },
+ meta: {
+ memoryLabel: "alex_deal_no"
+ }
+ }]
+}, {
+ id: "peter_big_secret",
+ text: "Peter, seni büyük bir sırrı hakkında uyarıyor. Güveniyor musun?",
+ portrait: "peter",
+ speaker: "Peter",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ peter: 20,
+ honest: 10
+ },
+ meta: {
+ memoryLabel: "peter_secret_trust"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ peter: -20,
+ betray: 15
+ },
+ meta: {
+ memoryLabel: "peter_secret_distrust"
+ }
+ }]
+}, {
+ id: "rebecca_club",
+ text: "Rebecca ile bir gece kulübünde dans ediyorsun. Daha yakın davranacak mısın?",
+ portrait: "rebecca",
+ speaker: "Rebecca",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ rebecca: 15,
+ lust: 15,
+ betray: 10
+ },
+ meta: {
+ memoryLabel: "rebecca_club_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ honest: 10
+ },
+ meta: {
+ memoryLabel: "rebecca_club_no"
+ }
+ }]
+}, {
+ id: "lisa_gossip",
+ text: "Lisa seni iş arkadaşlarınla ilgili dedikodulara karışmakla suçluyor. Savunacak mısın?",
+ portrait: "lisa",
+ speaker: "Lisa",
+ dramatic: true,
+ options: [{
+ text: "Savun",
+ effects: {
+ lisa: 10,
+ honest: 15
+ },
+ meta: {
+ memoryLabel: "lisa_gossip_defend"
+ }
+ }, {
+ text: "Kabullen",
+ effects: {
+ lisa: -15,
+ betray: 10
+ },
+ meta: {
+ memoryLabel: "lisa_gossip_admit"
+ }
+ }]
+}, {
+ id: "alex_promotion",
+ text: "Alex, seni iş yerinde terfi ile ödüllendiriyor ama bir karşılık bekliyor. Kabul edecek misin?",
+ portrait: "alex",
+ speaker: "Alex",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ alex: 25,
+ betray: 25
+ },
+ meta: {
+ memoryLabel: "alex_promotion_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ honest: 20
+ },
+ meta: {
+ memoryLabel: "alex_promotion_no"
+ }
+ }]
+}, {
+ id: "peter_sacrifice",
+ text: "Peter’in sana yardım etmek için büyük bir fedakarlık yapması gerekiyor. Kabul edecek misin?",
+ portrait: "peter",
+ speaker: "Peter",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ peter: 25,
+ happy: 15
+ },
+ meta: {
+ memoryLabel: "peter_sacrifice_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ peter: -20,
+ betray: 10
+ },
+ meta: {
+ memoryLabel: "peter_sacrifice_no"
+ }
+ }]
+}, {
+ id: "rebecca_restaurant",
+ text: "Rebecca, iş seyahatinde seni bir restoranda yalnız bırakıyor. Tek başına kalacak mısın yoksa kalabalığa mı karışacaksın?",
+ portrait: "rebecca",
+ speaker: "Rebecca",
+ dramatic: true,
+ options: [{
+ text: "Tek başına",
+ effects: {
+ rebecca: 10,
+ lust: 10
+ },
+ meta: {
+ memoryLabel: "rebecca_restaurant_alone"
+ }
+ }, {
+ text: "Kalabalık",
+ effects: {
+ honest: 10
+ },
+ meta: {
+ memoryLabel: "rebecca_restaurant_crowd"
+ }
+ }]
+}, {
+ id: "lisa_memory",
+ text: "Lisa sana eski bir anısını anlatıyor ve senden destek bekliyor. Onun yanında olacak mısın?",
+ portrait: "lisa",
+ speaker: "Lisa",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ lisa: 20,
+ happy: 15
+ },
+ meta: {
+ memoryLabel: "lisa_memory_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ lisa: -15
+ },
+ meta: {
+ memoryLabel: "lisa_memory_no"
+ }
+ }]
+}, {
+ id: "alex_ethics",
+ text: "Alex’in zorlayıcı teklifine karşılık verirken etik dışı bir şey yapman isteniyor. Kabul mü?",
+ portrait: "alex",
+ speaker: "Alex",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ alex: 20,
+ betray: 25
+ },
+ meta: {
+ memoryLabel: "alex_ethics_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ honest: 20
+ },
+ meta: {
+ memoryLabel: "alex_ethics_no"
+ }
+ }]
+}, {
+ id: "peter_secret_share",
+ text: "Peter seni beklenmedik bir şekilde büyük bir sırrını açıklıyor. Tepkin ne olur?",
+ portrait: "peter",
+ speaker: "Peter",
+ dramatic: true,
+ options: [{
+ text: "Sırlarınızı paylaşmaya devam edersin",
+ effects: {
+ peter: 20,
+ honest: 15
+ },
+ meta: {
+ memoryLabel: "peter_secret_share_yes"
+ }
+ }, {
+ text: "Mesafeli olursun",
+ effects: {
+ peter: -15,
+ betray: 10
+ },
+ meta: {
+ memoryLabel: "peter_secret_share_no"
+ }
+ }]
+}, {
+ id: "rebecca_bar_lisa",
+ text: "Rebecca ile iş sonrası bara gittiniz. Lisa ile yüzleşmeye hazır mısın?",
+ portrait: "rebecca",
+ speaker: "Rebecca",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ betray: 20,
+ lust: 15,
+ rebecca: 10
+ },
+ meta: {
+ memoryLabel: "rebecca_bar_lisa_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ honest: 15,
+ lisa: 10
+ },
+ meta: {
+ memoryLabel: "rebecca_bar_lisa_no"
+ }
+ }]
+}, {
+ id: "lisa_crisis",
+ text: "Lisa sana, evlilikte bir kriz yaşıyor ve profesyonel yardım almak istiyor. Destek verir misin?",
+ portrait: "lisa",
+ speaker: "Lisa",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ lisa: 25,
+ happy: 20
+ },
+ meta: {
+ memoryLabel: "lisa_crisis_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ lisa: -25
+ },
+ meta: {
+ memoryLabel: "lisa_crisis_no"
+ }
+ }]
+}, {
+ id: "alex_risk",
+ text: "Alex, kariyerin için büyük bir tehlike barındıran bir riski göze almana izin veriyor. Kabul mü?",
+ portrait: "alex",
+ speaker: "Alex",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ alex: 30,
+ betray: 30
+ },
+ meta: {
+ memoryLabel: "alex_risk_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ honest: 20
+ },
+ meta: {
+ memoryLabel: "alex_risk_no"
+ }
+ }]
+}, {
+ id: "peter_conflict",
+ text: "Peter ile aranızda aniden büyük bir anlaşmazlık çıkıyor. Özür dileyecek misin?",
+ portrait: "peter",
+ speaker: "Peter",
+ dramatic: true,
+ options: [{
+ text: "Evet",
+ effects: {
+ peter: 20,
+ happy: 15
+ },
+ meta: {
+ memoryLabel: "peter_conflict_yes"
+ }
+ }, {
+ text: "Hayır",
+ effects: {
+ peter: -20,
+ betray: 15
+ },
+ meta: {
+ memoryLabel: "peter_conflict_no"
+ }
+ }]
+}];
+// Dramatic choice frequency: every 4-6 turns, randomize
+var nextDramaticTurn = 4 + Math.floor(Math.random() * 3);
+var dramaticHistory = [];
+// Helper: get a random dramatic choice not recently shown
+function getDramaticChoice() {
+ var available = [];
+ for (var i = 0; i < dramaticChoices.length; i++) {
+ if (dramaticHistory.indexOf(dramaticChoices[i].id) === -1) {
+ available.push(dramaticChoices[i]);
+ }
+ }
+ // If all have been shown, reset history
+ if (available.length === 0) {
+ dramaticHistory = [];
+ available = dramaticChoices.slice();
+ }
+ var idx = Math.floor(Math.random() * available.length);
+ return available[idx];
+}
+// Show a dramatic choice with animation, music pause, and shadow overlay
+function showDramaticChoice() {
+ // Remove old option buttons
+ for (var i = 0; i < optionButtons.length; i++) {
+ game.removeChild(optionButtons[i]);
+ }
+ optionButtons = [];
+ // Pick a dramatic choice
+ var node = getDramaticChoice();
+ dramaticHistory.push(node.id);
+ // Pause music (if any)
+ if (typeof LK.stopMusic === "function") LK.stopMusic();
+ // Shadow overlay
+ if (!game._dramaticShadow) {
+ var shadow = LK.getAsset('bar_bg', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ shadow.width = 2048;
+ shadow.height = 2732;
+ shadow.x = 0;
+ shadow.y = 0;
+ shadow.alpha = 0.0;
+ shadow.zIndex = 99;
+ game.addChild(shadow);
+ game._dramaticShadow = shadow;
+ tween.create(shadow).to({
+ alpha: 0.7
+ }, 400).start();
+ }
+ // Portrait
+ if (portraitNode && node.portrait && LK.getAsset(node.portrait, {})) {
+ portraitNode.texture = LK.getAsset(node.portrait, {}).texture;
+ portraitNode.tint = 0xffffff;
+ }
+ // Speaker
+ if (speakerText) speakerText.setText(node.speaker ? node.speaker : '');
+ // Story text
+ if (storyText) {
+ storyText.setText(node.text);
+ storyText.alpha = 0.0;
+ tween.create(storyText).to({
+ alpha: 1
+ }, 400).start();
+ }
+ // Dramatic option buttons: animated grow/shrink
+ for (var i = 0; i < node.options.length; i++) {
+ (function (opt, idx) {
+ var btn = new OptionButton();
+ btn.setText(opt.text);
+ btn.x = 2048 / 2;
+ btn.y = 1700 + idx * 220;
+ btn.scale.x = 0.7;
+ btn.scale.y = 0.7;
+ btn.alpha = 0.0;
+ btn.bg.tint = 0x222222;
+ btn.text.style.fill = '#fff';
+ btn.zIndex = 100;
+ game.addChild(btn);
+ optionButtons.push(btn);
+ // Animate: grow in, pulse
+ tween.create(btn).to({
+ alpha: 1,
+ scaleX: 1.1,
+ scaleY: 1.1
+ }, 300).start().onComplete(function () {
+ tween.create(btn).to({
+ scaleX: 1.0,
+ scaleY: 1.0
+ }, 200).start();
+ });
+ btn.setCallback(function () {
+ // Remove shadow overlay
+ if (game._dramaticShadow) {
+ tween.create(game._dramaticShadow).to({
+ alpha: 0
+ }, 300).start().onComplete(function () {
+ game.removeChild(game._dramaticShadow);
+ game._dramaticShadow = null;
+ });
+ }
+ // Remove buttons with fade
+ for (var j = 0; j < optionButtons.length; j++) {
+ (function (b) {
+ tween.create(b).to({
+ alpha: 0
+ }, 200).start().onComplete(function () {
+ game.removeChild(b);
+ });
+ })(optionButtons[j]);
+ }
+ optionButtons = [];
+ // Apply effects (dramatic: +10~+30 or -30)
+ applyDramaticEffects(opt.effects, opt.meta);
+ // Resume music (if any)
+ if (typeof LK.playMusic === "function") LK.playMusic('musicId');
+ // Next dramatic turn: 4-6 turns later
+ nextDramaticTurn = turnCount + 4 + Math.floor(Math.random() * 3);
+ // Continue with normal story
+ LK.setTimeout(function () {
+ var nextIdx = getNextNode();
+ currentNode = nextIdx;
+ showStoryNode(currentNode);
+ }, 600);
+ });
+ })(node.options[i], i);
+ }
+}
+// Apply dramatic effects: bar changes are much larger
+function applyDramaticEffects(effects, meta) {
+ if (!effects) return;
+ // Record memory
+ if (meta && meta.memoryLabel) pastChoices.push(meta.memoryLabel);
+ // Dramatic: apply full effect value (not just +1/-1)
+ if (typeof effects.lisa === 'number') rel_lisa = Math.max(0, Math.min(100, rel_lisa + effects.lisa));
+ if (typeof effects.rebecca === 'number') rel_rebecca = Math.max(0, Math.min(100, rel_rebecca + effects.rebecca));
+ if (typeof effects.peter === 'number') rel_peter = Math.max(0, Math.min(100, rel_peter + effects.peter));
+ if (typeof effects.alex === 'number') rel_alex = Math.max(0, Math.min(100, rel_alex + effects.alex));
+ if (typeof effects.happy === 'number') bar_happy = Math.max(0, Math.min(100, bar_happy + effects.happy));
+ if (typeof effects.honest === 'number') bar_honest = Math.max(0, Math.min(100, bar_honest + effects.honest));
+ if (typeof effects.lust === 'number') bar_lust = Math.max(0, Math.min(100, bar_lust + effects.lust));
+ if (typeof effects.betray === 'number') bar_betray = Math.max(0, Math.min(100, bar_betray + effects.betray));
+ // Shadow bar: dramatic choices have bigger impact
+ if (typeof effects.betray === 'number' && effects.betray > 0) bar_shadow = Math.max(0, Math.min(100, bar_shadow + 10));
+ if (typeof effects.honest === 'number' && effects.honest > 0) bar_shadow = Math.max(0, bar_shadow - 5);
+ updateBars();
+ turnCount++;
+ // Cross effects
+ applyCrossEffects(effects, meta);
+ // Check for ending
+ if (bar_happy <= 0) {
+ showEnding('Mutluluk sıfırlandı. Mike depresyona girdi.');
+ return;
+ }
+ if (bar_honest <= 0) {
+ showEnding('Dürüstlük sıfırlandı. Mike yalanlarla dolu bir hayata saplandı.');
+ return;
+ }
+ if (bar_lust <= 0) {
+ showEnding('Şehvet sıfırlandı. Mike hayattan keyif alamıyor.');
+ return;
+ }
+ if (bar_betray >= 100) {
+ showEnding('İhanet %100 oldu. Mike ilişkilerini kaybetti.');
+ return;
+ }
+}
// Each story node: { text, options: [ {text, effects, next} ], portrait, speaker }
// --- Story Data ---
// Character portraits (simple colored boxes for now)
// Bar backgrounds and fills
@@ -795,8 +1459,15 @@
flags = {};
pastChoices = [];
turnCount = 0;
currentNode = 0;
+ // Reset dramatic system
+ nextDramaticTurn = 4 + Math.floor(Math.random() * 3);
+ dramaticHistory = [];
+ if (game._dramaticShadow) {
+ game.removeChild(game._dramaticShadow);
+ game._dramaticShadow = null;
+ }
}
function createUI() {
// Portrait
if (portraitNode) game.removeChild(portraitNode);
@@ -943,8 +1614,13 @@
for (var i = 0; i < optionButtons.length; i++) {
game.removeChild(optionButtons[i]);
}
optionButtons = [];
+ // Dramatic choice injection: if turnCount >= nextDramaticTurn, show dramatic choice instead
+ if (typeof nextDramaticTurn !== "undefined" && turnCount >= nextDramaticTurn) {
+ showDramaticChoice();
+ return;
+ }
var node = story[idx];
// Portrait
if (portraitNode) {
if (node.portrait && LK.getAsset(node.portrait, {})) {
Boss Man head. In-Game asset. 2d. High contrast. No shadows
Housewife Head. In-Game asset. 2d. High contrast. No shadows
Blonde Handsome Man. In-Game asset. 2d. High contrast. No shadows
handsome, black hair, goat beard man head. In-Game asset. 2d. High contrast. No shadows
sexy ginger woman head In-Game asset. 2d. High contrast. No shadows
briefcase. In-Game asset. 2d. High contrast. No shadows
soccer ball. In-Game asset. 2d. High contrast. No shadows
flame heart. In-Game asset. 2d. High contrast. No shadows
motorcycle. In-Game asset. 2d. High contrast. No shadows
limuzin. In-Game asset. 2d. High contrast. No shadows
Black popart background. Only dark colors. Lots of pop art reference In-Game asset. 2d. High contrast. No shadows
Sexy beautiful French Woman face In-Game asset. 2d. High contrast. No shadows
German Shepard face. realistic In-Game asset. 2d. High contrast. No shadows
realistic villa. In-Game asset. 2d. High contrast. No shadows