/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CenterMarker = Container.expand(function () {
var self = Container.call(this);
var markerGraphics = self.attachAsset('centerMarker', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.isMoving = false;
self.targetX = 0;
self.targetY = 0;
self.speed = 3;
self.lastX = 0; // Track last X position for direction detection
self.moveTo = function (x, y) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate speed bonus from speeditems (1% per speeditem)
var speedBonus = playerInventory.speeditem * 0.01;
var actualSpeed = self.speed * (1 + speedBonus);
if (distance < actualSpeed) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
} else {
// Store current X before updating
var currentX = self.x;
self.x += dx / distance * actualSpeed;
self.y += dy / distance * actualSpeed;
// Check direction change and flip character accordingly
if (self.x > currentX) {
// Moving right - face right (normal)
characterGraphics.scale.x = Math.abs(characterGraphics.scale.x);
} else if (self.x < currentX) {
// Moving left - face left (flipped)
characterGraphics.scale.x = -Math.abs(characterGraphics.scale.x);
}
}
}
};
return self;
});
var City = Container.expand(function () {
var self = Container.call(this);
var cityGraphics = self.attachAsset('city', {
anchorX: 0.5,
anchorY: 0.5
});
cityGraphics.y = -60; // Move graphics up by 60 pixels
return self;
});
var InventorySlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.quantity = 0;
// Create invisible slot background for click detection
var slotBg = LK.getAsset('centerMarker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
slotBg.alpha = 0; // Make invisible but still clickable
self.addChild(slotBg);
// Item icon (initially invisible)
var itemIcon = null;
// Quantity text (initially invisible)
var quantityText = new Text2('', {
size: 58,
fill: 0xFFFFFF
});
quantityText.anchor.set(1, 1);
quantityText.x = 60;
quantityText.y = 60;
self.addChild(quantityText);
// Method to set item and quantity
self.setItem = function (itemType, qty) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
self.quantity = qty || 0;
if (itemType === 'salt' && self.quantity > 0) {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'apple' && self.quantity > 0) {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'speeditem' && self.quantity > 0) {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'sword' && self.quantity > 0) {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else {
// Empty slot
self.item = null;
self.quantity = 0;
quantityText.setText('');
}
};
// Method to add quantity to existing item
self.addQuantity = function (qty) {
self.quantity += qty;
if (self.quantity > 0) {
quantityText.setText(self.quantity.toString());
} else {
self.setItem(null, 0);
}
};
return self;
});
var Mountain = Container.expand(function () {
var self = Container.call(this);
var mountainGraphics = self.attachAsset('mountain', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Passage = Container.expand(function () {
var self = Container.call(this);
var passageGraphics = self.attachAsset('passage', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetMap = 0;
self.targetX = 0;
self.targetY = 0;
return self;
});
var Road = Container.expand(function () {
var self = Container.call(this);
var roadGraphics = self.attachAsset('road', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var SellSlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.price = 0;
// Create slot background (tradearea)
var slotBg = self.attachAsset('tradearea', {
anchorX: 0.5,
anchorY: 0.5
});
// Item icon (initially invisible)
var itemIcon = null;
// Item name text
var itemNameText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.x = 0;
itemNameText.y = 50;
self.addChild(itemNameText);
// Item price text
var itemPriceText = new Text2('', {
size: 40,
fill: 0xFFD700
});
itemPriceText.anchor.set(0.5, 0.5);
itemPriceText.x = 0;
itemPriceText.y = 80;
self.addChild(itemPriceText);
// Method to set item
self.setItem = function (itemType) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
if (itemType === 'salt') {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Salt');
self.price = Math.round(saltCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'apple') {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Apple');
self.price = Math.round(appleCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'speeditem') {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Speed Item');
self.price = Math.round(speeditemCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'sword') {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Sword');
self.price = Math.round(swordCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else {
// Empty slot
itemNameText.setText('');
itemPriceText.setText('');
self.price = 0;
}
};
// Handle slot click
self.down = function (x, y, obj) {
if (self.item) {
// Check if player has this item in inventory
var hasItem = false;
if (self.item === 'salt' && playerInventory.salt > 0) {
hasItem = true;
} else if (self.item === 'apple' && playerInventory.apple > 0) {
hasItem = true;
} else if (self.item === 'speeditem' && playerInventory.speeditem > 0) {
hasItem = true;
} else if (self.item === 'sword' && playerInventory.sword > 0) {
hasItem = true;
}
if (hasItem) {
// Sell item
playerGold = Math.round((playerGold + self.price) * 10) / 10;
updateGoldDisplay();
// Remove item from inventory
if (self.item === 'salt') {
playerInventory.salt--;
storage.playerSaltCount = playerInventory.salt;
} else if (self.item === 'apple') {
playerInventory.apple--;
storage.playerAppleCount = playerInventory.apple;
} else if (self.item === 'speeditem') {
playerInventory.speeditem--;
storage.playerSpeeditemCount = playerInventory.speeditem;
} else if (self.item === 'sword') {
playerInventory.sword--;
storage.playerSwordCount = playerInventory.sword;
}
// Update inventory display if open
if (isInventoryOpen) {
updateInventoryDisplay();
}
// Flash effect on sale
LK.effects.flashObject(self, 0x00FF00, 500);
// Clear the slot after sale
self.setItem(null);
} else {
// Don't have item - flash red
LK.effects.flashObject(self, 0xFF0000, 500);
}
}
};
return self;
});
var TradeSlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.price = 0;
// Create slot background (tradearea)
var slotBg = self.attachAsset('tradearea', {
anchorX: 0.5,
anchorY: 0.5
});
// Item icon (initially invisible)
var itemIcon = null;
// Item name text
var itemNameText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.x = 0;
itemNameText.y = 50;
self.addChild(itemNameText);
// Item price text
var itemPriceText = new Text2('', {
size: 40,
fill: 0xFFD700
});
itemPriceText.anchor.set(0.5, 0.5);
itemPriceText.x = 0;
itemPriceText.y = 80;
self.addChild(itemPriceText);
// Method to set item
self.setItem = function (itemType) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
if (itemType === 'salt') {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Salt');
self.price = Math.round(saltCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'apple') {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Apple');
self.price = Math.round(appleCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'speeditem') {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Speed Item');
self.price = Math.round(speeditemCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'sword') {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Sword');
self.price = Math.round(swordCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else {
// Empty slot
itemNameText.setText('');
itemPriceText.setText('');
self.price = 0;
}
};
// Handle slot click
self.down = function (x, y, obj) {
if (self.item && playerGold >= self.price) {
// Purchase item
playerGold = Math.round((playerGold - self.price) * 10) / 10;
updateGoldDisplay();
// Add item to inventory
if (self.item === 'salt') {
playerInventory.salt++;
storage.playerSaltCount = playerInventory.salt;
} else if (self.item === 'apple') {
playerInventory.apple++;
storage.playerAppleCount = playerInventory.apple;
} else if (self.item === 'speeditem') {
playerInventory.speeditem++;
storage.playerSpeeditemCount = playerInventory.speeditem;
} else if (self.item === 'sword') {
playerInventory.sword++;
storage.playerSwordCount = playerInventory.sword;
}
// Update inventory display if open
if (isInventoryOpen) {
updateInventoryDisplay();
}
// Flash effect on purchase
LK.effects.flashObject(self, 0x00FF00, 500);
// Clear the slot after purchase
self.setItem(null);
} else if (self.item && playerGold < self.price) {
// Not enough gold - flash red
LK.effects.flashObject(self, 0xFF0000, 500);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228b22
});
/****
* Game Code
****/
var currentMap = storage.currentMap || 0;
var character = game.addChild(new Character());
var roads = [];
var mountains = [];
var passages = [];
var centerMarker = null;
var city = null;
// Gold system variables
var playerGold = Math.round((storage.playerGold || 100) * 10) / 10;
var goldIcon = null;
var goldText = null;
// Economy system variables - flattened for storage compatibility
var saltBasePrice = 2000;
var saltCurrentPrice = storage.saltCurrentPrice || 2000;
var appleBasePrice = 10;
var appleCurrentPrice = storage.appleCurrentPrice || 10;
var speeditemBasePrice = 20;
var speeditemCurrentPrice = storage.speeditemCurrentPrice || 20;
var swordBasePrice = 60;
var swordCurrentPrice = storage.swordCurrentPrice || 60;
// Movement tracking for economy
var lastPlayerX = 0;
var lastPlayerY = 0;
var totalMovementDistance = storage.totalMovementDistance || 0;
var lastSaltPriceUpdate = storage.lastSaltPriceUpdate || 0;
var lastApplePriceUpdate = storage.lastApplePriceUpdate || 0;
var lastSpeeditemPriceUpdate = storage.lastSpeeditemPriceUpdate || 0;
var lastSwordPriceUpdate = storage.lastSwordPriceUpdate || 0;
// Map data - 12 interconnected maps
var mapData = [
// Map 0
{
roads: [{
x: 200,
y: 400
}, {
x: 300,
y: 400
}, {
x: 400,
y: 400
}, {
x: 500,
y: 400
}, {
x: 600,
y: 400
}, {
x: 700,
y: 400
}, {
x: 800,
y: 500
}, {
x: 900,
y: 600
}, {
x: 1000,
y: 700
}, {
x: 1100,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1400,
y: 1100
}, {
x: 1500,
y: 1200
}, {
x: 1600,
y: 1300
}, {
x: 1700,
y: 1400
}, {
x: 1800,
y: 1500
}, {
x: 1900,
y: 1500
}, {
x: 2000,
y: 1500
}, {
x: 1800,
y: 1600
}, {
x: 1800,
y: 1700
}, {
x: 1800,
y: 1800
}, {
x: 1800,
y: 1900
}, {
x: 1800,
y: 2000
}, {
x: 1800,
y: 2100
}, {
x: 1800,
y: 2200
}, {
x: 1800,
y: 2300
}, {
x: 1800,
y: 2400
}, {
x: 1800,
y: 2500
}, {
x: 1800,
y: 2600
}, {
x: 1800,
y: 2700
}],
mountains: [{
x: 150,
y: 200
}, {
x: 250,
y: 150
}, {
x: 350,
y: 180
}, {
x: 450,
y: 220
}, {
x: 550,
y: 180
}, {
x: 650,
y: 200
}, {
x: 750,
y: 250
}, {
x: 850,
y: 300
}, {
x: 950,
y: 350
}, {
x: 1050,
y: 400
}, {
x: 1150,
y: 450
}, {
x: 1250,
y: 500
}, {
x: 1350,
y: 550
}, {
x: 1450,
y: 600
}, {
x: 1550,
y: 650
}, {
x: 1650,
y: 700
}],
passages: [{
x: 2000,
y: 1500,
targetMap: 1,
targetX: 100,
targetY: 1500
}, {
x: 1800,
y: 2700,
targetMap: 3,
targetX: 1800,
targetY: 100
}],
startX: 200,
startY: 400
},
// Map 1
{
roads: [{
x: 100,
y: 1500
}, {
x: 200,
y: 1500
}, {
x: 300,
y: 1500
}, {
x: 400,
y: 1400
}, {
x: 500,
y: 1300
}, {
x: 600,
y: 1200
}, {
x: 700,
y: 1100
}, {
x: 800,
y: 1000
}, {
x: 900,
y: 900
}, {
x: 1000,
y: 800
}, {
x: 1100,
y: 700
}, {
x: 1200,
y: 600
}, {
x: 1300,
y: 500
}, {
x: 1400,
y: 400
}, {
x: 1500,
y: 300
}, {
x: 1600,
y: 200
}, {
x: 48,
y: 1500
}, {
x: 1600,
y: 150
}, {
x: 1600,
y: 100
}, {
x: 1600,
y: 48
}],
mountains: [{
x: 200,
y: 1700
}, {
x: 300,
y: 1800
}, {
x: 400,
y: 1700
}, {
x: 500,
y: 1600
}, {
x: 600,
y: 1500
}, {
x: 700,
y: 1400
}, {
x: 800,
y: 1300
}, {
x: 900,
y: 1200
}, {
x: 1000,
y: 1100
}, {
x: 1100,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1300,
y: 800
}],
passages: [{
x: 100,
y: 1500,
targetMap: 0,
targetX: 2000,
targetY: 1500
}, {
x: 1600,
y: 100,
targetMap: 2,
targetX: 1600,
targetY: 2700
}],
startX: 100,
startY: 1500
},
// Map 2
{
roads: [{
x: 1600,
y: 2700
}, {
x: 1600,
y: 2600
}, {
x: 1600,
y: 2500
}, {
x: 1600,
y: 2400
}, {
x: 1600,
y: 2300
}, {
x: 1600,
y: 2200
}, {
x: 1600,
y: 2100
}, {
x: 1600,
y: 2000
}, {
x: 1600,
y: 1900
}, {
x: 1600,
y: 1800
}, {
x: 1600,
y: 1700
}, {
x: 1600,
y: 1600
}, {
x: 1600,
y: 1500
}, {
x: 1600,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1600,
y: 1200
}],
mountains: [{
x: 1400,
y: 2600
}, {
x: 1500,
y: 2500
}, {
x: 1700,
y: 2500
}, {
x: 1800,
y: 2600
}, {
x: 1400,
y: 2400
}, {
x: 1800,
y: 2400
}, {
x: 1400,
y: 2200
}, {
x: 1800,
y: 2200
}, {
x: 1400,
y: 2000
}, {
x: 1800,
y: 2000
}, {
x: 1400,
y: 1800
}, {
x: 1800,
y: 1800
}],
passages: [{
x: 1600,
y: 2700,
targetMap: 1,
targetX: 1600,
targetY: 100
}, {
x: 1600,
y: 1200,
targetMap: 4,
targetX: 1600,
targetY: 2350
}],
startX: 1600,
startY: 2700
},
// Map 3
{
roads: [{
x: 1800,
y: 100
}, {
x: 1700,
y: 200
}, {
x: 1600,
y: 300
}, {
x: 1500,
y: 400
}, {
x: 1400,
y: 500
}, {
x: 1300,
y: 600
}, {
x: 1200,
y: 700
}, {
x: 1100,
y: 800
}, {
x: 1000,
y: 900
}, {
x: 900,
y: 1000
}, {
x: 800,
y: 1100
}, {
x: 700,
y: 1200
}, {
x: 600,
y: 1300
}, {
x: 500,
y: 1400
}, {
x: 400,
y: 1500
}, {
x: 300,
y: 1600
}, {
x: 1800,
y: 48
}, {
x: 250,
y: 1600
}, {
x: 200,
y: 1600
}],
mountains: [{
x: 1900,
y: 200
}, {
x: 1800,
y: 300
}, {
x: 1700,
y: 400
}, {
x: 1600,
y: 500
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 1000
}, {
x: 1000,
y: 1100
}, {
x: 900,
y: 1200
}, {
x: 800,
y: 1300
}],
passages: [{
x: 1800,
y: 100,
targetMap: 0,
targetX: 1800,
targetY: 2700
}, {
x: 200,
y: 1600,
targetMap: 5,
targetX: 1900,
targetY: 1600
}],
startX: 1800,
startY: 100
},
// Map 4
{
roads: [{
x: 1600,
y: 2350
}, {
x: 1500,
y: 2250
}, {
x: 1400,
y: 2150
}, {
x: 1300,
y: 2050
}, {
x: 1200,
y: 1950
}, {
x: 1100,
y: 1850
}, {
x: 1000,
y: 1750
}, {
x: 900,
y: 1650
}, {
x: 800,
y: 1550
}, {
x: 700,
y: 1450
}, {
x: 600,
y: 1350
}, {
x: 500,
y: 1250
}],
mountains: [{
x: 1700,
y: 2700
}, {
x: 1600,
y: 2800
}, {
x: 1500,
y: 2700
}, {
x: 1400,
y: 2600
}, {
x: 1300,
y: 2500
}, {
x: 1200,
y: 2400
}, {
x: 1100,
y: 2300
}, {
x: 1000,
y: 2200
}],
passages: [{
x: 1600,
y: 2350,
targetMap: 2,
targetX: 1600,
targetY: 1200
}, {
x: 500,
y: 1250,
targetMap: 6,
targetX: 1800,
targetY: 1500
}],
startX: 1600,
startY: 2350
},
// Map 5
{
roads: [{
x: 1900,
y: 1600
}, {
x: 1800,
y: 1600
}, {
x: 1700,
y: 1600
}, {
x: 1600,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 1400,
y: 1600
}, {
x: 1300,
y: 1600
}, {
x: 1200,
y: 1600
}, {
x: 1100,
y: 1600
}, {
x: 1000,
y: 1600
}, {
x: 900,
y: 1600
}, {
x: 800,
y: 1600
}, {
x: 750,
y: 1600
}, {
x: 700,
y: 1600
}, {
x: 1950,
y: 1600
}, {
x: 2000,
y: 1600
}],
mountains: [{
x: 1900,
y: 1400
}, {
x: 1800,
y: 1400
}, {
x: 1900,
y: 1800
}, {
x: 1800,
y: 1800
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1400
}, {
x: 1700,
y: 1800
}, {
x: 1600,
y: 1800
}],
passages: [{
x: 2000,
y: 1600,
targetMap: 3,
targetX: 200,
targetY: 1600
}, {
x: 700,
y: 1600,
targetMap: 7,
targetX: 1400,
targetY: 1600
}],
startX: 1900,
startY: 1600
},
// Map 6
{
roads: [{
x: 1800,
y: 1500
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1500,
y: 1200
}, {
x: 1400,
y: 1100
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 800
}, {
x: 1000,
y: 700
}, {
x: 900,
y: 600
}, {
x: 800,
y: 500
}, {
x: 700,
y: 400
}, {
x: 1850,
y: 1500
}, {
x: 1900,
y: 1500
}, {
x: 1950,
y: 1500
}, {
x: 2000,
y: 1500
}, {
x: 650,
y: 400
}, {
x: 600,
y: 400
}],
mountains: [{
x: 1900,
y: 1600
}, {
x: 1800,
y: 1700
}, {
x: 1700,
y: 1600
}, {
x: 1600,
y: 1500
}, {
x: 1500,
y: 1400
}, {
x: 1400,
y: 1300
}, {
x: 1300,
y: 1200
}, {
x: 1200,
y: 1100
}],
passages: [{
x: 2000,
y: 1500,
targetMap: 4,
targetX: 500,
targetY: 1250
}, {
x: 600,
y: 400,
targetMap: 8,
targetX: 1500,
targetY: 2300
}],
startX: 1800,
startY: 1500
},
// Map 7
{
roads: [{
x: 1400,
y: 1600
}, {
x: 1300,
y: 1500
}, {
x: 1200,
y: 1400
}, {
x: 1100,
y: 1300
}, {
x: 1000,
y: 1200
}, {
x: 900,
y: 1100
}, {
x: 800,
y: 1000
}, {
x: 700,
y: 900
}, {
x: 600,
y: 800
}, {
x: 500,
y: 700
}, {
x: 400,
y: 600
}, {
x: 300,
y: 500
}, {
x: 1450,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 250,
y: 500
}, {
x: 200,
y: 500
}],
mountains: [{
x: 1500,
y: 1700
}, {
x: 1400,
y: 1800
}, {
x: 1300,
y: 1700
}, {
x: 1200,
y: 1600
}, {
x: 1100,
y: 1500
}, {
x: 1000,
y: 1400
}, {
x: 900,
y: 1300
}, {
x: 800,
y: 1200
}],
passages: [{
x: 1500,
y: 1600,
targetMap: 5,
targetX: 700,
targetY: 1600
}, {
x: 200,
y: 500,
targetMap: 9,
targetX: 1800,
targetY: 500
}],
startX: 1400,
startY: 1600
},
// Map 8
{
roads: [{
x: 1500,
y: 2300
}, {
x: 1400,
y: 2200
}, {
x: 1300,
y: 2100
}, {
x: 1200,
y: 2000
}, {
x: 1100,
y: 1900
}, {
x: 1000,
y: 1800
}, {
x: 900,
y: 1700
}, {
x: 800,
y: 1600
}, {
x: 700,
y: 1500
}, {
x: 600,
y: 1400
}, {
x: 500,
y: 1300
}, {
x: 400,
y: 1200
}, {
x: 1500,
y: 2400
}, {
x: 1500,
y: 2500
}, {
x: 1500,
y: 2600
}, {
x: 1500,
y: 2700
}, {
x: 1500,
y: 2732
}, {
x: 350,
y: 1200
}, {
x: 300,
y: 1200
}],
mountains: [{
x: 1600,
y: 2400
}, {
x: 1500,
y: 2500
}, {
x: 1400,
y: 2400
}, {
x: 1300,
y: 2300
}, {
x: 1200,
y: 2200
}, {
x: 1100,
y: 2100
}, {
x: 1000,
y: 2000
}, {
x: 900,
y: 1900
}],
passages: [{
x: 1500,
y: 2700,
targetMap: 6,
targetX: 600,
targetY: 400
}, {
x: 300,
y: 1200,
targetMap: 10,
targetX: 1700,
targetY: 1200
}],
startX: 1500,
startY: 2300
},
// Map 9
{
roads: [{
x: 1800,
y: 500
}, {
x: 1700,
y: 600
}, {
x: 1600,
y: 700
}, {
x: 1500,
y: 800
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 1100
}, {
x: 1100,
y: 1200
}, {
x: 1000,
y: 1300
}, {
x: 900,
y: 1400
}, {
x: 800,
y: 1500
}, {
x: 700,
y: 1600
}, {
x: 1850,
y: 500
}, {
x: 1900,
y: 500
}, {
x: 1950,
y: 500
}, {
x: 2000,
y: 500
}, {
x: 900,
y: 1300
}, {
x: 800,
y: 1300
}, {
x: 700,
y: 1300
}, {
x: 600,
y: 1300
}, {
x: 550,
y: 1300
}, {
x: 500,
y: 1300
}],
mountains: [{
x: 1900,
y: 400
}, {
x: 1800,
y: 300
}, {
x: 1700,
y: 400
}, {
x: 1600,
y: 500
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}],
passages: [{
x: 2000,
y: 500,
targetMap: 7,
targetX: 200,
targetY: 500
}, {
x: 500,
y: 1300,
targetMap: 11,
targetX: 1500,
targetY: 800
}],
startX: 1800,
startY: 500
},
// Map 10
{
roads: [{
x: 1700,
y: 1200
}, {
x: 1600,
y: 1100
}, {
x: 1500,
y: 1000
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 700
}, {
x: 1100,
y: 600
}, {
x: 1000,
y: 500
}, {
x: 900,
y: 400
}, {
x: 800,
y: 300
}, {
x: 700,
y: 200
}, {
x: 600,
y: 100
}, {
x: 1750,
y: 1200
}, {
x: 1800,
y: 1200
}, {
x: 600,
y: 75
}, {
x: 600,
y: 48
}],
mountains: [{
x: 1800,
y: 1300
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1500,
y: 1200
}, {
x: 1400,
y: 1100
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 800
}],
passages: [{
x: 1795,
y: 1260,
targetMap: 8,
targetX: 300,
targetY: 1200
}, {
x: 600,
y: 100,
targetMap: 11,
targetX: 600,
targetY: 2700
}],
startX: 1700,
startY: 1200
},
// Map 11
{
roads: [{
x: 1500,
y: 800
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 1100
}, {
x: 1100,
y: 1200
}, {
x: 1000,
y: 1300
}, {
x: 900,
y: 1400
}, {
x: 800,
y: 1500
}, {
x: 700,
y: 1600
}, {
x: 600,
y: 1700
}, {
x: 600,
y: 1800
}, {
x: 600,
y: 1900
}, {
x: 600,
y: 2000
}, {
x: 600,
y: 2100
}, {
x: 600,
y: 2200
}, {
x: 600,
y: 2300
}, {
x: 600,
y: 2400
}, {
x: 600,
y: 2500
}, {
x: 600,
y: 2600
}, {
x: 1500,
y: 750
}, {
x: 1500,
y: 700
}, {
x: 600,
y: 2650
}, {
x: 600,
y: 2700
}, {
x: 600,
y: 2732
}],
mountains: [{
x: 1600,
y: 700
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 1000
}, {
x: 1000,
y: 1100
}, {
x: 900,
y: 1200
}, {
x: 500,
y: 1700
}, {
x: 700,
y: 1700
}, {
x: 500,
y: 1900
}, {
x: 700,
y: 1900
}],
passages: [{
x: 1500,
y: 700,
targetMap: 9,
targetX: 600,
targetY: 1600
}, {
x: 600,
y: 2700,
targetMap: 10,
targetX: 600,
targetY: 100
}],
startX: 1500,
startY: 800
}];
var arBackground = null;
function loadMap(mapIndex) {
// Clear existing elements
for (var i = 0; i < roads.length; i++) {
roads[i].destroy();
}
// Mountain cleanup removed
for (var i = 0; i < passages.length; i++) {
passages[i].destroy();
}
// Clean up existing center marker
if (centerMarker) {
centerMarker.destroy();
centerMarker = null;
}
// Clean up existing city marker
if (city) {
city.destroy();
city = null;
}
// Clean up existing AR background
if (arBackground) {
arBackground.destroy();
arBackground = null;
}
roads = [];
mountains = [];
passages = [];
var map = mapData[mapIndex];
// Add AR background only for Ancient Ruins (map 6)
if (mapIndex === 6) {
arBackground = game.addChild(LK.getAsset('AR', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
x: 1024,
y: 1366
}));
}
// Add CP background only for Central Plains (map 4)
if (mapIndex === 4) {
arBackground = game.addChild(LK.getAsset('CP', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
x: 1024,
y: 1366
}));
}
// Add SR background only for Southern Ridge (map 2)
if (mapIndex === 2) {
arBackground = game.addChild(LK.getAsset('Sr', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
x: 1024,
y: 1366
}));
}
// Add EV background only for Eastern Valleys (map 1)
if (mapIndex === 1) {
arBackground = game.addChild(LK.getAsset('Ev', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add NH background only for Northern Highlands (map 0)
if (mapIndex === 0) {
arBackground = game.addChild(LK.getAsset('Nh', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add WP background only for Western Peaks (map 3)
if (mapIndex === 3) {
arBackground = game.addChild(LK.getAsset('wp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7,
scaleY: 9,
x: 1024,
y: 1366
}));
}
// Add MW background only for Mystic Woods (map 5)
if (mapIndex === 5) {
arBackground = game.addChild(LK.getAsset('mw', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add DS background only for Desert Sands (map 7)
if (mapIndex === 7) {
arBackground = game.addChild(LK.getAsset('ds', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add CC background only for Coastal Cliffs (map 9)
if (mapIndex === 9) {
arBackground = game.addChild(LK.getAsset('cc', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Add SG background only for Sacred Grove (map 11)
if (mapIndex === 11) {
arBackground = game.addChild(LK.getAsset('sg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add MP background only for Mountain Pass (map 10)
if (mapIndex === 10) {
arBackground = game.addChild(LK.getAsset('mp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Add FW background only for Frozen Wastes (map 8)
if (mapIndex === 8) {
arBackground = game.addChild(LK.getAsset('fw', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Create roads
for (var i = 0; i < map.roads.length; i++) {
var road = game.addChild(new Road());
road.x = map.roads[i].x;
road.y = map.roads[i].y;
roads.push(road);
}
// Mountains removed from display
// Create passages
for (var i = 0; i < map.passages.length; i++) {
var passage = game.addChild(new Passage());
passage.x = map.passages[i].x;
passage.y = map.passages[i].y;
passage.targetMap = map.passages[i].targetMap;
passage.targetX = map.passages[i].targetX;
passage.targetY = map.passages[i].targetY;
passages.push(passage);
}
// Set character position
if (character.x === 0 && character.y === 0) {
character.x = map.startX;
character.y = map.startY;
}
// Find and mark the center road point
var centerRoad = findCenterRoad();
if (centerRoad) {
centerMarker = game.addChild(new CenterMarker());
centerMarker.x = centerRoad.x;
centerMarker.y = centerRoad.y;
}
// Add city marker at calculated position
var cityPosition = findCityPosition();
city = game.addChild(new City());
city.x = cityPosition.x;
city.y = cityPosition.y;
// Create connecting road between center marker and city
if (centerMarker && city) {
var connectionRoads = createConnectionRoad(centerMarker.x, centerMarker.y, city.x, city.y);
for (var i = 0; i < connectionRoads.length; i++) {
roads.push(connectionRoads[i]);
}
}
// Bring city to front so it appears above roads
if (city) {
game.removeChild(city);
game.addChild(city);
}
// Bring character to front so it appears above roads
game.removeChild(character);
game.addChild(character);
// Reset city visit tracking for new map
hasVisitedCity = false;
lastCityDistance = Infinity;
if (isMarketOpen) {
closeMarketScreen();
}
// Generate new market slots for this map
if (!marketSlots) {
marketSlots = [];
}
// Refresh market inventories when changing regions
generateMarketSlots();
generateSellSlots();
}
function findNearestRoad(x, y) {
var nearestRoad = null;
var minDistance = Infinity;
for (var i = 0; i < roads.length; i++) {
var road = roads[i];
var dx = x - road.x;
var dy = y - road.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
nearestRoad = road;
}
}
return nearestRoad;
}
function findCityPosition() {
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
var mirrorPoints = [];
var map = mapData[currentMap];
// Calculate mirror coordinates for each passage
for (var i = 0; i < map.passages.length; i++) {
var passage = map.passages[i];
var mirrorX = 2 * centerX - passage.x;
var mirrorY = 2 * centerY - passage.y;
mirrorPoints.push({
x: mirrorX,
y: mirrorY
});
}
// Find the center of all mirror points
if (mirrorPoints.length === 0) {
return {
x: centerX,
y: centerY
}; // Default to screen center if no passages
}
var totalX = 0;
var totalY = 0;
for (var i = 0; i < mirrorPoints.length; i++) {
totalX += mirrorPoints[i].x;
totalY += mirrorPoints[i].y;
}
return {
x: totalX / mirrorPoints.length,
y: totalY / mirrorPoints.length
};
}
function createConnectionRoad(startX, startY, endX, endY) {
var connectionRoads = [];
var dx = endX - startX;
var dy = endY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
var steps = Math.floor(distance / 100); // Create road points every 100 pixels
for (var i = 1; i <= steps; i++) {
var progress = i / (steps + 1);
var roadX = startX + dx * progress;
var roadY = startY + dy * progress;
var road = game.addChild(new Road());
road.x = roadX;
road.y = roadY;
connectionRoads.push(road);
}
return connectionRoads;
}
function findCenterRoad() {
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
var centerRoad = null;
var minDistance = Infinity;
for (var i = 0; i < roads.length; i++) {
var road = roads[i];
var dx = centerX - road.x;
var dy = centerY - road.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
centerRoad = road;
}
}
return centerRoad;
}
function checkPassageCollision() {
for (var i = 0; i < passages.length; i++) {
var passage = passages[i];
var dx = character.x - passage.x;
var dy = character.y - passage.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 80) {
currentMap = passage.targetMap;
storage.currentMap = currentMap;
loadMap(currentMap);
// Find the 4th nearest road point to the target passage
var targetPassageX = passage.targetX;
var targetPassageY = passage.targetY;
var roadDistances = [];
// Calculate distances from target passage to all roads
for (var j = 0; j < roads.length; j++) {
var road = roads[j];
var rdx = targetPassageX - road.x;
var rdy = targetPassageY - road.y;
var roadDistance = Math.sqrt(rdx * rdx + rdy * rdy);
roadDistances.push({
road: road,
distance: roadDistance
});
}
// Sort roads by distance
roadDistances.sort(function (a, b) {
return a.distance - b.distance;
});
// Get the 4th nearest road (index 3), or closest available if less than 4 roads
var targetRoadIndex = Math.min(3, roadDistances.length - 1);
// Special case for Western Peaks left passage teleportation - use 5th nearest road for better positioning
if (currentMap === 5 && passage.targetX === 1900 && passage.targetY === 1600) {
targetRoadIndex = Math.min(4, roadDistances.length - 1);
}
// Special case for Sacred Grove to Coastal Cliffs teleportation - use 3rd nearest road
if (currentMap === 9 && passage.targetX === 600 && passage.targetY === 1600) {
targetRoadIndex = Math.min(2, roadDistances.length - 1);
}
var targetRoad = roadDistances[targetRoadIndex].road;
character.x = targetRoad.x;
character.y = targetRoad.y;
character.isMoving = false;
break;
}
}
}
// Initialize first map
loadMap(currentMap);
// Bring character to front so it appears above roads
game.removeChild(character);
game.addChild(character);
// Initialize economy system tracking
lastPlayerX = character.x;
lastPlayerY = character.y;
// Initialize market slots array to prevent undefined errors
var marketSlots = [];
var sellSlots = [];
// Slot probability pools for each city - initialized as global variable
var slotProbabilityPools = [
// Map 0 - Northern Highlands
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// 35% empty, 25% apple, 15% salt, 15% speeditem, 10% sword
// Map 1 - Eastern Valleys
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 2 - Southern Ridge
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 3 - Western Peaks
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 4 - Central Plains
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 5 - Mystic Woods
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 6 - Ancient Ruins
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 7 - Desert Sands
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 8 - Frozen Wastes
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 9 - Coastal Cliffs
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 10 - Mountain Pass
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 11 - Sacred Grove
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword']];
// Region names for each map
var regionNames = ['Northern Highlands', 'Eastern Valleys', 'Southern Ridge', 'Western Peaks', 'Central Plains', 'Mystic Woods', 'Ancient Ruins', 'Desert Sands', 'Frozen Wastes', 'Coastal Cliffs', 'Mountain Pass', 'Sacred Grove'];
// Map info display
var mapText = new Text2(regionNames[currentMap], {
size: 60,
fill: 0xFFFFFF
});
mapText.anchor.set(1, 1);
LK.gui.bottomRight.addChild(mapText);
// Gold display setup
goldIcon = LK.getAsset('gold', {
anchorX: 0,
anchorY: 0,
scaleX: 1.6,
scaleY: 1.6
});
goldIcon.x = 120;
goldIcon.y = 20;
LK.gui.topLeft.addChild(goldIcon);
goldText = new Text2(playerGold.toString(), {
size: 96,
fill: 0xFFD700
});
goldText.anchor.set(0, 0);
goldText.x = 280;
goldText.y = 50;
LK.gui.topLeft.addChild(goldText);
// Inventory button setup
var inventoryButton = LK.getAsset('bag', {
anchorX: 1,
anchorY: 0,
scaleX: 1.2,
scaleY: 1.2
});
inventoryButton.x = -20;
inventoryButton.y = 20;
LK.gui.topRight.addChild(inventoryButton);
// City market UI variables
var marketScreen = null;
var marketTitle = null;
var closeButton = null;
var isMarketOpen = false;
var lastCityDistance = Infinity;
var hasVisitedCity = false;
// Inventory UI variables
var inventoryScreen = null;
var isInventoryOpen = false;
var inventorySlots = [];
// Market mode variables
var marketMode = 'selection'; // 'selection', 'buy', 'sell'
var buyButton = null;
var sellButton = null;
// Player inventory system
var playerInventory = {
salt: storage.playerSaltCount || 0,
apple: storage.playerAppleCount || 0,
speeditem: storage.playerSpeeditemCount || 0,
sword: storage.playerSwordCount || 0
};
// Market slot system variables
// Slot refresh now happens on map change
function generateMarketSlots() {
// Clear existing slots
for (var i = 0; i < marketSlots.length; i++) {
if (marketSlots[i] && marketSlots[i].parent) {
marketSlots[i].parent.removeChild(marketSlots[i]);
}
}
marketSlots = [];
// Safety check for slotProbabilityPools existence
if (!slotProbabilityPools || !Array.isArray(slotProbabilityPools)) {
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// Get probability pool for current map
var probabilityPool = slotProbabilityPools[currentMap];
// Generate 6 slots
for (var i = 0; i < 6; i++) {
var slot = new TradeSlot();
// Random item from probability pool
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
slot.setItem(itemType);
marketSlots.push(slot);
}
}
function generateSellSlots() {
// Clear existing sell slots
// Safety check for sellSlots array existence
if (sellSlots && sellSlots.length > 0) {
for (var i = 0; i < sellSlots.length; i++) {
if (sellSlots[i] && sellSlots[i].parent) {
sellSlots[i].parent.removeChild(sellSlots[i]);
}
}
}
sellSlots = [];
// Safety check for slotProbabilityPools existence
if (!slotProbabilityPools || !Array.isArray(slotProbabilityPools)) {
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// Get probability pool for current map
var probabilityPool = slotProbabilityPools[currentMap];
// Generate 6 sell slots
for (var i = 0; i < 6; i++) {
var slot = new SellSlot();
// Random item from probability pool
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
slot.setItem(itemType);
sellSlots.push(slot);
}
}
function refreshMarketSlots() {
// Safety check for marketSlots array
if (!marketSlots) {
marketSlots = [];
generateMarketSlots();
return;
}
// Additional safety check for marketSlots length
if (marketSlots.length === 0) {
generateMarketSlots();
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// 10% chance to refresh each slot
var probabilityPool = slotProbabilityPools[currentMap];
for (var i = 0; i < marketSlots.length; i++) {
if (Math.random() < 0.1) {
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
marketSlots[i].setItem(itemType);
}
}
// Also refresh sell slots if they exist
if (sellSlots && sellSlots.length > 0) {
for (var i = 0; i < sellSlots.length; i++) {
if (Math.random() < 0.1) {
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
sellSlots[i].setItem(itemType);
}
}
}
}
function createMarketScreen() {
// Create market background container
marketScreen = new Container();
marketScreen.x = 0;
marketScreen.y = 0;
// Create market background using citytrade texture
var marketBg = LK.getAsset('citytrade', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
marketBg.x = 24;
marketBg.y = -34;
marketScreen.addChild(marketBg);
// Show mode selection buttons
if (marketMode === 'selection') {
// Create buy button
buyButton = LK.getAsset('buybuton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
buyButton.x = -150;
buyButton.y = 0;
marketScreen.addChild(buyButton);
// Create sell button
sellButton = LK.getAsset('sellbuton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
sellButton.x = 150;
sellButton.y = 0;
marketScreen.addChild(sellButton);
// Add button functionality
buyButton.down = function () {
marketMode = 'buy';
showBuyMode();
};
sellButton.down = function () {
marketMode = 'sell';
showSellMode();
};
} else if (marketMode === 'buy') {
showBuyMode();
} else if (marketMode === 'sell') {
showSellMode();
}
// Create market title
marketTitle = new Text2(regionNames[currentMap] + ' Market', {
size: 77,
fill: 0xFFFFFF
});
marketTitle.anchor.set(0.5, 0);
marketTitle.x = 24;
marketTitle.y = -490;
marketScreen.addChild(marketTitle);
// Create close button using xbutton texture
closeButton = LK.getAsset('xbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
closeButton.x = 556;
closeButton.y = -680;
marketScreen.addChild(closeButton);
// Add close button functionality
closeButton.down = function () {
closeMarketScreen();
};
LK.gui.center.addChild(marketScreen);
isMarketOpen = true;
}
function showBuyMode() {
// Clear mode selection buttons
if (buyButton) {
marketScreen.removeChild(buyButton);
buyButton = null;
}
if (sellButton) {
marketScreen.removeChild(sellButton);
sellButton = null;
}
// Generate market slots if they don't exist
if (marketSlots.length === 0) {
generateMarketSlots();
}
// Position and add buy slots to market screen (2 rows, 3 columns)
var slotStartX = -190;
var slotStartY = -180;
var slotSpacingX = 220;
var slotSpacingY = 210;
for (var i = 0; i < marketSlots.length; i++) {
var slot = marketSlots[i];
var row = Math.floor(i / 3);
var col = i % 3;
slot.x = slotStartX + col * slotSpacingX;
slot.y = slotStartY + row * slotSpacingY;
// Move top 3 slots (first row) 70 pixels up
if (row === 0) {
slot.y -= 70;
}
marketScreen.addChild(slot);
}
}
function showSellMode() {
// Clear mode selection buttons
if (buyButton) {
marketScreen.removeChild(buyButton);
buyButton = null;
}
if (sellButton) {
marketScreen.removeChild(sellButton);
sellButton = null;
}
// Generate sell slots if they don't exist
if (sellSlots.length === 0) {
generateSellSlots();
}
// Position and add sell slots to market screen (2 rows, 3 columns)
var slotStartX = -190;
var slotStartY = -180;
var slotSpacingX = 220;
var slotSpacingY = 210;
for (var i = 0; i < sellSlots.length; i++) {
var slot = sellSlots[i];
var row = Math.floor(i / 3);
var col = i % 3;
slot.x = slotStartX + col * slotSpacingX;
slot.y = slotStartY + row * slotSpacingY;
// Move top 3 slots (first row) 70 pixels up
if (row === 0) {
slot.y -= 70;
}
marketScreen.addChild(slot);
}
}
function closeMarketScreen() {
if (marketScreen) {
LK.gui.center.removeChild(marketScreen);
marketScreen = null;
marketTitle = null;
closeButton = null;
buyButton = null;
sellButton = null;
isMarketOpen = false;
marketMode = 'selection'; // Reset to selection mode
}
}
function checkCityProximity() {
if (!city) {
return;
}
var dx = character.x - city.x;
var dy = character.y - city.y;
var currentDistance = Math.sqrt(dx * dx + dy * dy);
// Check if entering city range (distance < 100)
if (lastCityDistance >= 100 && currentDistance < 100) {
// Just entered city - show market if not already visited
if (!hasVisitedCity && !isMarketOpen) {
createMarketScreen();
hasVisitedCity = true;
}
}
// Check if leaving city range (distance > 150)
if (lastCityDistance <= 150 && currentDistance > 150) {
// Left city area - reset visit flag for next entry
hasVisitedCity = false;
if (isMarketOpen) {
closeMarketScreen();
}
}
lastCityDistance = currentDistance;
}
game.down = function (x, y, obj) {
// Prevent movement when market or inventory is open
if (isMarketOpen || isInventoryOpen) {
return;
}
var nearestRoad = findNearestRoad(x, y);
if (nearestRoad) {
character.moveTo(nearestRoad.x, nearestRoad.y);
}
};
function updateGoldDisplay() {
if (goldText) {
goldText.setText(playerGold.toString());
storage.playerGold = Math.round(playerGold * 10) / 10;
}
}
function updateEconomySystem() {
// Track movement distance
var dx = character.x - lastPlayerX;
var dy = character.y - lastPlayerY;
var movementThisFrame = Math.sqrt(dx * dx + dy * dy);
if (movementThisFrame > 0) {
totalMovementDistance += movementThisFrame;
// Salt price update every 5000 pixels
var saltDistanceThreshold = lastSaltPriceUpdate + 5000;
if (totalMovementDistance >= saltDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (7%) or decrease (6%)
if (Math.random() < 0.5) {
saltCurrentPrice = Math.round(saltCurrentPrice * 1.07 * 10) / 10; // 7% increase
} else {
saltCurrentPrice = Math.round(saltCurrentPrice * 0.94 * 10) / 10; // 6% decrease
}
}
lastSaltPriceUpdate = totalMovementDistance;
}
// Apple price update every 500 pixels
var appleDistanceThreshold = lastApplePriceUpdate + 500;
if (totalMovementDistance >= appleDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (+1) or decrease (-1)
if (Math.random() < 0.5) {
appleCurrentPrice = Math.round((appleCurrentPrice + 1) * 10) / 10;
} else {
appleCurrentPrice = Math.round((appleCurrentPrice - 1) * 10) / 10;
}
// Apply price limits for apple (5-25)
if (appleCurrentPrice < 5) {
appleCurrentPrice = 5;
}
if (appleCurrentPrice > 25) {
appleCurrentPrice = 25;
}
}
lastApplePriceUpdate = totalMovementDistance;
}
// Speeditem price update every 2000 pixels
var speeditemDistanceThreshold = lastSpeeditemPriceUpdate + 2000;
if (totalMovementDistance >= speeditemDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (5%) or decrease (5%)
if (Math.random() < 0.5) {
speeditemCurrentPrice = Math.round(speeditemCurrentPrice * 1.05 * 10) / 10; // 5% increase
} else {
speeditemCurrentPrice = Math.round(speeditemCurrentPrice * 0.95 * 10) / 10; // 5% decrease
}
}
lastSpeeditemPriceUpdate = totalMovementDistance;
}
// Sword price update every 2000 pixels
var swordDistanceThreshold = lastSwordPriceUpdate + 2000;
if (totalMovementDistance >= swordDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (5%) or decrease (5%)
if (Math.random() < 0.5) {
swordCurrentPrice = Math.round(swordCurrentPrice * 1.05 * 10) / 10; // 5% increase
} else {
swordCurrentPrice = Math.round(swordCurrentPrice * 0.95 * 10) / 10; // 5% decrease
}
}
lastSwordPriceUpdate = totalMovementDistance;
}
// Slot refresh now happens on map change instead of movement distance
// Save economy data to storage
storage.saltCurrentPrice = saltCurrentPrice;
storage.appleCurrentPrice = appleCurrentPrice;
storage.speeditemCurrentPrice = speeditemCurrentPrice;
storage.swordCurrentPrice = swordCurrentPrice;
storage.totalMovementDistance = totalMovementDistance;
storage.lastSaltPriceUpdate = lastSaltPriceUpdate;
storage.lastApplePriceUpdate = lastApplePriceUpdate;
storage.lastSpeeditemPriceUpdate = lastSpeeditemPriceUpdate;
storage.lastSwordPriceUpdate = lastSwordPriceUpdate;
}
// Update last position
lastPlayerX = character.x;
lastPlayerY = character.y;
}
// Add inventory button functionality
inventoryButton.down = function () {
if (!isInventoryOpen) {
createInventoryScreen();
} else {
closeInventoryScreen();
}
};
function createInventoryScreen() {
// Create inventory background container
inventoryScreen = new Container();
inventoryScreen.x = 0;
inventoryScreen.y = 0;
// Create inventory background using playerinventory texture
var inventoryBg = LK.getAsset('playerinventory', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
inventoryBg.x = 0;
inventoryBg.y = 0;
inventoryScreen.addChild(inventoryBg);
// Create 4x4 grid of inventory slots
inventorySlots = [];
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++) {
var slot = new InventorySlot();
// Position with 8px down offset and increased spacing: 30px margin, 120px slot size, 15px spacing
slot.x = -300 + 30 + col * 135 + 60; // -300 to center, +30 margin, +60 for slot center, 135px spacing (120+15)
slot.y = -300 + 30 + row * 135 + 60 + 8; // -300 to center, +30 margin, +60 for slot center, +8px down, 135px spacing
inventoryScreen.addChild(slot);
inventorySlots.push(slot);
}
}
// Create close button
var inventoryCloseButton = LK.getAsset('xbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
inventoryCloseButton.x = 330;
inventoryCloseButton.y = -330;
inventoryScreen.addChild(inventoryCloseButton);
// Add close button functionality
inventoryCloseButton.down = function () {
closeInventoryScreen();
};
LK.gui.center.addChild(inventoryScreen);
isInventoryOpen = true;
// Update inventory display
updateInventoryDisplay();
}
function closeInventoryScreen() {
if (inventoryScreen) {
LK.gui.center.removeChild(inventoryScreen);
inventoryScreen = null;
inventorySlots = [];
isInventoryOpen = false;
}
}
function updateInventoryDisplay() {
if (!inventorySlots || inventorySlots.length === 0) return;
// Clear all slots first
for (var i = 0; i < inventorySlots.length; i++) {
inventorySlots[i].setItem(null, 0);
}
// Fill slots with player inventory
var slotIndex = 0;
// Add salt items
if (playerInventory.salt > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('salt', playerInventory.salt);
slotIndex++;
}
// Add apple items
if (playerInventory.apple > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('apple', playerInventory.apple);
slotIndex++;
}
// Add speeditem items
if (playerInventory.speeditem > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('speeditem', playerInventory.speeditem);
slotIndex++;
}
// Add sword items
if (playerInventory.sword > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('sword', playerInventory.sword);
slotIndex++;
}
}
function addItemToInventory(itemType) {
// Find existing slot with same item type
for (var i = 0; i < inventorySlots.length; i++) {
if (inventorySlots[i].item === itemType) {
inventorySlots[i].addQuantity(1);
return;
}
}
// Find first empty slot
for (var i = 0; i < inventorySlots.length; i++) {
if (!inventorySlots[i].item) {
inventorySlots[i].setItem(itemType, 1);
return;
}
}
}
// Generate initial market slots after everything is initialized
generateMarketSlots();
generateSellSlots();
game.update = function () {
checkPassageCollision();
mapText.setText(regionNames[currentMap]);
checkCityProximity();
updateGoldDisplay();
updateEconomySystem();
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CenterMarker = Container.expand(function () {
var self = Container.call(this);
var markerGraphics = self.attachAsset('centerMarker', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.isMoving = false;
self.targetX = 0;
self.targetY = 0;
self.speed = 3;
self.lastX = 0; // Track last X position for direction detection
self.moveTo = function (x, y) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate speed bonus from speeditems (1% per speeditem)
var speedBonus = playerInventory.speeditem * 0.01;
var actualSpeed = self.speed * (1 + speedBonus);
if (distance < actualSpeed) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
} else {
// Store current X before updating
var currentX = self.x;
self.x += dx / distance * actualSpeed;
self.y += dy / distance * actualSpeed;
// Check direction change and flip character accordingly
if (self.x > currentX) {
// Moving right - face right (normal)
characterGraphics.scale.x = Math.abs(characterGraphics.scale.x);
} else if (self.x < currentX) {
// Moving left - face left (flipped)
characterGraphics.scale.x = -Math.abs(characterGraphics.scale.x);
}
}
}
};
return self;
});
var City = Container.expand(function () {
var self = Container.call(this);
var cityGraphics = self.attachAsset('city', {
anchorX: 0.5,
anchorY: 0.5
});
cityGraphics.y = -60; // Move graphics up by 60 pixels
return self;
});
var InventorySlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.quantity = 0;
// Create invisible slot background for click detection
var slotBg = LK.getAsset('centerMarker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
slotBg.alpha = 0; // Make invisible but still clickable
self.addChild(slotBg);
// Item icon (initially invisible)
var itemIcon = null;
// Quantity text (initially invisible)
var quantityText = new Text2('', {
size: 58,
fill: 0xFFFFFF
});
quantityText.anchor.set(1, 1);
quantityText.x = 60;
quantityText.y = 60;
self.addChild(quantityText);
// Method to set item and quantity
self.setItem = function (itemType, qty) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
self.quantity = qty || 0;
if (itemType === 'salt' && self.quantity > 0) {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'apple' && self.quantity > 0) {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'speeditem' && self.quantity > 0) {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'sword' && self.quantity > 0) {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else {
// Empty slot
self.item = null;
self.quantity = 0;
quantityText.setText('');
}
};
// Method to add quantity to existing item
self.addQuantity = function (qty) {
self.quantity += qty;
if (self.quantity > 0) {
quantityText.setText(self.quantity.toString());
} else {
self.setItem(null, 0);
}
};
return self;
});
var Mountain = Container.expand(function () {
var self = Container.call(this);
var mountainGraphics = self.attachAsset('mountain', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Passage = Container.expand(function () {
var self = Container.call(this);
var passageGraphics = self.attachAsset('passage', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetMap = 0;
self.targetX = 0;
self.targetY = 0;
return self;
});
var Road = Container.expand(function () {
var self = Container.call(this);
var roadGraphics = self.attachAsset('road', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var SellSlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.price = 0;
// Create slot background (tradearea)
var slotBg = self.attachAsset('tradearea', {
anchorX: 0.5,
anchorY: 0.5
});
// Item icon (initially invisible)
var itemIcon = null;
// Item name text
var itemNameText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.x = 0;
itemNameText.y = 50;
self.addChild(itemNameText);
// Item price text
var itemPriceText = new Text2('', {
size: 40,
fill: 0xFFD700
});
itemPriceText.anchor.set(0.5, 0.5);
itemPriceText.x = 0;
itemPriceText.y = 80;
self.addChild(itemPriceText);
// Method to set item
self.setItem = function (itemType) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
if (itemType === 'salt') {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Salt');
self.price = Math.round(saltCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'apple') {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Apple');
self.price = Math.round(appleCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'speeditem') {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Speed Item');
self.price = Math.round(speeditemCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'sword') {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Sword');
self.price = Math.round(swordCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else {
// Empty slot
itemNameText.setText('');
itemPriceText.setText('');
self.price = 0;
}
};
// Handle slot click
self.down = function (x, y, obj) {
if (self.item) {
// Check if player has this item in inventory
var hasItem = false;
if (self.item === 'salt' && playerInventory.salt > 0) {
hasItem = true;
} else if (self.item === 'apple' && playerInventory.apple > 0) {
hasItem = true;
} else if (self.item === 'speeditem' && playerInventory.speeditem > 0) {
hasItem = true;
} else if (self.item === 'sword' && playerInventory.sword > 0) {
hasItem = true;
}
if (hasItem) {
// Sell item
playerGold = Math.round((playerGold + self.price) * 10) / 10;
updateGoldDisplay();
// Remove item from inventory
if (self.item === 'salt') {
playerInventory.salt--;
storage.playerSaltCount = playerInventory.salt;
} else if (self.item === 'apple') {
playerInventory.apple--;
storage.playerAppleCount = playerInventory.apple;
} else if (self.item === 'speeditem') {
playerInventory.speeditem--;
storage.playerSpeeditemCount = playerInventory.speeditem;
} else if (self.item === 'sword') {
playerInventory.sword--;
storage.playerSwordCount = playerInventory.sword;
}
// Update inventory display if open
if (isInventoryOpen) {
updateInventoryDisplay();
}
// Flash effect on sale
LK.effects.flashObject(self, 0x00FF00, 500);
// Clear the slot after sale
self.setItem(null);
} else {
// Don't have item - flash red
LK.effects.flashObject(self, 0xFF0000, 500);
}
}
};
return self;
});
var TradeSlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.price = 0;
// Create slot background (tradearea)
var slotBg = self.attachAsset('tradearea', {
anchorX: 0.5,
anchorY: 0.5
});
// Item icon (initially invisible)
var itemIcon = null;
// Item name text
var itemNameText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.x = 0;
itemNameText.y = 50;
self.addChild(itemNameText);
// Item price text
var itemPriceText = new Text2('', {
size: 40,
fill: 0xFFD700
});
itemPriceText.anchor.set(0.5, 0.5);
itemPriceText.x = 0;
itemPriceText.y = 80;
self.addChild(itemPriceText);
// Method to set item
self.setItem = function (itemType) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
if (itemType === 'salt') {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Salt');
self.price = Math.round(saltCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'apple') {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Apple');
self.price = Math.round(appleCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'speeditem') {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Speed Item');
self.price = Math.round(speeditemCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'sword') {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Sword');
self.price = Math.round(swordCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else {
// Empty slot
itemNameText.setText('');
itemPriceText.setText('');
self.price = 0;
}
};
// Handle slot click
self.down = function (x, y, obj) {
if (self.item && playerGold >= self.price) {
// Purchase item
playerGold = Math.round((playerGold - self.price) * 10) / 10;
updateGoldDisplay();
// Add item to inventory
if (self.item === 'salt') {
playerInventory.salt++;
storage.playerSaltCount = playerInventory.salt;
} else if (self.item === 'apple') {
playerInventory.apple++;
storage.playerAppleCount = playerInventory.apple;
} else if (self.item === 'speeditem') {
playerInventory.speeditem++;
storage.playerSpeeditemCount = playerInventory.speeditem;
} else if (self.item === 'sword') {
playerInventory.sword++;
storage.playerSwordCount = playerInventory.sword;
}
// Update inventory display if open
if (isInventoryOpen) {
updateInventoryDisplay();
}
// Flash effect on purchase
LK.effects.flashObject(self, 0x00FF00, 500);
// Clear the slot after purchase
self.setItem(null);
} else if (self.item && playerGold < self.price) {
// Not enough gold - flash red
LK.effects.flashObject(self, 0xFF0000, 500);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228b22
});
/****
* Game Code
****/
var currentMap = storage.currentMap || 0;
var character = game.addChild(new Character());
var roads = [];
var mountains = [];
var passages = [];
var centerMarker = null;
var city = null;
// Gold system variables
var playerGold = Math.round((storage.playerGold || 100) * 10) / 10;
var goldIcon = null;
var goldText = null;
// Economy system variables - flattened for storage compatibility
var saltBasePrice = 2000;
var saltCurrentPrice = storage.saltCurrentPrice || 2000;
var appleBasePrice = 10;
var appleCurrentPrice = storage.appleCurrentPrice || 10;
var speeditemBasePrice = 20;
var speeditemCurrentPrice = storage.speeditemCurrentPrice || 20;
var swordBasePrice = 60;
var swordCurrentPrice = storage.swordCurrentPrice || 60;
// Movement tracking for economy
var lastPlayerX = 0;
var lastPlayerY = 0;
var totalMovementDistance = storage.totalMovementDistance || 0;
var lastSaltPriceUpdate = storage.lastSaltPriceUpdate || 0;
var lastApplePriceUpdate = storage.lastApplePriceUpdate || 0;
var lastSpeeditemPriceUpdate = storage.lastSpeeditemPriceUpdate || 0;
var lastSwordPriceUpdate = storage.lastSwordPriceUpdate || 0;
// Map data - 12 interconnected maps
var mapData = [
// Map 0
{
roads: [{
x: 200,
y: 400
}, {
x: 300,
y: 400
}, {
x: 400,
y: 400
}, {
x: 500,
y: 400
}, {
x: 600,
y: 400
}, {
x: 700,
y: 400
}, {
x: 800,
y: 500
}, {
x: 900,
y: 600
}, {
x: 1000,
y: 700
}, {
x: 1100,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1400,
y: 1100
}, {
x: 1500,
y: 1200
}, {
x: 1600,
y: 1300
}, {
x: 1700,
y: 1400
}, {
x: 1800,
y: 1500
}, {
x: 1900,
y: 1500
}, {
x: 2000,
y: 1500
}, {
x: 1800,
y: 1600
}, {
x: 1800,
y: 1700
}, {
x: 1800,
y: 1800
}, {
x: 1800,
y: 1900
}, {
x: 1800,
y: 2000
}, {
x: 1800,
y: 2100
}, {
x: 1800,
y: 2200
}, {
x: 1800,
y: 2300
}, {
x: 1800,
y: 2400
}, {
x: 1800,
y: 2500
}, {
x: 1800,
y: 2600
}, {
x: 1800,
y: 2700
}],
mountains: [{
x: 150,
y: 200
}, {
x: 250,
y: 150
}, {
x: 350,
y: 180
}, {
x: 450,
y: 220
}, {
x: 550,
y: 180
}, {
x: 650,
y: 200
}, {
x: 750,
y: 250
}, {
x: 850,
y: 300
}, {
x: 950,
y: 350
}, {
x: 1050,
y: 400
}, {
x: 1150,
y: 450
}, {
x: 1250,
y: 500
}, {
x: 1350,
y: 550
}, {
x: 1450,
y: 600
}, {
x: 1550,
y: 650
}, {
x: 1650,
y: 700
}],
passages: [{
x: 2000,
y: 1500,
targetMap: 1,
targetX: 100,
targetY: 1500
}, {
x: 1800,
y: 2700,
targetMap: 3,
targetX: 1800,
targetY: 100
}],
startX: 200,
startY: 400
},
// Map 1
{
roads: [{
x: 100,
y: 1500
}, {
x: 200,
y: 1500
}, {
x: 300,
y: 1500
}, {
x: 400,
y: 1400
}, {
x: 500,
y: 1300
}, {
x: 600,
y: 1200
}, {
x: 700,
y: 1100
}, {
x: 800,
y: 1000
}, {
x: 900,
y: 900
}, {
x: 1000,
y: 800
}, {
x: 1100,
y: 700
}, {
x: 1200,
y: 600
}, {
x: 1300,
y: 500
}, {
x: 1400,
y: 400
}, {
x: 1500,
y: 300
}, {
x: 1600,
y: 200
}, {
x: 48,
y: 1500
}, {
x: 1600,
y: 150
}, {
x: 1600,
y: 100
}, {
x: 1600,
y: 48
}],
mountains: [{
x: 200,
y: 1700
}, {
x: 300,
y: 1800
}, {
x: 400,
y: 1700
}, {
x: 500,
y: 1600
}, {
x: 600,
y: 1500
}, {
x: 700,
y: 1400
}, {
x: 800,
y: 1300
}, {
x: 900,
y: 1200
}, {
x: 1000,
y: 1100
}, {
x: 1100,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1300,
y: 800
}],
passages: [{
x: 100,
y: 1500,
targetMap: 0,
targetX: 2000,
targetY: 1500
}, {
x: 1600,
y: 100,
targetMap: 2,
targetX: 1600,
targetY: 2700
}],
startX: 100,
startY: 1500
},
// Map 2
{
roads: [{
x: 1600,
y: 2700
}, {
x: 1600,
y: 2600
}, {
x: 1600,
y: 2500
}, {
x: 1600,
y: 2400
}, {
x: 1600,
y: 2300
}, {
x: 1600,
y: 2200
}, {
x: 1600,
y: 2100
}, {
x: 1600,
y: 2000
}, {
x: 1600,
y: 1900
}, {
x: 1600,
y: 1800
}, {
x: 1600,
y: 1700
}, {
x: 1600,
y: 1600
}, {
x: 1600,
y: 1500
}, {
x: 1600,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1600,
y: 1200
}],
mountains: [{
x: 1400,
y: 2600
}, {
x: 1500,
y: 2500
}, {
x: 1700,
y: 2500
}, {
x: 1800,
y: 2600
}, {
x: 1400,
y: 2400
}, {
x: 1800,
y: 2400
}, {
x: 1400,
y: 2200
}, {
x: 1800,
y: 2200
}, {
x: 1400,
y: 2000
}, {
x: 1800,
y: 2000
}, {
x: 1400,
y: 1800
}, {
x: 1800,
y: 1800
}],
passages: [{
x: 1600,
y: 2700,
targetMap: 1,
targetX: 1600,
targetY: 100
}, {
x: 1600,
y: 1200,
targetMap: 4,
targetX: 1600,
targetY: 2350
}],
startX: 1600,
startY: 2700
},
// Map 3
{
roads: [{
x: 1800,
y: 100
}, {
x: 1700,
y: 200
}, {
x: 1600,
y: 300
}, {
x: 1500,
y: 400
}, {
x: 1400,
y: 500
}, {
x: 1300,
y: 600
}, {
x: 1200,
y: 700
}, {
x: 1100,
y: 800
}, {
x: 1000,
y: 900
}, {
x: 900,
y: 1000
}, {
x: 800,
y: 1100
}, {
x: 700,
y: 1200
}, {
x: 600,
y: 1300
}, {
x: 500,
y: 1400
}, {
x: 400,
y: 1500
}, {
x: 300,
y: 1600
}, {
x: 1800,
y: 48
}, {
x: 250,
y: 1600
}, {
x: 200,
y: 1600
}],
mountains: [{
x: 1900,
y: 200
}, {
x: 1800,
y: 300
}, {
x: 1700,
y: 400
}, {
x: 1600,
y: 500
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 1000
}, {
x: 1000,
y: 1100
}, {
x: 900,
y: 1200
}, {
x: 800,
y: 1300
}],
passages: [{
x: 1800,
y: 100,
targetMap: 0,
targetX: 1800,
targetY: 2700
}, {
x: 200,
y: 1600,
targetMap: 5,
targetX: 1900,
targetY: 1600
}],
startX: 1800,
startY: 100
},
// Map 4
{
roads: [{
x: 1600,
y: 2350
}, {
x: 1500,
y: 2250
}, {
x: 1400,
y: 2150
}, {
x: 1300,
y: 2050
}, {
x: 1200,
y: 1950
}, {
x: 1100,
y: 1850
}, {
x: 1000,
y: 1750
}, {
x: 900,
y: 1650
}, {
x: 800,
y: 1550
}, {
x: 700,
y: 1450
}, {
x: 600,
y: 1350
}, {
x: 500,
y: 1250
}],
mountains: [{
x: 1700,
y: 2700
}, {
x: 1600,
y: 2800
}, {
x: 1500,
y: 2700
}, {
x: 1400,
y: 2600
}, {
x: 1300,
y: 2500
}, {
x: 1200,
y: 2400
}, {
x: 1100,
y: 2300
}, {
x: 1000,
y: 2200
}],
passages: [{
x: 1600,
y: 2350,
targetMap: 2,
targetX: 1600,
targetY: 1200
}, {
x: 500,
y: 1250,
targetMap: 6,
targetX: 1800,
targetY: 1500
}],
startX: 1600,
startY: 2350
},
// Map 5
{
roads: [{
x: 1900,
y: 1600
}, {
x: 1800,
y: 1600
}, {
x: 1700,
y: 1600
}, {
x: 1600,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 1400,
y: 1600
}, {
x: 1300,
y: 1600
}, {
x: 1200,
y: 1600
}, {
x: 1100,
y: 1600
}, {
x: 1000,
y: 1600
}, {
x: 900,
y: 1600
}, {
x: 800,
y: 1600
}, {
x: 750,
y: 1600
}, {
x: 700,
y: 1600
}, {
x: 1950,
y: 1600
}, {
x: 2000,
y: 1600
}],
mountains: [{
x: 1900,
y: 1400
}, {
x: 1800,
y: 1400
}, {
x: 1900,
y: 1800
}, {
x: 1800,
y: 1800
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1400
}, {
x: 1700,
y: 1800
}, {
x: 1600,
y: 1800
}],
passages: [{
x: 2000,
y: 1600,
targetMap: 3,
targetX: 200,
targetY: 1600
}, {
x: 700,
y: 1600,
targetMap: 7,
targetX: 1400,
targetY: 1600
}],
startX: 1900,
startY: 1600
},
// Map 6
{
roads: [{
x: 1800,
y: 1500
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1500,
y: 1200
}, {
x: 1400,
y: 1100
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 800
}, {
x: 1000,
y: 700
}, {
x: 900,
y: 600
}, {
x: 800,
y: 500
}, {
x: 700,
y: 400
}, {
x: 1850,
y: 1500
}, {
x: 1900,
y: 1500
}, {
x: 1950,
y: 1500
}, {
x: 2000,
y: 1500
}, {
x: 650,
y: 400
}, {
x: 600,
y: 400
}],
mountains: [{
x: 1900,
y: 1600
}, {
x: 1800,
y: 1700
}, {
x: 1700,
y: 1600
}, {
x: 1600,
y: 1500
}, {
x: 1500,
y: 1400
}, {
x: 1400,
y: 1300
}, {
x: 1300,
y: 1200
}, {
x: 1200,
y: 1100
}],
passages: [{
x: 2000,
y: 1500,
targetMap: 4,
targetX: 500,
targetY: 1250
}, {
x: 600,
y: 400,
targetMap: 8,
targetX: 1500,
targetY: 2300
}],
startX: 1800,
startY: 1500
},
// Map 7
{
roads: [{
x: 1400,
y: 1600
}, {
x: 1300,
y: 1500
}, {
x: 1200,
y: 1400
}, {
x: 1100,
y: 1300
}, {
x: 1000,
y: 1200
}, {
x: 900,
y: 1100
}, {
x: 800,
y: 1000
}, {
x: 700,
y: 900
}, {
x: 600,
y: 800
}, {
x: 500,
y: 700
}, {
x: 400,
y: 600
}, {
x: 300,
y: 500
}, {
x: 1450,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 250,
y: 500
}, {
x: 200,
y: 500
}],
mountains: [{
x: 1500,
y: 1700
}, {
x: 1400,
y: 1800
}, {
x: 1300,
y: 1700
}, {
x: 1200,
y: 1600
}, {
x: 1100,
y: 1500
}, {
x: 1000,
y: 1400
}, {
x: 900,
y: 1300
}, {
x: 800,
y: 1200
}],
passages: [{
x: 1500,
y: 1600,
targetMap: 5,
targetX: 700,
targetY: 1600
}, {
x: 200,
y: 500,
targetMap: 9,
targetX: 1800,
targetY: 500
}],
startX: 1400,
startY: 1600
},
// Map 8
{
roads: [{
x: 1500,
y: 2300
}, {
x: 1400,
y: 2200
}, {
x: 1300,
y: 2100
}, {
x: 1200,
y: 2000
}, {
x: 1100,
y: 1900
}, {
x: 1000,
y: 1800
}, {
x: 900,
y: 1700
}, {
x: 800,
y: 1600
}, {
x: 700,
y: 1500
}, {
x: 600,
y: 1400
}, {
x: 500,
y: 1300
}, {
x: 400,
y: 1200
}, {
x: 1500,
y: 2400
}, {
x: 1500,
y: 2500
}, {
x: 1500,
y: 2600
}, {
x: 1500,
y: 2700
}, {
x: 1500,
y: 2732
}, {
x: 350,
y: 1200
}, {
x: 300,
y: 1200
}],
mountains: [{
x: 1600,
y: 2400
}, {
x: 1500,
y: 2500
}, {
x: 1400,
y: 2400
}, {
x: 1300,
y: 2300
}, {
x: 1200,
y: 2200
}, {
x: 1100,
y: 2100
}, {
x: 1000,
y: 2000
}, {
x: 900,
y: 1900
}],
passages: [{
x: 1500,
y: 2700,
targetMap: 6,
targetX: 600,
targetY: 400
}, {
x: 300,
y: 1200,
targetMap: 10,
targetX: 1700,
targetY: 1200
}],
startX: 1500,
startY: 2300
},
// Map 9
{
roads: [{
x: 1800,
y: 500
}, {
x: 1700,
y: 600
}, {
x: 1600,
y: 700
}, {
x: 1500,
y: 800
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 1100
}, {
x: 1100,
y: 1200
}, {
x: 1000,
y: 1300
}, {
x: 900,
y: 1400
}, {
x: 800,
y: 1500
}, {
x: 700,
y: 1600
}, {
x: 1850,
y: 500
}, {
x: 1900,
y: 500
}, {
x: 1950,
y: 500
}, {
x: 2000,
y: 500
}, {
x: 900,
y: 1300
}, {
x: 800,
y: 1300
}, {
x: 700,
y: 1300
}, {
x: 600,
y: 1300
}, {
x: 550,
y: 1300
}, {
x: 500,
y: 1300
}],
mountains: [{
x: 1900,
y: 400
}, {
x: 1800,
y: 300
}, {
x: 1700,
y: 400
}, {
x: 1600,
y: 500
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}],
passages: [{
x: 2000,
y: 500,
targetMap: 7,
targetX: 200,
targetY: 500
}, {
x: 500,
y: 1300,
targetMap: 11,
targetX: 1500,
targetY: 800
}],
startX: 1800,
startY: 500
},
// Map 10
{
roads: [{
x: 1700,
y: 1200
}, {
x: 1600,
y: 1100
}, {
x: 1500,
y: 1000
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 700
}, {
x: 1100,
y: 600
}, {
x: 1000,
y: 500
}, {
x: 900,
y: 400
}, {
x: 800,
y: 300
}, {
x: 700,
y: 200
}, {
x: 600,
y: 100
}, {
x: 1750,
y: 1200
}, {
x: 1800,
y: 1200
}, {
x: 600,
y: 75
}, {
x: 600,
y: 48
}],
mountains: [{
x: 1800,
y: 1300
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1500,
y: 1200
}, {
x: 1400,
y: 1100
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 800
}],
passages: [{
x: 1795,
y: 1260,
targetMap: 8,
targetX: 300,
targetY: 1200
}, {
x: 600,
y: 100,
targetMap: 11,
targetX: 600,
targetY: 2700
}],
startX: 1700,
startY: 1200
},
// Map 11
{
roads: [{
x: 1500,
y: 800
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 1100
}, {
x: 1100,
y: 1200
}, {
x: 1000,
y: 1300
}, {
x: 900,
y: 1400
}, {
x: 800,
y: 1500
}, {
x: 700,
y: 1600
}, {
x: 600,
y: 1700
}, {
x: 600,
y: 1800
}, {
x: 600,
y: 1900
}, {
x: 600,
y: 2000
}, {
x: 600,
y: 2100
}, {
x: 600,
y: 2200
}, {
x: 600,
y: 2300
}, {
x: 600,
y: 2400
}, {
x: 600,
y: 2500
}, {
x: 600,
y: 2600
}, {
x: 1500,
y: 750
}, {
x: 1500,
y: 700
}, {
x: 600,
y: 2650
}, {
x: 600,
y: 2700
}, {
x: 600,
y: 2732
}],
mountains: [{
x: 1600,
y: 700
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 1000
}, {
x: 1000,
y: 1100
}, {
x: 900,
y: 1200
}, {
x: 500,
y: 1700
}, {
x: 700,
y: 1700
}, {
x: 500,
y: 1900
}, {
x: 700,
y: 1900
}],
passages: [{
x: 1500,
y: 700,
targetMap: 9,
targetX: 600,
targetY: 1600
}, {
x: 600,
y: 2700,
targetMap: 10,
targetX: 600,
targetY: 100
}],
startX: 1500,
startY: 800
}];
var arBackground = null;
function loadMap(mapIndex) {
// Clear existing elements
for (var i = 0; i < roads.length; i++) {
roads[i].destroy();
}
// Mountain cleanup removed
for (var i = 0; i < passages.length; i++) {
passages[i].destroy();
}
// Clean up existing center marker
if (centerMarker) {
centerMarker.destroy();
centerMarker = null;
}
// Clean up existing city marker
if (city) {
city.destroy();
city = null;
}
// Clean up existing AR background
if (arBackground) {
arBackground.destroy();
arBackground = null;
}
roads = [];
mountains = [];
passages = [];
var map = mapData[mapIndex];
// Add AR background only for Ancient Ruins (map 6)
if (mapIndex === 6) {
arBackground = game.addChild(LK.getAsset('AR', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
x: 1024,
y: 1366
}));
}
// Add CP background only for Central Plains (map 4)
if (mapIndex === 4) {
arBackground = game.addChild(LK.getAsset('CP', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
x: 1024,
y: 1366
}));
}
// Add SR background only for Southern Ridge (map 2)
if (mapIndex === 2) {
arBackground = game.addChild(LK.getAsset('Sr', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
x: 1024,
y: 1366
}));
}
// Add EV background only for Eastern Valleys (map 1)
if (mapIndex === 1) {
arBackground = game.addChild(LK.getAsset('Ev', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add NH background only for Northern Highlands (map 0)
if (mapIndex === 0) {
arBackground = game.addChild(LK.getAsset('Nh', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add WP background only for Western Peaks (map 3)
if (mapIndex === 3) {
arBackground = game.addChild(LK.getAsset('wp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7,
scaleY: 9,
x: 1024,
y: 1366
}));
}
// Add MW background only for Mystic Woods (map 5)
if (mapIndex === 5) {
arBackground = game.addChild(LK.getAsset('mw', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add DS background only for Desert Sands (map 7)
if (mapIndex === 7) {
arBackground = game.addChild(LK.getAsset('ds', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add CC background only for Coastal Cliffs (map 9)
if (mapIndex === 9) {
arBackground = game.addChild(LK.getAsset('cc', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Add SG background only for Sacred Grove (map 11)
if (mapIndex === 11) {
arBackground = game.addChild(LK.getAsset('sg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add MP background only for Mountain Pass (map 10)
if (mapIndex === 10) {
arBackground = game.addChild(LK.getAsset('mp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Add FW background only for Frozen Wastes (map 8)
if (mapIndex === 8) {
arBackground = game.addChild(LK.getAsset('fw', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Create roads
for (var i = 0; i < map.roads.length; i++) {
var road = game.addChild(new Road());
road.x = map.roads[i].x;
road.y = map.roads[i].y;
roads.push(road);
}
// Mountains removed from display
// Create passages
for (var i = 0; i < map.passages.length; i++) {
var passage = game.addChild(new Passage());
passage.x = map.passages[i].x;
passage.y = map.passages[i].y;
passage.targetMap = map.passages[i].targetMap;
passage.targetX = map.passages[i].targetX;
passage.targetY = map.passages[i].targetY;
passages.push(passage);
}
// Set character position
if (character.x === 0 && character.y === 0) {
character.x = map.startX;
character.y = map.startY;
}
// Find and mark the center road point
var centerRoad = findCenterRoad();
if (centerRoad) {
centerMarker = game.addChild(new CenterMarker());
centerMarker.x = centerRoad.x;
centerMarker.y = centerRoad.y;
}
// Add city marker at calculated position
var cityPosition = findCityPosition();
city = game.addChild(new City());
city.x = cityPosition.x;
city.y = cityPosition.y;
// Create connecting road between center marker and city
if (centerMarker && city) {
var connectionRoads = createConnectionRoad(centerMarker.x, centerMarker.y, city.x, city.y);
for (var i = 0; i < connectionRoads.length; i++) {
roads.push(connectionRoads[i]);
}
}
// Bring city to front so it appears above roads
if (city) {
game.removeChild(city);
game.addChild(city);
}
// Bring character to front so it appears above roads
game.removeChild(character);
game.addChild(character);
// Reset city visit tracking for new map
hasVisitedCity = false;
lastCityDistance = Infinity;
if (isMarketOpen) {
closeMarketScreen();
}
// Generate new market slots for this map
if (!marketSlots) {
marketSlots = [];
}
// Refresh market inventories when changing regions
generateMarketSlots();
generateSellSlots();
}
function findNearestRoad(x, y) {
var nearestRoad = null;
var minDistance = Infinity;
for (var i = 0; i < roads.length; i++) {
var road = roads[i];
var dx = x - road.x;
var dy = y - road.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
nearestRoad = road;
}
}
return nearestRoad;
}
function findCityPosition() {
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
var mirrorPoints = [];
var map = mapData[currentMap];
// Calculate mirror coordinates for each passage
for (var i = 0; i < map.passages.length; i++) {
var passage = map.passages[i];
var mirrorX = 2 * centerX - passage.x;
var mirrorY = 2 * centerY - passage.y;
mirrorPoints.push({
x: mirrorX,
y: mirrorY
});
}
// Find the center of all mirror points
if (mirrorPoints.length === 0) {
return {
x: centerX,
y: centerY
}; // Default to screen center if no passages
}
var totalX = 0;
var totalY = 0;
for (var i = 0; i < mirrorPoints.length; i++) {
totalX += mirrorPoints[i].x;
totalY += mirrorPoints[i].y;
}
return {
x: totalX / mirrorPoints.length,
y: totalY / mirrorPoints.length
};
}
function createConnectionRoad(startX, startY, endX, endY) {
var connectionRoads = [];
var dx = endX - startX;
var dy = endY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
var steps = Math.floor(distance / 100); // Create road points every 100 pixels
for (var i = 1; i <= steps; i++) {
var progress = i / (steps + 1);
var roadX = startX + dx * progress;
var roadY = startY + dy * progress;
var road = game.addChild(new Road());
road.x = roadX;
road.y = roadY;
connectionRoads.push(road);
}
return connectionRoads;
}
function findCenterRoad() {
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
var centerRoad = null;
var minDistance = Infinity;
for (var i = 0; i < roads.length; i++) {
var road = roads[i];
var dx = centerX - road.x;
var dy = centerY - road.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
centerRoad = road;
}
}
return centerRoad;
}
function checkPassageCollision() {
for (var i = 0; i < passages.length; i++) {
var passage = passages[i];
var dx = character.x - passage.x;
var dy = character.y - passage.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 80) {
currentMap = passage.targetMap;
storage.currentMap = currentMap;
loadMap(currentMap);
// Find the 4th nearest road point to the target passage
var targetPassageX = passage.targetX;
var targetPassageY = passage.targetY;
var roadDistances = [];
// Calculate distances from target passage to all roads
for (var j = 0; j < roads.length; j++) {
var road = roads[j];
var rdx = targetPassageX - road.x;
var rdy = targetPassageY - road.y;
var roadDistance = Math.sqrt(rdx * rdx + rdy * rdy);
roadDistances.push({
road: road,
distance: roadDistance
});
}
// Sort roads by distance
roadDistances.sort(function (a, b) {
return a.distance - b.distance;
});
// Get the 4th nearest road (index 3), or closest available if less than 4 roads
var targetRoadIndex = Math.min(3, roadDistances.length - 1);
// Special case for Western Peaks left passage teleportation - use 5th nearest road for better positioning
if (currentMap === 5 && passage.targetX === 1900 && passage.targetY === 1600) {
targetRoadIndex = Math.min(4, roadDistances.length - 1);
}
// Special case for Sacred Grove to Coastal Cliffs teleportation - use 3rd nearest road
if (currentMap === 9 && passage.targetX === 600 && passage.targetY === 1600) {
targetRoadIndex = Math.min(2, roadDistances.length - 1);
}
var targetRoad = roadDistances[targetRoadIndex].road;
character.x = targetRoad.x;
character.y = targetRoad.y;
character.isMoving = false;
break;
}
}
}
// Initialize first map
loadMap(currentMap);
// Bring character to front so it appears above roads
game.removeChild(character);
game.addChild(character);
// Initialize economy system tracking
lastPlayerX = character.x;
lastPlayerY = character.y;
// Initialize market slots array to prevent undefined errors
var marketSlots = [];
var sellSlots = [];
// Slot probability pools for each city - initialized as global variable
var slotProbabilityPools = [
// Map 0 - Northern Highlands
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// 35% empty, 25% apple, 15% salt, 15% speeditem, 10% sword
// Map 1 - Eastern Valleys
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 2 - Southern Ridge
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 3 - Western Peaks
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 4 - Central Plains
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 5 - Mystic Woods
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 6 - Ancient Ruins
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 7 - Desert Sands
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 8 - Frozen Wastes
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 9 - Coastal Cliffs
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 10 - Mountain Pass
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 11 - Sacred Grove
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword']];
// Region names for each map
var regionNames = ['Northern Highlands', 'Eastern Valleys', 'Southern Ridge', 'Western Peaks', 'Central Plains', 'Mystic Woods', 'Ancient Ruins', 'Desert Sands', 'Frozen Wastes', 'Coastal Cliffs', 'Mountain Pass', 'Sacred Grove'];
// Map info display
var mapText = new Text2(regionNames[currentMap], {
size: 60,
fill: 0xFFFFFF
});
mapText.anchor.set(1, 1);
LK.gui.bottomRight.addChild(mapText);
// Gold display setup
goldIcon = LK.getAsset('gold', {
anchorX: 0,
anchorY: 0,
scaleX: 1.6,
scaleY: 1.6
});
goldIcon.x = 120;
goldIcon.y = 20;
LK.gui.topLeft.addChild(goldIcon);
goldText = new Text2(playerGold.toString(), {
size: 96,
fill: 0xFFD700
});
goldText.anchor.set(0, 0);
goldText.x = 280;
goldText.y = 50;
LK.gui.topLeft.addChild(goldText);
// Inventory button setup
var inventoryButton = LK.getAsset('bag', {
anchorX: 1,
anchorY: 0,
scaleX: 1.2,
scaleY: 1.2
});
inventoryButton.x = -20;
inventoryButton.y = 20;
LK.gui.topRight.addChild(inventoryButton);
// City market UI variables
var marketScreen = null;
var marketTitle = null;
var closeButton = null;
var isMarketOpen = false;
var lastCityDistance = Infinity;
var hasVisitedCity = false;
// Inventory UI variables
var inventoryScreen = null;
var isInventoryOpen = false;
var inventorySlots = [];
// Market mode variables
var marketMode = 'selection'; // 'selection', 'buy', 'sell'
var buyButton = null;
var sellButton = null;
// Player inventory system
var playerInventory = {
salt: storage.playerSaltCount || 0,
apple: storage.playerAppleCount || 0,
speeditem: storage.playerSpeeditemCount || 0,
sword: storage.playerSwordCount || 0
};
// Market slot system variables
// Slot refresh now happens on map change
function generateMarketSlots() {
// Clear existing slots
for (var i = 0; i < marketSlots.length; i++) {
if (marketSlots[i] && marketSlots[i].parent) {
marketSlots[i].parent.removeChild(marketSlots[i]);
}
}
marketSlots = [];
// Safety check for slotProbabilityPools existence
if (!slotProbabilityPools || !Array.isArray(slotProbabilityPools)) {
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// Get probability pool for current map
var probabilityPool = slotProbabilityPools[currentMap];
// Generate 6 slots
for (var i = 0; i < 6; i++) {
var slot = new TradeSlot();
// Random item from probability pool
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
slot.setItem(itemType);
marketSlots.push(slot);
}
}
function generateSellSlots() {
// Clear existing sell slots
// Safety check for sellSlots array existence
if (sellSlots && sellSlots.length > 0) {
for (var i = 0; i < sellSlots.length; i++) {
if (sellSlots[i] && sellSlots[i].parent) {
sellSlots[i].parent.removeChild(sellSlots[i]);
}
}
}
sellSlots = [];
// Safety check for slotProbabilityPools existence
if (!slotProbabilityPools || !Array.isArray(slotProbabilityPools)) {
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// Get probability pool for current map
var probabilityPool = slotProbabilityPools[currentMap];
// Generate 6 sell slots
for (var i = 0; i < 6; i++) {
var slot = new SellSlot();
// Random item from probability pool
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
slot.setItem(itemType);
sellSlots.push(slot);
}
}
function refreshMarketSlots() {
// Safety check for marketSlots array
if (!marketSlots) {
marketSlots = [];
generateMarketSlots();
return;
}
// Additional safety check for marketSlots length
if (marketSlots.length === 0) {
generateMarketSlots();
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// 10% chance to refresh each slot
var probabilityPool = slotProbabilityPools[currentMap];
for (var i = 0; i < marketSlots.length; i++) {
if (Math.random() < 0.1) {
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
marketSlots[i].setItem(itemType);
}
}
// Also refresh sell slots if they exist
if (sellSlots && sellSlots.length > 0) {
for (var i = 0; i < sellSlots.length; i++) {
if (Math.random() < 0.1) {
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
sellSlots[i].setItem(itemType);
}
}
}
}
function createMarketScreen() {
// Create market background container
marketScreen = new Container();
marketScreen.x = 0;
marketScreen.y = 0;
// Create market background using citytrade texture
var marketBg = LK.getAsset('citytrade', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
marketBg.x = 24;
marketBg.y = -34;
marketScreen.addChild(marketBg);
// Show mode selection buttons
if (marketMode === 'selection') {
// Create buy button
buyButton = LK.getAsset('buybuton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
buyButton.x = -150;
buyButton.y = 0;
marketScreen.addChild(buyButton);
// Create sell button
sellButton = LK.getAsset('sellbuton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
sellButton.x = 150;
sellButton.y = 0;
marketScreen.addChild(sellButton);
// Add button functionality
buyButton.down = function () {
marketMode = 'buy';
showBuyMode();
};
sellButton.down = function () {
marketMode = 'sell';
showSellMode();
};
} else if (marketMode === 'buy') {
showBuyMode();
} else if (marketMode === 'sell') {
showSellMode();
}
// Create market title
marketTitle = new Text2(regionNames[currentMap] + ' Market', {
size: 77,
fill: 0xFFFFFF
});
marketTitle.anchor.set(0.5, 0);
marketTitle.x = 24;
marketTitle.y = -490;
marketScreen.addChild(marketTitle);
// Create close button using xbutton texture
closeButton = LK.getAsset('xbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
closeButton.x = 556;
closeButton.y = -680;
marketScreen.addChild(closeButton);
// Add close button functionality
closeButton.down = function () {
closeMarketScreen();
};
LK.gui.center.addChild(marketScreen);
isMarketOpen = true;
}
function showBuyMode() {
// Clear mode selection buttons
if (buyButton) {
marketScreen.removeChild(buyButton);
buyButton = null;
}
if (sellButton) {
marketScreen.removeChild(sellButton);
sellButton = null;
}
// Generate market slots if they don't exist
if (marketSlots.length === 0) {
generateMarketSlots();
}
// Position and add buy slots to market screen (2 rows, 3 columns)
var slotStartX = -190;
var slotStartY = -180;
var slotSpacingX = 220;
var slotSpacingY = 210;
for (var i = 0; i < marketSlots.length; i++) {
var slot = marketSlots[i];
var row = Math.floor(i / 3);
var col = i % 3;
slot.x = slotStartX + col * slotSpacingX;
slot.y = slotStartY + row * slotSpacingY;
// Move top 3 slots (first row) 70 pixels up
if (row === 0) {
slot.y -= 70;
}
marketScreen.addChild(slot);
}
}
function showSellMode() {
// Clear mode selection buttons
if (buyButton) {
marketScreen.removeChild(buyButton);
buyButton = null;
}
if (sellButton) {
marketScreen.removeChild(sellButton);
sellButton = null;
}
// Generate sell slots if they don't exist
if (sellSlots.length === 0) {
generateSellSlots();
}
// Position and add sell slots to market screen (2 rows, 3 columns)
var slotStartX = -190;
var slotStartY = -180;
var slotSpacingX = 220;
var slotSpacingY = 210;
for (var i = 0; i < sellSlots.length; i++) {
var slot = sellSlots[i];
var row = Math.floor(i / 3);
var col = i % 3;
slot.x = slotStartX + col * slotSpacingX;
slot.y = slotStartY + row * slotSpacingY;
// Move top 3 slots (first row) 70 pixels up
if (row === 0) {
slot.y -= 70;
}
marketScreen.addChild(slot);
}
}
function closeMarketScreen() {
if (marketScreen) {
LK.gui.center.removeChild(marketScreen);
marketScreen = null;
marketTitle = null;
closeButton = null;
buyButton = null;
sellButton = null;
isMarketOpen = false;
marketMode = 'selection'; // Reset to selection mode
}
}
function checkCityProximity() {
if (!city) {
return;
}
var dx = character.x - city.x;
var dy = character.y - city.y;
var currentDistance = Math.sqrt(dx * dx + dy * dy);
// Check if entering city range (distance < 100)
if (lastCityDistance >= 100 && currentDistance < 100) {
// Just entered city - show market if not already visited
if (!hasVisitedCity && !isMarketOpen) {
createMarketScreen();
hasVisitedCity = true;
}
}
// Check if leaving city range (distance > 150)
if (lastCityDistance <= 150 && currentDistance > 150) {
// Left city area - reset visit flag for next entry
hasVisitedCity = false;
if (isMarketOpen) {
closeMarketScreen();
}
}
lastCityDistance = currentDistance;
}
game.down = function (x, y, obj) {
// Prevent movement when market or inventory is open
if (isMarketOpen || isInventoryOpen) {
return;
}
var nearestRoad = findNearestRoad(x, y);
if (nearestRoad) {
character.moveTo(nearestRoad.x, nearestRoad.y);
}
};
function updateGoldDisplay() {
if (goldText) {
goldText.setText(playerGold.toString());
storage.playerGold = Math.round(playerGold * 10) / 10;
}
}
function updateEconomySystem() {
// Track movement distance
var dx = character.x - lastPlayerX;
var dy = character.y - lastPlayerY;
var movementThisFrame = Math.sqrt(dx * dx + dy * dy);
if (movementThisFrame > 0) {
totalMovementDistance += movementThisFrame;
// Salt price update every 5000 pixels
var saltDistanceThreshold = lastSaltPriceUpdate + 5000;
if (totalMovementDistance >= saltDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (7%) or decrease (6%)
if (Math.random() < 0.5) {
saltCurrentPrice = Math.round(saltCurrentPrice * 1.07 * 10) / 10; // 7% increase
} else {
saltCurrentPrice = Math.round(saltCurrentPrice * 0.94 * 10) / 10; // 6% decrease
}
}
lastSaltPriceUpdate = totalMovementDistance;
}
// Apple price update every 500 pixels
var appleDistanceThreshold = lastApplePriceUpdate + 500;
if (totalMovementDistance >= appleDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (+1) or decrease (-1)
if (Math.random() < 0.5) {
appleCurrentPrice = Math.round((appleCurrentPrice + 1) * 10) / 10;
} else {
appleCurrentPrice = Math.round((appleCurrentPrice - 1) * 10) / 10;
}
// Apply price limits for apple (5-25)
if (appleCurrentPrice < 5) {
appleCurrentPrice = 5;
}
if (appleCurrentPrice > 25) {
appleCurrentPrice = 25;
}
}
lastApplePriceUpdate = totalMovementDistance;
}
// Speeditem price update every 2000 pixels
var speeditemDistanceThreshold = lastSpeeditemPriceUpdate + 2000;
if (totalMovementDistance >= speeditemDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (5%) or decrease (5%)
if (Math.random() < 0.5) {
speeditemCurrentPrice = Math.round(speeditemCurrentPrice * 1.05 * 10) / 10; // 5% increase
} else {
speeditemCurrentPrice = Math.round(speeditemCurrentPrice * 0.95 * 10) / 10; // 5% decrease
}
}
lastSpeeditemPriceUpdate = totalMovementDistance;
}
// Sword price update every 2000 pixels
var swordDistanceThreshold = lastSwordPriceUpdate + 2000;
if (totalMovementDistance >= swordDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (5%) or decrease (5%)
if (Math.random() < 0.5) {
swordCurrentPrice = Math.round(swordCurrentPrice * 1.05 * 10) / 10; // 5% increase
} else {
swordCurrentPrice = Math.round(swordCurrentPrice * 0.95 * 10) / 10; // 5% decrease
}
}
lastSwordPriceUpdate = totalMovementDistance;
}
// Slot refresh now happens on map change instead of movement distance
// Save economy data to storage
storage.saltCurrentPrice = saltCurrentPrice;
storage.appleCurrentPrice = appleCurrentPrice;
storage.speeditemCurrentPrice = speeditemCurrentPrice;
storage.swordCurrentPrice = swordCurrentPrice;
storage.totalMovementDistance = totalMovementDistance;
storage.lastSaltPriceUpdate = lastSaltPriceUpdate;
storage.lastApplePriceUpdate = lastApplePriceUpdate;
storage.lastSpeeditemPriceUpdate = lastSpeeditemPriceUpdate;
storage.lastSwordPriceUpdate = lastSwordPriceUpdate;
}
// Update last position
lastPlayerX = character.x;
lastPlayerY = character.y;
}
// Add inventory button functionality
inventoryButton.down = function () {
if (!isInventoryOpen) {
createInventoryScreen();
} else {
closeInventoryScreen();
}
};
function createInventoryScreen() {
// Create inventory background container
inventoryScreen = new Container();
inventoryScreen.x = 0;
inventoryScreen.y = 0;
// Create inventory background using playerinventory texture
var inventoryBg = LK.getAsset('playerinventory', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
inventoryBg.x = 0;
inventoryBg.y = 0;
inventoryScreen.addChild(inventoryBg);
// Create 4x4 grid of inventory slots
inventorySlots = [];
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++) {
var slot = new InventorySlot();
// Position with 8px down offset and increased spacing: 30px margin, 120px slot size, 15px spacing
slot.x = -300 + 30 + col * 135 + 60; // -300 to center, +30 margin, +60 for slot center, 135px spacing (120+15)
slot.y = -300 + 30 + row * 135 + 60 + 8; // -300 to center, +30 margin, +60 for slot center, +8px down, 135px spacing
inventoryScreen.addChild(slot);
inventorySlots.push(slot);
}
}
// Create close button
var inventoryCloseButton = LK.getAsset('xbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
inventoryCloseButton.x = 330;
inventoryCloseButton.y = -330;
inventoryScreen.addChild(inventoryCloseButton);
// Add close button functionality
inventoryCloseButton.down = function () {
closeInventoryScreen();
};
LK.gui.center.addChild(inventoryScreen);
isInventoryOpen = true;
// Update inventory display
updateInventoryDisplay();
}
function closeInventoryScreen() {
if (inventoryScreen) {
LK.gui.center.removeChild(inventoryScreen);
inventoryScreen = null;
inventorySlots = [];
isInventoryOpen = false;
}
}
function updateInventoryDisplay() {
if (!inventorySlots || inventorySlots.length === 0) return;
// Clear all slots first
for (var i = 0; i < inventorySlots.length; i++) {
inventorySlots[i].setItem(null, 0);
}
// Fill slots with player inventory
var slotIndex = 0;
// Add salt items
if (playerInventory.salt > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('salt', playerInventory.salt);
slotIndex++;
}
// Add apple items
if (playerInventory.apple > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('apple', playerInventory.apple);
slotIndex++;
}
// Add speeditem items
if (playerInventory.speeditem > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('speeditem', playerInventory.speeditem);
slotIndex++;
}
// Add sword items
if (playerInventory.sword > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('sword', playerInventory.sword);
slotIndex++;
}
}
function addItemToInventory(itemType) {
// Find existing slot with same item type
for (var i = 0; i < inventorySlots.length; i++) {
if (inventorySlots[i].item === itemType) {
inventorySlots[i].addQuantity(1);
return;
}
}
// Find first empty slot
for (var i = 0; i < inventorySlots.length; i++) {
if (!inventorySlots[i].item) {
inventorySlots[i].setItem(itemType, 1);
return;
}
}
}
// Generate initial market slots after everything is initialized
generateMarketSlots();
generateSellSlots();
game.update = function () {
checkPassageCollision();
mapText.setText(regionNames[currentMap]);
checkCityProximity();
updateGoldDisplay();
updateEconomySystem();
};
mağara girişi. In-Game asset. 2d. High contrast. No shadows
ortaçağ atlı araba ve tüccar . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
aynısı arkaplansız
medieval X close button. In-Game asset. 2d. High contrast. No shadows
altın kesesi. In-Game asset. 2d. High contrast. No shadows
elma. In-Game asset. 2d. High contrast. No shadows
ortaçağ ticari tuz. In-Game asset. 2d. High contrast. No shadows
çivi ile duvara asılı hafif yıpranmış parşomen. In-Game asset. 2d. High contrast. No shadows
medieval envanter bag. In-Game asset. 2d. High contrast. No shadows
minecraft envaneri gibi kutucuklar sadece kutucuklar başka uı elementi yok. ortaçağ temasında bir çanta içi hissi vermeli dokusu . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bir ortaçağ eşyası bize hız veriyor ne olur bilmiyorum. In-Game asset. 2d. High contrast. No shadows
medieval sword. In-Game asset. 2d. High contrast. No shadows