User prompt
madenbtn ye tıklayınca düşen itemlerin düşme oranlarını yarı yarıya azalt ve kazmanın seviyesini yükselttikce düşme oranları artsın
User prompt
kazma ekipmanı kuşanılmış değilse madenBtn ye tıklanmasın
User prompt
kazma ekipmanını satın alınca otomatik kuşanmasın
User prompt
kazma ekipmanını kuşanınca diğer ekipmanlar çıkarılsın kazma ekipmanını çıkartınca diğer ekipmanlar yeniden kuşanılsın kazma ekipmanı kuşanılmış iken başka bir ekipman kuşan dediğimizde de kazma çıkarılsın
User prompt
madenBtn ye elimizde kazma yokken tıklanmasın ve yarı saydam gözüksün ve kazma olmadığı için kazmaya ihtiyacın var diye mesaj çıksın
User prompt
KAZMA BİRAZ DAHA YUKARDA DURSUN VE BOYUTUNU KOMPLE 2 KATINA ÇIKART
User prompt
kazmanın yüksekliğini 3 de 1 rine düşür ve sola çevir
User prompt
kazma da kılıçla aynı yerde gözükecek karakter resminin üzerinde aynı şekilde gözükecek ve boyutunu da aynı yap
User prompt
Please fix the bug: 'Uncaught ReferenceError: equipBtn is not defined' in or related to this line: 'itemBagListUI.addChild(equipBtn);' Line Number: 1968
User prompt
oyuna kazma isminde kuşanılabilen bir ekipman ekle ve demircideki bu pencereden satın alabileyim
User prompt
demirciBtn ye tıklayınca açılan pencerenin altınca ufak bir pencere daha açılsın dar olsun saceve bir satır olacak çünkü orda kazma yazsın yanında fiyatı olan 250 altın yazsın onunda yanında satın al yazsın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
madenBtn ye tıklayınca düşenlerin fiyatı 1000 olan %5 ihtimalle düşsün fiyatı 100 olan %25 ihtimalle düşsün fiyatı 50 olan %50 ihtimalle düşsin fiyatı 5 olan %95 ihtimalle düşsün
User prompt
ENVANTER PENCERESİNDE HANGİ SEKMEDE Bİ ŞEY SATARSAM O SEKME DE KALALIM
User prompt
itemBag a tıklayınca açılan pencerenin sekmelerini biliyorsun eğer ki öğeler sekmesinde ikenBİ ŞEY SATARSAM 3 SANİYE ÖĞELER SEKMESİNDE KALSIN ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
itemBag a tıklayınca açılan pencerenin sekmelerini biliyorsun eğer ki öğeler sekmesinde iken pencereyi kapatırsam yeniden açtığımda öğeler pencereyi açtığımda direk öğeler sekmesine geçsin bunu yap
User prompt
itemBag a tıklayınca açılan pencerenin sekmelerini biliyorsun eğer ki öğeler sekmesinde iken pencereyi kapatırsam yeniden açtığımda öğeler pencereyi açtığımda direk öğeler sekmesine geçsin
User prompt
TAMAM BUNU YAPMADIN AMA YAP
User prompt
ENVANTER PENCERESİNDE HANGİ SEKMEDE EN SON BİR ŞEY SATTIYSAM O SEKMEYİ EN BAŞA AL
User prompt
BİR ÖĞE SATTIKDAN SONRA ÖĞELER SEKMESİNE GEÇ
User prompt
ENVANTER PENCERESİNDE ÖĞELER SEKMESİNDE BİR ŞEY SATTIĞIM DA PENCEREYİ YENİLİYOR VE EKİPMANLAR SEKMESİNE GEÇİYOR , BUNUN OLMASINI İSTEMİYORUM İSTEDİĞİM ÖĞELER SEKMESİNDE BİR ŞEY SATINCA O SEKMEYİ KENDİM SEKMENİN ADINA BASIP DEĞİŞTİRENE KADAR YADA PENCEREYİ KAPATIP YENİDEN AÇANA KADAR ÖĞELER SEKMESİNDE KALSIN
User prompt
envanter penceresinde Bİ ÜRÜN SATINCA BAŞKA SEKMEYE BEN O SEKMENİN ADINA TIKLAMADAN GEÇMESİN
User prompt
envanter penceresinde DİĞER SEKMELERE GEÇEBİLEYİM Bİ ŞEY SATTIKDAN SONRA KENDİSİ GEÇMESSİN BEN TIKLARSAM GEÇSİN
User prompt
diğer sekmelere yada o pencereyi kapatınca bu işlem iptal olsun
User prompt
envanter penceresinde bi ürün satınca sattığım kısmın sekmesinde kalsın
User prompt
ve tıklandığında 90 derece sağa doğru dönsün ve bi pencere açsın pencereyi kapatınca geri 90 derece sola dönüp ilk konumuna gelmiş olacak ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGfx = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.hp = 1; self.x = 600; self.y = 2732 / 2; self.isAlive = true; // Animate enemy in self.spawnAnim = function () { self.scaleX = 0.5; self.scaleY = 0.5; tween(self, { scaleX: 1, scaleY: 1 }, { duration: 180, easing: tween.bounceOut }); }; // Animate enemy defeat self.defeatAnim = function (onFinish) { tween(self, { alpha: 0, scaleX: 1.3, scaleY: 1.3 }, { duration: 180, easing: tween.easeIn, onFinish: onFinish }); }; return self; }); // Enemy2 class (new enemy type after level 10) var Enemy2 = Container.expand(function () { var self = Container.call(this); var enemyGfx = self.attachAsset('enemy2', { anchorX: 0.5, anchorY: 0.5 }); self.hp = 1; self.x = 600; self.y = 2732 / 2; self.isAlive = true; // Animate enemy in self.spawnAnim = function () { self.scaleX = 0.5; self.scaleY = 0.5; tween(self, { scaleX: 1, scaleY: 1 }, { duration: 180, easing: tween.bounceOut }); }; // Animate enemy defeat self.defeatAnim = function (onFinish) { tween(self, { alpha: 0, scaleX: 1.3, scaleY: 1.3 }, { duration: 180, easing: tween.easeIn, onFinish: onFinish }); }; return self; }); // Gold class var Gold = Container.expand(function () { var self = Container.call(this); var goldGfx = self.attachAsset('gold', { anchorX: 0.5, anchorY: 0.5 }); self.x = 600; self.y = 2732 / 2; // Animate gold drop self.dropAnim = function (targetX, targetY, onFinish) { tween(self, { y: targetY }, { duration: 350, easing: tween.bounceOut, onFinish: onFinish }); }; // Animate gold collect self.collectAnim = function (targetX, targetY, onFinish) { tween(self, { x: targetX, y: targetY, scaleX: 0.3, scaleY: 0.3, alpha: 0 }, { duration: 320, easing: tween.cubicIn, onFinish: onFinish }); }; return self; }); // Hero class var Hero = Container.expand(function () { var self = Container.call(this); var heroGfx = self.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); self.level = 1; self.x = 200; self.y = 2732 / 2; // For upgrade animation self.flashUpgrade = function () { tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 120, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeIn }); } }); }; return self; }); // MadenResource class for madenBtn resource spawn/collect logic var MadenResource = Container.expand(function () { var self = Container.call(this); // Resource types and their values var types = [{ id: "hamdemir", value: 5 }, { id: "hamgumus", value: 50 }, { id: "hamaltin", value: 100 }, { id: "hammitril", value: 1000 }]; // Pick type (passed in or random) self.typeIdx = typeof arguments[0] === "number" ? arguments[0] : Math.floor(Math.random() * types.length); self.type = types[self.typeIdx]; // Attach asset var gfx = self.attachAsset(self.type.id, { anchorX: 0.5, anchorY: 0.5 }); // For animation self.scaleX = 0.7; self.scaleY = 0.7; // Animate pop out self.popAnim = function (fromX, fromY, toX, toY, onFinish) { self.x = fromX; self.y = fromY; self.alpha = 0.7; tween(self, { x: toX, y: toY, scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 220, easing: tween.bounceOut, onFinish: onFinish }); }; // Animate collect to itemBag self.collectAnim = function (targetX, targetY, onFinish) { tween(self, { x: targetX, y: targetY, scaleX: 0.3, scaleY: 0.3, alpha: 0 }, { duration: 320, easing: tween.cubicIn, onFinish: onFinish }); }; // Helper: check if point is inside self.containsPoint = function (pt) { var w = gfx.width || 100, h = gfx.height || 100; return pt.x >= self.x - w / 2 && pt.x <= self.x + w / 2 && pt.y >= self.y - h / 2 && pt.y <= self.y + h / 2; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222a36 }); /**** * Game Code ****/ // --- Gold drop amount table per level --- var goldDropByLevel = [ // Level 1 { min: 1, max: 5 }, // Level 2 { min: 3, max: 8 }, // Level 3 { min: 5, max: 12 }, // Level 4 { min: 8, max: 16 }, // Level 5 { min: 12, max: 20 }, // Level 6 { min: 15, max: 25 }, // Level 7 { min: 20, max: 32 }, // Level 8 { min: 25, max: 40 }, // Level 9 { min: 30, max: 48 }, // Level 10 { min: 35, max: 60 }]; // Defensive: If goldDropByLevel is referenced for higher levels, extend with scaled values (function extendGoldDropByLevel() { var last = goldDropByLevel[goldDropByLevel.length - 1]; for (var i = goldDropByLevel.length; i < 100; i++) { // Increase min/max by 10% per level after 10 var prev = goldDropByLevel[i - 1]; goldDropByLevel.push({ min: Math.round(prev.min * 1.1), max: Math.round(prev.max * 1.1) }); } })(); // --- Global State --- // new unique asset for leftBtn // Upgrade Button: orange box // Spawn Enemy Button: green box // Gold: yellow ellipse // Enemy: blue ellipse // Hero: red box, left side // Background images for each location (dummy ids, replace with real asset ids as needed) function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var backgroundImg = null; // Helper to create a scaled background asset (returns a dummy container for now) function getScaledBgAsset(bgId) { // Defensive: If bgId is not a valid asset, return a transparent container var bgAsset; try { bgAsset = LK.getAsset(bgId, { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, width: 2048, height: 2732 }); } catch (e) { bgAsset = new Container(); } return bgAsset; } // --- Set initial background to 'orman' (forest) --- backgroundImg = getScaledBgAsset('bg_orman'); game.addChildAt(backgroundImg, 0); // Add at bottom layer to ensure orman is visible at start // Show spawnBtn only for 'orman' and 'dağ' at game start if (typeof spawnBtn !== "undefined" && spawnBtn) { spawnBtn.visible = true; if (typeof findEnemyTxt !== "undefined" && findEnemyTxt) findEnemyTxt.visible = true; } var hero = new Hero(); game.addChild(hero); var currentEnemy = null; var enemySpawnCount = 0; // Track how many enemies have been spawned var golds = []; var goldAmount = 0; var heroLevel = 1; // --- Inventory and Items --- var inventory = []; // Track equipped item upgrade levels (itemId -> level) var equippedItemUpgradeLevels = {}; var equippedItems = { "shield-1": false, "sword-1": false }; // --- Shield-1 barrier state --- var heroShield1Barrier = 0; // If >0, this is the current shield-1 barrier HP var heroShield1BarrierMax = 0; // Max barrier HP (100 if equipped) // Shield-1 and Sword-1 item data var itemData = { "shield-1": { name: "Shield-1", type: "shield", bonusHp: 250, // +250 extra HP atkSpdPenalty: 2, // -2 attack speed buyPrice: 50, sellPrice: 15 }, "sword-1": { name: "Kılıç-1", type: "sword", bonusAtk: 50, // +50 attack bonusAtkSpd: 1, // +1 attack speed buyPrice: 50, sellPrice: 15 }, "kazma": { name: "Kazma", type: "tool", bonusMine: 1, // future: can be used for mining bonus buyPrice: 250, sellPrice: 75 }, "hamdemir": { name: "Ham Demir", type: "maden", buyPrice: 0, sellPrice: 5 }, "hamgumus": { name: "Ham Gümüş", type: "maden", buyPrice: 0, sellPrice: 50 }, "hamaltin": { name: "Ham Altın", type: "maden", buyPrice: 0, sellPrice: 100 }, "hammitril": { name: "Ham Mitril", type: "maden", buyPrice: 0, sellPrice: 1000 } }; // --- GoldBag effect state --- var heroIsImmortal = false; var heroOneShotEnemies = false; // Auto-fight timer handles var heroAutoAttackTimer = null; var enemyAutoAttackTimer = null; // --- GUI Elements --- // Location display (top center, above upgradeBtn) var locationNames = { "bg_orman": "ORMAN", "bg_sehir": "ŞEHİR", "bg_dag": "DAĞ", "bg_demirci": "DEMİRCİ", "bg_maden": "MADEN", "bg_kale": "KALE", "bg_sahil": "SAHİL" }; var currentLocationId = "bg_orman"; var locationTxt = new Text2(locationNames[currentLocationId], { size: 70, fill: "#fff", glow: { color: 0x2a6bde, distance: 8, strength: 2 } }); locationTxt.anchor.set(0.5, 0); locationTxt.x = LK.gui.top.width / 2; locationTxt.y = 10; LK.gui.top.addChild(locationTxt); // Gold display (top right) var goldTxt = new Text2('0', { size: 70, fill: 0xFFE066, glow: { color: 0xffffff, distance: 10, strength: 2 } }); goldTxt.anchor.set(1, 0); // right, top LK.gui.topRight.addChild(goldTxt); // (moved goldBagImg creation below workBtn definition) // --- Hero and Enemy Stats Display --- // Removed hero and enemy images from the bottom stats area // Hero stats text (bottom left) var heroStatsTxt = new Text2('', { size: 40, fill: "#fff", glow: { color: 0x000000, distance: 12, strength: 4 }, fontWeight: "bold" }); heroStatsTxt.anchor.set(0, 1); heroStatsTxt.x = 30; heroStatsTxt.y = LK.gui.bottom.height - 30; LK.gui.bottomLeft.addChild(heroStatsTxt); // Enemy stats text (bottom right, moved slightly to the right) var enemyStatsTxt = new Text2('', { size: 40, fill: "#fff", glow: { color: 0x000000, distance: 12, strength: 4 }, fontWeight: "bold" }); enemyStatsTxt.anchor.set(1, 1); // Move enemy stats slightly to the right (less offset from right edge) enemyStatsTxt.x = LK.gui.bottomRight.width - 130; enemyStatsTxt.y = LK.gui.bottom.height - 30; LK.gui.bottomRight.addChild(enemyStatsTxt); // Upgrade button (top center) var upgradeBtn = LK.getAsset('upgradeBtn', { anchorX: 0.5, anchorY: 0.5 }); // New button to the left of upgradeBtn, with its own unique visual var leftBtn = LK.getAsset('leftBtn', { anchorX: 0.5, anchorY: 0.5 }); // Ensure leftBtn is added to the GUI (if not already) if (!leftBtn.parent) { LK.gui.top.addChild(leftBtn); } // Add shrink-grow animation to leftBtn when tapped, and show location list leftBtn.down = function (x, y, obj) { tween.stop(leftBtn, { scaleX: true, scaleY: true }); tween(leftBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(leftBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut, onFinish: function onFinish() { // Show location list after animation if (typeof locationListWindow !== "undefined" && locationListWindow && locationListWindow.parent) { locationListWindow.parent.removeChild(locationListWindow); locationListWindow = null; } // Hide leftBtn while window is open leftBtn.visible = false; // Create window container locationListWindow = new Container(); var winWidth = 700; var winHeight = 900; var winColor = 0x000000; var winAlpha = 0.85; var winBg = LK.getAsset('centerCircle', { width: winWidth, height: winHeight, color: winColor, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); winBg.alpha = winAlpha; locationListWindow.addChild(winBg); // Add X close button to top right of window var closeBtnSize = 80; var closeBtn = LK.getAsset('centerCircle', { width: closeBtnSize, height: closeBtnSize, color: 0x222222, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: winWidth / 2 - closeBtnSize / 2 - 18, y: -winHeight / 2 + closeBtnSize / 2 + 18 }); closeBtn.alpha = 0.7; locationListWindow.addChild(closeBtn); var closeBtnTxt = new Text2("X", { size: 48, fill: "#fff" }); closeBtnTxt.anchor.set(0.5, 0.5); closeBtnTxt.x = closeBtn.x; closeBtnTxt.y = closeBtn.y; locationListWindow.addChild(closeBtnTxt); // Close logic for X button closeBtn.down = function () { if (locationListWindow && locationListWindow.parent) { locationListWindow.parent.removeChild(locationListWindow); locationListWindow = null; } // Restore leftBtn leftBtn.visible = true; }; // List of locations var locations = ["1. ORMAN", "2. ŞEHİR", "3. DAĞ", "4. DEMİRCİ", "5. MADEN", "6. KALE", "7. SAHİL"]; var btnHeight = 90; var btnWidth = winWidth - 120; var btnGap = 18; var startY = -winHeight / 2 + 120; for (var i = 0; i < locations.length; i++) { (function (idx) { var btnY = startY + idx * (btnHeight + btnGap); var locBtn = LK.getAsset('centerCircle', { width: btnWidth, height: btnHeight, color: 0x2a6bde, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 0, y: btnY }); locBtn.alpha = 0.92; locationListWindow.addChild(locBtn); var locTxt = new Text2(locations[idx], { size: 44, fill: "#fff" }); locTxt.anchor.set(0.5, 0.5); locTxt.x = locBtn.x; locTxt.y = locBtn.y; locationListWindow.addChild(locTxt); // Optionally: add tap handler for each location locBtn.down = function () { // Animate button for feedback tween.stop(locBtn, { scaleX: true, scaleY: true }); tween(locBtn, { scaleX: 0.93, scaleY: 0.93 }, { duration: 80, easing: tween.cubicIn, onFinish: function onFinish() { tween(locBtn, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); } }); // Handle location selection and change background // Map each location to a unique background asset id var bgMap = ["bg_orman", // 1. ORMAN "bg_sehir", // 2. ŞEHİR "bg_dag", // 3. DAĞ "bg_demirci", // 4. DEMİRCİ "bg_maden", // 5. MADEN "bg_kale", // 6. KALE "bg_sahil" // 7. SAHİL ]; var selectedIdx = idx; var newBgId = bgMap[selectedIdx]; // Update currentLocationId and locationTxt currentLocationId = newBgId; if (locationTxt && locationNames[newBgId]) { locationTxt.setText(locationNames[newBgId]); } // Remove old background image if present if (backgroundImg && backgroundImg.parent) { backgroundImg.parent.removeChild(backgroundImg); backgroundImg.destroy(); } // Create new background image asset, scaled to fit the screen backgroundImg = getScaledBgAsset(newBgId); game.addChildAt(backgroundImg, 0); // Add at bottom layer // Show spawnBtn only for 'orman' and 'dağ', show demirciBtn for 'demirci', hide otherwise if (typeof spawnBtn !== "undefined" && spawnBtn) { if (newBgId === "bg_orman" || newBgId === "bg_dag") { spawnBtn.visible = true; if (typeof findEnemyTxt !== "undefined" && findEnemyTxt) findEnemyTxt.visible = true; if (typeof demirciBtn !== "undefined" && demirciBtn) demirciBtn.visible = false; } else if (newBgId === "bg_demirci") { spawnBtn.visible = false; if (typeof findEnemyTxt !== "undefined" && findEnemyTxt) findEnemyTxt.visible = false; if (typeof demirciBtn === "undefined" || !demirciBtn) { // Create demirciBtn if not already created demirciBtn = LK.getAsset('demirciBtn', { anchorX: 0.5, anchorY: 0.5, x: spawnBtn.x, y: spawnBtn.y }); demirciBtn.down = function (x, y, obj) { // Animate shrink/grow for feedback tween.stop(demirciBtn, { scaleX: true, scaleY: true }); tween(demirciBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(demirciBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut }); } }); // You can add demirci-specific logic here }; LK.gui.bottom.addChild(demirciBtn); } if (typeof demirciBtn !== "undefined" && demirciBtn) demirciBtn.visible = true; } else { spawnBtn.visible = false; if (typeof findEnemyTxt !== "undefined" && findEnemyTxt) findEnemyTxt.visible = false; if (typeof demirciBtn !== "undefined" && demirciBtn) demirciBtn.visible = false; } } // Close the location list window if (locationListWindow && locationListWindow.parent) { locationListWindow.parent.removeChild(locationListWindow); locationListWindow = null; } // Restore leftBtn leftBtn.visible = true; }; })(i); } // Center in game area locationListWindow.x = 2048 / 2; locationListWindow.y = 2732 / 2; game.addChild(locationListWindow); } }); } }); }; // Work button (to the right of upgradeBtn) var workBtn = LK.getAsset('workBtn', { anchorX: 0.5, anchorY: 0.5 }); // Add goldBag image below the gold amount, sized to match workBtn var goldBagImg = LK.getAsset('goldBag', { anchorX: 1, anchorY: 0, x: goldTxt.x + 40, //{1F} // Move 40px more to the right y: goldTxt.y + goldTxt.height + 10, // 10px gap below gold text width: workBtn.width, height: workBtn.height }); LK.gui.topRight.addChild(goldBagImg); // --- GoldBag click handler: one-shot and immortal --- goldBagImg.down = function (x, y, obj) { // Toggle immortal/one-shot state heroIsImmortal = !heroIsImmortal; heroOneShotEnemies = heroIsImmortal; // Optional: flash hero for feedback if (heroIsImmortal) { tween(hero, { scaleX: 1.3, scaleY: 1.3, tint: 0xFFD700 }, { duration: 200, easing: tween.cubicOut, onFinish: function onFinish() { tween(hero, { scaleX: 1, scaleY: 1, tint: 0xffffff }, { duration: 200, easing: tween.cubicIn }); } }); } else { // If disabling, reset hero color/scale tween.stop(hero, { tint: true, scaleX: true, scaleY: true }); hero.tint = 0xffffff; hero.scaleX = 1; hero.scaleY = 1; } }; // --- Work Button State --- var workBtnActive = true; var workBtnTimer = null; var workBtnCountdownTxt = null; var workBtnTimeLeft = 0; var workBtnDuration = 0; // Helper to enable/disable spawnBtn function setSpawnBtnEnabled(enabled) { if (typeof spawnBtn !== "undefined" && spawnBtn) { if (enabled) { spawnBtn.alpha = 1; spawnBtn.interactive = true; spawnBtn.buttonMode = true; } else { spawnBtn.alpha = 0.5; spawnBtn.interactive = false; spawnBtn.buttonMode = false; } } } setSpawnBtnEnabled(true); // Helper to show/hide workBtn countdown text function showWorkBtnCountdown(timeLeft) { if (!workBtnCountdownTxt) { workBtnCountdownTxt = new Text2("", { size: 38, fill: "#fff", glow: { color: 0x000000, distance: 12, strength: 4 }, fontWeight: "bold" }); workBtnCountdownTxt.anchor.set(0.5, 0); workBtnCountdownTxt.x = workBtn.x; workBtnCountdownTxt.y = workBtn.y + workBtn.height / 2 + 8; LK.gui.top.addChild(workBtnCountdownTxt); } workBtnCountdownTxt.visible = true; workBtnCountdownTxt.setText(timeLeft > 0 ? timeLeft.toFixed(1) + "s" : ""); } function hideWorkBtnCountdown() { if (workBtnCountdownTxt) { workBtnCountdownTxt.visible = false; } } // Place upgradeBtn at top center, but not in the top left 100x100 area // Use LK.gui.top (centered horizontally, below top edge) upgradeBtn.x = LK.gui.top.width / 2; upgradeBtn.y = 100 + upgradeBtn.height / 2; // Move leftBtn, upgradeBtn, and workBtn further left as a group, keeping upgradeBtn centered relative to the new group var groupShift = 120; // Amount to shift all three buttons left // Place upgradeBtn at new center upgradeBtn.x = LK.gui.top.width / 2 - groupShift; upgradeBtn.y = 100 + upgradeBtn.height / 2; // Place leftBtn to the left of upgradeBtn, with a small gap leftBtn.x = upgradeBtn.x - upgradeBtn.width / 2 - leftBtn.width / 2 - 30; leftBtn.y = upgradeBtn.y; // Place workBtn to the right of upgradeBtn, with a small gap workBtn.x = upgradeBtn.x + upgradeBtn.width / 2 + workBtn.width / 2 + 30; workBtn.y = upgradeBtn.y; // Add gold required text under the upgrade button var upgradeCostTxt = new Text2("", { size: 40, fill: "#fff", glow: { color: 0x000000, distance: 12, strength: 4 }, fontWeight: "bold" }); upgradeCostTxt.anchor.set(0.5, 0); upgradeCostTxt.x = upgradeBtn.x; upgradeCostTxt.y = upgradeBtn.y + upgradeBtn.height / 2 + 10; LK.gui.top.addChild(upgradeCostTxt); LK.gui.top.addChild(leftBtn); LK.gui.top.addChild(upgradeBtn); LK.gui.top.addChild(workBtn); // Spawn enemy button (bottom center) var spawnBtn = LK.getAsset('spawnBtn', { anchorX: 0.5, anchorY: 0.5 }); // Place spawnBtn at bottom center, above the very bottom edge spawnBtn.x = LK.gui.bottom.width / 2; spawnBtn.y = LK.gui.bottom.height - 100 - spawnBtn.height / 2; // Maden special button (only visible in maden) var madenBtn = LK.getAsset('madenBtn', { anchorX: 0.5, anchorY: 0.5, x: spawnBtn.x, y: spawnBtn.y }); madenBtn.visible = false; // Kale special button (only visible in kale, no function) var kaleBtn = LK.getAsset('kaleBtn', { anchorX: 0.5, anchorY: 0.5, x: spawnBtn.x, y: spawnBtn.y }); kaleBtn.visible = false; // --- KaleBtn tap: rotate 90deg right, open window, rotate back on close --- var kaleWindow = null; kaleBtn.down = function (x, y, obj) { // Animate shrink/grow for feedback tween.stop(kaleBtn, { scaleX: true, scaleY: true }); tween(kaleBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(kaleBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut, onFinish: function onFinish() { // After shrink/grow, rotate 90deg right tween.stop(kaleBtn, { rotation: true }); tween(kaleBtn, { rotation: kaleBtn.rotation + Math.PI / 2 }, { duration: 180, easing: tween.cubicInOut, onFinish: function onFinish() { // Open window after rotation if (kaleWindow && kaleWindow.parent) { kaleWindow.parent.removeChild(kaleWindow); kaleWindow = null; } kaleBtn.visible = false; // Create window container kaleWindow = new Container(); var winWidth = 800; var winHeight = 600; var winColor = 0x222222; var winAlpha = 0.92; var winBg = LK.getAsset('centerCircle', { width: winWidth, height: winHeight, color: winColor, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); winBg.alpha = winAlpha; kaleWindow.addChild(winBg); // Add X close button to top right of window var closeBtnSize = 80; var closeBtn = LK.getAsset('centerCircle', { width: closeBtnSize, height: closeBtnSize, color: 0x444444, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: winWidth / 2 - closeBtnSize / 2 - 18, y: -winHeight / 2 + closeBtnSize / 2 + 18 }); closeBtn.alpha = 0.7; kaleWindow.addChild(closeBtn); var closeBtnTxt = new Text2("X", { size: 48, fill: "#fff" }); closeBtnTxt.anchor.set(0.5, 0.5); closeBtnTxt.x = closeBtn.x; closeBtnTxt.y = closeBtn.y; kaleWindow.addChild(closeBtnTxt); // Close logic for X button closeBtn.down = function () { if (kaleWindow && kaleWindow.parent) { kaleWindow.parent.removeChild(kaleWindow); kaleWindow = null; } // Rotate back 90deg left and show kaleBtn tween.stop(kaleBtn, { rotation: true }); tween(kaleBtn, { rotation: kaleBtn.rotation - Math.PI / 2 }, { duration: 180, easing: tween.cubicInOut, onFinish: function onFinish() { kaleBtn.visible = true; } }); }; // Center window in game area kaleWindow.x = 2048 / 2; kaleWindow.y = 2732 / 2; game.addChild(kaleWindow); } }); } }); } }); }; LK.gui.bottom.addChild(kaleBtn); // --- MadenBtn resource spawn/collect logic --- var madenResourceTypes = [{ id: "hamdemir", value: 5 }, { id: "hamgumus", value: 50 }, { id: "hamaltin", value: 100 }, { id: "hammitril", value: 1000 }]; var madenActiveResource = null; var madenResourceTimeout = null; madenBtn.down = function (x, y, obj) { // Check if kazma is in inventory var hasKazma = false; for (var i = 0; i < inventory.length; i++) { if (inventory[i] === "kazma") { hasKazma = true; break; } } if (!hasKazma) { // Animate button for feedback tween.stop(madenBtn, { scaleX: true, scaleY: true }); tween(madenBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(madenBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut }); } }); // Show message: "Kazmaya ihtiyacın var" if (typeof madenBtnMsg === "undefined" || !madenBtnMsg || madenBtnMsg.destroyed) { madenBtnMsg = new Text2("Kazmaya ihtiyacın var", { size: 60, fill: "#fff", glow: { color: 0x000000, distance: 10, strength: 2 } }); madenBtnMsg.anchor.set(0.5, 0.5); madenBtnMsg.x = 2048 / 2; madenBtnMsg.y = 2732 / 2 + 400; game.addChild(madenBtnMsg); } madenBtnMsg.visible = true; madenBtnMsg.alpha = 1; // Fade out after 1.2s tween(madenBtnMsg, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { if (madenBtnMsg) madenBtnMsg.visible = false; } }); return; } // Animate shrink/grow for feedback tween.stop(madenBtn, { scaleX: true, scaleY: true }); tween(madenBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(madenBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut }); } }); // If resources are already active, ignore further clicks if (madenActiveResource && madenActiveResource.length > 0) return; // --- Custom drop logic: drop up to 4 resources, each with its own probability --- // Probabilities (cumulative for easier logic): // hammitril (1000): 5% // hamaltin (100): 25% // hamgumus (50): 50% // hamdemir (5): 95% // We'll try to drop each, but only if the random roll is within the chance. var centerX = 2048 / 2; var centerY = 2732 / 2; madenActiveResource = []; var madenResourceTimeouts = []; var oldGameDown = game.down; // --- Ava: Reduce drop rates by half, and increase with kazma upgrade level --- // Get kazma upgrade level (0 if not upgraded) var kazmaUpgradeLevel = equippedItemUpgradeLevels && equippedItemUpgradeLevels["kazma"] ? equippedItemUpgradeLevels["kazma"] : 0; // Each upgrade level increases drop rates by 10% of original (not compounded, capped at 100%) var upgradeBonus = kazmaUpgradeLevel * 0.1; // Base drop rates halved var dropTable = [{ typeIdx: 3, chance: Math.min(1, 0.025 + 0.05 * upgradeBonus) // hammitril (1000) }, { typeIdx: 2, chance: Math.min(1, 0.125 + 0.25 * upgradeBonus) // hamaltin (100) }, { typeIdx: 1, chance: Math.min(1, 0.25 + 0.5 * upgradeBonus) // hamgumus (50) }, { typeIdx: 0, chance: Math.min(1, 0.475 + 0.95 * upgradeBonus) // hamdemir (5) } // hamdemir (5) ]; // For each resource type, roll and drop if passed for (var i = 0; i < dropTable.length; i++) { var entry = dropTable[i]; if (Math.random() < entry.chance) { var fromX = centerX; var fromY = centerY; var toX = centerX; var toY = centerY; var resource = new MadenResource(entry.typeIdx); resource.x = fromX; resource.y = fromY; game.addChild(resource); resource.popAnim(fromX, fromY, toX, toY); (function (resource, idx) { var itemBagGlobal = LK.gui.bottom.toGlobal({ x: itemBagImg.x, y: itemBagImg.y }); var itemBagGamePos = game.toLocal(itemBagGlobal); LK.setTimeout(function () { resource.collectAnim(itemBagGamePos.x, itemBagGamePos.y, function () { inventory.push(resource.type.id); resource.destroy(); var idxInArr = madenActiveResource.indexOf(resource); if (idxInArr !== -1) madenActiveResource.splice(idxInArr, 1); if (madenActiveResource.length === 0) { game.down = oldGameDown; } }); }, 250 + Math.floor(Math.random() * 100)); resource._timeoutIdx = idx; madenActiveResource.push(resource); })(resource, i); } } // No tap handler needed, auto-collects }; LK.gui.bottom.addChild(madenBtn); // Demirci button (hidden by default, shown only in demirci) var demirciBtn = LK.getAsset('demirciBtn', { anchorX: 0.5, anchorY: 0.5, x: spawnBtn.x, y: spawnBtn.y }); demirciBtn.visible = false; demirciBtn.down = function (x, y, obj) { // Animate shrink/grow for feedback tween.stop(demirciBtn, { scaleX: true, scaleY: true }); tween(demirciBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(demirciBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut }); } }); // --- Show equipped items window with upgrade buttons --- if (typeof equippedItemsWindow !== "undefined" && equippedItemsWindow && equippedItemsWindow.parent) { equippedItemsWindow.parent.removeChild(equippedItemsWindow); equippedItemsWindow = null; } // Hide demirciBtn while window is open demirciBtn.visible = false; // Create window container equippedItemsWindow = new Container(); var winWidth = 900; var winHeight = 700; var winColor = 0x222222; var winAlpha = 0.92; var winBg = LK.getAsset('centerCircle', { width: winWidth, height: winHeight, color: winColor, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); winBg.alpha = winAlpha; equippedItemsWindow.addChild(winBg); // --- Small single-row window for 'Kazma' under main demirci window --- var kazmaWinWidth = 600; var kazmaWinHeight = 90; var kazmaWinColor = 0x111111; var kazmaWinAlpha = 0.95; var kazmaWinY = winHeight / 2 + kazmaWinHeight / 2 + 18; // just below main window var kazmaWindow = new Container(); var kazmaBg = LK.getAsset('centerCircle', { width: kazmaWinWidth, height: kazmaWinHeight, color: kazmaWinColor, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 0, y: kazmaWinY }); kazmaBg.alpha = kazmaWinAlpha; kazmaWindow.addChild(kazmaBg); // "Kazma" label var kazmaLabel = new Text2("Kazma", { size: 44, fill: "#fff" }); kazmaLabel.anchor.set(0, 0.5); kazmaLabel.x = -kazmaWinWidth / 2 + 30; kazmaLabel.y = kazmaWinY; kazmaWindow.addChild(kazmaLabel); // Price label var kazmaPrice = new Text2("250 altın", { size: 40, fill: 0xFFE066 }); kazmaPrice.anchor.set(0, 0.5); kazmaPrice.x = kazmaLabel.x + 180; kazmaPrice.y = kazmaWinY; kazmaWindow.addChild(kazmaPrice); // "Satın Al" button var satinAlBtnWidth = 180; var satinAlBtnHeight = 70; var satinAlBtn = LK.getAsset('centerCircle', { width: satinAlBtnWidth, height: satinAlBtnHeight, color: 0x2a6bde, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: kazmaWinWidth / 2 - satinAlBtnWidth / 2 - 20, y: kazmaWinY }); satinAlBtn.alpha = 0.92; kazmaWindow.addChild(satinAlBtn); var satinAlTxt = new Text2("Satın Al", { size: 38, fill: "#fff" }); satinAlTxt.anchor.set(0.5, 0.5); satinAlTxt.x = satinAlBtn.x; satinAlTxt.y = satinAlBtn.y; kazmaWindow.addChild(satinAlTxt); // Animate button on tap and handle buy logic for kazma satinAlBtn.down = function () { tween.stop(satinAlBtn, { scaleX: true, scaleY: true }); tween(satinAlBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 80, easing: tween.cubicIn, onFinish: function onFinish() { tween(satinAlBtn, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut, onFinish: function onFinish() { // Buy logic for kazma var kazmaPriceVal = itemData["kazma"] ? itemData["kazma"].buyPrice : 250; // Check if already owned var alreadyOwned = false; for (var i = 0; i < inventory.length; i++) { if (inventory[i] === "kazma") { alreadyOwned = true; break; } } if (alreadyOwned) { // Flash button red if already owned tween(satinAlBtn, { tint: 0xff4444 }, { duration: 120, onFinish: function onFinish() { tween(satinAlBtn, { tint: 0x2a6bde }, { duration: 120 }); } }); return; } if (goldAmount < kazmaPriceVal) { // Flash button red if not enough gold tween(satinAlBtn, { tint: 0xff4444 }, { duration: 120, onFinish: function onFinish() { tween(satinAlBtn, { tint: 0x2a6bde }, { duration: 120 }); } }); return; } // Deduct gold, add kazma to inventory (do NOT auto-equip) goldAmount -= kazmaPriceVal; updateGoldDisplay(); inventory.push("kazma"); // Refresh demirci window to show new inventory state if (equippedItemsWindow && equippedItemsWindow.parent) { equippedItemsWindow.parent.removeChild(equippedItemsWindow); equippedItemsWindow = null; } demirciBtn.down(); } }); } }); }; // Add kazmaWindow to equippedItemsWindow equippedItemsWindow.addChild(kazmaWindow); // Add X close button to bottom center of window var closeBtnSize = 90; var closeBtn = LK.getAsset('centerCircle', { width: closeBtnSize, height: closeBtnSize, color: 0x444444, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 0, y: winHeight / 2 - closeBtnSize / 2 - 20 }); closeBtn.alpha = 0.7; equippedItemsWindow.addChild(closeBtn); var closeBtnTxt = new Text2("X", { size: 60, fill: "#fff" }); closeBtnTxt.anchor.set(0.5, 0.5); closeBtnTxt.x = closeBtn.x; closeBtnTxt.y = closeBtn.y; equippedItemsWindow.addChild(closeBtnTxt); // Close logic for X button closeBtn.down = function () { if (equippedItemsWindow && equippedItemsWindow.parent) { equippedItemsWindow.parent.removeChild(equippedItemsWindow); equippedItemsWindow = null; } // Restore demirciBtn demirciBtn.visible = true; }; // --- List equipped items with upgrade buttons --- var equippedList = []; for (var itemId in equippedItems) { if (equippedItems[itemId]) equippedList.push(itemId); } var itemRowHeight = 180; var itemIconSize = 120; var btnWidth = 220; var btnHeight = 80; var fontSize = 44; var startY = -winHeight / 2 + 120; if (equippedList.length === 0) { var noEqTxt = new Text2("Kuşanılan eşya yok!", { size: 54, fill: "#fff" }); noEqTxt.anchor.set(0.5, 0.5); noEqTxt.x = 0; noEqTxt.y = 0; equippedItemsWindow.addChild(noEqTxt); } else { for (var i = 0; i < equippedList.length; i++) { (function (idx) { var itemId = equippedList[idx]; var data = itemData[itemId]; // Icon var icon = LK.getAsset(itemId, { anchorX: 0.5, anchorY: 0.5, x: -winWidth / 2 + itemIconSize / 2 + 60, y: startY + idx * itemRowHeight + itemIconSize / 2, width: itemIconSize, height: itemIconSize }); equippedItemsWindow.addChild(icon); // Name and stats var labelText = data ? data.name : itemId; var label = new Text2(labelText, { size: fontSize, fill: "#fff" }); label.anchor.set(0, 0.5); label.x = icon.x + itemIconSize / 2 + 30; label.y = icon.y; equippedItemsWindow.addChild(label); // Show upgrade bonus next to item name var upgradeLevel = equippedItemUpgradeLevels[itemId] || 0; var bonusText = ""; if (itemId === "shield-1") { var base = 250; var bonus = Math.round(base * (1 + 0.1 * upgradeLevel)); bonusText = "Bariyer: +" + bonus; } else if (itemId === "sword-1") { var base = itemData["sword-1"].bonusAtk; var bonus = Math.round(base * (1 + 0.1 * upgradeLevel)); bonusText = "Bonus: +" + bonus; } if (bonusText) { var bonusTxt = new Text2(bonusText, { size: 32, fill: 0xFFE066 }); bonusTxt.anchor.set(0, 0.5); bonusTxt.x = label.x; bonusTxt.y = label.y + 44; equippedItemsWindow.addChild(bonusTxt); } // Upgrade button var upgradeBtnEq = LK.getAsset('upgradeBtn', { anchorX: 0.5, anchorY: 0.5, x: label.x + 350, y: icon.y, width: btnWidth, height: btnHeight }); equippedItemsWindow.addChild(upgradeBtnEq); var upgradeTxt = new Text2("Yükselt", { size: fontSize, fill: "#fff" }); upgradeTxt.anchor.set(0.5, 0.5); upgradeTxt.x = upgradeBtnEq.x; upgradeTxt.y = upgradeBtnEq.y; equippedItemsWindow.addChild(upgradeTxt); // Show current upgrade level (if any) if (typeof equippedItemUpgradeLevels === "undefined") window.equippedItemUpgradeLevels = {}; if (typeof equippedItemUpgradeLevels[itemId] === "undefined") equippedItemUpgradeLevels[itemId] = 0; var upgradeLevel = equippedItemUpgradeLevels[itemId]; var levelTxt = new Text2("Seviye: " + (upgradeLevel + 1), { size: 36, fill: 0xFFE066 }); levelTxt.anchor.set(0, 0.5); levelTxt.x = upgradeBtnEq.x + btnWidth / 2 + 30; levelTxt.y = upgradeBtnEq.y; equippedItemsWindow.addChild(levelTxt); // Upgrade logic upgradeBtnEq.down = function () { // Cost: 20 * (upgradeLevel+1) var cost = 20 * (equippedItemUpgradeLevels[itemId] + 1); if (goldAmount < cost) { // Flash gold text red tween(goldTxt, { tint: 0xff4444 }, { duration: 120, onFinish: function onFinish() { tween(goldTxt, { tint: 0xFFE066 }, { duration: 120 }); } }); return; } goldAmount -= cost; equippedItemUpgradeLevels[itemId]++; updateGoldDisplay(); // Optionally: flash upgradeBtnEq tween(upgradeBtnEq, { scaleX: 1.15, scaleY: 1.15 }, { duration: 120, onFinish: function onFinish() { tween(upgradeBtnEq, { scaleX: 1, scaleY: 1 }, { duration: 120 }); } }); // Refresh window to update level text if (equippedItemsWindow && equippedItemsWindow.parent) { equippedItemsWindow.parent.removeChild(equippedItemsWindow); equippedItemsWindow = null; } demirciBtn.down(); }; })(i); } } // Center in game area equippedItemsWindow.x = 2048 / 2; equippedItemsWindow.y = 2732 / 2; game.addChild(equippedItemsWindow); }; LK.gui.bottom.addChild(demirciBtn); // Add "find enemy!" text above the spawn button var findEnemyTxt = new Text2("find enemy!", { size: 45, fill: "#fff", glow: { color: 0x000000, distance: 12, strength: 4 }, fontWeight: "bold" }); findEnemyTxt.anchor.set(0.5, 1); findEnemyTxt.x = spawnBtn.x; findEnemyTxt.y = spawnBtn.y - spawnBtn.height / 2 - 20; LK.gui.bottom.addChild(findEnemyTxt); LK.gui.bottom.addChild(spawnBtn); // Add itemBag image, 10x size, on the left diagonal of spawnBtn so they do not overlap // Set itemBag to width 300px, height 250px, anchor (0.3, 0.20) // Place on the left diagonal of spawnBtn, with a gap so they do not overlap var itemBagWidth = 300; var itemBagHeight = 200; var itemBagAnchorX = 0.3; var itemBagAnchorY = 0.20; var diagonalGap = 40; var diagonalOffset = (spawnBtn.width * (1 - itemBagAnchorX) + itemBagWidth * itemBagAnchorX + diagonalGap) / Math.sqrt(2); var itemBagImg = LK.getAsset('itemBag', { anchorX: itemBagAnchorX, anchorY: itemBagAnchorY, x: spawnBtn.x - diagonalOffset, y: spawnBtn.y - diagonalOffset, width: itemBagWidth, height: itemBagHeight }); LK.gui.bottom.addChild(itemBagImg); // --- Item drop logic on itemBag tap --- itemBagImg.down = function (x, y, obj) { // Animate shrink and grow like other buttons tween.stop(itemBagImg, { scaleX: true, scaleY: true }); tween(itemBagImg, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(itemBagImg, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut, onFinish: function onFinish() { // --- Show 1000x1000 black, 30% transparent window in center --- // Remove previous if exists if (typeof itemBagWindow !== "undefined" && itemBagWindow && itemBagWindow.parent) { itemBagWindow.parent.removeChild(itemBagWindow); itemBagWindow = null; } // Create window container itemBagWindow = new Container(); // Use a box shape for the window background var winWidth = 1000; var winHeight = 1000; var winColor = 0x000000; // black var winAlpha = 0.3; var winBg = LK.getAsset('centerCircle', { width: winWidth, height: winHeight, color: winColor, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); winBg.alpha = winAlpha; itemBagWindow.addChild(winBg); // Add X close button to bottom center of window var closeBtnSize = 90; var closeBtn = LK.getAsset('centerCircle', { width: closeBtnSize, height: closeBtnSize, color: 0x222222, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 0, y: winHeight / 2 - closeBtnSize / 2 - 20 }); closeBtn.alpha = 0.7; itemBagWindow.addChild(closeBtn); // Add X text on top of closeBtn var closeBtnTxt = new Text2("X", { size: 60, fill: "#fff" }); closeBtnTxt.anchor.set(0.5, 0.5); closeBtnTxt.x = closeBtn.x; closeBtnTxt.y = closeBtn.y; itemBagWindow.addChild(closeBtnTxt); // --- Hide spawnBtn, demirciBtn, workBtn, upgradeBtn, leftBtn, and all on-screen texts when X is visible --- spawnBtn.visible = false; if (typeof demirciBtn !== "undefined" && demirciBtn) demirciBtn.visible = false; workBtn.visible = false; upgradeBtn.visible = false; leftBtn.visible = false; findEnemyTxt.visible = false; upgradeCostTxt.visible = false; heroStatsTxt.visible = false; enemyStatsTxt.visible = false; goldTxt.visible = false; goldBagImg.visible = false; if (workBtnCountdownTxt) workBtnCountdownTxt.visible = false; // Close logic for X button closeBtn.down = function () { if (itemBagWindow && itemBagWindow.parent) { itemBagWindow.parent.removeChild(itemBagWindow); itemBagWindow = null; } // Restore all UI elements if (typeof demirciBtn !== "undefined" && demirciBtn && demirciBtn.parent && demirciBtn.visible === false) { // Only show demirciBtn if spawnBtn would be hidden (i.e. in demirci) if (backgroundImg && backgroundImg.assetId === "bg_demirci") { demirciBtn.visible = true; spawnBtn.visible = false; } else { demirciBtn.visible = false; spawnBtn.visible = true; } } else { spawnBtn.visible = true; } workBtn.visible = true; upgradeBtn.visible = true; leftBtn.visible = true; findEnemyTxt.visible = true; upgradeCostTxt.visible = true; heroStatsTxt.visible = true; enemyStatsTxt.visible = true; goldTxt.visible = true; goldBagImg.visible = true; if (workBtnCountdownTxt && workBtnActive === false && workBtnTimeLeft > 0) { workBtnCountdownTxt.visible = true; } }; // Center in game area itemBagWindow.x = 2048 / 2; itemBagWindow.y = 2732 / 2; // Add to game game.addChild(itemBagWindow); // (Removed: close window on tap anywhere on window. Now only X closes the window) // --- Inventory UI inside itemBagWindow --- // Remove any previous inventory UI if (typeof itemBagInventoryUI !== "undefined" && itemBagInventoryUI && itemBagInventoryUI.parent) { itemBagInventoryUI.parent.removeChild(itemBagInventoryUI); itemBagInventoryUI = null; } // --- Tabbed UI for inventory: "Ekipmanlar", "Öğeler", "Kuşandıklarım" --- itemBagInventoryUI = new Container(); var tabBarHeight = 90; var tabBarY = -winHeight / 2 + tabBarHeight / 2 + 10; var tabBarWidth = winWidth - 120; var tabBtnWidth = (tabBarWidth - 20) / 3; var tabBtnHeight = tabBarHeight - 10; var tabFontSize = 38; var tabActiveColor = 0x2a6bde; var tabInactiveColor = 0x444444; var tabTextColor = "#fff"; var tabNames = ["Ekipmanlar", "Öğeler", "Kuşandıklarım"]; var tabSelected = 0; // 0: ekipmanlar, 1: öğeler, 2: kuşandıklarım // Tab buttons var tabBtns = []; for (var t = 0; t < 3; t++) { (function (tabIdx) { var tabBtn = LK.getAsset('centerCircle', { width: tabBtnWidth, height: tabBtnHeight, color: tabIdx === tabSelected ? tabActiveColor : tabInactiveColor, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: -tabBarWidth / 2 + tabBtnWidth / 2 + tabIdx * (tabBtnWidth + 10), y: tabBarY }); tabBtn.alpha = 0.92; itemBagInventoryUI.addChild(tabBtn); var tabTxt = new Text2(tabNames[tabIdx], { size: tabFontSize, fill: tabTextColor }); tabTxt.anchor.set(0.5, 0.5); tabTxt.x = tabBtn.x; tabTxt.y = tabBtn.y; itemBagInventoryUI.addChild(tabTxt); tabBtns.push({ btn: tabBtn, txt: tabTxt }); tabBtn.down = function () { if (tabSelected === tabIdx) return; tabSelected = tabIdx; // Update tab colors for (var k = 0; k < tabBtns.length; k++) { tabBtns[k].btn.color = k === tabSelected ? tabActiveColor : tabInactiveColor; tabBtns[k].btn.alpha = 0.92; tabBtns[k].txt.fill = tabTextColor; } // Remove old list if exists if (typeof itemBagListUI !== "undefined" && itemBagListUI && itemBagListUI.parent) { itemBagListUI.parent.removeChild(itemBagListUI); itemBagListUI = null; } renderItemBagList(); }; })(t); } // --- List UI container (will be replaced on tab switch) --- var itemBagListUI = null; function renderItemBagList() { if (itemBagListUI && itemBagListUI.parent) { itemBagListUI.parent.removeChild(itemBagListUI); itemBagListUI = null; } itemBagListUI = new Container(); var itemListStartY = tabBarY + tabBarHeight / 2 + 20; var itemListStartX = -winWidth / 2 + 60; var itemRowHeight = 140; var itemIconSize = 100; var btnWidth = 160; var btnHeight = 70; var btnGap = 18; var fontSize = 38; // Build a count of each item in inventory, and track equipped index for each type var itemStackMap = {}; // itemId -> array of {idx, equipped} for (var i = 0; i < inventory.length; i++) { var id = inventory[i]; if (!itemStackMap[id]) itemStackMap[id] = []; // If this is equipped and not already marked, mark as equipped var isEquipped = false; if (equippedItems[id]) { // Only one equipped per type, so only one stack can be equipped var alreadyEquipped = false; for (var s = 0; s < itemStackMap[id].length; s++) { if (itemStackMap[id][s].equipped) alreadyEquipped = true; } if (!alreadyEquipped) isEquipped = true; } itemStackMap[id].push({ idx: i, equipped: isEquipped }); } // For each item type, create a stack for equipped and for each group of unequipped var stackRows = []; for (var id in itemStackMap) { var stack = itemStackMap[id]; // Find equipped var equippedIdx = -1; for (var s = 0; s < stack.length; s++) { if (stack[s].equipped) equippedIdx = stack[s].idx; } if (equippedIdx !== -1) { stackRows.push({ itemId: id, count: 1, equipped: true, indices: [equippedIdx] }); } // Now, group unequipped into stacks (could be more than one stack if equipped is in the middle) var unequippedIndices = []; for (var s = 0; s < stack.length; s++) { if (!stack[s].equipped) unequippedIndices.push(stack[s].idx); } if (unequippedIndices.length > 0) { stackRows.push({ itemId: id, count: unequippedIndices.length, equipped: false, indices: unequippedIndices }); } } // Filter stackRows by tab var filteredRows = []; if (tabSelected === 0) { // Ekipmanlar: only equipment (kalkan, kılıç, kazma, etc), regardless of equipped state for (var r = 0; r < stackRows.length; r++) { var id = stackRows[r].itemId; var data = itemData[id]; if (data && (data.type === "shield" || data.type === "sword" || data.type === "tool")) { filteredRows.push(stackRows[r]); } } } else if (tabSelected === 1) { // Öğeler: only non-equipment (ores, etc) for (var r = 0; r < stackRows.length; r++) { var id = stackRows[r].itemId; var data = itemData[id]; if (data && data.type === "maden") { filteredRows.push(stackRows[r]); } } } else if (tabSelected === 2) { // Kuşandıklarım: only equipped items (equipment) for (var r = 0; r < stackRows.length; r++) { var id = stackRows[r].itemId; var data = itemData[id]; if (stackRows[r].equipped && data && (data.type === "shield" || data.type === "sword" || data.type === "tool")) { filteredRows.push(stackRows[r]); } } } if (filteredRows.length === 0) { var noItemTxt = new Text2(tabSelected === 0 ? "Kuşanılan eşya yok!" : "Kuşanılmayan eşya yok!", { size: 48, fill: "#fff" }); noItemTxt.anchor.set(0.5, 0.5); noItemTxt.x = 0; noItemTxt.y = 0; itemBagListUI.addChild(noItemTxt); } else { for (var row = 0; row < filteredRows.length; row++) { (function (rowIdx) { var stack = filteredRows[rowIdx]; var itemId = stack.itemId; var data = itemData[itemId]; var count = stack.count; var isEquipped = stack.equipped; // Icon var icon = LK.getAsset(itemId, { anchorX: 0.5, anchorY: 0.5, x: itemListStartX + itemIconSize / 2, y: itemListStartY + rowIdx * itemRowHeight + itemIconSize / 2, width: itemIconSize, height: itemIconSize }); itemBagListUI.addChild(icon); // Name and stats, show count and equipped var labelText = data ? data.name : itemId; if (count > 1) labelText += " x" + count; if (isEquipped) labelText += " (Kuşanıldı)"; var label = new Text2(labelText, { size: fontSize, fill: "#fff" }); label.anchor.set(0, 0.5); label.x = icon.x + itemIconSize / 2 + 20; label.y = icon.y; itemBagListUI.addChild(label); // Equip/Remove button (only for equipped or first unequipped stack) // Only show for items that are not maden (raw ores) var isMaden = itemId === "hamdemir" || itemId === "hamgumus" || itemId === "hamaltin" || itemId === "hammitril"; var showEquipBtn = !isMaden && (!isEquipped && !equippedItems[itemId] || isEquipped); // Define equipBtn and equipTxt before using them var equipBtn = LK.getAsset('centerCircle', { width: btnWidth, height: btnHeight, color: isEquipped ? 0x8B4513 : 0x2a6bde, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: label.x + btnWidth / 2 + 30, y: icon.y }); equipBtn.alpha = 0.92; itemBagListUI.addChild(equipBtn); var equipTxt = new Text2(isEquipped ? "Çıkart" : "Kuşan", { size: fontSize, fill: "#fff" }); equipTxt.anchor.set(0.5, 0.5); equipTxt.x = equipBtn.x; equipTxt.y = equipBtn.y; itemBagListUI.addChild(equipTxt); equipBtn.visible = showEquipBtn; equipTxt.visible = showEquipBtn; // Equip/Remove logic equipBtn.down = function () { if (isMaden) return; // Do nothing for maden types // --- Ava: Kazma kuşanma/çıkarma ve diğer ekipmanlarla etkileşim --- // Helper: unequip all equipment except the given itemId function unequipAllExcept(itemIdToKeep) { for (var k in equippedItems) { if (k !== itemIdToKeep && equippedItems[k]) { equippedItems[k] = false; if (typeof hero.equippedVisuals !== "undefined" && hero.equippedVisuals[k]) { hero.removeChild(hero.equippedVisuals[k]); hero.equippedVisuals[k].destroy(); hero.equippedVisuals[k] = null; } // Shield-1 barrier reset if shield unequipped if (k === "shield-1") { heroShield1Barrier = 0; heroShield1BarrierMax = 0; } } } } // Helper: re-equip all equipment except kazma function reEquipAllExceptKazma() { for (var k in equippedItems) { if (k !== "kazma" && inventory.indexOf(k) !== -1 && !equippedItems[k]) { equippedItems[k] = true; // Add visual if not present if (typeof hero.equippedVisuals === "undefined") hero.equippedVisuals = {}; if (!hero.equippedVisuals[k]) { var equipVisual; if (k === "shield-1") { equipVisual = LK.getAsset(k, { anchorX: 0.5, anchorY: 0.5, x: 240, y: 0, width: 300, height: 698 }); } else if (k === "sword-1") { equipVisual = LK.getAsset(k, { anchorX: 0.5, anchorY: 0.5, x: -120, y: 320, width: 320, height: 1550 }); equipVisual.rotation = -Math.PI / 3; } else { equipVisual = LK.getAsset(k, { anchorX: 0.5, anchorY: 0.5, x: 90, y: 0, width: 320, height: 320 }); } hero.addChild(equipVisual); hero.equippedVisuals[k] = equipVisual; // Shield-1 barrier logic if (k === "shield-1") { var baseBarrier = 250; var shieldUpgradeLevel = equippedItemUpgradeLevels["shield-1"] || 0; if (shieldUpgradeLevel > 0) { baseBarrier = Math.round(baseBarrier * (1 + 0.1 * shieldUpgradeLevel)); } heroShield1Barrier = baseBarrier; heroShield1BarrierMax = baseBarrier; } } } } } if (!isEquipped) { // --- Equip logic --- // If equipping kazma, unequip all other equipment if (itemId === "kazma") { unequipAllExcept("kazma"); } else { // If kazma is equipped, unequip it before equipping another if (equippedItems["kazma"]) { equippedItems["kazma"] = false; if (typeof hero.equippedVisuals !== "undefined" && hero.equippedVisuals["kazma"]) { hero.removeChild(hero.equippedVisuals["kazma"]); hero.equippedVisuals["kazma"].destroy(); hero.equippedVisuals["kazma"] = null; } } // Unequip all of this type (original logic) for (var k in equippedItems) { if (itemData[k] && itemData[k].type === data.type) { equippedItems[k] = false; if (typeof hero.equippedVisuals !== "undefined" && hero.equippedVisuals[k]) { hero.removeChild(hero.equippedVisuals[k]); hero.equippedVisuals[k].destroy(); hero.equippedVisuals[k] = null; } } } } equippedItems[itemId] = true; // Show item visual on hero (front) if (typeof hero.equippedVisuals === "undefined") hero.equippedVisuals = {}; if (hero.equippedVisuals[itemId]) { hero.removeChild(hero.equippedVisuals[itemId]); hero.equippedVisuals[itemId].destroy(); hero.equippedVisuals[itemId] = null; } var equipVisual; if (itemId === "shield-1") { equipVisual = LK.getAsset(itemId, { anchorX: 0.5, anchorY: 0.5, x: 240, y: 0, width: 300, height: 698 }); } else if (itemId === "sword-1") { equipVisual = LK.getAsset(itemId, { anchorX: 0.5, anchorY: 0.5, x: -120, y: 320, width: 320, height: 1550 }); equipVisual.rotation = -Math.PI / 3; } else if (itemId === "kazma") { try { equipVisual = LK.getAsset('kazma', { anchorX: 0.5, anchorY: 0.5, x: -120, y: 220, width: 640, height: Math.round(1550 / 3 * 2) }); equipVisual.rotation = -Math.PI / 2; } catch (e) { equipVisual = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, x: -120, y: 220, width: 640, height: Math.round(1550 / 3 * 2), color: 0x888888, shape: "box" }); equipVisual.rotation = -Math.PI / 2; } } else { equipVisual = LK.getAsset(itemId, { anchorX: 0.5, anchorY: 0.5, x: 90, y: 0, width: 320, height: 320 }); } hero.addChild(equipVisual); hero.equippedVisuals[itemId] = equipVisual; // Shield-1 barrier logic if (itemId === "shield-1") { var baseBarrier = 250; var shieldUpgradeLevel = equippedItemUpgradeLevels["shield-1"] || 0; if (shieldUpgradeLevel > 0) { baseBarrier = Math.round(baseBarrier * (1 + 0.1 * shieldUpgradeLevel)); } heroShield1Barrier = baseBarrier; heroShield1BarrierMax = baseBarrier; } updateHeroStatsDisplay(); if (itemBagWindow && itemBagWindow.parent) { itemBagWindow.parent.removeChild(itemBagWindow); itemBagWindow = null; } itemBagImg.down(); } else { // --- Remove (Çıkart) logic --- equippedItems[itemId] = false; if (typeof hero.equippedVisuals !== "undefined" && hero.equippedVisuals[itemId]) { hero.removeChild(hero.equippedVisuals[itemId]); hero.equippedVisuals[itemId].destroy(); hero.equippedVisuals[itemId] = null; } if (itemId === "shield-1") { heroShield1Barrier = 0; heroShield1BarrierMax = 0; } // If kazma is being removed, re-equip all other equipment that is in inventory if (itemId === "kazma") { reEquipAllExceptKazma(); } updateHeroStatsDisplay(); if (itemBagWindow && itemBagWindow.parent) { itemBagWindow.parent.removeChild(itemBagWindow); itemBagWindow = null; } itemBagImg.down(); } }; // Sell button var sellBtn = LK.getAsset('centerCircle', { width: btnWidth, height: btnHeight, color: 0x8B4513, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: equipBtn.x + btnWidth + btnGap, y: icon.y }); sellBtn.alpha = 0.85; itemBagListUI.addChild(sellBtn); var sellTxt = new Text2("Sat (" + (data ? data.sellPrice : 1) + ")", { size: fontSize, fill: "#fff" }); sellTxt.anchor.set(0.5, 0.5); sellTxt.x = sellBtn.x; sellTxt.y = sellBtn.y; itemBagListUI.addChild(sellTxt); // Sell logic sellBtn.down = function () { // If this stack is equipped, and only one exists, prevent selling if (isEquipped && count === 1) { tween(sellBtn, { scaleX: 1.15, scaleY: 1.15, tint: 0xff4444 }, { duration: 120, onFinish: function onFinish() { tween(sellBtn, { scaleX: 1, scaleY: 1, tint: 0x8B4513 }, { duration: 120 }); } }); return; } // Remove one from inventory (from this stack) var removedIdx = -1; for (var j = 0; j < stack.indices.length; j++) { var idx = stack.indices[j]; // If equipped, skip if this is the equipped one if (isEquipped && count === 1) continue; removedIdx = idx; break; } if (removedIdx === -1) { // Defensive: fallback to remove first found for (var j = 0; j < inventory.length; j++) { if (inventory[j] === itemId && (!isEquipped || isEquipped && count > 1)) { removedIdx = j; break; } } } if (removedIdx !== -1) { inventory.splice(removedIdx, 1); } // If equipped and now zero remain, unequip var stillHas = false; for (var j = 0; j < inventory.length; j++) { if (inventory[j] === itemId) stillHas = true; } if (isEquipped && !stillHas) { equippedItems[itemId] = false; var stats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = stats.hp; updateHeroStatsDisplay(); } // Add gold goldAmount += data ? data.sellPrice : 1; updateGoldDisplay(); // Animate gold to gold counter var goldDisplayGlobal = LK.gui.topRight.toGlobal({ x: goldTxt.x, y: goldTxt.y }); var goldDisplayGamePos = game.toLocal(goldDisplayGlobal); var goldAnim = LK.getAsset('gold', { anchorX: 0.5, anchorY: 0.5, x: sellBtn.x + itemBagWindow.x, y: sellBtn.y + itemBagWindow.y, width: 80, height: 54 }); game.addChild(goldAnim); tween(goldAnim, { x: goldDisplayGamePos.x, y: goldDisplayGamePos.y, scaleX: 0.3, scaleY: 0.3, alpha: 0 }, { duration: 420, easing: tween.cubicIn, onFinish: function onFinish() { goldAnim.destroy(); } }); // Refresh inventory UI, but keep the same tab if (itemBagWindow && itemBagWindow.parent) { // Instead of closing and reopening, just re-render the list and keep the tab if (typeof itemBagListUI !== "undefined" && itemBagListUI && itemBagListUI.parent) { itemBagListUI.parent.removeChild(itemBagListUI); itemBagListUI = null; } renderItemBagList(); } }; })(row); } } itemBagListUI.x = 0; itemBagListUI.y = 0; itemBagInventoryUI.addChild(itemBagListUI); } // Initial render renderItemBagList(); itemBagInventoryUI.x = 0; itemBagInventoryUI.y = 0; itemBagWindow.addChild(itemBagInventoryUI); // --- (Keep original drop animation for demo) --- var dropX = itemBagImg.x; var dropY = 0 - itemBagHeight; // Start above screen var item = LK.getAsset('gold', { anchorX: 0.5, anchorY: 0.5, x: dropX, y: dropY, width: 150, height: 102 }); game.addChild(item); // Animate drop to itemBag tween(item, { x: itemBagImg.x, y: itemBagImg.y }, { duration: 600, easing: tween.bounceOut, onFinish: function onFinish() { // Optionally: fade out and destroy after reaching itemBag tween(item, { alpha: 0 }, { duration: 250, onFinish: function onFinish() { item.destroy(); } }); } }); } }); } }); }; // --- Helper Functions --- function updateGoldDisplay() { goldTxt.setText(goldAmount); } function updateUpgradeDisplay() { // Show gold required to upgrade under the upgrade button if (typeof upgradeCostTxt !== "undefined") { var nextUpgradeCost = heroLevel * 5; upgradeCostTxt.setText("Gold required: " + nextUpgradeCost); } } // Update hero stats display function updateHeroStatsDisplay() { var stats = getStatsForLevel(heroLevel, "hero"); var hpDisplay = typeof hero.currentHp === "number" ? Math.max(0, Math.round(hero.currentHp)) + " / " + stats.hp : stats.hp; var barrierDisplay = ""; if (equippedItems && equippedItems["shield-1"] && heroShield1Barrier > 0) { barrierDisplay = " +" + heroShield1Barrier; } var atkDisplay = "" + stats.atk; var bonusDisplay = ""; // Will show item upgrade bonuses // Calculate and show shield-1 barrier if equipped if (equippedItems && equippedItems["shield-1"]) { var baseBarrier = 250; var shieldUpgradeLevel = equippedItemUpgradeLevels["shield-1"] || 0; if (shieldUpgradeLevel > 0) { baseBarrier = Math.round(baseBarrier * (1 + 0.1 * shieldUpgradeLevel)); } bonusDisplay += "\nShield-1 Bariyer: +" + baseBarrier; } // Calculate and show sword-1 bonus if equipped if (equippedItems && equippedItems["sword-1"]) { var swordBonus = itemData["sword-1"].bonusAtk; var swordUpgradeLevel = equippedItemUpgradeLevels["sword-1"] || 0; if (swordUpgradeLevel > 0) { swordBonus = Math.round(swordBonus * (1 + 0.1 * swordUpgradeLevel)); } atkDisplay += " +" + swordBonus; bonusDisplay += "\nKılıç-1 Bonus: +" + swordBonus; } heroStatsTxt.setText("Hero\n" + "Level: " + heroLevel + "\n" + "Health: " + hpDisplay + barrierDisplay + "\n" + "Attack: " + atkDisplay + (bonusDisplay ? "\n" + bonusDisplay : "")); } // Update enemy stats display function updateEnemyStatsDisplay() { // DAĞ: multi-enemy stacked stats if (currentLocationId === "bg_dag" && Array.isArray(currentEnemy) && currentEnemy.length > 0) { // Show each enemy's stats, stacked, in order, with level above each enemy var lines = []; for (var i = 0; i < currentEnemy.length; i++) { var e = currentEnemy[i]; if (!e || !e.isAlive) continue; var enemyLevel = e.level || heroLevel; var maxHp = typeof e.maxHp === "number" ? e.maxHp : getStatsForLevel(enemyLevel, "enemy").hp; var hpDisplay = typeof e.hp === "number" ? Math.max(0, Math.round(e.hp)) + " / " + maxHp : maxHp; var atkDisplay = typeof e.attack === "number" ? e.attack : "-"; // Show level above each enemy lines.push("Seviye: " + enemyLevel); lines.push(i + 1 + "- " + hpDisplay + " HP " + atkDisplay + " ATK"); } if (lines.length > 0) { enemyStatsTxt.setText(lines.join("\n")); } else { enemyStatsTxt.setText("Enemy\n-"); } } else if (currentEnemy && currentEnemy.isAlive) { var enemyLevel = currentEnemy.level || heroLevel; // Use enemy.maxHp if available, otherwise fallback to stats.hp var maxHp = typeof currentEnemy.maxHp === "number" ? currentEnemy.maxHp : getStatsForLevel(enemyLevel, "enemy").hp; var hpDisplay = typeof currentEnemy.hp === "number" ? Math.max(0, Math.round(currentEnemy.hp)) + " / " + maxHp : maxHp; enemyStatsTxt.setText("Enemy\n" + "Level: " + enemyLevel + "\n" + "Health: " + hpDisplay + "\n" + "Attack: " + currentEnemy.attack); } else { enemyStatsTxt.setText("Enemy\n-"); } } // --- Game Logic --- // Spawn enemy logic // Enemy stat table for levels 1-10 (fixed stats) var enemyStatsByLevel = [ // Level 1 { hp: 60, atk: 10 }, // Level 2 { hp: 95, atk: 14 }, // Level 3 { hp: 130, atk: 18 }, // Level 4 { hp: 170, atk: 23 }, // Level 5 { hp: 215, atk: 27 }, // Level 6 { hp: 265, atk: 32 }, // Level 7 { hp: 320, atk: 38 }, // Level 8 { hp: 380, atk: 45 }, // Level 9 { hp: 445, atk: 53 }, // Level 10 { hp: 515, atk: 62 }]; // --- Stat scaling logic for hero and enemy after level 10 --- // Store hero stat growth per level (compounded) and enemy stat growth per level (linear from level 10 base) var heroStatGrowth = { hp: [enemyStatsByLevel[9].hp], atk: [enemyStatsByLevel[9].atk] }; var enemyStatGrowth = { hp: [enemyStatsByLevel[9].hp], atk: [enemyStatsByLevel[9].atk] }; // Store enemy stat percent increases per level (for linear scaling) var enemyStatPercents = { hp: [], atk: [] }; // Store hero stat percent increases per level (for compounded scaling) var heroStatPercents = { hp: [], atk: [] }; // Helper to get random percent between 5% and 20% function randomPercent() { return 0.05 + Math.random() * 0.15; } // Precompute stat growth up to a reasonable max level (e.g. 100) function ensureStatGrowthUpTo(level) { var maxComputed = heroStatGrowth.hp.length + 9; // since index 0 is level 10 for (var lvl = maxComputed + 1; lvl <= level; lvl++) { // HERO: compounded var prevHeroHp = heroStatGrowth.hp[heroStatGrowth.hp.length - 1]; var prevHeroAtk = heroStatGrowth.atk[heroStatGrowth.atk.length - 1]; var heroHpPct = randomPercent(); var heroAtkPct = randomPercent(); heroStatPercents.hp.push(heroHpPct); heroStatPercents.atk.push(heroAtkPct); heroStatGrowth.hp.push(Math.round(prevHeroHp * (1 + heroHpPct))); heroStatGrowth.atk.push(Math.round(prevHeroAtk * (1 + heroAtkPct))); // ENEMY: linear from level 10 base var baseHp = enemyStatsByLevel[9].hp; var baseAtk = enemyStatsByLevel[9].atk; var enemyHpPct = randomPercent(); var enemyAtkPct = randomPercent(); enemyStatPercents.hp.push(enemyHpPct); enemyStatPercents.atk.push(enemyAtkPct); // For linear, sum all previous percent increases var totalHpPct = 0; var totalAtkPct = 0; for (var i = 0; i < enemyStatPercents.hp.length; i++) totalHpPct += enemyStatPercents.hp[i]; for (var i = 0; i < enemyStatPercents.atk.length; i++) totalAtkPct += enemyStatPercents.atk[i]; // After level 20, enemy health increases by an additional 50% per level var extraHpMultiplier = 1; if (lvl > 20) { // For each level above 20, multiply by 1.5 for each extra level extraHpMultiplier = Math.pow(1.5, lvl - 20); } enemyStatGrowth.hp.push(Math.round(baseHp * (1 + totalHpPct) * extraHpMultiplier)); enemyStatGrowth.atk.push(Math.round(baseAtk * (1 + totalAtkPct))); } } // Returns stats for a given level and type ('hero' or 'enemy') function getStatsForLevel(level, type) { if (level <= 10) { var idx = Math.max(0, Math.min(enemyStatsByLevel.length - 1, level - 1)); var stats = enemyStatsByLevel[idx]; // Always include equipment HP calculation for hero if (type === "hero") { var baseHp = Math.round(stats.hp * 1.5); // At level 1, make sure hero attack is enough to defeat enemy 1 var baseAtk; if (level === 1) { // Enemy 1 HP: 60, Enemy 1 Atk: 10 // Give hero enough attack to defeat enemy in 6 hits (10 damage per hit) baseAtk = 10; } else { baseAtk = Math.round(stats.atk * 0.6); } // --- Increase stats by 15% for each equipped item --- var equippedCount = 0; if (equippedItems) { for (var k in equippedItems) { if (equippedItems[k]) equippedCount++; } } if (equippedCount > 0) { var multiplier = 1 + 0.15 * equippedCount; baseHp = Math.round(baseHp * multiplier); baseAtk = Math.round(baseAtk * multiplier); } // Apply shield-1 effects if equipped // No longer add shieldBonus to baseHp; shield-1 only gives barrier, not HP bonus // Apply sword-1 effects if equipped if (equippedItems && equippedItems["sword-1"]) { var swordBonus = itemData["sword-1"].bonusAtk; var swordUpgradeLevel = equippedItemUpgradeLevels["sword-1"] || 0; if (swordUpgradeLevel > 0) { swordBonus = Math.round(swordBonus * (1 + 0.1 * swordUpgradeLevel)); } baseAtk += swordBonus; } return { hp: baseHp, atk: baseAtk }; } else { return { hp: Math.round(stats.hp * 1.5), // %50 daha fazla can atk: Math.round(stats.atk * 0.6) // %40 daha az atak }; } } ensureStatGrowthUpTo(level); var idx = level - 10; if (type === "hero") { // Base stats var baseHp = heroStatGrowth.hp[idx]; var baseAtk = heroStatGrowth.atk[idx]; // --- Increase stats by 15% for each equipped item --- var equippedCount = 0; if (equippedItems) { for (var k in equippedItems) { if (equippedItems[k]) equippedCount++; } } if (equippedCount > 0) { var multiplier = 1 + 0.15 * equippedCount; baseHp = Math.round(baseHp * multiplier); baseAtk = Math.round(baseAtk * multiplier); } // Apply shield-1 effects if equipped // No longer add shieldBonus to baseHp; shield-1 only gives barrier, not HP bonus // Apply sword-1 effects if equipped if (equippedItems && equippedItems["sword-1"]) { var swordBonus = itemData["sword-1"].bonusAtk; var swordUpgradeLevel = equippedItemUpgradeLevels["sword-1"] || 0; if (swordUpgradeLevel > 0) { swordBonus = Math.round(swordBonus * (1 + 0.1 * swordUpgradeLevel)); } baseAtk += swordBonus; } return { hp: baseHp, atk: baseAtk }; } else { return { hp: Math.round(enemyStatGrowth.hp[idx] * 1.5), // %50 daha fazla can atk: Math.round(enemyStatGrowth.atk[idx] * 0.6) // %40 daha az atak }; } } // For backward compatibility, keep getEnemyStatsForLevel for hero stats (used in refill, etc) function getEnemyStatsForLevel(level) { return getStatsForLevel(level, "hero"); } function spawnEnemy() { // --- DAĞ: spawn 1-4 random enemies (from 1-20) side by side --- if (currentLocationId === "bg_dag") { // Remove any previous enemies if (Array.isArray(currentEnemy)) { for (var i = 0; i < currentEnemy.length; i++) { if (currentEnemy[i] && currentEnemy[i].parent) { currentEnemy[i].destroy(); } } } else if (currentEnemy && currentEnemy.isAlive && currentEnemy.parent) { currentEnemy.destroy(); } currentEnemy = null; // How many enemies? 1-4 random var enemyCount = Math.floor(Math.random() * 4) + 1; // Pick unique random levels for each enemy (from 1-20) var possibleLevels = []; for (var i = 1; i <= 20; i++) possibleLevels.push(i); // Shuffle for (var i = possibleLevels.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = possibleLevels[i]; possibleLevels[i] = possibleLevels[j]; possibleLevels[j] = temp; } var enemyLevels = possibleLevels.slice(0, enemyCount); // Calculate spacing and position so that all enemies are on the right half, never crossing center, and always visible var enemyWidth = 400; // estimate for safety, actual asset is 1280px but scaled down var rightHalfStart = 2048 / 2; var rightHalfEnd = 2048 - 100; // leave 100px margin on right var availableWidth = rightHalfEnd - rightHalfStart; var spacing = 0; if (enemyCount > 1) { spacing = Math.min(340, (availableWidth - enemyWidth) / (enemyCount - 1)); } else { spacing = 0; } var totalWidth = (enemyCount - 1) * spacing; var startX = rightHalfStart + (availableWidth - totalWidth - enemyWidth) / 2 + enemyWidth / 2; if (startX < rightHalfStart + enemyWidth / 2) startX = rightHalfStart + enemyWidth / 2; if (startX + totalWidth > rightHalfEnd - enemyWidth / 2) startX = rightHalfEnd - totalWidth - enemyWidth / 2; currentEnemy = []; for (var idx = 0; idx < enemyCount; idx++) { var level = enemyLevels[idx]; var isEnemy2 = false; var enemy; if (level > 10) { if (Math.random() < 0.5) { enemy = new Enemy2(); isEnemy2 = true; } else { enemy = new Enemy(); } } else { enemy = new Enemy(); } // Place enemies side by side, vertically aligned with hero enemy.x = startX + idx * spacing; enemy.y = hero.y + 100; // Get stats for this level var stats = getStatsForLevel(level, "enemy"); // Randomize stats ±30% var statRand = Math.random(); var hpMod = 1, atkMod = 1; if (statRand < 0.3) { hpMod = 0.7; atkMod = 0.7; } else if (statRand < 0.6) { hpMod = 1.3; atkMod = 1.3; } enemy.maxHp = Math.round(stats.hp * hpMod); if (isEnemy2) { enemy.hp = Math.round(stats.hp * 0.8 * hpMod); enemy.attack = Math.round(stats.atk * 1.3 * atkMod); } else { enemy.hp = Math.round(stats.hp * hpMod); enemy.attack = Math.round(stats.atk * atkMod); } enemy.isAlive = true; enemy.spawnAnim(); game.addChild(enemy); enemy.level = level; enemy.isEnemy2 = isEnemy2; enemy.isBoss = false; // Attach tap handler for each enemy (function (enemyObj) { enemyObj.down = function (x, y, obj) { if (!enemyObj.isAlive) return; enemyObj.hp -= 1; if (enemyObj.hp < 0) enemyObj.hp = 0; // Flash enemy tween(enemyObj, { tint: 0xffffff }, { duration: 60, onFinish: function onFinish() { tween(enemyObj, { tint: 0x2a6bde }, { duration: 60 }); } }); if (enemyObj.hp <= 0) { enemyObj.isAlive = false; enemyObj.defeatAnim(function () { enemyObj.destroy(); // Remove from currentEnemy array for (var i = 0; i < currentEnemy.length; i++) { if (currentEnemy[i] === enemyObj) { currentEnemy.splice(i, 1); break; } } // Drop gold and items // Gold drop logic (use same as defeatEnemy, but per enemy) // --- DAĞ: Make gold drop proportional to number of enemies defeated --- var goldDropByLevelIdx = Math.max(0, Math.min(level - 1, goldDropByLevel.length - 1)); var goldDropStats = goldDropByLevel[goldDropByLevelIdx]; var goldDropAmount = Math.floor(Math.random() * (goldDropStats.max - goldDropStats.min + 1)) + goldDropStats.min; // If DAĞ and multi-enemy, multiply by total number of enemies spawned in this wave if (currentLocationId === "bg_dag" && Array.isArray(currentEnemy)) { // enemyCount is the number of enemies spawned in this wave // We need to find the total number of enemies that were spawned for this wave. // Since currentEnemy is being spliced, we can track the original count. // Let's use a property on the array to store the original count if not already set. if (typeof currentEnemy._originalCount === "undefined") { // Set on first defeat currentEnemy._originalCount = currentEnemy.length + 1; } goldDropAmount = goldDropAmount * currentEnemy._originalCount; } // Drop gold at enemy position var goldDisplayGlobal = LK.gui.topRight.toGlobal({ x: goldTxt.x, y: goldTxt.y }); var goldDisplayGamePos = game.toLocal(goldDisplayGlobal); for (var g = 0; g < goldDropAmount; g++) { var gold = new Gold(); gold.x = enemyObj.x; gold.y = enemyObj.y; gold.scaleX = 1; gold.scaleY = 1; gold.alpha = 1; game.addChild(gold); golds.push(gold); var dropY = gold.y + (Math.random() * 120 - 60); (function (goldObj, idx) { goldObj.dropAnim(goldObj.x, dropY, function () { LK.setTimeout(function () { goldObj.collectAnim(goldDisplayGamePos.x, goldDisplayGamePos.y, function () { goldAmount += 1; updateGoldDisplay(); goldObj.destroy(); }); }, 80 * idx); }); })(gold, g); } // Shield-1 drop logic (5% per level, capped at 50% for level 10) if (level >= 1 && level <= 10 && !enemyObj.isEnemy2) { var shieldDropChance = level * 0.05; if (Math.random() < shieldDropChance) { var shieldAsset = LK.getAsset('shield-1', { anchorX: 0.5, anchorY: 0.5, x: enemyObj.x, y: enemyObj.y }); game.addChild(shieldAsset); var itemBagGlobal = LK.gui.bottom.toGlobal({ x: itemBagImg.x, y: itemBagImg.y }); var itemBagGamePos = game.toLocal(itemBagGlobal); tween(shieldAsset, { x: itemBagGamePos.x, y: itemBagGamePos.y, scaleX: 0.3, scaleY: 0.3, alpha: 0.2 }, { duration: 700, easing: tween.cubicIn, onFinish: function onFinish() { shieldAsset.destroy(); inventory.push("shield-1"); } }); } } // Sword-1 drop logic (Enemy2, level 10/20 always, else 15%) if (enemyObj.isEnemy2) { var swordDrop = false; if (level === 10 || level === 20) { swordDrop = true; } else if (Math.random() < 0.15) { swordDrop = true; } if (swordDrop) { var swordAsset = LK.getAsset('sword-1', { anchorX: 0.5, anchorY: 0.5, x: enemyObj.x, y: enemyObj.y }); game.addChild(swordAsset); var itemBagGlobalSword = LK.gui.bottom.toGlobal({ x: itemBagImg.x, y: itemBagImg.y }); var itemBagGamePosSword = game.toLocal(itemBagGlobalSword); tween(swordAsset, { x: itemBagGamePosSword.x, y: itemBagGamePosSword.y, scaleX: 0.3, scaleY: 0.3, alpha: 0.2 }, { duration: 700, easing: tween.cubicIn, onFinish: function onFinish() { swordAsset.destroy(); inventory.push("sword-1"); } }); } } }); } }; })(enemy); currentEnemy.push(enemy); } // DAĞ: auto-fight all enemies in array if (currentLocationId === "bg_dag" && Array.isArray(currentEnemy) && currentEnemy.length > 0) { // Defensive: clear any previous timers if (typeof heroAutoAttackTimer !== "undefined" && heroAutoAttackTimer) { LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; } if (typeof enemyAutoAttackTimer !== "undefined" && enemyAutoAttackTimer) { LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; } // Get hero stats for this level var heroStats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = heroStats.hp; hero.attack = heroStats.atk; if (equippedItems && equippedItems["sword-1"]) { hero.attack += itemData["sword-1"].bonusAtk; } // Hero attacks all alive enemies in array, one per second heroAutoAttackTimer = LK.setInterval(function () { // Defensive: skip if no enemies left if (!Array.isArray(currentEnemy) || currentEnemy.length === 0) { LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; if (typeof enemyAutoAttackTimer !== "undefined" && enemyAutoAttackTimer) { LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; } return; } // Animate hero and equipped items: move slightly right and return var heroAttackMoveX = 32; tween.stop(hero, { x: true }); tween(hero, { x: hero.x + heroAttackMoveX }, { duration: 60, easing: tween.cubicOut, onFinish: function onFinish() { tween(hero, { x: hero.x - heroAttackMoveX }, { duration: 80, easing: tween.cubicIn }); } }); // Animate equipped visuals if any if (_typeof(hero.equippedVisuals) === "object" && hero.equippedVisuals) { for (var k in hero.equippedVisuals) { if (hero.equippedVisuals[k]) { tween.stop(hero.equippedVisuals[k], { x: true }); var eq = hero.equippedVisuals[k]; var origX = typeof eq._origX === "number" ? eq._origX : eq.x; eq._origX = origX; tween(eq, { x: origX + heroAttackMoveX }, { duration: 60, easing: tween.cubicOut, onFinish: function (eq, origX) { return function () { tween(eq, { x: origX }, { duration: 80, easing: tween.cubicIn }); }; }(eq, origX) }); } } } // Attack all alive enemies for (var i = 0; i < currentEnemy.length; i++) { var e = currentEnemy[i]; if (!e || !e.isAlive) continue; // If one-shot mode, instantly defeat if (heroOneShotEnemies) { e.hp = 0; } else { e.hp -= hero.attack; if (e.hp < 0) e.hp = 0; } // Flash enemy tween(e, { tint: 0xffffff }, { duration: 60, onFinish: function (e) { return function () { tween(e, { tint: 0x2a6bde }, { duration: 60 }); }; }(e) }); // If enemy defeated, trigger its defeatAnim and remove from array if (e.hp <= 0 && e.isAlive) { e.isAlive = false; (function (enemyObj) { enemyObj.defeatAnim(function () { if (!Array.isArray(currentEnemy)) return; // Remove from currentEnemy array for (var j = 0; j < currentEnemy.length; j++) { if (currentEnemy[j] === enemyObj) { currentEnemy.splice(j, 1); break; } } // Drop gold and items (same as tap logic) var level = enemyObj.level || heroLevel; var goldDropByLevelIdx = Math.max(0, Math.min(level - 1, goldDropByLevel.length - 1)); var goldDropStats = goldDropByLevel[goldDropByLevelIdx]; var goldDropAmount = Math.floor(Math.random() * (goldDropStats.max - goldDropStats.min + 1)) + goldDropStats.min; // If DAĞ and multi-enemy, multiply by total number of enemies spawned in this wave if (currentLocationId === "bg_dag" && Array.isArray(currentEnemy)) { if (typeof currentEnemy._originalCount === "undefined") { // Set on first defeat currentEnemy._originalCount = currentEnemy.length + 1; } goldDropAmount = goldDropAmount * currentEnemy._originalCount; } var goldDisplayGlobal = LK.gui.topRight.toGlobal({ x: goldTxt.x, y: goldTxt.y }); var goldDisplayGamePos = game.toLocal(goldDisplayGlobal); for (var g = 0; g < goldDropAmount; g++) { var gold = new Gold(); gold.x = enemyObj.x; gold.y = enemyObj.y; gold.scaleX = 1; gold.scaleY = 1; gold.alpha = 1; game.addChild(gold); golds.push(gold); var dropY = gold.y + (Math.random() * 120 - 60); (function (goldObj, idx) { goldObj.dropAnim(goldObj.x, dropY, function () { LK.setTimeout(function () { goldObj.collectAnim(goldDisplayGamePos.x, goldDisplayGamePos.y, function () { goldAmount += 1; updateGoldDisplay(); goldObj.destroy(); }); }, 80 * idx); }); })(gold, g); } // Shield-1 drop logic (5% per level, capped at 50% for level 10) if (level >= 1 && level <= 10 && !enemyObj.isEnemy2) { var shieldDropChance = level * 0.05; if (Math.random() < shieldDropChance) { var shieldAsset = LK.getAsset('shield-1', { anchorX: 0.5, anchorY: 0.5, x: enemyObj.x, y: enemyObj.y }); game.addChild(shieldAsset); var itemBagGlobal = LK.gui.bottom.toGlobal({ x: itemBagImg.x, y: itemBagImg.y }); var itemBagGamePos = game.toLocal(itemBagGlobal); tween(shieldAsset, { x: itemBagGamePos.x, y: itemBagGamePos.y, scaleX: 0.3, scaleY: 0.3, alpha: 0.2 }, { duration: 700, easing: tween.cubicIn, onFinish: function onFinish() { shieldAsset.destroy(); inventory.push("shield-1"); } }); } } // Sword-1 drop logic (Enemy2, level 10/20 always, else 15%) if (enemyObj.isEnemy2) { var swordDrop = false; if (level === 10 || level === 20) { swordDrop = true; } else if (Math.random() < 0.15) { swordDrop = true; } if (swordDrop) { var swordAsset = LK.getAsset('sword-1', { anchorX: 0.5, anchorY: 0.5, x: enemyObj.x, y: enemyObj.y }); game.addChild(swordAsset); var itemBagGlobalSword = LK.gui.bottom.toGlobal({ x: itemBagImg.x, y: itemBagImg.y }); var itemBagGamePosSword = game.toLocal(itemBagGlobalSword); tween(swordAsset, { x: itemBagGamePosSword.x, y: itemBagGamePosSword.y, scaleX: 0.3, scaleY: 0.3, alpha: 0.2 }, { duration: 700, easing: tween.cubicIn, onFinish: function onFinish() { swordAsset.destroy(); inventory.push("sword-1"); } }); } } enemyObj.destroy(); updateEnemyStatsDisplay(); }); })(e); } } updateEnemyStatsDisplay(); // If all enemies are defeated, stop timer if (!Array.isArray(currentEnemy) || currentEnemy.length === 0) { LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; if (typeof enemyAutoAttackTimer !== "undefined" && enemyAutoAttackTimer) { LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; } } }, 1000); // All enemies attack hero, one per second enemyAutoAttackTimer = LK.setInterval(function () { if (!Array.isArray(currentEnemy) || currentEnemy.length === 0) { LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; if (typeof heroAutoAttackTimer !== "undefined" && heroAutoAttackTimer) { LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; } return; } if (typeof hero.currentHp !== "number") { var hStats = getEnemyStatsForLevel(heroLevel); hero.currentHp = hStats.hp; } if (!heroIsImmortal) { // Sum all alive enemy attacks var totalDmg = 0; for (var i = 0; i < currentEnemy.length; i++) { var e = currentEnemy[i]; if (e && e.isAlive && typeof e.attack === "number") { totalDmg += e.attack; } } // --- Shield-1 barrier logic: block damage with barrier first --- if (equippedItems && equippedItems["shield-1"] && heroShield1Barrier > 0) { var dmg = totalDmg; if (heroShield1Barrier >= dmg) { heroShield1Barrier -= dmg; dmg = 0; } else { dmg -= heroShield1Barrier; heroShield1Barrier = 0; } if (dmg > 0) { hero.currentHp -= dmg; } } else { hero.currentHp -= totalDmg; } // Flash hero tween(hero, { tint: 0xffffff }, { duration: 60, onFinish: function onFinish() { tween(hero, { tint: 0xd83318 }, { duration: 60 }); } }); updateHeroStatsDisplay(); if (hero.currentHp <= 0) { // Hero defeated, stop fighting hero.currentHp = 0; updateHeroStatsDisplay(); LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; // Start health refill (handled in update loop) hero.healthRefilling = false; // Will be set to true in update loop } } else { // If immortal, keep HP at max and flash gold var stats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = stats.hp; updateHeroStatsDisplay(); tween(hero, { tint: 0xFFD700 }, { duration: 60, onFinish: function onFinish() { tween(hero, { tint: 0xffffff }, { duration: 60 }); } }); } }, 1000); updateEnemyStatsDisplay(); return; } updateEnemyStatsDisplay(); return; } // --- DEFAULT: single enemy logic (as before) --- if (currentEnemy && currentEnemy.isAlive) return; // Only one at a time if (hero.healthRefilling) return; // Don't allow spawn while refilling var enemy; var isEnemy2 = false; // --- BOSS LOGIC --- // Increment enemy spawn count enemySpawnCount = (typeof enemySpawnCount === "number" ? enemySpawnCount : 0) + 1; var isBoss = enemySpawnCount % 8 === 0; // Determine enemy level: always one of heroLevel-1, heroLevel, heroLevel+1, or heroLevel+2 var possibleLevels = [Math.max(1, heroLevel - 1), heroLevel, heroLevel + 1, heroLevel + 2]; // Remove duplicates and clamp to at least 1 var uniqueLevels = []; for (var i = 0; i < possibleLevels.length; i++) { var lvl = Math.max(1, possibleLevels[i]); if (uniqueLevels.indexOf(lvl) === -1) uniqueLevels.push(lvl); } // Orman seçeneğinde benden yüksek seviyede düşman gelme ihtimali %5 olsun var enemyLevel; if (currentLocationId === "bg_orman") { // %5 ihtimalle heroLevel+1 veya heroLevel+2, %95 ihtimalle heroLevel veya heroLevel-1 if (Math.random() < 0.05) { // Yüksek seviye: heroLevel+1 veya heroLevel+2 var highLevels = []; for (var i = 0; i < uniqueLevels.length; i++) { if (uniqueLevels[i] > heroLevel) highLevels.push(uniqueLevels[i]); } if (highLevels.length > 0) { enemyLevel = highLevels[Math.floor(Math.random() * highLevels.length)]; } else { enemyLevel = heroLevel; } } else { // Düşük/aynı seviye: heroLevel veya heroLevel-1 var lowLevels = []; for (var i = 0; i < uniqueLevels.length; i++) { if (uniqueLevels[i] <= heroLevel) lowLevels.push(uniqueLevels[i]); } if (lowLevels.length > 0) { enemyLevel = lowLevels[Math.floor(Math.random() * lowLevels.length)]; } else { enemyLevel = heroLevel; } } } else { // Diğer lokasyonlar: eski random seçimi enemyLevel = uniqueLevels[Math.floor(Math.random() * uniqueLevels.length)]; } // Clamp enemyLevel to valid range for stats table enemyLevel = Math.max(1, Math.min(enemyStatsByLevel.length + heroStatGrowth.hp.length, enemyLevel)); // Decide which enemy type to spawn if (enemyLevel > 10) { // After level 10, 50% chance for Enemy2, 50% for Enemy if (Math.random() < 0.5) { enemy = new Enemy2(); isEnemy2 = true; } else { enemy = new Enemy(); } } else { enemy = new Enemy(); } // Place enemy on the far right, vertically aligned with hero if (isEnemy2) { enemy.x = 2048 - 400; // Move Enemy2 200px further left than Enemy } else { enemy.x = 2048 - 200; // 200px from the right edge, matching hero's 200px from left } enemy.y = hero.y; // Get stats for this level (enemy uses linear scaling after level 10) var stats = getStatsForLevel(enemyLevel, "enemy"); // --- RANDOMIZE ENEMY STATS: hp/atk ±30% for 30% --- // 0-0.3: -30% hp/atk, 0.3-0.6: +30% hp/atk, 0.6-1.0: normal var statRand = Math.random(); var hpMod = 1, atkMod = 1; if (statRand < 0.3) { hpMod = 0.7; atkMod = 0.7; } else if (statRand < 0.6) { hpMod = 1.3; atkMod = 1.3; } // Set maxHp for enemy, so it matches the randomized HP value enemy.maxHp = Math.round(stats.hp * hpMod); // --- BOSS STAT MODIFIERS --- if (isBoss) { // HP +100%, Atk +50% enemy.hp = Math.round(stats.hp * 2.0 * hpMod); enemy.attack = Math.round(stats.atk * 1.5 * atkMod); // Make enemy 50% larger enemy.scaleX = (typeof enemy.scaleX === "number" ? enemy.scaleX : 1) * 1.5; enemy.scaleY = (typeof enemy.scaleY === "number" ? enemy.scaleY : 1) * 1.5; // Add BOSS label above enemy var bossLabel = new Text2("BOSS", { size: 90, fill: 0xFF2222, glow: { color: 0xffffff, distance: 10, strength: 2 } }); bossLabel.anchor.set(0.5, 1); bossLabel.x = 0; bossLabel.y = -((enemy.height || 300) / 2) - 30; enemy.addChild(bossLabel); enemy.isBoss = true; } else if (isEnemy2) { // CAN %20 DAHA AZ, ATAK %30 DAHA ÇOK enemy.hp = Math.round(stats.hp * 0.8 * hpMod); enemy.attack = Math.round(stats.atk * 1.3 * atkMod); } else { enemy.hp = Math.round(stats.hp * hpMod); enemy.attack = Math.round(stats.atk * atkMod); } enemy.isAlive = true; enemy.spawnAnim(); game.addChild(enemy); currentEnemy = enemy; // Store the enemy's level for display currentEnemy.level = enemyLevel; currentEnemy.isEnemy2 = isEnemy2; // Track type for possible future use currentEnemy.isBoss = !!isBoss; updateEnemyStatsDisplay(); // --- Start auto-fight timers --- if (typeof heroAutoAttackTimer !== "undefined" && heroAutoAttackTimer) { LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; } if (typeof enemyAutoAttackTimer !== "undefined" && enemyAutoAttackTimer) { LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; } // Get hero stats for this level (hero uses compounded scaling after level 10) var heroStats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = heroStats.hp; // Calculate hero attack, always include sword-1 bonus if equipped hero.attack = heroStats.atk; if (equippedItems && equippedItems["sword-1"]) { hero.attack += itemData["sword-1"].bonusAtk; } // Hero attacks enemy (fixed interval, e.g. 1s) heroAutoAttackTimer = LK.setInterval(function () { if (!currentEnemy || !currentEnemy.isAlive) { LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; return; } // Animate hero and equipped items: move slightly right and return var heroAttackMoveX = 32; tween.stop(hero, { x: true }); tween(hero, { x: hero.x + heroAttackMoveX }, { duration: 60, easing: tween.cubicOut, onFinish: function onFinish() { tween(hero, { x: hero.x - heroAttackMoveX }, { duration: 80, easing: tween.cubicIn }); } }); // Animate equipped visuals if any if (_typeof(hero.equippedVisuals) === "object" && hero.equippedVisuals) { for (var k in hero.equippedVisuals) { if (hero.equippedVisuals[k]) { tween.stop(hero.equippedVisuals[k], { x: true }); var eq = hero.equippedVisuals[k]; var origX = typeof eq._origX === "number" ? eq._origX : eq.x; eq._origX = origX; tween(eq, { x: origX + heroAttackMoveX }, { duration: 60, easing: tween.cubicOut, onFinish: function (eq, origX) { return function () { tween(eq, { x: origX }, { duration: 80, easing: tween.cubicIn }); }; }(eq, origX) }); } } } // If one-shot mode, instantly defeat enemy if (heroOneShotEnemies) { currentEnemy.hp = 0; } else { currentEnemy.hp -= hero.attack; if (currentEnemy.hp < 0) currentEnemy.hp = 0; } // Flash enemy if (currentEnemy) { tween(currentEnemy, { tint: 0xffffff }, { duration: 60, onFinish: function onFinish() { if (currentEnemy) { tween(currentEnemy, { tint: 0x2a6bde }, { duration: 60 }); } } }); } updateEnemyStatsDisplay(); if (currentEnemy.hp <= 0) { defeatEnemy(); LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; } }, 1000); // Fixed 1s interval // Enemy attacks hero (fixed interval, e.g. 1s) enemyAutoAttackTimer = LK.setInterval(function () { if (!currentEnemy || !currentEnemy.isAlive) { LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; return; } if (typeof hero.currentHp !== "number") { // Defensive: ensure hero.currentHp is set var hStats = getEnemyStatsForLevel(heroLevel); hero.currentHp = hStats.hp; } if (!heroIsImmortal) { // --- Shield-1 barrier logic: block damage with barrier first --- if (equippedItems && equippedItems["shield-1"] && heroShield1Barrier > 0) { var dmg = currentEnemy.attack; if (heroShield1Barrier >= dmg) { heroShield1Barrier -= dmg; dmg = 0; } else { dmg -= heroShield1Barrier; heroShield1Barrier = 0; } if (dmg > 0) { hero.currentHp -= dmg; } } else { hero.currentHp -= currentEnemy.attack; } // Flash hero tween(hero, { tint: 0xffffff }, { duration: 60, onFinish: function onFinish() { tween(hero, { tint: 0xd83318 }, { duration: 60 }); } }); updateHeroStatsDisplay(); if (hero.currentHp <= 0) { // Hero defeated, stop fighting hero.currentHp = 0; updateHeroStatsDisplay(); // Optionally, you can add defeat logic here (e.g. show game over) LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; // Start health refill (handled in update loop) hero.healthRefilling = false; // Will be set to true in update loop } } else { // If immortal, keep HP at max and flash gold var stats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = stats.hp; updateHeroStatsDisplay(); tween(hero, { tint: 0xFFD700 }, { duration: 60, onFinish: function onFinish() { tween(hero, { tint: 0xffffff }, { duration: 60 }); } }); } }, 1000); // Fixed 1s interval } // Defeat enemy logic function defeatEnemy() { if (!currentEnemy || !currentEnemy.isAlive) return; currentEnemy.isAlive = false; // Stop auto-fight timers if (typeof heroAutoAttackTimer !== "undefined" && heroAutoAttackTimer) { LK.clearInterval(heroAutoAttackTimer); heroAutoAttackTimer = null; } if (typeof enemyAutoAttackTimer !== "undefined" && enemyAutoAttackTimer) { LK.clearInterval(enemyAutoAttackTimer); enemyAutoAttackTimer = null; } currentEnemy.defeatAnim(function () { if (currentEnemy) { // --- Shield-1 drop logic --- // Only drop for enemy levels 1-10, and only from Enemy (not Enemy2) if (typeof currentEnemy.level !== "undefined" && currentEnemy.level >= 1 && currentEnemy.level <= 10 && !currentEnemy.isEnemy2) { // 5% per level, capped at 50% for level 10 var shieldDropChance = currentEnemy.level * 0.05; if (Math.random() < shieldDropChance) { // Drop shield-1 at enemy's position var shieldAsset = LK.getAsset('shield-1', { anchorX: 0.5, anchorY: 0.5, x: currentEnemy.x, y: currentEnemy.y }); game.addChild(shieldAsset); // Animate drop: move to itemBag position and shrink/fade out // Get itemBag position in game coordinates var itemBagGlobal = LK.gui.bottom.toGlobal({ x: itemBagImg.x, y: itemBagImg.y }); var itemBagGamePos = game.toLocal(itemBagGlobal); tween(shieldAsset, { x: itemBagGamePos.x, y: itemBagGamePos.y, scaleX: 0.3, scaleY: 0.3, alpha: 0.2 }, { duration: 700, easing: tween.cubicIn, onFinish: function onFinish() { shieldAsset.destroy(); // Add to inventory only (do not auto-equip) inventory.push("shield-1"); } }); } } // --- Sword-1 drop logic: only for Enemy2, and only for level 10 and 20 enemies --- // Now: Drop chance is 100% at level 10/20, and for all other levels, 15% chance per defeat from Enemy2 if (typeof currentEnemy.level !== "undefined" && currentEnemy.isEnemy2) { var swordDrop = false; if (currentEnemy.level === 10 || currentEnemy.level === 20) { swordDrop = true; // Always drop at level 10 and 20 } else { // 15% drop chance for all other levels from Enemy2 if (Math.random() < 0.15) swordDrop = true; } if (swordDrop) { var swordAsset = LK.getAsset('sword-1', { anchorX: 0.5, anchorY: 0.5, x: currentEnemy.x, y: currentEnemy.y }); game.addChild(swordAsset); // Animate drop: move to itemBag position and shrink/fade out var itemBagGlobalSword = LK.gui.bottom.toGlobal({ x: itemBagImg.x, y: itemBagImg.y }); var itemBagGamePosSword = game.toLocal(itemBagGlobalSword); tween(swordAsset, { x: itemBagGamePosSword.x, y: itemBagGamePosSword.y, scaleX: 0.3, scaleY: 0.3, alpha: 0.2 }, { duration: 700, easing: tween.cubicIn, onFinish: function onFinish() { swordAsset.destroy(); // Add to inventory only (do not auto-equip) inventory.push("sword-1"); } }); } } // Track boss defeat for level gating if (typeof heroDefeatedBosses === "undefined") heroDefeatedBosses = []; if (currentEnemy && currentEnemy.isBoss && typeof currentEnemy.level === "number") { // Bosses are at spawn counts 8, 16, 24, ... which correspond to levels 5, 10, 15, ... // So, for level gating, bossIndex = Math.floor((currentEnemy.level) / 5) var bossIndex = Math.floor(currentEnemy.level / 5); heroDefeatedBosses[bossIndex] = true; } currentEnemy.destroy(); currentEnemy = null; updateEnemyStatsDisplay(); // HERO CANINI FULLLE! var stats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = stats.hp; updateHeroStatsDisplay(); // If shield-1 is equipped, restore hero HP to new max after enemy defeat if (equippedItems["shield-1"]) { heroShield1Barrier = 250; heroShield1BarrierMax = 250; var stats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = stats.hp; updateHeroStatsDisplay(); } } // --- spawnBtn rotation logic on enemy defeat --- // If hero HP is full, rotate 45deg right, else 90deg left var heroStats = getStatsForLevel(heroLevel, "hero"); if (typeof hero.currentHp === "number" && hero.currentHp >= heroStats.hp) { // Full health: rotate 45deg right spawnBtnRotationQueue.push({ angle: Math.PI / 4 }); } else { // Not full: rotate 90deg left spawnBtnRotationQueue.push({ angle: -Math.PI / 2, onFinish: function onFinish() { // After 90deg left, if hero HP is still not full and no enemy, resume right rotation if ((!currentEnemy || !currentEnemy.isAlive) && typeof hero.currentHp === "number" && hero.currentHp < getStatsForLevel(heroLevel, "hero").hp) { if (!spawnBtn._rotatingWhileNotFull) { spawnBtn._rotatingWhileNotFull = true; // Start continuous right rotation (1 full spin per 1.2s) var _rotateRightLoop = function rotateRightLoop() { if (!spawnBtn._rotatingWhileNotFull) return; var startRot = spawnBtn.rotation; var endRot = startRot + Math.PI * 2; tween(spawnBtn, { rotation: endRot }, { duration: 1200, easing: tween.linear, onFinish: function onFinish() { if (spawnBtn._rotatingWhileNotFull && (!currentEnemy || !currentEnemy.isAlive)) { _rotateRightLoop(); } } }); }; tween.stop(spawnBtn, { rotation: true }); _rotateRightLoop(); } } } }); } processSpawnBtnRotationQueue(); // Start hero health refill after any battle (at same refill speed as on defeat) // If hero died (currentHp <= 0), double the refill duration if (typeof hero.currentHp === "number" && hero.currentHp < getStatsForLevel(heroLevel, "hero").hp && !hero.healthRefilling) { hero.healthRefilling = true; hero.refillStartTime = Date.now(); var stats = getStatsForLevel(heroLevel, "hero"); hero.refillFromHp = hero.currentHp; hero.refillToHp = stats.hp; // Set refill duration to 1/5th speed (5x slower), or 1/10th (10x slower) if hero died var baseDuration = 1000; // original duration if (hero.currentHp <= 0) { hero.refillDuration = baseDuration * 10; // 10x slower if died } else { hero.refillDuration = baseDuration * 5; // 5x slower otherwise } } }); // --- Gold drop amount table per level --- var goldDropByLevel = [ // Level 1 { min: 1, max: 5 }, // Level 2 { min: 3, max: 8 }, // Level 3 { min: 5, max: 12 }, // Level 4 { min: 8, max: 16 }, // Level 5 { min: 12, max: 20 }, // Level 6 { min: 15, max: 25 }, // Level 7 { min: 20, max: 32 }, // Level 8 { min: 25, max: 40 }, // Level 9 { min: 30, max: 48 }, // Level 10 { min: 35, max: 60 }]; // Defensive: If goldDropByLevel is referenced for higher levels, extend with scaled values (function extendGoldDropByLevel() { var last = goldDropByLevel[goldDropByLevel.length - 1]; for (var i = goldDropByLevel.length; i < 100; i++) { // Increase min/max by 10% per level after 10 var prev = goldDropByLevel[i - 1]; goldDropByLevel.push({ min: Math.round(prev.min * 1.1), max: Math.round(prev.max * 1.1) }); } })(); // Determine gold drop amount for this level var goldDropStats = goldDropByLevel[Math.max(0, Math.min(heroLevel - 1, goldDropByLevel.length - 1))]; var goldDropAmount = Math.floor(Math.random() * (goldDropStats.max - goldDropStats.min + 1)) + goldDropStats.min; // Boss: drop 50% more gold if (currentEnemy && currentEnemy.isBoss) { goldDropAmount = Math.round(goldDropAmount * 1.5); } // Drop gold at the far right (where enemy was) // Animate and auto-collect gold after enemy defeat // Calculate the gold display position in game coordinates (top right, where goldTxt is) var goldDisplayGlobal = LK.gui.topRight.toGlobal({ x: goldTxt.x, y: goldTxt.y }); var goldDisplayGamePos = game.toLocal(goldDisplayGlobal); for (var i = 0; i < goldDropAmount; i++) { var gold = new Gold(); gold.x = 2048 - 200; gold.y = hero.y; gold.scaleX = 1; gold.scaleY = 1; gold.alpha = 1; game.addChild(gold); golds.push(gold); // Drop to random y near enemy var dropY = gold.y + (Math.random() * 120 - 60); (function (goldObj, idx) { goldObj.dropAnim(goldObj.x, dropY, function () { // Stagger collection for nice effect LK.setTimeout(function () { // Animate to gold display and collect goldObj.collectAnim(goldDisplayGamePos.x, goldDisplayGamePos.y, function () { goldAmount += 1; updateGoldDisplay(); goldObj.destroy(); }); }, 80 * idx); }); })(gold, i); } // --- Shield-1 drop logic --- // Only drop for enemy levels 1-10 if (typeof enemyLevel !== "undefined" && enemyLevel >= 1 && enemyLevel <= 10) { // 5% per level, capped at 50% for level 10 var shieldDropChance = enemyLevel * 0.05; if (Math.random() < shieldDropChance) { // Drop shield-1 at enemy's position var shieldAsset = LK.getAsset('shield-1', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 200, y: hero.y }); game.addChild(shieldAsset); // Animate drop (fall down a bit, then fade out) var dropTargetY = shieldAsset.y + 180 + (Math.random() * 40 - 20); tween(shieldAsset, { y: dropTargetY }, { duration: 400, easing: tween.bounceOut, onFinish: function onFinish() { // After a short delay, fade out and destroy LK.setTimeout(function () { tween(shieldAsset, { alpha: 0 }, { duration: 350, onFinish: function onFinish() { shieldAsset.destroy(); } }); }, 900); } }); } } } // --- Shield-1 drop logic --- // Only drop for enemy levels 1-10 if (typeof enemyLevel !== "undefined" && enemyLevel >= 1 && enemyLevel <= 10) { // 5% per level, capped at 50% for level 10 var shieldDropChance = enemyLevel * 0.05; if (Math.random() < shieldDropChance) { // Drop shield-1 at enemy's position var shieldAsset = LK.getAsset('shield-1', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 200, y: hero.y }); game.addChild(shieldAsset); // Animate drop (fall down a bit, then fade out) var dropTargetY = shieldAsset.y + 180 + (Math.random() * 40 - 20); tween(shieldAsset, { y: dropTargetY }, { duration: 400, easing: tween.bounceOut, onFinish: function onFinish() { // After a short delay, fade out and destroy LK.setTimeout(function () { tween(shieldAsset, { alpha: 0 }, { duration: 350, onFinish: function onFinish() { shieldAsset.destroy(); } }); }, 900); } }); } } // Collect gold logic function collectGold(gold) { // Animate to gold display var guiGoldPos = LK.gui.topRight.toLocal(gold.toGlobal({ x: 0, y: 0 })); goldAmount += 1; updateGoldDisplay(); gold.collectAnim(guiGoldPos.x, guiGoldPos.y, function () { gold.destroy(); }); } // Upgrade logic function upgradeHero() { var upgradeCost = heroLevel * 5; if (goldAmount < upgradeCost) { // Flash gold text red tween(goldTxt, { tint: 0xff4444 }, { duration: 120, onFinish: function onFinish() { tween(goldTxt, { tint: 0xFFE066 }, { duration: 120 }); } }); return; } // --- Boss defeat requirement for every 5th level --- var nextLevel = heroLevel + 1; var mustDefeatBoss = false; if (nextLevel > 5 && (nextLevel - 1) % 5 === 0) { // For 6, 11, 16, ... 501, etc. (i.e. 6 = after 1st boss, 11 = after 2nd boss, ...) var bossIndex = Math.floor((nextLevel - 1) / 5); // 6->1, 11->2, 16->3, ... // Track defeated bosses in an array if (typeof heroDefeatedBosses === "undefined") heroDefeatedBosses = []; if (!heroDefeatedBosses[bossIndex]) { // Block upgrade, flash upgradeBtn red tween(upgradeBtn, { tint: 0xff4444 }, { duration: 120, onFinish: function onFinish() { tween(upgradeBtn, { tint: 0xffffff }, { duration: 120 }); } }); // Optionally show a message (not required) return; } } goldAmount -= upgradeCost; heroLevel += 1; hero.level = heroLevel; // Refill hero health to full on level up var stats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = stats.hp; hero.healthRefilling = false; updateGoldDisplay(); updateUpgradeDisplay(); updateHeroStatsDisplay(); updateEnemyStatsDisplay(); hero.flashUpgrade(); } // --- Event Handlers --- // Spawn button tap // --- spawnBtn rotation queue state --- var spawnBtnRotationQueue = []; var spawnBtnIsRotating = false; function processSpawnBtnRotationQueue() { if (spawnBtnIsRotating || spawnBtnRotationQueue.length === 0) return; spawnBtnIsRotating = true; var next = spawnBtnRotationQueue.shift(); var targetRotation = spawnBtn.rotation + next.angle; tween(spawnBtn, { rotation: targetRotation }, { duration: 180, easing: tween.cubicInOut, onFinish: function onFinish() { spawnBtn.rotation = targetRotation; spawnBtnIsRotating = false; if (typeof next.onFinish === "function") next.onFinish(); // Process next in queue processSpawnBtnRotationQueue(); } }); } spawnBtn.down = function (x, y, obj) { // Animate shrink tween.stop(spawnBtn, { scaleX: true, scaleY: true }); tween(spawnBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(spawnBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut, onFinish: function onFinish() { // After animation, trigger action // Queue 45deg right rotation spawnBtnRotationQueue.push({ angle: Math.PI / 4 }); processSpawnBtnRotationQueue(); spawnEnemy(); } }); } }); }; // Enemy tap (defeat) function onEnemyDown(x, y, obj) { if (!currentEnemy || !currentEnemy.isAlive) return; currentEnemy.hp -= 1; if (currentEnemy.hp < 0) currentEnemy.hp = 0; // Flash enemy tween(currentEnemy, { tint: 0xffffff }, { duration: 60, onFinish: function onFinish() { tween(currentEnemy, { tint: 0x2a6bde }, { duration: 60 }); } }); if (currentEnemy.hp <= 0) { defeatEnemy(); } } // Gold tap (collect) function onGoldDown(x, y, obj) { for (var i = golds.length - 1; i >= 0; i--) { var gold = golds[i]; if (gold && gold.containsPoint && gold.containsPoint({ x: x, y: y })) { collectGold(gold); golds.splice(i, 1); break; } } } // Upgrade button tap upgradeBtn.down = function (x, y, obj) { // Animate shrink tween.stop(upgradeBtn, { scaleX: true, scaleY: true }); tween(upgradeBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(upgradeBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut, onFinish: function onFinish() { // After animation, trigger action upgradeHero(); } }); } }); }; // Work button tap workBtn.down = function (x, y, obj) { if (!workBtnActive) return; // Prevent workBtn press if hero HP is not full if (typeof hero.currentHp === "number" && hero.currentHp < getStatsForLevel(heroLevel, "hero").hp) return; // Animate shrink tween.stop(workBtn, { scaleX: true, scaleY: true }); tween(workBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, easing: tween.cubicIn, onFinish: function onFinish() { tween(workBtn, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.cubicOut, onFinish: function onFinish() { // After animation, trigger action // Calculate duration: let duration = Math.max(10000, ((level ** 1.2) * 60000) / (attackSpeed * attack)); var stats = getStatsForLevel(heroLevel, "hero"); var duration = Math.max(10, Math.pow(heroLevel, 1.2) * 2); // Simple duration, e.g. 2s per level^1.2 // Multiply duration by heroLevel (time level) duration = duration * heroLevel; workBtnActive = false; workBtnDuration = duration; workBtnTimeLeft = duration; setSpawnBtnEnabled(false); showWorkBtnCountdown(workBtnTimeLeft); // Start timer to update countdown if (workBtnTimer) { LK.clearInterval(workBtnTimer); workBtnTimer = null; } // Start rotation tween for workBtn at 20% of previous speed tween.stop(workBtn, { rotation: true }); workBtn.rotation = 0; // Calculate totalRotations for 20% speed (i.e., 1/5th the previous speed, so 1/5th the number of spins) var baseTotalRotations = 2 + Math.floor(workBtnDuration); var slowTotalRotations = Math.max(1, Math.round(baseTotalRotations * 0.2)); // at least 1 full spin tween(workBtn, { rotation: Math.PI * 2 * slowTotalRotations }, { duration: workBtnDuration * 1000, easing: tween.linear, onFinish: function onFinish() { workBtn.rotation = 0; // reset rotation to 0 for next use } }); workBtnTimer = LK.setInterval(function () { workBtnTimeLeft -= 0.1; if (workBtnTimeLeft < 0) workBtnTimeLeft = 0; showWorkBtnCountdown(workBtnTimeLeft); if (workBtnTimeLeft <= 0) { // Timer done LK.clearInterval(workBtnTimer); workBtnTimer = null; workBtnActive = true; setSpawnBtnEnabled(true); hideWorkBtnCountdown(); // Stop rotation tween and reset rotation tween.stop(workBtn, { rotation: true }); workBtn.rotation = 0; // Drop gold: (main character's level + attack / 2) / random(1-5) var stats = getStatsForLevel(heroLevel, "hero"); var divisor = Math.floor(Math.random() * 5) + 1; var goldVal = heroLevel + stats.atk / 2; var goldDrop = Math.max(1, Math.floor(goldVal / divisor)); // Calculate gold display position in game coordinates (top right, where goldTxt is) var goldDisplayGlobal = LK.gui.topRight.toGlobal({ x: goldTxt.x, y: goldTxt.y }); var goldDisplayGamePos = game.toLocal(goldDisplayGlobal); // Spawn gold under hero and animate to gold display for (var i = 0; i < goldDrop; i++) { var gold = new Gold(); gold.x = hero.x; gold.y = hero.y + hero.height / 2 + 60 + (Math.random() * 40 - 20); gold.scaleX = 1; gold.scaleY = 1; gold.alpha = 1; game.addChild(gold); golds.push(gold); // Animate to gold display (function (goldObj, idx) { // Retreat: move down a bit, then animate to gold display var retreatY = goldObj.y + 80 + (Math.random() * 30 - 15); goldObj.dropAnim(goldObj.x, retreatY, function () { LK.setTimeout(function () { goldObj.collectAnim(goldDisplayGamePos.x, goldDisplayGamePos.y, function () { goldAmount += 1; updateGoldDisplay(); goldObj.destroy(); }); }, 80 * idx); }); })(gold, i); } } }, 100); } }); } }); }; // --- Attach event handlers to game --- game.down = function (x, y, obj) { // Check if tap is on enemy if (currentEnemy && currentEnemy.isAlive && currentEnemy.containsPoint && currentEnemy.containsPoint({ x: x, y: y })) { onEnemyDown(x, y, obj); return; } // Check if tap is on any gold for (var i = golds.length - 1; i >= 0; i--) { var gold = golds[i]; if (gold && gold.containsPoint && gold.containsPoint({ x: x, y: y })) { collectGold(gold); golds.splice(i, 1); return; } } // (Buttons handled by their own .down) }; // --- Game update loop --- game.update = function () { // Hide spawnBtn if current location is şehir, demirci, maden, kale, or sahil if (currentLocationId === "bg_sehir" || currentLocationId === "bg_demirci" || currentLocationId === "bg_maden" || currentLocationId === "bg_kale" || currentLocationId === "bg_sahil") { if (typeof spawnBtn !== "undefined" && spawnBtn) spawnBtn.visible = false; if (typeof findEnemyTxt !== "undefined" && findEnemyTxt) findEnemyTxt.visible = false; // Always show demirciBtn if in demirci if (currentLocationId === "bg_demirci" && typeof demirciBtn !== "undefined" && demirciBtn) { demirciBtn.visible = true; } // Show madenBtn only in maden if (typeof madenBtn !== "undefined" && madenBtn) { madenBtn.visible = currentLocationId === "bg_maden"; // Check if kazma is in inventory var hasKazma = false; for (var i = 0; i < inventory.length; i++) { if (inventory[i] === "kazma") { hasKazma = true; break; } } if (madenBtn.visible) { // Only allow madenBtn if kazma is EQUIPPED, not just in inventory var kazmaEquipped = !!equippedItems["kazma"]; if (!kazmaEquipped) { madenBtn.alpha = 0.5; madenBtn.interactive = false; madenBtn.buttonMode = false; } else { madenBtn.alpha = 1; madenBtn.interactive = true; madenBtn.buttonMode = true; } } } // Show kaleBtn only in kale if (typeof kaleBtn !== "undefined" && kaleBtn) { kaleBtn.visible = currentLocationId === "bg_kale"; } } else { if (typeof spawnBtn !== "undefined" && spawnBtn) spawnBtn.visible = true; if (typeof findEnemyTxt !== "undefined" && findEnemyTxt) findEnemyTxt.visible = true; // Hide demirciBtn if not in demirci if (typeof demirciBtn !== "undefined" && demirciBtn) { demirciBtn.visible = false; } // Hide madenBtn if not in maden if (typeof madenBtn !== "undefined" && madenBtn) { madenBtn.visible = false; } // Hide kaleBtn if not in kale if (typeof kaleBtn !== "undefined" && kaleBtn) { kaleBtn.visible = false; } } // Remove golds that are invisible for (var i = golds.length - 1; i >= 0; i--) { var gold = golds[i]; if (gold.alpha <= 0.01) { gold.destroy(); golds.splice(i, 1); } } // --- Hero health refill logic --- if (typeof hero.healthRefilling === "undefined") hero.healthRefilling = false; if (typeof hero.refillStartTime === "undefined") hero.refillStartTime = 0; if (typeof hero.refillDuration === "undefined") hero.refillDuration = 5000; // Default, will be set below if (typeof hero.refillFromHp === "undefined") hero.refillFromHp = 0; if (typeof hero.refillToHp === "undefined") hero.refillToHp = 0; if (typeof hero.currentHp === "number" && hero.currentHp <= 0 && !hero.healthRefilling) { // Start refill hero.healthRefilling = true; hero.refillStartTime = Date.now(); var stats = getStatsForLevel(heroLevel, "hero"); hero.refillFromHp = 0; hero.refillToHp = stats.hp; // Set refill duration to 1/5th speed (5x slower) hero.refillDuration = 5000; // fallback var baseDuration = 1000; // original duration if (hero.currentHp <= 0) { hero.refillDuration = baseDuration * 10; // 10x slower if died } else { hero.refillDuration = baseDuration * 5; // 5x slower otherwise } // Destroy enemy immediately (so a new one can only be summoned after refill) // --- DAĞ: Remove all enemies and prevent gold drop on hero defeat --- if (currentLocationId === "bg_dag" && Array.isArray(currentEnemy)) { // Remove all DAĞ enemies for (var i = 0; i < currentEnemy.length; i++) { if (currentEnemy[i] && currentEnemy[i].isAlive) { currentEnemy[i].isAlive = false; // Animate defeat, but do not drop gold/items (function (enemyObj) { enemyObj.defeatAnim(function () { if (enemyObj && enemyObj.parent) { enemyObj.destroy(); } }); })(currentEnemy[i]); } } currentEnemy = null; updateEnemyStatsDisplay(); // --- DAĞ: Restore hero shield and health after fight, just like ORMAN --- // Always restore barrier to max after refill, if shield is equipped if (equippedItems && equippedItems["shield-1"]) { var baseBarrier = 250; var shieldUpgradeLevel = equippedItemUpgradeLevels["shield-1"] || 0; if (shieldUpgradeLevel > 0) { baseBarrier = Math.round(baseBarrier * (1 + 0.1 * shieldUpgradeLevel)); } heroShield1Barrier = baseBarrier; heroShield1BarrierMax = baseBarrier; } else { heroShield1Barrier = 0; heroShield1BarrierMax = 0; } // Restore hero health to FULL after DAĞ fight (like ORMAN) var stats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = stats.hp; updateHeroStatsDisplay(); } else if (currentEnemy && currentEnemy.isAlive) { currentEnemy.isAlive = false; currentEnemy.defeatAnim(function () { if (currentEnemy) { currentEnemy.destroy(); currentEnemy = null; updateEnemyStatsDisplay(); } }); } } if (hero.healthRefilling) { var now = Date.now(); var elapsed = now - hero.refillStartTime; var t = Math.min(1, elapsed / hero.refillDuration); var stats = getStatsForLevel(heroLevel, "hero"); hero.currentHp = Math.round(hero.refillFromHp + (hero.refillToHp - hero.refillFromHp) * t); if (t >= 1) { hero.currentHp = stats.hp; hero.healthRefilling = false; // After refill, if shield-1 is equipped, restore barrier to max if (equippedItems && equippedItems["shield-1"]) { heroShield1Barrier = 250; heroShield1BarrierMax = 250; } } } // Prevent spawnBtn and workBtn from being pressed unless hero HP is full if (typeof hero.currentHp === "number" && hero.currentHp < getStatsForLevel(heroLevel, "hero").hp) { setSpawnBtnEnabled(false); // Disable workBtn and make it semi-transparent workBtn.alpha = 0.5; workBtn.interactive = false; workBtn.buttonMode = false; // --- Rotate spawnBtn to the right while hero HP is not full, but only if NO enemy is alive --- if (!spawnBtn._rotatingWhileNotFull && (!currentEnemy || !currentEnemy.isAlive)) { var _rotateRightLoop = function rotateRightLoop() { if (!spawnBtn._rotatingWhileNotFull) return; var startRot = spawnBtn.rotation; var endRot = startRot + Math.PI * 2; tween(spawnBtn, { rotation: endRot }, { duration: 1200, easing: tween.linear, onFinish: function onFinish() { // Continue loop if still not full and still no enemy if (spawnBtn._rotatingWhileNotFull && (!currentEnemy || !currentEnemy.isAlive)) { _rotateRightLoop(); } } }); }; tween.stop(spawnBtn, { rotation: true }); // Start continuous right rotation (1 full spin per 1.2s) spawnBtn._rotatingWhileNotFull = true; _rotateRightLoop(); } } else if (!hero.healthRefilling && workBtnActive) { setSpawnBtnEnabled(true); // Enable workBtn and restore full opacity workBtn.alpha = 1; workBtn.interactive = true; workBtn.buttonMode = true; // If hero HP is full, remove all effects and restore color tween.stop(hero, { tint: true, alpha: true, scaleX: true, scaleY: true }); hero.tint = 0xffffff; hero.alpha = 1; hero.scaleX = 1; hero.scaleY = 1; // --- Stop spawnBtn rotation and reset to original position, with 45deg right spin if HP just became full and no enemy is alive --- if (spawnBtn._rotatingWhileNotFull) { spawnBtn._rotatingWhileNotFull = false; tween.stop(spawnBtn, { rotation: true }); // If hero HP just became full and no enemy is alive, rotate 45deg right and then reset to 0 if ((!currentEnemy || !currentEnemy.isAlive) && typeof hero.currentHp === "number" && hero.currentHp === getStatsForLevel(heroLevel, "hero").hp) { // Animate 45deg right, then reset to 0 tween(spawnBtn, { rotation: spawnBtn.rotation + Math.PI / 4 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { tween(spawnBtn, { rotation: 0 }, { duration: 200, easing: tween.cubicOut }); } }); } else { // Animate back to original rotation (0) tween(spawnBtn, { rotation: 0 }, { duration: 200, easing: tween.cubicOut }); } } } // Keep hero slightly lower than vertical center hero.y = 2732 / 2 + 200; // Keep enemy vertically centered and at far right if alive if (currentEnemy && currentEnemy.isAlive) { currentEnemy.x = 2048 - 200; currentEnemy.y = hero.y + 100; // Move enemy a little lower } updateHeroStatsDisplay(); updateEnemyStatsDisplay(); // Keep workBtnCountdownTxt positioned under workBtn if visible if (workBtnCountdownTxt && typeof workBtnCountdownTxt.destroyed === "boolean" && !workBtnCountdownTxt.destroyed && typeof workBtnCountdownTxt.setText === "function" && typeof workBtnCountdownTxt.x !== "undefined" && typeof workBtnCountdownTxt.y !== "undefined") { // Defensive: Only access .visible if it exists, and never access .setAsset if ((typeof workBtnCountdownTxt.visible === "undefined" || workBtnCountdownTxt.visible) && typeof workBtnCountdownTxt.x !== "undefined" && typeof workBtnCountdownTxt.y !== "undefined") { workBtnCountdownTxt.x = workBtn.x; workBtnCountdownTxt.y = workBtn.y + workBtn.height / 2 + 8; } } }; // --- Initial UI state --- updateGoldDisplay(); updateUpgradeDisplay(); updateHeroStatsDisplay(); updateEnemyStatsDisplay(); // --- Hero HP and Shield Auto-Regeneration Logic --- // Regenerate 25% of max HP per second, and refill shield barrier, if no enemy is present if (typeof heroAutoRegenInterval === "undefined") { var heroAutoRegenInterval = null; } if (heroAutoRegenInterval) { LK.clearInterval(heroAutoRegenInterval); heroAutoRegenInterval = null; } heroAutoRegenInterval = LK.setInterval(function () { // Defensive: Only run if hero exists and not in battle if (!hero || typeof hero.currentHp !== "number") return; // If any enemy is alive, do not regen var enemyAlive = false; if (Array.isArray(currentEnemy)) { for (var i = 0; i < currentEnemy.length; i++) { if (currentEnemy[i] && currentEnemy[i].isAlive) { enemyAlive = true; break; } } } else if (currentEnemy && currentEnemy.isAlive) { enemyAlive = true; } if (enemyAlive) return; // Regen HP if not full var stats = getStatsForLevel(heroLevel, "hero"); var maxHp = stats.hp; if (typeof hero.currentHp !== "number" || hero.currentHp >= maxHp) { hero.currentHp = Math.min(maxHp, hero.currentHp); } else { var regenAmount = Math.ceil(maxHp * 0.25); hero.currentHp = Math.min(maxHp, hero.currentHp + regenAmount); updateHeroStatsDisplay(); } // Regen shield barrier if equipped and not full if (equippedItems && equippedItems["shield-1"]) { var maxBarrier = 250; var shieldUpgradeLevel = equippedItemUpgradeLevels["shield-1"] || 0; if (shieldUpgradeLevel > 0) { maxBarrier = Math.round(maxBarrier * (1 + 0.1 * shieldUpgradeLevel)); } if (typeof heroShield1Barrier !== "number" || heroShield1Barrier >= maxBarrier) { heroShield1Barrier = Math.min(maxBarrier, heroShield1Barrier); heroShield1BarrierMax = maxBarrier; } else { // Refill all missing barrier at once per second heroShield1Barrier = maxBarrier; heroShield1BarrierMax = maxBarrier; updateHeroStatsDisplay(); } } }, 1000);
===================================================================
--- original.js
+++ change.js
@@ -1101,27 +1101,26 @@
var centerY = 2732 / 2;
madenActiveResource = [];
var madenResourceTimeouts = [];
var oldGameDown = game.down;
- // Define drop table with probabilities and typeIdx
+ // --- Ava: Reduce drop rates by half, and increase with kazma upgrade level ---
+ // Get kazma upgrade level (0 if not upgraded)
+ var kazmaUpgradeLevel = equippedItemUpgradeLevels && equippedItemUpgradeLevels["kazma"] ? equippedItemUpgradeLevels["kazma"] : 0;
+ // Each upgrade level increases drop rates by 10% of original (not compounded, capped at 100%)
+ var upgradeBonus = kazmaUpgradeLevel * 0.1;
+ // Base drop rates halved
var dropTable = [{
typeIdx: 3,
- chance: 0.05
- },
- // hammitril (1000)
- {
+ chance: Math.min(1, 0.025 + 0.05 * upgradeBonus) // hammitril (1000)
+ }, {
typeIdx: 2,
- chance: 0.25
- },
- // hamaltin (100)
- {
+ chance: Math.min(1, 0.125 + 0.25 * upgradeBonus) // hamaltin (100)
+ }, {
typeIdx: 1,
- chance: 0.50
- },
- // hamgumus (50)
- {
+ chance: Math.min(1, 0.25 + 0.5 * upgradeBonus) // hamgumus (50)
+ }, {
typeIdx: 0,
- chance: 0.95
+ chance: Math.min(1, 0.475 + 0.95 * upgradeBonus) // hamdemir (5)
} // hamdemir (5)
];
// For each resource type, roll and drop if passed
for (var i = 0; i < dropTable.length; i++) {