/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.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;
});
// Passive background object base class
var PassiveBgObject = Container.expand(function () {
var self = Container.call(this);
self.speed = 0;
self.assetId = '';
self.asset = null;
self.setAsset = function (assetId) {
if (self.asset) self.removeChild(self.asset);
self.assetId = assetId;
self.asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
};
self.resetPosition = function () {
// Start just outside right edge, random Y
self.x = 2048 + (self.asset ? self.asset.width : 100) / 2 + Math.random() * 200;
self.y = 200 + Math.random() * 2100;
};
self.update = function () {
if (typeof self.lastX === "undefined") self.lastX = self.x;
self.x -= self.speed;
// If off screen to the left, reset
if (self.lastX >= -200 && self.x < -200) {
self.resetPosition();
}
self.lastX = self.x;
};
return self;
});
// Motorcycle
var BgMotorcycle = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_motorcycle');
self.speed = 4.0 + Math.random() * 1.5;
self.resetPosition();
return self;
});
// Heart
var BgHeart = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_heart');
self.speed = 2.7 + Math.random() * 1.2;
self.resetPosition();
return self;
});
// Football
var BgFootball = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_football');
self.speed = 2.5 + Math.random() * 1.2;
self.resetPosition();
return self;
});
// Car
var BgCar = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_car');
self.speed = 3.2 + Math.random() * 1.5;
self.resetPosition();
return self;
});
// Briefcase
var BgBriefcase = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_briefcase');
self.speed = 2.2 + Math.random() * 1.2;
self.resetPosition();
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
****/
// Animate passive background objects
// Sağdan sola giden araba
// Sağdan sola giden iş çantası
// Sağdan sola giden ateşli kalp
// Sağdan sola giden futbol topu
// Sağdan sola giden motor
// --- Shop/Store assets (right side) ---
// Example id, replace with real
if (typeof bgObjects !== "undefined") {
for (var i = 0; i < bgObjects.length; i++) {
if (bgObjects[i] && typeof bgObjects[i].update === "function") {
bgObjects[i].update();
}
}
}
// No per-frame logic needed
// Not: 'background' asseti image olarak tanımlanmalı, ör: LK.init.image('background', {width:2048, height:2732, id:'YOUR_IMAGE_ID'})
var backgroundNode = LK.getAsset('background', {
anchorX: 0,
anchorY: 0
});
backgroundNode.width = 2048;
backgroundNode.height = 2732;
backgroundNode.x = 0;
backgroundNode.y = 0;
backgroundNode.zIndex = -100; // Her şeyin arkasında dursun
game.addChild(backgroundNode);
// --- Passive background objects (car, briefcase, heart, football, motorcycle) ---
var bgObjects = [];
function spawnBgObjects() {
// Remove old ones if any
for (var i = 0; i < bgObjects.length; i++) {
if (bgObjects[i] && bgObjects[i].parent) {
game.removeChild(bgObjects[i]);
}
}
bgObjects = [];
// Add 2 of each for variety
for (var i = 0; i < 2; i++) {
var car = new BgCar();
var briefcase = new BgBriefcase();
var heart = new BgHeart();
var football = new BgFootball();
var motorcycle = new BgMotorcycle();
game.addChild(car);
game.addChild(briefcase);
game.addChild(heart);
game.addChild(football);
game.addChild(motorcycle);
bgObjects.push(car, briefcase, heart, football, motorcycle);
}
}
spawnBgObjects();
// Çarpıcı seçimler: her 4-6 sahnede bir, yüksek risk/ödül, animasyonlu, barları büyük oranda etkiler
// --- Dramatic Choice (Çarpıcı Seçim) System ---
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; // Start fully transparent
shadow.zIndex = 99;
game.addChild(shadow);
game._dramaticShadow = shadow;
// Animate shadow fade-in
tween(shadow, {
alpha: 0.7
}, {
duration: 220,
easing: tween.easeOut
});
} else {
// If already present, ensure it's visible and interactive
game._dramaticShadow.alpha = 0.7;
game._dramaticShadow.zIndex = 99;
}
// 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 = 1.0; // No animation
}
// Dramatic option buttons: ensure visible, enabled, and selectable
for (var i = 0; i < node.options.length; i++) {
(function (opt, idx) {
var btn = new OptionButton();
btn.setText(opt.text);
// Büyük ve dikkat çekici: butonları daha büyük yap
btn.scale.x = 1.35;
btn.scale.y = 1.35;
// Ekranda tamamen görünür ve aralıklı olacak şekilde ayarla
// Yüksekliğe göre ortala, iki seçenek için yukarıdan ve aşağıdan eşit boşluk bırak
var totalBtnHeight = 2 * (btn.bg.height * btn.scale.y) + 120;
var startY = 1800 - totalBtnHeight / 2;
btn.x = 2048 / 2;
btn.y = startY + idx * (btn.bg.height * btn.scale.y + 120);
btn.alpha = 1.0;
btn.bg.tint = 0x000000;
if (btn.text && btn.text.style) btn.text.style.fill = '#ffffff';
btn.zIndex = 100;
btn.interactive = true;
btn.buttonMode = true;
// Make sure button is enabled and not grayed out
btn.bg.tint = 0x000000;
if (btn.text && btn.text.style) btn.text.style.fill = '#ffffff';
// Remove any previous disabled state
btn.alpha = 1.0;
btn.visible = true;
btn.setCallback(function () {
// Seçim sırasında iki butonu da büyüt ve animasyon ekle
for (var j = 0; j < optionButtons.length; j++) {
var b = optionButtons[j];
// Seçilen buton daha fazla büyüsün, diğeri de büyüsün ama biraz az
var targetScale = b === btn ? 1.55 : 1.25;
tween(b.scale, {
x: targetScale,
y: targetScale
}, {
duration: 220,
easing: tween.easeOut
});
tween(b, {
alpha: 1
}, {
duration: 220,
easing: tween.easeOut
});
}
// Seçimden kısa süre sonra butonları ve gölgeyi kaldır
LK.setTimeout(function () {
// Remove shadow overlay with fade out
if (game._dramaticShadow) {
tween(game._dramaticShadow, {
alpha: 0
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function onFinish() {
if (game._dramaticShadow) {
game.removeChild(game._dramaticShadow);
game._dramaticShadow = null;
}
}
});
}
// Remove buttons instantly
for (var j = 0; j < optionButtons.length; j++) {
(function (b) {
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);
}, 260);
});
game.addChild(btn);
optionButtons.push(btn);
})(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
// --- Whiskey'e özel sorular (yalnızca satın alındıysa gösterilecek) ---
var whiskeyQuestions = [{
id: "whiskey_intro",
text: "Whiskey: 'Hav hav! Mike, parka gidelim mi?'",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Whiskey'i parka götür.",
effects: {
happy: 5
}
}, {
text: "Bugün evde kalalım.",
effects: {
happy: -2
}
}]
}, {
id: "whiskey_walk",
text: "Whiskey kapının önünde heyecanla bekliyor. Dışarı çıkarmak ister misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Whiskey ile uzun yürüyüş yap.",
effects: {
happy: 5
}
}, {
text: "Kısa bir yürüyüş yap.",
effects: {
happy: 2
}
}, {
text: "Yürüyüşe çıkma.",
effects: {
happy: -3
}
}]
}, {
id: "whiskey_vet",
text: "Whiskey biraz halsiz görünüyor. Veterinere götürecek misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Veterinere götür. ($200 harca)",
effects: {
happy: 5
},
meta: {
type: "whiskey_spend",
money: -200
}
}, {
text: "Evde dinlensin.",
effects: {
happy: -2
}
}]
}, {
id: "whiskey_toy",
text: "Whiskey yeni bir oyuncak istiyor.",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Oyuncak al. ($50 harca)",
effects: {
happy: 3
},
meta: {
type: "whiskey_spend",
money: -50
}
}, {
text: "Oyuncak alma.",
effects: {
happy: -2
}
}]
}, {
id: "whiskey_bath",
text: "Whiskey çamura bulandı! Yıkayacak mısın?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Whiskey'i yıka.",
effects: {
happy: 2
}
}, {
text: "Yıkamadan bırak.",
effects: {
happy: -3
}
}]
}, {
id: "whiskey_trick",
text: "Whiskey yeni bir numara öğrenmek istiyor. Öğretecek misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Yeni numara öğret.",
effects: {
happy: 4
}
}, {
text: "Vakit ayırma.",
effects: {
happy: -2
}
}]
}, {
id: "whiskey_vacation",
text: "Tatile çıkacaksınız. Whiskey'i de götürecek misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Whiskey'i de götür. ($300 harca)",
effects: {
happy: 5
},
meta: {
type: "whiskey_spend",
money: -300
}
}, {
text: "Whiskey'i pansiyona bırak. ($150 harca)",
effects: {
happy: 2
},
meta: {
type: "whiskey_spend",
money: -150
}
}]
}, {
id: "whiskey_birthday",
text: "Whiskey'in doğum günü! Ona özel bir şey yapmak ister misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Köpek pastası al. ($80 harca)",
effects: {
happy: 4
},
meta: {
type: "whiskey_spend",
money: -80
}
}, {
text: "Sadece sarıl.",
effects: {
happy: 2
}
}]
}, {
id: "whiskey_lost",
text: "Whiskey bahçede kayboldu! Arayacak mısın?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Bahçede ara.",
effects: {
happy: 3
}
}, {
text: "Kendi gelir diye bekle.",
effects: {
happy: -3
}
}]
}, {
id: "whiskey_vet2",
text: "Whiskey aşı zamanı geldi. Aşı yaptıracak mısın?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Aşı yaptır. ($120 harca)",
effects: {
happy: 3
},
meta: {
type: "whiskey_spend",
money: -120
}
}, {
text: "Aşıyı ertele.",
effects: {
happy: -2
}
}]
}];
// --- Villa'ya davet eventleri ve özel sorular (her karakter için 2'şer tane) ---
var villaInviteEvents = [{
id: "villa_invite_lisa",
text: "Artık bir villan var! Lisa'yı eve davet etmek ister misin?",
portrait: "lisa",
speaker: "Lisa",
options: [{
text: "Lisa'yı villaya davet et.",
effects: {
lisa: 15,
happy: 5
},
meta: {
type: "villa_invite",
character: "lisa"
}
}, {
text: "Davet etme.",
effects: {
lisa: -2
}
}]
}, {
id: "villa_invite_rebecca",
text: "Artık bir villan var! Rebecca'yı eve davet etmek ister misin?",
portrait: "rebecca",
speaker: "Rebecca",
options: [{
text: "Rebecca'yı villaya davet et.",
effects: {
rebecca: 15,
happy: 5
},
meta: {
type: "villa_invite",
character: "rebecca"
}
}, {
text: "Davet etme.",
effects: {
rebecca: -2
}
}]
}, {
id: "villa_invite_peter",
text: "Artık bir villan var! Peter'ı eve davet etmek ister misin?",
portrait: "peter",
speaker: "Peter",
options: [{
text: "Peter'ı villaya davet et.",
effects: {
peter: 15,
happy: 5
},
meta: {
type: "villa_invite",
character: "peter"
}
}, {
text: "Davet etme.",
effects: {
peter: -2
}
}]
}, {
id: "villa_invite_alex",
text: "Artık bir villan var! Alex'i eve davet etmek ister misin?",
portrait: "alex",
speaker: "Alex",
options: [{
text: "Alex'i villaya davet et.",
effects: {
alex: 15,
happy: 5
},
meta: {
type: "villa_invite",
character: "alex"
}
}, {
text: "Davet etme.",
effects: {
alex: -2
}
}]
}];
var villaSpecialQuestions = [
// Lisa
{
id: "villa_lisa_1",
text: "Lisa: 'Bu evde birlikte yeni anılar biriktirelim mi?'",
portrait: "lisa",
speaker: "Lisa",
options: [{
text: "Evet, birlikte çok güzel anılarımız olacak.",
effects: {
lisa: 10,
happy: 5
}
}, {
text: "Ev güzel ama önemli olan sensin.",
effects: {
lisa: 7,
honest: 3
}
}]
}, {
id: "villa_lisa_2",
text: "Lisa: 'Villada bir parti verelim mi?'",
portrait: "lisa",
speaker: "Lisa",
options: [{
text: "Harika fikir, parti verelim.",
effects: {
lisa: 8,
happy: 4
}
}, {
text: "Parti istemiyorum.",
effects: {
lisa: -3
}
}]
},
// Rebecca
{
id: "villa_rebecca_1",
text: "Rebecca: 'Villanın havuzunda gece yüzmek ister misin?'",
portrait: "rebecca",
speaker: "Rebecca",
options: [{
text: "Tabii, birlikte yüzmek harika olur.",
effects: {
rebecca: 10,
lust: 5
}
}, {
text: "Yorgunum, başka zaman.",
effects: {
rebecca: -2
}
}]
}, {
id: "villa_rebecca_2",
text: "Rebecca: 'Villada baş başa bir akşam geçirelim mi?'",
portrait: "rebecca",
speaker: "Rebecca",
options: [{
text: "Evet, baş başa kalmak güzel olur.",
effects: {
rebecca: 8,
happy: 3
}
}, {
text: "Bugün olmaz.",
effects: {
rebecca: -2
}
}]
},
// Peter
{
id: "villa_peter_1",
text: "Peter: 'Bahçede mangal yapalım mı?'",
portrait: "peter",
speaker: "Peter",
options: [{
text: "Mangal harika olur!",
effects: {
peter: 10,
happy: 4
}
}, {
text: "Başka zaman.",
effects: {
peter: -2
}
}]
}, {
id: "villa_peter_2",
text: "Peter: 'Villada birlikte film gecesi yapalım mı?'",
portrait: "peter",
speaker: "Peter",
options: [{
text: "Evet, film gecesi yapalım.",
effects: {
peter: 8,
happy: 3
}
}, {
text: "İstemiyorum.",
effects: {
peter: -2
}
}]
},
// Alex
{
id: "villa_alex_1",
text: "Alex: 'Bu villada iş toplantısı yapmak isterim.'",
portrait: "alex",
speaker: "Alex",
options: [{
text: "Tabii, toplantı yapabiliriz.",
effects: {
alex: 10,
happy: 2
}
}, {
text: "Evde iş konuşmak istemiyorum.",
effects: {
alex: -2
}
}]
}, {
id: "villa_alex_2",
text: "Alex: 'Villanın manzarası harika, burada çalışmak isterim.'",
portrait: "alex",
speaker: "Alex",
options: [{
text: "İstediğin zaman gelebilirsin.",
effects: {
alex: 8,
honest: 2
}
}, {
text: "Evde yalnız kalmak istiyorum.",
effects: {
alex: -2
}
}]
}];
// --- Giselle'e özel sorular (yalnızca satın alındıysa gösterilecek) ---
var giselleQuestions = [{
id: "giselle_intro",
text: "Giselle: 'Mike, yeni bir çanta almak istiyorum. Bütçemiz yeterli mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Tabii, hemen alalım. ($500 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -500
}
}, {
text: "Şu an alamayız, bütçemiz kısıtlı.",
effects: {
happy: -5,
honest: 5
},
meta: {
type: "truth"
}
}]
}, {
id: "giselle_shopping",
text: "Giselle: 'Alışverişe çıkalım mı? Birkaç şey almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Giselle'e para ver. ($300 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -300
}
}, {
text: "Bugün alışveriş yok.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_dinner",
text: "Giselle: 'Bu akşam dışarıda yemek yiyelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Lüks restorana git. ($400 harca)",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_spend",
money: -400
}
}, {
text: "Evde yemek yapalım.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_gift",
text: "Giselle: 'Bana hediye alır mısın?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Pahalı bir kolye al. ($1000 harca)",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_spend",
money: -1000
}
}, {
text: "Küçük bir hediye al. ($100 harca)",
effects: {
happy: 3
},
meta: {
type: "giselle_spend",
money: -100
}
}, {
text: "Hediye almayacağım.",
effects: {
happy: -10
}
}]
}, {
id: "giselle_jealous",
text: "Giselle: 'Lisa ile çok vakit geçiriyorsun, kıskanıyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Giselle'e güven ver.",
effects: {
happy: 5,
honest: 5
}
}, {
text: "Lisa ile görüşmeyi azalt.",
effects: {
happy: 2,
lust: -2
}
}]
}, {
id: "giselle_party",
text: "Giselle: 'Hafta sonu partiye gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Partiye git. ($200 harca)",
effects: {
happy: 5,
lust: 5
},
meta: {
type: "giselle_spend",
money: -200
}
}, {
text: "Evde kalalım.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_baby",
text: "Giselle: 'Bir bebek sahibi olmayı düşünür müsün?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Evet, isterim.",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_baby"
}
}, {
text: "Henüz hazır değilim.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_trip",
text: "Giselle: 'Birlikte tatile çıkalım mı?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Tatile çık. ($1500 harca)",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_spend",
money: -1500
}
}, {
text: "Tatil için paramız yok.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_friends",
text: "Giselle: 'Arkadaşlarımı davet edebilir miyim?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Tabii, davet et.",
effects: {
happy: 5
}
}, {
text: "Hayır, bu akşam yalnız kalalım.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_shoes",
text: "Giselle: 'Yeni ayakkabılar almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Ayakkabı al. ($250 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -250
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_movie",
text: "Giselle: 'Bu akşam sinemaya gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Sinemaya git. ($100 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -100
}
}, {
text: "Evde film izleyelim.",
effects: {
happy: 2
}
}]
}, {
id: "giselle_dress",
text: "Giselle: 'Yeni bir elbise almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Elbise al. ($350 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -350
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_jewelry",
text: "Giselle: 'Takı mağazasına gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Takı al. ($200 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -200
}
}, {
text: "Takı almayalım.",
effects: {
happy: -2
}
}]
}, {
id: "giselle_spa",
text: "Giselle: 'Birlikte spa'ya gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Spa'ya git. ($400 harca)",
effects: {
happy: 7
},
meta: {
type: "giselle_spend",
money: -400
}
}, {
text: "Evde dinlenelim.",
effects: {
happy: 2
}
}]
}, {
id: "giselle_phone",
text: "Giselle: 'Yeni bir telefon almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Telefon al. ($1200 harca)",
effects: {
happy: 10
},
meta: {
type: "giselle_spend",
money: -1200
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_bag",
text: "Giselle: 'Çantam eskidi, yenisini alabilir miyiz?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Çanta al. ($300 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -300
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_makeup",
text: "Giselle: 'Kozmetik alışverişi yapalım mı?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Kozmetik al. ($150 harca)",
effects: {
happy: 3
},
meta: {
type: "giselle_spend",
money: -150
}
}, {
text: "Hayır, gerek yok.",
effects: {
happy: -2
}
}]
}, {
id: "giselle_jacket",
text: "Giselle: 'Yeni bir ceket almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Ceket al. ($400 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -400
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_ring",
text: "Giselle: 'Yüzük bakmaya gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Yüzük al. ($800 harca)",
effects: {
happy: 8
},
meta: {
type: "giselle_spend",
money: -800
}
}, {
text: "Yüzük almayalım.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_baby2",
text: "Giselle: 'Bebek sahibi olmayı hâlâ düşünüyor musun?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Evet, isterim.",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_baby"
}
}, {
text: "Henüz hazır değilim.",
effects: {
happy: -5
}
}]
}];
// --- Ana story havuzu ---
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
}]
},
// --- Ava: New story questions for more variety ---
{
text: "Lisa ile alışverişe çıktınız. Lisa yeni bir elbise almak istiyor.",
portrait: 'lisa',
speaker: 'Lisa',
options: [{
text: "Elbise almasına destek ol.",
effects: {
lisa: 10,
happy: 5
}
}, {
text: "Bütçemiz kısıtlı, başka zaman alalım.",
effects: {
lisa: -5,
honest: 5
}
}]
}, {
text: "Rebecca iş yerinde sana bir sır veriyor.",
portrait: 'rebecca',
speaker: 'Rebecca',
options: [{
text: "Sırrını sakla.",
effects: {
rebecca: 10,
honest: 5
}
}, {
text: "Sırrı başkasına anlat.",
effects: {
rebecca: -10,
betray: 10
}
}]
}, {
text: "Peter ile futbol maçı izliyorsunuz.",
portrait: 'peter',
speaker: 'Peter',
options: [{
text: "Beraber tezahürat yap.",
effects: {
peter: 10,
happy: 5
}
}, {
text: "Maçtan sıkıldığını söyle.",
effects: {
peter: -5
}
}]
}, {
text: "Alex yeni bir iş fırsatı sunuyor.",
portrait: 'alex',
speaker: 'Alex',
options: [{
text: "Fırsatı kabul et.",
effects: {
alex: 10,
happy: 5
}
}, {
text: "Reddet, mevcut işinden memnunsun.",
effects: {
alex: -5,
honest: 5
}
}]
}, {
text: "Lisa ile tartıştınız. Lisa üzgün.",
portrait: 'lisa',
speaker: 'Lisa',
options: [{
text: "Özür dile.",
effects: {
lisa: 10,
honest: 5
}
}, {
text: "Haklı olduğunu savun.",
effects: {
lisa: -10
}
}]
}, {
text: "Rebecca ile sinemaya gitme planı yapıyorsun.",
portrait: 'rebecca',
speaker: 'Rebecca',
options: [{
text: "Romantik bir film seç.",
effects: {
rebecca: 10,
lust: 5
}
}, {
text: "Aksiyon filmi seç.",
effects: {
rebecca: 5
}
}]
}, {
text: "Peter sana bir kitap öneriyor.",
portrait: 'peter',
speaker: 'Peter',
options: [{
text: "Kitabı oku ve yorum yap.",
effects: {
peter: 10,
honest: 5
}
}, {
text: "Kitabı okumadığını itiraf et.",
effects: {
peter: -5,
honest: 5
}
}]
}, {
text: "Alex ile iş seyahatine çıkıyorsun.",
portrait: 'alex',
speaker: 'Alex',
options: [{
text: "Alex ile yakınlaş.",
effects: {
alex: 10,
betray: 5
}
}, {
text: "Mesafeni koru.",
effects: {
alex: 5,
honest: 5
}
}]
}, {
text: "Lisa sana sürpriz bir doğum günü partisi hazırlıyor.",
portrait: 'lisa',
speaker: 'Lisa',
options: [{
text: "Çok mutlu ol ve teşekkür et.",
effects: {
lisa: 10,
happy: 10
}
}, {
text: "Sürprizleri sevmediğini söyle.",
effects: {
lisa: -5,
honest: 5
}
}]
}, {
text: "Rebecca ile bir tartışma yaşıyorsun.",
portrait: 'rebecca',
speaker: 'Rebecca',
options: [{
text: "Barışmak için adım at.",
effects: {
rebecca: 10
}
}, {
text: "Tartışmayı uzat.",
effects: {
rebecca: -10
}
}]
}, {
text: "Peter ile eski bir fotoğraf albümüne bakıyorsun.",
portrait: 'peter',
speaker: 'Peter',
options: [{
text: "Güzel anıları hatırla.",
effects: {
peter: 10,
happy: 5
}
}, {
text: "Geçmişi konuşmak istemediğini söyle.",
effects: {
peter: -5
}
}]
}, {
text: "Alex iş yerinde seni övüyor.",
portrait: 'alex',
speaker: 'Alex',
options: [{
text: "Teşekkür et.",
effects: {
alex: 10,
happy: 5
}
}, {
text: "Mütevazı davran.",
effects: {
alex: 5
}
}]
}, {
text: "Lisa ile birlikte yemek yapıyorsun.",
portrait: 'lisa',
speaker: 'Lisa',
options: [{
text: "Birlikte eğlenerek yemek yap.",
effects: {
lisa: 10,
happy: 5
}
}, {
text: "Yemek yapmayı sevmediğini söyle.",
effects: {
lisa: -5
}
}]
}, {
text: "Rebecca yeni bir hobiye başlamak istiyor.",
portrait: 'rebecca',
speaker: 'Rebecca',
options: [{
text: "Onu destekle.",
effects: {
rebecca: 10
}
}, {
text: "Hobisini gereksiz bul.",
effects: {
rebecca: -5
}
}]
}, {
text: "Peter ile bir iş projesinde çalışıyorsun.",
portrait: 'peter',
speaker: 'Peter',
options: [{
text: "Peter'ın fikirlerine değer ver.",
effects: {
peter: 10
}
}, {
text: "Kendi bildiğini yap.",
effects: {
peter: -5
}
}]
}, {
text: "Alex ile bir anlaşmazlık yaşıyorsun.",
portrait: 'alex',
speaker: 'Alex',
options: [{
text: "Uzlaşmacı ol.",
effects: {
alex: 10
}
}, {
text: "Kendi fikrinde ısrar et.",
effects: {
alex: -5
}
}]
},
// 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;
// --- Ava: Time, salary, baby, pregnancy, money mechanics ---
var dayCount = 1; // 1-based, every 2 questions = 1 day
var mikeSalary = 100;
var mikeMoney = 0;
var mikeBabyCount = 0;
var lisaPregnant = false;
var rebeccaPregnant = false;
var gisellePregnant = false;
var showLisaPregOption = false;
var showRebeccaPregOption = false;
var showGisellePregOption = false;
var giselleUnlocked = false; // Satın alındı mı?
var shopItemStates = [false, false, false, false]; // 0: Giselle, 1-3: diğerleri
// --- 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 = [];
// --- Ava: UI for day, salary, money, baby count ---
var dayText = null;
var salaryText = null;
var moneyText = null;
var babyText = null;
// --- Functions ---
// getNextNode: uygun story node'unu bar değerine göre seç
// --- Ava: Prevent same question from repeating within last 20, and add more questions ---
var lastStoryIndices = [];
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;
}
// Ava: Filter out nodes that were used in the last 20
var filteredIndices = [];
for (var k = 0; k < indices.length; k++) {
var idx = indices[k];
if (lastStoryIndices.indexOf(idx) === -1) {
filteredIndices.push(idx);
}
}
// If less than 5 available, allow all (reset)
var useIndices = filteredIndices.length > 5 ? filteredIndices : indices;
// --- Giselle: Eğer satın alındıysa, havuza Giselle sorularını da ekle ---
// --- Whiskey: Eğer satın alındıysa, havuza Whiskey sorularını da ekle ---
// --- Villa: Eğer satın alındıysa, havuza Villa event ve sorularını da ekle ---
var pool = [];
for (var k = 0; k < useIndices.length; k++) {
var idx = useIndices[k];
var node = story[idx];
// Sadece Giselle alınmışsa Giselle soruları havuza eklenir
if (node && node.portrait === "giselle" && !giselleUnlocked) continue;
// Sadece Whiskey alınmışsa Whiskey soruları havuza eklenir
if (node && node.portrait === "whiskey" && !whiskeyUnlocked) continue;
// Villa eventleri ve soruları sadece villaUnlocked ise eklenir
if (node && node.id && node.id.indexOf("villa_") === 0 && !villaUnlocked) continue;
pool.push({
idx: idx,
node: node
});
}
if (giselleUnlocked) {
// Son 20'de olmayan Giselle sorularını da ekle
for (var g = 0; g < giselleQuestions.length; g++) {
var gq = giselleQuestions[g];
var gqId = "giselle_" + g;
// Sadece son 20'de yoksa ekle
var alreadyUsed = false;
for (var h = 0; h < lastStoryIndices.length; h++) {
if (story[lastStoryIndices[h]] && story[lastStoryIndices[h]].id === gq.id) alreadyUsed = true;
}
if (!alreadyUsed) {
pool.push({
idx: -1,
node: gq
});
}
}
}
if (whiskeyUnlocked) {
// Son 20'de olmayan Whiskey sorularını da ekle
for (var w = 0; w < whiskeyQuestions.length; w++) {
var wq = whiskeyQuestions[w];
var wqId = "whiskey_" + w;
var alreadyUsedW = false;
for (var h = 0; h < lastStoryIndices.length; h++) {
if (story[lastStoryIndices[h]] && story[lastStoryIndices[h]].id === wq.id) alreadyUsedW = true;
}
if (!alreadyUsedW) {
pool.push({
idx: -1,
node: wq
});
}
}
}
if (villaUnlocked) {
// Son 20'de olmayan Villa invite eventlerini ekle
for (var v = 0; v < villaInviteEvents.length; v++) {
var ve = villaInviteEvents[v];
var alreadyUsedV = false;
for (var h = 0; h < lastStoryIndices.length; h++) {
if (story[lastStoryIndices[h]] && story[lastStoryIndices[h]].id === ve.id) alreadyUsedV = true;
}
if (!alreadyUsedV) {
pool.push({
idx: -1,
node: ve
});
}
}
// Son 20'de olmayan Villa özel sorularını ekle
for (var vq = 0; vq < villaSpecialQuestions.length; vq++) {
var vsq = villaSpecialQuestions[vq];
var alreadyUsedVSQ = false;
for (var h = 0; h < lastStoryIndices.length; h++) {
if (story[lastStoryIndices[h]] && story[lastStoryIndices[h]].id === vsq.id) alreadyUsedVSQ = true;
}
if (!alreadyUsedVSQ) {
pool.push({
idx: -1,
node: vsq
});
}
}
}
// Her bir node'u sırayla kontrol et, barCheck varsa uygun olanı döndür
for (var k = 0; k < pool.length; k++) {
var idx = pool[k].idx;
var node = pool[k].node;
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) {
lastStoryIndices.push(idx);
if (lastStoryIndices.length > 20) lastStoryIndices.shift();
return idx;
}
} else {
lastStoryIndices.push(idx);
if (lastStoryIndices.length > 20) lastStoryIndices.shift();
return idx;
}
}
// Hiçbiri uygun değilse ilk node'u döndür
lastStoryIndices.push(0);
if (lastStoryIndices.length > 20) lastStoryIndices.shift();
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;
}
dayCount = 1;
mikeSalary = 100;
mikeMoney = 0;
mikeBabyCount = 0;
lisaPregnant = false;
rebeccaPregnant = false;
gisellePregnant = false;
giselleUnlocked = false;
whiskeyUnlocked = false;
villaUnlocked = false;
shopItemStates = [false, false, false, false];
if (storage) {
storage.mikeMoney = 0;
storage.mikeSalary = 100;
storage.mikeBabyCount = 0;
storage.dayCount = 1;
storage.lisaPregnant = false;
storage.rebeccaPregnant = false;
storage.gisellePregnant = false;
storage.giselleUnlocked = false;
storage.whiskeyUnlocked = false;
storage.villaUnlocked = false;
}
}
function createUI() {
// Portrait
if (portraitNode) game.removeChild(portraitNode);
portraitNode = LK.getAsset('mike', {
anchorX: 0.5,
anchorY: 0.5
});
// Mike portresini ve karakteri ekrana tam ortala
portraitNode.x = 2048 / 2;
portraitNode.y = 520;
game.addChild(portraitNode);
// --- Mike portresine titreme animasyonu ekle ---
function shakePortrait(node) {
if (!node) return;
var origX = 2048 / 2;
var origY = 520;
function doShake() {
// Rastgele küçük bir ofset (±8px)
var dx = (Math.random() - 0.5) * 16;
var dy = (Math.random() - 0.5) * 10;
tween(node, {
x: origX + dx,
y: origY + dy
}, {
duration: 80,
easing: tween.linear,
onFinish: function onFinish() {
tween(node, {
x: origX,
y: origY
}, {
duration: 80,
easing: tween.linear,
onFinish: function onFinish() {
LK.setTimeout(doShake, 80 + Math.floor(Math.random() * 60));
}
});
}
});
}
doShake();
}
shakePortrait(portraitNode);
// --- Eğer ilgili karakter portresi varsa ona da titreme ekle ---
if (game.relatedPortraitNode) {
var _shakeRelated = function shakeRelated() {
if (!relNode.parent) return; // Silindiyse dur
var dx = (Math.random() - 0.5) * 16;
var dy = (Math.random() - 0.5) * 10;
tween(relNode, {
x: relOrigX + dx,
y: relOrigY + dy
}, {
duration: 80,
easing: tween.linear,
onFinish: function onFinish() {
tween(relNode, {
x: relOrigX,
y: relOrigY
}, {
duration: 80,
easing: tween.linear,
onFinish: function onFinish() {
LK.setTimeout(_shakeRelated, 80 + Math.floor(Math.random() * 60));
}
});
}
});
};
var relNode = game.relatedPortraitNode;
var relOrigX = relNode.x;
var relOrigY = relNode.y;
_shakeRelated();
}
// Speaker (isim) biraz daha aşağıda
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 = 740;
game.addChild(speakerText);
// Story text (olay) biraz daha aşağıda
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 = 830;
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);
}
// --- Ava: Add day, salary, money, baby count UI ---
if (dayText) game.removeChild(dayText);
if (salaryText) game.removeChild(salaryText);
if (moneyText) game.removeChild(moneyText);
if (babyText) game.removeChild(babyText);
dayText = new Text2('Gün: ' + dayCount, {
size: 54,
fill: '#fff'
});
dayText.anchor.set(0, 0);
dayText.x = 120;
dayText.y = 80;
game.addChild(dayText);
salaryText = new Text2('Maaş: $' + mikeSalary, {
size: 54,
fill: '#fff'
});
salaryText.anchor.set(0, 0);
salaryText.x = 120;
salaryText.y = 150;
game.addChild(salaryText);
moneyText = new Text2('Para: $' + mikeMoney, {
size: 54,
fill: '#fff'
});
moneyText.anchor.set(0, 0);
moneyText.x = 120;
moneyText.y = 220;
game.addChild(moneyText);
babyText = new Text2('Bebek: ' + mikeBabyCount, {
size: 54,
fill: '#fff'
});
babyText.anchor.set(0, 0);
babyText.x = 120;
babyText.y = 290;
game.addChild(babyText);
// --- Ava: Show relationship options if eligible ---
// Remove old relationship option buttons if any
if (game._relOptionBtns) {
for (var i = 0; i < game._relOptionBtns.length; i++) {
game.removeChild(game._relOptionBtns[i]);
}
}
game._relOptionBtns = [];
// --- Shop/Store UI (right side, vertical) ---
if (game._shopNodes) {
for (var i = 0; i < game._shopNodes.length; i++) {
game.removeChild(game._shopNodes[i]);
}
}
game._shopNodes = [];
var shopAssetIds = ['giselle', 'shop_item2', 'shop_item3', 'shop_item4'];
var shopPrices = [10000, 2500, 50000, 7500];
var shopLabels = ['Giselle', 'Whiskey', 'Villa', 'Eşya 4'];
var shopYStart = 1200; // moved even further down
var shopSpacing = 450; // even more space between items
// --- Villa state ---
if (typeof villaUnlocked === "undefined") villaUnlocked = false;
if (typeof whiskeyUnlocked === "undefined") whiskeyUnlocked = false;
for (var i = 0; i < 4; i++) {
var assetId = shopAssetIds[i];
var node = LK.getAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
node.x = 2048 - 120;
node.y = shopYStart + i * shopSpacing;
node.scale.x = node.scale.y = 1.0;
// Shop items are passive (dimmed, not interactive) until purchased, then active
if (shopItemStates[i]) {
node.alpha = 1.0;
node.interactive = false;
node.buttonMode = false;
} else {
node.alpha = 0.5;
node.interactive = true;
node.buttonMode = true;
}
// Price label (above the item)
var priceText = "";
if (i === 0) {
priceText = "$10,000";
} else if (i === 1) {
priceText = "$2,500";
} else if (i === 2) {
priceText = "$50,000";
} else if (i === 3) {
priceText = "$7,500";
}
var priceLabel = new Text2(priceText, {
size: 38,
fill: '#ffe066',
fontWeight: 'bold'
});
priceLabel.anchor.set(0.5, 1);
priceLabel.x = node.x;
priceLabel.y = node.y - node.height / 2 - 12;
game.addChild(priceLabel);
game._shopNodes.push(priceLabel);
// Name label (below the item)
var label = new Text2(shopLabels[i], {
size: 36,
fill: '#fff',
wordWrap: true,
wordWrapWidth: 180
});
label.anchor.set(0.5, 0);
label.x = node.x;
label.y = node.y + node.height / 2 + 10;
game.addChild(node);
game.addChild(label);
game._shopNodes.push(node, label);
// Giselle buy logic
if (i === 0 && !giselleUnlocked) {
node.down = function () {
if (mikeMoney >= 10000) {
mikeMoney -= 10000;
giselleUnlocked = true;
shopItemStates[0] = true;
// After purchase, make the item active (full alpha, not interactive)
node.alpha = 1.0;
node.interactive = false;
node.buttonMode = false;
updateBars();
createUI();
} else {
// Not enough money, flash red
tween(node, {
alpha: 0.3
}, {
duration: 120,
onFinish: function onFinish() {
tween(node, {
alpha: 1
}, {
duration: 120
});
}
});
}
};
}
// Whiskey buy logic
if (i === 1 && !whiskeyUnlocked) {
node.down = function () {
if (mikeMoney >= 2500) {
mikeMoney -= 2500;
whiskeyUnlocked = true;
shopItemStates[1] = true;
// After purchase, make the item active (full alpha, not interactive)
node.alpha = 1.0;
node.interactive = false;
node.buttonMode = false;
updateBars();
createUI();
} else {
// Not enough money, flash red
tween(node, {
alpha: 0.3
}, {
duration: 120,
onFinish: function onFinish() {
tween(node, {
alpha: 1
}, {
duration: 120
});
}
});
}
};
}
// Villa buy logic
if (i === 2 && !villaUnlocked) {
node.down = function () {
if (mikeMoney >= 50000) {
mikeMoney -= 50000;
villaUnlocked = true;
shopItemStates[2] = true;
// After purchase, make the item active (full alpha, not interactive)
node.alpha = 1.0;
node.interactive = false;
node.buttonMode = false;
updateBars();
createUI();
} else {
tween(node, {
alpha: 0.3
}, {
duration: 120,
onFinish: function onFinish() {
tween(node, {
alpha: 1
}, {
duration: 120
});
}
});
}
};
}
}
// Lisa
if (rel_lisa > 70 && !lisaPregnant) {
var btnLisa = new OptionButton();
btnLisa.setText("Lisa ile ilişkiye gir");
btnLisa.x = 2048 - 400;
btnLisa.y = 80;
btnLisa.setCallback(function () {
// %30 hamile kalma şansı
if (Math.random() < 0.3) {
lisaPregnant = true;
showStoryNode(currentNode);
}
});
game.addChild(btnLisa);
game._relOptionBtns.push(btnLisa);
}
// Rebecca
if (rel_rebecca > 70 && !rebeccaPregnant) {
var btnRebecca = new OptionButton();
btnRebecca.setText("Rebecca ile ilişkiye gir");
btnRebecca.x = 2048 - 400;
btnRebecca.y = 220;
btnRebecca.setCallback(function () {
if (Math.random() < 0.3) {
rebeccaPregnant = true;
showStoryNode(currentNode);
}
});
game.addChild(btnRebecca);
game._relOptionBtns.push(btnRebecca);
}
// Giselle
if (giselleUnlocked && !gisellePregnant) {
var btnGiselle = new OptionButton();
btnGiselle.setText("Giselle ile ilişkiye gir");
btnGiselle.x = 2048 - 400;
btnGiselle.y = 360;
btnGiselle.setCallback(function () {
if (Math.random() < 0.3) {
gisellePregnant = true;
showStoryNode(currentNode);
}
});
game.addChild(btnGiselle);
game._relOptionBtns.push(btnGiselle);
}
}
function updateBars() {
if (typeof villaUnlocked !== "undefined" && villaUnlocked && bar_happy < 80) {
bar_happy = 80;
}
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];
var _loop = function _loop() {
names = ['Lisa', 'Rebecca', 'Peter', 'Alex'];
label = characterLabels[i];
prevText = label.text;
newText = names[i] + ': ' + rels[i] + '%'; // Değer değiştiyse animasyon başlat
if (prevText !== newText) {
// Son değeri bul
prevVal = 0;
match = prevText && prevText.match(/: (\-?\d+)%/);
if (match) prevVal = parseInt(match[1]);
newVal = rels[i]; // Pozitif veya negatif değişim: sadece etkilenen karakter titresin
if (newVal > prevVal || newVal < prevVal) {
// Sadece ilişki değeri değişen karakter titresin
portrait = characterPortraits[i];
if (portrait) {
var _doShakeChar = function doShakeChar() {
if (!portrait.parent || shakeCount >= 6) {
// Titreme bitti, orijinal konuma dön
portrait.x = origX;
portrait.y = origY;
return;
}
var dx = (Math.random() - 0.5) * 16;
var dy = (Math.random() - 0.5) * 10;
tween(portrait, {
x: origX + dx,
y: origY + dy
}, {
duration: 50,
easing: tween.linear,
onFinish: function onFinish() {
tween(portrait, {
x: origX,
y: origY
}, {
duration: 50,
easing: tween.linear,
onFinish: function onFinish() {
shakeCount++;
LK.setTimeout(_doShakeChar, 10);
}
});
}
});
};
// Titreme animasyonu uygula
origX = portrait.x;
origY = portrait.y;
shakeCount = 0;
_doShakeChar();
}
}
if (newVal > prevVal) {
if (label.style) label.style.fill = '#00ff00';
tween(label, {
alpha: 0.3
}, {
duration: 120,
easing: tween.linear,
onFinish: function (lbl) {
tween(lbl, {
alpha: 1
}, {
duration: 120,
easing: tween.linear,
onFinish: function (lbl2) {
if (lbl2.style) lbl2.style.fill = '#ffffff';
}.bind(null, label)
});
}.bind(null, label)
});
} else if (newVal < prevVal) {
if (label.style) label.style.fill = '#ff2222';
tween(label, {
alpha: 0.3
}, {
duration: 120,
easing: tween.linear,
onFinish: function (lbl) {
tween(lbl, {
alpha: 1
}, {
duration: 120,
easing: tween.linear,
onFinish: function (lbl2) {
if (lbl2.style) lbl2.style.fill = '#ffffff';
}.bind(null, label)
});
}.bind(null, label)
});
}
}
label.setText(newText);
},
names,
label,
prevText,
newText,
prevVal,
match,
newVal,
portrait,
origX,
origY,
shakeCount;
for (var i = 0; i < characterLabels.length; i++) {
_loop();
}
// --- Ava: Update day, salary, money, baby count UI ---
if (dayText) dayText.setText('Gün: ' + dayCount);
if (salaryText) salaryText.setText('Maaş: $' + mikeSalary);
if (moneyText) moneyText.setText('Para: $' + mikeMoney);
if (babyText) babyText.setText('Bebek: ' + mikeBabyCount);
// Refresh relationship option buttons
if (typeof createUI === "function") {
// Only refresh if UI is visible (avoid infinite loop)
if (game && typeof game._relOptionBtns !== "undefined") {
createUI();
}
}
}
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(storyText, {
alpha: 1
}, {
duration: 1200,
easing: tween.easeOut
});
} 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(storyText, {
alpha: 1
}, {
duration: 1200,
easing: tween.easeOut
});
} 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 villaUnlocked !== "undefined" && villaUnlocked && bar_happy < 80) {
bar_happy = 80;
}
}
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)));
// --- Villa davet event: karakterle ilişkiyi %15 artır (etki zaten effects ile geliyor, ama burada ek bir kontrol de eklenebilir) ---
if (meta && meta.type === "villa_invite" && typeof meta.character === "string") {
if (meta.character === "lisa") rel_lisa = Math.min(100, rel_lisa + 15);
if (meta.character === "rebecca") rel_rebecca = Math.min(100, rel_rebecca + 15);
if (meta.character === "peter") rel_peter = Math.min(100, rel_peter + 15);
if (meta.character === "alex") rel_alex = Math.min(100, rel_alex + 15);
}
// --- Giselle para harcama ve hamilelik ---
if (meta && meta.type === "giselle_spend" && typeof meta.money === "number") {
mikeMoney = Math.max(0, mikeMoney + meta.money);
}
// --- Whiskey para harcama ---
if (meta && meta.type === "whiskey_spend" && typeof meta.money === "number") {
mikeMoney = Math.max(0, mikeMoney + meta.money);
}
if (meta && meta.type === "giselle_baby" && giselleUnlocked && !gisellePregnant) {
if (Math.random() < 0.3) {
gisellePregnant = true;
// Bebek doğumu bir sonraki günlerde gerçekleşecek
}
}
// --- 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++;
// --- Ava: Advance time every 2 turns (1 day = 2 questions) ---
if (turnCount % 2 === 0) {
dayCount++;
// Mike maaş alır
mikeMoney += mikeSalary;
// Alex ile ilişki > 70 ise maaş +50
if (rel_alex > 70) {
mikeSalary += 50;
}
// Alex ile ilişki < 30 ise maaş -20
if (rel_alex < 30) {
mikeSalary = Math.max(0, mikeSalary - 20);
}
// Peter ile ilişki > 70 ise mutluluk +1
if (rel_peter > 70) {
bar_happy = Math.min(100, bar_happy + 1);
}
// Lisa hamile ise doğum (her gün %10 ihtimal)
if (lisaPregnant && Math.random() < 0.1) {
mikeBabyCount++;
lisaPregnant = false;
}
// Rebecca hamile ise doğum (her gün %10 ihtimal)
if (rebeccaPregnant && Math.random() < 0.1) {
mikeBabyCount++;
rebeccaPregnant = false;
}
// Giselle hamile ise doğum (her gün %10 ihtimal)
if (gisellePregnant && Math.random() < 0.1) {
mikeBabyCount++;
gisellePregnant = false;
}
// Save to storage
storage.mikeMoney = mikeMoney;
storage.mikeSalary = mikeSalary;
storage.mikeBabyCount = mikeBabyCount;
storage.dayCount = dayCount;
storage.lisaPregnant = lisaPregnant;
storage.rebeccaPregnant = rebeccaPregnant;
// Update UI
updateBars();
}
// --- 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(storyText, {
alpha: 1
}, {
duration: 1200,
easing: tween.easeOut
});
}
// 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(storyText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
}
}
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(storyText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
}
// Portrait kırmızıya döner, kısa süreliğine
if (portraitNode) {
var oldTint = portraitNode.tint;
portraitNode.tint = 0xd0021b;
tween(portraitNode, {
tint: oldTint
}, {
duration: 1200,
easing: tween.easeOut
});
}
}
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(storyText, {
alpha: 1
}, {
duration: 1500,
easing: tween.easeOut
});
}
if (portraitNode) {
tween(portraitNode, {
alpha: 0.2
}, {
duration: 1500,
easing: tween.easeOut
});
}
}
// 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(portraitNode, {
alpha: 0.3
}, {
duration: 1200,
easing: tween.easeOut
});
// 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(cross1, {
alpha: 0.85
}, {
duration: 400,
easing: tween.easeOut
});
tween(cross2, {
alpha: 0.85
}, {
duration: 400,
easing: tween.easeOut
});
// Fade out after 1.2s
LK.setTimeout(function () {
tween(cross1, {
alpha: 0
}, {
duration: 600,
easing: tween.easeOut
});
tween(cross2, {
alpha: 0
}, {
duration: 600,
easing: tween.easeOut
});
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
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.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;
});
// Passive background object base class
var PassiveBgObject = Container.expand(function () {
var self = Container.call(this);
self.speed = 0;
self.assetId = '';
self.asset = null;
self.setAsset = function (assetId) {
if (self.asset) self.removeChild(self.asset);
self.assetId = assetId;
self.asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
};
self.resetPosition = function () {
// Start just outside right edge, random Y
self.x = 2048 + (self.asset ? self.asset.width : 100) / 2 + Math.random() * 200;
self.y = 200 + Math.random() * 2100;
};
self.update = function () {
if (typeof self.lastX === "undefined") self.lastX = self.x;
self.x -= self.speed;
// If off screen to the left, reset
if (self.lastX >= -200 && self.x < -200) {
self.resetPosition();
}
self.lastX = self.x;
};
return self;
});
// Motorcycle
var BgMotorcycle = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_motorcycle');
self.speed = 4.0 + Math.random() * 1.5;
self.resetPosition();
return self;
});
// Heart
var BgHeart = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_heart');
self.speed = 2.7 + Math.random() * 1.2;
self.resetPosition();
return self;
});
// Football
var BgFootball = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_football');
self.speed = 2.5 + Math.random() * 1.2;
self.resetPosition();
return self;
});
// Car
var BgCar = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_car');
self.speed = 3.2 + Math.random() * 1.5;
self.resetPosition();
return self;
});
// Briefcase
var BgBriefcase = PassiveBgObject.expand(function () {
var self = PassiveBgObject.call(this);
self.setAsset('bg_briefcase');
self.speed = 2.2 + Math.random() * 1.2;
self.resetPosition();
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
****/
// Animate passive background objects
// Sağdan sola giden araba
// Sağdan sola giden iş çantası
// Sağdan sola giden ateşli kalp
// Sağdan sola giden futbol topu
// Sağdan sola giden motor
// --- Shop/Store assets (right side) ---
// Example id, replace with real
if (typeof bgObjects !== "undefined") {
for (var i = 0; i < bgObjects.length; i++) {
if (bgObjects[i] && typeof bgObjects[i].update === "function") {
bgObjects[i].update();
}
}
}
// No per-frame logic needed
// Not: 'background' asseti image olarak tanımlanmalı, ör: LK.init.image('background', {width:2048, height:2732, id:'YOUR_IMAGE_ID'})
var backgroundNode = LK.getAsset('background', {
anchorX: 0,
anchorY: 0
});
backgroundNode.width = 2048;
backgroundNode.height = 2732;
backgroundNode.x = 0;
backgroundNode.y = 0;
backgroundNode.zIndex = -100; // Her şeyin arkasında dursun
game.addChild(backgroundNode);
// --- Passive background objects (car, briefcase, heart, football, motorcycle) ---
var bgObjects = [];
function spawnBgObjects() {
// Remove old ones if any
for (var i = 0; i < bgObjects.length; i++) {
if (bgObjects[i] && bgObjects[i].parent) {
game.removeChild(bgObjects[i]);
}
}
bgObjects = [];
// Add 2 of each for variety
for (var i = 0; i < 2; i++) {
var car = new BgCar();
var briefcase = new BgBriefcase();
var heart = new BgHeart();
var football = new BgFootball();
var motorcycle = new BgMotorcycle();
game.addChild(car);
game.addChild(briefcase);
game.addChild(heart);
game.addChild(football);
game.addChild(motorcycle);
bgObjects.push(car, briefcase, heart, football, motorcycle);
}
}
spawnBgObjects();
// Çarpıcı seçimler: her 4-6 sahnede bir, yüksek risk/ödül, animasyonlu, barları büyük oranda etkiler
// --- Dramatic Choice (Çarpıcı Seçim) System ---
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; // Start fully transparent
shadow.zIndex = 99;
game.addChild(shadow);
game._dramaticShadow = shadow;
// Animate shadow fade-in
tween(shadow, {
alpha: 0.7
}, {
duration: 220,
easing: tween.easeOut
});
} else {
// If already present, ensure it's visible and interactive
game._dramaticShadow.alpha = 0.7;
game._dramaticShadow.zIndex = 99;
}
// 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 = 1.0; // No animation
}
// Dramatic option buttons: ensure visible, enabled, and selectable
for (var i = 0; i < node.options.length; i++) {
(function (opt, idx) {
var btn = new OptionButton();
btn.setText(opt.text);
// Büyük ve dikkat çekici: butonları daha büyük yap
btn.scale.x = 1.35;
btn.scale.y = 1.35;
// Ekranda tamamen görünür ve aralıklı olacak şekilde ayarla
// Yüksekliğe göre ortala, iki seçenek için yukarıdan ve aşağıdan eşit boşluk bırak
var totalBtnHeight = 2 * (btn.bg.height * btn.scale.y) + 120;
var startY = 1800 - totalBtnHeight / 2;
btn.x = 2048 / 2;
btn.y = startY + idx * (btn.bg.height * btn.scale.y + 120);
btn.alpha = 1.0;
btn.bg.tint = 0x000000;
if (btn.text && btn.text.style) btn.text.style.fill = '#ffffff';
btn.zIndex = 100;
btn.interactive = true;
btn.buttonMode = true;
// Make sure button is enabled and not grayed out
btn.bg.tint = 0x000000;
if (btn.text && btn.text.style) btn.text.style.fill = '#ffffff';
// Remove any previous disabled state
btn.alpha = 1.0;
btn.visible = true;
btn.setCallback(function () {
// Seçim sırasında iki butonu da büyüt ve animasyon ekle
for (var j = 0; j < optionButtons.length; j++) {
var b = optionButtons[j];
// Seçilen buton daha fazla büyüsün, diğeri de büyüsün ama biraz az
var targetScale = b === btn ? 1.55 : 1.25;
tween(b.scale, {
x: targetScale,
y: targetScale
}, {
duration: 220,
easing: tween.easeOut
});
tween(b, {
alpha: 1
}, {
duration: 220,
easing: tween.easeOut
});
}
// Seçimden kısa süre sonra butonları ve gölgeyi kaldır
LK.setTimeout(function () {
// Remove shadow overlay with fade out
if (game._dramaticShadow) {
tween(game._dramaticShadow, {
alpha: 0
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function onFinish() {
if (game._dramaticShadow) {
game.removeChild(game._dramaticShadow);
game._dramaticShadow = null;
}
}
});
}
// Remove buttons instantly
for (var j = 0; j < optionButtons.length; j++) {
(function (b) {
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);
}, 260);
});
game.addChild(btn);
optionButtons.push(btn);
})(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
// --- Whiskey'e özel sorular (yalnızca satın alındıysa gösterilecek) ---
var whiskeyQuestions = [{
id: "whiskey_intro",
text: "Whiskey: 'Hav hav! Mike, parka gidelim mi?'",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Whiskey'i parka götür.",
effects: {
happy: 5
}
}, {
text: "Bugün evde kalalım.",
effects: {
happy: -2
}
}]
}, {
id: "whiskey_walk",
text: "Whiskey kapının önünde heyecanla bekliyor. Dışarı çıkarmak ister misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Whiskey ile uzun yürüyüş yap.",
effects: {
happy: 5
}
}, {
text: "Kısa bir yürüyüş yap.",
effects: {
happy: 2
}
}, {
text: "Yürüyüşe çıkma.",
effects: {
happy: -3
}
}]
}, {
id: "whiskey_vet",
text: "Whiskey biraz halsiz görünüyor. Veterinere götürecek misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Veterinere götür. ($200 harca)",
effects: {
happy: 5
},
meta: {
type: "whiskey_spend",
money: -200
}
}, {
text: "Evde dinlensin.",
effects: {
happy: -2
}
}]
}, {
id: "whiskey_toy",
text: "Whiskey yeni bir oyuncak istiyor.",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Oyuncak al. ($50 harca)",
effects: {
happy: 3
},
meta: {
type: "whiskey_spend",
money: -50
}
}, {
text: "Oyuncak alma.",
effects: {
happy: -2
}
}]
}, {
id: "whiskey_bath",
text: "Whiskey çamura bulandı! Yıkayacak mısın?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Whiskey'i yıka.",
effects: {
happy: 2
}
}, {
text: "Yıkamadan bırak.",
effects: {
happy: -3
}
}]
}, {
id: "whiskey_trick",
text: "Whiskey yeni bir numara öğrenmek istiyor. Öğretecek misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Yeni numara öğret.",
effects: {
happy: 4
}
}, {
text: "Vakit ayırma.",
effects: {
happy: -2
}
}]
}, {
id: "whiskey_vacation",
text: "Tatile çıkacaksınız. Whiskey'i de götürecek misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Whiskey'i de götür. ($300 harca)",
effects: {
happy: 5
},
meta: {
type: "whiskey_spend",
money: -300
}
}, {
text: "Whiskey'i pansiyona bırak. ($150 harca)",
effects: {
happy: 2
},
meta: {
type: "whiskey_spend",
money: -150
}
}]
}, {
id: "whiskey_birthday",
text: "Whiskey'in doğum günü! Ona özel bir şey yapmak ister misin?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Köpek pastası al. ($80 harca)",
effects: {
happy: 4
},
meta: {
type: "whiskey_spend",
money: -80
}
}, {
text: "Sadece sarıl.",
effects: {
happy: 2
}
}]
}, {
id: "whiskey_lost",
text: "Whiskey bahçede kayboldu! Arayacak mısın?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Bahçede ara.",
effects: {
happy: 3
}
}, {
text: "Kendi gelir diye bekle.",
effects: {
happy: -3
}
}]
}, {
id: "whiskey_vet2",
text: "Whiskey aşı zamanı geldi. Aşı yaptıracak mısın?",
portrait: "whiskey",
speaker: "Whiskey",
options: [{
text: "Aşı yaptır. ($120 harca)",
effects: {
happy: 3
},
meta: {
type: "whiskey_spend",
money: -120
}
}, {
text: "Aşıyı ertele.",
effects: {
happy: -2
}
}]
}];
// --- Villa'ya davet eventleri ve özel sorular (her karakter için 2'şer tane) ---
var villaInviteEvents = [{
id: "villa_invite_lisa",
text: "Artık bir villan var! Lisa'yı eve davet etmek ister misin?",
portrait: "lisa",
speaker: "Lisa",
options: [{
text: "Lisa'yı villaya davet et.",
effects: {
lisa: 15,
happy: 5
},
meta: {
type: "villa_invite",
character: "lisa"
}
}, {
text: "Davet etme.",
effects: {
lisa: -2
}
}]
}, {
id: "villa_invite_rebecca",
text: "Artık bir villan var! Rebecca'yı eve davet etmek ister misin?",
portrait: "rebecca",
speaker: "Rebecca",
options: [{
text: "Rebecca'yı villaya davet et.",
effects: {
rebecca: 15,
happy: 5
},
meta: {
type: "villa_invite",
character: "rebecca"
}
}, {
text: "Davet etme.",
effects: {
rebecca: -2
}
}]
}, {
id: "villa_invite_peter",
text: "Artık bir villan var! Peter'ı eve davet etmek ister misin?",
portrait: "peter",
speaker: "Peter",
options: [{
text: "Peter'ı villaya davet et.",
effects: {
peter: 15,
happy: 5
},
meta: {
type: "villa_invite",
character: "peter"
}
}, {
text: "Davet etme.",
effects: {
peter: -2
}
}]
}, {
id: "villa_invite_alex",
text: "Artık bir villan var! Alex'i eve davet etmek ister misin?",
portrait: "alex",
speaker: "Alex",
options: [{
text: "Alex'i villaya davet et.",
effects: {
alex: 15,
happy: 5
},
meta: {
type: "villa_invite",
character: "alex"
}
}, {
text: "Davet etme.",
effects: {
alex: -2
}
}]
}];
var villaSpecialQuestions = [
// Lisa
{
id: "villa_lisa_1",
text: "Lisa: 'Bu evde birlikte yeni anılar biriktirelim mi?'",
portrait: "lisa",
speaker: "Lisa",
options: [{
text: "Evet, birlikte çok güzel anılarımız olacak.",
effects: {
lisa: 10,
happy: 5
}
}, {
text: "Ev güzel ama önemli olan sensin.",
effects: {
lisa: 7,
honest: 3
}
}]
}, {
id: "villa_lisa_2",
text: "Lisa: 'Villada bir parti verelim mi?'",
portrait: "lisa",
speaker: "Lisa",
options: [{
text: "Harika fikir, parti verelim.",
effects: {
lisa: 8,
happy: 4
}
}, {
text: "Parti istemiyorum.",
effects: {
lisa: -3
}
}]
},
// Rebecca
{
id: "villa_rebecca_1",
text: "Rebecca: 'Villanın havuzunda gece yüzmek ister misin?'",
portrait: "rebecca",
speaker: "Rebecca",
options: [{
text: "Tabii, birlikte yüzmek harika olur.",
effects: {
rebecca: 10,
lust: 5
}
}, {
text: "Yorgunum, başka zaman.",
effects: {
rebecca: -2
}
}]
}, {
id: "villa_rebecca_2",
text: "Rebecca: 'Villada baş başa bir akşam geçirelim mi?'",
portrait: "rebecca",
speaker: "Rebecca",
options: [{
text: "Evet, baş başa kalmak güzel olur.",
effects: {
rebecca: 8,
happy: 3
}
}, {
text: "Bugün olmaz.",
effects: {
rebecca: -2
}
}]
},
// Peter
{
id: "villa_peter_1",
text: "Peter: 'Bahçede mangal yapalım mı?'",
portrait: "peter",
speaker: "Peter",
options: [{
text: "Mangal harika olur!",
effects: {
peter: 10,
happy: 4
}
}, {
text: "Başka zaman.",
effects: {
peter: -2
}
}]
}, {
id: "villa_peter_2",
text: "Peter: 'Villada birlikte film gecesi yapalım mı?'",
portrait: "peter",
speaker: "Peter",
options: [{
text: "Evet, film gecesi yapalım.",
effects: {
peter: 8,
happy: 3
}
}, {
text: "İstemiyorum.",
effects: {
peter: -2
}
}]
},
// Alex
{
id: "villa_alex_1",
text: "Alex: 'Bu villada iş toplantısı yapmak isterim.'",
portrait: "alex",
speaker: "Alex",
options: [{
text: "Tabii, toplantı yapabiliriz.",
effects: {
alex: 10,
happy: 2
}
}, {
text: "Evde iş konuşmak istemiyorum.",
effects: {
alex: -2
}
}]
}, {
id: "villa_alex_2",
text: "Alex: 'Villanın manzarası harika, burada çalışmak isterim.'",
portrait: "alex",
speaker: "Alex",
options: [{
text: "İstediğin zaman gelebilirsin.",
effects: {
alex: 8,
honest: 2
}
}, {
text: "Evde yalnız kalmak istiyorum.",
effects: {
alex: -2
}
}]
}];
// --- Giselle'e özel sorular (yalnızca satın alındıysa gösterilecek) ---
var giselleQuestions = [{
id: "giselle_intro",
text: "Giselle: 'Mike, yeni bir çanta almak istiyorum. Bütçemiz yeterli mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Tabii, hemen alalım. ($500 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -500
}
}, {
text: "Şu an alamayız, bütçemiz kısıtlı.",
effects: {
happy: -5,
honest: 5
},
meta: {
type: "truth"
}
}]
}, {
id: "giselle_shopping",
text: "Giselle: 'Alışverişe çıkalım mı? Birkaç şey almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Giselle'e para ver. ($300 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -300
}
}, {
text: "Bugün alışveriş yok.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_dinner",
text: "Giselle: 'Bu akşam dışarıda yemek yiyelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Lüks restorana git. ($400 harca)",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_spend",
money: -400
}
}, {
text: "Evde yemek yapalım.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_gift",
text: "Giselle: 'Bana hediye alır mısın?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Pahalı bir kolye al. ($1000 harca)",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_spend",
money: -1000
}
}, {
text: "Küçük bir hediye al. ($100 harca)",
effects: {
happy: 3
},
meta: {
type: "giselle_spend",
money: -100
}
}, {
text: "Hediye almayacağım.",
effects: {
happy: -10
}
}]
}, {
id: "giselle_jealous",
text: "Giselle: 'Lisa ile çok vakit geçiriyorsun, kıskanıyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Giselle'e güven ver.",
effects: {
happy: 5,
honest: 5
}
}, {
text: "Lisa ile görüşmeyi azalt.",
effects: {
happy: 2,
lust: -2
}
}]
}, {
id: "giselle_party",
text: "Giselle: 'Hafta sonu partiye gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Partiye git. ($200 harca)",
effects: {
happy: 5,
lust: 5
},
meta: {
type: "giselle_spend",
money: -200
}
}, {
text: "Evde kalalım.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_baby",
text: "Giselle: 'Bir bebek sahibi olmayı düşünür müsün?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Evet, isterim.",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_baby"
}
}, {
text: "Henüz hazır değilim.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_trip",
text: "Giselle: 'Birlikte tatile çıkalım mı?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Tatile çık. ($1500 harca)",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_spend",
money: -1500
}
}, {
text: "Tatil için paramız yok.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_friends",
text: "Giselle: 'Arkadaşlarımı davet edebilir miyim?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Tabii, davet et.",
effects: {
happy: 5
}
}, {
text: "Hayır, bu akşam yalnız kalalım.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_shoes",
text: "Giselle: 'Yeni ayakkabılar almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Ayakkabı al. ($250 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -250
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_movie",
text: "Giselle: 'Bu akşam sinemaya gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Sinemaya git. ($100 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -100
}
}, {
text: "Evde film izleyelim.",
effects: {
happy: 2
}
}]
}, {
id: "giselle_dress",
text: "Giselle: 'Yeni bir elbise almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Elbise al. ($350 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -350
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_jewelry",
text: "Giselle: 'Takı mağazasına gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Takı al. ($200 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -200
}
}, {
text: "Takı almayalım.",
effects: {
happy: -2
}
}]
}, {
id: "giselle_spa",
text: "Giselle: 'Birlikte spa'ya gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Spa'ya git. ($400 harca)",
effects: {
happy: 7
},
meta: {
type: "giselle_spend",
money: -400
}
}, {
text: "Evde dinlenelim.",
effects: {
happy: 2
}
}]
}, {
id: "giselle_phone",
text: "Giselle: 'Yeni bir telefon almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Telefon al. ($1200 harca)",
effects: {
happy: 10
},
meta: {
type: "giselle_spend",
money: -1200
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -5
}
}]
}, {
id: "giselle_bag",
text: "Giselle: 'Çantam eskidi, yenisini alabilir miyiz?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Çanta al. ($300 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -300
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_makeup",
text: "Giselle: 'Kozmetik alışverişi yapalım mı?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Kozmetik al. ($150 harca)",
effects: {
happy: 3
},
meta: {
type: "giselle_spend",
money: -150
}
}, {
text: "Hayır, gerek yok.",
effects: {
happy: -2
}
}]
}, {
id: "giselle_jacket",
text: "Giselle: 'Yeni bir ceket almak istiyorum.'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Ceket al. ($400 harca)",
effects: {
happy: 5
},
meta: {
type: "giselle_spend",
money: -400
}
}, {
text: "Şu an alamayız.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_ring",
text: "Giselle: 'Yüzük bakmaya gidelim mi?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Yüzük al. ($800 harca)",
effects: {
happy: 8
},
meta: {
type: "giselle_spend",
money: -800
}
}, {
text: "Yüzük almayalım.",
effects: {
happy: -3
}
}]
}, {
id: "giselle_baby2",
text: "Giselle: 'Bebek sahibi olmayı hâlâ düşünüyor musun?'",
portrait: "giselle",
speaker: "Giselle",
options: [{
text: "Evet, isterim.",
effects: {
happy: 10,
lust: 5
},
meta: {
type: "giselle_baby"
}
}, {
text: "Henüz hazır değilim.",
effects: {
happy: -5
}
}]
}];
// --- Ana story havuzu ---
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
}]
},
// --- Ava: New story questions for more variety ---
{
text: "Lisa ile alışverişe çıktınız. Lisa yeni bir elbise almak istiyor.",
portrait: 'lisa',
speaker: 'Lisa',
options: [{
text: "Elbise almasına destek ol.",
effects: {
lisa: 10,
happy: 5
}
}, {
text: "Bütçemiz kısıtlı, başka zaman alalım.",
effects: {
lisa: -5,
honest: 5
}
}]
}, {
text: "Rebecca iş yerinde sana bir sır veriyor.",
portrait: 'rebecca',
speaker: 'Rebecca',
options: [{
text: "Sırrını sakla.",
effects: {
rebecca: 10,
honest: 5
}
}, {
text: "Sırrı başkasına anlat.",
effects: {
rebecca: -10,
betray: 10
}
}]
}, {
text: "Peter ile futbol maçı izliyorsunuz.",
portrait: 'peter',
speaker: 'Peter',
options: [{
text: "Beraber tezahürat yap.",
effects: {
peter: 10,
happy: 5
}
}, {
text: "Maçtan sıkıldığını söyle.",
effects: {
peter: -5
}
}]
}, {
text: "Alex yeni bir iş fırsatı sunuyor.",
portrait: 'alex',
speaker: 'Alex',
options: [{
text: "Fırsatı kabul et.",
effects: {
alex: 10,
happy: 5
}
}, {
text: "Reddet, mevcut işinden memnunsun.",
effects: {
alex: -5,
honest: 5
}
}]
}, {
text: "Lisa ile tartıştınız. Lisa üzgün.",
portrait: 'lisa',
speaker: 'Lisa',
options: [{
text: "Özür dile.",
effects: {
lisa: 10,
honest: 5
}
}, {
text: "Haklı olduğunu savun.",
effects: {
lisa: -10
}
}]
}, {
text: "Rebecca ile sinemaya gitme planı yapıyorsun.",
portrait: 'rebecca',
speaker: 'Rebecca',
options: [{
text: "Romantik bir film seç.",
effects: {
rebecca: 10,
lust: 5
}
}, {
text: "Aksiyon filmi seç.",
effects: {
rebecca: 5
}
}]
}, {
text: "Peter sana bir kitap öneriyor.",
portrait: 'peter',
speaker: 'Peter',
options: [{
text: "Kitabı oku ve yorum yap.",
effects: {
peter: 10,
honest: 5
}
}, {
text: "Kitabı okumadığını itiraf et.",
effects: {
peter: -5,
honest: 5
}
}]
}, {
text: "Alex ile iş seyahatine çıkıyorsun.",
portrait: 'alex',
speaker: 'Alex',
options: [{
text: "Alex ile yakınlaş.",
effects: {
alex: 10,
betray: 5
}
}, {
text: "Mesafeni koru.",
effects: {
alex: 5,
honest: 5
}
}]
}, {
text: "Lisa sana sürpriz bir doğum günü partisi hazırlıyor.",
portrait: 'lisa',
speaker: 'Lisa',
options: [{
text: "Çok mutlu ol ve teşekkür et.",
effects: {
lisa: 10,
happy: 10
}
}, {
text: "Sürprizleri sevmediğini söyle.",
effects: {
lisa: -5,
honest: 5
}
}]
}, {
text: "Rebecca ile bir tartışma yaşıyorsun.",
portrait: 'rebecca',
speaker: 'Rebecca',
options: [{
text: "Barışmak için adım at.",
effects: {
rebecca: 10
}
}, {
text: "Tartışmayı uzat.",
effects: {
rebecca: -10
}
}]
}, {
text: "Peter ile eski bir fotoğraf albümüne bakıyorsun.",
portrait: 'peter',
speaker: 'Peter',
options: [{
text: "Güzel anıları hatırla.",
effects: {
peter: 10,
happy: 5
}
}, {
text: "Geçmişi konuşmak istemediğini söyle.",
effects: {
peter: -5
}
}]
}, {
text: "Alex iş yerinde seni övüyor.",
portrait: 'alex',
speaker: 'Alex',
options: [{
text: "Teşekkür et.",
effects: {
alex: 10,
happy: 5
}
}, {
text: "Mütevazı davran.",
effects: {
alex: 5
}
}]
}, {
text: "Lisa ile birlikte yemek yapıyorsun.",
portrait: 'lisa',
speaker: 'Lisa',
options: [{
text: "Birlikte eğlenerek yemek yap.",
effects: {
lisa: 10,
happy: 5
}
}, {
text: "Yemek yapmayı sevmediğini söyle.",
effects: {
lisa: -5
}
}]
}, {
text: "Rebecca yeni bir hobiye başlamak istiyor.",
portrait: 'rebecca',
speaker: 'Rebecca',
options: [{
text: "Onu destekle.",
effects: {
rebecca: 10
}
}, {
text: "Hobisini gereksiz bul.",
effects: {
rebecca: -5
}
}]
}, {
text: "Peter ile bir iş projesinde çalışıyorsun.",
portrait: 'peter',
speaker: 'Peter',
options: [{
text: "Peter'ın fikirlerine değer ver.",
effects: {
peter: 10
}
}, {
text: "Kendi bildiğini yap.",
effects: {
peter: -5
}
}]
}, {
text: "Alex ile bir anlaşmazlık yaşıyorsun.",
portrait: 'alex',
speaker: 'Alex',
options: [{
text: "Uzlaşmacı ol.",
effects: {
alex: 10
}
}, {
text: "Kendi fikrinde ısrar et.",
effects: {
alex: -5
}
}]
},
// 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;
// --- Ava: Time, salary, baby, pregnancy, money mechanics ---
var dayCount = 1; // 1-based, every 2 questions = 1 day
var mikeSalary = 100;
var mikeMoney = 0;
var mikeBabyCount = 0;
var lisaPregnant = false;
var rebeccaPregnant = false;
var gisellePregnant = false;
var showLisaPregOption = false;
var showRebeccaPregOption = false;
var showGisellePregOption = false;
var giselleUnlocked = false; // Satın alındı mı?
var shopItemStates = [false, false, false, false]; // 0: Giselle, 1-3: diğerleri
// --- 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 = [];
// --- Ava: UI for day, salary, money, baby count ---
var dayText = null;
var salaryText = null;
var moneyText = null;
var babyText = null;
// --- Functions ---
// getNextNode: uygun story node'unu bar değerine göre seç
// --- Ava: Prevent same question from repeating within last 20, and add more questions ---
var lastStoryIndices = [];
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;
}
// Ava: Filter out nodes that were used in the last 20
var filteredIndices = [];
for (var k = 0; k < indices.length; k++) {
var idx = indices[k];
if (lastStoryIndices.indexOf(idx) === -1) {
filteredIndices.push(idx);
}
}
// If less than 5 available, allow all (reset)
var useIndices = filteredIndices.length > 5 ? filteredIndices : indices;
// --- Giselle: Eğer satın alındıysa, havuza Giselle sorularını da ekle ---
// --- Whiskey: Eğer satın alındıysa, havuza Whiskey sorularını da ekle ---
// --- Villa: Eğer satın alındıysa, havuza Villa event ve sorularını da ekle ---
var pool = [];
for (var k = 0; k < useIndices.length; k++) {
var idx = useIndices[k];
var node = story[idx];
// Sadece Giselle alınmışsa Giselle soruları havuza eklenir
if (node && node.portrait === "giselle" && !giselleUnlocked) continue;
// Sadece Whiskey alınmışsa Whiskey soruları havuza eklenir
if (node && node.portrait === "whiskey" && !whiskeyUnlocked) continue;
// Villa eventleri ve soruları sadece villaUnlocked ise eklenir
if (node && node.id && node.id.indexOf("villa_") === 0 && !villaUnlocked) continue;
pool.push({
idx: idx,
node: node
});
}
if (giselleUnlocked) {
// Son 20'de olmayan Giselle sorularını da ekle
for (var g = 0; g < giselleQuestions.length; g++) {
var gq = giselleQuestions[g];
var gqId = "giselle_" + g;
// Sadece son 20'de yoksa ekle
var alreadyUsed = false;
for (var h = 0; h < lastStoryIndices.length; h++) {
if (story[lastStoryIndices[h]] && story[lastStoryIndices[h]].id === gq.id) alreadyUsed = true;
}
if (!alreadyUsed) {
pool.push({
idx: -1,
node: gq
});
}
}
}
if (whiskeyUnlocked) {
// Son 20'de olmayan Whiskey sorularını da ekle
for (var w = 0; w < whiskeyQuestions.length; w++) {
var wq = whiskeyQuestions[w];
var wqId = "whiskey_" + w;
var alreadyUsedW = false;
for (var h = 0; h < lastStoryIndices.length; h++) {
if (story[lastStoryIndices[h]] && story[lastStoryIndices[h]].id === wq.id) alreadyUsedW = true;
}
if (!alreadyUsedW) {
pool.push({
idx: -1,
node: wq
});
}
}
}
if (villaUnlocked) {
// Son 20'de olmayan Villa invite eventlerini ekle
for (var v = 0; v < villaInviteEvents.length; v++) {
var ve = villaInviteEvents[v];
var alreadyUsedV = false;
for (var h = 0; h < lastStoryIndices.length; h++) {
if (story[lastStoryIndices[h]] && story[lastStoryIndices[h]].id === ve.id) alreadyUsedV = true;
}
if (!alreadyUsedV) {
pool.push({
idx: -1,
node: ve
});
}
}
// Son 20'de olmayan Villa özel sorularını ekle
for (var vq = 0; vq < villaSpecialQuestions.length; vq++) {
var vsq = villaSpecialQuestions[vq];
var alreadyUsedVSQ = false;
for (var h = 0; h < lastStoryIndices.length; h++) {
if (story[lastStoryIndices[h]] && story[lastStoryIndices[h]].id === vsq.id) alreadyUsedVSQ = true;
}
if (!alreadyUsedVSQ) {
pool.push({
idx: -1,
node: vsq
});
}
}
}
// Her bir node'u sırayla kontrol et, barCheck varsa uygun olanı döndür
for (var k = 0; k < pool.length; k++) {
var idx = pool[k].idx;
var node = pool[k].node;
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) {
lastStoryIndices.push(idx);
if (lastStoryIndices.length > 20) lastStoryIndices.shift();
return idx;
}
} else {
lastStoryIndices.push(idx);
if (lastStoryIndices.length > 20) lastStoryIndices.shift();
return idx;
}
}
// Hiçbiri uygun değilse ilk node'u döndür
lastStoryIndices.push(0);
if (lastStoryIndices.length > 20) lastStoryIndices.shift();
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;
}
dayCount = 1;
mikeSalary = 100;
mikeMoney = 0;
mikeBabyCount = 0;
lisaPregnant = false;
rebeccaPregnant = false;
gisellePregnant = false;
giselleUnlocked = false;
whiskeyUnlocked = false;
villaUnlocked = false;
shopItemStates = [false, false, false, false];
if (storage) {
storage.mikeMoney = 0;
storage.mikeSalary = 100;
storage.mikeBabyCount = 0;
storage.dayCount = 1;
storage.lisaPregnant = false;
storage.rebeccaPregnant = false;
storage.gisellePregnant = false;
storage.giselleUnlocked = false;
storage.whiskeyUnlocked = false;
storage.villaUnlocked = false;
}
}
function createUI() {
// Portrait
if (portraitNode) game.removeChild(portraitNode);
portraitNode = LK.getAsset('mike', {
anchorX: 0.5,
anchorY: 0.5
});
// Mike portresini ve karakteri ekrana tam ortala
portraitNode.x = 2048 / 2;
portraitNode.y = 520;
game.addChild(portraitNode);
// --- Mike portresine titreme animasyonu ekle ---
function shakePortrait(node) {
if (!node) return;
var origX = 2048 / 2;
var origY = 520;
function doShake() {
// Rastgele küçük bir ofset (±8px)
var dx = (Math.random() - 0.5) * 16;
var dy = (Math.random() - 0.5) * 10;
tween(node, {
x: origX + dx,
y: origY + dy
}, {
duration: 80,
easing: tween.linear,
onFinish: function onFinish() {
tween(node, {
x: origX,
y: origY
}, {
duration: 80,
easing: tween.linear,
onFinish: function onFinish() {
LK.setTimeout(doShake, 80 + Math.floor(Math.random() * 60));
}
});
}
});
}
doShake();
}
shakePortrait(portraitNode);
// --- Eğer ilgili karakter portresi varsa ona da titreme ekle ---
if (game.relatedPortraitNode) {
var _shakeRelated = function shakeRelated() {
if (!relNode.parent) return; // Silindiyse dur
var dx = (Math.random() - 0.5) * 16;
var dy = (Math.random() - 0.5) * 10;
tween(relNode, {
x: relOrigX + dx,
y: relOrigY + dy
}, {
duration: 80,
easing: tween.linear,
onFinish: function onFinish() {
tween(relNode, {
x: relOrigX,
y: relOrigY
}, {
duration: 80,
easing: tween.linear,
onFinish: function onFinish() {
LK.setTimeout(_shakeRelated, 80 + Math.floor(Math.random() * 60));
}
});
}
});
};
var relNode = game.relatedPortraitNode;
var relOrigX = relNode.x;
var relOrigY = relNode.y;
_shakeRelated();
}
// Speaker (isim) biraz daha aşağıda
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 = 740;
game.addChild(speakerText);
// Story text (olay) biraz daha aşağıda
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 = 830;
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);
}
// --- Ava: Add day, salary, money, baby count UI ---
if (dayText) game.removeChild(dayText);
if (salaryText) game.removeChild(salaryText);
if (moneyText) game.removeChild(moneyText);
if (babyText) game.removeChild(babyText);
dayText = new Text2('Gün: ' + dayCount, {
size: 54,
fill: '#fff'
});
dayText.anchor.set(0, 0);
dayText.x = 120;
dayText.y = 80;
game.addChild(dayText);
salaryText = new Text2('Maaş: $' + mikeSalary, {
size: 54,
fill: '#fff'
});
salaryText.anchor.set(0, 0);
salaryText.x = 120;
salaryText.y = 150;
game.addChild(salaryText);
moneyText = new Text2('Para: $' + mikeMoney, {
size: 54,
fill: '#fff'
});
moneyText.anchor.set(0, 0);
moneyText.x = 120;
moneyText.y = 220;
game.addChild(moneyText);
babyText = new Text2('Bebek: ' + mikeBabyCount, {
size: 54,
fill: '#fff'
});
babyText.anchor.set(0, 0);
babyText.x = 120;
babyText.y = 290;
game.addChild(babyText);
// --- Ava: Show relationship options if eligible ---
// Remove old relationship option buttons if any
if (game._relOptionBtns) {
for (var i = 0; i < game._relOptionBtns.length; i++) {
game.removeChild(game._relOptionBtns[i]);
}
}
game._relOptionBtns = [];
// --- Shop/Store UI (right side, vertical) ---
if (game._shopNodes) {
for (var i = 0; i < game._shopNodes.length; i++) {
game.removeChild(game._shopNodes[i]);
}
}
game._shopNodes = [];
var shopAssetIds = ['giselle', 'shop_item2', 'shop_item3', 'shop_item4'];
var shopPrices = [10000, 2500, 50000, 7500];
var shopLabels = ['Giselle', 'Whiskey', 'Villa', 'Eşya 4'];
var shopYStart = 1200; // moved even further down
var shopSpacing = 450; // even more space between items
// --- Villa state ---
if (typeof villaUnlocked === "undefined") villaUnlocked = false;
if (typeof whiskeyUnlocked === "undefined") whiskeyUnlocked = false;
for (var i = 0; i < 4; i++) {
var assetId = shopAssetIds[i];
var node = LK.getAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
node.x = 2048 - 120;
node.y = shopYStart + i * shopSpacing;
node.scale.x = node.scale.y = 1.0;
// Shop items are passive (dimmed, not interactive) until purchased, then active
if (shopItemStates[i]) {
node.alpha = 1.0;
node.interactive = false;
node.buttonMode = false;
} else {
node.alpha = 0.5;
node.interactive = true;
node.buttonMode = true;
}
// Price label (above the item)
var priceText = "";
if (i === 0) {
priceText = "$10,000";
} else if (i === 1) {
priceText = "$2,500";
} else if (i === 2) {
priceText = "$50,000";
} else if (i === 3) {
priceText = "$7,500";
}
var priceLabel = new Text2(priceText, {
size: 38,
fill: '#ffe066',
fontWeight: 'bold'
});
priceLabel.anchor.set(0.5, 1);
priceLabel.x = node.x;
priceLabel.y = node.y - node.height / 2 - 12;
game.addChild(priceLabel);
game._shopNodes.push(priceLabel);
// Name label (below the item)
var label = new Text2(shopLabels[i], {
size: 36,
fill: '#fff',
wordWrap: true,
wordWrapWidth: 180
});
label.anchor.set(0.5, 0);
label.x = node.x;
label.y = node.y + node.height / 2 + 10;
game.addChild(node);
game.addChild(label);
game._shopNodes.push(node, label);
// Giselle buy logic
if (i === 0 && !giselleUnlocked) {
node.down = function () {
if (mikeMoney >= 10000) {
mikeMoney -= 10000;
giselleUnlocked = true;
shopItemStates[0] = true;
// After purchase, make the item active (full alpha, not interactive)
node.alpha = 1.0;
node.interactive = false;
node.buttonMode = false;
updateBars();
createUI();
} else {
// Not enough money, flash red
tween(node, {
alpha: 0.3
}, {
duration: 120,
onFinish: function onFinish() {
tween(node, {
alpha: 1
}, {
duration: 120
});
}
});
}
};
}
// Whiskey buy logic
if (i === 1 && !whiskeyUnlocked) {
node.down = function () {
if (mikeMoney >= 2500) {
mikeMoney -= 2500;
whiskeyUnlocked = true;
shopItemStates[1] = true;
// After purchase, make the item active (full alpha, not interactive)
node.alpha = 1.0;
node.interactive = false;
node.buttonMode = false;
updateBars();
createUI();
} else {
// Not enough money, flash red
tween(node, {
alpha: 0.3
}, {
duration: 120,
onFinish: function onFinish() {
tween(node, {
alpha: 1
}, {
duration: 120
});
}
});
}
};
}
// Villa buy logic
if (i === 2 && !villaUnlocked) {
node.down = function () {
if (mikeMoney >= 50000) {
mikeMoney -= 50000;
villaUnlocked = true;
shopItemStates[2] = true;
// After purchase, make the item active (full alpha, not interactive)
node.alpha = 1.0;
node.interactive = false;
node.buttonMode = false;
updateBars();
createUI();
} else {
tween(node, {
alpha: 0.3
}, {
duration: 120,
onFinish: function onFinish() {
tween(node, {
alpha: 1
}, {
duration: 120
});
}
});
}
};
}
}
// Lisa
if (rel_lisa > 70 && !lisaPregnant) {
var btnLisa = new OptionButton();
btnLisa.setText("Lisa ile ilişkiye gir");
btnLisa.x = 2048 - 400;
btnLisa.y = 80;
btnLisa.setCallback(function () {
// %30 hamile kalma şansı
if (Math.random() < 0.3) {
lisaPregnant = true;
showStoryNode(currentNode);
}
});
game.addChild(btnLisa);
game._relOptionBtns.push(btnLisa);
}
// Rebecca
if (rel_rebecca > 70 && !rebeccaPregnant) {
var btnRebecca = new OptionButton();
btnRebecca.setText("Rebecca ile ilişkiye gir");
btnRebecca.x = 2048 - 400;
btnRebecca.y = 220;
btnRebecca.setCallback(function () {
if (Math.random() < 0.3) {
rebeccaPregnant = true;
showStoryNode(currentNode);
}
});
game.addChild(btnRebecca);
game._relOptionBtns.push(btnRebecca);
}
// Giselle
if (giselleUnlocked && !gisellePregnant) {
var btnGiselle = new OptionButton();
btnGiselle.setText("Giselle ile ilişkiye gir");
btnGiselle.x = 2048 - 400;
btnGiselle.y = 360;
btnGiselle.setCallback(function () {
if (Math.random() < 0.3) {
gisellePregnant = true;
showStoryNode(currentNode);
}
});
game.addChild(btnGiselle);
game._relOptionBtns.push(btnGiselle);
}
}
function updateBars() {
if (typeof villaUnlocked !== "undefined" && villaUnlocked && bar_happy < 80) {
bar_happy = 80;
}
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];
var _loop = function _loop() {
names = ['Lisa', 'Rebecca', 'Peter', 'Alex'];
label = characterLabels[i];
prevText = label.text;
newText = names[i] + ': ' + rels[i] + '%'; // Değer değiştiyse animasyon başlat
if (prevText !== newText) {
// Son değeri bul
prevVal = 0;
match = prevText && prevText.match(/: (\-?\d+)%/);
if (match) prevVal = parseInt(match[1]);
newVal = rels[i]; // Pozitif veya negatif değişim: sadece etkilenen karakter titresin
if (newVal > prevVal || newVal < prevVal) {
// Sadece ilişki değeri değişen karakter titresin
portrait = characterPortraits[i];
if (portrait) {
var _doShakeChar = function doShakeChar() {
if (!portrait.parent || shakeCount >= 6) {
// Titreme bitti, orijinal konuma dön
portrait.x = origX;
portrait.y = origY;
return;
}
var dx = (Math.random() - 0.5) * 16;
var dy = (Math.random() - 0.5) * 10;
tween(portrait, {
x: origX + dx,
y: origY + dy
}, {
duration: 50,
easing: tween.linear,
onFinish: function onFinish() {
tween(portrait, {
x: origX,
y: origY
}, {
duration: 50,
easing: tween.linear,
onFinish: function onFinish() {
shakeCount++;
LK.setTimeout(_doShakeChar, 10);
}
});
}
});
};
// Titreme animasyonu uygula
origX = portrait.x;
origY = portrait.y;
shakeCount = 0;
_doShakeChar();
}
}
if (newVal > prevVal) {
if (label.style) label.style.fill = '#00ff00';
tween(label, {
alpha: 0.3
}, {
duration: 120,
easing: tween.linear,
onFinish: function (lbl) {
tween(lbl, {
alpha: 1
}, {
duration: 120,
easing: tween.linear,
onFinish: function (lbl2) {
if (lbl2.style) lbl2.style.fill = '#ffffff';
}.bind(null, label)
});
}.bind(null, label)
});
} else if (newVal < prevVal) {
if (label.style) label.style.fill = '#ff2222';
tween(label, {
alpha: 0.3
}, {
duration: 120,
easing: tween.linear,
onFinish: function (lbl) {
tween(lbl, {
alpha: 1
}, {
duration: 120,
easing: tween.linear,
onFinish: function (lbl2) {
if (lbl2.style) lbl2.style.fill = '#ffffff';
}.bind(null, label)
});
}.bind(null, label)
});
}
}
label.setText(newText);
},
names,
label,
prevText,
newText,
prevVal,
match,
newVal,
portrait,
origX,
origY,
shakeCount;
for (var i = 0; i < characterLabels.length; i++) {
_loop();
}
// --- Ava: Update day, salary, money, baby count UI ---
if (dayText) dayText.setText('Gün: ' + dayCount);
if (salaryText) salaryText.setText('Maaş: $' + mikeSalary);
if (moneyText) moneyText.setText('Para: $' + mikeMoney);
if (babyText) babyText.setText('Bebek: ' + mikeBabyCount);
// Refresh relationship option buttons
if (typeof createUI === "function") {
// Only refresh if UI is visible (avoid infinite loop)
if (game && typeof game._relOptionBtns !== "undefined") {
createUI();
}
}
}
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(storyText, {
alpha: 1
}, {
duration: 1200,
easing: tween.easeOut
});
} 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(storyText, {
alpha: 1
}, {
duration: 1200,
easing: tween.easeOut
});
} 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 villaUnlocked !== "undefined" && villaUnlocked && bar_happy < 80) {
bar_happy = 80;
}
}
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)));
// --- Villa davet event: karakterle ilişkiyi %15 artır (etki zaten effects ile geliyor, ama burada ek bir kontrol de eklenebilir) ---
if (meta && meta.type === "villa_invite" && typeof meta.character === "string") {
if (meta.character === "lisa") rel_lisa = Math.min(100, rel_lisa + 15);
if (meta.character === "rebecca") rel_rebecca = Math.min(100, rel_rebecca + 15);
if (meta.character === "peter") rel_peter = Math.min(100, rel_peter + 15);
if (meta.character === "alex") rel_alex = Math.min(100, rel_alex + 15);
}
// --- Giselle para harcama ve hamilelik ---
if (meta && meta.type === "giselle_spend" && typeof meta.money === "number") {
mikeMoney = Math.max(0, mikeMoney + meta.money);
}
// --- Whiskey para harcama ---
if (meta && meta.type === "whiskey_spend" && typeof meta.money === "number") {
mikeMoney = Math.max(0, mikeMoney + meta.money);
}
if (meta && meta.type === "giselle_baby" && giselleUnlocked && !gisellePregnant) {
if (Math.random() < 0.3) {
gisellePregnant = true;
// Bebek doğumu bir sonraki günlerde gerçekleşecek
}
}
// --- 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++;
// --- Ava: Advance time every 2 turns (1 day = 2 questions) ---
if (turnCount % 2 === 0) {
dayCount++;
// Mike maaş alır
mikeMoney += mikeSalary;
// Alex ile ilişki > 70 ise maaş +50
if (rel_alex > 70) {
mikeSalary += 50;
}
// Alex ile ilişki < 30 ise maaş -20
if (rel_alex < 30) {
mikeSalary = Math.max(0, mikeSalary - 20);
}
// Peter ile ilişki > 70 ise mutluluk +1
if (rel_peter > 70) {
bar_happy = Math.min(100, bar_happy + 1);
}
// Lisa hamile ise doğum (her gün %10 ihtimal)
if (lisaPregnant && Math.random() < 0.1) {
mikeBabyCount++;
lisaPregnant = false;
}
// Rebecca hamile ise doğum (her gün %10 ihtimal)
if (rebeccaPregnant && Math.random() < 0.1) {
mikeBabyCount++;
rebeccaPregnant = false;
}
// Giselle hamile ise doğum (her gün %10 ihtimal)
if (gisellePregnant && Math.random() < 0.1) {
mikeBabyCount++;
gisellePregnant = false;
}
// Save to storage
storage.mikeMoney = mikeMoney;
storage.mikeSalary = mikeSalary;
storage.mikeBabyCount = mikeBabyCount;
storage.dayCount = dayCount;
storage.lisaPregnant = lisaPregnant;
storage.rebeccaPregnant = rebeccaPregnant;
// Update UI
updateBars();
}
// --- 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(storyText, {
alpha: 1
}, {
duration: 1200,
easing: tween.easeOut
});
}
// 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(storyText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
}
}
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(storyText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut
});
}
// Portrait kırmızıya döner, kısa süreliğine
if (portraitNode) {
var oldTint = portraitNode.tint;
portraitNode.tint = 0xd0021b;
tween(portraitNode, {
tint: oldTint
}, {
duration: 1200,
easing: tween.easeOut
});
}
}
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(storyText, {
alpha: 1
}, {
duration: 1500,
easing: tween.easeOut
});
}
if (portraitNode) {
tween(portraitNode, {
alpha: 0.2
}, {
duration: 1500,
easing: tween.easeOut
});
}
}
// 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(portraitNode, {
alpha: 0.3
}, {
duration: 1200,
easing: tween.easeOut
});
// 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(cross1, {
alpha: 0.85
}, {
duration: 400,
easing: tween.easeOut
});
tween(cross2, {
alpha: 0.85
}, {
duration: 400,
easing: tween.easeOut
});
// Fade out after 1.2s
LK.setTimeout(function () {
tween(cross1, {
alpha: 0
}, {
duration: 600,
easing: tween.easeOut
});
tween(cross2, {
alpha: 0
}, {
duration: 600,
easing: tween.easeOut
});
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
};
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