/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Button = Container.expand(function (text, color, width, height) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
width: width || 300,
height: height || 120
});
buttonGraphics.tint = color || 0x27ae60;
var buttonText = new Text2(text, {
size: 32,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = 0;
buttonText.y = 0;
self.addChild(buttonText);
self.down = function (x, y, obj) {
buttonGraphics.scaleX = 0.9;
buttonGraphics.scaleY = 0.9;
};
self.up = function (x, y, obj) {
buttonGraphics.scaleX = 1.0;
buttonGraphics.scaleY = 1.0;
};
return self;
});
var Vehicle = Container.expand(function (carData, isMotorcycle, isVan) {
var self = Container.call(this);
self.carData = carData;
self.inspected = false;
self.repaired = false;
self.isMotorcycle = isMotorcycle || false;
self.isVan = isVan || false;
var assetPrefix = self.isVan ? 'van' : self.isMotorcycle ? 'moto' : 'car';
var assetSuffix = carData.condition === 'damaged' ? 'Damaged' : 'Offer';
var carGraphics = self.attachAsset(assetPrefix + assetSuffix, {
anchorX: 0.5,
anchorY: 0.5
});
var carText = new Text2(carData.make + ' ' + carData.model, {
size: 36,
fill: 0xFFFFFF
});
carText.anchor.set(0.5, 0.5);
carText.x = 0;
carText.y = -80;
self.addChild(carText);
var priceText = new Text2('$' + carData.price.toLocaleString(), {
size: 40,
fill: 0xFFFF00
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 0;
priceText.y = -40;
self.addChild(priceText);
var conditionText = new Text2(carData.condition + ' - ' + carData.mileage + 'k miles', {
size: 28,
fill: 0xFFFFFF
});
conditionText.anchor.set(0.5, 0.5);
conditionText.x = 0;
conditionText.y = 10;
self.addChild(conditionText);
self.updateDisplay = function () {
carGraphics.visible = false;
self.removeChild(carGraphics);
var assetPrefix = self.isVan ? 'van' : self.isMotorcycle ? 'moto' : 'car';
var assetType = assetPrefix + 'Offer';
if (self.carData.actualCondition === 'damaged' && !self.repaired) {
assetType = assetPrefix + 'Damaged';
} else if (self.repaired) {
assetType = assetPrefix + 'Repaired';
}
carGraphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
// Re-create and re-add text elements to ensure they are properly displayed
if (carText && carText.parent) {
self.removeChild(carText);
}
carText = new Text2(self.carData.make + ' ' + self.carData.model, {
size: 36,
fill: 0xFFFFFF
});
carText.anchor.set(0.5, 0.5);
carText.x = 0;
carText.y = -80;
self.addChild(carText);
if (priceText && priceText.parent) {
self.removeChild(priceText);
}
priceText = new Text2('$' + self.carData.price.toLocaleString(), {
size: 40,
fill: 0xFFFF00
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 0;
priceText.y = -40;
self.addChild(priceText);
if (conditionText && conditionText.parent) {
self.removeChild(conditionText);
}
// Use actual condition and mileage for display
var displayCondition = self.repaired ? 'good' : self.carData.actualCondition;
var displayMileage = self.carData.actualMileage || self.carData.mileage;
conditionText = new Text2(displayCondition + ' - ' + displayMileage + 'k miles', {
size: 28,
fill: 0xFFFFFF
});
conditionText.anchor.set(0.5, 0.5);
conditionText.x = 0;
conditionText.y = 10;
self.addChild(conditionText);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x34495e
});
/****
* Game Code
****/
// Game state variables
var playerMoney = storage.playerMoney || 50000;
var currentDay = storage.currentDay || 1;
var playerDebt = storage.playerDebt || 0;
var dailyInterestRate = 0.05; // 5% daily interest
var creditLimit = storage.creditLimit || 50000; // Maximum credit limit
var loanTakenDay = storage.loanTakenDay || 0; // Day when last loan was taken
var totalLoansOutstanding = storage.totalLoansOutstanding || 0; // Total amount in loans
var taxDebt = storage.taxDebt || 0;
var taxDueDate = storage.taxDueDate || 0;
var taxOverdueDate = storage.taxOverdueDate || 0;
var lastTaxDay = storage.lastTaxDay || 0;
var ownedVehicles = [];
var vehiclesInRepair = []; // Track vehicles currently being repaired
var motorcycleUnlocked = storage.motorcycleUnlocked || false;
var vanUnlocked = storage.vanUnlocked || false;
var soundEffectsEnabled = storage.soundEffectsEnabled !== undefined ? storage.soundEffectsEnabled : true;
var ownedMotorcycles = [];
var ownedVans = [];
var motorcyclesInRepair = []; // Track motorcycles currently being repaired
var vansInRepair = []; // Track vans currently being repaired
var dailyMotoOffers = [];
var vehicleType = 'cars'; // 'cars' or 'motorcycles'
// Load owned vehicles from storage
if (storage.vehicleCount) {
for (var i = 0; i < storage.vehicleCount; i++) {
ownedVehicles.push({
make: storage.vehicleMakes[i],
model: storage.vehicleModels[i],
condition: storage.vehicleConditions[i],
actualCondition: storage.vehicleActualConditions[i],
mileage: storage.vehicleMileages[i],
actualMileage: storage.vehicleActualMileages[i] || storage.vehicleMileages[i],
price: storage.vehiclePrices[i],
marketValue: storage.vehicleMarketValues[i],
sellerLying: storage.vehicleSellerLying[i],
id: storage.vehicleIds[i],
repaired: storage.vehicleRepaired[i],
inRepair: storage.vehicleInRepair ? storage.vehicleInRepair[i] : false,
repairCompletionDay: storage.vehicleRepairCompletionDay ? storage.vehicleRepairCompletionDay[i] : 0
});
}
}
// Load repair shop data
if (storage.vehiclesInRepairCount) {
for (var r = 0; r < storage.vehiclesInRepairCount; r++) {
vehiclesInRepair.push({
vehicleId: storage.repairVehicleIds[r],
completionDay: storage.repairCompletionDays[r],
repairDuration: storage.repairDurations[r]
});
}
}
// Load owned motorcycles from storage
if (storage.motorcycleCount) {
for (var m = 0; m < storage.motorcycleCount; m++) {
ownedMotorcycles.push({
make: storage.motorcycleMakes[m],
model: storage.motorcycleModels[m],
condition: storage.motorcycleConditions[m],
actualCondition: storage.motorcycleActualConditions[m],
mileage: storage.motorcycleMileages[m],
actualMileage: storage.motorcycleActualMileages[m] || storage.motorcycleMileages[m],
price: storage.motorcyclePrices[m],
marketValue: storage.motorcycleMarketValues[m],
sellerLying: storage.motorcycleSellerLying[m],
id: storage.motorcycleIds[m],
repaired: storage.motorcycleRepaired[m],
inRepair: storage.motorcycleInRepair ? storage.motorcycleInRepair[m] : false,
repairCompletionDay: storage.motorcycleRepairCompletionDay ? storage.motorcycleRepairCompletionDay[m] : 0
});
}
}
// Load motorcycle repair shop data
if (storage.motorcyclesInRepairCount) {
for (var mr = 0; mr < storage.motorcyclesInRepairCount; mr++) {
motorcyclesInRepair.push({
vehicleId: storage.repairMotoVehicleIds[mr],
completionDay: storage.repairMotoCompletionDays[mr],
repairDuration: storage.repairMotoDurations[mr]
});
}
}
// Load owned vans from storage
if (storage.vanCount) {
for (var v = 0; v < storage.vanCount; v++) {
ownedVans.push({
make: storage.vanMakes[v],
model: storage.vanModels[v],
condition: storage.vanConditions[v],
actualCondition: storage.vanActualConditions[v],
mileage: storage.vanMileages[v],
actualMileage: storage.vanActualMileages[v] || storage.vanMileages[v],
price: storage.vanPrices[v],
marketValue: storage.vanMarketValues[v],
sellerLying: storage.vanSellerLying[v],
id: storage.vanIds[v],
repaired: storage.vanRepaired[v],
inRepair: storage.vanInRepair ? storage.vanInRepair[v] : false,
repairCompletionDay: storage.vanRepairCompletionDay ? storage.vanRepairCompletionDay[v] : 0
});
}
}
// Load van repair shop data
if (storage.vansInRepairCount) {
for (var vr = 0; vr < storage.vansInRepairCount; vr++) {
vansInRepair.push({
vehicleId: storage.repairVanVehicleIds[vr],
completionDay: storage.repairVanCompletionDays[vr],
repairDuration: storage.repairVanDurations[vr]
});
}
}
var dailyOffers = [];
var selectedVehicle = null;
var gameState = 'daily_offers'; // 'daily_offers', 'vehicle_selected', 'owned_vehicles'
// Car data arrays
var carMakes = ['Toyota', 'Honda', 'Ford', 'Chevrolet', 'BMW', 'Mercedes', 'Audi', 'Nissan', 'Volkswagen', 'Hyundai'];
var carModels = ['Sedan', 'SUV', 'Coupe', 'Hatchback', 'Wagon', 'Convertible', 'Truck', 'Compact'];
var conditions = ['excellent', 'good', 'fair', 'poor', 'damaged'];
// Motorcycle data arrays
var motoMakes = ['Harley-Davidson', 'Yamaha', 'Honda', 'Kawasaki', 'Suzuki', 'Ducati', 'BMW', 'Triumph', 'Indian', 'KTM'];
var motoModels = ['Cruiser', 'Sport', 'Touring', 'Adventure', 'Naked', 'Chopper', 'Cafe Racer', 'Scooter'];
// Van data arrays
var vanMakes = ['Ford', 'Chevrolet', 'Mercedes', 'Nissan', 'Isuzu', 'Ram', 'Iveco', 'Volkswagen', 'Toyota', 'Peugeot'];
var vanModels = ['Transit', 'Express', 'Sprinter', 'ProMaster', 'NV200', 'Cargo Van', 'Panel Van', 'Box Truck'];
// UI Elements
var moneyText = new Text2('Money: $' + playerMoney.toLocaleString(), {
size: 50,
fill: 0x2ECC71
});
moneyText.anchor.set(0, 0);
moneyText.x = 120;
moneyText.y = 50;
LK.gui.topLeft.addChild(moneyText);
var dayText = new Text2('Day ' + currentDay, {
size: 50,
fill: 0xFFFFFF
});
dayText.anchor.set(1, 0);
dayText.x = 0;
dayText.y = 50;
LK.gui.topRight.addChild(dayText);
var debtText = new Text2('Debt: $' + playerDebt.toLocaleString(), {
size: 40,
fill: 0xe74c3c
});
debtText.anchor.set(0, 0);
debtText.x = 120;
debtText.y = 110;
LK.gui.topLeft.addChild(debtText);
var taxText = new Text2('Tax: $' + taxDebt.toLocaleString(), {
size: 40,
fill: 0xe74c3c
});
taxText.anchor.set(0, 0);
taxText.x = 120;
taxText.y = 170;
LK.gui.topLeft.addChild(taxText);
var titleText = new Text2('Car Dealer Tycoon', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 150;
game.addChild(titleText);
var stateText = new Text2('Daily Vehicle Offers', {
size: 50,
fill: 0xECF0F1
});
stateText.anchor.set(0.5, 0);
stateText.x = 2048 / 2;
stateText.y = 250;
game.addChild(stateText);
// Action buttons
var inspectButton = game.addChild(new Button('Inspect ($500)', 0xf39c12));
inspectButton.x = 2048 / 2 - 400;
inspectButton.y = 2200;
inspectButton.visible = false;
var buyButton = game.addChild(new Button('Buy Vehicle', 0x27ae60));
buyButton.x = 2048 / 2 - 150;
buyButton.y = 2200;
buyButton.visible = false;
var negotiateButton = game.addChild(new Button('Negotiate', 0x34495e));
negotiateButton.x = 2048 / 2 + 150;
negotiateButton.y = 2200;
negotiateButton.visible = false;
var repairButton = game.addChild(new Button('Repair (Dynamic)', 0xe67e22));
repairButton.x = 2048 / 2 - 150;
repairButton.y = 2200;
repairButton.visible = false;
var sellButton = game.addChild(new Button('Sell', 0x8e44ad));
sellButton.x = 2048 / 2 + 150;
sellButton.y = 2200;
sellButton.visible = false;
var nextDayButton = game.addChild(new Button('Next Day', 0x2c3e50, 400, 140));
nextDayButton.x = 2048 / 2;
nextDayButton.y = 2350;
var viewOwnedButton = game.addChild(new Button('View Owned Cars', 0x95a5a6));
viewOwnedButton.x = 2048 / 2;
viewOwnedButton.y = 2200;
var loanButton = game.addChild(new Button('Take Loan ($10,000)', 0x3498db));
loanButton.x = 2048 / 2 - 450;
loanButton.y = 2550;
var payDebtButton = game.addChild(new Button('Pay Debt', 0x27ae60));
payDebtButton.x = 2048 / 2 + 3;
payDebtButton.y = 2500;
var payTaxButton = game.addChild(new Button('Pay Tax', 0x27ae60));
payTaxButton.x = 2048 / 2 + 450;
payTaxButton.y = 2550;
var vehicleLocksButton = game.addChild(new Button('Vehicle Locks', 0x7f8c8d, 300, 120));
vehicleLocksButton.x = 1600;
vehicleLocksButton.y = 2400;
vehicleLocksButton.visible = !motorcycleUnlocked || !vanUnlocked;
var settingsButton = game.addChild(new Button('Settings', 0x7f8c8d, 300, 120));
settingsButton.x = -200;
settingsButton.y = 200;
LK.gui.topRight.addChild(settingsButton);
// Switch vehicle button removed - vehicles are now mixed together
// Vehicle display containers
var vehicleContainer = new Container();
vehicleContainer.x = 2048 / 2;
vehicleContainer.y = 800;
game.addChild(vehicleContainer);
var infoText = new Text2('', {
size: 32,
fill: 0xFFFFFF
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 2048 / 2;
infoText.y = 1800;
game.addChild(infoText);
// Generate random vehicle data
function generateRandomVehicle() {
var make = carMakes[Math.floor(Math.random() * carMakes.length)];
var model = carModels[Math.floor(Math.random() * carModels.length)];
var condition = conditions[Math.floor(Math.random() * conditions.length)];
var mileage = Math.floor(Math.random() * 200) + 20;
var basePrice = Math.floor(Math.random() * 40000) + 10000;
// Sellers may lie about condition - both ways
var actualCondition = condition;
var actualMileage = mileage;
var sellerLying = Math.random() < 0.4; // 40% chance of lying
if (sellerLying) {
// 70% chance they claim better condition, 30% chance they hide damage
if (Math.random() < 0.7 && condition !== 'damaged') {
// Claim better condition than actual
var betterConditions = conditions.slice(0, conditions.indexOf(condition));
if (betterConditions.length > 0) {
condition = betterConditions[Math.floor(Math.random() * betterConditions.length)];
}
} else {
// Hide damage - claim undamaged when actually damaged
var worseConditions = conditions.slice(conditions.indexOf(condition) + 1);
if (worseConditions.length > 0) {
actualCondition = worseConditions[Math.floor(Math.random() * worseConditions.length)];
// If actual condition becomes damaged, they claim it's not
if (actualCondition === 'damaged') {
condition = 'poor'; // They claim it's just poor condition
}
}
}
}
// 30% chance they also lie about mileage
if (Math.random() < 0.3) {
// They claim lower mileage than actual
var mileageReduction = Math.floor(Math.random() * 50) + 10; // 10-60k miles less
actualMileage = mileage + mileageReduction;
// Cap at reasonable maximum
if (actualMileage > 300) {
actualMileage = 300;
}
}
// Adjust price based on condition
var priceMultiplier = 1;
switch (actualCondition) {
case 'excellent':
priceMultiplier = 1.2;
break;
case 'good':
priceMultiplier = 1.0;
break;
case 'fair':
priceMultiplier = 0.8;
break;
case 'poor':
priceMultiplier = 0.6;
break;
case 'damaged':
priceMultiplier = 0.4;
break;
}
var price = Math.floor(basePrice * priceMultiplier * (1 - mileage / 300));
// 15% chance that this seller is a scammer
var isScammer = Math.random() < 0.15;
return {
make: make,
model: model,
condition: condition,
actualCondition: actualCondition,
mileage: mileage,
actualMileage: actualMileage,
price: price,
marketValue: Math.floor(price * 1.5),
sellerLying: sellerLying,
isScammer: isScammer,
id: Math.random().toString(36).substr(2, 9)
};
}
// Generate random motorcycle data
function generateRandomMotorcycle() {
var make = motoMakes[Math.floor(Math.random() * motoMakes.length)];
var model = motoModels[Math.floor(Math.random() * motoModels.length)];
var condition = conditions[Math.floor(Math.random() * conditions.length)];
var mileage = Math.floor(Math.random() * 150) + 10; // Lower mileage for motorcycles
var basePrice = Math.floor(Math.random() * 30000) + 5000; // Lower price range for motorcycles
// Sellers may lie about condition - both ways
var actualCondition = condition;
var actualMileage = mileage;
var sellerLying = Math.random() < 0.4; // 40% chance of lying
if (sellerLying) {
// 70% chance they claim better condition, 30% chance they hide damage
if (Math.random() < 0.7 && condition !== 'damaged') {
// Claim better condition than actual
var betterConditions = conditions.slice(0, conditions.indexOf(condition));
if (betterConditions.length > 0) {
condition = betterConditions[Math.floor(Math.random() * betterConditions.length)];
}
} else {
// Hide damage - claim undamaged when actually damaged
var worseConditions = conditions.slice(conditions.indexOf(condition) + 1);
if (worseConditions.length > 0) {
actualCondition = worseConditions[Math.floor(Math.random() * worseConditions.length)];
// If actual condition becomes damaged, they claim it's not
if (actualCondition === 'damaged') {
condition = 'poor'; // They claim it's just poor condition
}
}
}
}
// 30% chance they also lie about mileage
if (Math.random() < 0.3) {
// They claim lower mileage than actual
var mileageReduction = Math.floor(Math.random() * 40) + 10; // 10-50k miles less
actualMileage = mileage + mileageReduction;
// Cap at reasonable maximum
if (actualMileage > 200) {
actualMileage = 200;
}
}
// Adjust price based on condition
var priceMultiplier = 1;
switch (actualCondition) {
case 'excellent':
priceMultiplier = 1.2;
break;
case 'good':
priceMultiplier = 1.0;
break;
case 'fair':
priceMultiplier = 0.8;
break;
case 'poor':
priceMultiplier = 0.6;
break;
case 'damaged':
priceMultiplier = 0.4;
break;
}
var price = Math.floor(basePrice * priceMultiplier * (1 - mileage / 200));
// 15% chance that this seller is a scammer
var isScammer = Math.random() < 0.15;
return {
make: make,
model: model,
condition: condition,
actualCondition: actualCondition,
mileage: mileage,
actualMileage: actualMileage,
price: price,
marketValue: Math.floor(price * 1.5),
sellerLying: sellerLying,
isScammer: isScammer,
id: Math.random().toString(36).substr(2, 9)
};
}
// Generate random van data
function generateRandomVan() {
var make = vanMakes[Math.floor(Math.random() * vanMakes.length)];
var model = vanModels[Math.floor(Math.random() * vanModels.length)];
var condition = conditions[Math.floor(Math.random() * conditions.length)];
var mileage = Math.floor(Math.random() * 250) + 30; // Higher mileage for vans
var basePrice = Math.floor(Math.random() * 50000) + 20000; // Higher price range for vans
// Sellers may lie about condition - both ways
var actualCondition = condition;
var actualMileage = mileage;
var sellerLying = Math.random() < 0.4; // 40% chance of lying
if (sellerLying) {
// 70% chance they claim better condition, 30% chance they hide damage
if (Math.random() < 0.7 && condition !== 'damaged') {
// Claim better condition than actual
var betterConditions = conditions.slice(0, conditions.indexOf(condition));
if (betterConditions.length > 0) {
condition = betterConditions[Math.floor(Math.random() * betterConditions.length)];
}
} else {
// Hide damage - claim undamaged when actually damaged
var worseConditions = conditions.slice(conditions.indexOf(condition) + 1);
if (worseConditions.length > 0) {
actualCondition = worseConditions[Math.floor(Math.random() * worseConditions.length)];
// If actual condition becomes damaged, they claim it's not
if (actualCondition === 'damaged') {
condition = 'poor'; // They claim it's just poor condition
}
}
}
}
// 30% chance they also lie about mileage
if (Math.random() < 0.3) {
// They claim lower mileage than actual
var mileageReduction = Math.floor(Math.random() * 60) + 20; // 20-80k miles less
actualMileage = mileage + mileageReduction;
// Cap at reasonable maximum
if (actualMileage > 400) {
actualMileage = 400;
}
}
// Adjust price based on condition
var priceMultiplier = 1;
switch (actualCondition) {
case 'excellent':
priceMultiplier = 1.2;
break;
case 'good':
priceMultiplier = 1.0;
break;
case 'fair':
priceMultiplier = 0.8;
break;
case 'poor':
priceMultiplier = 0.6;
break;
case 'damaged':
priceMultiplier = 0.4;
break;
}
var price = Math.floor(basePrice * priceMultiplier * (1 - mileage / 400));
// 15% chance that this seller is a scammer
var isScammer = Math.random() < 0.15;
return {
make: make,
model: model,
condition: condition,
actualCondition: actualCondition,
mileage: mileage,
actualMileage: actualMileage,
price: price,
marketValue: Math.floor(price * 1.5),
sellerLying: sellerLying,
isScammer: isScammer,
id: Math.random().toString(36).substr(2, 9),
isVan: true
};
}
// Generate daily offers (mixed cars and motorcycles if unlocked)
function generateDailyOffers() {
dailyOffers = [];
var numOffers = Math.floor(Math.random() * 3) + 2;
for (var i = 0; i < numOffers; i++) {
var randomType = Math.random();
// If both motorcycles and vans are unlocked
if (motorcycleUnlocked && vanUnlocked) {
if (randomType < 0.3) {
// 30% chance for motorcycle
var motoOffer = generateRandomMotorcycle();
motoOffer.isMotorcycle = true;
dailyOffers.push(motoOffer);
} else if (randomType < 0.5) {
// 20% chance for van
var vanOffer = generateRandomVan();
vanOffer.isVan = true;
dailyOffers.push(vanOffer);
} else {
// 50% chance for car
dailyOffers.push(generateRandomVehicle());
}
} else if (motorcycleUnlocked && Math.random() < 0.4) {
// 40% chance for motorcycle
var motoOffer = generateRandomMotorcycle();
motoOffer.isMotorcycle = true; // Mark as motorcycle
dailyOffers.push(motoOffer);
} else if (vanUnlocked && Math.random() < 0.3) {
// 30% chance for van
var vanOffer = generateRandomVan();
vanOffer.isVan = true;
dailyOffers.push(vanOffer);
} else {
dailyOffers.push(generateRandomVehicle());
}
}
}
// Generate daily motorcycle offers
function generateDailyMotoOffers() {
dailyMotoOffers = [];
var numOffers = Math.floor(Math.random() * 3) + 2;
for (var i = 0; i < numOffers; i++) {
dailyMotoOffers.push(generateRandomMotorcycle());
}
}
// Display vehicles
function displayVehicles(vehicles) {
vehicleContainer.removeChildren();
for (var i = 0; i < vehicles.length; i++) {
var isMotorcycle = vehicles[i].isMotorcycle || false;
var isVan = vehicles[i].isVan || false;
var vehicle = new Vehicle(vehicles[i], isMotorcycle, isVan);
vehicle.x = i % 2 * 600 - 300;
vehicle.y = Math.floor(i / 2) * 380;
vehicleContainer.addChild(vehicle);
vehicle.vehicleData = vehicles[i];
vehicle.down = function (x, y, obj) {
selectedVehicle = obj.vehicleData;
updateUI();
};
// Add buy button for each vehicle
var vehicleBuyButton = new Button('Buy', 0x27ae60, 200, 80);
vehicleBuyButton.x = 0;
vehicleBuyButton.y = 150;
vehicle.addChild(vehicleBuyButton);
// Store vehicle data directly on the button using closure
(function (vehicleData, vehicleIndex) {
vehicleBuyButton.up = function (x, y, obj) {
if (vehicleData && playerMoney >= vehicleData.price) {
playerMoney -= vehicleData.price;
// Check if this seller is a scammer
if (vehicleData.isScammer) {
// Player loses money but gets no vehicle
infoText.setText('SCAMMED! The seller took your money and disappeared!\nYou lost $' + vehicleData.price.toLocaleString() + '!');
LK.effects.flashScreen(0xff0000, 1500); // Red flash for scam
} else {
// Normal purchase - Create a copy of the vehicle data for owned vehicles
var ownedVehicleData = {
make: vehicleData.make,
model: vehicleData.model,
condition: vehicleData.condition,
actualCondition: vehicleData.actualCondition,
mileage: vehicleData.mileage,
actualMileage: vehicleData.actualMileage,
price: vehicleData.price,
marketValue: vehicleData.marketValue,
sellerLying: vehicleData.sellerLying,
id: vehicleData.id,
repaired: false
};
if (vehicleData.isMotorcycle) {
ownedMotorcycles.push(ownedVehicleData);
} else if (vehicleData.isVan) {
ownedVans.push(ownedVehicleData);
} else {
ownedVehicles.push(ownedVehicleData);
}
if (soundEffectsEnabled) LK.getSound('purchase').play();
}
// Remove from daily offers in both cases
for (var j = 0; j < dailyOffers.length; j++) {
if (dailyOffers[j].id === vehicleData.id) {
dailyOffers.splice(j, 1);
break;
}
}
selectedVehicle = null;
updateMoneyDisplay();
displayVehicles(dailyOffers);
updateUI();
saveGame();
}
};
})(vehicles[i], i);
}
}
// Update UI based on game state
function updateUI() {
inspectButton.visible = false;
buyButton.visible = false;
negotiateButton.visible = false;
repairButton.visible = false;
sellButton.visible = false;
expertiseButton.visible = false;
if (gameState === 'daily_offers' && selectedVehicle) {
inspectButton.visible = true;
buyButton.visible = true;
negotiateButton.visible = true;
expertiseButton.visible = true;
// Calculate expertise cost based on vehicle price (15-20% of price)
var expertiseCost = Math.floor(selectedVehicle.price * (Math.random() * 0.05 + 0.15));
// Minimum expertise cost of $1000
if (expertiseCost < 1000) {
expertiseCost = 1000;
}
// Update expertise button text with dynamic cost
expertiseButton.children[0].setText('Expertise ($' + expertiseCost.toLocaleString() + ')');
infoText.setText('Selected: ' + selectedVehicle.make + ' ' + selectedVehicle.model + '\nCondition: ' + selectedVehicle.condition + '\nMileage: ' + selectedVehicle.mileage + 'k miles' + '\nPrice: $' + selectedVehicle.price.toLocaleString());
} else if (gameState === 'owned_vehicles' && selectedVehicle) {
if (selectedVehicle.actualCondition === 'damaged' && !selectedVehicle.repaired) {
repairButton.visible = true;
} else {
sellButton.visible = true;
}
infoText.setText('Owned: ' + selectedVehicle.make + ' ' + selectedVehicle.model + '\nCondition: ' + selectedVehicle.actualCondition + '\nMileage: ' + selectedVehicle.actualMileage + 'k miles' + '\nMarket Value: $' + selectedVehicle.marketValue.toLocaleString());
} else {
infoText.setText('Select a vehicle to view options');
}
}
// Add expertise button
var expertiseButton = game.addChild(new Button('Expertise (Dynamic)', 0x9b59b6));
expertiseButton.x = 2048 / 2 + 400;
expertiseButton.y = 2200;
expertiseButton.visible = false;
// Button event handlers
inspectButton.up = function (x, y, obj) {
if (selectedVehicle && playerMoney >= 500) {
playerMoney -= 500;
selectedVehicle.inspected = true;
selectedVehicle.condition = selectedVehicle.actualCondition;
if (soundEffectsEnabled) LK.getSound('inspect').play();
updateMoneyDisplay();
displayVehicles(dailyOffers);
updateUI();
if (selectedVehicle.sellerLying || selectedVehicle.mileage !== selectedVehicle.actualMileage) {
var lieText = 'Inspection revealed the seller was lying!\n';
if (selectedVehicle.sellerLying) {
lieText += 'Actual condition: ' + selectedVehicle.actualCondition + '\n';
}
if (selectedVehicle.mileage !== selectedVehicle.actualMileage) {
lieText += 'Actual mileage: ' + selectedVehicle.actualMileage + 'k miles';
}
infoText.setText(lieText);
} else {
infoText.setText('Inspection confirmed seller was honest.');
}
}
};
expertiseButton.up = function (x, y, obj) {
if (selectedVehicle) {
// Calculate expertise cost based on vehicle price (15-20% of price)
var expertiseCost = Math.floor(selectedVehicle.price * (Math.random() * 0.05 + 0.15));
// Minimum expertise cost of $1000
if (expertiseCost < 1000) {
expertiseCost = 1000;
}
if (playerMoney >= expertiseCost) {
playerMoney -= expertiseCost;
selectedVehicle.inspected = true;
selectedVehicle.condition = selectedVehicle.actualCondition;
if (soundEffectsEnabled) LK.getSound('inspect').play();
updateMoneyDisplay();
displayVehicles(dailyOffers);
updateUI();
var detailsText = 'EXPERTISE REPORT (Cost: $' + expertiseCost.toLocaleString() + '):\n';
detailsText += 'True Condition: ' + selectedVehicle.actualCondition + '\n';
detailsText += 'Claimed Mileage: ' + selectedVehicle.mileage + 'k miles\n';
detailsText += 'Actual Mileage: ' + selectedVehicle.actualMileage + 'k miles\n';
detailsText += 'Mileage Honest: ' + (selectedVehicle.mileage === selectedVehicle.actualMileage ? 'YES' : 'NO') + '\n';
detailsText += 'Seller Honest: ' + (selectedVehicle.sellerLying ? 'NO' : 'YES') + '\n';
detailsText += 'Market Value: $' + selectedVehicle.marketValue.toLocaleString() + '\n';
detailsText += 'Seller Trustworthy: ' + (selectedVehicle.isScammer ? 'SUSPICIOUS - POSSIBLE SCAMMER!' : 'YES') + '\n';
detailsText += 'Recommended Action: ';
if (selectedVehicle.isScammer) {
detailsText += 'AVOID - HIGH SCAM RISK!';
} else if (selectedVehicle.price < selectedVehicle.marketValue * 0.8) {
detailsText += 'BUY - Good Deal';
} else if (selectedVehicle.price > selectedVehicle.marketValue * 1.2) {
detailsText += 'AVOID - Overpriced';
} else {
detailsText += 'NEGOTIATE - Fair Price';
}
infoText.setText(detailsText);
} else {
infoText.setText('Not enough money! Expertise costs $' + expertiseCost.toLocaleString());
}
}
};
buyButton.up = function (x, y, obj) {
if (selectedVehicle && playerMoney >= selectedVehicle.price) {
playerMoney -= selectedVehicle.price;
// Check if this seller is a scammer
if (selectedVehicle.isScammer) {
// Player loses money but gets no vehicle
infoText.setText('SCAMMED! The seller took your money and disappeared!\nYou lost $' + selectedVehicle.price.toLocaleString() + '!');
LK.effects.flashScreen(0xff0000, 1500); // Red flash for scam
} else {
// Normal purchase
selectedVehicle.actualCondition = selectedVehicle.actualCondition;
if (selectedVehicle.isMotorcycle) {
ownedMotorcycles.push(selectedVehicle);
} else if (selectedVehicle.isVan) {
ownedVans.push(selectedVehicle);
} else {
ownedVehicles.push(selectedVehicle);
}
if (soundEffectsEnabled) LK.getSound('purchase').play();
}
// Remove from daily offers in both cases
for (var i = 0; i < dailyOffers.length; i++) {
if (dailyOffers[i].id === selectedVehicle.id) {
dailyOffers.splice(i, 1);
break;
}
}
selectedVehicle = null;
updateMoneyDisplay();
displayVehicles(dailyOffers);
updateUI();
saveGame();
}
};
negotiateButton.up = function (x, y, obj) {
if (selectedVehicle) {
var reduction = Math.floor(selectedVehicle.price * (Math.random() * 0.2 + 0.05));
selectedVehicle.price -= reduction;
displayVehicles(dailyOffers);
updateUI();
infoText.setText('Negotiated $' + reduction.toLocaleString() + ' off the price!');
}
};
repairButton.up = function (x, y, obj) {
if (selectedVehicle) {
// Calculate repair cost based on vehicle price (10-25% of price)
var repairCost = Math.floor(selectedVehicle.price * (Math.random() * 0.15 + 0.10));
// Minimum repair cost of $1000
if (repairCost < 1000) {
repairCost = 1000;
}
if (playerMoney >= repairCost) {
playerMoney -= repairCost;
// Calculate repair duration based on damage level
var repairDuration = 1; // Default 1 day
if (selectedVehicle.actualCondition === 'damaged') {
repairDuration = Math.floor(Math.random() * 3) + 1; // 1-3 days for damaged
} else if (selectedVehicle.actualCondition === 'poor') {
repairDuration = 1; // 1 day for poor
}
// Move vehicle to repair shop
var repairData = {
vehicleId: selectedVehicle.id,
completionDay: currentDay + repairDuration,
repairDuration: repairDuration
};
vehiclesInRepair.push(repairData);
// Mark vehicle as in repair but not completed
for (var k = 0; k < ownedVehicles.length; k++) {
if (ownedVehicles[k].id === selectedVehicle.id) {
ownedVehicles[k].inRepair = true;
ownedVehicles[k].repairCompletionDay = currentDay + repairDuration;
break;
}
}
if (soundEffectsEnabled) LK.getSound('repair').play();
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
infoText.setText('Vehicle sent to repair shop for $' + repairCost.toLocaleString() + '!\nWill be ready in ' + repairDuration + ' day(s).');
} else {
infoText.setText('Not enough money! Repair costs $' + repairCost.toLocaleString());
}
}
};
sellButton.up = function (x, y, obj) {
if (selectedVehicle) {
var salePrice = Math.floor(selectedVehicle.marketValue * (Math.random() * 0.3 + 0.8));
playerMoney += salePrice;
// Remove from owned vehicles
for (var i = 0; i < ownedVehicles.length; i++) {
if (ownedVehicles[i].id === selectedVehicle.id) {
ownedVehicles.splice(i, 1);
break;
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
infoText.setText('Sold for $' + salePrice.toLocaleString() + '!');
}
};
nextDayButton.up = function (x, y, obj) {
currentDay++;
selectedVehicle = null;
generateDailyOffers();
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
dayText.setText('Day ' + currentDay);
displayVehicles(dailyOffers);
updateUI();
// Add random daily expenses
var dailyExpenses = Math.floor(Math.random() * 5000) + 1000; // Between $1000-$6000
playerMoney -= dailyExpenses;
var expenseText = 'Daily expenses: $' + dailyExpenses.toLocaleString() + ' (rent, utilities, staff wages)';
// Add maintenance costs for owned vehicles
var maintenanceCosts = applyMaintenanceCosts();
if (maintenanceCosts > 0) {
expenseText += '\nVehicle maintenance: $' + maintenanceCosts.toLocaleString();
}
// Add insurance costs based on number of owned vehicles
var insuranceCost = ownedVehicles.length * 150;
if (insuranceCost > 0) {
playerMoney -= insuranceCost;
expenseText += '\nInsurance: $' + insuranceCost.toLocaleString();
}
// Random unexpected repairs (10% chance per owned vehicle)
var unexpectedRepairs = 0;
for (var i = 0; i < ownedVehicles.length; i++) {
if (Math.random() < 0.1) {
var repairCost = Math.floor(Math.random() * 2000) + 500;
unexpectedRepairs += repairCost;
}
}
if (unexpectedRepairs > 0) {
playerMoney -= unexpectedRepairs;
expenseText += '\nUnexpected repairs: $' + unexpectedRepairs.toLocaleString();
}
// Apply vehicle depreciation
applyVehicleDepreciation();
// Update repair progress and check for completed repairs
var completedRepairs = [];
for (var r = vehiclesInRepair.length - 1; r >= 0; r--) {
// Decrease remaining repair days
vehiclesInRepair[r].repairDuration--;
// Update vehicle repair completion day display
for (var v = 0; v < ownedVehicles.length; v++) {
if (ownedVehicles[v].id === vehiclesInRepair[r].vehicleId) {
ownedVehicles[v].repairCompletionDay = currentDay + vehiclesInRepair[r].repairDuration;
break;
}
}
// Check if repair is completed (0 days remaining)
if (vehiclesInRepair[r].repairDuration <= 0) {
completedRepairs.push(vehiclesInRepair[r]);
vehiclesInRepair.splice(r, 1);
}
}
// Complete repairs and update vehicle data
for (var c = 0; c < completedRepairs.length; c++) {
var completedRepair = completedRepairs[c];
for (var v = 0; v < ownedVehicles.length; v++) {
if (ownedVehicles[v].id === completedRepair.vehicleId) {
ownedVehicles[v].repaired = true;
ownedVehicles[v].actualCondition = 'good';
ownedVehicles[v].marketValue = Math.floor(ownedVehicles[v].marketValue * 1.5);
ownedVehicles[v].inRepair = false;
delete ownedVehicles[v].repairCompletionDay;
break;
}
}
}
// Update motorcycle repair progress and check for completed repairs
var completedMotoRepairs = [];
for (var mr = motorcyclesInRepair.length - 1; mr >= 0; mr--) {
// Decrease remaining repair days
motorcyclesInRepair[mr].repairDuration--;
// Update motorcycle repair completion day display
for (var mv = 0; mv < ownedMotorcycles.length; mv++) {
if (ownedMotorcycles[mv].id === motorcyclesInRepair[mr].vehicleId) {
ownedMotorcycles[mv].repairCompletionDay = currentDay + motorcyclesInRepair[mr].repairDuration;
break;
}
}
// Check if repair is completed (0 days remaining)
if (motorcyclesInRepair[mr].repairDuration <= 0) {
completedMotoRepairs.push(motorcyclesInRepair[mr]);
motorcyclesInRepair.splice(mr, 1);
}
}
// Complete motorcycle repairs and update motorcycle data
for (var mc = 0; mc < completedMotoRepairs.length; mc++) {
var completedMotoRepair = completedMotoRepairs[mc];
for (var mv = 0; mv < ownedMotorcycles.length; mv++) {
if (ownedMotorcycles[mv].id === completedMotoRepair.vehicleId) {
ownedMotorcycles[mv].repaired = true;
ownedMotorcycles[mv].actualCondition = 'good';
ownedMotorcycles[mv].marketValue = Math.floor(ownedMotorcycles[mv].marketValue * 1.5);
ownedMotorcycles[mv].inRepair = false;
delete ownedMotorcycles[mv].repairCompletionDay;
break;
}
}
}
// Show repair completion message
var totalCompletedRepairs = completedRepairs.length + completedMotoRepairs.length;
if (totalCompletedRepairs > 0) {
expenseText += '\n' + totalCompletedRepairs + ' vehicle(s) completed repair and ready for sale!';
LK.effects.flashScreen(0x2ecc71, 1000); // Green flash for completed repairs
}
// Apply daily interest on debt
var interestCharge = 0;
if (playerDebt > 0) {
interestCharge = Math.floor(playerDebt * dailyInterestRate);
playerDebt += interestCharge;
expenseText += '\nDebt interest: $' + interestCharge.toLocaleString();
}
// Check for loan seizure (5 days after loan was taken)
if (playerDebt > 0 && loanTakenDay > 0 && currentDay > loanTakenDay + 5) {
var seizureAmount = Math.floor(playerDebt * 1.5); // 50% more than debt
var actualSeizureAmount = 0;
var seizedVehicles = [];
// First seize money
if (playerMoney > 0) {
var moneySeized = Math.min(playerMoney, seizureAmount);
playerMoney -= moneySeized;
actualSeizureAmount += moneySeized;
seizureAmount -= moneySeized;
}
// Then seize vehicles if more seizure needed
if (seizureAmount > 0) {
// Seize cars
for (var i = ownedVehicles.length - 1; i >= 0 && seizureAmount > 0; i--) {
var vehicle = ownedVehicles[i];
if (vehicle.marketValue <= seizureAmount) {
seizedVehicles.push(vehicle.make + ' ' + vehicle.model);
actualSeizureAmount += vehicle.marketValue;
seizureAmount -= vehicle.marketValue;
ownedVehicles.splice(i, 1);
}
}
// Seize motorcycles
for (var i = ownedMotorcycles.length - 1; i >= 0 && seizureAmount > 0; i--) {
var vehicle = ownedMotorcycles[i];
if (vehicle.marketValue <= seizureAmount) {
seizedVehicles.push(vehicle.make + ' ' + vehicle.model + ' (Motorcycle)');
actualSeizureAmount += vehicle.marketValue;
seizureAmount -= vehicle.marketValue;
ownedMotorcycles.splice(i, 1);
}
}
// Seize vans
for (var i = ownedVans.length - 1; i >= 0 && seizureAmount > 0; i--) {
var vehicle = ownedVans[i];
if (vehicle.marketValue <= seizureAmount) {
seizedVehicles.push(vehicle.make + ' ' + vehicle.model + ' (Van)');
actualSeizureAmount += vehicle.marketValue;
seizureAmount -= vehicle.marketValue;
ownedVans.splice(i, 1);
}
}
}
// Clear debt and reset loan tracking after seizure
playerDebt = 0;
totalLoansOutstanding = 0;
loanTakenDay = 0;
var seizureText = 'LOAN SEIZURE! Assets worth $' + actualSeizureAmount.toLocaleString() + ' seized for unpaid loans!';
if (seizedVehicles.length > 0) {
seizureText += '\nVehicles seized: ' + seizedVehicles.join(', ');
}
expenseText += '\n' + seizureText;
LK.effects.flashScreen(0xff0000, 2000); // Red flash for seizure
// Update displays after seizure
if (gameState === 'owned_vehicles') {
displayOwnedVehicles();
}
}
// Tax system - every 7 days
if (currentDay % 7 === 1 && currentDay > lastTaxDay) {
// Calculate total vehicle value
var totalVehicleValue = 0;
for (var i = 0; i < ownedVehicles.length; i++) {
totalVehicleValue += ownedVehicles[i].marketValue;
}
// Tax is 8% of total assets (money + vehicles)
var taxAmount = Math.floor((playerMoney + totalVehicleValue) * 0.08);
taxDebt += taxAmount;
taxDueDate = currentDay + 2; // 2 days to pay
taxOverdueDate = currentDay + 2; // Start charging interest after 2 days
lastTaxDay = currentDay;
expenseText += '\nTAX DUE: $' + taxAmount.toLocaleString() + ' (due in 2 days)';
LK.effects.flashScreen(0xffa500, 1000); // Orange flash for tax notice
}
// Apply tax interest if overdue (after 2 days)
if (taxDebt > 0 && currentDay > taxOverdueDate) {
var taxInterest = Math.floor(taxDebt * 0.15); // 15% daily interest
taxDebt += taxInterest;
expenseText += '\nTax interest: $' + taxInterest.toLocaleString() + ' (15% daily)';
}
// Tax seizure after 14 days of unpaid tax debt
if (taxDebt > 0 && currentDay > taxDueDate + 14) {
var seizureAmount = Math.floor(taxDebt * 1.5); // 50% more than tax debt
var actualSeizureAmount = 0;
// First seize money
if (playerMoney > 0) {
var moneySeized = Math.min(playerMoney, seizureAmount);
playerMoney -= moneySeized;
actualSeizureAmount += moneySeized;
seizureAmount -= moneySeized;
}
// Then seize vehicles if more seizure needed
if (seizureAmount > 0 && ownedVehicles.length > 0) {
var vehiclesSeized = [];
for (var i = ownedVehicles.length - 1; i >= 0 && seizureAmount > 0; i--) {
var vehicle = ownedVehicles[i];
if (vehicle.marketValue <= seizureAmount) {
vehiclesSeized.push(vehicle.make + ' ' + vehicle.model);
actualSeizureAmount += vehicle.marketValue;
seizureAmount -= vehicle.marketValue;
ownedVehicles.splice(i, 1);
}
}
}
// Clear tax debt after seizure
taxDebt = 0;
taxDueDate = 0;
taxOverdueDate = 0;
var seizureText = 'TAX SEIZURE! Assets worth $' + actualSeizureAmount.toLocaleString() + ' seized for unpaid taxes!';
if (vehiclesSeized.length > 0) {
seizureText += '\nVehicles seized: ' + vehiclesSeized.join(', ');
}
expenseText += '\n' + seizureText;
LK.effects.flashScreen(0xff0000, 2000); // Red flash for seizure
// Update displays after seizure
if (gameState === 'owned_vehicles') {
displayOwnedVehicles();
}
}
updateMoneyDisplay();
updateDebtDisplay();
updateTaxDisplay();
infoText.setText(expenseText);
saveGame();
};
viewOwnedButton.up = function (x, y, obj) {
if (gameState === 'daily_offers') {
gameState = 'owned_vehicles';
stateText.setText('Owned Vehicles & Motorcycles');
displayOwnedVehicles();
} else {
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
}
selectedVehicle = null;
updateUI();
};
loanButton.up = function (x, y, obj) {
var loanAmount = 10000;
// Check if player can take more loans (credit limit)
if (totalLoansOutstanding + loanAmount > creditLimit) {
infoText.setText('Loan denied! Credit limit reached.\nCredit limit: $' + creditLimit.toLocaleString() + '\nOutstanding loans: $' + totalLoansOutstanding.toLocaleString());
return;
}
playerMoney += loanAmount;
playerDebt += loanAmount;
totalLoansOutstanding += loanAmount;
loanTakenDay = currentDay; // Track when loan was taken
updateMoneyDisplay();
updateDebtDisplay();
saveGame();
infoText.setText('Loan approved! You received $' + loanAmount.toLocaleString() + '\nDaily interest: 5%\nDue in 5 days or 50% penalty applies');
};
payDebtButton.up = function (x, y, obj) {
if (playerDebt > 0 && playerMoney > 0) {
var paymentAmount = Math.min(playerMoney, playerDebt);
playerMoney -= paymentAmount;
playerDebt -= paymentAmount;
totalLoansOutstanding -= paymentAmount; // Reduce outstanding loans
if (totalLoansOutstanding < 0) totalLoansOutstanding = 0;
updateMoneyDisplay();
updateDebtDisplay();
saveGame();
infoText.setText('Paid $' + paymentAmount.toLocaleString() + ' towards debt!\nRemaining debt: $' + playerDebt.toLocaleString());
} else if (playerDebt <= 0) {
infoText.setText('You have no debt to pay!');
} else {
infoText.setText('You need money to pay your debt!');
}
};
payTaxButton.up = function (x, y, obj) {
if (taxDebt > 0 && playerMoney > 0) {
var paymentAmount = Math.min(playerMoney, taxDebt);
playerMoney -= paymentAmount;
taxDebt -= paymentAmount;
updateMoneyDisplay();
updateTaxDisplay();
saveGame();
infoText.setText('Paid $' + paymentAmount.toLocaleString() + ' towards tax!\nRemaining tax: $' + taxDebt.toLocaleString());
} else if (taxDebt <= 0) {
infoText.setText('You have no tax to pay!');
} else {
infoText.setText('You need money to pay your tax!');
}
};
settingsButton.up = function (x, y, obj) {
// Show settings menu
gameState = 'settings';
stateText.setText('Settings');
vehicleContainer.removeChildren();
// Create sound effects toggle button
var soundToggleText = soundEffectsEnabled ? 'Sound Effects: ON' : 'Sound Effects: OFF';
var soundToggleBtn = new Button(soundToggleText, soundEffectsEnabled ? 0x2ecc71 : 0xe74c3c, 400, 120);
soundToggleBtn.x = 0;
soundToggleBtn.y = -150;
vehicleContainer.addChild(soundToggleBtn);
soundToggleBtn.up = function () {
soundEffectsEnabled = !soundEffectsEnabled;
saveGame();
// Refresh settings menu
settingsButton.up();
};
// Create reset game button with warning
var resetBtn = new Button('Reset Game', 0xe74c3c, 400, 120);
resetBtn.x = 0;
resetBtn.y = 150;
vehicleContainer.addChild(resetBtn);
resetBtn.up = function () {
// Show confirmation warning
gameState = 'reset_confirmation';
stateText.setText('Reset Confirmation');
vehicleContainer.removeChildren();
var warningText = new Text2('WARNING!\nThis will delete ALL your progress!\nAre you sure?', {
size: 48,
fill: 0xff0000
});
warningText.anchor.set(0.5, 0.5);
warningText.x = 0;
warningText.y = -100;
vehicleContainer.addChild(warningText);
var confirmBtn = new Button('YES - Reset Everything', 0xe74c3c, 400, 120);
confirmBtn.x = -250;
confirmBtn.y = 100;
vehicleContainer.addChild(confirmBtn);
confirmBtn.up = function () {
// Clear all stored data
delete storage.playerMoney;
delete storage.currentDay;
delete storage.playerDebt;
delete storage.creditLimit;
delete storage.loanTakenDay;
delete storage.totalLoansOutstanding;
delete storage.taxDebt;
delete storage.taxDueDate;
delete storage.taxOverdueDate;
delete storage.lastTaxDay;
delete storage.vehicleCount;
delete storage.vehicleMakes;
delete storage.vehicleModels;
delete storage.vehicleConditions;
delete storage.vehicleActualConditions;
delete storage.vehicleMileages;
delete storage.vehicleActualMileages;
delete storage.vehiclePrices;
delete storage.vehicleMarketValues;
delete storage.vehicleSellerLying;
delete storage.vehicleIds;
delete storage.vehicleRepaired;
delete storage.vehicleInRepair;
delete storage.vehicleRepairCompletionDay;
delete storage.vehiclesInRepairCount;
delete storage.repairVehicleIds;
delete storage.repairCompletionDays;
delete storage.repairDurations;
delete storage.motorcycleUnlocked;
delete storage.motorcycleCount;
delete storage.motorcycleMakes;
delete storage.motorcycleModels;
delete storage.motorcycleConditions;
delete storage.motorcycleActualConditions;
delete storage.motorcycleMileages;
delete storage.motorcycleActualMileages;
delete storage.motorcyclePrices;
delete storage.motorcycleMarketValues;
delete storage.motorcycleSellerLying;
delete storage.motorcycleIds;
delete storage.motorcycleRepaired;
delete storage.motorcycleInRepair;
delete storage.motorcycleRepairCompletionDay;
delete storage.motorcyclesInRepairCount;
delete storage.repairMotoVehicleIds;
delete storage.repairMotoCompletionDays;
delete storage.repairMotoDurations;
delete storage.vanUnlocked;
delete storage.vanCount;
delete storage.vanMakes;
delete storage.vanModels;
delete storage.vanConditions;
delete storage.vanActualConditions;
delete storage.vanMileages;
delete storage.vanActualMileages;
delete storage.vanPrices;
delete storage.vanMarketValues;
delete storage.vanSellerLying;
delete storage.vanIds;
delete storage.vanRepaired;
delete storage.vanInRepair;
delete storage.vanRepairCompletionDay;
delete storage.vansInRepairCount;
delete storage.repairVanVehicleIds;
delete storage.repairVanCompletionDays;
delete storage.repairVanDurations;
delete storage.soundEffectsEnabled;
// Reset game state to initial values
playerMoney = 50000;
currentDay = 1;
playerDebt = 0;
creditLimit = 50000;
loanTakenDay = 0;
totalLoansOutstanding = 0;
taxDebt = 0;
taxDueDate = 0;
taxOverdueDate = 0;
lastTaxDay = 0;
ownedVehicles = [];
vehiclesInRepair = [];
motorcycleUnlocked = false;
vanUnlocked = false;
ownedMotorcycles = [];
ownedVans = [];
motorcyclesInRepair = [];
vansInRepair = [];
vehicleType = 'cars';
selectedVehicle = null;
gameState = 'daily_offers';
soundEffectsEnabled = true;
vehicleLocksButton.visible = true;
// Update UI
stateText.setText('Daily Vehicle Offers');
dayText.setText('Day ' + currentDay);
updateMoneyDisplay();
updateDebtDisplay();
updateTaxDisplay();
generateDailyOffers();
displayVehicles(dailyOffers);
updateUI();
};
var cancelBtn = new Button('NO - Keep Progress', 0x2ecc71, 400, 120);
cancelBtn.x = 250;
cancelBtn.y = 100;
vehicleContainer.addChild(cancelBtn);
cancelBtn.up = function () {
// Return to settings
settingsButton.up();
};
};
var backBtn = new Button('Back', 0x95a5a6, 200, 80);
backBtn.x = 0;
backBtn.y = 300;
vehicleContainer.addChild(backBtn);
backBtn.up = function () {
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
updateUI();
};
selectedVehicle = null;
updateUI();
};
vehicleLocksButton.up = function (x, y, obj) {
// Show vehicle locks menu
gameState = 'vehicle_locks';
stateText.setText('Vehicle Locks');
vehicleContainer.removeChildren();
// Create unlock buttons for motorcycles and vans
if (!motorcycleUnlocked) {
var unlockMotoBtn = new Button('Unlock Motorcycles ($100,000)', 0x9b59b6, 400, 120);
unlockMotoBtn.x = 0;
unlockMotoBtn.y = -100;
vehicleContainer.addChild(unlockMotoBtn);
unlockMotoBtn.up = function () {
if (playerMoney >= 100000) {
playerMoney -= 100000;
motorcycleUnlocked = true;
updateMoneyDisplay();
saveGame();
infoText.setText('Motorcycles unlocked! Motorcycle offers will now appear mixed with car offers.');
LK.effects.flashScreen(0x2ecc71, 1000);
// Return to main menu
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
updateUI();
vehicleLocksButton.visible = !motorcycleUnlocked || !vanUnlocked;
} else {
infoText.setText('Not enough money! Need $100,000 to unlock motorcycles.');
}
};
}
if (!vanUnlocked) {
var unlockVanBtn = new Button('Unlock Vans ($250,000)', 0x34495e, 400, 120);
unlockVanBtn.x = 0;
unlockVanBtn.y = motorcycleUnlocked ? -100 : 50;
vehicleContainer.addChild(unlockVanBtn);
unlockVanBtn.up = function () {
if (playerMoney >= 250000) {
playerMoney -= 250000;
vanUnlocked = true;
updateMoneyDisplay();
saveGame();
infoText.setText('Vans unlocked! Van offers will now appear mixed with other vehicle offers.');
LK.effects.flashScreen(0x2ecc71, 1000);
// Return to main menu
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
updateUI();
vehicleLocksButton.visible = !motorcycleUnlocked || !vanUnlocked;
} else {
infoText.setText('Not enough money! Need $250,000 to unlock vans.');
}
};
}
var backBtn = new Button('Back', 0x95a5a6, 200, 80);
backBtn.x = 0;
backBtn.y = 200;
vehicleContainer.addChild(backBtn);
backBtn.up = function () {
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
updateUI();
};
selectedVehicle = null;
updateUI();
};
// Switch vehicle button functionality removed - vehicles are now mixed together
function displayOwnedVehicles() {
vehicleContainer.removeChildren();
var allOwnedVehicles = ownedVehicles.concat(ownedMotorcycles).concat(ownedVans);
for (var i = 0; i < allOwnedVehicles.length; i++) {
var vehicleData = allOwnedVehicles[i];
var isMotorcycle = i >= ownedVehicles.length && i < ownedVehicles.length + ownedMotorcycles.length;
var isVan = i >= ownedVehicles.length + ownedMotorcycles.length;
var vehicle = new Vehicle(vehicleData, isMotorcycle, isVan);
if (vehicleData.repaired) {
vehicle.repaired = true;
vehicle.updateDisplay();
}
vehicle.x = i % 2 * 600 - 300;
vehicle.y = Math.floor(i / 2) * 380;
vehicleContainer.addChild(vehicle);
vehicle.vehicleData = vehicleData;
vehicle.down = function (x, y, obj) {
selectedVehicle = obj.vehicleData;
updateUI();
};
// Add action buttons for each owned vehicle
if (vehicleData.inRepair) {
// Vehicle is in repair - show status and prevent actions
var daysRemaining = 0;
// Find repair data to get remaining days
var repairArray = isMotorcycle ? motorcyclesInRepair : vehiclesInRepair;
for (var rr = 0; rr < repairArray.length; rr++) {
if (repairArray[rr].vehicleId === vehicleData.id) {
daysRemaining = repairArray[rr].repairDuration;
break;
}
}
var repairStatusText = new Text2('IN REPAIR - ' + daysRemaining + ' day(s) remaining', {
size: 24,
fill: 0xf39c12
});
repairStatusText.anchor.set(0.5, 0.5);
repairStatusText.x = 0;
repairStatusText.y = 150;
vehicle.addChild(repairStatusText);
} else if (vehicleData.actualCondition === 'damaged' && !vehicleData.repaired) {
// Add repair button with dynamic cost
var repairCost = Math.floor(vehicleData.price * (Math.random() * 0.15 + 0.10));
var minRepairCost = isMotorcycle ? 500 : 1000;
if (repairCost < minRepairCost) {
repairCost = minRepairCost;
}
var vehicleRepairButton = new Button('Repair ($' + repairCost.toLocaleString() + ')', 0xe67e22, 200, 60);
vehicleRepairButton.x = -150;
vehicleRepairButton.y = 150;
vehicle.addChild(vehicleRepairButton);
(function (vehicleData, isMotorcycle) {
vehicleRepairButton.up = function (x, y, obj) {
// Calculate repair cost based on vehicle price (10-25% of price)
var repairCost = Math.floor(vehicleData.price * (Math.random() * 0.15 + 0.10));
// Minimum repair cost based on vehicle type
var minRepairCost = isMotorcycle ? 500 : 1000;
if (repairCost < minRepairCost) {
repairCost = minRepairCost;
}
if (playerMoney >= repairCost) {
playerMoney -= repairCost;
// Calculate repair duration based on damage level
var repairDuration = 1; // Default 1 day
if (vehicleData.actualCondition === 'damaged') {
repairDuration = Math.floor(Math.random() * 3) + 1; // 1-3 days for damaged
} else if (vehicleData.actualCondition === 'poor') {
repairDuration = 1; // 1 day for poor
}
// Move vehicle to repair shop
var repairData = {
vehicleId: vehicleData.id,
completionDay: currentDay + repairDuration,
repairDuration: repairDuration
};
if (isMotorcycle) {
motorcyclesInRepair.push(repairData);
// Update the vehicle data in the ownedMotorcycles array
for (var k = 0; k < ownedMotorcycles.length; k++) {
if (ownedMotorcycles[k].id === vehicleData.id) {
ownedMotorcycles[k].inRepair = true;
ownedMotorcycles[k].repairCompletionDay = currentDay + repairDuration;
break;
}
}
} else {
vehiclesInRepair.push(repairData);
// Update the vehicle data in the ownedVehicles array
for (var k = 0; k < ownedVehicles.length; k++) {
if (ownedVehicles[k].id === vehicleData.id) {
ownedVehicles[k].inRepair = true;
ownedVehicles[k].repairCompletionDay = currentDay + repairDuration;
break;
}
}
}
if (soundEffectsEnabled) LK.getSound('repair').play();
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
infoText.setText('Vehicle sent to repair shop for $' + repairCost.toLocaleString() + '!\nWill be ready in ' + repairDuration + ' day(s).');
} else {
infoText.setText('Not enough money! Repair costs $' + repairCost.toLocaleString());
}
};
})(vehicleData, isMotorcycle);
// Add sell button for damaged vehicles (sell as-is for low price)
var damagedSalePrice = Math.floor(vehicleData.marketValue * (Math.random() * 0.20 + 0.30));
var vehicleSellDamagedButton = new Button('Sell LOW ($' + damagedSalePrice.toLocaleString() + ')', 0x8e44ad, 200, 60);
vehicleSellDamagedButton.x = 50;
vehicleSellDamagedButton.y = 150;
vehicle.addChild(vehicleSellDamagedButton);
(function (vehicleData, displayedSalePrice, isMotorcycle) {
vehicleSellDamagedButton.up = function (x, y, obj) {
var salePrice = displayedSalePrice;
playerMoney += salePrice;
// Remove from appropriate owned vehicles array
if (isMotorcycle) {
for (var j = 0; j < ownedMotorcycles.length; j++) {
if (ownedMotorcycles[j].id === vehicleData.id) {
ownedMotorcycles.splice(j, 1);
break;
}
}
} else {
for (var j = 0; j < ownedVehicles.length; j++) {
if (ownedVehicles[j].id === vehicleData.id) {
ownedVehicles.splice(j, 1);
break;
}
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
infoText.setText('Sold damaged vehicle for $' + salePrice.toLocaleString() + '! (Low Price - Could have repaired for higher profit)');
};
})(vehicleData, damagedSalePrice, isMotorcycle);
} else {
// Add sell button with sale price - different pricing for repaired vs unrepaired
var salePrice;
if (vehicleData.repaired) {
// Repaired vehicles sell for 80-95% of market value (high price)
salePrice = Math.floor(vehicleData.marketValue * (Math.random() * 0.15 + 0.80));
} else if (vehicleData.actualCondition === 'damaged') {
// Damaged vehicles sell for 30-50% of market value (low price)
salePrice = Math.floor(vehicleData.marketValue * (Math.random() * 0.20 + 0.30));
} else {
// Other conditions sell for 60-80% of market value (medium price)
salePrice = Math.floor(vehicleData.marketValue * (Math.random() * 0.20 + 0.60));
}
var sellButtonText = 'Sell ($' + salePrice.toLocaleString() + ')';
if (vehicleData.repaired) {
sellButtonText += ' HIGH';
} else if (vehicleData.actualCondition === 'damaged') {
sellButtonText += ' LOW';
}
var vehicleSellButton = new Button(sellButtonText, 0x8e44ad, 200, 60);
vehicleSellButton.x = -100;
vehicleSellButton.y = 150;
vehicle.addChild(vehicleSellButton);
(function (vehicleData, displayedSalePrice, isMotorcycle) {
vehicleSellButton.up = function (x, y, obj) {
var salePrice = displayedSalePrice;
playerMoney += salePrice;
// Remove from appropriate owned vehicles array
if (isMotorcycle) {
for (var j = 0; j < ownedMotorcycles.length; j++) {
if (ownedMotorcycles[j].id === vehicleData.id) {
ownedMotorcycles.splice(j, 1);
break;
}
}
} else {
for (var j = 0; j < ownedVehicles.length; j++) {
if (ownedVehicles[j].id === vehicleData.id) {
ownedVehicles.splice(j, 1);
break;
}
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
var sellMessage = 'Sold for $' + salePrice.toLocaleString() + '!';
if (vehicleData.repaired) {
sellMessage += ' (Repaired - High Price)';
} else if (vehicleData.actualCondition === 'damaged') {
sellMessage += ' (Damaged - Low Price)';
}
infoText.setText(sellMessage);
};
})(vehicleData, salePrice, isMotorcycle);
}
}
}
function displayOwnedMotorcycles() {
vehicleContainer.removeChildren();
for (var i = 0; i < ownedMotorcycles.length; i++) {
var vehicle = new Vehicle(ownedMotorcycles[i], true);
if (ownedMotorcycles[i].repaired) {
vehicle.repaired = true;
vehicle.updateDisplay();
}
vehicle.x = i % 2 * 600 - 300;
vehicle.y = Math.floor(i / 2) * 380;
vehicleContainer.addChild(vehicle);
vehicle.vehicleData = ownedMotorcycles[i];
vehicle.down = function (x, y, obj) {
selectedVehicle = obj.vehicleData;
updateUI();
};
// Add action buttons for each owned motorcycle
if (ownedMotorcycles[i].inRepair) {
// Motorcycle is in repair - show status and prevent actions
var daysRemaining = 0;
// Find repair data to get remaining days
for (var rr = 0; rr < motorcyclesInRepair.length; rr++) {
if (motorcyclesInRepair[rr].vehicleId === ownedMotorcycles[i].id) {
daysRemaining = motorcyclesInRepair[rr].repairDuration;
break;
}
}
var repairStatusText = new Text2('IN REPAIR - ' + daysRemaining + ' day(s) remaining', {
size: 24,
fill: 0xf39c12
});
repairStatusText.anchor.set(0.5, 0.5);
repairStatusText.x = 0;
repairStatusText.y = 150;
vehicle.addChild(repairStatusText);
} else if (ownedMotorcycles[i].actualCondition === 'damaged' && !ownedMotorcycles[i].repaired) {
// Add repair button with dynamic cost
var repairCost = Math.floor(ownedMotorcycles[i].price * (Math.random() * 0.15 + 0.10));
if (repairCost < 500) {
repairCost = 500;
}
var vehicleRepairButton = new Button('Repair ($' + repairCost.toLocaleString() + ')', 0xe67e22, 200, 60);
vehicleRepairButton.x = -150;
vehicleRepairButton.y = 150;
vehicle.addChild(vehicleRepairButton);
(function (vehicleData) {
vehicleRepairButton.up = function (x, y, obj) {
// Calculate repair cost based on vehicle price (10-25% of price)
var repairCost = Math.floor(vehicleData.price * (Math.random() * 0.15 + 0.10));
// Minimum repair cost of $500 for motorcycles
if (repairCost < 500) {
repairCost = 500;
}
if (playerMoney >= repairCost) {
playerMoney -= repairCost;
// Calculate repair duration based on damage level
var repairDuration = 1; // Default 1 day
if (vehicleData.actualCondition === 'damaged') {
repairDuration = Math.floor(Math.random() * 3) + 1; // 1-3 days for damaged
} else if (vehicleData.actualCondition === 'poor') {
repairDuration = 1; // 1 day for poor
}
// Move motorcycle to repair shop
var repairData = {
vehicleId: vehicleData.id,
completionDay: currentDay + repairDuration,
repairDuration: repairDuration
};
motorcyclesInRepair.push(repairData);
// Update the motorcycle data in the ownedMotorcycles array
for (var k = 0; k < ownedMotorcycles.length; k++) {
if (ownedMotorcycles[k].id === vehicleData.id) {
ownedMotorcycles[k].inRepair = true;
ownedMotorcycles[k].repairCompletionDay = currentDay + repairDuration;
break;
}
}
if (soundEffectsEnabled) LK.getSound('repair').play();
updateMoneyDisplay();
displayOwnedMotorcycles();
updateUI();
saveGame();
infoText.setText('Motorcycle sent to repair shop for $' + repairCost.toLocaleString() + '!\nWill be ready in ' + repairDuration + ' day(s).');
} else {
infoText.setText('Not enough money! Repair costs $' + repairCost.toLocaleString());
}
};
})(ownedMotorcycles[i]);
// Add sell button for damaged motorcycles (sell as-is for low price)
var damagedSalePrice = Math.floor(ownedMotorcycles[i].marketValue * (Math.random() * 0.20 + 0.30));
var vehicleSellDamagedButton = new Button('Sell LOW ($' + damagedSalePrice.toLocaleString() + ')', 0x8e44ad, 200, 60);
vehicleSellDamagedButton.x = 50;
vehicleSellDamagedButton.y = 150;
vehicle.addChild(vehicleSellDamagedButton);
(function (vehicleData, displayedSalePrice) {
vehicleSellDamagedButton.up = function (x, y, obj) {
var salePrice = displayedSalePrice;
playerMoney += salePrice;
// Remove from owned motorcycles
for (var j = 0; j < ownedMotorcycles.length; j++) {
if (ownedMotorcycles[j].id === vehicleData.id) {
ownedMotorcycles.splice(j, 1);
break;
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedMotorcycles();
updateUI();
saveGame();
infoText.setText('Sold damaged motorcycle for $' + salePrice.toLocaleString() + '! (Low Price - Could have repaired for higher profit)');
};
})(ownedMotorcycles[i], damagedSalePrice);
} else {
// Add sell button with sale price - different pricing for repaired vs unrepaired
var salePrice;
if (ownedMotorcycles[i].repaired) {
// Repaired motorcycles sell for 80-95% of market value (high price)
salePrice = Math.floor(ownedMotorcycles[i].marketValue * (Math.random() * 0.15 + 0.80));
} else if (ownedMotorcycles[i].actualCondition === 'damaged') {
// Damaged motorcycles sell for 30-50% of market value (low price)
salePrice = Math.floor(ownedMotorcycles[i].marketValue * (Math.random() * 0.20 + 0.30));
} else {
// Other conditions sell for 60-80% of market value (medium price)
salePrice = Math.floor(ownedMotorcycles[i].marketValue * (Math.random() * 0.20 + 0.60));
}
var sellButtonText = 'Sell ($' + salePrice.toLocaleString() + ')';
if (ownedMotorcycles[i].repaired) {
sellButtonText += ' HIGH';
} else if (ownedMotorcycles[i].actualCondition === 'damaged') {
sellButtonText += ' LOW';
}
var vehicleSellButton = new Button(sellButtonText, 0x8e44ad, 200, 60);
vehicleSellButton.x = -100;
vehicleSellButton.y = 150;
vehicle.addChild(vehicleSellButton);
(function (vehicleData, displayedSalePrice) {
vehicleSellButton.up = function (x, y, obj) {
var salePrice = displayedSalePrice;
playerMoney += salePrice;
// Remove from owned motorcycles
for (var j = 0; j < ownedMotorcycles.length; j++) {
if (ownedMotorcycles[j].id === vehicleData.id) {
ownedMotorcycles.splice(j, 1);
break;
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedMotorcycles();
updateUI();
saveGame();
var sellMessage = 'Sold for $' + salePrice.toLocaleString() + '!';
if (vehicleData.repaired) {
sellMessage += ' (Repaired - High Price)';
} else if (vehicleData.actualCondition === 'damaged') {
sellMessage += ' (Damaged - Low Price)';
}
infoText.setText(sellMessage);
};
})(ownedMotorcycles[i], salePrice);
}
}
}
function updateMoneyDisplay() {
moneyText.setText('Money: $' + playerMoney.toLocaleString());
}
function updateDebtDisplay() {
debtText.setText('Debt: $' + playerDebt.toLocaleString());
if (playerDebt > 0) {
debtText.tint = 0xe74c3c; // Red for debt
} else {
debtText.tint = 0x2ecc71; // Green for no debt
}
}
function updateTaxDisplay() {
taxText.setText('Tax: $' + taxDebt.toLocaleString());
if (taxDebt > 0) {
taxText.tint = 0xe74c3c; // Red for tax debt
} else {
taxText.tint = 0x2ecc71; // Green for no tax
}
}
function saveGame() {
storage.playerMoney = playerMoney;
storage.currentDay = currentDay;
storage.playerDebt = playerDebt;
storage.creditLimit = creditLimit;
storage.loanTakenDay = loanTakenDay;
storage.totalLoansOutstanding = totalLoansOutstanding;
storage.taxDebt = taxDebt;
storage.taxDueDate = taxDueDate;
storage.taxOverdueDate = taxOverdueDate;
storage.lastTaxDay = lastTaxDay;
storage.motorcycleUnlocked = motorcycleUnlocked;
storage.vanUnlocked = vanUnlocked;
storage.soundEffectsEnabled = soundEffectsEnabled;
// Store each vehicle property as separate arrays to avoid nested objects
var vehicleCount = ownedVehicles.length;
storage.vehicleCount = vehicleCount;
storage.vehicleMakes = [];
storage.vehicleModels = [];
storage.vehicleConditions = [];
storage.vehicleActualConditions = [];
storage.vehicleMileages = [];
storage.vehicleActualMileages = [];
storage.vehiclePrices = [];
storage.vehicleMarketValues = [];
storage.vehicleSellerLying = [];
storage.vehicleIds = [];
storage.vehicleRepaired = [];
storage.vehicleInRepair = [];
storage.vehicleRepairCompletionDay = [];
for (var i = 0; i < ownedVehicles.length; i++) {
var vehicle = ownedVehicles[i];
storage.vehicleMakes.push(vehicle.make);
storage.vehicleModels.push(vehicle.model);
storage.vehicleConditions.push(vehicle.condition);
storage.vehicleActualConditions.push(vehicle.actualCondition);
storage.vehicleMileages.push(vehicle.mileage);
storage.vehicleActualMileages.push(vehicle.actualMileage);
storage.vehiclePrices.push(vehicle.price);
storage.vehicleMarketValues.push(vehicle.marketValue);
storage.vehicleSellerLying.push(vehicle.sellerLying);
storage.vehicleIds.push(vehicle.id);
storage.vehicleRepaired.push(vehicle.repaired || false);
storage.vehicleInRepair.push(vehicle.inRepair || false);
storage.vehicleRepairCompletionDay.push(vehicle.repairCompletionDay || 0);
}
// Save repair shop data
storage.vehiclesInRepairCount = vehiclesInRepair.length;
storage.repairVehicleIds = [];
storage.repairCompletionDays = [];
storage.repairDurations = [];
for (var r = 0; r < vehiclesInRepair.length; r++) {
storage.repairVehicleIds.push(vehiclesInRepair[r].vehicleId);
storage.repairCompletionDays.push(vehiclesInRepair[r].completionDay);
storage.repairDurations.push(vehiclesInRepair[r].repairDuration);
}
// Save motorcycle data
var motorcycleCount = ownedMotorcycles.length;
storage.motorcycleCount = motorcycleCount;
storage.motorcycleMakes = [];
storage.motorcycleModels = [];
storage.motorcycleConditions = [];
storage.motorcycleActualConditions = [];
storage.motorcycleMileages = [];
storage.motorcycleActualMileages = [];
storage.motorcyclePrices = [];
storage.motorcycleMarketValues = [];
storage.motorcycleSellerLying = [];
storage.motorcycleIds = [];
storage.motorcycleRepaired = [];
storage.motorcycleInRepair = [];
storage.motorcycleRepairCompletionDay = [];
for (var m = 0; m < ownedMotorcycles.length; m++) {
var motorcycle = ownedMotorcycles[m];
storage.motorcycleMakes.push(motorcycle.make);
storage.motorcycleModels.push(motorcycle.model);
storage.motorcycleConditions.push(motorcycle.condition);
storage.motorcycleActualConditions.push(motorcycle.actualCondition);
storage.motorcycleMileages.push(motorcycle.mileage);
storage.motorcycleActualMileages.push(motorcycle.actualMileage);
storage.motorcyclePrices.push(motorcycle.price);
storage.motorcycleMarketValues.push(motorcycle.marketValue);
storage.motorcycleSellerLying.push(motorcycle.sellerLying);
storage.motorcycleIds.push(motorcycle.id);
storage.motorcycleRepaired.push(motorcycle.repaired || false);
storage.motorcycleInRepair.push(motorcycle.inRepair || false);
storage.motorcycleRepairCompletionDay.push(motorcycle.repairCompletionDay || 0);
}
// Save motorcycle repair shop data
storage.motorcyclesInRepairCount = motorcyclesInRepair.length;
storage.repairMotoVehicleIds = [];
storage.repairMotoCompletionDays = [];
storage.repairMotoDurations = [];
for (var mr = 0; mr < motorcyclesInRepair.length; mr++) {
storage.repairMotoVehicleIds.push(motorcyclesInRepair[mr].vehicleId);
storage.repairMotoCompletionDays.push(motorcyclesInRepair[mr].completionDay);
storage.repairMotoDurations.push(motorcyclesInRepair[mr].repairDuration);
}
// Save van data
var vanCount = ownedVans.length;
storage.vanCount = vanCount;
storage.vanMakes = [];
storage.vanModels = [];
storage.vanConditions = [];
storage.vanActualConditions = [];
storage.vanMileages = [];
storage.vanActualMileages = [];
storage.vanPrices = [];
storage.vanMarketValues = [];
storage.vanSellerLying = [];
storage.vanIds = [];
storage.vanRepaired = [];
storage.vanInRepair = [];
storage.vanRepairCompletionDay = [];
for (var v = 0; v < ownedVans.length; v++) {
var van = ownedVans[v];
storage.vanMakes.push(van.make);
storage.vanModels.push(van.model);
storage.vanConditions.push(van.condition);
storage.vanActualConditions.push(van.actualCondition);
storage.vanMileages.push(van.mileage);
storage.vanActualMileages.push(van.actualMileage);
storage.vanPrices.push(van.price);
storage.vanMarketValues.push(van.marketValue);
storage.vanSellerLying.push(van.sellerLying);
storage.vanIds.push(van.id);
storage.vanRepaired.push(van.repaired || false);
storage.vanInRepair.push(van.inRepair || false);
storage.vanRepairCompletionDay.push(van.repairCompletionDay || 0);
}
// Save van repair shop data
storage.vansInRepairCount = vansInRepair.length;
storage.repairVanVehicleIds = [];
storage.repairVanCompletionDays = [];
storage.repairVanDurations = [];
for (var vr = 0; vr < vansInRepair.length; vr++) {
storage.repairVanVehicleIds.push(vansInRepair[vr].vehicleId);
storage.repairVanCompletionDays.push(vansInRepair[vr].completionDay);
storage.repairVanDurations.push(vansInRepair[vr].repairDuration);
}
}
// Add maintenance costs for owned vehicles
function applyMaintenanceCosts() {
var totalMaintenanceCost = 0;
for (var i = 0; i < ownedVehicles.length; i++) {
var vehicle = ownedVehicles[i];
// Higher maintenance cost for damaged vehicles
var baseCost = vehicle.actualCondition === 'damaged' ? 200 : 100;
var maintenanceCost = Math.floor(Math.random() * baseCost) + 50;
totalMaintenanceCost += maintenanceCost;
}
if (totalMaintenanceCost > 0) {
playerMoney -= totalMaintenanceCost;
return totalMaintenanceCost;
}
return 0;
}
// Apply vehicle depreciation
function applyVehicleDepreciation() {
for (var i = 0; i < ownedVehicles.length; i++) {
var vehicle = ownedVehicles[i];
// Vehicles lose 2-5% of their market value each day
var depreciationRate = Math.random() * 0.03 + 0.02;
vehicle.marketValue = Math.floor(vehicle.marketValue * (1 - depreciationRate));
// Minimum market value floor
if (vehicle.marketValue < 1000) {
vehicle.marketValue = 1000;
}
}
}
// Initialize game
updateDebtDisplay();
updateTaxDisplay();
generateDailyOffers();
if (motorcycleUnlocked) {
generateDailyMotoOffers();
}
displayVehicles(dailyOffers);
updateUI();
// Game restart function
function restartGame() {
// Reset all game state variables to initial values
playerMoney = 50000;
currentDay = 1;
playerDebt = 0;
taxDebt = 0;
taxDueDate = 0;
taxOverdueDate = 0;
lastTaxDay = 0;
ownedVehicles = [];
vehiclesInRepair = [];
motorcycleUnlocked = false;
ownedMotorcycles = [];
motorcyclesInRepair = [];
vehicleType = 'cars';
selectedVehicle = null;
gameState = 'daily_offers';
vehicleLocksButton.visible = !motorcycleUnlocked || !vanUnlocked;
// Clear storage
delete storage.playerMoney;
delete storage.currentDay;
delete storage.playerDebt;
delete storage.taxDebt;
delete storage.taxDueDate;
delete storage.taxOverdueDate;
delete storage.lastTaxDay;
delete storage.vehicleCount;
delete storage.vehicleMakes;
delete storage.vehicleModels;
delete storage.vehicleConditions;
delete storage.vehicleActualConditions;
delete storage.vehicleMileages;
delete storage.vehicleActualMileages;
delete storage.vehiclePrices;
delete storage.vehicleMarketValues;
delete storage.vehicleSellerLying;
delete storage.vehicleIds;
delete storage.vehicleRepaired;
delete storage.vehicleInRepair;
delete storage.vehicleRepairCompletionDay;
delete storage.vehiclesInRepairCount;
delete storage.repairVehicleIds;
delete storage.repairCompletionDays;
delete storage.repairDurations;
delete storage.motorcycleUnlocked;
delete storage.motorcycleCount;
delete storage.motorcycleMakes;
delete storage.motorcycleModels;
delete storage.motorcycleConditions;
delete storage.motorcycleActualConditions;
delete storage.motorcycleMileages;
delete storage.motorcycleActualMileages;
delete storage.motorcyclePrices;
delete storage.motorcycleMarketValues;
delete storage.motorcycleSellerLying;
delete storage.motorcycleIds;
delete storage.motorcycleRepaired;
delete storage.motorcycleInRepair;
delete storage.motorcycleRepairCompletionDay;
delete storage.motorcyclesInRepairCount;
delete storage.repairMotoVehicleIds;
delete storage.repairMotoCompletionDays;
delete storage.repairMotoDurations;
// Update UI elements
stateText.setText('Daily Vehicle Offers');
dayText.setText('Day ' + currentDay);
updateMoneyDisplay();
updateDebtDisplay();
updateTaxDisplay();
generateDailyOffers();
displayVehicles(dailyOffers);
updateUI();
infoText.setText('Game restarted! Welcome back to Car Dealer Tycoon!');
}
// Game update loop
game.update = function () {
// Check for game over condition
if (playerMoney < 0) {
LK.showGameOver();
// Reset game state for restart
restartGame();
}
// Check for winning condition
if (playerMoney >= 500000) {
LK.showYouWin();
// Reset game state for restart
restartGame();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Button = Container.expand(function (text, color, width, height) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
width: width || 300,
height: height || 120
});
buttonGraphics.tint = color || 0x27ae60;
var buttonText = new Text2(text, {
size: 32,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = 0;
buttonText.y = 0;
self.addChild(buttonText);
self.down = function (x, y, obj) {
buttonGraphics.scaleX = 0.9;
buttonGraphics.scaleY = 0.9;
};
self.up = function (x, y, obj) {
buttonGraphics.scaleX = 1.0;
buttonGraphics.scaleY = 1.0;
};
return self;
});
var Vehicle = Container.expand(function (carData, isMotorcycle, isVan) {
var self = Container.call(this);
self.carData = carData;
self.inspected = false;
self.repaired = false;
self.isMotorcycle = isMotorcycle || false;
self.isVan = isVan || false;
var assetPrefix = self.isVan ? 'van' : self.isMotorcycle ? 'moto' : 'car';
var assetSuffix = carData.condition === 'damaged' ? 'Damaged' : 'Offer';
var carGraphics = self.attachAsset(assetPrefix + assetSuffix, {
anchorX: 0.5,
anchorY: 0.5
});
var carText = new Text2(carData.make + ' ' + carData.model, {
size: 36,
fill: 0xFFFFFF
});
carText.anchor.set(0.5, 0.5);
carText.x = 0;
carText.y = -80;
self.addChild(carText);
var priceText = new Text2('$' + carData.price.toLocaleString(), {
size: 40,
fill: 0xFFFF00
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 0;
priceText.y = -40;
self.addChild(priceText);
var conditionText = new Text2(carData.condition + ' - ' + carData.mileage + 'k miles', {
size: 28,
fill: 0xFFFFFF
});
conditionText.anchor.set(0.5, 0.5);
conditionText.x = 0;
conditionText.y = 10;
self.addChild(conditionText);
self.updateDisplay = function () {
carGraphics.visible = false;
self.removeChild(carGraphics);
var assetPrefix = self.isVan ? 'van' : self.isMotorcycle ? 'moto' : 'car';
var assetType = assetPrefix + 'Offer';
if (self.carData.actualCondition === 'damaged' && !self.repaired) {
assetType = assetPrefix + 'Damaged';
} else if (self.repaired) {
assetType = assetPrefix + 'Repaired';
}
carGraphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
// Re-create and re-add text elements to ensure they are properly displayed
if (carText && carText.parent) {
self.removeChild(carText);
}
carText = new Text2(self.carData.make + ' ' + self.carData.model, {
size: 36,
fill: 0xFFFFFF
});
carText.anchor.set(0.5, 0.5);
carText.x = 0;
carText.y = -80;
self.addChild(carText);
if (priceText && priceText.parent) {
self.removeChild(priceText);
}
priceText = new Text2('$' + self.carData.price.toLocaleString(), {
size: 40,
fill: 0xFFFF00
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 0;
priceText.y = -40;
self.addChild(priceText);
if (conditionText && conditionText.parent) {
self.removeChild(conditionText);
}
// Use actual condition and mileage for display
var displayCondition = self.repaired ? 'good' : self.carData.actualCondition;
var displayMileage = self.carData.actualMileage || self.carData.mileage;
conditionText = new Text2(displayCondition + ' - ' + displayMileage + 'k miles', {
size: 28,
fill: 0xFFFFFF
});
conditionText.anchor.set(0.5, 0.5);
conditionText.x = 0;
conditionText.y = 10;
self.addChild(conditionText);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x34495e
});
/****
* Game Code
****/
// Game state variables
var playerMoney = storage.playerMoney || 50000;
var currentDay = storage.currentDay || 1;
var playerDebt = storage.playerDebt || 0;
var dailyInterestRate = 0.05; // 5% daily interest
var creditLimit = storage.creditLimit || 50000; // Maximum credit limit
var loanTakenDay = storage.loanTakenDay || 0; // Day when last loan was taken
var totalLoansOutstanding = storage.totalLoansOutstanding || 0; // Total amount in loans
var taxDebt = storage.taxDebt || 0;
var taxDueDate = storage.taxDueDate || 0;
var taxOverdueDate = storage.taxOverdueDate || 0;
var lastTaxDay = storage.lastTaxDay || 0;
var ownedVehicles = [];
var vehiclesInRepair = []; // Track vehicles currently being repaired
var motorcycleUnlocked = storage.motorcycleUnlocked || false;
var vanUnlocked = storage.vanUnlocked || false;
var soundEffectsEnabled = storage.soundEffectsEnabled !== undefined ? storage.soundEffectsEnabled : true;
var ownedMotorcycles = [];
var ownedVans = [];
var motorcyclesInRepair = []; // Track motorcycles currently being repaired
var vansInRepair = []; // Track vans currently being repaired
var dailyMotoOffers = [];
var vehicleType = 'cars'; // 'cars' or 'motorcycles'
// Load owned vehicles from storage
if (storage.vehicleCount) {
for (var i = 0; i < storage.vehicleCount; i++) {
ownedVehicles.push({
make: storage.vehicleMakes[i],
model: storage.vehicleModels[i],
condition: storage.vehicleConditions[i],
actualCondition: storage.vehicleActualConditions[i],
mileage: storage.vehicleMileages[i],
actualMileage: storage.vehicleActualMileages[i] || storage.vehicleMileages[i],
price: storage.vehiclePrices[i],
marketValue: storage.vehicleMarketValues[i],
sellerLying: storage.vehicleSellerLying[i],
id: storage.vehicleIds[i],
repaired: storage.vehicleRepaired[i],
inRepair: storage.vehicleInRepair ? storage.vehicleInRepair[i] : false,
repairCompletionDay: storage.vehicleRepairCompletionDay ? storage.vehicleRepairCompletionDay[i] : 0
});
}
}
// Load repair shop data
if (storage.vehiclesInRepairCount) {
for (var r = 0; r < storage.vehiclesInRepairCount; r++) {
vehiclesInRepair.push({
vehicleId: storage.repairVehicleIds[r],
completionDay: storage.repairCompletionDays[r],
repairDuration: storage.repairDurations[r]
});
}
}
// Load owned motorcycles from storage
if (storage.motorcycleCount) {
for (var m = 0; m < storage.motorcycleCount; m++) {
ownedMotorcycles.push({
make: storage.motorcycleMakes[m],
model: storage.motorcycleModels[m],
condition: storage.motorcycleConditions[m],
actualCondition: storage.motorcycleActualConditions[m],
mileage: storage.motorcycleMileages[m],
actualMileage: storage.motorcycleActualMileages[m] || storage.motorcycleMileages[m],
price: storage.motorcyclePrices[m],
marketValue: storage.motorcycleMarketValues[m],
sellerLying: storage.motorcycleSellerLying[m],
id: storage.motorcycleIds[m],
repaired: storage.motorcycleRepaired[m],
inRepair: storage.motorcycleInRepair ? storage.motorcycleInRepair[m] : false,
repairCompletionDay: storage.motorcycleRepairCompletionDay ? storage.motorcycleRepairCompletionDay[m] : 0
});
}
}
// Load motorcycle repair shop data
if (storage.motorcyclesInRepairCount) {
for (var mr = 0; mr < storage.motorcyclesInRepairCount; mr++) {
motorcyclesInRepair.push({
vehicleId: storage.repairMotoVehicleIds[mr],
completionDay: storage.repairMotoCompletionDays[mr],
repairDuration: storage.repairMotoDurations[mr]
});
}
}
// Load owned vans from storage
if (storage.vanCount) {
for (var v = 0; v < storage.vanCount; v++) {
ownedVans.push({
make: storage.vanMakes[v],
model: storage.vanModels[v],
condition: storage.vanConditions[v],
actualCondition: storage.vanActualConditions[v],
mileage: storage.vanMileages[v],
actualMileage: storage.vanActualMileages[v] || storage.vanMileages[v],
price: storage.vanPrices[v],
marketValue: storage.vanMarketValues[v],
sellerLying: storage.vanSellerLying[v],
id: storage.vanIds[v],
repaired: storage.vanRepaired[v],
inRepair: storage.vanInRepair ? storage.vanInRepair[v] : false,
repairCompletionDay: storage.vanRepairCompletionDay ? storage.vanRepairCompletionDay[v] : 0
});
}
}
// Load van repair shop data
if (storage.vansInRepairCount) {
for (var vr = 0; vr < storage.vansInRepairCount; vr++) {
vansInRepair.push({
vehicleId: storage.repairVanVehicleIds[vr],
completionDay: storage.repairVanCompletionDays[vr],
repairDuration: storage.repairVanDurations[vr]
});
}
}
var dailyOffers = [];
var selectedVehicle = null;
var gameState = 'daily_offers'; // 'daily_offers', 'vehicle_selected', 'owned_vehicles'
// Car data arrays
var carMakes = ['Toyota', 'Honda', 'Ford', 'Chevrolet', 'BMW', 'Mercedes', 'Audi', 'Nissan', 'Volkswagen', 'Hyundai'];
var carModels = ['Sedan', 'SUV', 'Coupe', 'Hatchback', 'Wagon', 'Convertible', 'Truck', 'Compact'];
var conditions = ['excellent', 'good', 'fair', 'poor', 'damaged'];
// Motorcycle data arrays
var motoMakes = ['Harley-Davidson', 'Yamaha', 'Honda', 'Kawasaki', 'Suzuki', 'Ducati', 'BMW', 'Triumph', 'Indian', 'KTM'];
var motoModels = ['Cruiser', 'Sport', 'Touring', 'Adventure', 'Naked', 'Chopper', 'Cafe Racer', 'Scooter'];
// Van data arrays
var vanMakes = ['Ford', 'Chevrolet', 'Mercedes', 'Nissan', 'Isuzu', 'Ram', 'Iveco', 'Volkswagen', 'Toyota', 'Peugeot'];
var vanModels = ['Transit', 'Express', 'Sprinter', 'ProMaster', 'NV200', 'Cargo Van', 'Panel Van', 'Box Truck'];
// UI Elements
var moneyText = new Text2('Money: $' + playerMoney.toLocaleString(), {
size: 50,
fill: 0x2ECC71
});
moneyText.anchor.set(0, 0);
moneyText.x = 120;
moneyText.y = 50;
LK.gui.topLeft.addChild(moneyText);
var dayText = new Text2('Day ' + currentDay, {
size: 50,
fill: 0xFFFFFF
});
dayText.anchor.set(1, 0);
dayText.x = 0;
dayText.y = 50;
LK.gui.topRight.addChild(dayText);
var debtText = new Text2('Debt: $' + playerDebt.toLocaleString(), {
size: 40,
fill: 0xe74c3c
});
debtText.anchor.set(0, 0);
debtText.x = 120;
debtText.y = 110;
LK.gui.topLeft.addChild(debtText);
var taxText = new Text2('Tax: $' + taxDebt.toLocaleString(), {
size: 40,
fill: 0xe74c3c
});
taxText.anchor.set(0, 0);
taxText.x = 120;
taxText.y = 170;
LK.gui.topLeft.addChild(taxText);
var titleText = new Text2('Car Dealer Tycoon', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 150;
game.addChild(titleText);
var stateText = new Text2('Daily Vehicle Offers', {
size: 50,
fill: 0xECF0F1
});
stateText.anchor.set(0.5, 0);
stateText.x = 2048 / 2;
stateText.y = 250;
game.addChild(stateText);
// Action buttons
var inspectButton = game.addChild(new Button('Inspect ($500)', 0xf39c12));
inspectButton.x = 2048 / 2 - 400;
inspectButton.y = 2200;
inspectButton.visible = false;
var buyButton = game.addChild(new Button('Buy Vehicle', 0x27ae60));
buyButton.x = 2048 / 2 - 150;
buyButton.y = 2200;
buyButton.visible = false;
var negotiateButton = game.addChild(new Button('Negotiate', 0x34495e));
negotiateButton.x = 2048 / 2 + 150;
negotiateButton.y = 2200;
negotiateButton.visible = false;
var repairButton = game.addChild(new Button('Repair (Dynamic)', 0xe67e22));
repairButton.x = 2048 / 2 - 150;
repairButton.y = 2200;
repairButton.visible = false;
var sellButton = game.addChild(new Button('Sell', 0x8e44ad));
sellButton.x = 2048 / 2 + 150;
sellButton.y = 2200;
sellButton.visible = false;
var nextDayButton = game.addChild(new Button('Next Day', 0x2c3e50, 400, 140));
nextDayButton.x = 2048 / 2;
nextDayButton.y = 2350;
var viewOwnedButton = game.addChild(new Button('View Owned Cars', 0x95a5a6));
viewOwnedButton.x = 2048 / 2;
viewOwnedButton.y = 2200;
var loanButton = game.addChild(new Button('Take Loan ($10,000)', 0x3498db));
loanButton.x = 2048 / 2 - 450;
loanButton.y = 2550;
var payDebtButton = game.addChild(new Button('Pay Debt', 0x27ae60));
payDebtButton.x = 2048 / 2 + 3;
payDebtButton.y = 2500;
var payTaxButton = game.addChild(new Button('Pay Tax', 0x27ae60));
payTaxButton.x = 2048 / 2 + 450;
payTaxButton.y = 2550;
var vehicleLocksButton = game.addChild(new Button('Vehicle Locks', 0x7f8c8d, 300, 120));
vehicleLocksButton.x = 1600;
vehicleLocksButton.y = 2400;
vehicleLocksButton.visible = !motorcycleUnlocked || !vanUnlocked;
var settingsButton = game.addChild(new Button('Settings', 0x7f8c8d, 300, 120));
settingsButton.x = -200;
settingsButton.y = 200;
LK.gui.topRight.addChild(settingsButton);
// Switch vehicle button removed - vehicles are now mixed together
// Vehicle display containers
var vehicleContainer = new Container();
vehicleContainer.x = 2048 / 2;
vehicleContainer.y = 800;
game.addChild(vehicleContainer);
var infoText = new Text2('', {
size: 32,
fill: 0xFFFFFF
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 2048 / 2;
infoText.y = 1800;
game.addChild(infoText);
// Generate random vehicle data
function generateRandomVehicle() {
var make = carMakes[Math.floor(Math.random() * carMakes.length)];
var model = carModels[Math.floor(Math.random() * carModels.length)];
var condition = conditions[Math.floor(Math.random() * conditions.length)];
var mileage = Math.floor(Math.random() * 200) + 20;
var basePrice = Math.floor(Math.random() * 40000) + 10000;
// Sellers may lie about condition - both ways
var actualCondition = condition;
var actualMileage = mileage;
var sellerLying = Math.random() < 0.4; // 40% chance of lying
if (sellerLying) {
// 70% chance they claim better condition, 30% chance they hide damage
if (Math.random() < 0.7 && condition !== 'damaged') {
// Claim better condition than actual
var betterConditions = conditions.slice(0, conditions.indexOf(condition));
if (betterConditions.length > 0) {
condition = betterConditions[Math.floor(Math.random() * betterConditions.length)];
}
} else {
// Hide damage - claim undamaged when actually damaged
var worseConditions = conditions.slice(conditions.indexOf(condition) + 1);
if (worseConditions.length > 0) {
actualCondition = worseConditions[Math.floor(Math.random() * worseConditions.length)];
// If actual condition becomes damaged, they claim it's not
if (actualCondition === 'damaged') {
condition = 'poor'; // They claim it's just poor condition
}
}
}
}
// 30% chance they also lie about mileage
if (Math.random() < 0.3) {
// They claim lower mileage than actual
var mileageReduction = Math.floor(Math.random() * 50) + 10; // 10-60k miles less
actualMileage = mileage + mileageReduction;
// Cap at reasonable maximum
if (actualMileage > 300) {
actualMileage = 300;
}
}
// Adjust price based on condition
var priceMultiplier = 1;
switch (actualCondition) {
case 'excellent':
priceMultiplier = 1.2;
break;
case 'good':
priceMultiplier = 1.0;
break;
case 'fair':
priceMultiplier = 0.8;
break;
case 'poor':
priceMultiplier = 0.6;
break;
case 'damaged':
priceMultiplier = 0.4;
break;
}
var price = Math.floor(basePrice * priceMultiplier * (1 - mileage / 300));
// 15% chance that this seller is a scammer
var isScammer = Math.random() < 0.15;
return {
make: make,
model: model,
condition: condition,
actualCondition: actualCondition,
mileage: mileage,
actualMileage: actualMileage,
price: price,
marketValue: Math.floor(price * 1.5),
sellerLying: sellerLying,
isScammer: isScammer,
id: Math.random().toString(36).substr(2, 9)
};
}
// Generate random motorcycle data
function generateRandomMotorcycle() {
var make = motoMakes[Math.floor(Math.random() * motoMakes.length)];
var model = motoModels[Math.floor(Math.random() * motoModels.length)];
var condition = conditions[Math.floor(Math.random() * conditions.length)];
var mileage = Math.floor(Math.random() * 150) + 10; // Lower mileage for motorcycles
var basePrice = Math.floor(Math.random() * 30000) + 5000; // Lower price range for motorcycles
// Sellers may lie about condition - both ways
var actualCondition = condition;
var actualMileage = mileage;
var sellerLying = Math.random() < 0.4; // 40% chance of lying
if (sellerLying) {
// 70% chance they claim better condition, 30% chance they hide damage
if (Math.random() < 0.7 && condition !== 'damaged') {
// Claim better condition than actual
var betterConditions = conditions.slice(0, conditions.indexOf(condition));
if (betterConditions.length > 0) {
condition = betterConditions[Math.floor(Math.random() * betterConditions.length)];
}
} else {
// Hide damage - claim undamaged when actually damaged
var worseConditions = conditions.slice(conditions.indexOf(condition) + 1);
if (worseConditions.length > 0) {
actualCondition = worseConditions[Math.floor(Math.random() * worseConditions.length)];
// If actual condition becomes damaged, they claim it's not
if (actualCondition === 'damaged') {
condition = 'poor'; // They claim it's just poor condition
}
}
}
}
// 30% chance they also lie about mileage
if (Math.random() < 0.3) {
// They claim lower mileage than actual
var mileageReduction = Math.floor(Math.random() * 40) + 10; // 10-50k miles less
actualMileage = mileage + mileageReduction;
// Cap at reasonable maximum
if (actualMileage > 200) {
actualMileage = 200;
}
}
// Adjust price based on condition
var priceMultiplier = 1;
switch (actualCondition) {
case 'excellent':
priceMultiplier = 1.2;
break;
case 'good':
priceMultiplier = 1.0;
break;
case 'fair':
priceMultiplier = 0.8;
break;
case 'poor':
priceMultiplier = 0.6;
break;
case 'damaged':
priceMultiplier = 0.4;
break;
}
var price = Math.floor(basePrice * priceMultiplier * (1 - mileage / 200));
// 15% chance that this seller is a scammer
var isScammer = Math.random() < 0.15;
return {
make: make,
model: model,
condition: condition,
actualCondition: actualCondition,
mileage: mileage,
actualMileage: actualMileage,
price: price,
marketValue: Math.floor(price * 1.5),
sellerLying: sellerLying,
isScammer: isScammer,
id: Math.random().toString(36).substr(2, 9)
};
}
// Generate random van data
function generateRandomVan() {
var make = vanMakes[Math.floor(Math.random() * vanMakes.length)];
var model = vanModels[Math.floor(Math.random() * vanModels.length)];
var condition = conditions[Math.floor(Math.random() * conditions.length)];
var mileage = Math.floor(Math.random() * 250) + 30; // Higher mileage for vans
var basePrice = Math.floor(Math.random() * 50000) + 20000; // Higher price range for vans
// Sellers may lie about condition - both ways
var actualCondition = condition;
var actualMileage = mileage;
var sellerLying = Math.random() < 0.4; // 40% chance of lying
if (sellerLying) {
// 70% chance they claim better condition, 30% chance they hide damage
if (Math.random() < 0.7 && condition !== 'damaged') {
// Claim better condition than actual
var betterConditions = conditions.slice(0, conditions.indexOf(condition));
if (betterConditions.length > 0) {
condition = betterConditions[Math.floor(Math.random() * betterConditions.length)];
}
} else {
// Hide damage - claim undamaged when actually damaged
var worseConditions = conditions.slice(conditions.indexOf(condition) + 1);
if (worseConditions.length > 0) {
actualCondition = worseConditions[Math.floor(Math.random() * worseConditions.length)];
// If actual condition becomes damaged, they claim it's not
if (actualCondition === 'damaged') {
condition = 'poor'; // They claim it's just poor condition
}
}
}
}
// 30% chance they also lie about mileage
if (Math.random() < 0.3) {
// They claim lower mileage than actual
var mileageReduction = Math.floor(Math.random() * 60) + 20; // 20-80k miles less
actualMileage = mileage + mileageReduction;
// Cap at reasonable maximum
if (actualMileage > 400) {
actualMileage = 400;
}
}
// Adjust price based on condition
var priceMultiplier = 1;
switch (actualCondition) {
case 'excellent':
priceMultiplier = 1.2;
break;
case 'good':
priceMultiplier = 1.0;
break;
case 'fair':
priceMultiplier = 0.8;
break;
case 'poor':
priceMultiplier = 0.6;
break;
case 'damaged':
priceMultiplier = 0.4;
break;
}
var price = Math.floor(basePrice * priceMultiplier * (1 - mileage / 400));
// 15% chance that this seller is a scammer
var isScammer = Math.random() < 0.15;
return {
make: make,
model: model,
condition: condition,
actualCondition: actualCondition,
mileage: mileage,
actualMileage: actualMileage,
price: price,
marketValue: Math.floor(price * 1.5),
sellerLying: sellerLying,
isScammer: isScammer,
id: Math.random().toString(36).substr(2, 9),
isVan: true
};
}
// Generate daily offers (mixed cars and motorcycles if unlocked)
function generateDailyOffers() {
dailyOffers = [];
var numOffers = Math.floor(Math.random() * 3) + 2;
for (var i = 0; i < numOffers; i++) {
var randomType = Math.random();
// If both motorcycles and vans are unlocked
if (motorcycleUnlocked && vanUnlocked) {
if (randomType < 0.3) {
// 30% chance for motorcycle
var motoOffer = generateRandomMotorcycle();
motoOffer.isMotorcycle = true;
dailyOffers.push(motoOffer);
} else if (randomType < 0.5) {
// 20% chance for van
var vanOffer = generateRandomVan();
vanOffer.isVan = true;
dailyOffers.push(vanOffer);
} else {
// 50% chance for car
dailyOffers.push(generateRandomVehicle());
}
} else if (motorcycleUnlocked && Math.random() < 0.4) {
// 40% chance for motorcycle
var motoOffer = generateRandomMotorcycle();
motoOffer.isMotorcycle = true; // Mark as motorcycle
dailyOffers.push(motoOffer);
} else if (vanUnlocked && Math.random() < 0.3) {
// 30% chance for van
var vanOffer = generateRandomVan();
vanOffer.isVan = true;
dailyOffers.push(vanOffer);
} else {
dailyOffers.push(generateRandomVehicle());
}
}
}
// Generate daily motorcycle offers
function generateDailyMotoOffers() {
dailyMotoOffers = [];
var numOffers = Math.floor(Math.random() * 3) + 2;
for (var i = 0; i < numOffers; i++) {
dailyMotoOffers.push(generateRandomMotorcycle());
}
}
// Display vehicles
function displayVehicles(vehicles) {
vehicleContainer.removeChildren();
for (var i = 0; i < vehicles.length; i++) {
var isMotorcycle = vehicles[i].isMotorcycle || false;
var isVan = vehicles[i].isVan || false;
var vehicle = new Vehicle(vehicles[i], isMotorcycle, isVan);
vehicle.x = i % 2 * 600 - 300;
vehicle.y = Math.floor(i / 2) * 380;
vehicleContainer.addChild(vehicle);
vehicle.vehicleData = vehicles[i];
vehicle.down = function (x, y, obj) {
selectedVehicle = obj.vehicleData;
updateUI();
};
// Add buy button for each vehicle
var vehicleBuyButton = new Button('Buy', 0x27ae60, 200, 80);
vehicleBuyButton.x = 0;
vehicleBuyButton.y = 150;
vehicle.addChild(vehicleBuyButton);
// Store vehicle data directly on the button using closure
(function (vehicleData, vehicleIndex) {
vehicleBuyButton.up = function (x, y, obj) {
if (vehicleData && playerMoney >= vehicleData.price) {
playerMoney -= vehicleData.price;
// Check if this seller is a scammer
if (vehicleData.isScammer) {
// Player loses money but gets no vehicle
infoText.setText('SCAMMED! The seller took your money and disappeared!\nYou lost $' + vehicleData.price.toLocaleString() + '!');
LK.effects.flashScreen(0xff0000, 1500); // Red flash for scam
} else {
// Normal purchase - Create a copy of the vehicle data for owned vehicles
var ownedVehicleData = {
make: vehicleData.make,
model: vehicleData.model,
condition: vehicleData.condition,
actualCondition: vehicleData.actualCondition,
mileage: vehicleData.mileage,
actualMileage: vehicleData.actualMileage,
price: vehicleData.price,
marketValue: vehicleData.marketValue,
sellerLying: vehicleData.sellerLying,
id: vehicleData.id,
repaired: false
};
if (vehicleData.isMotorcycle) {
ownedMotorcycles.push(ownedVehicleData);
} else if (vehicleData.isVan) {
ownedVans.push(ownedVehicleData);
} else {
ownedVehicles.push(ownedVehicleData);
}
if (soundEffectsEnabled) LK.getSound('purchase').play();
}
// Remove from daily offers in both cases
for (var j = 0; j < dailyOffers.length; j++) {
if (dailyOffers[j].id === vehicleData.id) {
dailyOffers.splice(j, 1);
break;
}
}
selectedVehicle = null;
updateMoneyDisplay();
displayVehicles(dailyOffers);
updateUI();
saveGame();
}
};
})(vehicles[i], i);
}
}
// Update UI based on game state
function updateUI() {
inspectButton.visible = false;
buyButton.visible = false;
negotiateButton.visible = false;
repairButton.visible = false;
sellButton.visible = false;
expertiseButton.visible = false;
if (gameState === 'daily_offers' && selectedVehicle) {
inspectButton.visible = true;
buyButton.visible = true;
negotiateButton.visible = true;
expertiseButton.visible = true;
// Calculate expertise cost based on vehicle price (15-20% of price)
var expertiseCost = Math.floor(selectedVehicle.price * (Math.random() * 0.05 + 0.15));
// Minimum expertise cost of $1000
if (expertiseCost < 1000) {
expertiseCost = 1000;
}
// Update expertise button text with dynamic cost
expertiseButton.children[0].setText('Expertise ($' + expertiseCost.toLocaleString() + ')');
infoText.setText('Selected: ' + selectedVehicle.make + ' ' + selectedVehicle.model + '\nCondition: ' + selectedVehicle.condition + '\nMileage: ' + selectedVehicle.mileage + 'k miles' + '\nPrice: $' + selectedVehicle.price.toLocaleString());
} else if (gameState === 'owned_vehicles' && selectedVehicle) {
if (selectedVehicle.actualCondition === 'damaged' && !selectedVehicle.repaired) {
repairButton.visible = true;
} else {
sellButton.visible = true;
}
infoText.setText('Owned: ' + selectedVehicle.make + ' ' + selectedVehicle.model + '\nCondition: ' + selectedVehicle.actualCondition + '\nMileage: ' + selectedVehicle.actualMileage + 'k miles' + '\nMarket Value: $' + selectedVehicle.marketValue.toLocaleString());
} else {
infoText.setText('Select a vehicle to view options');
}
}
// Add expertise button
var expertiseButton = game.addChild(new Button('Expertise (Dynamic)', 0x9b59b6));
expertiseButton.x = 2048 / 2 + 400;
expertiseButton.y = 2200;
expertiseButton.visible = false;
// Button event handlers
inspectButton.up = function (x, y, obj) {
if (selectedVehicle && playerMoney >= 500) {
playerMoney -= 500;
selectedVehicle.inspected = true;
selectedVehicle.condition = selectedVehicle.actualCondition;
if (soundEffectsEnabled) LK.getSound('inspect').play();
updateMoneyDisplay();
displayVehicles(dailyOffers);
updateUI();
if (selectedVehicle.sellerLying || selectedVehicle.mileage !== selectedVehicle.actualMileage) {
var lieText = 'Inspection revealed the seller was lying!\n';
if (selectedVehicle.sellerLying) {
lieText += 'Actual condition: ' + selectedVehicle.actualCondition + '\n';
}
if (selectedVehicle.mileage !== selectedVehicle.actualMileage) {
lieText += 'Actual mileage: ' + selectedVehicle.actualMileage + 'k miles';
}
infoText.setText(lieText);
} else {
infoText.setText('Inspection confirmed seller was honest.');
}
}
};
expertiseButton.up = function (x, y, obj) {
if (selectedVehicle) {
// Calculate expertise cost based on vehicle price (15-20% of price)
var expertiseCost = Math.floor(selectedVehicle.price * (Math.random() * 0.05 + 0.15));
// Minimum expertise cost of $1000
if (expertiseCost < 1000) {
expertiseCost = 1000;
}
if (playerMoney >= expertiseCost) {
playerMoney -= expertiseCost;
selectedVehicle.inspected = true;
selectedVehicle.condition = selectedVehicle.actualCondition;
if (soundEffectsEnabled) LK.getSound('inspect').play();
updateMoneyDisplay();
displayVehicles(dailyOffers);
updateUI();
var detailsText = 'EXPERTISE REPORT (Cost: $' + expertiseCost.toLocaleString() + '):\n';
detailsText += 'True Condition: ' + selectedVehicle.actualCondition + '\n';
detailsText += 'Claimed Mileage: ' + selectedVehicle.mileage + 'k miles\n';
detailsText += 'Actual Mileage: ' + selectedVehicle.actualMileage + 'k miles\n';
detailsText += 'Mileage Honest: ' + (selectedVehicle.mileage === selectedVehicle.actualMileage ? 'YES' : 'NO') + '\n';
detailsText += 'Seller Honest: ' + (selectedVehicle.sellerLying ? 'NO' : 'YES') + '\n';
detailsText += 'Market Value: $' + selectedVehicle.marketValue.toLocaleString() + '\n';
detailsText += 'Seller Trustworthy: ' + (selectedVehicle.isScammer ? 'SUSPICIOUS - POSSIBLE SCAMMER!' : 'YES') + '\n';
detailsText += 'Recommended Action: ';
if (selectedVehicle.isScammer) {
detailsText += 'AVOID - HIGH SCAM RISK!';
} else if (selectedVehicle.price < selectedVehicle.marketValue * 0.8) {
detailsText += 'BUY - Good Deal';
} else if (selectedVehicle.price > selectedVehicle.marketValue * 1.2) {
detailsText += 'AVOID - Overpriced';
} else {
detailsText += 'NEGOTIATE - Fair Price';
}
infoText.setText(detailsText);
} else {
infoText.setText('Not enough money! Expertise costs $' + expertiseCost.toLocaleString());
}
}
};
buyButton.up = function (x, y, obj) {
if (selectedVehicle && playerMoney >= selectedVehicle.price) {
playerMoney -= selectedVehicle.price;
// Check if this seller is a scammer
if (selectedVehicle.isScammer) {
// Player loses money but gets no vehicle
infoText.setText('SCAMMED! The seller took your money and disappeared!\nYou lost $' + selectedVehicle.price.toLocaleString() + '!');
LK.effects.flashScreen(0xff0000, 1500); // Red flash for scam
} else {
// Normal purchase
selectedVehicle.actualCondition = selectedVehicle.actualCondition;
if (selectedVehicle.isMotorcycle) {
ownedMotorcycles.push(selectedVehicle);
} else if (selectedVehicle.isVan) {
ownedVans.push(selectedVehicle);
} else {
ownedVehicles.push(selectedVehicle);
}
if (soundEffectsEnabled) LK.getSound('purchase').play();
}
// Remove from daily offers in both cases
for (var i = 0; i < dailyOffers.length; i++) {
if (dailyOffers[i].id === selectedVehicle.id) {
dailyOffers.splice(i, 1);
break;
}
}
selectedVehicle = null;
updateMoneyDisplay();
displayVehicles(dailyOffers);
updateUI();
saveGame();
}
};
negotiateButton.up = function (x, y, obj) {
if (selectedVehicle) {
var reduction = Math.floor(selectedVehicle.price * (Math.random() * 0.2 + 0.05));
selectedVehicle.price -= reduction;
displayVehicles(dailyOffers);
updateUI();
infoText.setText('Negotiated $' + reduction.toLocaleString() + ' off the price!');
}
};
repairButton.up = function (x, y, obj) {
if (selectedVehicle) {
// Calculate repair cost based on vehicle price (10-25% of price)
var repairCost = Math.floor(selectedVehicle.price * (Math.random() * 0.15 + 0.10));
// Minimum repair cost of $1000
if (repairCost < 1000) {
repairCost = 1000;
}
if (playerMoney >= repairCost) {
playerMoney -= repairCost;
// Calculate repair duration based on damage level
var repairDuration = 1; // Default 1 day
if (selectedVehicle.actualCondition === 'damaged') {
repairDuration = Math.floor(Math.random() * 3) + 1; // 1-3 days for damaged
} else if (selectedVehicle.actualCondition === 'poor') {
repairDuration = 1; // 1 day for poor
}
// Move vehicle to repair shop
var repairData = {
vehicleId: selectedVehicle.id,
completionDay: currentDay + repairDuration,
repairDuration: repairDuration
};
vehiclesInRepair.push(repairData);
// Mark vehicle as in repair but not completed
for (var k = 0; k < ownedVehicles.length; k++) {
if (ownedVehicles[k].id === selectedVehicle.id) {
ownedVehicles[k].inRepair = true;
ownedVehicles[k].repairCompletionDay = currentDay + repairDuration;
break;
}
}
if (soundEffectsEnabled) LK.getSound('repair').play();
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
infoText.setText('Vehicle sent to repair shop for $' + repairCost.toLocaleString() + '!\nWill be ready in ' + repairDuration + ' day(s).');
} else {
infoText.setText('Not enough money! Repair costs $' + repairCost.toLocaleString());
}
}
};
sellButton.up = function (x, y, obj) {
if (selectedVehicle) {
var salePrice = Math.floor(selectedVehicle.marketValue * (Math.random() * 0.3 + 0.8));
playerMoney += salePrice;
// Remove from owned vehicles
for (var i = 0; i < ownedVehicles.length; i++) {
if (ownedVehicles[i].id === selectedVehicle.id) {
ownedVehicles.splice(i, 1);
break;
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
infoText.setText('Sold for $' + salePrice.toLocaleString() + '!');
}
};
nextDayButton.up = function (x, y, obj) {
currentDay++;
selectedVehicle = null;
generateDailyOffers();
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
dayText.setText('Day ' + currentDay);
displayVehicles(dailyOffers);
updateUI();
// Add random daily expenses
var dailyExpenses = Math.floor(Math.random() * 5000) + 1000; // Between $1000-$6000
playerMoney -= dailyExpenses;
var expenseText = 'Daily expenses: $' + dailyExpenses.toLocaleString() + ' (rent, utilities, staff wages)';
// Add maintenance costs for owned vehicles
var maintenanceCosts = applyMaintenanceCosts();
if (maintenanceCosts > 0) {
expenseText += '\nVehicle maintenance: $' + maintenanceCosts.toLocaleString();
}
// Add insurance costs based on number of owned vehicles
var insuranceCost = ownedVehicles.length * 150;
if (insuranceCost > 0) {
playerMoney -= insuranceCost;
expenseText += '\nInsurance: $' + insuranceCost.toLocaleString();
}
// Random unexpected repairs (10% chance per owned vehicle)
var unexpectedRepairs = 0;
for (var i = 0; i < ownedVehicles.length; i++) {
if (Math.random() < 0.1) {
var repairCost = Math.floor(Math.random() * 2000) + 500;
unexpectedRepairs += repairCost;
}
}
if (unexpectedRepairs > 0) {
playerMoney -= unexpectedRepairs;
expenseText += '\nUnexpected repairs: $' + unexpectedRepairs.toLocaleString();
}
// Apply vehicle depreciation
applyVehicleDepreciation();
// Update repair progress and check for completed repairs
var completedRepairs = [];
for (var r = vehiclesInRepair.length - 1; r >= 0; r--) {
// Decrease remaining repair days
vehiclesInRepair[r].repairDuration--;
// Update vehicle repair completion day display
for (var v = 0; v < ownedVehicles.length; v++) {
if (ownedVehicles[v].id === vehiclesInRepair[r].vehicleId) {
ownedVehicles[v].repairCompletionDay = currentDay + vehiclesInRepair[r].repairDuration;
break;
}
}
// Check if repair is completed (0 days remaining)
if (vehiclesInRepair[r].repairDuration <= 0) {
completedRepairs.push(vehiclesInRepair[r]);
vehiclesInRepair.splice(r, 1);
}
}
// Complete repairs and update vehicle data
for (var c = 0; c < completedRepairs.length; c++) {
var completedRepair = completedRepairs[c];
for (var v = 0; v < ownedVehicles.length; v++) {
if (ownedVehicles[v].id === completedRepair.vehicleId) {
ownedVehicles[v].repaired = true;
ownedVehicles[v].actualCondition = 'good';
ownedVehicles[v].marketValue = Math.floor(ownedVehicles[v].marketValue * 1.5);
ownedVehicles[v].inRepair = false;
delete ownedVehicles[v].repairCompletionDay;
break;
}
}
}
// Update motorcycle repair progress and check for completed repairs
var completedMotoRepairs = [];
for (var mr = motorcyclesInRepair.length - 1; mr >= 0; mr--) {
// Decrease remaining repair days
motorcyclesInRepair[mr].repairDuration--;
// Update motorcycle repair completion day display
for (var mv = 0; mv < ownedMotorcycles.length; mv++) {
if (ownedMotorcycles[mv].id === motorcyclesInRepair[mr].vehicleId) {
ownedMotorcycles[mv].repairCompletionDay = currentDay + motorcyclesInRepair[mr].repairDuration;
break;
}
}
// Check if repair is completed (0 days remaining)
if (motorcyclesInRepair[mr].repairDuration <= 0) {
completedMotoRepairs.push(motorcyclesInRepair[mr]);
motorcyclesInRepair.splice(mr, 1);
}
}
// Complete motorcycle repairs and update motorcycle data
for (var mc = 0; mc < completedMotoRepairs.length; mc++) {
var completedMotoRepair = completedMotoRepairs[mc];
for (var mv = 0; mv < ownedMotorcycles.length; mv++) {
if (ownedMotorcycles[mv].id === completedMotoRepair.vehicleId) {
ownedMotorcycles[mv].repaired = true;
ownedMotorcycles[mv].actualCondition = 'good';
ownedMotorcycles[mv].marketValue = Math.floor(ownedMotorcycles[mv].marketValue * 1.5);
ownedMotorcycles[mv].inRepair = false;
delete ownedMotorcycles[mv].repairCompletionDay;
break;
}
}
}
// Show repair completion message
var totalCompletedRepairs = completedRepairs.length + completedMotoRepairs.length;
if (totalCompletedRepairs > 0) {
expenseText += '\n' + totalCompletedRepairs + ' vehicle(s) completed repair and ready for sale!';
LK.effects.flashScreen(0x2ecc71, 1000); // Green flash for completed repairs
}
// Apply daily interest on debt
var interestCharge = 0;
if (playerDebt > 0) {
interestCharge = Math.floor(playerDebt * dailyInterestRate);
playerDebt += interestCharge;
expenseText += '\nDebt interest: $' + interestCharge.toLocaleString();
}
// Check for loan seizure (5 days after loan was taken)
if (playerDebt > 0 && loanTakenDay > 0 && currentDay > loanTakenDay + 5) {
var seizureAmount = Math.floor(playerDebt * 1.5); // 50% more than debt
var actualSeizureAmount = 0;
var seizedVehicles = [];
// First seize money
if (playerMoney > 0) {
var moneySeized = Math.min(playerMoney, seizureAmount);
playerMoney -= moneySeized;
actualSeizureAmount += moneySeized;
seizureAmount -= moneySeized;
}
// Then seize vehicles if more seizure needed
if (seizureAmount > 0) {
// Seize cars
for (var i = ownedVehicles.length - 1; i >= 0 && seizureAmount > 0; i--) {
var vehicle = ownedVehicles[i];
if (vehicle.marketValue <= seizureAmount) {
seizedVehicles.push(vehicle.make + ' ' + vehicle.model);
actualSeizureAmount += vehicle.marketValue;
seizureAmount -= vehicle.marketValue;
ownedVehicles.splice(i, 1);
}
}
// Seize motorcycles
for (var i = ownedMotorcycles.length - 1; i >= 0 && seizureAmount > 0; i--) {
var vehicle = ownedMotorcycles[i];
if (vehicle.marketValue <= seizureAmount) {
seizedVehicles.push(vehicle.make + ' ' + vehicle.model + ' (Motorcycle)');
actualSeizureAmount += vehicle.marketValue;
seizureAmount -= vehicle.marketValue;
ownedMotorcycles.splice(i, 1);
}
}
// Seize vans
for (var i = ownedVans.length - 1; i >= 0 && seizureAmount > 0; i--) {
var vehicle = ownedVans[i];
if (vehicle.marketValue <= seizureAmount) {
seizedVehicles.push(vehicle.make + ' ' + vehicle.model + ' (Van)');
actualSeizureAmount += vehicle.marketValue;
seizureAmount -= vehicle.marketValue;
ownedVans.splice(i, 1);
}
}
}
// Clear debt and reset loan tracking after seizure
playerDebt = 0;
totalLoansOutstanding = 0;
loanTakenDay = 0;
var seizureText = 'LOAN SEIZURE! Assets worth $' + actualSeizureAmount.toLocaleString() + ' seized for unpaid loans!';
if (seizedVehicles.length > 0) {
seizureText += '\nVehicles seized: ' + seizedVehicles.join(', ');
}
expenseText += '\n' + seizureText;
LK.effects.flashScreen(0xff0000, 2000); // Red flash for seizure
// Update displays after seizure
if (gameState === 'owned_vehicles') {
displayOwnedVehicles();
}
}
// Tax system - every 7 days
if (currentDay % 7 === 1 && currentDay > lastTaxDay) {
// Calculate total vehicle value
var totalVehicleValue = 0;
for (var i = 0; i < ownedVehicles.length; i++) {
totalVehicleValue += ownedVehicles[i].marketValue;
}
// Tax is 8% of total assets (money + vehicles)
var taxAmount = Math.floor((playerMoney + totalVehicleValue) * 0.08);
taxDebt += taxAmount;
taxDueDate = currentDay + 2; // 2 days to pay
taxOverdueDate = currentDay + 2; // Start charging interest after 2 days
lastTaxDay = currentDay;
expenseText += '\nTAX DUE: $' + taxAmount.toLocaleString() + ' (due in 2 days)';
LK.effects.flashScreen(0xffa500, 1000); // Orange flash for tax notice
}
// Apply tax interest if overdue (after 2 days)
if (taxDebt > 0 && currentDay > taxOverdueDate) {
var taxInterest = Math.floor(taxDebt * 0.15); // 15% daily interest
taxDebt += taxInterest;
expenseText += '\nTax interest: $' + taxInterest.toLocaleString() + ' (15% daily)';
}
// Tax seizure after 14 days of unpaid tax debt
if (taxDebt > 0 && currentDay > taxDueDate + 14) {
var seizureAmount = Math.floor(taxDebt * 1.5); // 50% more than tax debt
var actualSeizureAmount = 0;
// First seize money
if (playerMoney > 0) {
var moneySeized = Math.min(playerMoney, seizureAmount);
playerMoney -= moneySeized;
actualSeizureAmount += moneySeized;
seizureAmount -= moneySeized;
}
// Then seize vehicles if more seizure needed
if (seizureAmount > 0 && ownedVehicles.length > 0) {
var vehiclesSeized = [];
for (var i = ownedVehicles.length - 1; i >= 0 && seizureAmount > 0; i--) {
var vehicle = ownedVehicles[i];
if (vehicle.marketValue <= seizureAmount) {
vehiclesSeized.push(vehicle.make + ' ' + vehicle.model);
actualSeizureAmount += vehicle.marketValue;
seizureAmount -= vehicle.marketValue;
ownedVehicles.splice(i, 1);
}
}
}
// Clear tax debt after seizure
taxDebt = 0;
taxDueDate = 0;
taxOverdueDate = 0;
var seizureText = 'TAX SEIZURE! Assets worth $' + actualSeizureAmount.toLocaleString() + ' seized for unpaid taxes!';
if (vehiclesSeized.length > 0) {
seizureText += '\nVehicles seized: ' + vehiclesSeized.join(', ');
}
expenseText += '\n' + seizureText;
LK.effects.flashScreen(0xff0000, 2000); // Red flash for seizure
// Update displays after seizure
if (gameState === 'owned_vehicles') {
displayOwnedVehicles();
}
}
updateMoneyDisplay();
updateDebtDisplay();
updateTaxDisplay();
infoText.setText(expenseText);
saveGame();
};
viewOwnedButton.up = function (x, y, obj) {
if (gameState === 'daily_offers') {
gameState = 'owned_vehicles';
stateText.setText('Owned Vehicles & Motorcycles');
displayOwnedVehicles();
} else {
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
}
selectedVehicle = null;
updateUI();
};
loanButton.up = function (x, y, obj) {
var loanAmount = 10000;
// Check if player can take more loans (credit limit)
if (totalLoansOutstanding + loanAmount > creditLimit) {
infoText.setText('Loan denied! Credit limit reached.\nCredit limit: $' + creditLimit.toLocaleString() + '\nOutstanding loans: $' + totalLoansOutstanding.toLocaleString());
return;
}
playerMoney += loanAmount;
playerDebt += loanAmount;
totalLoansOutstanding += loanAmount;
loanTakenDay = currentDay; // Track when loan was taken
updateMoneyDisplay();
updateDebtDisplay();
saveGame();
infoText.setText('Loan approved! You received $' + loanAmount.toLocaleString() + '\nDaily interest: 5%\nDue in 5 days or 50% penalty applies');
};
payDebtButton.up = function (x, y, obj) {
if (playerDebt > 0 && playerMoney > 0) {
var paymentAmount = Math.min(playerMoney, playerDebt);
playerMoney -= paymentAmount;
playerDebt -= paymentAmount;
totalLoansOutstanding -= paymentAmount; // Reduce outstanding loans
if (totalLoansOutstanding < 0) totalLoansOutstanding = 0;
updateMoneyDisplay();
updateDebtDisplay();
saveGame();
infoText.setText('Paid $' + paymentAmount.toLocaleString() + ' towards debt!\nRemaining debt: $' + playerDebt.toLocaleString());
} else if (playerDebt <= 0) {
infoText.setText('You have no debt to pay!');
} else {
infoText.setText('You need money to pay your debt!');
}
};
payTaxButton.up = function (x, y, obj) {
if (taxDebt > 0 && playerMoney > 0) {
var paymentAmount = Math.min(playerMoney, taxDebt);
playerMoney -= paymentAmount;
taxDebt -= paymentAmount;
updateMoneyDisplay();
updateTaxDisplay();
saveGame();
infoText.setText('Paid $' + paymentAmount.toLocaleString() + ' towards tax!\nRemaining tax: $' + taxDebt.toLocaleString());
} else if (taxDebt <= 0) {
infoText.setText('You have no tax to pay!');
} else {
infoText.setText('You need money to pay your tax!');
}
};
settingsButton.up = function (x, y, obj) {
// Show settings menu
gameState = 'settings';
stateText.setText('Settings');
vehicleContainer.removeChildren();
// Create sound effects toggle button
var soundToggleText = soundEffectsEnabled ? 'Sound Effects: ON' : 'Sound Effects: OFF';
var soundToggleBtn = new Button(soundToggleText, soundEffectsEnabled ? 0x2ecc71 : 0xe74c3c, 400, 120);
soundToggleBtn.x = 0;
soundToggleBtn.y = -150;
vehicleContainer.addChild(soundToggleBtn);
soundToggleBtn.up = function () {
soundEffectsEnabled = !soundEffectsEnabled;
saveGame();
// Refresh settings menu
settingsButton.up();
};
// Create reset game button with warning
var resetBtn = new Button('Reset Game', 0xe74c3c, 400, 120);
resetBtn.x = 0;
resetBtn.y = 150;
vehicleContainer.addChild(resetBtn);
resetBtn.up = function () {
// Show confirmation warning
gameState = 'reset_confirmation';
stateText.setText('Reset Confirmation');
vehicleContainer.removeChildren();
var warningText = new Text2('WARNING!\nThis will delete ALL your progress!\nAre you sure?', {
size: 48,
fill: 0xff0000
});
warningText.anchor.set(0.5, 0.5);
warningText.x = 0;
warningText.y = -100;
vehicleContainer.addChild(warningText);
var confirmBtn = new Button('YES - Reset Everything', 0xe74c3c, 400, 120);
confirmBtn.x = -250;
confirmBtn.y = 100;
vehicleContainer.addChild(confirmBtn);
confirmBtn.up = function () {
// Clear all stored data
delete storage.playerMoney;
delete storage.currentDay;
delete storage.playerDebt;
delete storage.creditLimit;
delete storage.loanTakenDay;
delete storage.totalLoansOutstanding;
delete storage.taxDebt;
delete storage.taxDueDate;
delete storage.taxOverdueDate;
delete storage.lastTaxDay;
delete storage.vehicleCount;
delete storage.vehicleMakes;
delete storage.vehicleModels;
delete storage.vehicleConditions;
delete storage.vehicleActualConditions;
delete storage.vehicleMileages;
delete storage.vehicleActualMileages;
delete storage.vehiclePrices;
delete storage.vehicleMarketValues;
delete storage.vehicleSellerLying;
delete storage.vehicleIds;
delete storage.vehicleRepaired;
delete storage.vehicleInRepair;
delete storage.vehicleRepairCompletionDay;
delete storage.vehiclesInRepairCount;
delete storage.repairVehicleIds;
delete storage.repairCompletionDays;
delete storage.repairDurations;
delete storage.motorcycleUnlocked;
delete storage.motorcycleCount;
delete storage.motorcycleMakes;
delete storage.motorcycleModels;
delete storage.motorcycleConditions;
delete storage.motorcycleActualConditions;
delete storage.motorcycleMileages;
delete storage.motorcycleActualMileages;
delete storage.motorcyclePrices;
delete storage.motorcycleMarketValues;
delete storage.motorcycleSellerLying;
delete storage.motorcycleIds;
delete storage.motorcycleRepaired;
delete storage.motorcycleInRepair;
delete storage.motorcycleRepairCompletionDay;
delete storage.motorcyclesInRepairCount;
delete storage.repairMotoVehicleIds;
delete storage.repairMotoCompletionDays;
delete storage.repairMotoDurations;
delete storage.vanUnlocked;
delete storage.vanCount;
delete storage.vanMakes;
delete storage.vanModels;
delete storage.vanConditions;
delete storage.vanActualConditions;
delete storage.vanMileages;
delete storage.vanActualMileages;
delete storage.vanPrices;
delete storage.vanMarketValues;
delete storage.vanSellerLying;
delete storage.vanIds;
delete storage.vanRepaired;
delete storage.vanInRepair;
delete storage.vanRepairCompletionDay;
delete storage.vansInRepairCount;
delete storage.repairVanVehicleIds;
delete storage.repairVanCompletionDays;
delete storage.repairVanDurations;
delete storage.soundEffectsEnabled;
// Reset game state to initial values
playerMoney = 50000;
currentDay = 1;
playerDebt = 0;
creditLimit = 50000;
loanTakenDay = 0;
totalLoansOutstanding = 0;
taxDebt = 0;
taxDueDate = 0;
taxOverdueDate = 0;
lastTaxDay = 0;
ownedVehicles = [];
vehiclesInRepair = [];
motorcycleUnlocked = false;
vanUnlocked = false;
ownedMotorcycles = [];
ownedVans = [];
motorcyclesInRepair = [];
vansInRepair = [];
vehicleType = 'cars';
selectedVehicle = null;
gameState = 'daily_offers';
soundEffectsEnabled = true;
vehicleLocksButton.visible = true;
// Update UI
stateText.setText('Daily Vehicle Offers');
dayText.setText('Day ' + currentDay);
updateMoneyDisplay();
updateDebtDisplay();
updateTaxDisplay();
generateDailyOffers();
displayVehicles(dailyOffers);
updateUI();
};
var cancelBtn = new Button('NO - Keep Progress', 0x2ecc71, 400, 120);
cancelBtn.x = 250;
cancelBtn.y = 100;
vehicleContainer.addChild(cancelBtn);
cancelBtn.up = function () {
// Return to settings
settingsButton.up();
};
};
var backBtn = new Button('Back', 0x95a5a6, 200, 80);
backBtn.x = 0;
backBtn.y = 300;
vehicleContainer.addChild(backBtn);
backBtn.up = function () {
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
updateUI();
};
selectedVehicle = null;
updateUI();
};
vehicleLocksButton.up = function (x, y, obj) {
// Show vehicle locks menu
gameState = 'vehicle_locks';
stateText.setText('Vehicle Locks');
vehicleContainer.removeChildren();
// Create unlock buttons for motorcycles and vans
if (!motorcycleUnlocked) {
var unlockMotoBtn = new Button('Unlock Motorcycles ($100,000)', 0x9b59b6, 400, 120);
unlockMotoBtn.x = 0;
unlockMotoBtn.y = -100;
vehicleContainer.addChild(unlockMotoBtn);
unlockMotoBtn.up = function () {
if (playerMoney >= 100000) {
playerMoney -= 100000;
motorcycleUnlocked = true;
updateMoneyDisplay();
saveGame();
infoText.setText('Motorcycles unlocked! Motorcycle offers will now appear mixed with car offers.');
LK.effects.flashScreen(0x2ecc71, 1000);
// Return to main menu
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
updateUI();
vehicleLocksButton.visible = !motorcycleUnlocked || !vanUnlocked;
} else {
infoText.setText('Not enough money! Need $100,000 to unlock motorcycles.');
}
};
}
if (!vanUnlocked) {
var unlockVanBtn = new Button('Unlock Vans ($250,000)', 0x34495e, 400, 120);
unlockVanBtn.x = 0;
unlockVanBtn.y = motorcycleUnlocked ? -100 : 50;
vehicleContainer.addChild(unlockVanBtn);
unlockVanBtn.up = function () {
if (playerMoney >= 250000) {
playerMoney -= 250000;
vanUnlocked = true;
updateMoneyDisplay();
saveGame();
infoText.setText('Vans unlocked! Van offers will now appear mixed with other vehicle offers.');
LK.effects.flashScreen(0x2ecc71, 1000);
// Return to main menu
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
updateUI();
vehicleLocksButton.visible = !motorcycleUnlocked || !vanUnlocked;
} else {
infoText.setText('Not enough money! Need $250,000 to unlock vans.');
}
};
}
var backBtn = new Button('Back', 0x95a5a6, 200, 80);
backBtn.x = 0;
backBtn.y = 200;
vehicleContainer.addChild(backBtn);
backBtn.up = function () {
gameState = 'daily_offers';
stateText.setText('Daily Vehicle Offers');
displayVehicles(dailyOffers);
updateUI();
};
selectedVehicle = null;
updateUI();
};
// Switch vehicle button functionality removed - vehicles are now mixed together
function displayOwnedVehicles() {
vehicleContainer.removeChildren();
var allOwnedVehicles = ownedVehicles.concat(ownedMotorcycles).concat(ownedVans);
for (var i = 0; i < allOwnedVehicles.length; i++) {
var vehicleData = allOwnedVehicles[i];
var isMotorcycle = i >= ownedVehicles.length && i < ownedVehicles.length + ownedMotorcycles.length;
var isVan = i >= ownedVehicles.length + ownedMotorcycles.length;
var vehicle = new Vehicle(vehicleData, isMotorcycle, isVan);
if (vehicleData.repaired) {
vehicle.repaired = true;
vehicle.updateDisplay();
}
vehicle.x = i % 2 * 600 - 300;
vehicle.y = Math.floor(i / 2) * 380;
vehicleContainer.addChild(vehicle);
vehicle.vehicleData = vehicleData;
vehicle.down = function (x, y, obj) {
selectedVehicle = obj.vehicleData;
updateUI();
};
// Add action buttons for each owned vehicle
if (vehicleData.inRepair) {
// Vehicle is in repair - show status and prevent actions
var daysRemaining = 0;
// Find repair data to get remaining days
var repairArray = isMotorcycle ? motorcyclesInRepair : vehiclesInRepair;
for (var rr = 0; rr < repairArray.length; rr++) {
if (repairArray[rr].vehicleId === vehicleData.id) {
daysRemaining = repairArray[rr].repairDuration;
break;
}
}
var repairStatusText = new Text2('IN REPAIR - ' + daysRemaining + ' day(s) remaining', {
size: 24,
fill: 0xf39c12
});
repairStatusText.anchor.set(0.5, 0.5);
repairStatusText.x = 0;
repairStatusText.y = 150;
vehicle.addChild(repairStatusText);
} else if (vehicleData.actualCondition === 'damaged' && !vehicleData.repaired) {
// Add repair button with dynamic cost
var repairCost = Math.floor(vehicleData.price * (Math.random() * 0.15 + 0.10));
var minRepairCost = isMotorcycle ? 500 : 1000;
if (repairCost < minRepairCost) {
repairCost = minRepairCost;
}
var vehicleRepairButton = new Button('Repair ($' + repairCost.toLocaleString() + ')', 0xe67e22, 200, 60);
vehicleRepairButton.x = -150;
vehicleRepairButton.y = 150;
vehicle.addChild(vehicleRepairButton);
(function (vehicleData, isMotorcycle) {
vehicleRepairButton.up = function (x, y, obj) {
// Calculate repair cost based on vehicle price (10-25% of price)
var repairCost = Math.floor(vehicleData.price * (Math.random() * 0.15 + 0.10));
// Minimum repair cost based on vehicle type
var minRepairCost = isMotorcycle ? 500 : 1000;
if (repairCost < minRepairCost) {
repairCost = minRepairCost;
}
if (playerMoney >= repairCost) {
playerMoney -= repairCost;
// Calculate repair duration based on damage level
var repairDuration = 1; // Default 1 day
if (vehicleData.actualCondition === 'damaged') {
repairDuration = Math.floor(Math.random() * 3) + 1; // 1-3 days for damaged
} else if (vehicleData.actualCondition === 'poor') {
repairDuration = 1; // 1 day for poor
}
// Move vehicle to repair shop
var repairData = {
vehicleId: vehicleData.id,
completionDay: currentDay + repairDuration,
repairDuration: repairDuration
};
if (isMotorcycle) {
motorcyclesInRepair.push(repairData);
// Update the vehicle data in the ownedMotorcycles array
for (var k = 0; k < ownedMotorcycles.length; k++) {
if (ownedMotorcycles[k].id === vehicleData.id) {
ownedMotorcycles[k].inRepair = true;
ownedMotorcycles[k].repairCompletionDay = currentDay + repairDuration;
break;
}
}
} else {
vehiclesInRepair.push(repairData);
// Update the vehicle data in the ownedVehicles array
for (var k = 0; k < ownedVehicles.length; k++) {
if (ownedVehicles[k].id === vehicleData.id) {
ownedVehicles[k].inRepair = true;
ownedVehicles[k].repairCompletionDay = currentDay + repairDuration;
break;
}
}
}
if (soundEffectsEnabled) LK.getSound('repair').play();
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
infoText.setText('Vehicle sent to repair shop for $' + repairCost.toLocaleString() + '!\nWill be ready in ' + repairDuration + ' day(s).');
} else {
infoText.setText('Not enough money! Repair costs $' + repairCost.toLocaleString());
}
};
})(vehicleData, isMotorcycle);
// Add sell button for damaged vehicles (sell as-is for low price)
var damagedSalePrice = Math.floor(vehicleData.marketValue * (Math.random() * 0.20 + 0.30));
var vehicleSellDamagedButton = new Button('Sell LOW ($' + damagedSalePrice.toLocaleString() + ')', 0x8e44ad, 200, 60);
vehicleSellDamagedButton.x = 50;
vehicleSellDamagedButton.y = 150;
vehicle.addChild(vehicleSellDamagedButton);
(function (vehicleData, displayedSalePrice, isMotorcycle) {
vehicleSellDamagedButton.up = function (x, y, obj) {
var salePrice = displayedSalePrice;
playerMoney += salePrice;
// Remove from appropriate owned vehicles array
if (isMotorcycle) {
for (var j = 0; j < ownedMotorcycles.length; j++) {
if (ownedMotorcycles[j].id === vehicleData.id) {
ownedMotorcycles.splice(j, 1);
break;
}
}
} else {
for (var j = 0; j < ownedVehicles.length; j++) {
if (ownedVehicles[j].id === vehicleData.id) {
ownedVehicles.splice(j, 1);
break;
}
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
infoText.setText('Sold damaged vehicle for $' + salePrice.toLocaleString() + '! (Low Price - Could have repaired for higher profit)');
};
})(vehicleData, damagedSalePrice, isMotorcycle);
} else {
// Add sell button with sale price - different pricing for repaired vs unrepaired
var salePrice;
if (vehicleData.repaired) {
// Repaired vehicles sell for 80-95% of market value (high price)
salePrice = Math.floor(vehicleData.marketValue * (Math.random() * 0.15 + 0.80));
} else if (vehicleData.actualCondition === 'damaged') {
// Damaged vehicles sell for 30-50% of market value (low price)
salePrice = Math.floor(vehicleData.marketValue * (Math.random() * 0.20 + 0.30));
} else {
// Other conditions sell for 60-80% of market value (medium price)
salePrice = Math.floor(vehicleData.marketValue * (Math.random() * 0.20 + 0.60));
}
var sellButtonText = 'Sell ($' + salePrice.toLocaleString() + ')';
if (vehicleData.repaired) {
sellButtonText += ' HIGH';
} else if (vehicleData.actualCondition === 'damaged') {
sellButtonText += ' LOW';
}
var vehicleSellButton = new Button(sellButtonText, 0x8e44ad, 200, 60);
vehicleSellButton.x = -100;
vehicleSellButton.y = 150;
vehicle.addChild(vehicleSellButton);
(function (vehicleData, displayedSalePrice, isMotorcycle) {
vehicleSellButton.up = function (x, y, obj) {
var salePrice = displayedSalePrice;
playerMoney += salePrice;
// Remove from appropriate owned vehicles array
if (isMotorcycle) {
for (var j = 0; j < ownedMotorcycles.length; j++) {
if (ownedMotorcycles[j].id === vehicleData.id) {
ownedMotorcycles.splice(j, 1);
break;
}
}
} else {
for (var j = 0; j < ownedVehicles.length; j++) {
if (ownedVehicles[j].id === vehicleData.id) {
ownedVehicles.splice(j, 1);
break;
}
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedVehicles();
updateUI();
saveGame();
var sellMessage = 'Sold for $' + salePrice.toLocaleString() + '!';
if (vehicleData.repaired) {
sellMessage += ' (Repaired - High Price)';
} else if (vehicleData.actualCondition === 'damaged') {
sellMessage += ' (Damaged - Low Price)';
}
infoText.setText(sellMessage);
};
})(vehicleData, salePrice, isMotorcycle);
}
}
}
function displayOwnedMotorcycles() {
vehicleContainer.removeChildren();
for (var i = 0; i < ownedMotorcycles.length; i++) {
var vehicle = new Vehicle(ownedMotorcycles[i], true);
if (ownedMotorcycles[i].repaired) {
vehicle.repaired = true;
vehicle.updateDisplay();
}
vehicle.x = i % 2 * 600 - 300;
vehicle.y = Math.floor(i / 2) * 380;
vehicleContainer.addChild(vehicle);
vehicle.vehicleData = ownedMotorcycles[i];
vehicle.down = function (x, y, obj) {
selectedVehicle = obj.vehicleData;
updateUI();
};
// Add action buttons for each owned motorcycle
if (ownedMotorcycles[i].inRepair) {
// Motorcycle is in repair - show status and prevent actions
var daysRemaining = 0;
// Find repair data to get remaining days
for (var rr = 0; rr < motorcyclesInRepair.length; rr++) {
if (motorcyclesInRepair[rr].vehicleId === ownedMotorcycles[i].id) {
daysRemaining = motorcyclesInRepair[rr].repairDuration;
break;
}
}
var repairStatusText = new Text2('IN REPAIR - ' + daysRemaining + ' day(s) remaining', {
size: 24,
fill: 0xf39c12
});
repairStatusText.anchor.set(0.5, 0.5);
repairStatusText.x = 0;
repairStatusText.y = 150;
vehicle.addChild(repairStatusText);
} else if (ownedMotorcycles[i].actualCondition === 'damaged' && !ownedMotorcycles[i].repaired) {
// Add repair button with dynamic cost
var repairCost = Math.floor(ownedMotorcycles[i].price * (Math.random() * 0.15 + 0.10));
if (repairCost < 500) {
repairCost = 500;
}
var vehicleRepairButton = new Button('Repair ($' + repairCost.toLocaleString() + ')', 0xe67e22, 200, 60);
vehicleRepairButton.x = -150;
vehicleRepairButton.y = 150;
vehicle.addChild(vehicleRepairButton);
(function (vehicleData) {
vehicleRepairButton.up = function (x, y, obj) {
// Calculate repair cost based on vehicle price (10-25% of price)
var repairCost = Math.floor(vehicleData.price * (Math.random() * 0.15 + 0.10));
// Minimum repair cost of $500 for motorcycles
if (repairCost < 500) {
repairCost = 500;
}
if (playerMoney >= repairCost) {
playerMoney -= repairCost;
// Calculate repair duration based on damage level
var repairDuration = 1; // Default 1 day
if (vehicleData.actualCondition === 'damaged') {
repairDuration = Math.floor(Math.random() * 3) + 1; // 1-3 days for damaged
} else if (vehicleData.actualCondition === 'poor') {
repairDuration = 1; // 1 day for poor
}
// Move motorcycle to repair shop
var repairData = {
vehicleId: vehicleData.id,
completionDay: currentDay + repairDuration,
repairDuration: repairDuration
};
motorcyclesInRepair.push(repairData);
// Update the motorcycle data in the ownedMotorcycles array
for (var k = 0; k < ownedMotorcycles.length; k++) {
if (ownedMotorcycles[k].id === vehicleData.id) {
ownedMotorcycles[k].inRepair = true;
ownedMotorcycles[k].repairCompletionDay = currentDay + repairDuration;
break;
}
}
if (soundEffectsEnabled) LK.getSound('repair').play();
updateMoneyDisplay();
displayOwnedMotorcycles();
updateUI();
saveGame();
infoText.setText('Motorcycle sent to repair shop for $' + repairCost.toLocaleString() + '!\nWill be ready in ' + repairDuration + ' day(s).');
} else {
infoText.setText('Not enough money! Repair costs $' + repairCost.toLocaleString());
}
};
})(ownedMotorcycles[i]);
// Add sell button for damaged motorcycles (sell as-is for low price)
var damagedSalePrice = Math.floor(ownedMotorcycles[i].marketValue * (Math.random() * 0.20 + 0.30));
var vehicleSellDamagedButton = new Button('Sell LOW ($' + damagedSalePrice.toLocaleString() + ')', 0x8e44ad, 200, 60);
vehicleSellDamagedButton.x = 50;
vehicleSellDamagedButton.y = 150;
vehicle.addChild(vehicleSellDamagedButton);
(function (vehicleData, displayedSalePrice) {
vehicleSellDamagedButton.up = function (x, y, obj) {
var salePrice = displayedSalePrice;
playerMoney += salePrice;
// Remove from owned motorcycles
for (var j = 0; j < ownedMotorcycles.length; j++) {
if (ownedMotorcycles[j].id === vehicleData.id) {
ownedMotorcycles.splice(j, 1);
break;
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedMotorcycles();
updateUI();
saveGame();
infoText.setText('Sold damaged motorcycle for $' + salePrice.toLocaleString() + '! (Low Price - Could have repaired for higher profit)');
};
})(ownedMotorcycles[i], damagedSalePrice);
} else {
// Add sell button with sale price - different pricing for repaired vs unrepaired
var salePrice;
if (ownedMotorcycles[i].repaired) {
// Repaired motorcycles sell for 80-95% of market value (high price)
salePrice = Math.floor(ownedMotorcycles[i].marketValue * (Math.random() * 0.15 + 0.80));
} else if (ownedMotorcycles[i].actualCondition === 'damaged') {
// Damaged motorcycles sell for 30-50% of market value (low price)
salePrice = Math.floor(ownedMotorcycles[i].marketValue * (Math.random() * 0.20 + 0.30));
} else {
// Other conditions sell for 60-80% of market value (medium price)
salePrice = Math.floor(ownedMotorcycles[i].marketValue * (Math.random() * 0.20 + 0.60));
}
var sellButtonText = 'Sell ($' + salePrice.toLocaleString() + ')';
if (ownedMotorcycles[i].repaired) {
sellButtonText += ' HIGH';
} else if (ownedMotorcycles[i].actualCondition === 'damaged') {
sellButtonText += ' LOW';
}
var vehicleSellButton = new Button(sellButtonText, 0x8e44ad, 200, 60);
vehicleSellButton.x = -100;
vehicleSellButton.y = 150;
vehicle.addChild(vehicleSellButton);
(function (vehicleData, displayedSalePrice) {
vehicleSellButton.up = function (x, y, obj) {
var salePrice = displayedSalePrice;
playerMoney += salePrice;
// Remove from owned motorcycles
for (var j = 0; j < ownedMotorcycles.length; j++) {
if (ownedMotorcycles[j].id === vehicleData.id) {
ownedMotorcycles.splice(j, 1);
break;
}
}
if (soundEffectsEnabled) LK.getSound('sale').play();
selectedVehicle = null;
updateMoneyDisplay();
displayOwnedMotorcycles();
updateUI();
saveGame();
var sellMessage = 'Sold for $' + salePrice.toLocaleString() + '!';
if (vehicleData.repaired) {
sellMessage += ' (Repaired - High Price)';
} else if (vehicleData.actualCondition === 'damaged') {
sellMessage += ' (Damaged - Low Price)';
}
infoText.setText(sellMessage);
};
})(ownedMotorcycles[i], salePrice);
}
}
}
function updateMoneyDisplay() {
moneyText.setText('Money: $' + playerMoney.toLocaleString());
}
function updateDebtDisplay() {
debtText.setText('Debt: $' + playerDebt.toLocaleString());
if (playerDebt > 0) {
debtText.tint = 0xe74c3c; // Red for debt
} else {
debtText.tint = 0x2ecc71; // Green for no debt
}
}
function updateTaxDisplay() {
taxText.setText('Tax: $' + taxDebt.toLocaleString());
if (taxDebt > 0) {
taxText.tint = 0xe74c3c; // Red for tax debt
} else {
taxText.tint = 0x2ecc71; // Green for no tax
}
}
function saveGame() {
storage.playerMoney = playerMoney;
storage.currentDay = currentDay;
storage.playerDebt = playerDebt;
storage.creditLimit = creditLimit;
storage.loanTakenDay = loanTakenDay;
storage.totalLoansOutstanding = totalLoansOutstanding;
storage.taxDebt = taxDebt;
storage.taxDueDate = taxDueDate;
storage.taxOverdueDate = taxOverdueDate;
storage.lastTaxDay = lastTaxDay;
storage.motorcycleUnlocked = motorcycleUnlocked;
storage.vanUnlocked = vanUnlocked;
storage.soundEffectsEnabled = soundEffectsEnabled;
// Store each vehicle property as separate arrays to avoid nested objects
var vehicleCount = ownedVehicles.length;
storage.vehicleCount = vehicleCount;
storage.vehicleMakes = [];
storage.vehicleModels = [];
storage.vehicleConditions = [];
storage.vehicleActualConditions = [];
storage.vehicleMileages = [];
storage.vehicleActualMileages = [];
storage.vehiclePrices = [];
storage.vehicleMarketValues = [];
storage.vehicleSellerLying = [];
storage.vehicleIds = [];
storage.vehicleRepaired = [];
storage.vehicleInRepair = [];
storage.vehicleRepairCompletionDay = [];
for (var i = 0; i < ownedVehicles.length; i++) {
var vehicle = ownedVehicles[i];
storage.vehicleMakes.push(vehicle.make);
storage.vehicleModels.push(vehicle.model);
storage.vehicleConditions.push(vehicle.condition);
storage.vehicleActualConditions.push(vehicle.actualCondition);
storage.vehicleMileages.push(vehicle.mileage);
storage.vehicleActualMileages.push(vehicle.actualMileage);
storage.vehiclePrices.push(vehicle.price);
storage.vehicleMarketValues.push(vehicle.marketValue);
storage.vehicleSellerLying.push(vehicle.sellerLying);
storage.vehicleIds.push(vehicle.id);
storage.vehicleRepaired.push(vehicle.repaired || false);
storage.vehicleInRepair.push(vehicle.inRepair || false);
storage.vehicleRepairCompletionDay.push(vehicle.repairCompletionDay || 0);
}
// Save repair shop data
storage.vehiclesInRepairCount = vehiclesInRepair.length;
storage.repairVehicleIds = [];
storage.repairCompletionDays = [];
storage.repairDurations = [];
for (var r = 0; r < vehiclesInRepair.length; r++) {
storage.repairVehicleIds.push(vehiclesInRepair[r].vehicleId);
storage.repairCompletionDays.push(vehiclesInRepair[r].completionDay);
storage.repairDurations.push(vehiclesInRepair[r].repairDuration);
}
// Save motorcycle data
var motorcycleCount = ownedMotorcycles.length;
storage.motorcycleCount = motorcycleCount;
storage.motorcycleMakes = [];
storage.motorcycleModels = [];
storage.motorcycleConditions = [];
storage.motorcycleActualConditions = [];
storage.motorcycleMileages = [];
storage.motorcycleActualMileages = [];
storage.motorcyclePrices = [];
storage.motorcycleMarketValues = [];
storage.motorcycleSellerLying = [];
storage.motorcycleIds = [];
storage.motorcycleRepaired = [];
storage.motorcycleInRepair = [];
storage.motorcycleRepairCompletionDay = [];
for (var m = 0; m < ownedMotorcycles.length; m++) {
var motorcycle = ownedMotorcycles[m];
storage.motorcycleMakes.push(motorcycle.make);
storage.motorcycleModels.push(motorcycle.model);
storage.motorcycleConditions.push(motorcycle.condition);
storage.motorcycleActualConditions.push(motorcycle.actualCondition);
storage.motorcycleMileages.push(motorcycle.mileage);
storage.motorcycleActualMileages.push(motorcycle.actualMileage);
storage.motorcyclePrices.push(motorcycle.price);
storage.motorcycleMarketValues.push(motorcycle.marketValue);
storage.motorcycleSellerLying.push(motorcycle.sellerLying);
storage.motorcycleIds.push(motorcycle.id);
storage.motorcycleRepaired.push(motorcycle.repaired || false);
storage.motorcycleInRepair.push(motorcycle.inRepair || false);
storage.motorcycleRepairCompletionDay.push(motorcycle.repairCompletionDay || 0);
}
// Save motorcycle repair shop data
storage.motorcyclesInRepairCount = motorcyclesInRepair.length;
storage.repairMotoVehicleIds = [];
storage.repairMotoCompletionDays = [];
storage.repairMotoDurations = [];
for (var mr = 0; mr < motorcyclesInRepair.length; mr++) {
storage.repairMotoVehicleIds.push(motorcyclesInRepair[mr].vehicleId);
storage.repairMotoCompletionDays.push(motorcyclesInRepair[mr].completionDay);
storage.repairMotoDurations.push(motorcyclesInRepair[mr].repairDuration);
}
// Save van data
var vanCount = ownedVans.length;
storage.vanCount = vanCount;
storage.vanMakes = [];
storage.vanModels = [];
storage.vanConditions = [];
storage.vanActualConditions = [];
storage.vanMileages = [];
storage.vanActualMileages = [];
storage.vanPrices = [];
storage.vanMarketValues = [];
storage.vanSellerLying = [];
storage.vanIds = [];
storage.vanRepaired = [];
storage.vanInRepair = [];
storage.vanRepairCompletionDay = [];
for (var v = 0; v < ownedVans.length; v++) {
var van = ownedVans[v];
storage.vanMakes.push(van.make);
storage.vanModels.push(van.model);
storage.vanConditions.push(van.condition);
storage.vanActualConditions.push(van.actualCondition);
storage.vanMileages.push(van.mileage);
storage.vanActualMileages.push(van.actualMileage);
storage.vanPrices.push(van.price);
storage.vanMarketValues.push(van.marketValue);
storage.vanSellerLying.push(van.sellerLying);
storage.vanIds.push(van.id);
storage.vanRepaired.push(van.repaired || false);
storage.vanInRepair.push(van.inRepair || false);
storage.vanRepairCompletionDay.push(van.repairCompletionDay || 0);
}
// Save van repair shop data
storage.vansInRepairCount = vansInRepair.length;
storage.repairVanVehicleIds = [];
storage.repairVanCompletionDays = [];
storage.repairVanDurations = [];
for (var vr = 0; vr < vansInRepair.length; vr++) {
storage.repairVanVehicleIds.push(vansInRepair[vr].vehicleId);
storage.repairVanCompletionDays.push(vansInRepair[vr].completionDay);
storage.repairVanDurations.push(vansInRepair[vr].repairDuration);
}
}
// Add maintenance costs for owned vehicles
function applyMaintenanceCosts() {
var totalMaintenanceCost = 0;
for (var i = 0; i < ownedVehicles.length; i++) {
var vehicle = ownedVehicles[i];
// Higher maintenance cost for damaged vehicles
var baseCost = vehicle.actualCondition === 'damaged' ? 200 : 100;
var maintenanceCost = Math.floor(Math.random() * baseCost) + 50;
totalMaintenanceCost += maintenanceCost;
}
if (totalMaintenanceCost > 0) {
playerMoney -= totalMaintenanceCost;
return totalMaintenanceCost;
}
return 0;
}
// Apply vehicle depreciation
function applyVehicleDepreciation() {
for (var i = 0; i < ownedVehicles.length; i++) {
var vehicle = ownedVehicles[i];
// Vehicles lose 2-5% of their market value each day
var depreciationRate = Math.random() * 0.03 + 0.02;
vehicle.marketValue = Math.floor(vehicle.marketValue * (1 - depreciationRate));
// Minimum market value floor
if (vehicle.marketValue < 1000) {
vehicle.marketValue = 1000;
}
}
}
// Initialize game
updateDebtDisplay();
updateTaxDisplay();
generateDailyOffers();
if (motorcycleUnlocked) {
generateDailyMotoOffers();
}
displayVehicles(dailyOffers);
updateUI();
// Game restart function
function restartGame() {
// Reset all game state variables to initial values
playerMoney = 50000;
currentDay = 1;
playerDebt = 0;
taxDebt = 0;
taxDueDate = 0;
taxOverdueDate = 0;
lastTaxDay = 0;
ownedVehicles = [];
vehiclesInRepair = [];
motorcycleUnlocked = false;
ownedMotorcycles = [];
motorcyclesInRepair = [];
vehicleType = 'cars';
selectedVehicle = null;
gameState = 'daily_offers';
vehicleLocksButton.visible = !motorcycleUnlocked || !vanUnlocked;
// Clear storage
delete storage.playerMoney;
delete storage.currentDay;
delete storage.playerDebt;
delete storage.taxDebt;
delete storage.taxDueDate;
delete storage.taxOverdueDate;
delete storage.lastTaxDay;
delete storage.vehicleCount;
delete storage.vehicleMakes;
delete storage.vehicleModels;
delete storage.vehicleConditions;
delete storage.vehicleActualConditions;
delete storage.vehicleMileages;
delete storage.vehicleActualMileages;
delete storage.vehiclePrices;
delete storage.vehicleMarketValues;
delete storage.vehicleSellerLying;
delete storage.vehicleIds;
delete storage.vehicleRepaired;
delete storage.vehicleInRepair;
delete storage.vehicleRepairCompletionDay;
delete storage.vehiclesInRepairCount;
delete storage.repairVehicleIds;
delete storage.repairCompletionDays;
delete storage.repairDurations;
delete storage.motorcycleUnlocked;
delete storage.motorcycleCount;
delete storage.motorcycleMakes;
delete storage.motorcycleModels;
delete storage.motorcycleConditions;
delete storage.motorcycleActualConditions;
delete storage.motorcycleMileages;
delete storage.motorcycleActualMileages;
delete storage.motorcyclePrices;
delete storage.motorcycleMarketValues;
delete storage.motorcycleSellerLying;
delete storage.motorcycleIds;
delete storage.motorcycleRepaired;
delete storage.motorcycleInRepair;
delete storage.motorcycleRepairCompletionDay;
delete storage.motorcyclesInRepairCount;
delete storage.repairMotoVehicleIds;
delete storage.repairMotoCompletionDays;
delete storage.repairMotoDurations;
// Update UI elements
stateText.setText('Daily Vehicle Offers');
dayText.setText('Day ' + currentDay);
updateMoneyDisplay();
updateDebtDisplay();
updateTaxDisplay();
generateDailyOffers();
displayVehicles(dailyOffers);
updateUI();
infoText.setText('Game restarted! Welcome back to Car Dealer Tycoon!');
}
// Game update loop
game.update = function () {
// Check for game over condition
if (playerMoney < 0) {
LK.showGameOver();
// Reset game state for restart
restartGame();
}
// Check for winning condition
if (playerMoney >= 500000) {
LK.showYouWin();
// Reset game state for restart
restartGame();
}
};