/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	tutorialCompleted: false
});
/**** 
* Classes
****/ 
var Bullet = Container.expand(function (startX, startY, targetEnemy, damage, speed) {
	var self = Container.call(this);
	self.targetEnemy = targetEnemy;
	self.damage = damage || 10;
	self.speed = speed || 5;
	self.x = startX;
	self.y = startY;
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		// Skip bullet update when game is paused (gameSpeed = 0)
		if (gameSpeed === 0) {
			return;
		}
		if (!self.targetEnemy || !self.targetEnemy.parent) {
			self.destroy();
			return;
		}
		var dx = self.targetEnemy.x - self.x;
		var dy = self.targetEnemy.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < self.speed) {
			// Apply damage to target enemy
			var actualDamage = self.damage;
			// Artillery towers deal 40% of enemy's current health as damage
			if (self.type === 'splash') {
				actualDamage = Math.ceil(self.targetEnemy.health * 0.4);
				// AntiAir bullets deal half damage to flying enemies
				if (self.targetEnemy.isFlying) {
					actualDamage = actualDamage * 0.5;
				}
			}
			// Immune enemies take 10% more damage from all bullets
			if (self.targetEnemy.isImmune) {
				actualDamage = actualDamage * 1.1;
			}
			// Immune enemies now take damage from all bullet types
			self.targetEnemy.health -= actualDamage;
			if (self.targetEnemy.health <= 0) {
				self.targetEnemy.health = 0;
			} else {
				self.targetEnemy.healthBar.width = self.targetEnemy.health / self.targetEnemy.maxHealth * 70;
			}
			// Apply special effects based on bullet type
			if (self.type === 'splash') {
				// Create visual splash effect
				var splashEffect = new EffectIndicator(self.targetEnemy.x, self.targetEnemy.y, 'splash');
				game.addChild(splashEffect);
				// Splash damage to nearby enemies
				var splashRadius = CELL_SIZE * 1.5;
				for (var i = 0; i < enemies.length; i++) {
					var otherEnemy = enemies[i];
					if (otherEnemy !== self.targetEnemy) {
						var splashDx = otherEnemy.x - self.targetEnemy.x;
						var splashDy = otherEnemy.y - self.targetEnemy.y;
						var splashDistance = Math.sqrt(splashDx * splashDx + splashDy * splashDy);
						if (splashDistance <= splashRadius) {
							// Apply splash damage (50% of original damage or 20% of enemy health for Artillery)
							var splashDamage;
							if (self.type === 'splash') {
								splashDamage = Math.ceil(otherEnemy.health * 0.2); // 20% of current health for splash
							} else {
								splashDamage = self.damage * 0.5;
							}
							// Immune enemies take 10% more splash damage
							if (otherEnemy.isImmune) {
								splashDamage = splashDamage * 1.1;
							}
							// Immune enemies now take splash damage from all bullet types
							otherEnemy.health -= splashDamage;
							if (otherEnemy.health <= 0) {
								otherEnemy.health = 0;
							} else {
								otherEnemy.healthBar.width = otherEnemy.health / otherEnemy.maxHealth * 70;
							}
						}
					}
				}
			} else if (self.type === 'poison') {
				// Prevent poison effect on immune enemies
				if (!self.targetEnemy.isImmune) {
					// Create visual poison effect
					var poisonEffect = new EffectIndicator(self.targetEnemy.x, self.targetEnemy.y, 'poison');
					game.addChild(poisonEffect);
					// Apply poison effect
					self.targetEnemy.poisoned = true;
					self.targetEnemy.poisonDamage = self.damage * 0.2; // 20% of original damage per tick
					self.targetEnemy.poisonDuration = 300; // 5 seconds at 60 FPS
				}
			} else if (self.type === 'sniper') {
				// Create visual critical hit effect for sniper
				var sniperEffect = new EffectIndicator(self.targetEnemy.x, self.targetEnemy.y, 'sniper');
				game.addChild(sniperEffect);
			}
			self.destroy();
		} else {
			var angle = Math.atan2(dy, dx);
			self.x += Math.cos(angle) * self.speed;
			self.y += Math.sin(angle) * self.speed;
		}
	};
	return self;
});
var DebugCell = Container.expand(function () {
	var self = Container.call(this);
	var cellGraphics = self.attachAsset('cell', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cellGraphics.tint = Math.random() * 0xffffff;
	var debugArrows = [];
	var numberLabel = new Text2('0', {
		size: 30,
		fill: 0xFFFFFF,
		weight: 800
	});
	numberLabel.anchor.set(.5, .5);
	numberLabel.visible = false; // Hide numbers in battlefield
	self.addChild(numberLabel);
	self.update = function () {};
	self.down = function () {
		return;
		if (self.cell.type == 0 || self.cell.type == 1) {
			self.cell.type = self.cell.type == 1 ? 0 : 1;
			if (grid.pathFind()) {
				self.cell.type = self.cell.type == 1 ? 0 : 1;
				grid.pathFind();
				var notification = game.addChild(new Notification("Path is blocked!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 50;
			}
			grid.renderDebug();
		}
	};
	self.removeArrows = function () {
		while (debugArrows.length) {
			self.removeChild(debugArrows.pop());
		}
	};
	self.render = function (data) {
		switch (data.type) {
			case 0:
			case 2:
				{
					if (data.pathId != pathId) {
						self.removeArrows();
						numberLabel.setText("-");
						cellGraphics.tint = 0x880000;
						return;
					}
					numberLabel.visible = false; // Hide numbers in battlefield
					var tint = Math.floor(data.score / maxScore * 0x88);
					var towerInRangeHighlight = false;
					if (selectedTower && data.towersInRange && data.towersInRange.indexOf(selectedTower) !== -1) {
						towerInRangeHighlight = true;
						cellGraphics.tint = 0x0088ff;
					} else {
						cellGraphics.tint = 0x88 - tint << 8 | tint;
					}
					// Remove arrow rendering - no longer display arrows
					break;
				}
			case 1:
				{
					self.removeArrows();
					cellGraphics.tint = 0xaaaaaa;
					numberLabel.visible = false;
					break;
				}
			case 3:
				{
					self.removeArrows();
					cellGraphics.tint = 0x008800;
					numberLabel.visible = false;
					break;
				}
			case 4:
				{
					self.removeArrows();
					cellGraphics.tint = 0x000000; // Black color for castle walls
					numberLabel.visible = false;
					break;
				}
		}
		// numberLabel.setText(Math.floor(data.score / 1000) / 10); // Removed number display
	};
});
// This update method was incorrectly placed here and should be removed
var EffectIndicator = Container.expand(function (x, y, type) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var effectGraphics = self.attachAsset('rangeCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	effectGraphics.blendMode = 1;
	switch (type) {
		case 'splash':
			effectGraphics.tint = 0x33CC00;
			effectGraphics.width = effectGraphics.height = CELL_SIZE * 1.5;
			break;
		case 'slow':
			effectGraphics.tint = 0x9900FF;
			effectGraphics.width = effectGraphics.height = CELL_SIZE;
			break;
		case 'poison':
			effectGraphics.tint = 0x00FFAA;
			effectGraphics.width = effectGraphics.height = CELL_SIZE;
			break;
		case 'sniper':
			effectGraphics.tint = 0xFF5500;
			effectGraphics.width = effectGraphics.height = CELL_SIZE;
			break;
	}
	effectGraphics.alpha = 0.7;
	self.alpha = 0;
	// Animate the effect
	tween(self, {
		alpha: 0.8,
		scaleX: 1.5,
		scaleY: 1.5
	}, {
		duration: 200,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(self, {
				alpha: 0,
				scaleX: 2,
				scaleY: 2
			}, {
				duration: 300,
				easing: tween.easeIn,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
		}
	});
	return self;
});
// Base enemy class for common functionality
var Enemy = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'normal';
	self.speed = .01;
	self.cellX = 0;
	self.cellY = 0;
	self.currentCellX = 0;
	self.currentCellY = 0;
	self.currentTarget = undefined;
	self.maxHealth = 100;
	self.health = self.maxHealth;
	self.bulletsTargetingThis = [];
	self.waveNumber = currentWave;
	self.isFlying = false;
	self.isImmune = false;
	self.isBoss = false;
	// Check if this is a boss wave
	// Check if this is a boss wave
	// Apply different stats based on enemy type
	switch (self.type) {
		case 'fast':
			self.speed *= 2; // Twice as fast
			self.maxHealth = 100;
			break;
		case 'immune':
			self.isImmune = true;
			self.speed *= 1.275; // 27.5% faster than normal (reduced by 15% from previous 50%)
			self.maxHealth = 40;
			break;
		case 'flying':
			self.isFlying = true;
			self.maxHealth = 80;
			break;
		case 'swarm':
			self.maxHealth = 50; // Weaker enemies
			break;
		case 'angry':
			self.speed *= 1; // Same speed as normal enemies
			self.maxHealth = 120; // More health than normal
			break;
		case 'modern':
			self.speed *= 1; // Same speed as angry enemies
			self.maxHealth = 600; // 5x health of angry enemies (120 * 5)
			break;
		case 'bad':
			self.speed *= 0.5; // 50% slower than normal
			self.maxHealth = 1000; // 10 times the health of a normal enemy
			break;
		case 'super':
			self.speed *= 0.4; // 60% slower than normal
			self.maxHealth = 2000; // 20 times the health of a normal enemy (2x bad enemy)
			break;
		case 'normal':
		default:
			// Normal enemy uses default values
			break;
	}
	// Boss spawning disabled for waves 10, 20, 30
	// if (currentWave % 10 === 0 && currentWave > 0 && type !== 'swarm') {
	//     self.isBoss = true;
	//     // Boss enemies have 20x health and are larger
	//     self.maxHealth *= 20;
	//     // Slower speed for bosses
	//     self.speed = self.speed * 0.7;
	// }
	self.health = self.maxHealth;
	// Get appropriate asset for this enemy type
	var assetId = 'enemy';
	if (self.type === 'angry') {
		assetId = 'Angry_Enemy';
	} else if (self.type === 'modern') {
		assetId = 'modern_enemy';
	} else if (self.type === 'bad') {
		assetId = 'enemy_bad';
	} else if (self.type === 'super') {
		assetId = 'enemy_super';
	} else if (self.type !== 'normal') {
		assetId = 'enemy_' + self.type;
	}
	var enemyGraphics = self.attachAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Scale up boss enemies
	if (self.isBoss) {
		enemyGraphics.scaleX = 1.8;
		enemyGraphics.scaleY = 1.8;
	}
	// Fall back to regular enemy asset if specific type asset not found
	// Apply tint to differentiate enemy types
	/*switch (self.type) {
		case 'fast':
			enemyGraphics.tint = 0x00AAFF; // Blue for fast enemies
			break;
		case 'immune':
			enemyGraphics.tint = 0xAA0000; // Red for immune enemies
			break;
		case 'flying':
			enemyGraphics.tint = 0xFFFF00; // Yellow for flying enemies
			break;
		case 'swarm':
			enemyGraphics.tint = 0xFF00FF; // Pink for swarm enemies
			break;
	}*/
	// Create shadow for flying enemies
	if (self.isFlying) {
		// Create a shadow container that will be added to the shadow layer
		self.shadow = new Container();
		// Clone the enemy graphics for the shadow
		var shadowGraphics = self.shadow.attachAsset(assetId || 'enemy', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		// Apply shadow effect
		shadowGraphics.tint = 0x000000; // Black shadow
		shadowGraphics.alpha = 0.4; // Semi-transparent
		// If this is a boss, scale up the shadow to match
		if (self.isBoss) {
			shadowGraphics.scaleX = 1.8;
			shadowGraphics.scaleY = 1.8;
		}
		// Position shadow slightly offset
		self.shadow.x = 20; // Offset right
		self.shadow.y = 20; // Offset down
		// Ensure shadow has the same rotation as the enemy
		shadowGraphics.rotation = enemyGraphics.rotation;
	}
	var healthBarOutline = self.attachAsset('healthBarOutline', {
		anchorX: 0,
		anchorY: 0.5
	});
	var healthBarBG = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	var healthBar = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	healthBarBG.y = healthBarOutline.y = healthBar.y = -enemyGraphics.height / 2 - 10;
	healthBarOutline.x = -healthBarOutline.width / 2;
	healthBarBG.x = healthBar.x = -healthBar.width / 2 - .5;
	healthBar.tint = 0x00ff00;
	healthBarBG.tint = 0xff0000;
	self.healthBar = healthBar;
	self.update = function () {
		// Skip enemy update when game is paused (gameSpeed = 0)
		if (gameSpeed === 0) {
			return;
		}
		if (self.health <= 0) {
			self.health = 0;
			self.healthBar.width = 0;
		}
		// Anti-stuck mechanism: track if enemy hasn't moved significantly
		if (self.lastPosition === undefined) {
			self.lastPosition = {
				x: self.currentCellX,
				y: self.currentCellY,
				time: LK.ticks
			};
			self.stuckCounter = 0;
		}
		// Check if enemy has been stuck in same position for too long
		var timeSinceLastCheck = LK.ticks - self.lastPosition.time;
		if (timeSinceLastCheck > 180) {
			// Check every 3 seconds
			var distanceMoved = Math.sqrt((self.currentCellX - self.lastPosition.x) * (self.currentCellX - self.lastPosition.x) + (self.currentCellY - self.lastPosition.y) * (self.currentCellY - self.lastPosition.y));
			if (distanceMoved < 0.5) {
				// If moved less than half a cell
				self.stuckCounter++;
				if (self.stuckCounter >= 3) {
					// If stuck for 3 checks (9 seconds)
					// Force reset enemy position and target
					self.currentTarget = null;
					// Try to find a valid spawn position
					for (var sx = 9; sx <= 14; sx++) {
						var testCell = grid.getCell(sx, 5);
						if (testCell && testCell.pathId === pathId) {
							self.cellX = sx;
							self.cellY = 5;
							self.currentCellX = sx;
							self.currentCellY = 5;
							self.stuckCounter = 0;
							break;
						}
					}
				}
			} else {
				self.stuckCounter = 0; // Reset stuck counter if moving
			}
			// Update last position
			self.lastPosition = {
				x: self.currentCellX,
				y: self.currentCellY,
				time: LK.ticks
			};
		}
		// Immune enemies attack towers in range
		if (self.isImmune) {
			// Immune enemies cannot be slowed or poisoned, clear any such effects
			self.poisoned = false;
			self.poisonEffect = false;
			// Attack towers every 120 frames (2 seconds)
			if (LK.ticks % Math.max(1, Math.floor(120 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 2 cell range
					if (distance <= CELL_SIZE * 2) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Only attack if not protected by a Healer tower
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								var damage = Math.floor(tower.maxHealth / 10); // 1/10th of tower's max health
								// Hardcore mode: enemies deal 2x damage
								if (gameSettings.difficulty === 'hardcore') {
									damage *= 2;
								}
								// Hardcore mode: spawn 3 immune enemies every wave
								if (gameSettings.difficulty === 'hardcore') {
									immuneCount = 3;
								}
								tower.health -= damage;
								if (tower.health <= 0) {
									tower.health = 0;
								}
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else if (self.type === 'angry') {
			// Angry enemies attack towers in range, but are blocked by Healer towers
			// Attack towers every 120 frames (2 seconds)
			if (LK.ticks % Math.max(1, Math.floor(120 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 2 cell range
					if (distance <= CELL_SIZE * 2) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Healer towers completely block damage from Angry enemies
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								var damage = Math.floor(tower.maxHealth * 0.25); // 25% of tower's max health
								// Hardcore mode: enemies deal 2x damage
								if (gameSettings.difficulty === 'hardcore') {
									damage *= 2;
								}
								tower.health -= damage;
								if (tower.health <= 0) {
									tower.health = 0;
								}
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else if (self.type === 'modern') {
			// Modern enemies attack towers in range with 2x damage compared to Angry enemies
			// Attack towers every 120 frames (2 seconds)
			if (LK.ticks % Math.max(1, Math.floor(120 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 2 cell range
					if (distance <= CELL_SIZE * 2) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Healer towers completely block damage from Modern enemies
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								var damage = Math.floor(tower.maxHealth * 0.50); // 50% of tower's max health (2x angry damage)
								// Hardcore mode: enemies deal 2x damage
								if (gameSettings.difficulty === 'hardcore') {
									damage *= 2;
								}
								tower.health -= damage;
								if (tower.health <= 0) {
									tower.health = 0;
								}
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else if (self.type === 'bad') {
			// Bad enemies attack towers more frequently and deal more damage
			// Attack towers every 90 frames (1.5 seconds)
			if (LK.ticks % Math.max(1, Math.floor(90 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 2.5 cell range (longer range than angry)
					if (distance <= CELL_SIZE * 2.5) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Only attack if not protected by a Healer tower
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								// Bad enemies destroy towers in one hit (or deal massive damage in hardcore)
								if (gameSettings.difficulty === 'hardcore') {
									tower.health = 0; // Still one-shot in hardcore
								} else {
									tower.health = 0; // One-shot in normal/hard
								}
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else if (self.type === 'super') {
			// Super enemies attack towers more frequently and deal devastating damage
			// Attack towers every 60 frames (1 second)
			if (LK.ticks % Math.max(1, Math.floor(60 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 3 cell range (longer range than bad)
					if (distance <= CELL_SIZE * 3) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Only attack if not protected by a Healer tower
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								// Super enemies destroy towers instantly regardless of difficulty
								tower.health = 0;
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else {
			// Handle poison effect
			if (self.poisoned) {
				// Visual indication of poisoned status
				if (!self.poisonEffect) {
					self.poisonEffect = true;
				}
				// Apply poison damage every 30 frames (twice per second), adjusted for game speed
				if (LK.ticks % Math.max(1, Math.floor(30 / gameSpeed)) === 0) {
					self.health -= self.poisonDamage * gameSpeed;
					if (self.health <= 0) {
						self.health = 0;
					}
					self.healthBar.width = self.health / self.maxHealth * 70;
				}
				self.poisonDuration -= gameSpeed;
				if (self.poisonDuration <= 0) {
					self.poisoned = false;
					self.poisonEffect = false;
					// Only reset tint if not slowed
					if (!self.slowed) {
						enemyGraphics.tint = 0xFFFFFF; // Reset tint
					}
				}
			}
		}
		// Set tint based on effect status
		if (self.isImmune) {
			enemyGraphics.tint = 0xFFFFFF;
		} else if (self.poisoned) {
			enemyGraphics.tint = 0x00FFAA;
		} else if (self.type === 'bad') {
			// Bad enemies use their asset's natural color - no tint applied
		} else if (self.type === 'super') {
			enemyGraphics.tint = 0x800080; // Purple tint for super enemies
		} else {
			enemyGraphics.tint = 0xFFFFFF;
		}
		if (self.currentTarget) {
			var ox = self.currentTarget.x - self.currentCellX;
			var oy = self.currentTarget.y - self.currentCellY;
			if (ox !== 0 || oy !== 0) {
				var angle = Math.atan2(oy, ox);
				if (enemyGraphics.targetRotation === undefined) {
					enemyGraphics.targetRotation = angle;
					enemyGraphics.rotation = angle;
				} else {
					if (Math.abs(angle - enemyGraphics.targetRotation) > 0.05) {
						tween.stop(enemyGraphics, {
							rotation: true
						});
						// Calculate the shortest angle to rotate
						var currentRotation = enemyGraphics.rotation;
						var angleDiff = angle - currentRotation;
						// Normalize angle difference to -PI to PI range for shortest path
						while (angleDiff > Math.PI) {
							angleDiff -= Math.PI * 2;
						}
						while (angleDiff < -Math.PI) {
							angleDiff += Math.PI * 2;
						}
						enemyGraphics.targetRotation = angle;
						tween(enemyGraphics, {
							rotation: currentRotation + angleDiff
						}, {
							duration: 250,
							easing: tween.easeOut
						});
					}
				}
			}
		}
		healthBarOutline.y = healthBarBG.y = healthBar.y = -enemyGraphics.height / 2 - 10;
	};
	return self;
});
var GoldIndicator = Container.expand(function (value, x, y) {
	var self = Container.call(this);
	var shadowText = new Text2("+" + value, {
		size: 45,
		fill: 0x000000,
		weight: 800
	});
	shadowText.anchor.set(0.5, 0.5);
	shadowText.x = 2;
	shadowText.y = 2;
	self.addChild(shadowText);
	var goldText = new Text2("+" + value, {
		size: 45,
		fill: 0xFFD700,
		weight: 800
	});
	goldText.anchor.set(0.5, 0.5);
	self.addChild(goldText);
	self.x = x;
	self.y = y;
	self.alpha = 0;
	self.scaleX = 0.5;
	self.scaleY = 0.5;
	tween(self, {
		alpha: 1,
		scaleX: 1.2,
		scaleY: 1.2,
		y: y - 40
	}, {
		duration: 50,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(self, {
				alpha: 0,
				scaleX: 1.5,
				scaleY: 1.5,
				y: y - 80
			}, {
				duration: 600,
				easing: tween.easeIn,
				delay: 800,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
		}
	});
	return self;
});
var Grid = Container.expand(function (gridWidth, gridHeight) {
	var self = Container.call(this);
	self.cells = [];
	self.spawns = [];
	self.goals = [];
	for (var i = 0; i < gridWidth; i++) {
		self.cells[i] = [];
		for (var j = 0; j < gridHeight; j++) {
			self.cells[i][j] = {
				score: 0,
				pathId: 0,
				towersInRange: []
			};
		}
	}
	/*
	Cell Types
	0: Transparent floor
	1: Wall
	2: Spawn
	3: Goal
	4: Castle wall
	*/
	for (var i = 0; i < gridWidth; i++) {
		var _loop = function _loop() {
				cell = self.cells[i][j];
				cellType = i === 0 || i === gridWidth - 1 || j <= 4 || j >= gridHeight - 4 ? 1 : 0; // Create castle structure with random labyrinth
				if (j > 4 && j < gridHeight - 4) {
					// Simple pseudo-random number generator using seed
					var seededRandom = function seededRandom() {
						mazeSeed = (mazeSeed * 9301 + 49297) % 233280;
						return mazeSeed / 233280;
					}; // Main castle outer walls
					// Generate maze seed based on reload counter to ensure different maze each reload
					// Use reload-based seed as primary factor for maze generation
					mazeSeed = gameSessionSeed * 7919 + (currentWave + 1) * 1009 + reloadCounter * 4397;
					if ((i === 2 || i === gridWidth - 3) && j >= 8 && j <= gridHeight - 8) {
						cellType = 4; // Castle wall
					}
					// Castle towers at corners
					if ((i >= 1 && i <= 4 || i >= gridWidth - 5 && i <= gridWidth - 2) && (j >= 7 && j <= 10 || j >= gridHeight - 11 && j <= gridHeight - 8)) {
						cellType = 4;
					}
					// Generate unique geometric maze patterns based on seed
					var mazePattern = (mazeSeed * 17 + (currentWave + 1) * 23) % 100;
					if (j >= 12 && j <= gridHeight - 12) {
						// Create safe corridors first - ensure at least 3 clear horizontal paths
						var safePaths = [16, 20, 24];
						var isSafePath = false;
						for (var sp = 0; sp < safePaths.length; sp++) {
							if (j === safePaths[sp] && i >= 8 && i <= gridWidth - 9) {
								isSafePath = true;
								break;
							}
						}
						if (!isSafePath) {
							// Generate dynamic geometric patterns based on random seed
							if (mazePattern < 20) {
								// Concentric geometric shapes
								var centerX = Math.floor(gridWidth / 2);
								var centerY = Math.floor((gridHeight - 12 + 12) / 2);
								var distance = Math.sqrt((i - centerX) * (i - centerX) + (j - centerY) * (j - centerY));
								var ringSize = 2 + mazeSeed % 3;
								if (Math.floor(distance) % ringSize === 1 && distance > 2 && distance < 8 && i >= 6 && i <= gridWidth - 7) {
									if (seededRandom() > 0.6) {
										cellType = 4;
									}
								}
							} else if (mazePattern < 40) {
								// Geometric wave patterns
								var waveFreq = 0.2 + mazeSeed % 5 * 0.1;
								var waveHeight = 2 + mazeSeed % 3;
								var expectedY = Math.floor(Math.sin(i * waveFreq) * waveHeight) + Math.floor((gridHeight - 12 + 12) / 2);
								if (Math.abs(j - expectedY) < 2 && i >= 6 && i <= gridWidth - 7) {
									if (seededRandom() > 0.5) {
										cellType = 4;
									}
								}
							} else if (mazePattern < 60) {
								// Diamond and rhombus patterns
								var midX = Math.floor(gridWidth / 2);
								var midY = Math.floor((gridHeight - 12 + 12) / 2);
								var manhattanDist = Math.abs(i - midX) + Math.abs(j - midY);
								var diamondSize = 3 + mazeSeed % 4;
								if (manhattanDist >= diamondSize && manhattanDist <= diamondSize + 3 && manhattanDist % 2 === 0) {
									if (seededRandom() > 0.5) {
										cellType = 4;
									}
								}
							} else if (mazePattern < 80) {
								// Hexagonal and triangular patterns
								var hexSize = 4 + mazeSeed % 3;
								var hexX = Math.floor(i / hexSize);
								var hexY = Math.floor(j / hexSize);
								if ((hexX + hexY) % 3 === 0 && (i % hexSize < 2 || j % hexSize < 2) && i >= 6 && i <= gridWidth - 7) {
									if (seededRandom() > 0.4) {
										cellType = 4;
									}
								}
							} else {
								// Spiral and radial patterns
								var centerX = Math.floor(gridWidth / 2);
								var centerY = Math.floor((gridHeight - 12 + 12) / 2);
								var angle = Math.atan2(j - centerY, i - centerX);
								var spiralArms = 4 + mazeSeed % 4;
								var armIndex = Math.floor(angle / (Math.PI * 2 / spiralArms));
								var distance = Math.sqrt((i - centerX) * (i - centerX) + (j - centerY) * (j - centerY));
								if (armIndex % 2 === 0 && distance > 2 && distance < 7 && i >= 6 && i <= gridWidth - 7) {
									if (seededRandom() > 0.45) {
										cellType = 4;
									}
								}
							}
							// Add strategic scattered obstacles with lower density
							if (i >= 7 && i <= gridWidth - 8 && j >= 14 && j <= gridHeight - 14) {
								if (seededRandom() > 0.8) {
									cellType = 4;
								}
							}
						}
					}
					// Central castle keep - always present
					if (i >= 10 && i <= 13 && j >= gridHeight - 16 && j <= gridHeight - 13) {
						if (!(i === 11 || i === 12) || !(j === gridHeight - 15 || j === gridHeight - 14)) {
							cellType = 4;
						}
					}
				}
				// Spawn and goal areas
				if (i > 11 - 3 && i <= 11 + 3) {
					if (j === 0) {
						cellType = 2;
						self.spawns.push(cell);
					} else if (j <= 4) {
						cellType = 0;
					} else if (j === gridHeight - 1) {
						cellType = 3;
						self.goals.push(cell);
					} else if (j >= gridHeight - 4) {
						cellType = 0;
					}
				}
				cell.type = cellType;
				cell.x = i;
				cell.y = j;
				cell.upLeft = self.cells[i - 1] && self.cells[i - 1][j - 1];
				cell.up = self.cells[i - 1] && self.cells[i - 1][j];
				cell.upRight = self.cells[i - 1] && self.cells[i - 1][j + 1];
				cell.left = self.cells[i][j - 1];
				cell.right = self.cells[i][j + 1];
				cell.downLeft = self.cells[i + 1] && self.cells[i + 1][j - 1];
				cell.down = self.cells[i + 1] && self.cells[i + 1][j];
				cell.downRight = self.cells[i + 1] && self.cells[i + 1][j + 1];
				cell.neighbors = [cell.upLeft, cell.up, cell.upRight, cell.right, cell.downRight, cell.down, cell.downLeft, cell.left];
				cell.targets = [];
				if (j > 3 && j <= gridHeight - 4) {
					debugCell = new DebugCell();
					self.addChild(debugCell);
					debugCell.cell = cell;
					debugCell.x = i * CELL_SIZE;
					debugCell.y = j * CELL_SIZE;
					cell.debugCell = debugCell;
				}
			},
			cell,
			cellType,
			mazeSeed,
			horizontalWallRows,
			hr,
			verticalWallCols,
			vc,
			debugCell;
		for (var j = 0; j < gridHeight; j++) {
			_loop();
		}
	}
	self.getCell = function (x, y) {
		return self.cells[x] && self.cells[x][y];
	};
	self.pathFind = function () {
		var before = new Date().getTime();
		var toProcess = self.goals.concat([]);
		maxScore = 0;
		pathId += 1;
		for (var a = 0; a < toProcess.length; a++) {
			toProcess[a].pathId = pathId;
		}
		function processNode(node, targetValue, targetNode) {
			if (node && node.type != 1 && node.type != 4) {
				if (node.pathId < pathId || targetValue < node.score) {
					node.targets = [targetNode];
				} else if (node.pathId == pathId && targetValue == node.score) {
					node.targets.push(targetNode);
				}
				if (node.pathId < pathId || targetValue < node.score) {
					node.score = targetValue;
					if (node.pathId != pathId) {
						toProcess.push(node);
					}
					node.pathId = pathId;
					if (targetValue > maxScore) {
						maxScore = targetValue;
					}
				}
			}
		}
		while (toProcess.length) {
			var nodes = toProcess;
			toProcess = [];
			for (var a = 0; a < nodes.length; a++) {
				var node = nodes[a];
				var targetScore = node.score + 14142;
				if (node.up && node.left && node.up.type != 1 && node.up.type != 4 && node.left.type != 1 && node.left.type != 4 && node.upLeft && node.upLeft.type != 1 && node.upLeft.type != 4) {
					processNode(node.upLeft, targetScore, node);
				}
				if (node.up && node.right && node.up.type != 1 && node.up.type != 4 && node.right.type != 1 && node.right.type != 4 && node.upRight && node.upRight.type != 1 && node.upRight.type != 4) {
					processNode(node.upRight, targetScore, node);
				}
				if (node.down && node.right && node.down.type != 1 && node.down.type != 4 && node.right.type != 1 && node.right.type != 4 && node.downRight && node.downRight.type != 1 && node.downRight.type != 4) {
					processNode(node.downRight, targetScore, node);
				}
				if (node.down && node.left && node.down.type != 1 && node.down.type != 4 && node.left.type != 1 && node.left.type != 4 && node.downLeft && node.downLeft.type != 1 && node.downLeft.type != 4) {
					processNode(node.downLeft, targetScore, node);
				}
				targetScore = node.score + 10000;
				processNode(node.up, targetScore, node);
				processNode(node.right, targetScore, node);
				processNode(node.down, targetScore, node);
				processNode(node.left, targetScore, node);
			}
		}
		// Check if any spawn point has a valid path to any goal
		var hasValidPath = false;
		for (var a = 0; a < self.spawns.length; a++) {
			if (self.spawns[a].pathId === pathId) {
				hasValidPath = true;
				break;
			}
		}
		// Ensure maze is navigable - return false if paths are blocked
		if (!hasValidPath) {
			console.log("Maze blocks all paths - this layout will be regenerated");
			return true; // Signal that maze needs regeneration
		}
		for (var a = 0; a < enemies.length; a++) {
			var enemy = enemies[a];
			// Skip enemies that haven't entered the viewable area yet
			if (enemy.currentCellY < 4) {
				continue;
			}
			// Skip flying enemies from path check as they can fly over obstacles
			if (enemy.isFlying) {
				continue;
			}
			var target = self.getCell(enemy.cellX, enemy.cellY);
			if (enemy.currentTarget) {
				if (enemy.currentTarget.pathId != pathId) {
					if (!target || target.pathId != pathId) {
						console.warn("Enemy blocked 1 ");
						return true;
					}
				}
			} else if (!target || target.pathId != pathId) {
				console.warn("Enemy blocked 2");
				return true;
			}
		}
		console.log("Speed", new Date().getTime() - before);
	};
	self.renderDebug = function () {
		for (var i = 0; i < gridWidth; i++) {
			for (var j = 0; j < gridHeight; j++) {
				var debugCell = self.cells[i][j].debugCell;
				if (debugCell) {
					debugCell.render(self.cells[i][j]);
				}
			}
		}
	};
	self.updateEnemy = function (enemy) {
		var cell = grid.getCell(enemy.cellX, enemy.cellY);
		if (cell.type == 3) {
			return true;
		}
		if (enemy.isFlying && enemy.shadow) {
			enemy.shadow.x = enemy.x + 20; // Match enemy x-position + offset
			enemy.shadow.y = enemy.y + 20; // Match enemy y-position + offset
			// Match shadow rotation with enemy rotation
			if (enemy.children[0] && enemy.shadow.children[0]) {
				enemy.shadow.children[0].rotation = enemy.children[0].rotation;
			}
		}
		// Check if the enemy has reached the entry area (y position is at least 5)
		var hasReachedEntryArea = enemy.currentCellY >= 4;
		// If enemy hasn't reached the entry area yet, just move down vertically
		if (!hasReachedEntryArea) {
			// Move directly downward
			enemy.currentCellY += enemy.speed * gameSpeed;
			// Rotate enemy graphic to face downward (PI/2 radians = 90 degrees)
			var angle = Math.PI / 2;
			if (enemy.children[0] && enemy.children[0].targetRotation === undefined) {
				enemy.children[0].targetRotation = angle;
				enemy.children[0].rotation = angle;
			} else if (enemy.children[0]) {
				if (Math.abs(angle - enemy.children[0].targetRotation) > 0.05) {
					tween.stop(enemy.children[0], {
						rotation: true
					});
					// Calculate the shortest angle to rotate
					var currentRotation = enemy.children[0].rotation;
					var angleDiff = angle - currentRotation;
					// Normalize angle difference to -PI to PI range for shortest path
					while (angleDiff > Math.PI) {
						angleDiff -= Math.PI * 2;
					}
					while (angleDiff < -Math.PI) {
						angleDiff += Math.PI * 2;
					}
					// Set target rotation and animate to it
					enemy.children[0].targetRotation = angle;
					tween(enemy.children[0], {
						rotation: currentRotation + angleDiff
					}, {
						duration: 250,
						easing: tween.easeOut
					});
				}
			}
			// Update enemy's position
			enemy.x = grid.x + enemy.currentCellX * CELL_SIZE;
			enemy.y = grid.y + enemy.currentCellY * CELL_SIZE;
			// If enemy has now reached the entry area, update cell coordinates
			if (enemy.currentCellY >= 4) {
				enemy.cellX = Math.round(enemy.currentCellX);
				enemy.cellY = Math.round(enemy.currentCellY);
			}
			return false;
		}
		// After reaching entry area, handle flying enemies differently
		if (enemy.isFlying) {
			// Flying enemies head straight to the closest goal
			if (!enemy.flyingTarget) {
				// Set flying target to the closest goal
				enemy.flyingTarget = self.goals[0];
				// Find closest goal if there are multiple
				if (self.goals.length > 1) {
					var closestDist = Infinity;
					for (var i = 0; i < self.goals.length; i++) {
						var goal = self.goals[i];
						var dx = goal.x - enemy.cellX;
						var dy = goal.y - enemy.cellY;
						var dist = dx * dx + dy * dy;
						if (dist < closestDist) {
							closestDist = dist;
							enemy.flyingTarget = goal;
						}
					}
				}
			}
			// Move directly toward the goal
			var ox = enemy.flyingTarget.x - enemy.currentCellX;
			var oy = enemy.flyingTarget.y - enemy.currentCellY;
			var dist = Math.sqrt(ox * ox + oy * oy);
			if (dist < enemy.speed) {
				// Reached the goal
				return true;
			}
			var angle = Math.atan2(oy, ox);
			// Rotate enemy graphic to match movement direction
			if (enemy.children[0] && enemy.children[0].targetRotation === undefined) {
				enemy.children[0].targetRotation = angle;
				enemy.children[0].rotation = angle;
			} else if (enemy.children[0]) {
				if (Math.abs(angle - enemy.children[0].targetRotation) > 0.05) {
					tween.stop(enemy.children[0], {
						rotation: true
					});
					// Calculate the shortest angle to rotate
					var currentRotation = enemy.children[0].rotation;
					var angleDiff = angle - currentRotation;
					// Normalize angle difference to -PI to PI range for shortest path
					while (angleDiff > Math.PI) {
						angleDiff -= Math.PI * 2;
					}
					while (angleDiff < -Math.PI) {
						angleDiff += Math.PI * 2;
					}
					// Set target rotation and animate to it
					enemy.children[0].targetRotation = angle;
					tween(enemy.children[0], {
						rotation: currentRotation + angleDiff
					}, {
						duration: 250,
						easing: tween.easeOut
					});
				}
			}
			// Update the cell position to track where the flying enemy is
			enemy.cellX = Math.round(enemy.currentCellX);
			enemy.cellY = Math.round(enemy.currentCellY);
			enemy.currentCellX += Math.cos(angle) * enemy.speed * gameSpeed;
			enemy.currentCellY += Math.sin(angle) * enemy.speed * gameSpeed;
			enemy.x = grid.x + enemy.currentCellX * CELL_SIZE;
			enemy.y = grid.y + enemy.currentCellY * CELL_SIZE;
			// Update shadow position if this is a flying enemy
			return false;
		}
		// Handle normal pathfinding enemies
		if (!enemy.currentTarget || !cell || cell.pathId !== pathId) {
			// Reset target if we don't have one or if current cell is invalid
			if (cell && cell.pathId === pathId && cell.targets && cell.targets.length > 0) {
				enemy.currentTarget = cell.targets[0];
			} else {
				// If current cell is invalid, try to find nearest valid cell
				var nearestValidCell = null;
				var minDistance = Infinity;
				// Search for nearby valid cells
				for (var searchX = Math.max(0, enemy.cellX - 2); searchX <= Math.min(grid.cells.length - 1, enemy.cellX + 2); searchX++) {
					for (var searchY = Math.max(0, enemy.cellY - 2); searchY <= Math.min(grid.cells[0].length - 1, enemy.cellY + 2); searchY++) {
						var searchCell = grid.getCell(searchX, searchY);
						if (searchCell && searchCell.pathId === pathId && searchCell.targets && searchCell.targets.length > 0) {
							var dx = searchX - enemy.cellX;
							var dy = searchY - enemy.cellY;
							var distance = dx * dx + dy * dy;
							if (distance < minDistance) {
								minDistance = distance;
								nearestValidCell = searchCell;
							}
						}
					}
				}
				if (nearestValidCell) {
					enemy.currentTarget = nearestValidCell;
					// Snap enemy to the valid cell position
					enemy.cellX = nearestValidCell.x;
					enemy.cellY = nearestValidCell.y;
					enemy.currentCellX = nearestValidCell.x;
					enemy.currentCellY = nearestValidCell.y;
				}
			}
		}
		if (enemy.currentTarget) {
			// Validate that current target is still valid
			if (enemy.currentTarget.pathId !== pathId) {
				enemy.currentTarget = null;
				return; // Will be fixed next frame
			}
			// If we have a better path from current cell, use it
			if (cell && cell.pathId === pathId && cell.score < enemy.currentTarget.score) {
				enemy.currentTarget = cell;
			}
			var ox = enemy.currentTarget.x - enemy.currentCellX;
			var oy = enemy.currentTarget.y - enemy.currentCellY;
			var dist = Math.sqrt(ox * ox + oy * oy);
			if (dist < enemy.speed * gameSpeed) {
				// Reached target, snap to grid and clear target
				enemy.cellX = enemy.currentTarget.x;
				enemy.cellY = enemy.currentTarget.y;
				enemy.currentCellX = enemy.currentTarget.x;
				enemy.currentCellY = enemy.currentTarget.y;
				enemy.currentTarget = null;
				// Don't return here, let position update happen
			} else {
				// Move toward target
				var angle = Math.atan2(oy, ox);
				enemy.currentCellX += Math.cos(angle) * enemy.speed * gameSpeed;
				enemy.currentCellY += Math.sin(angle) * enemy.speed * gameSpeed;
			}
		} else {
			// No valid target - try to get unstuck by moving toward goal
			var goalFound = false;
			for (var g = 0; g < self.goals.length; g++) {
				var goal = self.goals[g];
				var gx = goal.x - enemy.currentCellX;
				var gy = goal.y - enemy.currentCellY;
				if (Math.abs(gx) > 0.1 || Math.abs(gy) > 0.1) {
					var gAngle = Math.atan2(gy, gx);
					enemy.currentCellX += Math.cos(gAngle) * enemy.speed * gameSpeed * 0.5; // Move slower when lost
					enemy.currentCellY += Math.sin(gAngle) * enemy.speed * gameSpeed * 0.5;
					goalFound = true;
					break;
				}
			}
		}
		// Update visual position
		enemy.x = grid.x + enemy.currentCellX * CELL_SIZE;
		enemy.y = grid.y + enemy.currentCellY * CELL_SIZE;
	};
});
var MainMenu = Container.expand(function () {
	var self = Container.call(this);
	// Center the menu container
	self.x = 2048 / 2;
	self.y = 2732 / 2;
	// Background overlay
	var menuBackground = self.attachAsset('notification', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	menuBackground.width = 2048;
	menuBackground.height = 2732;
	menuBackground.tint = 0x000000;
	menuBackground.alpha = 0.8;
	// Current state: 'difficulty' or 'empire'
	self.currentState = 'difficulty';
	self.selectedDifficulty = null;
	// Difficulty selection elements
	var difficultyTitle = new Text2("Select Difficulty", {
		size: 120,
		fill: 0xFFFFFF,
		weight: 800
	});
	difficultyTitle.anchor.set(0.5, 0.5);
	difficultyTitle.y = -600;
	self.addChild(difficultyTitle);
	// Difficulty buttons
	var difficulties = ['easy', 'normal', 'hard', 'hardcore', 'ultra'];
	var difficultyButtons = [];
	var difficultyButtonSpacing = 150;
	var difficultyStartY = -300;
	for (var i = 0; i < difficulties.length; i++) {
		var difficulty = difficulties[i];
		var button = new Container();
		var buttonBG = button.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		buttonBG.width = 600;
		buttonBG.height = 120;
		// Set button color based on difficulty
		switch (difficulty) {
			case 'easy':
				buttonBG.tint = 0x00FF00; // Green
				break;
			case 'hard':
				buttonBG.tint = 0xFF8800; // Orange
				break;
			case 'hardcore':
				buttonBG.tint = 0xFF0000; // Red
				break;
			case 'ultra':
				buttonBG.tint = 0x800080; // Purple for ultra
				break;
			default:
				buttonBG.tint = 0x0088FF; // Blue for normal
				break;
		}
		var buttonText = new Text2(difficulty.charAt(0).toUpperCase() + difficulty.slice(1), {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		buttonText.anchor.set(0.5, 0.5);
		button.addChild(buttonText);
		button.y = difficultyStartY + i * difficultyButtonSpacing;
		button.difficulty = difficulty;
		button.down = function () {
			LK.getSound('Click').play();
			// Show confirmation popup for Easy, Normal, and Hard, direct to empire selection for hardcore and ultra
			if (this.difficulty === 'easy' || this.difficulty === 'normal' || this.difficulty === 'hard') {
				self.showConfirmationPopup(this.difficulty);
			} else {
				self.selectedDifficulty = this.difficulty;
				self.showEmpireSelection();
			}
		};
		self.addChild(button);
		difficultyButtons.push(button);
	}
	// Empire selection elements (initially hidden)
	var empireTitle = new Text2("Choose Your Empire!", {
		size: 100,
		fill: 0xFFFFFF,
		weight: 800
	});
	empireTitle.anchor.set(0.5, 0.5);
	empireTitle.y = -700;
	empireTitle.visible = false;
	self.addChild(empireTitle);
	// Empire buttons - 9 different empires including Normal
	var empires = [{
		name: 'Normal',
		color: 0xAAAAAA,
		description: ''
	}, {
		name: 'Austria',
		color: 0x00FF00,
		description: ''
	}, {
		name: 'Hungary',
		color: 0x0088FF,
		description: ''
	}, {
		name: 'Ottoman',
		color: 0xFF8800,
		description: ''
	}, {
		name: 'French',
		color: 0xFF0000,
		description: ''
	}, {
		name: 'England',
		color: 0x800080,
		description: ''
	}, {
		name: 'Scotch',
		color: 0x008080,
		description: ''
	}, {
		name: 'Kalmar Union',
		color: 0x006400,
		description: ''
	}, {
		name: 'Byzantine',
		color: 0xFF69B4,
		description: ''
	}];
	var empireButtons = [];
	var empireButtonSpacing = 200;
	var empireStartY = -400;
	for (var i = 0; i < empires.length; i++) {
		var empire = empires[i];
		var button = new Container();
		var buttonBG = button.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		buttonBG.width = 528;
		buttonBG.height = 176;
		buttonBG.tint = empire.color;
		var buttonText = new Text2(empire.name, {
			size: 53,
			fill: 0xFFFFFF,
			weight: 800
		});
		buttonText.anchor.set(0.5, 0.5);
		buttonText.y = 0;
		button.addChild(buttonText);
		var descText = new Text2(empire.description, {
			size: 35,
			fill: 0xFFFFFF,
			weight: 400
		});
		descText.anchor.set(0.5, 0.5);
		descText.y = 40;
		button.addChild(descText);
		button.y = empireStartY + i * empireButtonSpacing;
		button.visible = false; // Initially hidden
		button.down = function (empireData) {
			return function () {
				LK.getSound('Click').play();
				// Show empire characteristics menu instead of starting game directly
				self.showEmpireCharacteristics(empireData);
			};
		}(empire);
		self.addChild(button);
		empireButtons.push(button);
	}
	// No exit buttons needed
	var exitButtons = [];
	// Add confirmation popup for Easy and Hard difficulties
	self.confirmationPopup = null;
	self.showConfirmationPopup = function (difficulty) {
		// Remove any existing confirmation popup
		if (self.confirmationPopup) {
			self.removeChild(self.confirmationPopup);
			self.confirmationPopup.destroy();
		}
		// Create confirmation popup
		self.confirmationPopup = new Container();
		// Background for confirmation popup
		var confirmBG = self.confirmationPopup.attachAsset('menu', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		confirmBG.width = 1200;
		confirmBG.height = 600;
		confirmBG.alpha = 0.95;
		// Confirmation title
		var confirmText = "Are you sure: ";
		if (difficulty === "easy") {
			confirmText += "Easy?";
		} else if (difficulty === "normal") {
			confirmText += "Normal?";
		} else if (difficulty === "hard") {
			confirmText += "Hard?";
		} else {
			confirmText = "Are You Sure?";
		}
		var confirmTitle = new Text2(confirmText, {
			size: 80,
			fill: 0xFFFFFF,
			weight: 800
		});
		confirmTitle.anchor.set(0.5, 0.5);
		confirmTitle.y = -150;
		self.confirmationPopup.addChild(confirmTitle);
		// Yes button
		var yesButton = new Container();
		var yesBG = yesButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		yesBG.width = 300;
		yesBG.height = 120;
		yesBG.tint = 0x00AA00;
		var yesText = new Text2("Yes", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		yesText.anchor.set(0.5, 0.5);
		yesButton.addChild(yesText);
		yesButton.x = -200;
		yesButton.y = 100;
		yesButton.down = function () {
			LK.getSound('Click').play();
			// Remove confirmation popup and proceed to empire selection
			self.removeChild(self.confirmationPopup);
			self.confirmationPopup.destroy();
			self.confirmationPopup = null;
			// Show empire selection
			self.selectedDifficulty = difficulty;
			self.showEmpireSelection();
		};
		self.confirmationPopup.addChild(yesButton);
		// No button
		var noButton = new Container();
		var noBG = noButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		noBG.width = 300;
		noBG.height = 120;
		noBG.tint = 0xAA0000;
		var noText = new Text2("No", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		noText.anchor.set(0.5, 0.5);
		noButton.addChild(noText);
		noButton.x = 200;
		noButton.y = 100;
		noButton.down = function () {
			LK.getSound('Click').play();
			// Remove confirmation popup and return to difficulty selection
			self.removeChild(self.confirmationPopup);
			self.confirmationPopup.destroy();
			self.confirmationPopup = null;
			self.selectedDifficulty = null;
			// Stay on difficulty selection screen - no state change needed
		};
		self.confirmationPopup.addChild(noButton);
		self.addChild(self.confirmationPopup);
	};
	self.showEmpireSelection = function () {
		// Check if hardcore or ultra difficulty was selected
		if (self.selectedDifficulty === 'hardcore') {
			// Show hardcore warning popup instead of empire selection
			self.showHardcoreWarning();
			return;
		} else if (self.selectedDifficulty === 'ultra') {
			// Show ultra warning popup instead of empire selection
			self.showUltraWarning();
			return;
		}
		self.currentState = 'empire';
		// Hide difficulty elements
		difficultyTitle.visible = false;
		for (var i = 0; i < difficultyButtons.length; i++) {
			difficultyButtons[i].visible = false;
		}
		// Show empire elements
		empireTitle.visible = true;
		for (var i = 0; i < empireButtons.length; i++) {
			empireButtons[i].visible = true;
		}
		// No exit buttons to show
	};
	self.showHardcoreWarning = function () {
		// Remove any existing warning popup
		if (self.hardcoreWarningPopup) {
			self.removeChild(self.hardcoreWarningPopup);
			self.hardcoreWarningPopup.destroy();
		}
		// Create hardcore warning popup
		self.hardcoreWarningPopup = new Container();
		// Background for warning popup
		var warningBG = self.hardcoreWarningPopup.attachAsset('menu', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		warningBG.width = 1600;
		warningBG.height = 800;
		warningBG.alpha = 0.95;
		// Warning title
		var warningTitle = new Text2("WARNING", {
			size: 100,
			fill: 0xFF0000,
			weight: 800
		});
		warningTitle.anchor.set(0.5, 0.5);
		warningTitle.y = -250;
		self.hardcoreWarningPopup.addChild(warningTitle);
		// Warning message
		var warningText = new Text2("This difficulty is not one of the original game\ndifficulties for Honorbound: Rise on the Fifth Dawn.\nIT IS FOR ADVANCED PLAYERS ONLY!", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 400
		});
		warningText.anchor.set(0.5, 0.5);
		warningText.y = -50;
		self.hardcoreWarningPopup.addChild(warningText);
		// Okay button
		var okayButton = new Container();
		var okayBG = okayButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		okayBG.width = 300;
		okayBG.height = 120;
		okayBG.tint = 0x00AA00;
		var okayText = new Text2("Okay", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		okayText.anchor.set(0.5, 0.5);
		okayButton.addChild(okayText);
		okayButton.x = -200;
		okayButton.y = 200;
		okayButton.down = function () {
			LK.getSound('Click').play();
			// Remove warning popup and proceed to empire selection
			self.removeChild(self.hardcoreWarningPopup);
			self.hardcoreWarningPopup.destroy();
			self.hardcoreWarningPopup = null;
			// Show empire selection
			self.currentState = 'empire';
			// Hide difficulty elements
			difficultyTitle.visible = false;
			for (var i = 0; i < difficultyButtons.length; i++) {
				difficultyButtons[i].visible = false;
			}
			// Show empire elements
			empireTitle.visible = true;
			for (var i = 0; i < empireButtons.length; i++) {
				empireButtons[i].visible = true;
			}
		};
		self.hardcoreWarningPopup.addChild(okayButton);
		// Back button
		var backButton = new Container();
		var backBG = backButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		backBG.width = 300;
		backBG.height = 120;
		backBG.tint = 0xAA0000;
		var backText = new Text2("Back", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		backText.anchor.set(0.5, 0.5);
		backButton.addChild(backText);
		backButton.x = 200;
		backButton.y = 200;
		backButton.down = function () {
			LK.getSound('Click').play();
			// Remove warning popup and return to difficulty selection
			self.removeChild(self.hardcoreWarningPopup);
			self.hardcoreWarningPopup.destroy();
			self.hardcoreWarningPopup = null;
			self.selectedDifficulty = null;
			// Return to difficulty selection
			self.currentState = 'difficulty';
			// Show difficulty elements
			difficultyTitle.visible = true;
			for (var i = 0; i < difficultyButtons.length; i++) {
				difficultyButtons[i].visible = true;
			}
			// Hide empire elements
			empireTitle.visible = false;
			for (var i = 0; i < empireButtons.length; i++) {
				empireButtons[i].visible = false;
			}
		};
		self.hardcoreWarningPopup.addChild(backButton);
		self.addChild(self.hardcoreWarningPopup);
	};
	self.showUltraWarning = function () {
		// Remove any existing warning popup
		if (self.ultraWarningPopup) {
			self.removeChild(self.ultraWarningPopup);
			self.ultraWarningPopup.destroy();
		}
		// Create ultra warning popup
		self.ultraWarningPopup = new Container();
		// Background for warning popup
		var warningBG = self.ultraWarningPopup.attachAsset('menu', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		warningBG.width = 1600;
		warningBG.height = 800;
		warningBG.alpha = 0.95;
		// Warning title
		var warningTitle = new Text2("ULTRA MODE", {
			size: 100,
			fill: 0x800080,
			weight: 800
		});
		warningTitle.anchor.set(0.5, 0.5);
		warningTitle.y = -250;
		self.ultraWarningPopup.addChild(warningTitle);
		// Warning message
		var warningText = new Text2("This is an extreme endurance mode!\n30 waves without any King.\nEverything else is the same as Hardcore.\nAre you ready for the ultimate challenge?", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 400
		});
		warningText.anchor.set(0.5, 0.5);
		warningText.y = -50;
		self.ultraWarningPopup.addChild(warningText);
		// Okay button
		var okayButton = new Container();
		var okayBG = okayButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		okayBG.width = 300;
		okayBG.height = 120;
		okayBG.tint = 0x00AA00;
		var okayText = new Text2("Okay", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		okayText.anchor.set(0.5, 0.5);
		okayButton.addChild(okayText);
		okayButton.x = -200;
		okayButton.y = 200;
		okayButton.down = function () {
			LK.getSound('Click').play();
			// Remove warning popup and proceed to empire selection
			self.removeChild(self.ultraWarningPopup);
			self.ultraWarningPopup.destroy();
			self.ultraWarningPopup = null;
			// Show empire selection
			self.currentState = 'empire';
			// Hide difficulty elements
			difficultyTitle.visible = false;
			for (var i = 0; i < difficultyButtons.length; i++) {
				difficultyButtons[i].visible = false;
			}
			// Show empire elements
			empireTitle.visible = true;
			for (var i = 0; i < empireButtons.length; i++) {
				empireButtons[i].visible = true;
			}
		};
		self.ultraWarningPopup.addChild(okayButton);
		// Back button
		var backButton = new Container();
		var backBG = backButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		backBG.width = 300;
		backBG.height = 120;
		backBG.tint = 0xAA0000;
		var backText = new Text2("Back", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		backText.anchor.set(0.5, 0.5);
		backButton.addChild(backText);
		backButton.x = 200;
		backButton.y = 200;
		backButton.down = function () {
			LK.getSound('Click').play();
			// Remove warning popup and return to difficulty selection
			self.removeChild(self.ultraWarningPopup);
			self.ultraWarningPopup.destroy();
			self.ultraWarningPopup = null;
			self.selectedDifficulty = null;
			// Return to difficulty selection
			self.currentState = 'difficulty';
			// Show difficulty elements
			difficultyTitle.visible = true;
			for (var i = 0; i < difficultyButtons.length; i++) {
				difficultyButtons[i].visible = true;
			}
			// Hide empire elements
			empireTitle.visible = false;
			for (var i = 0; i < empireButtons.length; i++) {
				empireButtons[i].visible = false;
			}
		};
		self.ultraWarningPopup.addChild(backButton);
		self.addChild(self.ultraWarningPopup);
	};
	self.showEmpireCharacteristics = function (empireData) {
		// Remove any existing characteristics popup
		if (self.characteristicsPopup) {
			self.removeChild(self.characteristicsPopup);
			self.characteristicsPopup.destroy();
		}
		// Create characteristics popup
		self.characteristicsPopup = new Container();
		// Background for characteristics popup
		var charBG = self.characteristicsPopup.attachAsset('menu', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		charBG.width = 1400;
		charBG.height = 1000;
		charBG.alpha = 0.95;
		// Empire name title
		var titleText = new Text2(empireData.name + " Empire", {
			size: 80,
			fill: empireData.color,
			weight: 800
		});
		titleText.anchor.set(0.5, 0.5);
		titleText.y = -400;
		self.characteristicsPopup.addChild(titleText);
		// Empire characteristics text
		var characteristicsText = "";
		switch (empireData.name) {
			case 'Normal':
				characteristicsText = "Advantages:\n• Standard gameplay\n• No special bonuses\n• Balanced empire\n• Good for beginners";
				break;
			case 'Austria':
				characteristicsText = "Advantages:\n• +20% tower fire rate\n• All towers attack faster\n• Excellent for rapid defense";
				break;
			case 'Hungary':
				characteristicsText = "Advantages:\n• Tower cost -5 gold\n  (Normal+ difficulty)\n• Better economy management\n• More affordable towers";
				break;
			case 'Ottoman':
				characteristicsText = "Advantages:\n• Start with 100 gold\n  (instead of 80)\n• +20% damage on all attacks\n• Strong early game";
				break;
			case 'French':
				characteristicsText = "Advantages:\n• +20% tower durability\n• Towers have more health\n• Better defensive capability";
				break;
			case 'England':
				characteristicsText = "Advantages:\n• Start with 100 gold\n  (instead of 80)\n• 3 fewer enemies per wave\n• Easier defense management";
				break;
			case 'Scotch':
				characteristicsText = "Advantages:\n• Tower costs -3 gold\n• Archer range +50%\n• Better defense capability";
				break;
			case 'Kalmar Union':
				characteristicsText = "Advantages:\n• Healer range +100%\n• Better healing coverage\n• Improved tower protection";
				break;
			case 'Byzantine':
				characteristicsText = "Advantages:\n• Tower durability +100%\n• Towers have double health\nDisadvantages:\n• +3 enemies per wave\n• Higher enemy pressure";
				break;
			default:
				characteristicsText = "Advantages:\n• Standard empire\n• No special bonuses\n• Balanced gameplay";
		}
		var infoText = new Text2(characteristicsText, {
			size: 60,
			fill: 0xFFFFFF,
			weight: 400
		});
		infoText.anchor.set(0.5, 0.5);
		infoText.y = -150;
		self.characteristicsPopup.addChild(infoText);
		// Select Empire button
		var selectButton = new Container();
		var selectBG = selectButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		selectBG.width = 400;
		selectBG.height = 120;
		selectBG.tint = 0x00AA00;
		var selectText = new Text2("Select Empire", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		selectText.anchor.set(0.5, 0.5);
		selectButton.addChild(selectText);
		selectButton.y = 200;
		selectButton.down = function () {
			LK.getSound('Click').play();
			// Store selected empire and start tutorial for easy/normal, or start game directly for others
			gameSettings.selectedEmpire = empireData.name;
			self.removeChild(self.characteristicsPopup);
			self.characteristicsPopup.destroy();
			self.characteristicsPopup = null;
			// Show tutorial for easy and normal modes
			if (self.selectedDifficulty === 'easy' || self.selectedDifficulty === 'normal') {
				self.startTutorial();
			} else {
				self.startGame();
			}
		};
		self.characteristicsPopup.addChild(selectButton);
		// Back button
		var backButton = new Container();
		var backBG = backButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		backBG.width = 200;
		backBG.height = 100;
		backBG.tint = 0xAA0000;
		var backText = new Text2("Back", {
			size: 50,
			fill: 0xFFFFFF,
			weight: 800
		});
		backText.anchor.set(0.5, 0.5);
		backButton.addChild(backText);
		backButton.y = 350;
		backButton.down = function () {
			LK.getSound('Click').play();
			self.removeChild(self.characteristicsPopup);
			self.characteristicsPopup.destroy();
			self.characteristicsPopup = null;
		};
		self.characteristicsPopup.addChild(backButton);
		self.addChild(self.characteristicsPopup);
	};
	self.startTutorial = function () {
		// Check if tutorial has already been completed
		if (storage.tutorialCompleted) {
			// Skip tutorial and start game directly
			self.startGame();
			return;
		}
		// Remove start menu first
		self.destroy();
		// Apply game settings but don't enable interactions yet
		gameSettings.difficulty = self.selectedDifficulty;
		gameSettings.selectedDifficulty = self.selectedDifficulty;
		updateTotalWaves();
		// Apply empire starting gold bonuses
		if (gameSettings.selectedEmpire === 'Ottoman' || gameSettings.selectedEmpire === 'England') {
			setGold(100);
		} else {
			setGold(80);
		}
		// Show UI elements but keep interactions disabled
		if (typeof medievalButton !== "undefined") medievalButton.visible = true;
		if (typeof trenchButton !== "undefined") trenchButton.visible = true;
		if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
		if (typeof goldText !== "undefined") goldText.visible = true;
		if (typeof livesText !== "undefined") livesText.visible = true;
		if (typeof musicControl !== "undefined") musicControl.visible = true;
		if (typeof speedControl !== "undefined") speedControl.visible = true;
		// Update tower cost displays
		for (var i = 0; i < sourceTowers.length; i++) {
			sourceTowers[i].updateCostLabels();
		}
		// Create and show tutorial
		var tutorial = new Tutorial(self.selectedDifficulty);
		tutorial.x = 2048 / 2;
		tutorial.y = 2732 / 2;
		game.addChild(tutorial);
		// Override tutorial end to return to main menu
		tutorial.endTutorial = function () {
			tutorial.isActive = false;
			tutorial.destroy();
			// Mark tutorial as completed and save to storage
			storage.tutorialCompleted = true;
			// Return to main menu after tutorial completion
			var mainMenu = new MainMenu();
			game.addChild(mainMenu);
		};
		tutorial.startTutorial();
	};
	self.startGame = function () {
		// Apply difficulty settings
		gameSettings.difficulty = self.selectedDifficulty;
		gameSettings.selectedDifficulty = self.selectedDifficulty;
		// Update totalWaves based on selected difficulty
		updateTotalWaves();
		// Apply empire starting gold bonuses
		if (gameSettings.selectedEmpire === 'Ottoman' || gameSettings.selectedEmpire === 'England') {
			setGold(100);
		} else {
			setGold(80);
		}
		// Enable game interactions
		gameStartAllowed = true;
		// Restore visibility of hidden elements when game starts
		if (typeof medievalButton !== "undefined") medievalButton.visible = true;
		if (typeof trenchButton !== "undefined") trenchButton.visible = true;
		if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
		if (typeof goldText !== "undefined") goldText.visible = true;
		if (typeof livesText !== "undefined") livesText.visible = true;
		if (typeof musicControl !== "undefined") musicControl.visible = true;
		if (typeof speedControl !== "undefined") speedControl.visible = true;
		// Update tower cost displays for new difficulty
		for (var i = 0; i < sourceTowers.length; i++) {
			sourceTowers[i].updateCostLabels();
		}
		// Exit menu when empire is selected
		self.destroy();
	};
	return self;
});
var MusicControl = Container.expand(function () {
	var self = Container.call(this);
	var buttonBackground = self.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBackground.width = 200;
	buttonBackground.height = 70;
	buttonBackground.tint = 0xFF8800;
	var musicText = new Text2("Music1", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	musicText.anchor.set(0.5, 0.5);
	self.addChild(musicText);
	var currentMusicIndex = 1;
	self.updateDisplay = function () {
		var musicName = currentMusicIndex === 8 ? "Nomusic" : "Music" + currentMusicIndex;
		musicText.setText(musicName);
		// Update button color based on music selection
		switch (currentMusicIndex) {
			case 1:
				buttonBackground.tint = 0xFF8800; // Orange for Music1
				break;
			case 2:
				buttonBackground.tint = 0x8800FF; // Purple for Music2
				break;
			case 3:
				buttonBackground.tint = 0x00FF88; // Green for Music3
				break;
			case 4:
				buttonBackground.tint = 0xFF0088; // Pink for Music4
				break;
			case 5:
				buttonBackground.tint = 0x0088FF; // Blue for Music5
				break;
			case 6:
				buttonBackground.tint = 0x006400; // Dark green for Music6
				break;
			case 7:
				buttonBackground.tint = 0x800080; // Purple for Music7
				break;
			case 8:
				buttonBackground.tint = 0x444444; // Gray for Nomusic
				break;
		}
	};
	self.down = function () {
		// Block music control if difficulty not selected
		if (!gameStartAllowed) {
			return;
		}
		// Cycle through music options 1-8 (including Nomusic at position 8)
		currentMusicIndex = currentMusicIndex >= 8 ? 1 : currentMusicIndex + 1;
		self.updateDisplay();
		// Play the corresponding music track or stop music for Nomusic
		if (currentMusicIndex === 8) {
			LK.stopMusic();
		} else {
			var musicTrack = "warmusic" + (currentMusicIndex === 1 ? "" : currentMusicIndex);
			LK.playMusic(musicTrack);
		}
	};
	// Initialize display
	self.updateDisplay();
	return self;
});
var NextWaveButton = Container.expand(function () {
	var self = Container.call(this);
	var buttonBackground = self.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBackground.width = 300;
	buttonBackground.height = 100;
	buttonBackground.tint = 0x0088FF;
	var buttonText = new Text2("Next Wave", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	buttonText.anchor.set(0.5, 0.5);
	self.addChild(buttonText);
	self.enabled = false;
	self.visible = false;
	self.update = function () {
		if (waveIndicator && waveIndicator.gameStarted && currentWave < totalWaves) {
			self.enabled = true;
			self.visible = true;
			buttonBackground.tint = 0x0088FF;
			self.alpha = 1;
		} else {
			self.enabled = false;
			self.visible = false;
			buttonBackground.tint = 0x888888;
			self.alpha = 0.7;
		}
	};
	self.down = function () {
		// Block next wave if difficulty not selected
		if (!gameStartAllowed) {
			return;
		}
		if (!self.enabled) {
			return;
		}
		if (waveIndicator.gameStarted && currentWave < totalWaves) {
			currentWave++; // Increment to the next wave directly
			waveTimer = 0; // Reset wave timer
			waveInProgress = true;
			waveSpawned = false;
			var notification = game.addChild(new Notification("Wave " + currentWave + " activated!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 150;
		}
	};
	return self;
});
var Notification = Container.expand(function (message) {
	var self = Container.call(this);
	var notificationGraphics = self.attachAsset('notification', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var notificationText = new Text2(message, {
		size: 50,
		fill: 0x000000,
		weight: 800
	});
	notificationText.anchor.set(0.5, 0.5);
	notificationGraphics.width = notificationText.width + 30;
	self.addChild(notificationText);
	self.alpha = 1;
	var fadeOutTime = 120;
	self.update = function () {
		if (fadeOutTime > 0) {
			fadeOutTime--;
			self.alpha = Math.min(fadeOutTime / 120 * 2, 1);
		} else {
			self.destroy();
		}
	};
	return self;
});
var SourceTower = Container.expand(function (towerType) {
	var self = Container.call(this);
	self.towerType = towerType || 'default';
	// Increase size of base for easier touch
	var baseGraphics = self.attachAsset(towerSet === 'futuristic' ? 'future' : towerSet === 'trench' ? 'builds' : towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'Farmland' : 'builds' : 'tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.3,
		scaleY: 1.3
	});
	switch (self.towerType) {
		case 'rapid':
			baseGraphics.tint = 0x00AAFF;
			break;
		case 'sniper':
			baseGraphics.tint = 0xFF5500;
			break;
		case 'splash':
			baseGraphics.tint = 0x33CC00;
			break;
		case 'slow':
			baseGraphics.tint = 0x9900FF;
			break;
		case 'poison':
			baseGraphics.tint = 0x00FFAA;
			break;
		default:
			baseGraphics.tint = 0xAAAAAA;
	}
	var towerCost = getTowerCost(self.towerType);
	// Add shadow for tower type label
	var displayNameShadow = self.towerType === 'default' ? towerSet === 'futuristic' ? 'Robot' : 'Infantry' : self.towerType === 'rapid' ? towerSet === 'futuristic' ? 'Lazerer' : 'Catapult' : self.towerType === 'splash' ? towerSet === 'futuristic' ? 'Fwacha' : 'Hwacha' : self.towerType === 'sniper' ? towerSet === 'futuristic' ? 'Eaglebot' : 'Archer' : self.towerType === 'slow' ? towerSet === 'futuristic' ? 'f-Bullet' : towerSet === 'builds' ? 'Upgrader' : 'Bullet' : self.towerType === 'poison' ? towerSet === 'futuristic' ? 'Hospital' : 'Healer' : self.towerType.charAt(0).toUpperCase() + self.towerType.slice(1);
	var typeLabelShadow = new Text2(displayNameShadow, {
		size: 50,
		fill: 0x000000,
		weight: 800
	});
	typeLabelShadow.anchor.set(0.5, 0.5);
	typeLabelShadow.x = 4;
	typeLabelShadow.y = -20 + 4;
	self.addChild(typeLabelShadow);
	// Add tower type label
	var displayName = self.towerType === 'default' ? towerSet === 'futuristic' ? 'Robot' : towerSet === 'trench' ? 'Blocker' : towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'House' : 'Build1' : 'Infantry' : self.towerType === 'rapid' ? towerSet === 'futuristic' ? 'Lazerer' : towerSet === 'trench' ? 'Trapper' : towerSet === 'builds' ? 'Farm' : 'Catapult' : self.towerType === 'splash' ? towerSet === 'futuristic' ? 'Fwacha' : towerSet === 'builds' ? 'Research' : 'Hwacha' : self.towerType === 'sniper' ? towerSet === 'futuristic' ? 'Eaglebot' : towerSet === 'trench' ? 'Money' : towerSet === 'builds' ? 'Miner' : 'Archer' : self.towerType === 'slow' ? towerSet === 'futuristic' ? 'f-Bullet' : towerSet === 'builds' ? 'Upgrader' : 'Bullet' : self.towerType === 'poison' ? towerSet === 'futuristic' ? 'Hospital' : towerSet === 'builds' ? 'Smith' : 'Healer' : self.towerType.charAt(0).toUpperCase() + self.towerType.slice(1);
	var typeLabel = new Text2(displayName, {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	typeLabel.anchor.set(0.5, 0.5);
	typeLabel.y = -20; // Position above center of tower
	self.addChild(typeLabel);
	// Add cost shadow
	var costLabelShadow = new Text2(towerCost, {
		size: 50,
		fill: 0x000000,
		weight: 800
	});
	costLabelShadow.anchor.set(0.5, 0.5);
	costLabelShadow.x = 4;
	costLabelShadow.y = 24 + 12;
	self.addChild(costLabelShadow);
	// Add cost label
	var displayCost = towerCost;
	var towerOreCost = getTowerOreCost(self.towerType);
	if (towerOreCost > 0) {
		displayCost = towerCost + "G/" + towerOreCost + "O";
	}
	var costLabel = new Text2(displayCost, {
		size: 50,
		fill: 0xFFD700,
		weight: 800
	});
	costLabel.anchor.set(0.5, 0.5);
	costLabel.y = 20 + 12;
	self.addChild(costLabel);
	self.updateCostLabels = function () {
		var newCost = getTowerCost(self.towerType);
		var towerOreCost = getTowerOreCost(self.towerType);
		var displayCost = newCost;
		if (towerOreCost > 0) {
			displayCost = newCost + "G/" + towerOreCost + "O";
		}
		costLabel.setText(displayCost);
		costLabelShadow.setText(displayCost);
	};
	self.update = function () {
		// Check if player can afford this tower
		var towerOreCost = getTowerOreCost(self.towerType);
		var canAfford = gold >= getTowerCost(self.towerType) && ore >= towerOreCost;
		// Set opacity based on affordability
		self.alpha = canAfford ? 1 : 0.5;
	};
	return self;
});
var SpeedControl = Container.expand(function () {
	var self = Container.call(this);
	var buttonBackground = self.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBackground.width = 200;
	buttonBackground.height = 70;
	buttonBackground.tint = 0x0088FF;
	var speedText = new Text2("Normal", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	speedText.anchor.set(0.5, 0.5);
	self.addChild(speedText);
	self.updateDisplay = function () {
		var speedName = gameSpeedOptions[currentSpeedIndex];
		speedText.setText(speedName.charAt(0).toUpperCase() + speedName.slice(1));
		// Update game speed based on selection
		switch (speedName) {
			case 'slow':
				gameSpeed = 0.5;
				buttonBackground.tint = 0xFF8800; // Orange for slow
				break;
			case 'normal':
				gameSpeed = 1.0;
				buttonBackground.tint = 0x0088FF; // Blue for normal
				break;
			case 'fast':
				gameSpeed = 2.0;
				buttonBackground.tint = 0x00FF00; // Green for fast
				break;
			case 'ultra':
				gameSpeed = 2.5; // 25% faster than fast
				buttonBackground.tint = 0xFF0000; // Red for ultra
				break;
			case 'paused':
				gameSpeed = 0.0; // Complete pause
				buttonBackground.tint = 0x666666; // Gray for paused
				break;
		}
	};
	self.down = function () {
		// Block speed control if difficulty not selected
		if (!gameStartAllowed) {
			return;
		}
		// Cycle through speed options
		currentSpeedIndex = (currentSpeedIndex + 1) % gameSpeedOptions.length;
		self.updateDisplay();
	};
	// Initialize display
	self.updateDisplay();
	return self;
});
var StartMenu = Container.expand(function () {
	var self = Container.call(this);
	// Center the menu container
	self.x = 2048 / 2;
	self.y = 2732 / 2;
	// Background overlay
	var menuBackground = self.attachAsset('notification', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	menuBackground.width = 2048;
	menuBackground.height = 2732;
	menuBackground.tint = 0x000000;
	menuBackground.alpha = 0.8;
	// Game title
	var titleText = new Text2("HONORBOUND", {
		size: 150,
		fill: 0xFFFFFF,
		weight: 800
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.y = -250;
	self.addChild(titleText);
	// Subtitle
	var subtitleText = new Text2("Rise on the Fifth Dawn", {
		size: 80,
		fill: 0xCCCCCC,
		weight: 400
	});
	subtitleText.anchor.set(0.5, 0.5);
	subtitleText.y = -150;
	self.addChild(subtitleText);
	// Play button
	var playButton = new Container();
	var playButtonBG = playButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	playButtonBG.width = 400;
	playButtonBG.height = 120;
	playButtonBG.tint = 0x00AA00; // Green color
	var playText = new Text2("PLAY", {
		size: 80,
		fill: 0xFFFFFF,
		weight: 800
	});
	playText.anchor.set(0.5, 0.5);
	playButton.addChild(playText);
	playButton.y = 50;
	playButton.down = function () {
		LK.getSound('Click').play();
		// Remove start menu and show main menu (difficulty selection)
		self.destroy();
		var mainMenu = new MainMenu();
		game.addChild(mainMenu);
	};
	self.addChild(playButton);
	// Story Mode button
	var storyButton = new Container();
	var storyButtonBG = storyButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	storyButtonBG.width = 400;
	storyButtonBG.height = 120;
	storyButtonBG.tint = 0x1976D2; // Blue color for Story Mode
	var storyText = new Text2("Story Mode", {
		size: 70,
		fill: 0xFFFFFF,
		weight: 800
	});
	storyText.anchor.set(0.5, 0.5);
	storyButton.addChild(storyText);
	storyButton.y = playButton.y + 160; // Place below Play button
	// Tutorial button
	var tutorialButton = new Container();
	var tutorialButtonBG = tutorialButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	tutorialButtonBG.width = 400;
	tutorialButtonBG.height = 120;
	tutorialButtonBG.tint = 0x4CAF50; // Green color for Tutorial
	var tutorialText = new Text2("Tutorial", {
		size: 70,
		fill: 0xFFFFFF,
		weight: 800
	});
	tutorialText.anchor.set(0.5, 0.5);
	tutorialButton.addChild(tutorialText);
	tutorialButton.y = storyButton.y + 160; // Place below Story Mode button
	tutorialButton.down = function () {
		LK.getSound('Click').play();
		// Check if tutorial has already been completed
		if (storage.tutorialCompleted) {
			// Show notification that tutorial was already completed and start normal game
			var notification = game.addChild(new Notification("Tutorial already completed! Starting normal game."));
			notification.x = 2048 / 2;
			notification.y = 2732 / 2;
			// Remove start menu and start normal game
			self.destroy();
			gameSettings.difficulty = 'normal';
			gameSettings.selectedEmpire = 'Normal';
			updateTotalWaves();
			setGold(80);
			gameStartAllowed = true;
			// Show UI elements
			if (typeof medievalButton !== "undefined") medievalButton.visible = true;
			if (typeof trenchButton !== "undefined") trenchButton.visible = true;
			if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
			if (typeof goldText !== "undefined") goldText.visible = true;
			if (typeof livesText !== "undefined") livesText.visible = true;
			if (typeof musicControl !== "undefined") musicControl.visible = true;
			if (typeof speedControl !== "undefined") speedControl.visible = true;
			// Update tower cost displays
			for (var i = 0; i < sourceTowers.length; i++) {
				sourceTowers[i].updateCostLabels();
			}
			return;
		}
		// Remove start menu and go directly to tutorial with normal difficulty and Normal empire
		self.destroy();
		// Set up tutorial with default settings
		gameSettings.difficulty = 'normal';
		gameSettings.selectedEmpire = 'Normal';
		updateTotalWaves();
		setGold(80);
		// Show UI elements but keep interactions disabled initially
		if (typeof medievalButton !== "undefined") medievalButton.visible = true;
		if (typeof trenchButton !== "undefined") trenchButton.visible = true;
		if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
		if (typeof goldText !== "undefined") goldText.visible = true;
		if (typeof livesText !== "undefined") livesText.visible = true;
		if (typeof musicControl !== "undefined") musicControl.visible = true;
		if (typeof speedControl !== "undefined") speedControl.visible = true;
		// Update tower cost displays
		for (var i = 0; i < sourceTowers.length; i++) {
			sourceTowers[i].updateCostLabels();
		}
		// Create and show tutorial
		var tutorial = new Tutorial('normal');
		tutorial.x = 2048 / 2;
		tutorial.y = 2732 / 2;
		game.addChild(tutorial);
		// Override tutorial end to return to main menu
		tutorial.endTutorial = function () {
			tutorial.isActive = false;
			tutorial.destroy();
			// Mark tutorial as completed and save to storage
			storage.tutorialCompleted = true;
			// Return to main menu after tutorial completion
			var mainMenu = new MainMenu();
			game.addChild(mainMenu);
		};
		tutorial.startTutorial();
	};
	self.addChild(tutorialButton);
	storyButton.down = function () {
		LK.getSound('Click').play();
		// Remove start menu
		self.destroy();
		// --- STORY MODE SEQUENCE ---
		// Block all input during story mode
		gameStartAllowed = false;
		// Set a flag for story mode
		gameSettings.storyMode = true;
		// --- Play music7 for story mode ---
		LK.playMusic('warmusic7');
		// 1. Black overlay (fade in)
		var blackOverlay = new Container();
		var blackBG = blackOverlay.attachAsset('notification', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		blackBG.width = 2048;
		blackBG.height = 2732;
		blackBG.tint = 0x000000;
		blackBG.alpha = 1;
		blackOverlay.x = 2048 / 2;
		blackOverlay.y = 2732 / 2;
		blackOverlay.alpha = 0;
		game.addChild(blackOverlay);
		// Fade in black overlay over 1s
		tween(blackOverlay, {
			alpha: 1
		}, {
			duration: 1000,
			easing: tween.linear,
			onFinish: function onFinish() {
				// 2. Show story asset (fade in)
				var storyAsset = new Container();
				var storyBG = storyAsset.attachAsset('story', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				storyBG.width = 2048;
				storyBG.height = 2732;
				storyBG.alpha = 1;
				storyAsset.x = 2048 / 2;
				storyAsset.y = 2732 / 2;
				storyAsset.alpha = 0;
				game.addChild(storyAsset);
				tween(storyAsset, {
					alpha: 1
				}, {
					duration: 1000,
					easing: tween.linear
				});
				// 3. After 1s, show first text (fade in)
				LK.setTimeout(function () {
					var text1 = new Text2("Everyone is dead, you are\nthe only one left.", {
						size: 90,
						fill: 0xFFFFFF,
						weight: 800
					});
					text1.anchor.set(0.5, 0.5);
					text1.x = 2048 / 2;
					text1.y = 2732 / 2 - 200;
					text1.alpha = 0;
					game.addChild(text1);
					tween(text1, {
						alpha: 1
					}, {
						duration: 600,
						easing: tween.linear
					});
					// After 3s, fade out text1
					LK.setTimeout(function () {
						tween(text1, {
							alpha: 0
						}, {
							duration: 1000,
							easing: tween.linear,
							onFinish: function onFinish() {
								text1.destroy();
							}
						});
					}, 3000);
					// 4. After 4s, show second text (fade in)
					LK.setTimeout(function () {
						var text2 = new Text2("The enemies that are coming\nnow are advancing towards\nthe capital.", {
							size: 80,
							fill: 0xFFFFFF,
							weight: 800
						});
						text2.anchor.set(0.5, 0.5);
						text2.x = 2048 / 2;
						text2.y = 2732 / 2 - 60;
						text2.alpha = 0;
						game.addChild(text2);
						tween(text2, {
							alpha: 1
						}, {
							duration: 600,
							easing: tween.linear
						});
						// After 5s, fade out text2
						LK.setTimeout(function () {
							tween(text2, {
								alpha: 0
							}, {
								duration: 1000,
								easing: tween.linear,
								onFinish: function onFinish() {
									text2.destroy();
								}
							});
						}, 5000);
						// 5. After 5s (total 9s), show third text (fade in)
						LK.setTimeout(function () {
							var text3 = new Text2("You are the chosen one,\nI have complete confidence\nthat you will save our\nempire. (From Emperor)", {
								size: 70,
								fill: 0xFFFFFF,
								weight: 800
							});
							text3.anchor.set(0.5, 0.5);
							text3.x = 2048 / 2;
							text3.y = 2732 / 2 + 80;
							text3.alpha = 0;
							game.addChild(text3);
							tween(text3, {
								alpha: 1
							}, {
								duration: 600,
								easing: tween.linear
							});
							// After 5s, fade out text3 and story asset, then start game
							LK.setTimeout(function () {
								tween(text3, {
									alpha: 0
								}, {
									duration: 1000,
									easing: tween.linear,
									onFinish: function onFinish() {
										text3.destroy();
									}
								});
								// Fade out story asset and black overlay
								tween(storyAsset, {
									alpha: 0
								}, {
									duration: 1200,
									easing: tween.linear,
									onFinish: function onFinish() {
										storyAsset.destroy();
									}
								});
								tween(blackOverlay, {
									alpha: 0
								}, {
									duration: 1200,
									easing: tween.linear,
									onFinish: function onFinish() {
										blackOverlay.destroy();
										// --- Start game in normal mode, Normal empire ---
										gameSettings.difficulty = 'normal';
										gameSettings.selectedEmpire = 'Normal';
										updateTotalWaves();
										setGold(80);
										// Enable game interactions
										gameStartAllowed = true;
										// Restore visibility of hidden elements when story mode game starts
										if (typeof medievalButton !== "undefined") medievalButton.visible = true;
										if (typeof trenchButton !== "undefined") trenchButton.visible = true;
										if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
										if (typeof goldText !== "undefined") goldText.visible = true;
										if (typeof livesText !== "undefined") livesText.visible = true;
										if (typeof musicControl !== "undefined") musicControl.visible = true;
										if (typeof speedControl !== "undefined") speedControl.visible = true;
										// Update UI for new settings
										updateUI();
										// Remove any menus, show main game
										// Remove all children except core layers and UI
										for (var i = game.children.length - 1; i >= 0; i--) {
											var child = game.children[i];
											// Remove any menu or overlay containers
											if (child instanceof MainMenu || child instanceof StartMenu) {
												game.removeChild(child);
												child.destroy();
											}
										}
										// --- Switch back to music1 after story mode ends ---
										LK.playMusic('warmusic');
									}
								});
							}, 5000);
						}, 5000);
					}, 4000);
				}, 1000);
			}
		});
	};
	self.addChild(storyButton);
	return self;
});
var Tower = Container.expand(function (id) {
	var self = Container.call(this);
	self.id = id || 'default';
	self.towerSet = towerSet;
	self.level = 1;
	self.maxLevel = 6;
	self.gridX = 0;
	self.gridY = 0;
	self.range = 3 * CELL_SIZE;
	// Tower health system
	self.maxHealth = 100;
	// Apply French empire bonus: 20% more tower durability
	if (gameSettings.selectedEmpire === 'French') {
		self.maxHealth = Math.floor(self.maxHealth * 1.2); // 20% more health
	}
	// Apply Byzantine empire bonus: 100% more tower durability
	if (gameSettings.selectedEmpire === 'Byzantine') {
		self.maxHealth = Math.floor(self.maxHealth * 2.0); // 100% more health
	}
	self.health = self.maxHealth;
	// Special trench tower properties
	self.isBlocker = false;
	self.isTrapper = false;
	self.isMoney = false;
	self.goldTimer = 0;
	self.goldInterval = 300; // 5 seconds at 60 FPS
	// Initialize goldTimer for Farm functionality
	if (self.towerSet === 'builds' && self.id === 'rapid') {
		self.goldTimer = 0;
	}
	// Set trench tower properties based on ID
	if (self.towerSet === 'trench') {
		if (self.id === 'default') {
			self.isBlocker = true;
		} else if (self.id === 'rapid') {
			self.isTrapper = true;
		} else if (self.id === 'sniper') {
			self.isMoney = true;
		}
	}
	// Standardized method to get the current range of the tower
	self.getRange = function () {
		// Trench towers: only Trapper has range, Blocker and Money have no range
		if (self.towerSet === 'trench') {
			if (self.isTrapper) {
				// Trapper: base 2.5, +0.5 per level
				return (2.5 + (self.level - 1) * 0.5) * CELL_SIZE;
			} else {
				// Blocker and Money towers have no range
				return 0;
			}
		}
		// Always calculate range based on tower type and level
		switch (self.id) {
			case 'sniper':
				// Sniper: base 5, +0.8 per level, but final upgrade gets a huge boost
				var baseRange;
				if (self.level === self.maxLevel) {
					baseRange = 12 * CELL_SIZE; // Significantly increased range for max level
				} else {
					baseRange = (5 + (self.level - 1) * 0.8) * CELL_SIZE;
				}
				// Apply Scotch empire bonus: 50% more archer range
				if (gameSettings.selectedEmpire === 'Scotch') {
					baseRange = baseRange * 1.5;
				}
				return baseRange;
			case 'splash':
				// Splash: base 4, +0.4 per level (max ~8 blocks at max level)
				return (4 + (self.level - 1) * 0.4) * CELL_SIZE;
			case 'rapid':
				// Rapid: base 2.5, +0.5 per level
				return (2.5 + (self.level - 1) * 0.5) * CELL_SIZE;
			case 'slow':
				// f-Bullet: 2x range when futuristic unlocked
				if (futuristicUnlocked) {
					return (3.5 + (self.level - 1) * 0.5) * CELL_SIZE * 2; // 2x normal range
				}
				// Slow: base 3.5, +0.5 per level
				return (3.5 + (self.level - 1) * 0.5) * CELL_SIZE;
			case 'poison':
				// Hospital: 2x range when futuristic unlocked
				if (futuristicUnlocked) {
					var baseRange = (3.2 + (self.level - 1) * 0.5) * CELL_SIZE * 2; // 2x normal range
					// Apply Kalmar Union empire bonus: 100% more healer range
					if (gameSettings.selectedEmpire === 'Kalmar Union') {
						baseRange = baseRange * 2.0;
					}
					return baseRange;
				}
				// Poison: base 3.2, +0.5 per level
				var baseRange = (3.2 + (self.level - 1) * 0.5) * CELL_SIZE;
				// Apply Kalmar Union empire bonus: 100% more healer range
				if (gameSettings.selectedEmpire === 'Kalmar Union') {
					baseRange = baseRange * 2.0;
				}
				return baseRange;
			default:
				// Default: base 3, +0.5 per level
				return (3 + (self.level - 1) * 0.5) * CELL_SIZE;
		}
	};
	self.cellsInRange = [];
	self.fireRate = 60;
	self.bulletSpeed = 5;
	self.damage = 10;
	self.lastFired = 0;
	self.targetEnemy = null;
	// Check if futuristic has been unlocked and apply 3x fire rate boost
	var fireRateMultiplier = futuristicUnlocked ? 1 / 3 : 1;
	switch (self.id) {
		case 'rapid':
			self.fireRate = 30 * fireRateMultiplier;
			self.damage = 5;
			self.range = 2.5 * CELL_SIZE;
			self.bulletSpeed = 7;
			break;
		case 'sniper':
			self.fireRate = 90 * fireRateMultiplier;
			self.damage = 25;
			self.range = 5 * CELL_SIZE;
			self.bulletSpeed = 25;
			break;
		case 'splash':
			self.fireRate = 52 * fireRateMultiplier; // 30% faster than 75 (75 * 0.7 = 52.5, rounded to 52)
			self.damage = 15;
			self.range = 2 * CELL_SIZE;
			self.bulletSpeed = 4;
			break;
		case 'slow':
			self.fireRate = 50 * fireRateMultiplier;
			self.damage = 8;
			self.range = 3.5 * CELL_SIZE;
			self.bulletSpeed = 5;
			break;
		case 'poison':
			self.fireRate = 70 * fireRateMultiplier;
			self.damage = 12;
			self.range = 3.2 * CELL_SIZE;
			self.bulletSpeed = 5;
			break;
	}
	var baseGraphics = self.attachAsset(towerSet === 'futuristic' ? 'future' : towerSet === 'trench' ? 'builds' : towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'Farmland' : 'builds' : 'tower', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	switch (self.id) {
		case 'rapid':
			baseGraphics.tint = 0x00AAFF;
			break;
		case 'sniper':
			baseGraphics.tint = 0xFF5500;
			break;
		case 'splash':
			baseGraphics.tint = 0x33CC00;
			break;
		case 'slow':
			baseGraphics.tint = 0x9900FF;
			break;
		case 'poison':
			baseGraphics.tint = 0x00FFAA;
			break;
		default:
			baseGraphics.tint = 0xAAAAAA;
	}
	// Add tower health bar
	var towerHealthBarOutline = self.attachAsset('healthBarOutline', {
		anchorX: 0,
		anchorY: 0.5
	});
	var towerHealthBarBG = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	var towerHealthBar = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	towerHealthBarBG.y = towerHealthBarOutline.y = towerHealthBar.y = baseGraphics.height / 2 + 15;
	towerHealthBarOutline.x = -towerHealthBarOutline.width / 2;
	towerHealthBarBG.x = towerHealthBar.x = -towerHealthBar.width / 2 - .5;
	towerHealthBar.tint = 0x00ff00;
	towerHealthBarBG.tint = 0xff0000;
	self.towerHealthBar = towerHealthBar;
	var levelIndicators = [];
	var maxDots = self.maxLevel;
	var dotSpacing = baseGraphics.width / (maxDots + 1);
	var dotSize = CELL_SIZE / 6;
	for (var i = 0; i < maxDots; i++) {
		var dot = new Container();
		var outlineCircle = dot.attachAsset('towerLevelIndicator', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		outlineCircle.width = dotSize + 4;
		outlineCircle.height = dotSize + 4;
		outlineCircle.tint = 0x000000;
		var towerLevelIndicator = dot.attachAsset('towerLevelIndicator', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		towerLevelIndicator.width = dotSize;
		towerLevelIndicator.height = dotSize;
		towerLevelIndicator.tint = 0xCCCCCC;
		dot.x = -CELL_SIZE + dotSpacing * (i + 1);
		dot.y = CELL_SIZE * 0.7;
		self.addChild(dot);
		levelIndicators.push(dot);
	}
	var gunContainer = new Container();
	self.addChild(gunContainer);
	// Don't add arrow/gun graphics for trench towers
	if (self.towerSet !== 'trench') {
		var gunGraphics = gunContainer.attachAsset(towerSet === 'futuristic' ? 'farrow' : 'defense', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	}
	self.updateLevelIndicators = function () {
		for (var i = 0; i < maxDots; i++) {
			var dot = levelIndicators[i];
			var towerLevelIndicator = dot.children[1];
			if (i < self.level) {
				towerLevelIndicator.tint = 0xFFFFFF;
			} else {
				switch (self.id) {
					case 'rapid':
						towerLevelIndicator.tint = 0x00AAFF;
						break;
					case 'sniper':
						towerLevelIndicator.tint = 0xFF5500;
						break;
					case 'splash':
						towerLevelIndicator.tint = 0x33CC00;
						break;
					case 'slow':
						towerLevelIndicator.tint = 0x9900FF;
						break;
					case 'poison':
						towerLevelIndicator.tint = 0x00FFAA;
						break;
					default:
						towerLevelIndicator.tint = 0xAAAAAA;
				}
			}
		}
	};
	self.updateLevelIndicators();
	self.refreshCellsInRange = function () {
		for (var i = 0; i < self.cellsInRange.length; i++) {
			var cell = self.cellsInRange[i];
			var towerIndex = cell.towersInRange.indexOf(self);
			if (towerIndex !== -1) {
				cell.towersInRange.splice(towerIndex, 1);
			}
		}
		self.cellsInRange = [];
		var rangeRadius = self.getRange() / CELL_SIZE;
		var centerX = self.gridX + 1;
		var centerY = self.gridY + 1;
		var minI = Math.floor(centerX - rangeRadius - 0.5);
		var maxI = Math.ceil(centerX + rangeRadius + 0.5);
		var minJ = Math.floor(centerY - rangeRadius - 0.5);
		var maxJ = Math.ceil(centerY + rangeRadius + 0.5);
		for (var i = minI; i <= maxI; i++) {
			for (var j = minJ; j <= maxJ; j++) {
				var closestX = Math.max(i, Math.min(centerX, i + 1));
				var closestY = Math.max(j, Math.min(centerY, j + 1));
				var deltaX = closestX - centerX;
				var deltaY = closestY - centerY;
				var distanceSquared = deltaX * deltaX + deltaY * deltaY;
				if (distanceSquared <= rangeRadius * rangeRadius) {
					var cell = grid.getCell(i, j);
					if (cell) {
						self.cellsInRange.push(cell);
						cell.towersInRange.push(self);
					}
				}
			}
		}
		grid.renderDebug();
	};
	self.getTotalValue = function () {
		var baseTowerCost = getTowerCost(self.id);
		var totalInvestment = baseTowerCost;
		var baseUpgradeCost = baseTowerCost; // Upgrade cost now scales with base tower cost
		for (var i = 1; i < self.level; i++) {
			totalInvestment += Math.floor(baseUpgradeCost * Math.pow(2, i - 1));
		}
		return totalInvestment;
	};
	self.upgrade = function () {
		if (self.level < self.maxLevel) {
			// Exponential upgrade cost: base cost * (2 ^ (level-1)), scaled by tower base cost
			var baseUpgradeCost = getTowerCost(self.id);
			var upgradeCost;
			// Make last upgrade level extra expensive
			if (self.level === self.maxLevel - 1) {
				upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.level - 1) * 3.5 / 2); // Half the cost for final upgrade
			} else {
				upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.level - 1));
			}
			if (gold >= upgradeCost) {
				setGold(gold - upgradeCost);
				self.level++;
				// Increase tower health by 50% on upgrade
				self.maxHealth = Math.floor(self.maxHealth * 1.5);
				self.health = self.maxHealth; // Restore to full health on upgrade
				// No need to update self.range here; getRange() is now the source of truth
				// Apply tower-specific upgrades based on type
				var fireRateMultiplier = futuristicUnlocked ? 1 / 3 : 1;
				if (self.id === 'rapid') {
					if (self.level === self.maxLevel) {
						// Extra powerful last upgrade (double the effect)
						self.fireRate = Math.max(4, 30 - self.level * 9) * fireRateMultiplier; // double the effect
						self.damage = 5 + self.level * 10; // double the effect
						self.bulletSpeed = 7 + self.level * 2.4; // double the effect
					} else {
						self.fireRate = Math.max(15, 30 - self.level * 3) * fireRateMultiplier; // Fast tower gets faster with upgrades
						self.damage = 5 + self.level * 3;
						self.bulletSpeed = 7 + self.level * 0.7;
					}
				} else {
					if (self.level === self.maxLevel) {
						// Extra powerful last upgrade for all other towers (double the effect)
						self.fireRate = Math.max(5, 60 - self.level * 24) * fireRateMultiplier; // double the effect
						self.damage = 10 + self.level * 20; // double the effect
						self.bulletSpeed = 5 + self.level * 2.4; // double the effect
					} else {
						self.fireRate = Math.max(20, 60 - self.level * 8) * fireRateMultiplier;
						self.damage = 10 + self.level * 5;
						self.bulletSpeed = 5 + self.level * 0.5;
					}
				}
				self.refreshCellsInRange();
				self.updateLevelIndicators();
				if (self.level > 1) {
					var levelDot = levelIndicators[self.level - 1].children[1];
					tween(levelDot, {
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 300,
						easing: tween.elasticOut,
						onFinish: function onFinish() {
							tween(levelDot, {
								scaleX: 1,
								scaleY: 1
							}, {
								duration: 200,
								easing: tween.easeOut
							});
						}
					});
				}
				return true;
			} else {
				var notification = game.addChild(new Notification("Not enough gold to upgrade!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 50;
				return false;
			}
		}
		return false;
	};
	self.findTarget = function () {
		var closestEnemy = null;
		var closestScore = Infinity;
		for (var i = 0; i < enemies.length; i++) {
			var enemy = enemies[i];
			var dx = enemy.x - self.x;
			var dy = enemy.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			// Check if enemy is in range
			if (distance <= self.getRange()) {
				// Artillery towers can target all enemy types
				if (self.id === 'splash') {
					// Handle flying enemies differently - they can be targeted regardless of path
					if (enemy.isFlying) {
						// For flying enemies, prioritize by distance to the goal
						if (enemy.flyingTarget) {
							var goalX = enemy.flyingTarget.x;
							var goalY = enemy.flyingTarget.y;
							var distToGoal = Math.sqrt((goalX - enemy.cellX) * (goalX - enemy.cellX) + (goalY - enemy.cellY) * (goalY - enemy.cellY));
							// Use distance to goal as score
							if (distToGoal < closestScore) {
								closestScore = distToGoal;
								closestEnemy = enemy;
							}
						} else {
							// If no flying target yet (shouldn't happen), prioritize by distance to tower
							if (distance < closestScore) {
								closestScore = distance;
								closestEnemy = enemy;
							}
						}
					} else {
						// For ground enemies, use the original path-based targeting
						// Get the cell for this enemy
						var cell = grid.getCell(enemy.cellX, enemy.cellY);
						if (cell && cell.pathId === pathId) {
							// Use the cell's score (distance to exit) for prioritization
							// Lower score means closer to exit
							if (cell.score < closestScore) {
								closestScore = cell.score;
								closestEnemy = enemy;
							}
						}
					}
				} else {
					// Other towers can target both flying and ground enemies
					// Handle flying enemies differently - they can be targeted regardless of path
					if (enemy.isFlying) {
						// For flying enemies, prioritize by distance to the goal
						if (enemy.flyingTarget) {
							var goalX = enemy.flyingTarget.x;
							var goalY = enemy.flyingTarget.y;
							var distToGoal = Math.sqrt((goalX - enemy.cellX) * (goalX - enemy.cellX) + (goalY - enemy.cellY) * (goalY - enemy.cellY));
							// Use distance to goal as score
							if (distToGoal < closestScore) {
								closestScore = distToGoal;
								closestEnemy = enemy;
							}
						} else {
							// If no flying target yet (shouldn't happen), prioritize by distance to tower
							if (distance < closestScore) {
								closestScore = distance;
								closestEnemy = enemy;
							}
						}
					} else {
						// For ground enemies, use the original path-based targeting
						// Get the cell for this enemy
						var cell = grid.getCell(enemy.cellX, enemy.cellY);
						if (cell && cell.pathId === pathId) {
							// Use the cell's score (distance to exit) for prioritization
							// Lower score means closer to exit
							if (cell.score < closestScore) {
								closestScore = cell.score;
								closestEnemy = enemy;
							}
						}
					}
				}
			}
		}
		if (!closestEnemy) {
			self.targetEnemy = null;
		}
		return closestEnemy;
	};
	self.update = function () {
		// Money tower gold generation
		if (self.isMoney) {
			// Only generate gold if game has started and is not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				self.goldTimer += gameSpeed;
				if (self.goldTimer >= self.goldInterval) {
					self.goldTimer = 0;
					setGold(gold + 10);
					var goldIndicator = new GoldIndicator(10, self.x, self.y);
					game.addChild(goldIndicator);
				}
			}
		}
		// Miner functionality for sniper tower in builds set (ultra mode)
		if (self.towerSet === 'builds' && self.id === 'sniper' && gameSettings.difficulty === 'ultra') {
			// Only generate ore if game has started and is not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				self.goldTimer += gameSpeed;
				if (self.goldTimer >= 600) {
					// 10 seconds at 60 FPS
					self.goldTimer = 0;
					ore += 1;
					var oreIndicator = new GoldIndicator("1 Ore", self.x, self.y);
					game.addChild(oreIndicator);
					updateUI();
				}
			}
		}
		// Farm functionality for rapid tower in builds set
		if (self.towerSet === 'builds' && self.id === 'rapid') {
			// Only generate gold if game has started and is not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				self.goldTimer += gameSpeed;
				if (self.goldTimer >= 600) {
					// 10 seconds at 60 FPS
					self.goldTimer = 0;
					setGold(gold + 2);
					var goldIndicator = new GoldIndicator(2, self.x, self.y);
					game.addChild(goldIndicator);
				}
			}
		}
		// Upgrader functionality for builds set (Build5/Upgrader)
		if (self.towerSet === 'builds' && self.id === 'slow') {
			// Set range to match Archer (sniper) tower
			self.getRange = function () {
				// Archer base: 5 + (level-1)*0.8, but use maxLevel for Upgrader
				var baseRange = (5 + (self.level - 1) * 0.8) * CELL_SIZE;
				return baseRange;
			};
			// --- NEW: Instantly increase level by 1 for all towers in range for free ---
			if (!self._upgraderBuffedTowers) self._upgraderBuffedTowers = [];
			// Only activate if game started and not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				// Find all towers in range that haven't been buffed by this Upgrader
				for (var i = 0; i < towers.length; i++) {
					var t = towers[i];
					if (t !== self && self.isInRange(t)) {
						if (!t._upgradedByUpgrader) t._upgradedByUpgrader = [];
						if (t._upgradedByUpgrader.indexOf(self) === -1) {
							// Only buff if not at max level
							if (t.level < t.maxLevel) {
								t.level += 1;
								t.updateLevelIndicators && t.updateLevelIndicators();
								t._upgradedByUpgrader.push(self);
								self._upgraderBuffedTowers.push(t);
							}
						}
					}
				}
			}
		}
		// Smith (Build6) functionality for builds set
		if (self.towerSet === 'builds' && self.id === 'poison') {
			// Set range to match Archer (sniper) tower
			self.getRange = function () {
				var baseRange = (5 + (self.level - 1) * 0.8) * CELL_SIZE;
				return baseRange;
			};
			// --- NEW: Double maxHealth of towers in range, fully heal every 5s, remove on destroy ---
			if (!self._smithBuffedTowers) self._smithBuffedTowers = [];
			// Only activate if game started and not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				// Double maxHealth of towers in range (only once per tower)
				for (var i = 0; i < towers.length; i++) {
					var t = towers[i];
					if (t !== self && self.isInRange(t)) {
						if (!t._smithBuffedBy) t._smithBuffedBy = [];
						if (t._smithBuffedBy.indexOf(self) === -1) {
							t.maxHealth = t.maxHealth * 2;
							t.health = t.maxHealth;
							t._smithBuffedBy.push(self);
							self._smithBuffedTowers.push(t);
							if (t.towerHealthBar) t.towerHealthBar.width = 70;
						}
					}
				}
				// Every 5 seconds, fully heal towers in range
				if (typeof self.smithHealTimer === "undefined") self.smithHealTimer = 0;
				self.smithHealTimer += gameSpeed;
				if (self.smithHealTimer >= 300) {
					// 5 seconds at 60 FPS
					self.smithHealTimer = 0;
					var healed = false;
					for (var i = 0; i < towers.length; i++) {
						var t = towers[i];
						if (t !== self && self.isInRange(t)) {
							if (t.health < t.maxHealth) {
								t.health = t.maxHealth;
								if (t.towerHealthBar) t.towerHealthBar.width = 70;
								healed = true;
							}
						}
					}
					if (healed) {
						var note = game.addChild(new Notification("Smith: Towers in range fully healed!"));
						note.x = 2048 / 2;
						note.y = grid.height - 60;
					}
				}
			}
		}
		// Research functionality - unlocks futuristic towers when built
		if (self.towerSet === 'builds' && self.id === 'splash') {
			// This is Research - it unlocks futuristic towers immediately when built
			if (!futuristicUnlocked) {
				futuristicUnlocked = true;
				var notification = game.addChild(new Notification("Futuristic towers unlocked!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 150;
				// Update all existing towers to benefit from futuristic unlock
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					// Apply 3x fire rate boost to all existing towers
					tower.fireRate = tower.fireRate / 3;
					// Refresh range for slow and poison towers (now cover entire map)
					if (tower.id === 'slow' || tower.id === 'poison') {
						tower.refreshCellsInRange();
					}
				}
			}
		}
		// House functionality for builds in ultra mode
		if (self.towerSet === 'builds' && self.id === 'default' && gameSettings.difficulty === 'ultra') {
			// This is a house - it provides 3 workers when built
			// Workers are added when house is placed, not over time
		}
		// Trapper tower enemy detection and damage
		if (self.isTrapper) {
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				var dx = enemy.x - self.x;
				var dy = enemy.y - self.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				if (distance <= CELL_SIZE && !enemy.trappedBy) {
					enemy.trappedBy = self;
					// Damage all enemies in range when triggered
					for (var j = 0; j < enemies.length; j++) {
						var rangeEnemy = enemies[j];
						var rangeDx = rangeEnemy.x - self.x;
						var rangeDy = rangeEnemy.y - self.y;
						var rangeDistance = Math.sqrt(rangeDx * rangeDx + rangeDy * rangeDy);
						if (rangeDistance <= self.getRange()) {
							var damage = 0;
							if (rangeEnemy.isImmune) {
								// Immune enemies take full health damage
								damage = rangeEnemy.health;
							} else {
								// Regular enemies take 25% damage
								damage = Math.ceil(rangeEnemy.health * 0.25);
							}
							rangeEnemy.health -= damage;
							if (rangeEnemy.health <= 0) {
								rangeEnemy.health = 0;
							} else {
								rangeEnemy.healthBar.width = rangeEnemy.health / rangeEnemy.maxHealth * 70;
							}
						}
					}
					// Destroy trapper after use
					self.health = 0;
					break;
				}
			}
		}
		// Update tower health bar
		if (self.health <= 0) {
			// Healer towers are immune to destruction
			if (self.id === 'poison') {
				self.health = self.maxHealth; // Reset to full health
				self.towerHealthBar.width = 70; // Full health bar
			} else {
				self.health = 0;
				self.towerHealthBar.width = 0;
				// Destroy tower when health reaches zero
				// Remove from cells in range
				for (var i = 0; i < self.cellsInRange.length; i++) {
					var cell = self.cellsInRange[i];
					var towerIndex = cell.towersInRange.indexOf(self);
					if (towerIndex !== -1) {
						cell.towersInRange.splice(towerIndex, 1);
					}
				}
				// Reset grid cells to floor (if not castle walls)
				for (var i = 0; i < 2; i++) {
					for (var j = 0; j < 2; j++) {
						var cell = grid.getCell(self.gridX + i, self.gridY + j);
						if (cell && cell.type !== 4) {
							cell.type = 0;
						}
					}
				}
				// Remove Upgrader/Smith effects from towers in range if this is Upgrader or Smith
				if (self.towerSet === 'builds' && (self.id === 'slow' || self.id === 'poison')) {
					for (var i = 0; i < towers.length; i++) {
						var t = towers[i];
						if (t !== self) {
							// If Upgrader: revert level if it was increased by this Upgrader
							if (self.id === 'slow' && t._upgradedByUpgrader && t._upgradedByUpgrader.indexOf(self) !== -1) {
								if (t.level > 1) {
									t.level -= 1;
									t.updateLevelIndicators && t.updateLevelIndicators();
								}
								// Remove this Upgrader from the list
								var idx = t._upgradedByUpgrader.indexOf(self);
								if (idx !== -1) t._upgradedByUpgrader.splice(idx, 1);
							}
							// If Smith: revert maxHealth and health if it was buffed by this Smith
							if (self.id === 'poison' && t._smithBuffedBy && t._smithBuffedBy.indexOf(self) !== -1) {
								t.maxHealth = t.maxHealth / 2;
								if (t.health > t.maxHealth) t.health = t.maxHealth;
								if (t.towerHealthBar) t.towerHealthBar.width = t.health / t.maxHealth * 70;
								// Remove this Smith from the buffedBy list
								var sidx = t._smithBuffedBy.indexOf(self);
								if (sidx !== -1) t._smithBuffedBy.splice(sidx, 1);
							}
						}
					}
					// Clean up Upgrader/Smith's buffed towers list
					if (self._upgraderBuffedTowers) self._upgraderBuffedTowers = [];
					if (self._smithBuffedTowers) self._smithBuffedTowers = [];
				}
				// Check if this is Research being destroyed - lock futuristic towers and remove existing ones
				if (self.towerSet === 'builds' && self.id === 'splash') {
					// This is Research being destroyed - lock futuristic towers
					futuristicUnlocked = false;
					// Remove all existing futuristic towers and refund their cost
					for (var i = towers.length - 1; i >= 0; i--) {
						var tower = towers[i];
						if (tower.towerSet === 'futuristic') {
							// Calculate refund value
							var totalInvestment = tower.getTotalValue ? tower.getTotalValue() : 0;
							var refundValue = getTowerSellValue(totalInvestment);
							setGold(gold + refundValue);
							// Remove from cells in range
							for (var j = 0; j < tower.cellsInRange.length; j++) {
								var cell = tower.cellsInRange[j];
								var towerIndex = cell.towersInRange.indexOf(tower);
								if (towerIndex !== -1) {
									cell.towersInRange.splice(towerIndex, 1);
								}
							}
							// Reset grid cells to floor (if not castle walls)
							for (var gx = 0; gx < 2; gx++) {
								for (var gy = 0; gy < 2; gy++) {
									var cell = grid.getCell(tower.gridX + gx, tower.gridY + gy);
									if (cell && cell.type !== 4) {
										cell.type = 0;
									}
								}
							}
							// Clear selected tower if this was selected
							if (selectedTower === tower) {
								selectedTower = null;
							}
							// Remove from towers array
							var towerArrayIndex = towers.indexOf(tower);
							if (towerArrayIndex !== -1) {
								towers.splice(towerArrayIndex, 1);
							}
							// Remove from game
							tower.destroy();
						}
					}
					// Switch back to medieval towers if currently on futuristic
					if (towerSet === 'futuristic') {
						towerSet = 'medieval';
						updateSourceTowers();
						medievalBG.tint = 0x8B4513;
						medievalBG.alpha = 0.5;
						futuristicBG.tint = 0x222222;
						futuristicBG.alpha = 0.5;
					}
					var notification = game.addChild(new Notification("Research destroyed! Futuristic towers locked and removed!"));
					notification.x = 2048 / 2;
					notification.y = grid.height - 100;
				}
				// Remove tower from towers array
				var towerIndex = towers.indexOf(self);
				if (towerIndex !== -1) {
					towers.splice(towerIndex, 1);
				}
				// Clear selected tower if this was selected
				if (selectedTower === self) {
					selectedTower = null;
				}
				// Remove tower from game
				self.destroy();
				// Update pathfinding
				grid.pathFind();
				grid.renderDebug();
				return;
			}
		} else {
			self.towerHealthBar.width = self.health / self.maxHealth * 70;
		}
		self.targetEnemy = self.findTarget();
		if (self.targetEnemy) {
			var dx = self.targetEnemy.x - self.x;
			var dy = self.targetEnemy.y - self.y;
			var angle = Math.atan2(dy, dx);
			// Only rotate gun container if this is not a Trecher tower or Healer tower
			if (self.id !== 'slow' && self.id !== 'poison') {
				gunContainer.rotation = angle;
			}
			// Check if this tower is affected by any Trecher towers
			var effectiveFireRate = self.fireRate;
			if (self.id !== 'slow') {
				// Trechers don't boost themselves
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					if (tower.id === 'slow' && tower.isInRange(self)) {
						effectiveFireRate = self.fireRate * 0.5; // 50% faster firing (half the fire rate delay)
						break;
					}
				}
			}
			// Apply Austrian empire bonus: 20% faster fire rate (20% less delay)
			if (gameSettings.selectedEmpire === 'Austria') {
				effectiveFireRate = effectiveFireRate * 0.8; // 20% faster firing
			}
			if (LK.ticks - self.lastFired >= effectiveFireRate / gameSpeed) {
				self.fire();
				self.lastFired = LK.ticks;
			}
		}
	};
	self.down = function (x, y, obj) {
		var existingMenus = game.children.filter(function (child) {
			return child instanceof UpgradeMenu;
		});
		var hasOwnMenu = false;
		var rangeCircle = null;
		for (var i = 0; i < game.children.length; i++) {
			if (game.children[i].isTowerRange && game.children[i].tower === self) {
				rangeCircle = game.children[i];
				break;
			}
		}
		for (var i = 0; i < existingMenus.length; i++) {
			if (existingMenus[i].tower === self) {
				hasOwnMenu = true;
				break;
			}
		}
		if (hasOwnMenu) {
			for (var i = 0; i < existingMenus.length; i++) {
				if (existingMenus[i].tower === self) {
					hideUpgradeMenu(existingMenus[i]);
				}
			}
			if (rangeCircle) {
				game.removeChild(rangeCircle);
			}
			selectedTower = null;
			grid.renderDebug();
			return;
		}
		for (var i = 0; i < existingMenus.length; i++) {
			existingMenus[i].destroy();
		}
		for (var i = game.children.length - 1; i >= 0; i--) {
			if (game.children[i].isTowerRange) {
				game.removeChild(game.children[i]);
			}
		}
		selectedTower = self;
		var rangeIndicator = new Container();
		rangeIndicator.isTowerRange = true;
		rangeIndicator.tower = self;
		game.addChild(rangeIndicator);
		rangeIndicator.x = self.x;
		rangeIndicator.y = self.y;
		var rangeGraphics = rangeIndicator.attachAsset('rangeCircle', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		rangeGraphics.width = rangeGraphics.height = self.getRange() * 2;
		rangeGraphics.alpha = 0.3;
		var upgradeMenu = new UpgradeMenu(self);
		game.addChild(upgradeMenu);
		upgradeMenu.x = 2048 / 2;
		tween(upgradeMenu, {
			y: 2732 - 225
		}, {
			duration: 200,
			easing: tween.backOut
		});
		grid.renderDebug();
	};
	self.isInRange = function (enemy) {
		if (!enemy) {
			return false;
		}
		var dx = enemy.x - self.x;
		var dy = enemy.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		return distance <= self.getRange();
	};
	self.fire = function () {
		// Trecher towers don't fire bullets - they only provide support effects
		if (self.id === 'slow') {
			return;
		}
		// Healer towers don't fire bullets - they only provide healing/protection effects
		if (self.id === 'poison') {
			return;
		}
		// Trench towers don't fire bullets - they only provide support effects
		if (self.towerSet === 'trench') {
			return;
		}
		// Builds towers (house, Farm, build 3,4,5,6) don't fire bullets
		if (self.towerSet === 'builds') {
			return;
		}
		if (self.targetEnemy) {
			var potentialDamage = 0;
			for (var i = 0; i < self.targetEnemy.bulletsTargetingThis.length; i++) {
				potentialDamage += self.targetEnemy.bulletsTargetingThis[i].damage;
			}
			if (self.targetEnemy.health > potentialDamage) {
				var bulletX = self.x + Math.cos(gunContainer.rotation) * 40;
				var bulletY = self.y + Math.sin(gunContainer.rotation) * 40;
				var bulletDamage = self.damage;
				// Apply Ottoman empire bonus: 20% more damage
				if (gameSettings.selectedEmpire === 'Ottoman') {
					bulletDamage = Math.ceil(bulletDamage * 1.2); // 20% more damage
				}
				var bullet = new Bullet(bulletX, bulletY, self.targetEnemy, bulletDamage, self.bulletSpeed);
				// Set bullet type based on tower type
				bullet.type = self.id;
				// Customize bullet appearance based on tower type
				switch (self.id) {
					case 'rapid':
						bullet.children[0].tint = 0x00AAFF;
						bullet.children[0].width = 20;
						bullet.children[0].height = 20;
						break;
					case 'sniper':
						bullet.children[0].tint = 0xFF5500;
						bullet.children[0].width = 15;
						bullet.children[0].height = 15;
						break;
					case 'splash':
						bullet.children[0].tint = 0x33CC00;
						bullet.children[0].width = 40;
						bullet.children[0].height = 40;
						break;
					case 'poison':
						bullet.children[0].tint = 0x00FFAA;
						bullet.children[0].width = 35;
						bullet.children[0].height = 35;
						break;
				}
				game.addChild(bullet);
				bullets.push(bullet);
				self.targetEnemy.bulletsTargetingThis.push(bullet);
				// --- Fire recoil effect for gunContainer ---
				// Stop any ongoing recoil tweens before starting a new one
				tween.stop(gunContainer, {
					x: true,
					y: true,
					scaleX: true,
					scaleY: true
				});
				// Always use the original resting position for recoil, never accumulate offset
				if (gunContainer._restX === undefined) {
					gunContainer._restX = 0;
				}
				if (gunContainer._restY === undefined) {
					gunContainer._restY = 0;
				}
				if (gunContainer._restScaleX === undefined) {
					gunContainer._restScaleX = 1;
				}
				if (gunContainer._restScaleY === undefined) {
					gunContainer._restScaleY = 1;
				}
				// Reset to resting position before animating (in case of interrupted tweens)
				gunContainer.x = gunContainer._restX;
				gunContainer.y = gunContainer._restY;
				gunContainer.scaleX = gunContainer._restScaleX;
				gunContainer.scaleY = gunContainer._restScaleY;
				// Calculate recoil offset (recoil back along the gun's rotation)
				var recoilDistance = 8;
				var recoilX = -Math.cos(gunContainer.rotation) * recoilDistance;
				var recoilY = -Math.sin(gunContainer.rotation) * recoilDistance;
				// Animate recoil back from the resting position
				tween(gunContainer, {
					x: gunContainer._restX + recoilX,
					y: gunContainer._restY + recoilY
				}, {
					duration: 60,
					easing: tween.cubicOut,
					onFinish: function onFinish() {
						// Animate return to original position/scale
						tween(gunContainer, {
							x: gunContainer._restX,
							y: gunContainer._restY
						}, {
							duration: 90,
							easing: tween.cubicIn
						});
					}
				});
			}
		}
	};
	self.placeOnGrid = function (gridX, gridY) {
		self.gridX = gridX;
		self.gridY = gridY;
		self.x = grid.x + gridX * CELL_SIZE + CELL_SIZE / 2;
		self.y = grid.y + gridY * CELL_SIZE + CELL_SIZE / 2;
		for (var i = 0; i < 2; i++) {
			for (var j = 0; j < 2; j++) {
				var cell = grid.getCell(gridX + i, gridY + j);
				if (cell) {
					// All towers block enemy movement except Trapper
					if (self.isTrapper) {
						// Trapper allows enemies to pass through
						cell.type = 0;
					} else {
						// All other structures block enemy movement
						cell.type = 1;
					}
				}
			}
		}
		self.refreshCellsInRange();
		// Completely destroy and recreate tower preview when tower is successfully placed
		if (towerPreview && towerPreview.parent) {
			game.removeChild(towerPreview);
			towerPreview.destroy();
			towerPreview = new TowerPreview();
			towerPreview.visible = false;
		}
	};
	return self;
});
var TowerPreview = Container.expand(function () {
	var self = Container.call(this);
	var towerRange = 3;
	var rangeInPixels = towerRange * CELL_SIZE;
	self.towerType = 'default';
	self.hasEnoughGold = true;
	var rangeIndicator = new Container();
	self.addChild(rangeIndicator);
	var rangeGraphics = rangeIndicator.attachAsset('rangeCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	rangeGraphics.alpha = 0.3;
	var previewGraphics = self.attachAsset(towerSet === 'futuristic' ? 'futurep' : towerSet === 'trench' ? 'builds' : towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'Farmland' : 'builds' : 'rare', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	previewGraphics.width = CELL_SIZE * 2;
	previewGraphics.height = CELL_SIZE * 2;
	self.canPlace = false;
	self.gridX = 0;
	self.gridY = 0;
	self.blockedByEnemy = false;
	self.update = function () {
		var previousHasEnoughGold = self.hasEnoughGold;
		var towerOreCost = getTowerOreCost(self.towerType);
		self.hasEnoughGold = gold >= getTowerCost(self.towerType) && ore >= towerOreCost;
		// Only update appearance if the affordability status has changed
		if (previousHasEnoughGold !== self.hasEnoughGold) {
			self.updateAppearance();
		}
	};
	self.updateAppearance = function () {
		// Use Tower class to get the source of truth for range
		var tempTower = new Tower(self.towerType);
		var previewRange = tempTower.getRange();
		// Clean up tempTower to avoid memory leaks
		if (tempTower && tempTower.destroy) {
			tempTower.destroy();
		}
		// Set range indicator using unified range logic
		rangeGraphics.width = rangeGraphics.height = previewRange * 2;
		switch (self.towerType) {
			case 'rapid':
				previewGraphics.tint = 0x00AAFF;
				break;
			case 'sniper':
				previewGraphics.tint = 0xFF5500;
				break;
			case 'splash':
				previewGraphics.tint = 0x33CC00;
				break;
			case 'slow':
				previewGraphics.tint = 0x9900FF;
				break;
			case 'poison':
				previewGraphics.tint = 0x00FFAA;
				break;
			default:
				previewGraphics.tint = 0xAAAAAA;
		}
		if (!self.canPlace || !self.hasEnoughGold) {
			previewGraphics.tint = 0xFF0000;
		}
	};
	self.updatePlacementStatus = function () {
		var validGridPlacement = true;
		if (self.gridY <= 4 || self.gridY + 1 >= grid.cells[0].length - 4) {
			validGridPlacement = false;
		} else {
			for (var i = 0; i < 2; i++) {
				for (var j = 0; j < 2; j++) {
					var cell = grid.getCell(self.gridX + i, self.gridY + j);
					// Allow placement only on regular floor (type 0)
					if (!cell || cell.type !== 0) {
						validGridPlacement = false;
						break;
					}
				}
				if (!validGridPlacement) {
					break;
				}
			}
		}
		self.blockedByEnemy = false;
		if (validGridPlacement) {
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				if (enemy.currentCellY < 4) {
					continue;
				}
				// Only check non-flying enemies, flying enemies can pass over towers
				if (!enemy.isFlying) {
					if (enemy.cellX >= self.gridX && enemy.cellX < self.gridX + 2 && enemy.cellY >= self.gridY && enemy.cellY < self.gridY + 2) {
						self.blockedByEnemy = true;
						break;
					}
					if (enemy.currentTarget) {
						var targetX = enemy.currentTarget.x;
						var targetY = enemy.currentTarget.y;
						if (targetX >= self.gridX && targetX < self.gridX + 2 && targetY >= self.gridY && targetY < self.gridY + 2) {
							self.blockedByEnemy = true;
							break;
						}
					}
				}
			}
		}
		self.canPlace = validGridPlacement && !self.blockedByEnemy;
		self.hasEnoughGold = gold >= getTowerCost(self.towerType);
		self.updateAppearance();
	};
	self.checkPlacement = function () {
		self.updatePlacementStatus();
	};
	self.snapToGrid = function (x, y) {
		var gridPosX = x - grid.x;
		var gridPosY = y - grid.y;
		self.gridX = Math.floor(gridPosX / CELL_SIZE);
		self.gridY = Math.floor(gridPosY / CELL_SIZE);
		self.x = grid.x + self.gridX * CELL_SIZE + CELL_SIZE / 2;
		self.y = grid.y + self.gridY * CELL_SIZE + CELL_SIZE / 2;
		self.checkPlacement();
	};
	return self;
});
var Tutorial = Container.expand(function (difficulty) {
	var self = Container.call(this);
	self.difficulty = difficulty;
	self.currentStep = 0;
	self.tutorialSteps = [];
	self.isActive = false;
	// Tutorial overlay background
	var tutorialOverlay = self.attachAsset('notification', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	tutorialOverlay.width = 2048;
	tutorialOverlay.height = 2732;
	tutorialOverlay.tint = 0x000000;
	tutorialOverlay.alpha = 0.7;
	// Tutorial text box
	var textBox = new Container();
	var textBG = textBox.attachAsset('menu', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	textBG.width = 1600;
	textBG.height = 400;
	textBG.alpha = 0.95;
	var tutorialText = new Text2("", {
		size: 60,
		fill: 0xFFFFFF,
		weight: 600
	});
	tutorialText.anchor.set(0.5, 0.5);
	textBox.addChild(tutorialText);
	textBox.x = 0;
	textBox.y = -200;
	self.addChild(textBox);
	// Next button
	var nextButton = new Container();
	var nextBG = nextButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	nextBG.width = 300;
	nextBG.height = 100;
	nextBG.tint = 0x00AA00;
	var nextText = new Text2("Next", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	nextText.anchor.set(0.5, 0.5);
	nextButton.addChild(nextText);
	nextButton.x = 0;
	nextButton.y = 150;
	nextButton.down = function () {
		self.nextStep();
	};
	self.addChild(nextButton);
	// Define tutorial steps based on difficulty
	if (difficulty === 'easy') {
		self.tutorialSteps = [{
			text: "Welcome to HONORBOUND!\nThis is Easy Mode - perfect for learning.\nTowers cost 50% less and enemies are easier.",
			indicator: {
				x: 0,
				y: 0,
				visible: false
			}
		}, {
			text: "This is your gold (top right).\nYou spend gold to build towers.\nYou earn gold by defeating enemies.",
			indicator: {
				x: 1500,
				y: -1200,
				visible: true
			}
		}, {
			text: "These are your lives (top left).\nYou lose lives when enemies reach the bottom.\nDon't let them reach zero!",
			indicator: {
				x: -1500,
				y: -1200,
				visible: true
			}
		}, {
			text: "These are tower types you can build.\nDrag them onto the battlefield to place towers.\nEach has different abilities and costs.",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Advanced Technology: Futuristic towers unlock\nat wave 4. They have\n3x faster fire rate and\nspecial abilities. Robot, Lazerer,\nEaglebot, Fwacha, f-Bullet, Hospital.",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Click 'Start Game' to begin the first wave.\nEnemies will spawn from the top and try to reach the bottom.",
			indicator: {
				x: 0,
				y: 800,
				visible: true
			}
		}, {
			text: "Good luck, Commander!\nBuild towers to stop the enemies.\nUpgrade towers by clicking on them.",
			indicator: {
				x: 0,
				y: 0,
				visible: false
			}
		}];
	} else {
		self.tutorialSteps = [{
			text: "Welcome to HONORBOUND!\nYou are the last defender of the empire.\nStop the advancing enemies at all costs!",
			indicator: {
				x: 0,
				y: 0,
				visible: false
			}
		}, {
			text: "Gold (top right) is your main resource.\nSpend it wisely on towers and upgrades.\nEarn more by defeating enemies.",
			indicator: {
				x: 1500,
				y: -1200,
				visible: true
			}
		}, {
			text: "Lives (top left) represent your defenses.\nEach enemy that escapes costs 1 life.\nBoss enemies cost more lives!",
			indicator: {
				x: -1500,
				y: -1200,
				visible: true
			}
		}, {
			text: "Tower Selection: Drag towers to build them.\nInfantry: Balanced • Catapult: Fast\nArcher: Long range • Hwacha: Area damage",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Advanced towers: Bullet (slows enemies)\nHealer (protects nearby towers)\nClick built towers to upgrade them.",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Speed Control (top center): Adjust game speed.\nMusic Control: Change background music.\nUse these to manage your strategy.",
			indicator: {
				x: 0,
				y: -1200,
				visible: true
			}
		}, {
			text: "Futuristic Technology: At wave 4,\nunlock advanced towers! Robot, Lazerer,\nEaglebot, Fwacha, f-Bullet, Hospital.\nThey fire 3x faster\nwith special abilities.",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Wave System: Enemies come in waves.\nEach wave gets stronger.\nPrepare defenses between waves!",
			indicator: {
				x: 0,
				y: 800,
				visible: true
			}
		}, {
			text: "Strategic Tips:\n• Block enemy paths with towers\n• Upgrade key towers\n• Use terrain to your advantage",
			indicator: {
				x: 0,
				y: 0,
				visible: false
			}
		}, {
			text: "The fate of the empire rests with you!\nClick 'Start Game' when ready.\nMay victory be yours, Commander!",
			indicator: {
				x: 0,
				y: 800,
				visible: true
			}
		}];
	}
	self.startTutorial = function () {
		self.isActive = true;
		self.currentStep = 0;
		self.showCurrentStep();
	};
	self.showCurrentStep = function () {
		if (self.currentStep >= self.tutorialSteps.length) {
			self.endTutorial();
			return;
		}
		var step = self.tutorialSteps[self.currentStep];
		tutorialText.setText(step.text);
		// Remove existing indicators
		for (var i = self.children.length - 1; i >= 0; i--) {
			if (self.children[i].isTutorialIndicator) {
				self.removeChild(self.children[i]);
			}
		}
		// Add indicators based on tutorial step
		if (self.difficulty === 'easy') {
			if (self.currentStep === 1) {
				// Gold instruction
				var goldIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				goldIndicator.x = 500;
				goldIndicator.y = -1150;
				goldIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 2) {
				// Lives instruction  
				var livesIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				livesIndicator.x = -500;
				livesIndicator.y = -1150;
				livesIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 4) {
				// Futuristic towers instruction
				var futuristicIndicator = self.attachAsset('isaret2', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				futuristicIndicator.x = 0;
				futuristicIndicator.y = 1050;
				futuristicIndicator.isTutorialIndicator = true;
			}
		} else {
			// Normal difficulty
			if (self.currentStep === 1) {
				// Gold instruction
				var goldIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				goldIndicator.x = 500;
				goldIndicator.y = -1150;
				goldIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 2) {
				// Lives instruction
				var livesIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				livesIndicator.x = -500;
				livesIndicator.y = -1150;
				livesIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 5) {
				// Speed Control and Music instruction
				var speedIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				speedIndicator.x = -100;
				speedIndicator.y = -1150;
				speedIndicator.isTutorialIndicator = true;
				var musicIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				musicIndicator.x = 100;
				musicIndicator.y = -1150;
				musicIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 6) {
				// Futuristic towers instruction
				var futuristicIndicator = self.attachAsset('isaret2', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				futuristicIndicator.x = 0;
				futuristicIndicator.y = 1050;
				futuristicIndicator.isTutorialIndicator = true;
			}
		}
		// Update next button text
		if (self.currentStep === self.tutorialSteps.length - 1) {
			nextText.setText("Start!");
		} else {
			nextText.setText("Next");
		}
	};
	self.nextStep = function () {
		self.currentStep++;
		if (self.currentStep >= self.tutorialSteps.length) {
			self.endTutorial();
		} else {
			self.showCurrentStep();
		}
	};
	self.endTutorial = function () {
		self.isActive = false;
		// Mark tutorial as completed and save to storage
		storage.tutorialCompleted = true;
		// Remove any tutorial indicators
		for (var i = self.children.length - 1; i >= 0; i--) {
			if (self.children[i].isTutorialIndicator) {
				self.removeChild(self.children[i]);
			}
		}
		self.destroy();
		// Return to main menu after tutorial completion
		var mainMenu = new MainMenu();
		game.addChild(mainMenu);
	};
	return self;
});
var UpgradeMenu = Container.expand(function (tower) {
	var self = Container.call(this);
	self.tower = tower;
	self.y = 2732 + 225;
	var menuBackground = self.attachAsset('menu', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	menuBackground.width = 2048;
	menuBackground.height = 500;
	menuBackground.alpha = 0.9;
	var towerDisplayName = self.tower.id === 'default' ? self.tower.towerSet === 'futuristic' ? 'Robot' : self.tower.towerSet === 'trench' ? 'Blocker' : self.tower.towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'House' : 'Build1' : 'Infantry' : self.tower.id === 'rapid' ? self.tower.towerSet === 'futuristic' ? 'Lazerer' : self.tower.towerSet === 'trench' ? 'Trapper' : self.tower.towerSet === 'builds' ? 'Farm' : 'Catapult' : self.tower.id === 'splash' ? self.tower.towerSet === 'futuristic' ? 'Fwacha' : self.tower.towerSet === 'builds' ? 'Research' : 'Hwacha' : self.tower.id === 'sniper' ? self.tower.towerSet === 'futuristic' ? 'Eaglebot' : self.tower.towerSet === 'trench' ? 'Money' : self.tower.towerSet === 'builds' ? 'Miner' : 'Archer' : self.tower.id === 'slow' ? self.tower.towerSet === 'futuristic' ? 'f-Bullet' : self.tower.towerSet === 'builds' ? 'Upgrader' : 'Bullet' : self.tower.id === 'poison' ? self.tower.towerSet === 'futuristic' ? 'Hospital' : self.tower.towerSet === 'builds' ? 'Smith' : 'Healer' : self.tower.id.charAt(0).toUpperCase() + self.tower.id.slice(1);
	var towerTypeText = new Text2(towerDisplayName + ' Tower', {
		size: 80,
		fill: 0xFFFFFF,
		weight: 800
	});
	towerTypeText.anchor.set(0, 0);
	towerTypeText.x = -840;
	towerTypeText.y = -160;
	self.addChild(towerTypeText);
	var statsText = new Text2('Level: ' + self.tower.level + '/' + self.tower.maxLevel + '\nDamage: ' + self.tower.damage + '\nFire Rate: ' + (60 / self.tower.fireRate).toFixed(1) + '/s', {
		size: 70,
		fill: 0xFFFFFF,
		weight: 400
	});
	statsText.anchor.set(0, 0.5);
	statsText.x = -840;
	statsText.y = 50;
	self.addChild(statsText);
	var buttonsContainer = new Container();
	buttonsContainer.x = 500;
	self.addChild(buttonsContainer);
	var upgradeButton = new Container();
	buttonsContainer.addChild(upgradeButton);
	var buttonBackground = upgradeButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBackground.width = 500;
	buttonBackground.height = 150;
	var isMaxLevel = self.tower.level >= self.tower.maxLevel;
	// Exponential upgrade cost: base cost * (2 ^ (level-1)), scaled by tower base cost
	var baseUpgradeCost = getTowerCost(self.tower.id);
	var upgradeCost;
	if (isMaxLevel) {
		upgradeCost = 0;
	} else if (self.tower.level === self.tower.maxLevel - 1) {
		upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1) * 3.5 / 2);
	} else {
		upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1));
	}
	buttonBackground.tint = isMaxLevel ? 0x888888 : gold >= upgradeCost ? 0x00AA00 : 0x888888;
	var buttonText = new Text2(isMaxLevel ? 'Max Level' : 'Upgrade: ' + upgradeCost + ' gold', {
		size: 60,
		fill: 0xFFFFFF,
		weight: 800
	});
	buttonText.anchor.set(0.5, 0.5);
	upgradeButton.addChild(buttonText);
	var sellButton = new Container();
	buttonsContainer.addChild(sellButton);
	var sellButtonBackground = sellButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	sellButtonBackground.width = 500;
	sellButtonBackground.height = 150;
	sellButtonBackground.tint = 0xCC0000;
	var totalInvestment = self.tower.getTotalValue ? self.tower.getTotalValue() : 0;
	var sellValue = getTowerSellValue(totalInvestment);
	var sellButtonText = new Text2('Sell: +' + sellValue + ' gold', {
		size: 60,
		fill: 0xFFFFFF,
		weight: 800
	});
	sellButtonText.anchor.set(0.5, 0.5);
	sellButton.addChild(sellButtonText);
	upgradeButton.y = -85;
	sellButton.y = 85;
	var closeButton = new Container();
	self.addChild(closeButton);
	var closeBackground = closeButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	closeBackground.width = 90;
	closeBackground.height = 90;
	closeBackground.tint = 0xAA0000;
	var closeText = new Text2('X', {
		size: 68,
		fill: 0xFFFFFF,
		weight: 800
	});
	closeText.anchor.set(0.5, 0.5);
	closeButton.addChild(closeText);
	closeButton.x = menuBackground.width / 2 - 57;
	closeButton.y = -menuBackground.height / 2 + 57;
	upgradeButton.down = function (x, y, obj) {
		if (self.tower.level >= self.tower.maxLevel) {
			var notification = game.addChild(new Notification("Tower is already at max level!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
			return;
		}
		if (self.tower.upgrade()) {
			// Exponential upgrade cost: base cost * (2 ^ (level-1)), scaled by tower base cost
			var baseUpgradeCost = getTowerCost(self.tower.id);
			if (self.tower.level >= self.tower.maxLevel) {
				upgradeCost = 0;
			} else if (self.tower.level === self.tower.maxLevel - 1) {
				upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1) * 3.5 / 2);
			} else {
				upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1));
			}
			statsText.setText('Level: ' + self.tower.level + '/' + self.tower.maxLevel + '\nDamage: ' + self.tower.damage + '\nFire Rate: ' + (60 / self.tower.fireRate).toFixed(1) + '/s');
			buttonText.setText('Upgrade: ' + upgradeCost + ' gold');
			var totalInvestment = self.tower.getTotalValue ? self.tower.getTotalValue() : 0;
			var sellValue = Math.floor(totalInvestment * 0.6);
			sellButtonText.setText('Sell: +' + sellValue + ' gold');
			if (self.tower.level >= self.tower.maxLevel) {
				buttonBackground.tint = 0x888888;
				buttonText.setText('Max Level');
			}
			var rangeCircle = null;
			for (var i = 0; i < game.children.length; i++) {
				if (game.children[i].isTowerRange && game.children[i].tower === self.tower) {
					rangeCircle = game.children[i];
					break;
				}
			}
			if (rangeCircle) {
				var rangeGraphics = rangeCircle.children[0];
				rangeGraphics.width = rangeGraphics.height = self.tower.getRange() * 2;
			} else {
				var newRangeIndicator = new Container();
				newRangeIndicator.isTowerRange = true;
				newRangeIndicator.tower = self.tower;
				game.addChildAt(newRangeIndicator, 0);
				newRangeIndicator.x = self.tower.x;
				newRangeIndicator.y = self.tower.y;
				var rangeGraphics = newRangeIndicator.attachAsset('rangeCircle', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				rangeGraphics.width = rangeGraphics.height = self.tower.getRange() * 2;
				rangeGraphics.alpha = 0.3;
			}
			tween(self, {
				scaleX: 1.05,
				scaleY: 1.05
			}, {
				duration: 100,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					tween(self, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 100,
						easing: tween.easeIn
					});
				}
			});
		}
	};
	sellButton.down = function (x, y, obj) {
		var totalInvestment = self.tower.getTotalValue ? self.tower.getTotalValue() : 0;
		var sellValue = getTowerSellValue(totalInvestment);
		setGold(gold + sellValue);
		var notification = game.addChild(new Notification("Tower sold for " + sellValue + " gold!"));
		notification.x = 2048 / 2;
		notification.y = grid.height - 50;
		// Handle population logic for houses in ultra mode
		if (gameSettings.difficulty === 'ultra' && self.tower.towerSet === 'builds' && self.tower.id === 'default') {
			// This was a house - reduce population by 1000
			population = Math.max(0, population - 1000);
			var popNotification = game.addChild(new Notification("-1000 population"));
			popNotification.x = 2048 / 2;
			popNotification.y = grid.height - 100;
		}
		updateUI();
		var gridX = self.tower.gridX;
		var gridY = self.tower.gridY;
		for (var i = 0; i < 2; i++) {
			for (var j = 0; j < 2; j++) {
				var cell = grid.getCell(gridX + i, gridY + j);
				if (cell) {
					// Only reset to floor if it's not a castle wall
					if (cell.type !== 4) {
						cell.type = 0;
					}
					var towerIndex = cell.towersInRange.indexOf(self.tower);
					if (towerIndex !== -1) {
						cell.towersInRange.splice(towerIndex, 1);
					}
				}
			}
		}
		if (selectedTower === self.tower) {
			selectedTower = null;
		}
		var towerIndex = towers.indexOf(self.tower);
		if (towerIndex !== -1) {
			towers.splice(towerIndex, 1);
		}
		towerLayer.removeChild(self.tower);
		grid.pathFind();
		grid.renderDebug();
		self.destroy();
		for (var i = 0; i < game.children.length; i++) {
			if (game.children[i].isTowerRange && game.children[i].tower === self.tower) {
				game.removeChild(game.children[i]);
				break;
			}
		}
	};
	closeButton.down = function (x, y, obj) {
		hideUpgradeMenu(self);
		selectedTower = null;
		grid.renderDebug();
	};
	self.update = function () {
		if (self.tower.level >= self.tower.maxLevel) {
			if (buttonText.text !== 'Max Level') {
				buttonText.setText('Max Level');
				buttonBackground.tint = 0x888888;
			}
			return;
		}
		// Exponential upgrade cost: base cost * (2 ^ (level-1)), scaled by tower base cost
		var baseUpgradeCost = getTowerCost(self.tower.id);
		var currentUpgradeCost;
		if (self.tower.level >= self.tower.maxLevel) {
			currentUpgradeCost = 0;
		} else if (self.tower.level === self.tower.maxLevel - 1) {
			currentUpgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1) * 3.5 / 2);
		} else {
			currentUpgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1));
		}
		var canAfford = gold >= currentUpgradeCost;
		buttonBackground.tint = canAfford ? 0x00AA00 : 0x888888;
		var newText = 'Upgrade: ' + currentUpgradeCost + ' gold';
		if (buttonText.text !== newText) {
			buttonText.setText(newText);
		}
	};
	return self;
});
var WaveIndicator = Container.expand(function () {
	var self = Container.call(this);
	self.gameStarted = false;
	self.waveMarkers = [];
	self.waveTypes = [];
	self.enemyCounts = [];
	self.indicatorWidth = 0;
	self.lastBossType = null; // Track the last boss type to avoid repeating
	var blockWidth = 400;
	var totalBlocksWidth = blockWidth * totalWaves;
	var startMarker = new Container();
	var startBlock = startMarker.attachAsset('hi', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	startBlock.width = blockWidth - 10;
	startBlock.height = 70 * 2;
	startBlock.tint = 0x00AA00;
	// Add shadow for start text
	var startTextShadow = new Text2("Start Game", {
		size: 50,
		fill: 0x000000,
		weight: 800
	});
	startTextShadow.anchor.set(0.5, 0.5);
	startTextShadow.x = 4;
	startTextShadow.y = 4;
	startMarker.addChild(startTextShadow);
	var startText = new Text2("Start Game", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	startText.anchor.set(0.5, 0.5);
	startMarker.addChild(startText);
	startMarker.x = -self.indicatorWidth;
	self.addChild(startMarker);
	self.waveMarkers.push(startMarker);
	startMarker.down = function () {
		// Block game start if difficulty not selected
		if (!gameStartAllowed) {
			return;
		}
		if (!self.gameStarted) {
			self.gameStarted = true;
			currentWave = 0;
			waveTimer = nextWaveTime;
			startBlock.tint = 0x00FF00;
			startText.setText("Started!");
			startTextShadow.setText("Started!");
			// Make sure shadow position remains correct after text change
			startTextShadow.x = 4;
			startTextShadow.y = 4;
			// Reset to medieval towers at game start
			if (towerSet === 'futuristic') {
				towerSet = 'medieval';
				updateSourceTowers();
				medievalBG.tint = 0x8B4513;
				medievalBG.alpha = 0.5; // Keep transparency
				futuristicBG.tint = 0x222222;
				futuristicBG.alpha = 0.5; // Keep transparency
			}
			var notification = game.addChild(new Notification("Game started! Wave 1 incoming!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 150;
			// Start music when game begins
			LK.playMusic('warmusic');
		}
	};
	for (var i = 0; i < totalWaves; i++) {
		var marker = new Container();
		var block = marker.attachAsset('hi', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		block.width = blockWidth - 10;
		block.height = 70 * 2;
		// All waves are normal enemy waves
		var waveType = "Dawn";
		var enemyType = "normal";
		var enemyCount = 10;
		block.tint = 0xAAAAAA;
		// Store the wave type and enemy count
		self.waveTypes[i] = enemyType;
		self.enemyCounts[i] = enemyCount;
		// Add shadow for wave type - 30% smaller than before
		var waveTypeShadow = new Text2(waveType, {
			size: 56,
			fill: 0x000000,
			weight: 800
		});
		waveTypeShadow.anchor.set(0.5, 0.5);
		waveTypeShadow.x = 4;
		waveTypeShadow.y = 4;
		marker.addChild(waveTypeShadow);
		// Add wave type text - 30% smaller than before
		var waveTypeText = new Text2(waveType, {
			size: 56,
			fill: 0xFFFFFF,
			weight: 800
		});
		waveTypeText.anchor.set(0.5, 0.5);
		waveTypeText.y = 0;
		marker.addChild(waveTypeText);
		// Add shadow for wave number - 20% larger than before
		var waveNumShadow = new Text2((i + 1).toString(), {
			size: 48,
			fill: 0x000000,
			weight: 800
		});
		waveNumShadow.anchor.set(1.0, 1.0);
		waveNumShadow.x = blockWidth / 2 - 16 + 5;
		waveNumShadow.y = block.height / 2 - 12 + 5;
		marker.addChild(waveNumShadow);
		// Main wave number text - 20% larger than before
		var waveNum = new Text2((i + 1).toString(), {
			size: 48,
			fill: 0xFFFFFF,
			weight: 800
		});
		waveNum.anchor.set(1.0, 1.0);
		waveNum.x = blockWidth / 2 - 16;
		waveNum.y = block.height / 2 - 12;
		marker.addChild(waveNum);
		marker.x = -self.indicatorWidth + (i + 1) * blockWidth;
		self.addChild(marker);
		self.waveMarkers.push(marker);
	}
	// Get wave type for a specific wave number
	self.getWaveType = function (waveNumber) {
		if (waveNumber < 1 || waveNumber > totalWaves) {
			return "normal";
		}
		// If this is a boss wave (waveNumber % 10 === 0), and the type is the same as lastBossType
		// then we should return a different boss type
		var waveType = self.waveTypes[waveNumber - 1];
		return waveType;
	};
	// Get enemy count for a specific wave number
	self.getEnemyCount = function (waveNumber) {
		if (waveNumber < 1 || waveNumber > totalWaves) {
			return 10;
		}
		return self.enemyCounts[waveNumber - 1];
	};
	// Get display name for a wave type
	self.getWaveTypeName = function (waveNumber) {
		var type = self.getWaveType(waveNumber);
		var typeName = type.charAt(0).toUpperCase() + type.slice(1);
		// Boss spawning disabled - no boss prefix for waves 10, 20, 30
		// if (waveNumber % 10 === 0 && waveNumber > 0 && type !== 'swarm') {
		//     typeName = "BOSS";
		// }
		return typeName;
	};
	self.positionIndicator = new Container();
	var indicator = self.positionIndicator.attachAsset('towerLevelIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	indicator.width = blockWidth - 10;
	indicator.height = 16;
	indicator.tint = 0xffad0e;
	indicator.y = -65;
	var indicator2 = self.positionIndicator.attachAsset('towerLevelIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	indicator2.width = blockWidth - 10;
	indicator2.height = 16;
	indicator2.tint = 0xffad0e;
	indicator2.y = 65;
	var leftWall = self.positionIndicator.attachAsset('towerLevelIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	leftWall.width = 16;
	leftWall.height = 146;
	leftWall.tint = 0xffad0e;
	leftWall.x = -(blockWidth - 16) / 2;
	var rightWall = self.positionIndicator.attachAsset('towerLevelIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	rightWall.width = 16;
	rightWall.height = 146;
	rightWall.tint = 0xffad0e;
	rightWall.x = (blockWidth - 16) / 2;
	self.addChild(self.positionIndicator);
	self.update = function () {
		var progress = waveTimer / nextWaveTime;
		var moveAmount = (progress + currentWave) * blockWidth;
		for (var i = 0; i < self.waveMarkers.length; i++) {
			var marker = self.waveMarkers[i];
			marker.x = -moveAmount + i * blockWidth;
		}
		self.positionIndicator.x = 0;
		for (var i = 0; i < totalWaves + 1; i++) {
			var marker = self.waveMarkers[i];
			if (i === 0) {
				continue;
			}
			var block = marker.children[0];
			// Only apply red tint after game has started
			if (self.gameStarted) {
				if (i - 1 < currentWave) {
					// Completed waves: red tint with reduced alpha
					block.alpha = .5;
					tween(block, {
						tint: 0xFF0000
					}, {
						duration: 300,
						easing: tween.easeOut
					});
				}
			}
		}
		self.handleWaveProgression = function () {
			if (!self.gameStarted) {
				return;
			}
			// Skip wave progression when game is paused (gameSpeed = 0)
			if (gameSpeed === 0) {
				return;
			}
			if (currentWave < totalWaves) {
				waveTimer += gameSpeed;
				if (waveTimer >= nextWaveTime) {
					waveTimer = 0;
					currentWave++;
					waveInProgress = true;
					waveSpawned = false;
					if (currentWave != 1) {
						var notification = game.addChild(new Notification("Wave " + currentWave + " incoming!"));
						notification.x = 2048 / 2;
						notification.y = grid.height - 150;
					}
				}
			}
		};
		self.handleWaveProgression();
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x333333
});
/**** 
* Game Code
****/ 
// Initialize gameSettings early to prevent undefined access
var gameSettings = {
	difficulty: 'normal',
	selectedEmpire: 'Normal'
};
var isHidingUpgradeMenu = false;
function hideUpgradeMenu(menu) {
	if (isHidingUpgradeMenu) {
		return;
	}
	isHidingUpgradeMenu = true;
	tween(menu, {
		y: 2732 + 225
	}, {
		duration: 150,
		easing: tween.easeIn,
		onFinish: function onFinish() {
			menu.destroy();
			isHidingUpgradeMenu = false;
		}
	});
}
var CELL_SIZE = 76;
var pathId = 1;
var maxScore = 0;
var enemies = [];
var towers = [];
var bullets = [];
var defenses = [];
var selectedTower = null;
// --- Population-based gold income for ultra mode ---
if (gameSettings.difficulty === 'ultra') {
	var populationGoldTimer = 0;
	game.update = function (origUpdate) {
		return function () {
			// Call original update
			if (typeof origUpdate === "function") origUpdate.apply(this, arguments);
			// Only run if game is started and not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				populationGoldTimer += gameSpeed;
				if (populationGoldTimer >= 1800) {
					// 30 seconds at 60 FPS
					populationGoldTimer = 0;
					var popK = Math.floor(population / 1000);
					if (popK > 0) {
						var goldToAdd = popK * 3;
						setGold(gold + goldToAdd);
						var note = game.addChild(new Notification("+" + goldToAdd + " gold from population!"));
						note.x = 2048 / 2;
						note.y = grid.height - 180;
					}
				}
			}
		};
	}(game.update);
}
// Update gameSettings with stored values
gameSettings.difficulty = 'normal';
gameSettings.selectedEmpire = 'Normal';
var goldMines = [];
var gold = gameSettings.selectedEmpire === 'Ottoman' ? 100 : 80;
// Leaderboard system for ultra mode
var playerScore = 0;
var playerName = "";
// Leaderboard functionality removed
var leaderboardData = [];
// Population system for ultra mode
if (gameSettings.difficulty === 'ultra') {
	var population = 0; // Start with 0 population
	var ultraEnemyKills = 0;
	var ore = 0; // Ore resource for ultra mode only - starts at 0
} else {
	var population = 0;
	var ore = 0; // Initialize ore for all modes to prevent undefined
}
// Generate a new session seed on each reload/restart
var reloadCounter = 0;
reloadCounter++;
var gameSessionSeed = reloadCounter * 12345 + Math.floor(Date.now() / 1000); // Unique seed per reload
// Track if difficulty has been selected and game can start
var gameStartAllowed = false;
var lives = 10;
var currentWave = 0;
var totalWaves = gameSettings.difficulty === 'ultra' ? 30 : gameSettings.difficulty === 'hardcore' ? 10 : 5;
var waveTimer = 0;
var waveInProgress = false;
var waveSpawned = false;
var nextWaveTime = 12000 / 2;
var gameSpeed = 1.0; // 1.0 = normal, 0.5 = slow, 2.0 = fast
var gameSpeedOptions = ['slow', 'normal', 'fast', 'ultra', 'paused'];
var currentSpeedIndex = 1; // Start with normal (index 1)
var sourceTower = null;
var enemiesToSpawn = 10; // Default number of enemies per wave
var goldText = new Text2('Gold: ' + gold, {
	size: 60,
	fill: 0xFFD700,
	weight: 800
});
goldText.anchor.set(0.5, 0.5);
var livesText = new Text2('Lives: ' + lives, {
	size: 60,
	fill: 0x00FF00,
	weight: 800
});
livesText.anchor.set(0.5, 0.5);
var populationText = new Text2('Population: ' + population, {
	size: 60,
	fill: 0x00FFFF,
	weight: 800
});
populationText.anchor.set(0.5, 0.5);
var oreText = new Text2('Ore: ' + ore, {
	size: 60,
	fill: 0x888888,
	weight: 800
});
oreText.anchor.set(0.5, 0.5);
var topMargin = 50;
var centerX = 2048 / 2;
var spacing = 400;
// Hide these elements initially in menu
goldText.visible = false;
livesText.visible = false;
LK.gui.top.addChild(goldText);
LK.gui.top.addChild(livesText);
// Only show populationText in ultra mode
if (gameSettings.difficulty === 'ultra') {
	LK.gui.top.addChild(populationText);
	LK.gui.top.addChild(oreText);
	populationText.x = spacing;
	populationText.y = topMargin + 80; // Position below gold
	populationText.visible = true;
	oreText.x = spacing;
	oreText.y = topMargin + 160; // Position below population text
	oreText.visible = true;
} else {
	populationText.visible = false;
	oreText.visible = false;
}
livesText.x = -spacing;
livesText.y = topMargin;
goldText.x = spacing;
goldText.y = topMargin;
function updateTotalWaves() {
	totalWaves = gameSettings.difficulty === 'ultra' ? 30 : gameSettings.difficulty === 'hardcore' ? 10 : 5;
	// Recreate wave indicator with correct number of waves
	if (waveIndicator && waveIndicator.parent) {
		waveIndicator.parent.removeChild(waveIndicator);
		waveIndicator.destroy();
	}
	waveIndicator = new WaveIndicator();
	waveIndicator.x = 2048 / 2;
	waveIndicator.y = 2732 - 80;
	game.addChild(waveIndicator);
}
function updateUI() {
	goldText.setText('Gold: ' + gold);
	livesText.setText('Lives: ' + lives);
	if (gameSettings.difficulty === 'ultra') {
		// Ensure population and ore UI elements are added to GUI if not already present
		if (!populationText.parent) {
			LK.gui.top.addChild(populationText);
			populationText.x = spacing;
			populationText.y = topMargin + 80;
		}
		if (!oreText.parent) {
			LK.gui.top.addChild(oreText);
			oreText.x = spacing;
			oreText.y = topMargin + 160;
		}
		populationText.setText('Population: ' + population);
		oreText.setText('Ore: ' + ore);
		populationText.visible = true;
		oreText.visible = true;
	} else {
		populationText.visible = false;
		oreText.visible = false;
	}
}
function setGold(value) {
	gold = value;
	updateUI();
}
function addScore(points) {
	if (gameSettings.difficulty === 'ultra') {
		playerScore += points;
	}
}
var debugLayer = new Container();
var towerLayer = new Container();
// Create three separate layers for enemy hierarchy
var enemyLayerBottom = new Container(); // For normal enemies
var enemyLayerMiddle = new Container(); // For shadows
var enemyLayerTop = new Container(); // For flying enemies
var enemyLayer = new Container(); // Main container to hold all enemy layers
// Add layers in correct order (bottom first, then middle for shadows, then top)
enemyLayer.addChild(enemyLayerBottom);
enemyLayer.addChild(enemyLayerMiddle);
enemyLayer.addChild(enemyLayerTop);
// Create background tile grid (12x15)
var backgroundContainer = new Container();
var bgTileWidth = 2048 / 12; // Divide screen width by 12
var bgTileHeight = 2732 / 15; // Divide screen height by 15
for (var row = 0; row < 15; row++) {
	for (var col = 0; col < 12; col++) {
		var bgTile = backgroundContainer.attachAsset('background', {
			anchorX: 0,
			anchorY: 0,
			width: bgTileWidth,
			height: bgTileHeight
		});
		bgTile.x = col * bgTileWidth;
		bgTile.y = row * bgTileHeight;
	}
}
// Add background container first (behind everything else)
game.addChild(backgroundContainer);
var grid = new Grid(24, 29 + 6);
grid.x = 150;
grid.y = 200 - CELL_SIZE * 4;
grid.pathFind();
grid.renderDebug();
debugLayer.addChild(grid);
game.addChild(debugLayer);
game.addChild(towerLayer);
game.addChild(enemyLayer);
var offset = 0;
var towerPreview = new TowerPreview();
game.addChild(towerPreview);
towerPreview.visible = false;
var isDragging = false;
function wouldBlockPath(gridX, gridY) {
	// Trapper towers don't block paths
	if (towerPreview && towerPreview.towerType === 'rapid' && towerSet === 'trench') {
		return false;
	}
	var cells = [];
	for (var i = 0; i < 2; i++) {
		for (var j = 0; j < 2; j++) {
			var cell = grid.getCell(gridX + i, gridY + j);
			if (cell) {
				cells.push({
					cell: cell,
					originalType: cell.type
				});
				cell.type = 1;
			}
		}
	}
	var blocked = grid.pathFind();
	for (var i = 0; i < cells.length; i++) {
		cells[i].cell.type = cells[i].originalType;
	}
	grid.pathFind();
	grid.renderDebug();
	return blocked;
}
function getTowerCost(towerType) {
	var cost = 10;
	switch (towerType) {
		case 'rapid':
			// Different costs for trench vs medieval/futuristic
			if (towerSet === 'trench') {
				cost = 50; // Trapper cost
			} else {
				cost = 30; // Original catapult cost
			}
			break;
		case 'sniper':
			// Different costs for trench vs medieval/futuristic
			if (towerSet === 'trench') {
				cost = 120; // Money tower cost
			} else {
				cost = 50; // Original archer cost
			}
			break;
		case 'splash':
			cost = 50;
			break;
		case 'slow':
			cost = gameSettings.difficulty === 'hardcore' ? 100 : 50;
			break;
		case 'poison':
			cost = gameSettings.difficulty === 'hardcore' ? 100 : 50;
			break;
	}
	// Apply Easy mode discount
	if (gameSettings.difficulty === 'easy') {
		cost = Math.floor(cost / 2);
	}
	// Apply Hungary empire bonus: 5 gold less on normal and higher difficulties
	if (gameSettings.selectedEmpire === 'Hungary' && gameSettings.difficulty !== 'easy') {
		cost = Math.max(5, cost - 5); // Minimum cost of 5 gold
	}
	// Apply Scotch empire bonus: 3 gold less for all towers
	if (gameSettings.selectedEmpire === 'Scotch') {
		cost = Math.max(5, cost - 3); // Minimum cost of 5 gold
	}
	// Remove price doubling - research no longer increases costs
	return cost;
}
function getTowerOreCost(towerType) {
	// Upgrader (Build5) in builds set always costs 10 ore in ultra mode
	if (towerSet === 'builds' && gameSettings.difficulty === 'ultra' && towerType === 'slow') {
		return 10;
	}
	// Smith (Build6) in builds set always costs 15 ore in ultra mode
	if (towerSet === 'builds' && gameSettings.difficulty === 'ultra' && towerType === 'poison') {
		return 15;
	}
	// Only futuristic towers in ultra mode require ore
	if (towerSet === 'futuristic' && gameSettings.difficulty === 'ultra') {
		switch (towerType) {
			case 'default':
				return 5;
			case 'rapid':
				return 3;
			case 'sniper':
				return 8;
			case 'splash':
				return 7;
			case 'slow':
				return 6;
			case 'poison':
				return 9;
			default:
				return 5;
		}
	}
	return 0;
}
function getTowerSellValue(totalValue) {
	return waveIndicator && waveIndicator.gameStarted ? Math.floor(totalValue * 0.6) : totalValue;
}
function placeTower(gridX, gridY, towerType) {
	var towerCost = getTowerCost(towerType);
	var towerOreCost = getTowerOreCost(towerType);
	if (gold >= towerCost && ore >= towerOreCost) {
		// Check if this is a house (Build1 in Ultra mode)
		var isHouse = towerSet === 'builds' && towerType === 'default' && gameSettings.difficulty === 'ultra';
		var tower = new Tower(towerType || 'default');
		tower.placeOnGrid(gridX, gridY);
		towerLayer.addChild(tower);
		towers.push(tower);
		setGold(gold - towerCost);
		ore -= towerOreCost;
		// Handle population logic only in ultra mode
		if (gameSettings.difficulty === 'ultra') {
			if (isHouse) {
				// Each house gives 1000 population
				population += 1000;
				var note = game.addChild(new Notification("+1000 population!"));
				note.x = 2048 / 2;
				note.y = grid.height - 100;
			}
		}
		updateUI();
		grid.pathFind();
		grid.renderDebug();
		return true;
	} else {
		var notification = game.addChild(new Notification("Not enough gold!"));
		notification.x = 2048 / 2;
		notification.y = grid.height - 50;
		return false;
	}
}
game.down = function (x, y, obj) {
	// Block all interactions if difficulty not selected
	if (!gameStartAllowed) {
		return;
	}
	var upgradeMenuVisible = game.children.some(function (child) {
		return child instanceof UpgradeMenu;
	});
	if (upgradeMenuVisible) {
		return;
	}
	for (var i = 0; i < sourceTowers.length; i++) {
		var tower = sourceTowers[i];
		if (x >= tower.x - tower.width / 2 && x <= tower.x + tower.width / 2 && y >= tower.y - tower.height / 2 && y <= tower.y + tower.height / 2) {
			// Completely recreate tower preview to ensure clean state
			if (towerPreview && towerPreview.parent) {
				game.removeChild(towerPreview);
				towerPreview.destroy();
			}
			towerPreview = new TowerPreview();
			game.addChild(towerPreview);
			towerPreview.visible = true;
			isDragging = true;
			towerPreview.towerType = tower.towerType;
			towerPreview.updateAppearance();
			// Apply the same offset as in move handler to ensure consistency when starting drag
			towerPreview.snapToGrid(x, y - CELL_SIZE * 1.5);
			break;
		}
	}
};
game.move = function (x, y, obj) {
	// Block all interactions if difficulty not selected
	if (!gameStartAllowed) {
		return;
	}
	if (isDragging) {
		// Shift the y position upward by 1.5 tiles to show preview above finger
		towerPreview.snapToGrid(x, y - CELL_SIZE * 1.5);
	}
};
game.up = function (x, y, obj) {
	// Block all interactions if difficulty not selected
	if (!gameStartAllowed) {
		return;
	}
	var clickedOnTower = false;
	for (var i = 0; i < towers.length; i++) {
		var tower = towers[i];
		var towerLeft = tower.x - tower.width / 2;
		var towerRight = tower.x + tower.width / 2;
		var towerTop = tower.y - tower.height / 2;
		var towerBottom = tower.y + tower.height / 2;
		if (x >= towerLeft && x <= towerRight && y >= towerTop && y <= towerBottom) {
			clickedOnTower = true;
			break;
		}
	}
	var upgradeMenus = game.children.filter(function (child) {
		return child instanceof UpgradeMenu;
	});
	if (upgradeMenus.length > 0 && !isDragging && !clickedOnTower) {
		var clickedOnMenu = false;
		for (var i = 0; i < upgradeMenus.length; i++) {
			var menu = upgradeMenus[i];
			var menuWidth = 2048;
			var menuHeight = 450;
			var menuLeft = menu.x - menuWidth / 2;
			var menuRight = menu.x + menuWidth / 2;
			var menuTop = menu.y - menuHeight / 2;
			var menuBottom = menu.y + menuHeight / 2;
			if (x >= menuLeft && x <= menuRight && y >= menuTop && y <= menuBottom) {
				clickedOnMenu = true;
				break;
			}
		}
		if (!clickedOnMenu) {
			for (var i = 0; i < upgradeMenus.length; i++) {
				var menu = upgradeMenus[i];
				hideUpgradeMenu(menu);
			}
			for (var i = game.children.length - 1; i >= 0; i--) {
				if (game.children[i].isTowerRange) {
					game.removeChild(game.children[i]);
				}
			}
			selectedTower = null;
			grid.renderDebug();
		}
	}
	if (isDragging) {
		isDragging = false;
		if (towerPreview.canPlace) {
			if (!wouldBlockPath(towerPreview.gridX, towerPreview.gridY)) {
				placeTower(towerPreview.gridX, towerPreview.gridY, towerPreview.towerType);
			} else {
				var notification = game.addChild(new Notification("Tower would block the path!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 50;
			}
		} else if (towerPreview.blockedByEnemy) {
			var notification = game.addChild(new Notification("Cannot build: Enemy in the way!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
		} else if (towerPreview.visible) {
			var notification = game.addChild(new Notification("Cannot build here!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
		}
		towerPreview.visible = false;
		// Completely destroy and recreate tower preview to ensure it's completely clean
		if (towerPreview.parent) {
			game.removeChild(towerPreview);
			towerPreview.destroy();
			towerPreview = new TowerPreview();
			towerPreview.visible = false;
		}
		if (isDragging) {
			var upgradeMenus = game.children.filter(function (child) {
				return child instanceof UpgradeMenu;
			});
			for (var i = 0; i < upgradeMenus.length; i++) {
				upgradeMenus[i].destroy();
			}
		}
	}
};
var waveIndicator = new WaveIndicator();
waveIndicator.x = 2048 / 2;
waveIndicator.y = 2732 - 80;
game.addChild(waveIndicator);
// Create tower set buttons first (they will be behind the menu)
// Tower set buttons are already created above
// Always show start menu at game start with PLAY button
// --- Layered, non-interactive, behind-menu text labels ---
// Create a container for background labels
var menuBackgroundLabels = new Container();
menuBackgroundLabels.x = 2048 / 2;
menuBackgroundLabels.y = 2732 / 2;
menuBackgroundLabels.alpha = 0.13; // Faint, but visible behind menu
// Helper to add a label
function addMenuBGLabel(text, x, y, size, color, rotation) {
	var label = new Text2(text, {
		size: size,
		fill: color,
		weight: 800
	});
	label.anchor.set(0.5, 0.5);
	label.x = x;
	label.y = y;
	if (rotation) label.rotation = rotation;
	label.interactive = false;
	label.buttonMode = false;
	menuBackgroundLabels.addChild(label);
}
// Add the requested labels, spaced and sized for background effect
addMenuBGLabel("Medieval", -600, -700, 220, 0x8B4513, -0.08);
addMenuBGLabel("locked", 600, -700, 180, 0x888888, 0.07);
addMenuBGLabel("Trench", -600, 0, 200, 0x8B4513, 0.05);
addMenuBGLabel("lives", 600, 0, 180, 0x00FF00, -0.06);
addMenuBGLabel("normal", -600, 700, 200, 0x0088FF, 0.08);
addMenuBGLabel("music1", 600, 700, 180, 0xFF8800, -0.07);
addMenuBGLabel("Gold", 0, 0, 300, 0xFFD700, 0);
// Place the label container behind the menu
game.addChildAt(menuBackgroundLabels, 0);
var startMenu = new StartMenu();
game.addChild(startMenu);
var speedControl = new SpeedControl();
speedControl.x = -100; // Position closer to center to be adjacent to music control
speedControl.y = topMargin;
// Hide speed control in menu initially
speedControl.visible = false;
LK.gui.top.addChild(speedControl);
var musicControl = new MusicControl();
musicControl.x = 100; // Position closer to center to be adjacent to speed control
musicControl.y = topMargin;
// Hide music control in menu initially
musicControl.visible = false;
LK.gui.top.addChild(musicControl);
// Leaderboard functionality removed
// --- Tower Set Toggle Buttons ---
var towerSet = 'medieval'; // 'medieval', 'futuristic', or 'trench'
var futuristicUnlocked = false; // Track if futuristic towers have been unlocked
// Define tower types for each set
var medievalTowerTypes = ['default', 'rapid', 'sniper', 'splash', 'slow', 'poison'];
var futuristicTowerTypes = ['default', 'rapid', 'sniper', 'splash', 'slow', 'poison']; // Placeholder, can be changed later
var trenchTowerTypes = ['default', 'rapid', 'sniper']; // Blocker, Trapper, Money
var buildsTowerTypes = ['default', 'rapid', 'sniper', 'splash', 'slow', 'poison']; // 6 build options for Ultra mode
var sourceTowers = [];
var towerSpacing = 300; // Increase spacing for larger towers
var towerY = 2732 - CELL_SIZE * 3 - 90;
// Button container - add to game so it's in front of towers
var towerSetButtonContainer = new Container();
towerSetButtonContainer.x = 2048 / 2;
// Move the button container up by the button height (100px) so the buttons are higher by their own height
towerSetButtonContainer.y = towerY - 60 - 100; // Move up by button height
game.addChild(towerSetButtonContainer);
// Move to top of display list so it's in front of towers
if (towerSetButtonContainer.parent) {
	towerSetButtonContainer.parent.removeChild(towerSetButtonContainer);
}
game.addChild(towerSetButtonContainer);
// Medieval Button
var medievalButton = new Container();
var medievalBG = medievalButton.attachAsset('Buton', {
	anchorX: 0.5,
	anchorY: 0.5
});
medievalBG.width = 350;
medievalBG.height = 100;
medievalBG.tint = 0x8B4513;
medievalBG.alpha = 0.8; // Reduce transparency
var medievalText = new Text2("Medieval", {
	size: 55,
	fill: 0xFFFFFF,
	weight: 800
});
medievalText.anchor.set(0.5, 0.5);
medievalText.alpha = 0.9; // Reduce transparency
medievalButton.addChild(medievalText);
// Arrange tower set buttons side by side, not overlapping
var buttonSpacing = 400; // Enough to avoid overlap, adjust as needed for visuals
medievalButton.x = -buttonSpacing;
medievalButton.y = 0;
medievalButton.down = function () {
	LK.getSound('Click').play();
	if (towerSet !== 'medieval') {
		towerSet = 'medieval';
		updateSourceTowers();
		medievalBG.tint = 0x8B4513;
		medievalBG.alpha = 0.8; // Reduce transparency
		futuristicBG.tint = 0x000080; // Dark blue color
		futuristicBG.alpha = 0.8; // Reduce transparency
		trenchBG.tint = 0x8B4513;
		trenchBG.alpha = 0.8; // Reduce transparency
	}
};
// Hide medieval button in menu initially
medievalButton.visible = false;
towerSetButtonContainer.addChild(medievalButton);
// Futuristic Button
var futuristicButton = new Container();
var futuristicBG = futuristicButton.attachAsset('Buton', {
	anchorX: 0.5,
	anchorY: 0.5
});
futuristicBG.width = 350;
futuristicBG.height = 100;
futuristicBG.tint = 0x000080; // Dark blue color
futuristicBG.alpha = 0.8; // Reduce transparency
var futuristicText = new Text2("Futuristic", {
	size: 55,
	fill: 0xFFFFFF,
	weight: 800
});
futuristicText.anchor.set(0.5, 0.5);
futuristicText.alpha = 0.9; // Reduce transparency
futuristicButton.addChild(futuristicText);
futuristicButton.x = 0;
futuristicButton.y = 0;
// Hide futuristic button in menu initially
futuristicButton.visible = false;
// Trench Button
var trenchButton = new Container();
var trenchBG = trenchButton.attachAsset('Buton', {
	anchorX: 0.5,
	anchorY: 0.5
});
trenchButton.x = buttonSpacing;
trenchBG.width = 350;
trenchBG.height = 100;
trenchBG.tint = 0x8B4513; // Same as medieval
trenchBG.alpha = 0.8; // Reduce transparency
var trenchText = new Text2("Builds", {
	size: 55,
	fill: 0xFFFFFF,
	weight: 800
});
trenchText.anchor.set(0.5, 0.5);
trenchText.alpha = 0.9; // Reduce transparency
trenchButton.addChild(trenchText);
trenchButton.y = 0;
futuristicButton.down = function () {
	LK.getSound('Click').play();
	// Always block futuristic towers in story mode
	if (gameSettings.storyMode) {
		var notification = game.addChild(new Notification("Futuristic towers are permanently locked in Story Mode!"));
		notification.x = 2048 / 2;
		notification.y = grid.height - 50;
		return;
	}
	// Block futuristic towers until wave 4 OR Research (Build3) is completed (except in Ultra mode)
	if (gameSettings.difficulty === 'ultra' && !futuristicUnlocked) {
		// In ultra mode, only allow if Research (Build3) is built and not destroyed
		var researchBuilt = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchBuilt = true;
				break;
			}
		}
		if (!researchBuilt) {
			var notification = game.addChild(new Notification("Futuristic towers are locked until you build Research!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
			return;
		}
	} else if (gameSettings.difficulty !== 'ultra' && currentWave < 4 && !futuristicUnlocked) {
		var notification = game.addChild(new Notification("Futuristic towers unlock at wave 4 or by building Build3!"));
		notification.x = 2048 / 2;
		notification.y = grid.height - 50;
		return;
	}
	// --- NEW: Prevent Futuristic if Research was destroyed in Ultra mode ---
	if (gameSettings.difficulty === 'ultra' && !futuristicUnlocked) {
		var researchExists = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchExists = true;
				break;
			}
		}
		if (!researchExists) {
			var notification = game.addChild(new Notification("Futuristic towers are locked until you build Research!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
			return;
		}
	}
	if (towerSet !== 'futuristic') {
		towerSet = 'futuristic';
		futuristicUnlocked = true; // Mark futuristic as unlocked
		updateSourceTowers();
		medievalBG.tint = 0x000080; // Dark blue color
		medievalBG.alpha = 0.8; // Reduce transparency
		futuristicBG.tint = 0x1976D2;
		futuristicBG.alpha = 0.8; // Reduce transparency
		trenchBG.tint = 0x8B4513;
		trenchBG.alpha = 0.8; // Reduce transparency
	}
};
futuristicButton.update = function () {
	// Always show locked state in story mode
	if (gameSettings.storyMode) {
		futuristicBG.tint = 0x000080; // Dark blue when locked
		futuristicBG.alpha = 0.3; // More transparent when locked
		futuristicText.setText("Locked");
		return;
	}
	// Update button appearance based on wave progress OR Research (Build3) in Ultra mode
	if (gameSettings.difficulty === 'ultra' && !futuristicUnlocked) {
		// In ultra mode, only allow if Research (Build3) is built and not destroyed
		var researchBuilt = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchBuilt = true;
				break;
			}
		}
		if (!researchBuilt) {
			futuristicBG.tint = 0x000080; // Dark blue when locked
			futuristicBG.alpha = 0.3; // More transparent when locked
			futuristicText.setText("Locked");
			return;
		}
	}
	if (gameSettings.difficulty !== 'ultra' && currentWave < 4 && !futuristicUnlocked) {
		futuristicBG.tint = 0x000080; // Dark blue when locked
		futuristicBG.alpha = 0.3; // More transparent when locked
		futuristicText.setText("Locked");
	} else {
		if (towerSet === 'futuristic') {
			futuristicBG.tint = 0x1976D2;
		} else {
			futuristicBG.tint = 0x000080; // Dark blue when not selected
		}
		futuristicBG.alpha = 0.8; // Reduce transparency
		futuristicText.setText("Futuristic");
	}
	// --- NEW: Lock Futuristic if Research was destroyed in Ultra mode ---
	if (gameSettings.difficulty === 'ultra' && !futuristicUnlocked) {
		// If Research was destroyed, lock the button
		var researchExists = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchExists = true;
				break;
			}
		}
		if (!researchExists) {
			futuristicBG.tint = 0x000080;
			futuristicBG.alpha = 0.3;
			futuristicText.setText("Locked");
		}
	}
};
towerSetButtonContainer.addChild(futuristicButton);
trenchButton.down = function () {
	LK.getSound('Click').play();
	var targetSet = gameSettings.difficulty === 'ultra' ? 'builds' : 'trench';
	if (towerSet !== targetSet) {
		towerSet = targetSet;
		updateSourceTowers();
		medievalBG.tint = 0x8B4513;
		medievalBG.alpha = 0.8; // Reduce transparency
		futuristicBG.tint = 0x000080; // Dark blue color
		futuristicBG.alpha = 0.8; // Reduce transparency
		trenchBG.tint = 0x8B4513;
		trenchBG.alpha = 0.8; // Reduce transparency
	}
};
// Hide trench button in menu initially
trenchButton.visible = false;
towerSetButtonContainer.addChild(trenchButton);
// Helper to clear and re-create source towers
// Leaderboard input functionality removed
// Save to leaderboard functionality removed
// Show leaderboard functionality removed
function updateSourceTowers() {
	// Remove old source towers
	for (var i = 0; i < sourceTowers.length; i++) {
		if (sourceTowers[i].parent) {
			sourceTowers[i].parent.removeChild(sourceTowers[i]);
		}
		sourceTowers[i].destroy && sourceTowers[i].destroy();
	}
	sourceTowers = [];
	// Pick correct tower types
	var types = towerSet === 'medieval' ? medievalTowerTypes : towerSet === 'futuristic' ? futuristicTowerTypes : towerSet === 'trench' ? trenchTowerTypes : towerSet === 'builds' ? buildsTowerTypes : medievalTowerTypes;
	var startX = 2048 / 2 - types.length * towerSpacing / 2 + towerSpacing / 2;
	for (var i = 0; i < types.length; i++) {
		var tower = new SourceTower(types[i]);
		tower.x = startX + i * towerSpacing;
		tower.y = towerY;
		towerLayer.addChild(tower);
		sourceTowers.push(tower);
	}
}
updateSourceTowers();
sourceTower = null;
enemiesToSpawn = 10;
// Always keep tower set button container above towers visually
if (towerSetButtonContainer && towerSetButtonContainer.parent) {
	towerSetButtonContainer.parent.removeChild(towerSetButtonContainer);
	game.addChild(towerSetButtonContainer);
}
game.update = function () {
	// --- NEW: Lock futuristic towers immediately if no Research exists in ultra mode ---
	if (gameSettings.difficulty === 'ultra') {
		var researchExists = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchExists = true;
				break;
			}
		}
		if (!researchExists && futuristicUnlocked) {
			futuristicUnlocked = false;
			// Switch back to medieval towers if currently on futuristic
			if (towerSet === 'futuristic') {
				towerSet = 'medieval';
				updateSourceTowers();
				if (typeof medievalBG !== "undefined") {
					medievalBG.tint = 0x8B4513;
					medievalBG.alpha = 0.5;
				}
				if (typeof futuristicBG !== "undefined") {
					futuristicBG.tint = 0x222222;
					futuristicBG.alpha = 0.5;
				}
			}
		}
	}
	if (waveInProgress) {
		if (!waveSpawned) {
			waveSpawned = true;
			grid.pathFind();
			grid.renderDebug();
			// --- ULTRA MODE SPECIAL WAVES ---
			if (gameSettings.difficulty === 'ultra' && currentWave > 7) {
				// After wave 7, spawn Modern + 10 Angry + 2 Immune
				var enemyTypes = [];
				// Add 10 Angry enemies
				for (var i = 0; i < 10; i++) {
					enemyTypes.push('angry');
				}
				// Add 2 Immune enemies
				for (var i = 0; i < 2; i++) {
					enemyTypes.push('immune');
				}
				// --- Modern enemy logic for Ultra mode ---
				var modernCount = 0;
				if (currentWave % 10 === 0) {
					modernCount = 3;
				} else {
					modernCount = 1;
				}
				// Add modern enemies to the enemyTypes array
				for (var i = 0; i < modernCount; i++) {
					enemyTypes.push('modern');
				}
				// Shuffle enemyTypes for randomness
				for (var i = enemyTypes.length - 1; i > 0; i--) {
					var j = Math.floor(Math.random() * (i + 1));
					var temp = enemyTypes[i];
					enemyTypes[i] = enemyTypes[j];
					enemyTypes[j] = temp;
				}
				// Spawn enemies
				for (var i = 0; i < enemyTypes.length; i++) {
					var waveType = enemyTypes[i];
					var enemy = new Enemy(waveType);
					enemyLayerBottom.addChild(enemy);
					var healthMultiplier = Math.pow(1.12, currentWave);
					enemy.maxHealth = Math.round(enemy.maxHealth * healthMultiplier);
					enemy.health = enemy.maxHealth;
					var gridWidth = 24;
					var midPoint = Math.floor(gridWidth / 2);
					var availableColumns = [];
					for (var col = midPoint - 3; col < midPoint + 3; col++) {
						var columnOccupied = false;
						for (var e = 0; e < enemies.length; e++) {
							if (enemies[e].cellX === col && enemies[e].currentCellY < 4) {
								columnOccupied = true;
								break;
							}
						}
						if (!columnOccupied) {
							availableColumns.push(col);
						}
					}
					var spawnX;
					if (availableColumns.length > 0) {
						spawnX = availableColumns[Math.floor(Math.random() * availableColumns.length)];
					} else {
						spawnX = midPoint - 3 + Math.floor(Math.random() * 6);
					}
					var spawnY = -1 - Math.random() * 5;
					enemy.cellX = spawnX;
					enemy.cellY = 5;
					enemy.currentCellX = spawnX;
					enemy.currentCellY = spawnY;
					enemy.waveNumber = currentWave;
					enemies.push(enemy);
				}
			} else if ((gameSettings.difficulty === 'hardcore' || gameSettings.difficulty === 'ultra') && currentWave > 7) {
				// --- Modern enemy logic for Hardcore mode (and Ultra fallback for <=10) ---
				// Insert after normal spawn logic, so after all other enemies are spawned
				// This block will be reached for hardcore and for ultra waves <= 10
				// (for ultra > 10, handled above)
				// Determine how many modern enemies to spawn
				var modernCount = 0;
				if (currentWave % 10 === 0) {
					modernCount = 3;
				} else {
					modernCount = 1;
				}
				for (var m = 0; m < modernCount; m++) {
					var modernEnemy = new Enemy('modern');
					enemyLayerBottom.addChild(modernEnemy);
					var healthMultiplier = Math.pow(1.12, currentWave);
					modernEnemy.maxHealth = Math.round(modernEnemy.maxHealth * healthMultiplier);
					modernEnemy.health = modernEnemy.maxHealth;
					var gridWidth = 24;
					var midPoint = Math.floor(gridWidth / 2);
					var availableColumns = [];
					for (var col = midPoint - 3; col < midPoint + 3; col++) {
						var columnOccupied = false;
						for (var e = 0; e < enemies.length; e++) {
							if (enemies[e].cellX === col && enemies[e].currentCellY < 4) {
								columnOccupied = true;
								break;
							}
						}
						if (!columnOccupied) {
							availableColumns.push(col);
						}
					}
					var spawnX;
					if (availableColumns.length > 0) {
						spawnX = availableColumns[Math.floor(Math.random() * availableColumns.length)];
					} else {
						spawnX = midPoint - 3 + Math.floor(Math.random() * 6);
					}
					var spawnY = -1 - Math.random() * 5;
					modernEnemy.cellX = spawnX;
					modernEnemy.cellY = 5;
					modernEnemy.currentCellX = spawnX;
					modernEnemy.currentCellY = spawnY;
					modernEnemy.waveNumber = currentWave;
					enemies.push(modernEnemy);
				}
			} else {
				// --- ORIGINAL SPAWN LOGIC FOR NON-ULTRA OR <=10 ---
				// Every wave spawns 10 enemies on wave 1, then 25% more each wave
				var enemyCount = Math.floor(10 * Math.pow(1.25, currentWave - 1));
				// England empire: 3 fewer normal enemies per wave
				if (gameSettings.selectedEmpire === 'England') {
					enemyCount = Math.max(1, enemyCount - 3); // Minimum 1 enemy
				}
				// Byzantine empire: 3 more enemies per wave
				if (gameSettings.selectedEmpire === 'Byzantine') {
					enemyCount = enemyCount + 3;
				}
				// Determine flying enemy count based on wave number
				var flyingEnemyCount = 0;
				if (currentWave === 1) {
					flyingEnemyCount = 0;
				} else if (currentWave === 2) {
					flyingEnemyCount = 1;
				} else if (currentWave === 3 || currentWave === 4) {
					flyingEnemyCount = 3;
				} else if (currentWave === 5) {
					flyingEnemyCount = 5;
					enemyCount = 9; // Total enemies for wave 5
				} else if (currentWave === 6) {
					flyingEnemyCount = 0; // No flying enemies in wave 6
					enemyCount = 18; // 5 normal + 3 angry + 10 immune = 18 total enemies
				} else if (currentWave === 7) {
					flyingEnemyCount = 0; // No flying enemies in wave 7
					enemyCount = 15; // 10 angry + 5 immune = 15 total enemies
				} else if (currentWave === 8) {
					flyingEnemyCount = 0; // No flying enemies in wave 8
					enemyCount = 25; // 25 normal enemies
				} else if (currentWave === 9) {
					flyingEnemyCount = 0; // No flying enemies in wave 9
					enemyCount = 25; // 25 normal enemies
				}
				// Spawn the appropriate number of enemies
				for (var i = 0; i < enemyCount; i++) {
					// Determine enemy type based on specific wave requirements
					var waveType = 'normal'; // Default to normal
					var immuneCount = 0;
					var angryCount = 0;
					// Set specific immune enemy counts per wave
					if (currentWave === 2 || currentWave === 3 || currentWave === 4 || currentWave === 5) {
						immuneCount = 3;
					} else if (currentWave === 6) {
						immuneCount = 10; // Wave 6: 10 immune enemies
					} else if (currentWave === 7) {
						immuneCount = 5; // Wave 7: 5 immune enemies
					} else if (currentWave === 8 || currentWave === 9) {
						immuneCount = 0; // Wave 8 and 9: 0 immune enemies
					}
					// Hard mode: more immune and angry enemies
					if (gameSettings.difficulty === 'hard') {
						// Wave 1: 2 immune enemies
						if (currentWave === 1) {
							immuneCount = 2;
						}
						// Waves 2,3,4: 3 angry enemies each
						if (currentWave === 2 || currentWave === 3 || currentWave === 4) {
							angryCount = 3;
							immuneCount = 3;
						}
						// Wave 5: keep existing counts
						if (currentWave === 5) {
							angryCount = 3;
							immuneCount = 5;
						}
					} else {
						// Set angry enemy spawning: 0 in waves 1-3, 2 in waves 4-5, 3 in wave 6
						if (currentWave === 4) {
							angryCount = 2;
						} else if (currentWave === 5) {
							angryCount = 2;
						} else if (currentWave === 6) {
							angryCount = 3; // Wave 6: 3 angry enemies
						} else if (currentWave === 7) {
							angryCount = 10; // Wave 7: 10 angry enemies
						} else if (currentWave === 8 || currentWave === 9) {
							angryCount = 0; // Wave 8 and 9: 0 angry enemies
						}
					}
					// Set bad enemy spawning: only in wave 5, but not in Ultra mode
					var badCount = 0;
					if (currentWave === 5 && gameSettings.difficulty !== 'ultra') {
						badCount = 1; // 1 bad enemy - same for all empires including England
						immuneCount = 5; // 5 immune enemies
						angryCount = 3; // 3 angry enemies
					}
					// Set super enemy spawning: only in wave 10 for hardcore mode, but not in Ultra mode
					var superCount = 0;
					if (currentWave === 10 && gameSettings.difficulty === 'hardcore') {
						superCount = 0; // No super enemy in wave 10
						badCount = 3; // 3 bad enemies in wave 10
						angryCount = 0; // No angry enemies in wave 10
						immuneCount = 0; // No immune enemies in wave 10
						enemyCount = 3; // 3 bad enemies total
					}
					// Make the first 'angryCount' enemies angry for this wave
					if (i < angryCount) {
						waveType = 'angry';
					}
					// Make the next 'badCount' enemies bad for this wave (after angry enemies)
					else if (i >= angryCount && i < angryCount + badCount) {
						waveType = 'bad';
					}
					// Make the next 'superCount' enemies super for this wave (after bad enemies)
					else if (i >= angryCount + badCount && i < angryCount + badCount + superCount) {
						waveType = 'super';
					}
					// Make the last 'immuneCount' enemies immune for this wave (but not if already angry, bad, or super)
					else if (i >= enemyCount - immuneCount) {
						waveType = 'immune';
					}
					var enemy = new Enemy(waveType);
					enemyLayerBottom.addChild(enemy);
					var healthMultiplier = Math.pow(1.12, currentWave);
					enemy.maxHealth = Math.round(enemy.maxHealth * healthMultiplier);
					enemy.health = enemy.maxHealth;
					var gridWidth = 24;
					var midPoint = Math.floor(gridWidth / 2);
					var availableColumns = [];
					for (var col = midPoint - 3; col < midPoint + 3; col++) {
						var columnOccupied = false;
						for (var e = 0; e < enemies.length; e++) {
							if (enemies[e].cellX === col && enemies[e].currentCellY < 4) {
								columnOccupied = true;
								break;
							}
						}
						if (!columnOccupied) {
							availableColumns.push(col);
						}
					}
					var spawnX;
					if (availableColumns.length > 0) {
						spawnX = availableColumns[Math.floor(Math.random() * availableColumns.length)];
					} else {
						spawnX = midPoint - 3 + Math.floor(Math.random() * 6); // x from 9 to 14
					}
					var spawnY = -1 - Math.random() * 5; // Random distance above the grid for spreading
					enemy.cellX = spawnX;
					enemy.cellY = 5; // Position after entry
					enemy.currentCellX = spawnX;
					enemy.currentCellY = spawnY;
					enemy.waveNumber = currentWave;
					enemies.push(enemy);
				}
			} // end else (original spawn logic)
		}
		var currentWaveEnemiesRemaining = false;
		for (var i = 0; i < enemies.length; i++) {
			if (enemies[i].waveNumber === currentWave) {
				currentWaveEnemiesRemaining = true;
				break;
			}
		}
		if (waveSpawned && !currentWaveEnemiesRemaining) {
			waveInProgress = false;
			waveSpawned = false;
			var notification = game.addChild(new Notification("Wave " + currentWave + " completed!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 150;
			// Add 10 points for completing each wave in ultra mode
			if (gameSettings.difficulty === 'ultra') {
				addScore(10);
				// Add all enemy kills for this wave to score (already counted per kill)
				// (No extra code needed here, as kills are counted above)
			}
			// Automatically advance to next wave if all enemies are gone
			if (currentWave < totalWaves) {
				waveTimer = nextWaveTime; // Trigger next wave immediately
			}
		}
	}
	for (var a = enemies.length - 1; a >= 0; a--) {
		var enemy = enemies[a];
		if (enemy.health <= 0) {
			for (var i = 0; i < enemy.bulletsTargetingThis.length; i++) {
				var bullet = enemy.bulletsTargetingThis[i];
				bullet.targetEnemy = null;
			}
			// Give gold for every enemy killed - Hard mode gives 5 gold, others give 10
			var goldEarned = gameSettings.difficulty === 'hard' ? 5 : 10;
			var goldIndicator = new GoldIndicator(goldEarned, enemy.x, enemy.y);
			game.addChild(goldIndicator);
			setGold(gold + goldEarned);
			// Add 1 point for each enemy killed in ultra mode and count kills
			if (gameSettings.difficulty === 'ultra') {
				addScore(1);
				if (typeof ultraEnemyKills !== "undefined") {
					ultraEnemyKills++;
				}
			}
			// Add a notification for boss defeat
			if (enemy.isBoss) {
				var notification = game.addChild(new Notification("Boss defeated! +" + goldEarned + " gold!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 150;
			}
			updateUI();
			// Clean up shadow if it's a flying enemy
			if (enemy.isFlying && enemy.shadow) {
				enemyLayerMiddle.removeChild(enemy.shadow);
				enemy.shadow = null;
			}
			// Remove enemy from the appropriate layer
			if (enemy.isFlying) {
				enemyLayerTop.removeChild(enemy);
			} else {
				enemyLayerBottom.removeChild(enemy);
			}
			enemies.splice(a, 1);
			continue;
		}
		if (grid.updateEnemy(enemy)) {
			// Clean up shadow if it's a flying enemy
			if (enemy.isFlying && enemy.shadow) {
				enemyLayerMiddle.removeChild(enemy.shadow);
				enemy.shadow = null;
			}
			// Remove enemy from the appropriate layer
			if (enemy.isFlying) {
				enemyLayerTop.removeChild(enemy);
			} else {
				enemyLayerBottom.removeChild(enemy);
			}
			enemies.splice(a, 1);
			lives = Math.max(0, lives - (enemy.type === 'bad' ? 10 : 1));
			updateUI();
			if (lives <= 0) {
				LK.showGameOver();
			}
		}
	}
	for (var i = bullets.length - 1; i >= 0; i--) {
		if (!bullets[i].parent) {
			if (bullets[i].targetEnemy) {
				var targetEnemy = bullets[i].targetEnemy;
				var bulletIndex = targetEnemy.bulletsTargetingThis.indexOf(bullets[i]);
				if (bulletIndex !== -1) {
					targetEnemy.bulletsTargetingThis.splice(bulletIndex, 1);
				}
			}
			bullets.splice(i, 1);
		}
	}
	if (towerPreview.visible) {
		towerPreview.checkPlacement();
	}
	if (currentWave >= totalWaves && enemies.length === 0 && !waveInProgress) {
		LK.showYouWin();
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	tutorialCompleted: false
});
/**** 
* Classes
****/ 
var Bullet = Container.expand(function (startX, startY, targetEnemy, damage, speed) {
	var self = Container.call(this);
	self.targetEnemy = targetEnemy;
	self.damage = damage || 10;
	self.speed = speed || 5;
	self.x = startX;
	self.y = startY;
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		// Skip bullet update when game is paused (gameSpeed = 0)
		if (gameSpeed === 0) {
			return;
		}
		if (!self.targetEnemy || !self.targetEnemy.parent) {
			self.destroy();
			return;
		}
		var dx = self.targetEnemy.x - self.x;
		var dy = self.targetEnemy.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < self.speed) {
			// Apply damage to target enemy
			var actualDamage = self.damage;
			// Artillery towers deal 40% of enemy's current health as damage
			if (self.type === 'splash') {
				actualDamage = Math.ceil(self.targetEnemy.health * 0.4);
				// AntiAir bullets deal half damage to flying enemies
				if (self.targetEnemy.isFlying) {
					actualDamage = actualDamage * 0.5;
				}
			}
			// Immune enemies take 10% more damage from all bullets
			if (self.targetEnemy.isImmune) {
				actualDamage = actualDamage * 1.1;
			}
			// Immune enemies now take damage from all bullet types
			self.targetEnemy.health -= actualDamage;
			if (self.targetEnemy.health <= 0) {
				self.targetEnemy.health = 0;
			} else {
				self.targetEnemy.healthBar.width = self.targetEnemy.health / self.targetEnemy.maxHealth * 70;
			}
			// Apply special effects based on bullet type
			if (self.type === 'splash') {
				// Create visual splash effect
				var splashEffect = new EffectIndicator(self.targetEnemy.x, self.targetEnemy.y, 'splash');
				game.addChild(splashEffect);
				// Splash damage to nearby enemies
				var splashRadius = CELL_SIZE * 1.5;
				for (var i = 0; i < enemies.length; i++) {
					var otherEnemy = enemies[i];
					if (otherEnemy !== self.targetEnemy) {
						var splashDx = otherEnemy.x - self.targetEnemy.x;
						var splashDy = otherEnemy.y - self.targetEnemy.y;
						var splashDistance = Math.sqrt(splashDx * splashDx + splashDy * splashDy);
						if (splashDistance <= splashRadius) {
							// Apply splash damage (50% of original damage or 20% of enemy health for Artillery)
							var splashDamage;
							if (self.type === 'splash') {
								splashDamage = Math.ceil(otherEnemy.health * 0.2); // 20% of current health for splash
							} else {
								splashDamage = self.damage * 0.5;
							}
							// Immune enemies take 10% more splash damage
							if (otherEnemy.isImmune) {
								splashDamage = splashDamage * 1.1;
							}
							// Immune enemies now take splash damage from all bullet types
							otherEnemy.health -= splashDamage;
							if (otherEnemy.health <= 0) {
								otherEnemy.health = 0;
							} else {
								otherEnemy.healthBar.width = otherEnemy.health / otherEnemy.maxHealth * 70;
							}
						}
					}
				}
			} else if (self.type === 'poison') {
				// Prevent poison effect on immune enemies
				if (!self.targetEnemy.isImmune) {
					// Create visual poison effect
					var poisonEffect = new EffectIndicator(self.targetEnemy.x, self.targetEnemy.y, 'poison');
					game.addChild(poisonEffect);
					// Apply poison effect
					self.targetEnemy.poisoned = true;
					self.targetEnemy.poisonDamage = self.damage * 0.2; // 20% of original damage per tick
					self.targetEnemy.poisonDuration = 300; // 5 seconds at 60 FPS
				}
			} else if (self.type === 'sniper') {
				// Create visual critical hit effect for sniper
				var sniperEffect = new EffectIndicator(self.targetEnemy.x, self.targetEnemy.y, 'sniper');
				game.addChild(sniperEffect);
			}
			self.destroy();
		} else {
			var angle = Math.atan2(dy, dx);
			self.x += Math.cos(angle) * self.speed;
			self.y += Math.sin(angle) * self.speed;
		}
	};
	return self;
});
var DebugCell = Container.expand(function () {
	var self = Container.call(this);
	var cellGraphics = self.attachAsset('cell', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cellGraphics.tint = Math.random() * 0xffffff;
	var debugArrows = [];
	var numberLabel = new Text2('0', {
		size: 30,
		fill: 0xFFFFFF,
		weight: 800
	});
	numberLabel.anchor.set(.5, .5);
	numberLabel.visible = false; // Hide numbers in battlefield
	self.addChild(numberLabel);
	self.update = function () {};
	self.down = function () {
		return;
		if (self.cell.type == 0 || self.cell.type == 1) {
			self.cell.type = self.cell.type == 1 ? 0 : 1;
			if (grid.pathFind()) {
				self.cell.type = self.cell.type == 1 ? 0 : 1;
				grid.pathFind();
				var notification = game.addChild(new Notification("Path is blocked!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 50;
			}
			grid.renderDebug();
		}
	};
	self.removeArrows = function () {
		while (debugArrows.length) {
			self.removeChild(debugArrows.pop());
		}
	};
	self.render = function (data) {
		switch (data.type) {
			case 0:
			case 2:
				{
					if (data.pathId != pathId) {
						self.removeArrows();
						numberLabel.setText("-");
						cellGraphics.tint = 0x880000;
						return;
					}
					numberLabel.visible = false; // Hide numbers in battlefield
					var tint = Math.floor(data.score / maxScore * 0x88);
					var towerInRangeHighlight = false;
					if (selectedTower && data.towersInRange && data.towersInRange.indexOf(selectedTower) !== -1) {
						towerInRangeHighlight = true;
						cellGraphics.tint = 0x0088ff;
					} else {
						cellGraphics.tint = 0x88 - tint << 8 | tint;
					}
					// Remove arrow rendering - no longer display arrows
					break;
				}
			case 1:
				{
					self.removeArrows();
					cellGraphics.tint = 0xaaaaaa;
					numberLabel.visible = false;
					break;
				}
			case 3:
				{
					self.removeArrows();
					cellGraphics.tint = 0x008800;
					numberLabel.visible = false;
					break;
				}
			case 4:
				{
					self.removeArrows();
					cellGraphics.tint = 0x000000; // Black color for castle walls
					numberLabel.visible = false;
					break;
				}
		}
		// numberLabel.setText(Math.floor(data.score / 1000) / 10); // Removed number display
	};
});
// This update method was incorrectly placed here and should be removed
var EffectIndicator = Container.expand(function (x, y, type) {
	var self = Container.call(this);
	self.x = x;
	self.y = y;
	var effectGraphics = self.attachAsset('rangeCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	effectGraphics.blendMode = 1;
	switch (type) {
		case 'splash':
			effectGraphics.tint = 0x33CC00;
			effectGraphics.width = effectGraphics.height = CELL_SIZE * 1.5;
			break;
		case 'slow':
			effectGraphics.tint = 0x9900FF;
			effectGraphics.width = effectGraphics.height = CELL_SIZE;
			break;
		case 'poison':
			effectGraphics.tint = 0x00FFAA;
			effectGraphics.width = effectGraphics.height = CELL_SIZE;
			break;
		case 'sniper':
			effectGraphics.tint = 0xFF5500;
			effectGraphics.width = effectGraphics.height = CELL_SIZE;
			break;
	}
	effectGraphics.alpha = 0.7;
	self.alpha = 0;
	// Animate the effect
	tween(self, {
		alpha: 0.8,
		scaleX: 1.5,
		scaleY: 1.5
	}, {
		duration: 200,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(self, {
				alpha: 0,
				scaleX: 2,
				scaleY: 2
			}, {
				duration: 300,
				easing: tween.easeIn,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
		}
	});
	return self;
});
// Base enemy class for common functionality
var Enemy = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'normal';
	self.speed = .01;
	self.cellX = 0;
	self.cellY = 0;
	self.currentCellX = 0;
	self.currentCellY = 0;
	self.currentTarget = undefined;
	self.maxHealth = 100;
	self.health = self.maxHealth;
	self.bulletsTargetingThis = [];
	self.waveNumber = currentWave;
	self.isFlying = false;
	self.isImmune = false;
	self.isBoss = false;
	// Check if this is a boss wave
	// Check if this is a boss wave
	// Apply different stats based on enemy type
	switch (self.type) {
		case 'fast':
			self.speed *= 2; // Twice as fast
			self.maxHealth = 100;
			break;
		case 'immune':
			self.isImmune = true;
			self.speed *= 1.275; // 27.5% faster than normal (reduced by 15% from previous 50%)
			self.maxHealth = 40;
			break;
		case 'flying':
			self.isFlying = true;
			self.maxHealth = 80;
			break;
		case 'swarm':
			self.maxHealth = 50; // Weaker enemies
			break;
		case 'angry':
			self.speed *= 1; // Same speed as normal enemies
			self.maxHealth = 120; // More health than normal
			break;
		case 'modern':
			self.speed *= 1; // Same speed as angry enemies
			self.maxHealth = 600; // 5x health of angry enemies (120 * 5)
			break;
		case 'bad':
			self.speed *= 0.5; // 50% slower than normal
			self.maxHealth = 1000; // 10 times the health of a normal enemy
			break;
		case 'super':
			self.speed *= 0.4; // 60% slower than normal
			self.maxHealth = 2000; // 20 times the health of a normal enemy (2x bad enemy)
			break;
		case 'normal':
		default:
			// Normal enemy uses default values
			break;
	}
	// Boss spawning disabled for waves 10, 20, 30
	// if (currentWave % 10 === 0 && currentWave > 0 && type !== 'swarm') {
	//     self.isBoss = true;
	//     // Boss enemies have 20x health and are larger
	//     self.maxHealth *= 20;
	//     // Slower speed for bosses
	//     self.speed = self.speed * 0.7;
	// }
	self.health = self.maxHealth;
	// Get appropriate asset for this enemy type
	var assetId = 'enemy';
	if (self.type === 'angry') {
		assetId = 'Angry_Enemy';
	} else if (self.type === 'modern') {
		assetId = 'modern_enemy';
	} else if (self.type === 'bad') {
		assetId = 'enemy_bad';
	} else if (self.type === 'super') {
		assetId = 'enemy_super';
	} else if (self.type !== 'normal') {
		assetId = 'enemy_' + self.type;
	}
	var enemyGraphics = self.attachAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Scale up boss enemies
	if (self.isBoss) {
		enemyGraphics.scaleX = 1.8;
		enemyGraphics.scaleY = 1.8;
	}
	// Fall back to regular enemy asset if specific type asset not found
	// Apply tint to differentiate enemy types
	/*switch (self.type) {
		case 'fast':
			enemyGraphics.tint = 0x00AAFF; // Blue for fast enemies
			break;
		case 'immune':
			enemyGraphics.tint = 0xAA0000; // Red for immune enemies
			break;
		case 'flying':
			enemyGraphics.tint = 0xFFFF00; // Yellow for flying enemies
			break;
		case 'swarm':
			enemyGraphics.tint = 0xFF00FF; // Pink for swarm enemies
			break;
	}*/
	// Create shadow for flying enemies
	if (self.isFlying) {
		// Create a shadow container that will be added to the shadow layer
		self.shadow = new Container();
		// Clone the enemy graphics for the shadow
		var shadowGraphics = self.shadow.attachAsset(assetId || 'enemy', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		// Apply shadow effect
		shadowGraphics.tint = 0x000000; // Black shadow
		shadowGraphics.alpha = 0.4; // Semi-transparent
		// If this is a boss, scale up the shadow to match
		if (self.isBoss) {
			shadowGraphics.scaleX = 1.8;
			shadowGraphics.scaleY = 1.8;
		}
		// Position shadow slightly offset
		self.shadow.x = 20; // Offset right
		self.shadow.y = 20; // Offset down
		// Ensure shadow has the same rotation as the enemy
		shadowGraphics.rotation = enemyGraphics.rotation;
	}
	var healthBarOutline = self.attachAsset('healthBarOutline', {
		anchorX: 0,
		anchorY: 0.5
	});
	var healthBarBG = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	var healthBar = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	healthBarBG.y = healthBarOutline.y = healthBar.y = -enemyGraphics.height / 2 - 10;
	healthBarOutline.x = -healthBarOutline.width / 2;
	healthBarBG.x = healthBar.x = -healthBar.width / 2 - .5;
	healthBar.tint = 0x00ff00;
	healthBarBG.tint = 0xff0000;
	self.healthBar = healthBar;
	self.update = function () {
		// Skip enemy update when game is paused (gameSpeed = 0)
		if (gameSpeed === 0) {
			return;
		}
		if (self.health <= 0) {
			self.health = 0;
			self.healthBar.width = 0;
		}
		// Anti-stuck mechanism: track if enemy hasn't moved significantly
		if (self.lastPosition === undefined) {
			self.lastPosition = {
				x: self.currentCellX,
				y: self.currentCellY,
				time: LK.ticks
			};
			self.stuckCounter = 0;
		}
		// Check if enemy has been stuck in same position for too long
		var timeSinceLastCheck = LK.ticks - self.lastPosition.time;
		if (timeSinceLastCheck > 180) {
			// Check every 3 seconds
			var distanceMoved = Math.sqrt((self.currentCellX - self.lastPosition.x) * (self.currentCellX - self.lastPosition.x) + (self.currentCellY - self.lastPosition.y) * (self.currentCellY - self.lastPosition.y));
			if (distanceMoved < 0.5) {
				// If moved less than half a cell
				self.stuckCounter++;
				if (self.stuckCounter >= 3) {
					// If stuck for 3 checks (9 seconds)
					// Force reset enemy position and target
					self.currentTarget = null;
					// Try to find a valid spawn position
					for (var sx = 9; sx <= 14; sx++) {
						var testCell = grid.getCell(sx, 5);
						if (testCell && testCell.pathId === pathId) {
							self.cellX = sx;
							self.cellY = 5;
							self.currentCellX = sx;
							self.currentCellY = 5;
							self.stuckCounter = 0;
							break;
						}
					}
				}
			} else {
				self.stuckCounter = 0; // Reset stuck counter if moving
			}
			// Update last position
			self.lastPosition = {
				x: self.currentCellX,
				y: self.currentCellY,
				time: LK.ticks
			};
		}
		// Immune enemies attack towers in range
		if (self.isImmune) {
			// Immune enemies cannot be slowed or poisoned, clear any such effects
			self.poisoned = false;
			self.poisonEffect = false;
			// Attack towers every 120 frames (2 seconds)
			if (LK.ticks % Math.max(1, Math.floor(120 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 2 cell range
					if (distance <= CELL_SIZE * 2) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Only attack if not protected by a Healer tower
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								var damage = Math.floor(tower.maxHealth / 10); // 1/10th of tower's max health
								// Hardcore mode: enemies deal 2x damage
								if (gameSettings.difficulty === 'hardcore') {
									damage *= 2;
								}
								// Hardcore mode: spawn 3 immune enemies every wave
								if (gameSettings.difficulty === 'hardcore') {
									immuneCount = 3;
								}
								tower.health -= damage;
								if (tower.health <= 0) {
									tower.health = 0;
								}
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else if (self.type === 'angry') {
			// Angry enemies attack towers in range, but are blocked by Healer towers
			// Attack towers every 120 frames (2 seconds)
			if (LK.ticks % Math.max(1, Math.floor(120 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 2 cell range
					if (distance <= CELL_SIZE * 2) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Healer towers completely block damage from Angry enemies
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								var damage = Math.floor(tower.maxHealth * 0.25); // 25% of tower's max health
								// Hardcore mode: enemies deal 2x damage
								if (gameSettings.difficulty === 'hardcore') {
									damage *= 2;
								}
								tower.health -= damage;
								if (tower.health <= 0) {
									tower.health = 0;
								}
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else if (self.type === 'modern') {
			// Modern enemies attack towers in range with 2x damage compared to Angry enemies
			// Attack towers every 120 frames (2 seconds)
			if (LK.ticks % Math.max(1, Math.floor(120 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 2 cell range
					if (distance <= CELL_SIZE * 2) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Healer towers completely block damage from Modern enemies
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								var damage = Math.floor(tower.maxHealth * 0.50); // 50% of tower's max health (2x angry damage)
								// Hardcore mode: enemies deal 2x damage
								if (gameSettings.difficulty === 'hardcore') {
									damage *= 2;
								}
								tower.health -= damage;
								if (tower.health <= 0) {
									tower.health = 0;
								}
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else if (self.type === 'bad') {
			// Bad enemies attack towers more frequently and deal more damage
			// Attack towers every 90 frames (1.5 seconds)
			if (LK.ticks % Math.max(1, Math.floor(90 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 2.5 cell range (longer range than angry)
					if (distance <= CELL_SIZE * 2.5) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Only attack if not protected by a Healer tower
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								// Bad enemies destroy towers in one hit (or deal massive damage in hardcore)
								if (gameSettings.difficulty === 'hardcore') {
									tower.health = 0; // Still one-shot in hardcore
								} else {
									tower.health = 0; // One-shot in normal/hard
								}
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else if (self.type === 'super') {
			// Super enemies attack towers more frequently and deal devastating damage
			// Attack towers every 60 frames (1 second)
			if (LK.ticks % Math.max(1, Math.floor(60 / gameSpeed)) === 0) {
				// Find towers in range and attack them
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					var dx = tower.x - self.x;
					var dy = tower.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Attack towers within 3 cell range (longer range than bad)
					if (distance <= CELL_SIZE * 3) {
						// Check if any Healer towers are protecting this tower
						var isProtectedByHealer = false;
						for (var h = 0; h < towers.length; h++) {
							var healerTower = towers[h];
							if (healerTower.id === 'poison' && healerTower.isInRange(tower)) {
								isProtectedByHealer = true;
								break;
							}
						}
						// Only attack if not protected by a Healer tower
						if (!isProtectedByHealer) {
							// Easy mode: towers take no damage
							if (gameSettings.difficulty !== 'easy') {
								// Super enemies destroy towers instantly regardless of difficulty
								tower.health = 0;
								// Update tower health bar
								tower.towerHealthBar.width = tower.health / tower.maxHealth * 70;
							}
						}
						break; // Only attack one tower per update
					}
				}
			}
		} else {
			// Handle poison effect
			if (self.poisoned) {
				// Visual indication of poisoned status
				if (!self.poisonEffect) {
					self.poisonEffect = true;
				}
				// Apply poison damage every 30 frames (twice per second), adjusted for game speed
				if (LK.ticks % Math.max(1, Math.floor(30 / gameSpeed)) === 0) {
					self.health -= self.poisonDamage * gameSpeed;
					if (self.health <= 0) {
						self.health = 0;
					}
					self.healthBar.width = self.health / self.maxHealth * 70;
				}
				self.poisonDuration -= gameSpeed;
				if (self.poisonDuration <= 0) {
					self.poisoned = false;
					self.poisonEffect = false;
					// Only reset tint if not slowed
					if (!self.slowed) {
						enemyGraphics.tint = 0xFFFFFF; // Reset tint
					}
				}
			}
		}
		// Set tint based on effect status
		if (self.isImmune) {
			enemyGraphics.tint = 0xFFFFFF;
		} else if (self.poisoned) {
			enemyGraphics.tint = 0x00FFAA;
		} else if (self.type === 'bad') {
			// Bad enemies use their asset's natural color - no tint applied
		} else if (self.type === 'super') {
			enemyGraphics.tint = 0x800080; // Purple tint for super enemies
		} else {
			enemyGraphics.tint = 0xFFFFFF;
		}
		if (self.currentTarget) {
			var ox = self.currentTarget.x - self.currentCellX;
			var oy = self.currentTarget.y - self.currentCellY;
			if (ox !== 0 || oy !== 0) {
				var angle = Math.atan2(oy, ox);
				if (enemyGraphics.targetRotation === undefined) {
					enemyGraphics.targetRotation = angle;
					enemyGraphics.rotation = angle;
				} else {
					if (Math.abs(angle - enemyGraphics.targetRotation) > 0.05) {
						tween.stop(enemyGraphics, {
							rotation: true
						});
						// Calculate the shortest angle to rotate
						var currentRotation = enemyGraphics.rotation;
						var angleDiff = angle - currentRotation;
						// Normalize angle difference to -PI to PI range for shortest path
						while (angleDiff > Math.PI) {
							angleDiff -= Math.PI * 2;
						}
						while (angleDiff < -Math.PI) {
							angleDiff += Math.PI * 2;
						}
						enemyGraphics.targetRotation = angle;
						tween(enemyGraphics, {
							rotation: currentRotation + angleDiff
						}, {
							duration: 250,
							easing: tween.easeOut
						});
					}
				}
			}
		}
		healthBarOutline.y = healthBarBG.y = healthBar.y = -enemyGraphics.height / 2 - 10;
	};
	return self;
});
var GoldIndicator = Container.expand(function (value, x, y) {
	var self = Container.call(this);
	var shadowText = new Text2("+" + value, {
		size: 45,
		fill: 0x000000,
		weight: 800
	});
	shadowText.anchor.set(0.5, 0.5);
	shadowText.x = 2;
	shadowText.y = 2;
	self.addChild(shadowText);
	var goldText = new Text2("+" + value, {
		size: 45,
		fill: 0xFFD700,
		weight: 800
	});
	goldText.anchor.set(0.5, 0.5);
	self.addChild(goldText);
	self.x = x;
	self.y = y;
	self.alpha = 0;
	self.scaleX = 0.5;
	self.scaleY = 0.5;
	tween(self, {
		alpha: 1,
		scaleX: 1.2,
		scaleY: 1.2,
		y: y - 40
	}, {
		duration: 50,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(self, {
				alpha: 0,
				scaleX: 1.5,
				scaleY: 1.5,
				y: y - 80
			}, {
				duration: 600,
				easing: tween.easeIn,
				delay: 800,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
		}
	});
	return self;
});
var Grid = Container.expand(function (gridWidth, gridHeight) {
	var self = Container.call(this);
	self.cells = [];
	self.spawns = [];
	self.goals = [];
	for (var i = 0; i < gridWidth; i++) {
		self.cells[i] = [];
		for (var j = 0; j < gridHeight; j++) {
			self.cells[i][j] = {
				score: 0,
				pathId: 0,
				towersInRange: []
			};
		}
	}
	/*
	Cell Types
	0: Transparent floor
	1: Wall
	2: Spawn
	3: Goal
	4: Castle wall
	*/
	for (var i = 0; i < gridWidth; i++) {
		var _loop = function _loop() {
				cell = self.cells[i][j];
				cellType = i === 0 || i === gridWidth - 1 || j <= 4 || j >= gridHeight - 4 ? 1 : 0; // Create castle structure with random labyrinth
				if (j > 4 && j < gridHeight - 4) {
					// Simple pseudo-random number generator using seed
					var seededRandom = function seededRandom() {
						mazeSeed = (mazeSeed * 9301 + 49297) % 233280;
						return mazeSeed / 233280;
					}; // Main castle outer walls
					// Generate maze seed based on reload counter to ensure different maze each reload
					// Use reload-based seed as primary factor for maze generation
					mazeSeed = gameSessionSeed * 7919 + (currentWave + 1) * 1009 + reloadCounter * 4397;
					if ((i === 2 || i === gridWidth - 3) && j >= 8 && j <= gridHeight - 8) {
						cellType = 4; // Castle wall
					}
					// Castle towers at corners
					if ((i >= 1 && i <= 4 || i >= gridWidth - 5 && i <= gridWidth - 2) && (j >= 7 && j <= 10 || j >= gridHeight - 11 && j <= gridHeight - 8)) {
						cellType = 4;
					}
					// Generate unique geometric maze patterns based on seed
					var mazePattern = (mazeSeed * 17 + (currentWave + 1) * 23) % 100;
					if (j >= 12 && j <= gridHeight - 12) {
						// Create safe corridors first - ensure at least 3 clear horizontal paths
						var safePaths = [16, 20, 24];
						var isSafePath = false;
						for (var sp = 0; sp < safePaths.length; sp++) {
							if (j === safePaths[sp] && i >= 8 && i <= gridWidth - 9) {
								isSafePath = true;
								break;
							}
						}
						if (!isSafePath) {
							// Generate dynamic geometric patterns based on random seed
							if (mazePattern < 20) {
								// Concentric geometric shapes
								var centerX = Math.floor(gridWidth / 2);
								var centerY = Math.floor((gridHeight - 12 + 12) / 2);
								var distance = Math.sqrt((i - centerX) * (i - centerX) + (j - centerY) * (j - centerY));
								var ringSize = 2 + mazeSeed % 3;
								if (Math.floor(distance) % ringSize === 1 && distance > 2 && distance < 8 && i >= 6 && i <= gridWidth - 7) {
									if (seededRandom() > 0.6) {
										cellType = 4;
									}
								}
							} else if (mazePattern < 40) {
								// Geometric wave patterns
								var waveFreq = 0.2 + mazeSeed % 5 * 0.1;
								var waveHeight = 2 + mazeSeed % 3;
								var expectedY = Math.floor(Math.sin(i * waveFreq) * waveHeight) + Math.floor((gridHeight - 12 + 12) / 2);
								if (Math.abs(j - expectedY) < 2 && i >= 6 && i <= gridWidth - 7) {
									if (seededRandom() > 0.5) {
										cellType = 4;
									}
								}
							} else if (mazePattern < 60) {
								// Diamond and rhombus patterns
								var midX = Math.floor(gridWidth / 2);
								var midY = Math.floor((gridHeight - 12 + 12) / 2);
								var manhattanDist = Math.abs(i - midX) + Math.abs(j - midY);
								var diamondSize = 3 + mazeSeed % 4;
								if (manhattanDist >= diamondSize && manhattanDist <= diamondSize + 3 && manhattanDist % 2 === 0) {
									if (seededRandom() > 0.5) {
										cellType = 4;
									}
								}
							} else if (mazePattern < 80) {
								// Hexagonal and triangular patterns
								var hexSize = 4 + mazeSeed % 3;
								var hexX = Math.floor(i / hexSize);
								var hexY = Math.floor(j / hexSize);
								if ((hexX + hexY) % 3 === 0 && (i % hexSize < 2 || j % hexSize < 2) && i >= 6 && i <= gridWidth - 7) {
									if (seededRandom() > 0.4) {
										cellType = 4;
									}
								}
							} else {
								// Spiral and radial patterns
								var centerX = Math.floor(gridWidth / 2);
								var centerY = Math.floor((gridHeight - 12 + 12) / 2);
								var angle = Math.atan2(j - centerY, i - centerX);
								var spiralArms = 4 + mazeSeed % 4;
								var armIndex = Math.floor(angle / (Math.PI * 2 / spiralArms));
								var distance = Math.sqrt((i - centerX) * (i - centerX) + (j - centerY) * (j - centerY));
								if (armIndex % 2 === 0 && distance > 2 && distance < 7 && i >= 6 && i <= gridWidth - 7) {
									if (seededRandom() > 0.45) {
										cellType = 4;
									}
								}
							}
							// Add strategic scattered obstacles with lower density
							if (i >= 7 && i <= gridWidth - 8 && j >= 14 && j <= gridHeight - 14) {
								if (seededRandom() > 0.8) {
									cellType = 4;
								}
							}
						}
					}
					// Central castle keep - always present
					if (i >= 10 && i <= 13 && j >= gridHeight - 16 && j <= gridHeight - 13) {
						if (!(i === 11 || i === 12) || !(j === gridHeight - 15 || j === gridHeight - 14)) {
							cellType = 4;
						}
					}
				}
				// Spawn and goal areas
				if (i > 11 - 3 && i <= 11 + 3) {
					if (j === 0) {
						cellType = 2;
						self.spawns.push(cell);
					} else if (j <= 4) {
						cellType = 0;
					} else if (j === gridHeight - 1) {
						cellType = 3;
						self.goals.push(cell);
					} else if (j >= gridHeight - 4) {
						cellType = 0;
					}
				}
				cell.type = cellType;
				cell.x = i;
				cell.y = j;
				cell.upLeft = self.cells[i - 1] && self.cells[i - 1][j - 1];
				cell.up = self.cells[i - 1] && self.cells[i - 1][j];
				cell.upRight = self.cells[i - 1] && self.cells[i - 1][j + 1];
				cell.left = self.cells[i][j - 1];
				cell.right = self.cells[i][j + 1];
				cell.downLeft = self.cells[i + 1] && self.cells[i + 1][j - 1];
				cell.down = self.cells[i + 1] && self.cells[i + 1][j];
				cell.downRight = self.cells[i + 1] && self.cells[i + 1][j + 1];
				cell.neighbors = [cell.upLeft, cell.up, cell.upRight, cell.right, cell.downRight, cell.down, cell.downLeft, cell.left];
				cell.targets = [];
				if (j > 3 && j <= gridHeight - 4) {
					debugCell = new DebugCell();
					self.addChild(debugCell);
					debugCell.cell = cell;
					debugCell.x = i * CELL_SIZE;
					debugCell.y = j * CELL_SIZE;
					cell.debugCell = debugCell;
				}
			},
			cell,
			cellType,
			mazeSeed,
			horizontalWallRows,
			hr,
			verticalWallCols,
			vc,
			debugCell;
		for (var j = 0; j < gridHeight; j++) {
			_loop();
		}
	}
	self.getCell = function (x, y) {
		return self.cells[x] && self.cells[x][y];
	};
	self.pathFind = function () {
		var before = new Date().getTime();
		var toProcess = self.goals.concat([]);
		maxScore = 0;
		pathId += 1;
		for (var a = 0; a < toProcess.length; a++) {
			toProcess[a].pathId = pathId;
		}
		function processNode(node, targetValue, targetNode) {
			if (node && node.type != 1 && node.type != 4) {
				if (node.pathId < pathId || targetValue < node.score) {
					node.targets = [targetNode];
				} else if (node.pathId == pathId && targetValue == node.score) {
					node.targets.push(targetNode);
				}
				if (node.pathId < pathId || targetValue < node.score) {
					node.score = targetValue;
					if (node.pathId != pathId) {
						toProcess.push(node);
					}
					node.pathId = pathId;
					if (targetValue > maxScore) {
						maxScore = targetValue;
					}
				}
			}
		}
		while (toProcess.length) {
			var nodes = toProcess;
			toProcess = [];
			for (var a = 0; a < nodes.length; a++) {
				var node = nodes[a];
				var targetScore = node.score + 14142;
				if (node.up && node.left && node.up.type != 1 && node.up.type != 4 && node.left.type != 1 && node.left.type != 4 && node.upLeft && node.upLeft.type != 1 && node.upLeft.type != 4) {
					processNode(node.upLeft, targetScore, node);
				}
				if (node.up && node.right && node.up.type != 1 && node.up.type != 4 && node.right.type != 1 && node.right.type != 4 && node.upRight && node.upRight.type != 1 && node.upRight.type != 4) {
					processNode(node.upRight, targetScore, node);
				}
				if (node.down && node.right && node.down.type != 1 && node.down.type != 4 && node.right.type != 1 && node.right.type != 4 && node.downRight && node.downRight.type != 1 && node.downRight.type != 4) {
					processNode(node.downRight, targetScore, node);
				}
				if (node.down && node.left && node.down.type != 1 && node.down.type != 4 && node.left.type != 1 && node.left.type != 4 && node.downLeft && node.downLeft.type != 1 && node.downLeft.type != 4) {
					processNode(node.downLeft, targetScore, node);
				}
				targetScore = node.score + 10000;
				processNode(node.up, targetScore, node);
				processNode(node.right, targetScore, node);
				processNode(node.down, targetScore, node);
				processNode(node.left, targetScore, node);
			}
		}
		// Check if any spawn point has a valid path to any goal
		var hasValidPath = false;
		for (var a = 0; a < self.spawns.length; a++) {
			if (self.spawns[a].pathId === pathId) {
				hasValidPath = true;
				break;
			}
		}
		// Ensure maze is navigable - return false if paths are blocked
		if (!hasValidPath) {
			console.log("Maze blocks all paths - this layout will be regenerated");
			return true; // Signal that maze needs regeneration
		}
		for (var a = 0; a < enemies.length; a++) {
			var enemy = enemies[a];
			// Skip enemies that haven't entered the viewable area yet
			if (enemy.currentCellY < 4) {
				continue;
			}
			// Skip flying enemies from path check as they can fly over obstacles
			if (enemy.isFlying) {
				continue;
			}
			var target = self.getCell(enemy.cellX, enemy.cellY);
			if (enemy.currentTarget) {
				if (enemy.currentTarget.pathId != pathId) {
					if (!target || target.pathId != pathId) {
						console.warn("Enemy blocked 1 ");
						return true;
					}
				}
			} else if (!target || target.pathId != pathId) {
				console.warn("Enemy blocked 2");
				return true;
			}
		}
		console.log("Speed", new Date().getTime() - before);
	};
	self.renderDebug = function () {
		for (var i = 0; i < gridWidth; i++) {
			for (var j = 0; j < gridHeight; j++) {
				var debugCell = self.cells[i][j].debugCell;
				if (debugCell) {
					debugCell.render(self.cells[i][j]);
				}
			}
		}
	};
	self.updateEnemy = function (enemy) {
		var cell = grid.getCell(enemy.cellX, enemy.cellY);
		if (cell.type == 3) {
			return true;
		}
		if (enemy.isFlying && enemy.shadow) {
			enemy.shadow.x = enemy.x + 20; // Match enemy x-position + offset
			enemy.shadow.y = enemy.y + 20; // Match enemy y-position + offset
			// Match shadow rotation with enemy rotation
			if (enemy.children[0] && enemy.shadow.children[0]) {
				enemy.shadow.children[0].rotation = enemy.children[0].rotation;
			}
		}
		// Check if the enemy has reached the entry area (y position is at least 5)
		var hasReachedEntryArea = enemy.currentCellY >= 4;
		// If enemy hasn't reached the entry area yet, just move down vertically
		if (!hasReachedEntryArea) {
			// Move directly downward
			enemy.currentCellY += enemy.speed * gameSpeed;
			// Rotate enemy graphic to face downward (PI/2 radians = 90 degrees)
			var angle = Math.PI / 2;
			if (enemy.children[0] && enemy.children[0].targetRotation === undefined) {
				enemy.children[0].targetRotation = angle;
				enemy.children[0].rotation = angle;
			} else if (enemy.children[0]) {
				if (Math.abs(angle - enemy.children[0].targetRotation) > 0.05) {
					tween.stop(enemy.children[0], {
						rotation: true
					});
					// Calculate the shortest angle to rotate
					var currentRotation = enemy.children[0].rotation;
					var angleDiff = angle - currentRotation;
					// Normalize angle difference to -PI to PI range for shortest path
					while (angleDiff > Math.PI) {
						angleDiff -= Math.PI * 2;
					}
					while (angleDiff < -Math.PI) {
						angleDiff += Math.PI * 2;
					}
					// Set target rotation and animate to it
					enemy.children[0].targetRotation = angle;
					tween(enemy.children[0], {
						rotation: currentRotation + angleDiff
					}, {
						duration: 250,
						easing: tween.easeOut
					});
				}
			}
			// Update enemy's position
			enemy.x = grid.x + enemy.currentCellX * CELL_SIZE;
			enemy.y = grid.y + enemy.currentCellY * CELL_SIZE;
			// If enemy has now reached the entry area, update cell coordinates
			if (enemy.currentCellY >= 4) {
				enemy.cellX = Math.round(enemy.currentCellX);
				enemy.cellY = Math.round(enemy.currentCellY);
			}
			return false;
		}
		// After reaching entry area, handle flying enemies differently
		if (enemy.isFlying) {
			// Flying enemies head straight to the closest goal
			if (!enemy.flyingTarget) {
				// Set flying target to the closest goal
				enemy.flyingTarget = self.goals[0];
				// Find closest goal if there are multiple
				if (self.goals.length > 1) {
					var closestDist = Infinity;
					for (var i = 0; i < self.goals.length; i++) {
						var goal = self.goals[i];
						var dx = goal.x - enemy.cellX;
						var dy = goal.y - enemy.cellY;
						var dist = dx * dx + dy * dy;
						if (dist < closestDist) {
							closestDist = dist;
							enemy.flyingTarget = goal;
						}
					}
				}
			}
			// Move directly toward the goal
			var ox = enemy.flyingTarget.x - enemy.currentCellX;
			var oy = enemy.flyingTarget.y - enemy.currentCellY;
			var dist = Math.sqrt(ox * ox + oy * oy);
			if (dist < enemy.speed) {
				// Reached the goal
				return true;
			}
			var angle = Math.atan2(oy, ox);
			// Rotate enemy graphic to match movement direction
			if (enemy.children[0] && enemy.children[0].targetRotation === undefined) {
				enemy.children[0].targetRotation = angle;
				enemy.children[0].rotation = angle;
			} else if (enemy.children[0]) {
				if (Math.abs(angle - enemy.children[0].targetRotation) > 0.05) {
					tween.stop(enemy.children[0], {
						rotation: true
					});
					// Calculate the shortest angle to rotate
					var currentRotation = enemy.children[0].rotation;
					var angleDiff = angle - currentRotation;
					// Normalize angle difference to -PI to PI range for shortest path
					while (angleDiff > Math.PI) {
						angleDiff -= Math.PI * 2;
					}
					while (angleDiff < -Math.PI) {
						angleDiff += Math.PI * 2;
					}
					// Set target rotation and animate to it
					enemy.children[0].targetRotation = angle;
					tween(enemy.children[0], {
						rotation: currentRotation + angleDiff
					}, {
						duration: 250,
						easing: tween.easeOut
					});
				}
			}
			// Update the cell position to track where the flying enemy is
			enemy.cellX = Math.round(enemy.currentCellX);
			enemy.cellY = Math.round(enemy.currentCellY);
			enemy.currentCellX += Math.cos(angle) * enemy.speed * gameSpeed;
			enemy.currentCellY += Math.sin(angle) * enemy.speed * gameSpeed;
			enemy.x = grid.x + enemy.currentCellX * CELL_SIZE;
			enemy.y = grid.y + enemy.currentCellY * CELL_SIZE;
			// Update shadow position if this is a flying enemy
			return false;
		}
		// Handle normal pathfinding enemies
		if (!enemy.currentTarget || !cell || cell.pathId !== pathId) {
			// Reset target if we don't have one or if current cell is invalid
			if (cell && cell.pathId === pathId && cell.targets && cell.targets.length > 0) {
				enemy.currentTarget = cell.targets[0];
			} else {
				// If current cell is invalid, try to find nearest valid cell
				var nearestValidCell = null;
				var minDistance = Infinity;
				// Search for nearby valid cells
				for (var searchX = Math.max(0, enemy.cellX - 2); searchX <= Math.min(grid.cells.length - 1, enemy.cellX + 2); searchX++) {
					for (var searchY = Math.max(0, enemy.cellY - 2); searchY <= Math.min(grid.cells[0].length - 1, enemy.cellY + 2); searchY++) {
						var searchCell = grid.getCell(searchX, searchY);
						if (searchCell && searchCell.pathId === pathId && searchCell.targets && searchCell.targets.length > 0) {
							var dx = searchX - enemy.cellX;
							var dy = searchY - enemy.cellY;
							var distance = dx * dx + dy * dy;
							if (distance < minDistance) {
								minDistance = distance;
								nearestValidCell = searchCell;
							}
						}
					}
				}
				if (nearestValidCell) {
					enemy.currentTarget = nearestValidCell;
					// Snap enemy to the valid cell position
					enemy.cellX = nearestValidCell.x;
					enemy.cellY = nearestValidCell.y;
					enemy.currentCellX = nearestValidCell.x;
					enemy.currentCellY = nearestValidCell.y;
				}
			}
		}
		if (enemy.currentTarget) {
			// Validate that current target is still valid
			if (enemy.currentTarget.pathId !== pathId) {
				enemy.currentTarget = null;
				return; // Will be fixed next frame
			}
			// If we have a better path from current cell, use it
			if (cell && cell.pathId === pathId && cell.score < enemy.currentTarget.score) {
				enemy.currentTarget = cell;
			}
			var ox = enemy.currentTarget.x - enemy.currentCellX;
			var oy = enemy.currentTarget.y - enemy.currentCellY;
			var dist = Math.sqrt(ox * ox + oy * oy);
			if (dist < enemy.speed * gameSpeed) {
				// Reached target, snap to grid and clear target
				enemy.cellX = enemy.currentTarget.x;
				enemy.cellY = enemy.currentTarget.y;
				enemy.currentCellX = enemy.currentTarget.x;
				enemy.currentCellY = enemy.currentTarget.y;
				enemy.currentTarget = null;
				// Don't return here, let position update happen
			} else {
				// Move toward target
				var angle = Math.atan2(oy, ox);
				enemy.currentCellX += Math.cos(angle) * enemy.speed * gameSpeed;
				enemy.currentCellY += Math.sin(angle) * enemy.speed * gameSpeed;
			}
		} else {
			// No valid target - try to get unstuck by moving toward goal
			var goalFound = false;
			for (var g = 0; g < self.goals.length; g++) {
				var goal = self.goals[g];
				var gx = goal.x - enemy.currentCellX;
				var gy = goal.y - enemy.currentCellY;
				if (Math.abs(gx) > 0.1 || Math.abs(gy) > 0.1) {
					var gAngle = Math.atan2(gy, gx);
					enemy.currentCellX += Math.cos(gAngle) * enemy.speed * gameSpeed * 0.5; // Move slower when lost
					enemy.currentCellY += Math.sin(gAngle) * enemy.speed * gameSpeed * 0.5;
					goalFound = true;
					break;
				}
			}
		}
		// Update visual position
		enemy.x = grid.x + enemy.currentCellX * CELL_SIZE;
		enemy.y = grid.y + enemy.currentCellY * CELL_SIZE;
	};
});
var MainMenu = Container.expand(function () {
	var self = Container.call(this);
	// Center the menu container
	self.x = 2048 / 2;
	self.y = 2732 / 2;
	// Background overlay
	var menuBackground = self.attachAsset('notification', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	menuBackground.width = 2048;
	menuBackground.height = 2732;
	menuBackground.tint = 0x000000;
	menuBackground.alpha = 0.8;
	// Current state: 'difficulty' or 'empire'
	self.currentState = 'difficulty';
	self.selectedDifficulty = null;
	// Difficulty selection elements
	var difficultyTitle = new Text2("Select Difficulty", {
		size: 120,
		fill: 0xFFFFFF,
		weight: 800
	});
	difficultyTitle.anchor.set(0.5, 0.5);
	difficultyTitle.y = -600;
	self.addChild(difficultyTitle);
	// Difficulty buttons
	var difficulties = ['easy', 'normal', 'hard', 'hardcore', 'ultra'];
	var difficultyButtons = [];
	var difficultyButtonSpacing = 150;
	var difficultyStartY = -300;
	for (var i = 0; i < difficulties.length; i++) {
		var difficulty = difficulties[i];
		var button = new Container();
		var buttonBG = button.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		buttonBG.width = 600;
		buttonBG.height = 120;
		// Set button color based on difficulty
		switch (difficulty) {
			case 'easy':
				buttonBG.tint = 0x00FF00; // Green
				break;
			case 'hard':
				buttonBG.tint = 0xFF8800; // Orange
				break;
			case 'hardcore':
				buttonBG.tint = 0xFF0000; // Red
				break;
			case 'ultra':
				buttonBG.tint = 0x800080; // Purple for ultra
				break;
			default:
				buttonBG.tint = 0x0088FF; // Blue for normal
				break;
		}
		var buttonText = new Text2(difficulty.charAt(0).toUpperCase() + difficulty.slice(1), {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		buttonText.anchor.set(0.5, 0.5);
		button.addChild(buttonText);
		button.y = difficultyStartY + i * difficultyButtonSpacing;
		button.difficulty = difficulty;
		button.down = function () {
			LK.getSound('Click').play();
			// Show confirmation popup for Easy, Normal, and Hard, direct to empire selection for hardcore and ultra
			if (this.difficulty === 'easy' || this.difficulty === 'normal' || this.difficulty === 'hard') {
				self.showConfirmationPopup(this.difficulty);
			} else {
				self.selectedDifficulty = this.difficulty;
				self.showEmpireSelection();
			}
		};
		self.addChild(button);
		difficultyButtons.push(button);
	}
	// Empire selection elements (initially hidden)
	var empireTitle = new Text2("Choose Your Empire!", {
		size: 100,
		fill: 0xFFFFFF,
		weight: 800
	});
	empireTitle.anchor.set(0.5, 0.5);
	empireTitle.y = -700;
	empireTitle.visible = false;
	self.addChild(empireTitle);
	// Empire buttons - 9 different empires including Normal
	var empires = [{
		name: 'Normal',
		color: 0xAAAAAA,
		description: ''
	}, {
		name: 'Austria',
		color: 0x00FF00,
		description: ''
	}, {
		name: 'Hungary',
		color: 0x0088FF,
		description: ''
	}, {
		name: 'Ottoman',
		color: 0xFF8800,
		description: ''
	}, {
		name: 'French',
		color: 0xFF0000,
		description: ''
	}, {
		name: 'England',
		color: 0x800080,
		description: ''
	}, {
		name: 'Scotch',
		color: 0x008080,
		description: ''
	}, {
		name: 'Kalmar Union',
		color: 0x006400,
		description: ''
	}, {
		name: 'Byzantine',
		color: 0xFF69B4,
		description: ''
	}];
	var empireButtons = [];
	var empireButtonSpacing = 200;
	var empireStartY = -400;
	for (var i = 0; i < empires.length; i++) {
		var empire = empires[i];
		var button = new Container();
		var buttonBG = button.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		buttonBG.width = 528;
		buttonBG.height = 176;
		buttonBG.tint = empire.color;
		var buttonText = new Text2(empire.name, {
			size: 53,
			fill: 0xFFFFFF,
			weight: 800
		});
		buttonText.anchor.set(0.5, 0.5);
		buttonText.y = 0;
		button.addChild(buttonText);
		var descText = new Text2(empire.description, {
			size: 35,
			fill: 0xFFFFFF,
			weight: 400
		});
		descText.anchor.set(0.5, 0.5);
		descText.y = 40;
		button.addChild(descText);
		button.y = empireStartY + i * empireButtonSpacing;
		button.visible = false; // Initially hidden
		button.down = function (empireData) {
			return function () {
				LK.getSound('Click').play();
				// Show empire characteristics menu instead of starting game directly
				self.showEmpireCharacteristics(empireData);
			};
		}(empire);
		self.addChild(button);
		empireButtons.push(button);
	}
	// No exit buttons needed
	var exitButtons = [];
	// Add confirmation popup for Easy and Hard difficulties
	self.confirmationPopup = null;
	self.showConfirmationPopup = function (difficulty) {
		// Remove any existing confirmation popup
		if (self.confirmationPopup) {
			self.removeChild(self.confirmationPopup);
			self.confirmationPopup.destroy();
		}
		// Create confirmation popup
		self.confirmationPopup = new Container();
		// Background for confirmation popup
		var confirmBG = self.confirmationPopup.attachAsset('menu', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		confirmBG.width = 1200;
		confirmBG.height = 600;
		confirmBG.alpha = 0.95;
		// Confirmation title
		var confirmText = "Are you sure: ";
		if (difficulty === "easy") {
			confirmText += "Easy?";
		} else if (difficulty === "normal") {
			confirmText += "Normal?";
		} else if (difficulty === "hard") {
			confirmText += "Hard?";
		} else {
			confirmText = "Are You Sure?";
		}
		var confirmTitle = new Text2(confirmText, {
			size: 80,
			fill: 0xFFFFFF,
			weight: 800
		});
		confirmTitle.anchor.set(0.5, 0.5);
		confirmTitle.y = -150;
		self.confirmationPopup.addChild(confirmTitle);
		// Yes button
		var yesButton = new Container();
		var yesBG = yesButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		yesBG.width = 300;
		yesBG.height = 120;
		yesBG.tint = 0x00AA00;
		var yesText = new Text2("Yes", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		yesText.anchor.set(0.5, 0.5);
		yesButton.addChild(yesText);
		yesButton.x = -200;
		yesButton.y = 100;
		yesButton.down = function () {
			LK.getSound('Click').play();
			// Remove confirmation popup and proceed to empire selection
			self.removeChild(self.confirmationPopup);
			self.confirmationPopup.destroy();
			self.confirmationPopup = null;
			// Show empire selection
			self.selectedDifficulty = difficulty;
			self.showEmpireSelection();
		};
		self.confirmationPopup.addChild(yesButton);
		// No button
		var noButton = new Container();
		var noBG = noButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		noBG.width = 300;
		noBG.height = 120;
		noBG.tint = 0xAA0000;
		var noText = new Text2("No", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		noText.anchor.set(0.5, 0.5);
		noButton.addChild(noText);
		noButton.x = 200;
		noButton.y = 100;
		noButton.down = function () {
			LK.getSound('Click').play();
			// Remove confirmation popup and return to difficulty selection
			self.removeChild(self.confirmationPopup);
			self.confirmationPopup.destroy();
			self.confirmationPopup = null;
			self.selectedDifficulty = null;
			// Stay on difficulty selection screen - no state change needed
		};
		self.confirmationPopup.addChild(noButton);
		self.addChild(self.confirmationPopup);
	};
	self.showEmpireSelection = function () {
		// Check if hardcore or ultra difficulty was selected
		if (self.selectedDifficulty === 'hardcore') {
			// Show hardcore warning popup instead of empire selection
			self.showHardcoreWarning();
			return;
		} else if (self.selectedDifficulty === 'ultra') {
			// Show ultra warning popup instead of empire selection
			self.showUltraWarning();
			return;
		}
		self.currentState = 'empire';
		// Hide difficulty elements
		difficultyTitle.visible = false;
		for (var i = 0; i < difficultyButtons.length; i++) {
			difficultyButtons[i].visible = false;
		}
		// Show empire elements
		empireTitle.visible = true;
		for (var i = 0; i < empireButtons.length; i++) {
			empireButtons[i].visible = true;
		}
		// No exit buttons to show
	};
	self.showHardcoreWarning = function () {
		// Remove any existing warning popup
		if (self.hardcoreWarningPopup) {
			self.removeChild(self.hardcoreWarningPopup);
			self.hardcoreWarningPopup.destroy();
		}
		// Create hardcore warning popup
		self.hardcoreWarningPopup = new Container();
		// Background for warning popup
		var warningBG = self.hardcoreWarningPopup.attachAsset('menu', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		warningBG.width = 1600;
		warningBG.height = 800;
		warningBG.alpha = 0.95;
		// Warning title
		var warningTitle = new Text2("WARNING", {
			size: 100,
			fill: 0xFF0000,
			weight: 800
		});
		warningTitle.anchor.set(0.5, 0.5);
		warningTitle.y = -250;
		self.hardcoreWarningPopup.addChild(warningTitle);
		// Warning message
		var warningText = new Text2("This difficulty is not one of the original game\ndifficulties for Honorbound: Rise on the Fifth Dawn.\nIT IS FOR ADVANCED PLAYERS ONLY!", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 400
		});
		warningText.anchor.set(0.5, 0.5);
		warningText.y = -50;
		self.hardcoreWarningPopup.addChild(warningText);
		// Okay button
		var okayButton = new Container();
		var okayBG = okayButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		okayBG.width = 300;
		okayBG.height = 120;
		okayBG.tint = 0x00AA00;
		var okayText = new Text2("Okay", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		okayText.anchor.set(0.5, 0.5);
		okayButton.addChild(okayText);
		okayButton.x = -200;
		okayButton.y = 200;
		okayButton.down = function () {
			LK.getSound('Click').play();
			// Remove warning popup and proceed to empire selection
			self.removeChild(self.hardcoreWarningPopup);
			self.hardcoreWarningPopup.destroy();
			self.hardcoreWarningPopup = null;
			// Show empire selection
			self.currentState = 'empire';
			// Hide difficulty elements
			difficultyTitle.visible = false;
			for (var i = 0; i < difficultyButtons.length; i++) {
				difficultyButtons[i].visible = false;
			}
			// Show empire elements
			empireTitle.visible = true;
			for (var i = 0; i < empireButtons.length; i++) {
				empireButtons[i].visible = true;
			}
		};
		self.hardcoreWarningPopup.addChild(okayButton);
		// Back button
		var backButton = new Container();
		var backBG = backButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		backBG.width = 300;
		backBG.height = 120;
		backBG.tint = 0xAA0000;
		var backText = new Text2("Back", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		backText.anchor.set(0.5, 0.5);
		backButton.addChild(backText);
		backButton.x = 200;
		backButton.y = 200;
		backButton.down = function () {
			LK.getSound('Click').play();
			// Remove warning popup and return to difficulty selection
			self.removeChild(self.hardcoreWarningPopup);
			self.hardcoreWarningPopup.destroy();
			self.hardcoreWarningPopup = null;
			self.selectedDifficulty = null;
			// Return to difficulty selection
			self.currentState = 'difficulty';
			// Show difficulty elements
			difficultyTitle.visible = true;
			for (var i = 0; i < difficultyButtons.length; i++) {
				difficultyButtons[i].visible = true;
			}
			// Hide empire elements
			empireTitle.visible = false;
			for (var i = 0; i < empireButtons.length; i++) {
				empireButtons[i].visible = false;
			}
		};
		self.hardcoreWarningPopup.addChild(backButton);
		self.addChild(self.hardcoreWarningPopup);
	};
	self.showUltraWarning = function () {
		// Remove any existing warning popup
		if (self.ultraWarningPopup) {
			self.removeChild(self.ultraWarningPopup);
			self.ultraWarningPopup.destroy();
		}
		// Create ultra warning popup
		self.ultraWarningPopup = new Container();
		// Background for warning popup
		var warningBG = self.ultraWarningPopup.attachAsset('menu', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		warningBG.width = 1600;
		warningBG.height = 800;
		warningBG.alpha = 0.95;
		// Warning title
		var warningTitle = new Text2("ULTRA MODE", {
			size: 100,
			fill: 0x800080,
			weight: 800
		});
		warningTitle.anchor.set(0.5, 0.5);
		warningTitle.y = -250;
		self.ultraWarningPopup.addChild(warningTitle);
		// Warning message
		var warningText = new Text2("This is an extreme endurance mode!\n30 waves without any King.\nEverything else is the same as Hardcore.\nAre you ready for the ultimate challenge?", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 400
		});
		warningText.anchor.set(0.5, 0.5);
		warningText.y = -50;
		self.ultraWarningPopup.addChild(warningText);
		// Okay button
		var okayButton = new Container();
		var okayBG = okayButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		okayBG.width = 300;
		okayBG.height = 120;
		okayBG.tint = 0x00AA00;
		var okayText = new Text2("Okay", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		okayText.anchor.set(0.5, 0.5);
		okayButton.addChild(okayText);
		okayButton.x = -200;
		okayButton.y = 200;
		okayButton.down = function () {
			LK.getSound('Click').play();
			// Remove warning popup and proceed to empire selection
			self.removeChild(self.ultraWarningPopup);
			self.ultraWarningPopup.destroy();
			self.ultraWarningPopup = null;
			// Show empire selection
			self.currentState = 'empire';
			// Hide difficulty elements
			difficultyTitle.visible = false;
			for (var i = 0; i < difficultyButtons.length; i++) {
				difficultyButtons[i].visible = false;
			}
			// Show empire elements
			empireTitle.visible = true;
			for (var i = 0; i < empireButtons.length; i++) {
				empireButtons[i].visible = true;
			}
		};
		self.ultraWarningPopup.addChild(okayButton);
		// Back button
		var backButton = new Container();
		var backBG = backButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		backBG.width = 300;
		backBG.height = 120;
		backBG.tint = 0xAA0000;
		var backText = new Text2("Back", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		backText.anchor.set(0.5, 0.5);
		backButton.addChild(backText);
		backButton.x = 200;
		backButton.y = 200;
		backButton.down = function () {
			LK.getSound('Click').play();
			// Remove warning popup and return to difficulty selection
			self.removeChild(self.ultraWarningPopup);
			self.ultraWarningPopup.destroy();
			self.ultraWarningPopup = null;
			self.selectedDifficulty = null;
			// Return to difficulty selection
			self.currentState = 'difficulty';
			// Show difficulty elements
			difficultyTitle.visible = true;
			for (var i = 0; i < difficultyButtons.length; i++) {
				difficultyButtons[i].visible = true;
			}
			// Hide empire elements
			empireTitle.visible = false;
			for (var i = 0; i < empireButtons.length; i++) {
				empireButtons[i].visible = false;
			}
		};
		self.ultraWarningPopup.addChild(backButton);
		self.addChild(self.ultraWarningPopup);
	};
	self.showEmpireCharacteristics = function (empireData) {
		// Remove any existing characteristics popup
		if (self.characteristicsPopup) {
			self.removeChild(self.characteristicsPopup);
			self.characteristicsPopup.destroy();
		}
		// Create characteristics popup
		self.characteristicsPopup = new Container();
		// Background for characteristics popup
		var charBG = self.characteristicsPopup.attachAsset('menu', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		charBG.width = 1400;
		charBG.height = 1000;
		charBG.alpha = 0.95;
		// Empire name title
		var titleText = new Text2(empireData.name + " Empire", {
			size: 80,
			fill: empireData.color,
			weight: 800
		});
		titleText.anchor.set(0.5, 0.5);
		titleText.y = -400;
		self.characteristicsPopup.addChild(titleText);
		// Empire characteristics text
		var characteristicsText = "";
		switch (empireData.name) {
			case 'Normal':
				characteristicsText = "Advantages:\n• Standard gameplay\n• No special bonuses\n• Balanced empire\n• Good for beginners";
				break;
			case 'Austria':
				characteristicsText = "Advantages:\n• +20% tower fire rate\n• All towers attack faster\n• Excellent for rapid defense";
				break;
			case 'Hungary':
				characteristicsText = "Advantages:\n• Tower cost -5 gold\n  (Normal+ difficulty)\n• Better economy management\n• More affordable towers";
				break;
			case 'Ottoman':
				characteristicsText = "Advantages:\n• Start with 100 gold\n  (instead of 80)\n• +20% damage on all attacks\n• Strong early game";
				break;
			case 'French':
				characteristicsText = "Advantages:\n• +20% tower durability\n• Towers have more health\n• Better defensive capability";
				break;
			case 'England':
				characteristicsText = "Advantages:\n• Start with 100 gold\n  (instead of 80)\n• 3 fewer enemies per wave\n• Easier defense management";
				break;
			case 'Scotch':
				characteristicsText = "Advantages:\n• Tower costs -3 gold\n• Archer range +50%\n• Better defense capability";
				break;
			case 'Kalmar Union':
				characteristicsText = "Advantages:\n• Healer range +100%\n• Better healing coverage\n• Improved tower protection";
				break;
			case 'Byzantine':
				characteristicsText = "Advantages:\n• Tower durability +100%\n• Towers have double health\nDisadvantages:\n• +3 enemies per wave\n• Higher enemy pressure";
				break;
			default:
				characteristicsText = "Advantages:\n• Standard empire\n• No special bonuses\n• Balanced gameplay";
		}
		var infoText = new Text2(characteristicsText, {
			size: 60,
			fill: 0xFFFFFF,
			weight: 400
		});
		infoText.anchor.set(0.5, 0.5);
		infoText.y = -150;
		self.characteristicsPopup.addChild(infoText);
		// Select Empire button
		var selectButton = new Container();
		var selectBG = selectButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		selectBG.width = 400;
		selectBG.height = 120;
		selectBG.tint = 0x00AA00;
		var selectText = new Text2("Select Empire", {
			size: 60,
			fill: 0xFFFFFF,
			weight: 800
		});
		selectText.anchor.set(0.5, 0.5);
		selectButton.addChild(selectText);
		selectButton.y = 200;
		selectButton.down = function () {
			LK.getSound('Click').play();
			// Store selected empire and start tutorial for easy/normal, or start game directly for others
			gameSettings.selectedEmpire = empireData.name;
			self.removeChild(self.characteristicsPopup);
			self.characteristicsPopup.destroy();
			self.characteristicsPopup = null;
			// Show tutorial for easy and normal modes
			if (self.selectedDifficulty === 'easy' || self.selectedDifficulty === 'normal') {
				self.startTutorial();
			} else {
				self.startGame();
			}
		};
		self.characteristicsPopup.addChild(selectButton);
		// Back button
		var backButton = new Container();
		var backBG = backButton.attachAsset('Buton', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		backBG.width = 200;
		backBG.height = 100;
		backBG.tint = 0xAA0000;
		var backText = new Text2("Back", {
			size: 50,
			fill: 0xFFFFFF,
			weight: 800
		});
		backText.anchor.set(0.5, 0.5);
		backButton.addChild(backText);
		backButton.y = 350;
		backButton.down = function () {
			LK.getSound('Click').play();
			self.removeChild(self.characteristicsPopup);
			self.characteristicsPopup.destroy();
			self.characteristicsPopup = null;
		};
		self.characteristicsPopup.addChild(backButton);
		self.addChild(self.characteristicsPopup);
	};
	self.startTutorial = function () {
		// Check if tutorial has already been completed
		if (storage.tutorialCompleted) {
			// Skip tutorial and start game directly
			self.startGame();
			return;
		}
		// Remove start menu first
		self.destroy();
		// Apply game settings but don't enable interactions yet
		gameSettings.difficulty = self.selectedDifficulty;
		gameSettings.selectedDifficulty = self.selectedDifficulty;
		updateTotalWaves();
		// Apply empire starting gold bonuses
		if (gameSettings.selectedEmpire === 'Ottoman' || gameSettings.selectedEmpire === 'England') {
			setGold(100);
		} else {
			setGold(80);
		}
		// Show UI elements but keep interactions disabled
		if (typeof medievalButton !== "undefined") medievalButton.visible = true;
		if (typeof trenchButton !== "undefined") trenchButton.visible = true;
		if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
		if (typeof goldText !== "undefined") goldText.visible = true;
		if (typeof livesText !== "undefined") livesText.visible = true;
		if (typeof musicControl !== "undefined") musicControl.visible = true;
		if (typeof speedControl !== "undefined") speedControl.visible = true;
		// Update tower cost displays
		for (var i = 0; i < sourceTowers.length; i++) {
			sourceTowers[i].updateCostLabels();
		}
		// Create and show tutorial
		var tutorial = new Tutorial(self.selectedDifficulty);
		tutorial.x = 2048 / 2;
		tutorial.y = 2732 / 2;
		game.addChild(tutorial);
		// Override tutorial end to return to main menu
		tutorial.endTutorial = function () {
			tutorial.isActive = false;
			tutorial.destroy();
			// Mark tutorial as completed and save to storage
			storage.tutorialCompleted = true;
			// Return to main menu after tutorial completion
			var mainMenu = new MainMenu();
			game.addChild(mainMenu);
		};
		tutorial.startTutorial();
	};
	self.startGame = function () {
		// Apply difficulty settings
		gameSettings.difficulty = self.selectedDifficulty;
		gameSettings.selectedDifficulty = self.selectedDifficulty;
		// Update totalWaves based on selected difficulty
		updateTotalWaves();
		// Apply empire starting gold bonuses
		if (gameSettings.selectedEmpire === 'Ottoman' || gameSettings.selectedEmpire === 'England') {
			setGold(100);
		} else {
			setGold(80);
		}
		// Enable game interactions
		gameStartAllowed = true;
		// Restore visibility of hidden elements when game starts
		if (typeof medievalButton !== "undefined") medievalButton.visible = true;
		if (typeof trenchButton !== "undefined") trenchButton.visible = true;
		if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
		if (typeof goldText !== "undefined") goldText.visible = true;
		if (typeof livesText !== "undefined") livesText.visible = true;
		if (typeof musicControl !== "undefined") musicControl.visible = true;
		if (typeof speedControl !== "undefined") speedControl.visible = true;
		// Update tower cost displays for new difficulty
		for (var i = 0; i < sourceTowers.length; i++) {
			sourceTowers[i].updateCostLabels();
		}
		// Exit menu when empire is selected
		self.destroy();
	};
	return self;
});
var MusicControl = Container.expand(function () {
	var self = Container.call(this);
	var buttonBackground = self.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBackground.width = 200;
	buttonBackground.height = 70;
	buttonBackground.tint = 0xFF8800;
	var musicText = new Text2("Music1", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	musicText.anchor.set(0.5, 0.5);
	self.addChild(musicText);
	var currentMusicIndex = 1;
	self.updateDisplay = function () {
		var musicName = currentMusicIndex === 8 ? "Nomusic" : "Music" + currentMusicIndex;
		musicText.setText(musicName);
		// Update button color based on music selection
		switch (currentMusicIndex) {
			case 1:
				buttonBackground.tint = 0xFF8800; // Orange for Music1
				break;
			case 2:
				buttonBackground.tint = 0x8800FF; // Purple for Music2
				break;
			case 3:
				buttonBackground.tint = 0x00FF88; // Green for Music3
				break;
			case 4:
				buttonBackground.tint = 0xFF0088; // Pink for Music4
				break;
			case 5:
				buttonBackground.tint = 0x0088FF; // Blue for Music5
				break;
			case 6:
				buttonBackground.tint = 0x006400; // Dark green for Music6
				break;
			case 7:
				buttonBackground.tint = 0x800080; // Purple for Music7
				break;
			case 8:
				buttonBackground.tint = 0x444444; // Gray for Nomusic
				break;
		}
	};
	self.down = function () {
		// Block music control if difficulty not selected
		if (!gameStartAllowed) {
			return;
		}
		// Cycle through music options 1-8 (including Nomusic at position 8)
		currentMusicIndex = currentMusicIndex >= 8 ? 1 : currentMusicIndex + 1;
		self.updateDisplay();
		// Play the corresponding music track or stop music for Nomusic
		if (currentMusicIndex === 8) {
			LK.stopMusic();
		} else {
			var musicTrack = "warmusic" + (currentMusicIndex === 1 ? "" : currentMusicIndex);
			LK.playMusic(musicTrack);
		}
	};
	// Initialize display
	self.updateDisplay();
	return self;
});
var NextWaveButton = Container.expand(function () {
	var self = Container.call(this);
	var buttonBackground = self.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBackground.width = 300;
	buttonBackground.height = 100;
	buttonBackground.tint = 0x0088FF;
	var buttonText = new Text2("Next Wave", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	buttonText.anchor.set(0.5, 0.5);
	self.addChild(buttonText);
	self.enabled = false;
	self.visible = false;
	self.update = function () {
		if (waveIndicator && waveIndicator.gameStarted && currentWave < totalWaves) {
			self.enabled = true;
			self.visible = true;
			buttonBackground.tint = 0x0088FF;
			self.alpha = 1;
		} else {
			self.enabled = false;
			self.visible = false;
			buttonBackground.tint = 0x888888;
			self.alpha = 0.7;
		}
	};
	self.down = function () {
		// Block next wave if difficulty not selected
		if (!gameStartAllowed) {
			return;
		}
		if (!self.enabled) {
			return;
		}
		if (waveIndicator.gameStarted && currentWave < totalWaves) {
			currentWave++; // Increment to the next wave directly
			waveTimer = 0; // Reset wave timer
			waveInProgress = true;
			waveSpawned = false;
			var notification = game.addChild(new Notification("Wave " + currentWave + " activated!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 150;
		}
	};
	return self;
});
var Notification = Container.expand(function (message) {
	var self = Container.call(this);
	var notificationGraphics = self.attachAsset('notification', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var notificationText = new Text2(message, {
		size: 50,
		fill: 0x000000,
		weight: 800
	});
	notificationText.anchor.set(0.5, 0.5);
	notificationGraphics.width = notificationText.width + 30;
	self.addChild(notificationText);
	self.alpha = 1;
	var fadeOutTime = 120;
	self.update = function () {
		if (fadeOutTime > 0) {
			fadeOutTime--;
			self.alpha = Math.min(fadeOutTime / 120 * 2, 1);
		} else {
			self.destroy();
		}
	};
	return self;
});
var SourceTower = Container.expand(function (towerType) {
	var self = Container.call(this);
	self.towerType = towerType || 'default';
	// Increase size of base for easier touch
	var baseGraphics = self.attachAsset(towerSet === 'futuristic' ? 'future' : towerSet === 'trench' ? 'builds' : towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'Farmland' : 'builds' : 'tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.3,
		scaleY: 1.3
	});
	switch (self.towerType) {
		case 'rapid':
			baseGraphics.tint = 0x00AAFF;
			break;
		case 'sniper':
			baseGraphics.tint = 0xFF5500;
			break;
		case 'splash':
			baseGraphics.tint = 0x33CC00;
			break;
		case 'slow':
			baseGraphics.tint = 0x9900FF;
			break;
		case 'poison':
			baseGraphics.tint = 0x00FFAA;
			break;
		default:
			baseGraphics.tint = 0xAAAAAA;
	}
	var towerCost = getTowerCost(self.towerType);
	// Add shadow for tower type label
	var displayNameShadow = self.towerType === 'default' ? towerSet === 'futuristic' ? 'Robot' : 'Infantry' : self.towerType === 'rapid' ? towerSet === 'futuristic' ? 'Lazerer' : 'Catapult' : self.towerType === 'splash' ? towerSet === 'futuristic' ? 'Fwacha' : 'Hwacha' : self.towerType === 'sniper' ? towerSet === 'futuristic' ? 'Eaglebot' : 'Archer' : self.towerType === 'slow' ? towerSet === 'futuristic' ? 'f-Bullet' : towerSet === 'builds' ? 'Upgrader' : 'Bullet' : self.towerType === 'poison' ? towerSet === 'futuristic' ? 'Hospital' : 'Healer' : self.towerType.charAt(0).toUpperCase() + self.towerType.slice(1);
	var typeLabelShadow = new Text2(displayNameShadow, {
		size: 50,
		fill: 0x000000,
		weight: 800
	});
	typeLabelShadow.anchor.set(0.5, 0.5);
	typeLabelShadow.x = 4;
	typeLabelShadow.y = -20 + 4;
	self.addChild(typeLabelShadow);
	// Add tower type label
	var displayName = self.towerType === 'default' ? towerSet === 'futuristic' ? 'Robot' : towerSet === 'trench' ? 'Blocker' : towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'House' : 'Build1' : 'Infantry' : self.towerType === 'rapid' ? towerSet === 'futuristic' ? 'Lazerer' : towerSet === 'trench' ? 'Trapper' : towerSet === 'builds' ? 'Farm' : 'Catapult' : self.towerType === 'splash' ? towerSet === 'futuristic' ? 'Fwacha' : towerSet === 'builds' ? 'Research' : 'Hwacha' : self.towerType === 'sniper' ? towerSet === 'futuristic' ? 'Eaglebot' : towerSet === 'trench' ? 'Money' : towerSet === 'builds' ? 'Miner' : 'Archer' : self.towerType === 'slow' ? towerSet === 'futuristic' ? 'f-Bullet' : towerSet === 'builds' ? 'Upgrader' : 'Bullet' : self.towerType === 'poison' ? towerSet === 'futuristic' ? 'Hospital' : towerSet === 'builds' ? 'Smith' : 'Healer' : self.towerType.charAt(0).toUpperCase() + self.towerType.slice(1);
	var typeLabel = new Text2(displayName, {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	typeLabel.anchor.set(0.5, 0.5);
	typeLabel.y = -20; // Position above center of tower
	self.addChild(typeLabel);
	// Add cost shadow
	var costLabelShadow = new Text2(towerCost, {
		size: 50,
		fill: 0x000000,
		weight: 800
	});
	costLabelShadow.anchor.set(0.5, 0.5);
	costLabelShadow.x = 4;
	costLabelShadow.y = 24 + 12;
	self.addChild(costLabelShadow);
	// Add cost label
	var displayCost = towerCost;
	var towerOreCost = getTowerOreCost(self.towerType);
	if (towerOreCost > 0) {
		displayCost = towerCost + "G/" + towerOreCost + "O";
	}
	var costLabel = new Text2(displayCost, {
		size: 50,
		fill: 0xFFD700,
		weight: 800
	});
	costLabel.anchor.set(0.5, 0.5);
	costLabel.y = 20 + 12;
	self.addChild(costLabel);
	self.updateCostLabels = function () {
		var newCost = getTowerCost(self.towerType);
		var towerOreCost = getTowerOreCost(self.towerType);
		var displayCost = newCost;
		if (towerOreCost > 0) {
			displayCost = newCost + "G/" + towerOreCost + "O";
		}
		costLabel.setText(displayCost);
		costLabelShadow.setText(displayCost);
	};
	self.update = function () {
		// Check if player can afford this tower
		var towerOreCost = getTowerOreCost(self.towerType);
		var canAfford = gold >= getTowerCost(self.towerType) && ore >= towerOreCost;
		// Set opacity based on affordability
		self.alpha = canAfford ? 1 : 0.5;
	};
	return self;
});
var SpeedControl = Container.expand(function () {
	var self = Container.call(this);
	var buttonBackground = self.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBackground.width = 200;
	buttonBackground.height = 70;
	buttonBackground.tint = 0x0088FF;
	var speedText = new Text2("Normal", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	speedText.anchor.set(0.5, 0.5);
	self.addChild(speedText);
	self.updateDisplay = function () {
		var speedName = gameSpeedOptions[currentSpeedIndex];
		speedText.setText(speedName.charAt(0).toUpperCase() + speedName.slice(1));
		// Update game speed based on selection
		switch (speedName) {
			case 'slow':
				gameSpeed = 0.5;
				buttonBackground.tint = 0xFF8800; // Orange for slow
				break;
			case 'normal':
				gameSpeed = 1.0;
				buttonBackground.tint = 0x0088FF; // Blue for normal
				break;
			case 'fast':
				gameSpeed = 2.0;
				buttonBackground.tint = 0x00FF00; // Green for fast
				break;
			case 'ultra':
				gameSpeed = 2.5; // 25% faster than fast
				buttonBackground.tint = 0xFF0000; // Red for ultra
				break;
			case 'paused':
				gameSpeed = 0.0; // Complete pause
				buttonBackground.tint = 0x666666; // Gray for paused
				break;
		}
	};
	self.down = function () {
		// Block speed control if difficulty not selected
		if (!gameStartAllowed) {
			return;
		}
		// Cycle through speed options
		currentSpeedIndex = (currentSpeedIndex + 1) % gameSpeedOptions.length;
		self.updateDisplay();
	};
	// Initialize display
	self.updateDisplay();
	return self;
});
var StartMenu = Container.expand(function () {
	var self = Container.call(this);
	// Center the menu container
	self.x = 2048 / 2;
	self.y = 2732 / 2;
	// Background overlay
	var menuBackground = self.attachAsset('notification', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	menuBackground.width = 2048;
	menuBackground.height = 2732;
	menuBackground.tint = 0x000000;
	menuBackground.alpha = 0.8;
	// Game title
	var titleText = new Text2("HONORBOUND", {
		size: 150,
		fill: 0xFFFFFF,
		weight: 800
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.y = -250;
	self.addChild(titleText);
	// Subtitle
	var subtitleText = new Text2("Rise on the Fifth Dawn", {
		size: 80,
		fill: 0xCCCCCC,
		weight: 400
	});
	subtitleText.anchor.set(0.5, 0.5);
	subtitleText.y = -150;
	self.addChild(subtitleText);
	// Play button
	var playButton = new Container();
	var playButtonBG = playButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	playButtonBG.width = 400;
	playButtonBG.height = 120;
	playButtonBG.tint = 0x00AA00; // Green color
	var playText = new Text2("PLAY", {
		size: 80,
		fill: 0xFFFFFF,
		weight: 800
	});
	playText.anchor.set(0.5, 0.5);
	playButton.addChild(playText);
	playButton.y = 50;
	playButton.down = function () {
		LK.getSound('Click').play();
		// Remove start menu and show main menu (difficulty selection)
		self.destroy();
		var mainMenu = new MainMenu();
		game.addChild(mainMenu);
	};
	self.addChild(playButton);
	// Story Mode button
	var storyButton = new Container();
	var storyButtonBG = storyButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	storyButtonBG.width = 400;
	storyButtonBG.height = 120;
	storyButtonBG.tint = 0x1976D2; // Blue color for Story Mode
	var storyText = new Text2("Story Mode", {
		size: 70,
		fill: 0xFFFFFF,
		weight: 800
	});
	storyText.anchor.set(0.5, 0.5);
	storyButton.addChild(storyText);
	storyButton.y = playButton.y + 160; // Place below Play button
	// Tutorial button
	var tutorialButton = new Container();
	var tutorialButtonBG = tutorialButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	tutorialButtonBG.width = 400;
	tutorialButtonBG.height = 120;
	tutorialButtonBG.tint = 0x4CAF50; // Green color for Tutorial
	var tutorialText = new Text2("Tutorial", {
		size: 70,
		fill: 0xFFFFFF,
		weight: 800
	});
	tutorialText.anchor.set(0.5, 0.5);
	tutorialButton.addChild(tutorialText);
	tutorialButton.y = storyButton.y + 160; // Place below Story Mode button
	tutorialButton.down = function () {
		LK.getSound('Click').play();
		// Check if tutorial has already been completed
		if (storage.tutorialCompleted) {
			// Show notification that tutorial was already completed and start normal game
			var notification = game.addChild(new Notification("Tutorial already completed! Starting normal game."));
			notification.x = 2048 / 2;
			notification.y = 2732 / 2;
			// Remove start menu and start normal game
			self.destroy();
			gameSettings.difficulty = 'normal';
			gameSettings.selectedEmpire = 'Normal';
			updateTotalWaves();
			setGold(80);
			gameStartAllowed = true;
			// Show UI elements
			if (typeof medievalButton !== "undefined") medievalButton.visible = true;
			if (typeof trenchButton !== "undefined") trenchButton.visible = true;
			if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
			if (typeof goldText !== "undefined") goldText.visible = true;
			if (typeof livesText !== "undefined") livesText.visible = true;
			if (typeof musicControl !== "undefined") musicControl.visible = true;
			if (typeof speedControl !== "undefined") speedControl.visible = true;
			// Update tower cost displays
			for (var i = 0; i < sourceTowers.length; i++) {
				sourceTowers[i].updateCostLabels();
			}
			return;
		}
		// Remove start menu and go directly to tutorial with normal difficulty and Normal empire
		self.destroy();
		// Set up tutorial with default settings
		gameSettings.difficulty = 'normal';
		gameSettings.selectedEmpire = 'Normal';
		updateTotalWaves();
		setGold(80);
		// Show UI elements but keep interactions disabled initially
		if (typeof medievalButton !== "undefined") medievalButton.visible = true;
		if (typeof trenchButton !== "undefined") trenchButton.visible = true;
		if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
		if (typeof goldText !== "undefined") goldText.visible = true;
		if (typeof livesText !== "undefined") livesText.visible = true;
		if (typeof musicControl !== "undefined") musicControl.visible = true;
		if (typeof speedControl !== "undefined") speedControl.visible = true;
		// Update tower cost displays
		for (var i = 0; i < sourceTowers.length; i++) {
			sourceTowers[i].updateCostLabels();
		}
		// Create and show tutorial
		var tutorial = new Tutorial('normal');
		tutorial.x = 2048 / 2;
		tutorial.y = 2732 / 2;
		game.addChild(tutorial);
		// Override tutorial end to return to main menu
		tutorial.endTutorial = function () {
			tutorial.isActive = false;
			tutorial.destroy();
			// Mark tutorial as completed and save to storage
			storage.tutorialCompleted = true;
			// Return to main menu after tutorial completion
			var mainMenu = new MainMenu();
			game.addChild(mainMenu);
		};
		tutorial.startTutorial();
	};
	self.addChild(tutorialButton);
	storyButton.down = function () {
		LK.getSound('Click').play();
		// Remove start menu
		self.destroy();
		// --- STORY MODE SEQUENCE ---
		// Block all input during story mode
		gameStartAllowed = false;
		// Set a flag for story mode
		gameSettings.storyMode = true;
		// --- Play music7 for story mode ---
		LK.playMusic('warmusic7');
		// 1. Black overlay (fade in)
		var blackOverlay = new Container();
		var blackBG = blackOverlay.attachAsset('notification', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		blackBG.width = 2048;
		blackBG.height = 2732;
		blackBG.tint = 0x000000;
		blackBG.alpha = 1;
		blackOverlay.x = 2048 / 2;
		blackOverlay.y = 2732 / 2;
		blackOverlay.alpha = 0;
		game.addChild(blackOverlay);
		// Fade in black overlay over 1s
		tween(blackOverlay, {
			alpha: 1
		}, {
			duration: 1000,
			easing: tween.linear,
			onFinish: function onFinish() {
				// 2. Show story asset (fade in)
				var storyAsset = new Container();
				var storyBG = storyAsset.attachAsset('story', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				storyBG.width = 2048;
				storyBG.height = 2732;
				storyBG.alpha = 1;
				storyAsset.x = 2048 / 2;
				storyAsset.y = 2732 / 2;
				storyAsset.alpha = 0;
				game.addChild(storyAsset);
				tween(storyAsset, {
					alpha: 1
				}, {
					duration: 1000,
					easing: tween.linear
				});
				// 3. After 1s, show first text (fade in)
				LK.setTimeout(function () {
					var text1 = new Text2("Everyone is dead, you are\nthe only one left.", {
						size: 90,
						fill: 0xFFFFFF,
						weight: 800
					});
					text1.anchor.set(0.5, 0.5);
					text1.x = 2048 / 2;
					text1.y = 2732 / 2 - 200;
					text1.alpha = 0;
					game.addChild(text1);
					tween(text1, {
						alpha: 1
					}, {
						duration: 600,
						easing: tween.linear
					});
					// After 3s, fade out text1
					LK.setTimeout(function () {
						tween(text1, {
							alpha: 0
						}, {
							duration: 1000,
							easing: tween.linear,
							onFinish: function onFinish() {
								text1.destroy();
							}
						});
					}, 3000);
					// 4. After 4s, show second text (fade in)
					LK.setTimeout(function () {
						var text2 = new Text2("The enemies that are coming\nnow are advancing towards\nthe capital.", {
							size: 80,
							fill: 0xFFFFFF,
							weight: 800
						});
						text2.anchor.set(0.5, 0.5);
						text2.x = 2048 / 2;
						text2.y = 2732 / 2 - 60;
						text2.alpha = 0;
						game.addChild(text2);
						tween(text2, {
							alpha: 1
						}, {
							duration: 600,
							easing: tween.linear
						});
						// After 5s, fade out text2
						LK.setTimeout(function () {
							tween(text2, {
								alpha: 0
							}, {
								duration: 1000,
								easing: tween.linear,
								onFinish: function onFinish() {
									text2.destroy();
								}
							});
						}, 5000);
						// 5. After 5s (total 9s), show third text (fade in)
						LK.setTimeout(function () {
							var text3 = new Text2("You are the chosen one,\nI have complete confidence\nthat you will save our\nempire. (From Emperor)", {
								size: 70,
								fill: 0xFFFFFF,
								weight: 800
							});
							text3.anchor.set(0.5, 0.5);
							text3.x = 2048 / 2;
							text3.y = 2732 / 2 + 80;
							text3.alpha = 0;
							game.addChild(text3);
							tween(text3, {
								alpha: 1
							}, {
								duration: 600,
								easing: tween.linear
							});
							// After 5s, fade out text3 and story asset, then start game
							LK.setTimeout(function () {
								tween(text3, {
									alpha: 0
								}, {
									duration: 1000,
									easing: tween.linear,
									onFinish: function onFinish() {
										text3.destroy();
									}
								});
								// Fade out story asset and black overlay
								tween(storyAsset, {
									alpha: 0
								}, {
									duration: 1200,
									easing: tween.linear,
									onFinish: function onFinish() {
										storyAsset.destroy();
									}
								});
								tween(blackOverlay, {
									alpha: 0
								}, {
									duration: 1200,
									easing: tween.linear,
									onFinish: function onFinish() {
										blackOverlay.destroy();
										// --- Start game in normal mode, Normal empire ---
										gameSettings.difficulty = 'normal';
										gameSettings.selectedEmpire = 'Normal';
										updateTotalWaves();
										setGold(80);
										// Enable game interactions
										gameStartAllowed = true;
										// Restore visibility of hidden elements when story mode game starts
										if (typeof medievalButton !== "undefined") medievalButton.visible = true;
										if (typeof trenchButton !== "undefined") trenchButton.visible = true;
										if (typeof futuristicButton !== "undefined") futuristicButton.visible = true;
										if (typeof goldText !== "undefined") goldText.visible = true;
										if (typeof livesText !== "undefined") livesText.visible = true;
										if (typeof musicControl !== "undefined") musicControl.visible = true;
										if (typeof speedControl !== "undefined") speedControl.visible = true;
										// Update UI for new settings
										updateUI();
										// Remove any menus, show main game
										// Remove all children except core layers and UI
										for (var i = game.children.length - 1; i >= 0; i--) {
											var child = game.children[i];
											// Remove any menu or overlay containers
											if (child instanceof MainMenu || child instanceof StartMenu) {
												game.removeChild(child);
												child.destroy();
											}
										}
										// --- Switch back to music1 after story mode ends ---
										LK.playMusic('warmusic');
									}
								});
							}, 5000);
						}, 5000);
					}, 4000);
				}, 1000);
			}
		});
	};
	self.addChild(storyButton);
	return self;
});
var Tower = Container.expand(function (id) {
	var self = Container.call(this);
	self.id = id || 'default';
	self.towerSet = towerSet;
	self.level = 1;
	self.maxLevel = 6;
	self.gridX = 0;
	self.gridY = 0;
	self.range = 3 * CELL_SIZE;
	// Tower health system
	self.maxHealth = 100;
	// Apply French empire bonus: 20% more tower durability
	if (gameSettings.selectedEmpire === 'French') {
		self.maxHealth = Math.floor(self.maxHealth * 1.2); // 20% more health
	}
	// Apply Byzantine empire bonus: 100% more tower durability
	if (gameSettings.selectedEmpire === 'Byzantine') {
		self.maxHealth = Math.floor(self.maxHealth * 2.0); // 100% more health
	}
	self.health = self.maxHealth;
	// Special trench tower properties
	self.isBlocker = false;
	self.isTrapper = false;
	self.isMoney = false;
	self.goldTimer = 0;
	self.goldInterval = 300; // 5 seconds at 60 FPS
	// Initialize goldTimer for Farm functionality
	if (self.towerSet === 'builds' && self.id === 'rapid') {
		self.goldTimer = 0;
	}
	// Set trench tower properties based on ID
	if (self.towerSet === 'trench') {
		if (self.id === 'default') {
			self.isBlocker = true;
		} else if (self.id === 'rapid') {
			self.isTrapper = true;
		} else if (self.id === 'sniper') {
			self.isMoney = true;
		}
	}
	// Standardized method to get the current range of the tower
	self.getRange = function () {
		// Trench towers: only Trapper has range, Blocker and Money have no range
		if (self.towerSet === 'trench') {
			if (self.isTrapper) {
				// Trapper: base 2.5, +0.5 per level
				return (2.5 + (self.level - 1) * 0.5) * CELL_SIZE;
			} else {
				// Blocker and Money towers have no range
				return 0;
			}
		}
		// Always calculate range based on tower type and level
		switch (self.id) {
			case 'sniper':
				// Sniper: base 5, +0.8 per level, but final upgrade gets a huge boost
				var baseRange;
				if (self.level === self.maxLevel) {
					baseRange = 12 * CELL_SIZE; // Significantly increased range for max level
				} else {
					baseRange = (5 + (self.level - 1) * 0.8) * CELL_SIZE;
				}
				// Apply Scotch empire bonus: 50% more archer range
				if (gameSettings.selectedEmpire === 'Scotch') {
					baseRange = baseRange * 1.5;
				}
				return baseRange;
			case 'splash':
				// Splash: base 4, +0.4 per level (max ~8 blocks at max level)
				return (4 + (self.level - 1) * 0.4) * CELL_SIZE;
			case 'rapid':
				// Rapid: base 2.5, +0.5 per level
				return (2.5 + (self.level - 1) * 0.5) * CELL_SIZE;
			case 'slow':
				// f-Bullet: 2x range when futuristic unlocked
				if (futuristicUnlocked) {
					return (3.5 + (self.level - 1) * 0.5) * CELL_SIZE * 2; // 2x normal range
				}
				// Slow: base 3.5, +0.5 per level
				return (3.5 + (self.level - 1) * 0.5) * CELL_SIZE;
			case 'poison':
				// Hospital: 2x range when futuristic unlocked
				if (futuristicUnlocked) {
					var baseRange = (3.2 + (self.level - 1) * 0.5) * CELL_SIZE * 2; // 2x normal range
					// Apply Kalmar Union empire bonus: 100% more healer range
					if (gameSettings.selectedEmpire === 'Kalmar Union') {
						baseRange = baseRange * 2.0;
					}
					return baseRange;
				}
				// Poison: base 3.2, +0.5 per level
				var baseRange = (3.2 + (self.level - 1) * 0.5) * CELL_SIZE;
				// Apply Kalmar Union empire bonus: 100% more healer range
				if (gameSettings.selectedEmpire === 'Kalmar Union') {
					baseRange = baseRange * 2.0;
				}
				return baseRange;
			default:
				// Default: base 3, +0.5 per level
				return (3 + (self.level - 1) * 0.5) * CELL_SIZE;
		}
	};
	self.cellsInRange = [];
	self.fireRate = 60;
	self.bulletSpeed = 5;
	self.damage = 10;
	self.lastFired = 0;
	self.targetEnemy = null;
	// Check if futuristic has been unlocked and apply 3x fire rate boost
	var fireRateMultiplier = futuristicUnlocked ? 1 / 3 : 1;
	switch (self.id) {
		case 'rapid':
			self.fireRate = 30 * fireRateMultiplier;
			self.damage = 5;
			self.range = 2.5 * CELL_SIZE;
			self.bulletSpeed = 7;
			break;
		case 'sniper':
			self.fireRate = 90 * fireRateMultiplier;
			self.damage = 25;
			self.range = 5 * CELL_SIZE;
			self.bulletSpeed = 25;
			break;
		case 'splash':
			self.fireRate = 52 * fireRateMultiplier; // 30% faster than 75 (75 * 0.7 = 52.5, rounded to 52)
			self.damage = 15;
			self.range = 2 * CELL_SIZE;
			self.bulletSpeed = 4;
			break;
		case 'slow':
			self.fireRate = 50 * fireRateMultiplier;
			self.damage = 8;
			self.range = 3.5 * CELL_SIZE;
			self.bulletSpeed = 5;
			break;
		case 'poison':
			self.fireRate = 70 * fireRateMultiplier;
			self.damage = 12;
			self.range = 3.2 * CELL_SIZE;
			self.bulletSpeed = 5;
			break;
	}
	var baseGraphics = self.attachAsset(towerSet === 'futuristic' ? 'future' : towerSet === 'trench' ? 'builds' : towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'Farmland' : 'builds' : 'tower', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	switch (self.id) {
		case 'rapid':
			baseGraphics.tint = 0x00AAFF;
			break;
		case 'sniper':
			baseGraphics.tint = 0xFF5500;
			break;
		case 'splash':
			baseGraphics.tint = 0x33CC00;
			break;
		case 'slow':
			baseGraphics.tint = 0x9900FF;
			break;
		case 'poison':
			baseGraphics.tint = 0x00FFAA;
			break;
		default:
			baseGraphics.tint = 0xAAAAAA;
	}
	// Add tower health bar
	var towerHealthBarOutline = self.attachAsset('healthBarOutline', {
		anchorX: 0,
		anchorY: 0.5
	});
	var towerHealthBarBG = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	var towerHealthBar = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0.5
	});
	towerHealthBarBG.y = towerHealthBarOutline.y = towerHealthBar.y = baseGraphics.height / 2 + 15;
	towerHealthBarOutline.x = -towerHealthBarOutline.width / 2;
	towerHealthBarBG.x = towerHealthBar.x = -towerHealthBar.width / 2 - .5;
	towerHealthBar.tint = 0x00ff00;
	towerHealthBarBG.tint = 0xff0000;
	self.towerHealthBar = towerHealthBar;
	var levelIndicators = [];
	var maxDots = self.maxLevel;
	var dotSpacing = baseGraphics.width / (maxDots + 1);
	var dotSize = CELL_SIZE / 6;
	for (var i = 0; i < maxDots; i++) {
		var dot = new Container();
		var outlineCircle = dot.attachAsset('towerLevelIndicator', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		outlineCircle.width = dotSize + 4;
		outlineCircle.height = dotSize + 4;
		outlineCircle.tint = 0x000000;
		var towerLevelIndicator = dot.attachAsset('towerLevelIndicator', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		towerLevelIndicator.width = dotSize;
		towerLevelIndicator.height = dotSize;
		towerLevelIndicator.tint = 0xCCCCCC;
		dot.x = -CELL_SIZE + dotSpacing * (i + 1);
		dot.y = CELL_SIZE * 0.7;
		self.addChild(dot);
		levelIndicators.push(dot);
	}
	var gunContainer = new Container();
	self.addChild(gunContainer);
	// Don't add arrow/gun graphics for trench towers
	if (self.towerSet !== 'trench') {
		var gunGraphics = gunContainer.attachAsset(towerSet === 'futuristic' ? 'farrow' : 'defense', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	}
	self.updateLevelIndicators = function () {
		for (var i = 0; i < maxDots; i++) {
			var dot = levelIndicators[i];
			var towerLevelIndicator = dot.children[1];
			if (i < self.level) {
				towerLevelIndicator.tint = 0xFFFFFF;
			} else {
				switch (self.id) {
					case 'rapid':
						towerLevelIndicator.tint = 0x00AAFF;
						break;
					case 'sniper':
						towerLevelIndicator.tint = 0xFF5500;
						break;
					case 'splash':
						towerLevelIndicator.tint = 0x33CC00;
						break;
					case 'slow':
						towerLevelIndicator.tint = 0x9900FF;
						break;
					case 'poison':
						towerLevelIndicator.tint = 0x00FFAA;
						break;
					default:
						towerLevelIndicator.tint = 0xAAAAAA;
				}
			}
		}
	};
	self.updateLevelIndicators();
	self.refreshCellsInRange = function () {
		for (var i = 0; i < self.cellsInRange.length; i++) {
			var cell = self.cellsInRange[i];
			var towerIndex = cell.towersInRange.indexOf(self);
			if (towerIndex !== -1) {
				cell.towersInRange.splice(towerIndex, 1);
			}
		}
		self.cellsInRange = [];
		var rangeRadius = self.getRange() / CELL_SIZE;
		var centerX = self.gridX + 1;
		var centerY = self.gridY + 1;
		var minI = Math.floor(centerX - rangeRadius - 0.5);
		var maxI = Math.ceil(centerX + rangeRadius + 0.5);
		var minJ = Math.floor(centerY - rangeRadius - 0.5);
		var maxJ = Math.ceil(centerY + rangeRadius + 0.5);
		for (var i = minI; i <= maxI; i++) {
			for (var j = minJ; j <= maxJ; j++) {
				var closestX = Math.max(i, Math.min(centerX, i + 1));
				var closestY = Math.max(j, Math.min(centerY, j + 1));
				var deltaX = closestX - centerX;
				var deltaY = closestY - centerY;
				var distanceSquared = deltaX * deltaX + deltaY * deltaY;
				if (distanceSquared <= rangeRadius * rangeRadius) {
					var cell = grid.getCell(i, j);
					if (cell) {
						self.cellsInRange.push(cell);
						cell.towersInRange.push(self);
					}
				}
			}
		}
		grid.renderDebug();
	};
	self.getTotalValue = function () {
		var baseTowerCost = getTowerCost(self.id);
		var totalInvestment = baseTowerCost;
		var baseUpgradeCost = baseTowerCost; // Upgrade cost now scales with base tower cost
		for (var i = 1; i < self.level; i++) {
			totalInvestment += Math.floor(baseUpgradeCost * Math.pow(2, i - 1));
		}
		return totalInvestment;
	};
	self.upgrade = function () {
		if (self.level < self.maxLevel) {
			// Exponential upgrade cost: base cost * (2 ^ (level-1)), scaled by tower base cost
			var baseUpgradeCost = getTowerCost(self.id);
			var upgradeCost;
			// Make last upgrade level extra expensive
			if (self.level === self.maxLevel - 1) {
				upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.level - 1) * 3.5 / 2); // Half the cost for final upgrade
			} else {
				upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.level - 1));
			}
			if (gold >= upgradeCost) {
				setGold(gold - upgradeCost);
				self.level++;
				// Increase tower health by 50% on upgrade
				self.maxHealth = Math.floor(self.maxHealth * 1.5);
				self.health = self.maxHealth; // Restore to full health on upgrade
				// No need to update self.range here; getRange() is now the source of truth
				// Apply tower-specific upgrades based on type
				var fireRateMultiplier = futuristicUnlocked ? 1 / 3 : 1;
				if (self.id === 'rapid') {
					if (self.level === self.maxLevel) {
						// Extra powerful last upgrade (double the effect)
						self.fireRate = Math.max(4, 30 - self.level * 9) * fireRateMultiplier; // double the effect
						self.damage = 5 + self.level * 10; // double the effect
						self.bulletSpeed = 7 + self.level * 2.4; // double the effect
					} else {
						self.fireRate = Math.max(15, 30 - self.level * 3) * fireRateMultiplier; // Fast tower gets faster with upgrades
						self.damage = 5 + self.level * 3;
						self.bulletSpeed = 7 + self.level * 0.7;
					}
				} else {
					if (self.level === self.maxLevel) {
						// Extra powerful last upgrade for all other towers (double the effect)
						self.fireRate = Math.max(5, 60 - self.level * 24) * fireRateMultiplier; // double the effect
						self.damage = 10 + self.level * 20; // double the effect
						self.bulletSpeed = 5 + self.level * 2.4; // double the effect
					} else {
						self.fireRate = Math.max(20, 60 - self.level * 8) * fireRateMultiplier;
						self.damage = 10 + self.level * 5;
						self.bulletSpeed = 5 + self.level * 0.5;
					}
				}
				self.refreshCellsInRange();
				self.updateLevelIndicators();
				if (self.level > 1) {
					var levelDot = levelIndicators[self.level - 1].children[1];
					tween(levelDot, {
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 300,
						easing: tween.elasticOut,
						onFinish: function onFinish() {
							tween(levelDot, {
								scaleX: 1,
								scaleY: 1
							}, {
								duration: 200,
								easing: tween.easeOut
							});
						}
					});
				}
				return true;
			} else {
				var notification = game.addChild(new Notification("Not enough gold to upgrade!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 50;
				return false;
			}
		}
		return false;
	};
	self.findTarget = function () {
		var closestEnemy = null;
		var closestScore = Infinity;
		for (var i = 0; i < enemies.length; i++) {
			var enemy = enemies[i];
			var dx = enemy.x - self.x;
			var dy = enemy.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			// Check if enemy is in range
			if (distance <= self.getRange()) {
				// Artillery towers can target all enemy types
				if (self.id === 'splash') {
					// Handle flying enemies differently - they can be targeted regardless of path
					if (enemy.isFlying) {
						// For flying enemies, prioritize by distance to the goal
						if (enemy.flyingTarget) {
							var goalX = enemy.flyingTarget.x;
							var goalY = enemy.flyingTarget.y;
							var distToGoal = Math.sqrt((goalX - enemy.cellX) * (goalX - enemy.cellX) + (goalY - enemy.cellY) * (goalY - enemy.cellY));
							// Use distance to goal as score
							if (distToGoal < closestScore) {
								closestScore = distToGoal;
								closestEnemy = enemy;
							}
						} else {
							// If no flying target yet (shouldn't happen), prioritize by distance to tower
							if (distance < closestScore) {
								closestScore = distance;
								closestEnemy = enemy;
							}
						}
					} else {
						// For ground enemies, use the original path-based targeting
						// Get the cell for this enemy
						var cell = grid.getCell(enemy.cellX, enemy.cellY);
						if (cell && cell.pathId === pathId) {
							// Use the cell's score (distance to exit) for prioritization
							// Lower score means closer to exit
							if (cell.score < closestScore) {
								closestScore = cell.score;
								closestEnemy = enemy;
							}
						}
					}
				} else {
					// Other towers can target both flying and ground enemies
					// Handle flying enemies differently - they can be targeted regardless of path
					if (enemy.isFlying) {
						// For flying enemies, prioritize by distance to the goal
						if (enemy.flyingTarget) {
							var goalX = enemy.flyingTarget.x;
							var goalY = enemy.flyingTarget.y;
							var distToGoal = Math.sqrt((goalX - enemy.cellX) * (goalX - enemy.cellX) + (goalY - enemy.cellY) * (goalY - enemy.cellY));
							// Use distance to goal as score
							if (distToGoal < closestScore) {
								closestScore = distToGoal;
								closestEnemy = enemy;
							}
						} else {
							// If no flying target yet (shouldn't happen), prioritize by distance to tower
							if (distance < closestScore) {
								closestScore = distance;
								closestEnemy = enemy;
							}
						}
					} else {
						// For ground enemies, use the original path-based targeting
						// Get the cell for this enemy
						var cell = grid.getCell(enemy.cellX, enemy.cellY);
						if (cell && cell.pathId === pathId) {
							// Use the cell's score (distance to exit) for prioritization
							// Lower score means closer to exit
							if (cell.score < closestScore) {
								closestScore = cell.score;
								closestEnemy = enemy;
							}
						}
					}
				}
			}
		}
		if (!closestEnemy) {
			self.targetEnemy = null;
		}
		return closestEnemy;
	};
	self.update = function () {
		// Money tower gold generation
		if (self.isMoney) {
			// Only generate gold if game has started and is not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				self.goldTimer += gameSpeed;
				if (self.goldTimer >= self.goldInterval) {
					self.goldTimer = 0;
					setGold(gold + 10);
					var goldIndicator = new GoldIndicator(10, self.x, self.y);
					game.addChild(goldIndicator);
				}
			}
		}
		// Miner functionality for sniper tower in builds set (ultra mode)
		if (self.towerSet === 'builds' && self.id === 'sniper' && gameSettings.difficulty === 'ultra') {
			// Only generate ore if game has started and is not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				self.goldTimer += gameSpeed;
				if (self.goldTimer >= 600) {
					// 10 seconds at 60 FPS
					self.goldTimer = 0;
					ore += 1;
					var oreIndicator = new GoldIndicator("1 Ore", self.x, self.y);
					game.addChild(oreIndicator);
					updateUI();
				}
			}
		}
		// Farm functionality for rapid tower in builds set
		if (self.towerSet === 'builds' && self.id === 'rapid') {
			// Only generate gold if game has started and is not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				self.goldTimer += gameSpeed;
				if (self.goldTimer >= 600) {
					// 10 seconds at 60 FPS
					self.goldTimer = 0;
					setGold(gold + 2);
					var goldIndicator = new GoldIndicator(2, self.x, self.y);
					game.addChild(goldIndicator);
				}
			}
		}
		// Upgrader functionality for builds set (Build5/Upgrader)
		if (self.towerSet === 'builds' && self.id === 'slow') {
			// Set range to match Archer (sniper) tower
			self.getRange = function () {
				// Archer base: 5 + (level-1)*0.8, but use maxLevel for Upgrader
				var baseRange = (5 + (self.level - 1) * 0.8) * CELL_SIZE;
				return baseRange;
			};
			// --- NEW: Instantly increase level by 1 for all towers in range for free ---
			if (!self._upgraderBuffedTowers) self._upgraderBuffedTowers = [];
			// Only activate if game started and not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				// Find all towers in range that haven't been buffed by this Upgrader
				for (var i = 0; i < towers.length; i++) {
					var t = towers[i];
					if (t !== self && self.isInRange(t)) {
						if (!t._upgradedByUpgrader) t._upgradedByUpgrader = [];
						if (t._upgradedByUpgrader.indexOf(self) === -1) {
							// Only buff if not at max level
							if (t.level < t.maxLevel) {
								t.level += 1;
								t.updateLevelIndicators && t.updateLevelIndicators();
								t._upgradedByUpgrader.push(self);
								self._upgraderBuffedTowers.push(t);
							}
						}
					}
				}
			}
		}
		// Smith (Build6) functionality for builds set
		if (self.towerSet === 'builds' && self.id === 'poison') {
			// Set range to match Archer (sniper) tower
			self.getRange = function () {
				var baseRange = (5 + (self.level - 1) * 0.8) * CELL_SIZE;
				return baseRange;
			};
			// --- NEW: Double maxHealth of towers in range, fully heal every 5s, remove on destroy ---
			if (!self._smithBuffedTowers) self._smithBuffedTowers = [];
			// Only activate if game started and not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				// Double maxHealth of towers in range (only once per tower)
				for (var i = 0; i < towers.length; i++) {
					var t = towers[i];
					if (t !== self && self.isInRange(t)) {
						if (!t._smithBuffedBy) t._smithBuffedBy = [];
						if (t._smithBuffedBy.indexOf(self) === -1) {
							t.maxHealth = t.maxHealth * 2;
							t.health = t.maxHealth;
							t._smithBuffedBy.push(self);
							self._smithBuffedTowers.push(t);
							if (t.towerHealthBar) t.towerHealthBar.width = 70;
						}
					}
				}
				// Every 5 seconds, fully heal towers in range
				if (typeof self.smithHealTimer === "undefined") self.smithHealTimer = 0;
				self.smithHealTimer += gameSpeed;
				if (self.smithHealTimer >= 300) {
					// 5 seconds at 60 FPS
					self.smithHealTimer = 0;
					var healed = false;
					for (var i = 0; i < towers.length; i++) {
						var t = towers[i];
						if (t !== self && self.isInRange(t)) {
							if (t.health < t.maxHealth) {
								t.health = t.maxHealth;
								if (t.towerHealthBar) t.towerHealthBar.width = 70;
								healed = true;
							}
						}
					}
					if (healed) {
						var note = game.addChild(new Notification("Smith: Towers in range fully healed!"));
						note.x = 2048 / 2;
						note.y = grid.height - 60;
					}
				}
			}
		}
		// Research functionality - unlocks futuristic towers when built
		if (self.towerSet === 'builds' && self.id === 'splash') {
			// This is Research - it unlocks futuristic towers immediately when built
			if (!futuristicUnlocked) {
				futuristicUnlocked = true;
				var notification = game.addChild(new Notification("Futuristic towers unlocked!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 150;
				// Update all existing towers to benefit from futuristic unlock
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					// Apply 3x fire rate boost to all existing towers
					tower.fireRate = tower.fireRate / 3;
					// Refresh range for slow and poison towers (now cover entire map)
					if (tower.id === 'slow' || tower.id === 'poison') {
						tower.refreshCellsInRange();
					}
				}
			}
		}
		// House functionality for builds in ultra mode
		if (self.towerSet === 'builds' && self.id === 'default' && gameSettings.difficulty === 'ultra') {
			// This is a house - it provides 3 workers when built
			// Workers are added when house is placed, not over time
		}
		// Trapper tower enemy detection and damage
		if (self.isTrapper) {
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				var dx = enemy.x - self.x;
				var dy = enemy.y - self.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				if (distance <= CELL_SIZE && !enemy.trappedBy) {
					enemy.trappedBy = self;
					// Damage all enemies in range when triggered
					for (var j = 0; j < enemies.length; j++) {
						var rangeEnemy = enemies[j];
						var rangeDx = rangeEnemy.x - self.x;
						var rangeDy = rangeEnemy.y - self.y;
						var rangeDistance = Math.sqrt(rangeDx * rangeDx + rangeDy * rangeDy);
						if (rangeDistance <= self.getRange()) {
							var damage = 0;
							if (rangeEnemy.isImmune) {
								// Immune enemies take full health damage
								damage = rangeEnemy.health;
							} else {
								// Regular enemies take 25% damage
								damage = Math.ceil(rangeEnemy.health * 0.25);
							}
							rangeEnemy.health -= damage;
							if (rangeEnemy.health <= 0) {
								rangeEnemy.health = 0;
							} else {
								rangeEnemy.healthBar.width = rangeEnemy.health / rangeEnemy.maxHealth * 70;
							}
						}
					}
					// Destroy trapper after use
					self.health = 0;
					break;
				}
			}
		}
		// Update tower health bar
		if (self.health <= 0) {
			// Healer towers are immune to destruction
			if (self.id === 'poison') {
				self.health = self.maxHealth; // Reset to full health
				self.towerHealthBar.width = 70; // Full health bar
			} else {
				self.health = 0;
				self.towerHealthBar.width = 0;
				// Destroy tower when health reaches zero
				// Remove from cells in range
				for (var i = 0; i < self.cellsInRange.length; i++) {
					var cell = self.cellsInRange[i];
					var towerIndex = cell.towersInRange.indexOf(self);
					if (towerIndex !== -1) {
						cell.towersInRange.splice(towerIndex, 1);
					}
				}
				// Reset grid cells to floor (if not castle walls)
				for (var i = 0; i < 2; i++) {
					for (var j = 0; j < 2; j++) {
						var cell = grid.getCell(self.gridX + i, self.gridY + j);
						if (cell && cell.type !== 4) {
							cell.type = 0;
						}
					}
				}
				// Remove Upgrader/Smith effects from towers in range if this is Upgrader or Smith
				if (self.towerSet === 'builds' && (self.id === 'slow' || self.id === 'poison')) {
					for (var i = 0; i < towers.length; i++) {
						var t = towers[i];
						if (t !== self) {
							// If Upgrader: revert level if it was increased by this Upgrader
							if (self.id === 'slow' && t._upgradedByUpgrader && t._upgradedByUpgrader.indexOf(self) !== -1) {
								if (t.level > 1) {
									t.level -= 1;
									t.updateLevelIndicators && t.updateLevelIndicators();
								}
								// Remove this Upgrader from the list
								var idx = t._upgradedByUpgrader.indexOf(self);
								if (idx !== -1) t._upgradedByUpgrader.splice(idx, 1);
							}
							// If Smith: revert maxHealth and health if it was buffed by this Smith
							if (self.id === 'poison' && t._smithBuffedBy && t._smithBuffedBy.indexOf(self) !== -1) {
								t.maxHealth = t.maxHealth / 2;
								if (t.health > t.maxHealth) t.health = t.maxHealth;
								if (t.towerHealthBar) t.towerHealthBar.width = t.health / t.maxHealth * 70;
								// Remove this Smith from the buffedBy list
								var sidx = t._smithBuffedBy.indexOf(self);
								if (sidx !== -1) t._smithBuffedBy.splice(sidx, 1);
							}
						}
					}
					// Clean up Upgrader/Smith's buffed towers list
					if (self._upgraderBuffedTowers) self._upgraderBuffedTowers = [];
					if (self._smithBuffedTowers) self._smithBuffedTowers = [];
				}
				// Check if this is Research being destroyed - lock futuristic towers and remove existing ones
				if (self.towerSet === 'builds' && self.id === 'splash') {
					// This is Research being destroyed - lock futuristic towers
					futuristicUnlocked = false;
					// Remove all existing futuristic towers and refund their cost
					for (var i = towers.length - 1; i >= 0; i--) {
						var tower = towers[i];
						if (tower.towerSet === 'futuristic') {
							// Calculate refund value
							var totalInvestment = tower.getTotalValue ? tower.getTotalValue() : 0;
							var refundValue = getTowerSellValue(totalInvestment);
							setGold(gold + refundValue);
							// Remove from cells in range
							for (var j = 0; j < tower.cellsInRange.length; j++) {
								var cell = tower.cellsInRange[j];
								var towerIndex = cell.towersInRange.indexOf(tower);
								if (towerIndex !== -1) {
									cell.towersInRange.splice(towerIndex, 1);
								}
							}
							// Reset grid cells to floor (if not castle walls)
							for (var gx = 0; gx < 2; gx++) {
								for (var gy = 0; gy < 2; gy++) {
									var cell = grid.getCell(tower.gridX + gx, tower.gridY + gy);
									if (cell && cell.type !== 4) {
										cell.type = 0;
									}
								}
							}
							// Clear selected tower if this was selected
							if (selectedTower === tower) {
								selectedTower = null;
							}
							// Remove from towers array
							var towerArrayIndex = towers.indexOf(tower);
							if (towerArrayIndex !== -1) {
								towers.splice(towerArrayIndex, 1);
							}
							// Remove from game
							tower.destroy();
						}
					}
					// Switch back to medieval towers if currently on futuristic
					if (towerSet === 'futuristic') {
						towerSet = 'medieval';
						updateSourceTowers();
						medievalBG.tint = 0x8B4513;
						medievalBG.alpha = 0.5;
						futuristicBG.tint = 0x222222;
						futuristicBG.alpha = 0.5;
					}
					var notification = game.addChild(new Notification("Research destroyed! Futuristic towers locked and removed!"));
					notification.x = 2048 / 2;
					notification.y = grid.height - 100;
				}
				// Remove tower from towers array
				var towerIndex = towers.indexOf(self);
				if (towerIndex !== -1) {
					towers.splice(towerIndex, 1);
				}
				// Clear selected tower if this was selected
				if (selectedTower === self) {
					selectedTower = null;
				}
				// Remove tower from game
				self.destroy();
				// Update pathfinding
				grid.pathFind();
				grid.renderDebug();
				return;
			}
		} else {
			self.towerHealthBar.width = self.health / self.maxHealth * 70;
		}
		self.targetEnemy = self.findTarget();
		if (self.targetEnemy) {
			var dx = self.targetEnemy.x - self.x;
			var dy = self.targetEnemy.y - self.y;
			var angle = Math.atan2(dy, dx);
			// Only rotate gun container if this is not a Trecher tower or Healer tower
			if (self.id !== 'slow' && self.id !== 'poison') {
				gunContainer.rotation = angle;
			}
			// Check if this tower is affected by any Trecher towers
			var effectiveFireRate = self.fireRate;
			if (self.id !== 'slow') {
				// Trechers don't boost themselves
				for (var i = 0; i < towers.length; i++) {
					var tower = towers[i];
					if (tower.id === 'slow' && tower.isInRange(self)) {
						effectiveFireRate = self.fireRate * 0.5; // 50% faster firing (half the fire rate delay)
						break;
					}
				}
			}
			// Apply Austrian empire bonus: 20% faster fire rate (20% less delay)
			if (gameSettings.selectedEmpire === 'Austria') {
				effectiveFireRate = effectiveFireRate * 0.8; // 20% faster firing
			}
			if (LK.ticks - self.lastFired >= effectiveFireRate / gameSpeed) {
				self.fire();
				self.lastFired = LK.ticks;
			}
		}
	};
	self.down = function (x, y, obj) {
		var existingMenus = game.children.filter(function (child) {
			return child instanceof UpgradeMenu;
		});
		var hasOwnMenu = false;
		var rangeCircle = null;
		for (var i = 0; i < game.children.length; i++) {
			if (game.children[i].isTowerRange && game.children[i].tower === self) {
				rangeCircle = game.children[i];
				break;
			}
		}
		for (var i = 0; i < existingMenus.length; i++) {
			if (existingMenus[i].tower === self) {
				hasOwnMenu = true;
				break;
			}
		}
		if (hasOwnMenu) {
			for (var i = 0; i < existingMenus.length; i++) {
				if (existingMenus[i].tower === self) {
					hideUpgradeMenu(existingMenus[i]);
				}
			}
			if (rangeCircle) {
				game.removeChild(rangeCircle);
			}
			selectedTower = null;
			grid.renderDebug();
			return;
		}
		for (var i = 0; i < existingMenus.length; i++) {
			existingMenus[i].destroy();
		}
		for (var i = game.children.length - 1; i >= 0; i--) {
			if (game.children[i].isTowerRange) {
				game.removeChild(game.children[i]);
			}
		}
		selectedTower = self;
		var rangeIndicator = new Container();
		rangeIndicator.isTowerRange = true;
		rangeIndicator.tower = self;
		game.addChild(rangeIndicator);
		rangeIndicator.x = self.x;
		rangeIndicator.y = self.y;
		var rangeGraphics = rangeIndicator.attachAsset('rangeCircle', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		rangeGraphics.width = rangeGraphics.height = self.getRange() * 2;
		rangeGraphics.alpha = 0.3;
		var upgradeMenu = new UpgradeMenu(self);
		game.addChild(upgradeMenu);
		upgradeMenu.x = 2048 / 2;
		tween(upgradeMenu, {
			y: 2732 - 225
		}, {
			duration: 200,
			easing: tween.backOut
		});
		grid.renderDebug();
	};
	self.isInRange = function (enemy) {
		if (!enemy) {
			return false;
		}
		var dx = enemy.x - self.x;
		var dy = enemy.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		return distance <= self.getRange();
	};
	self.fire = function () {
		// Trecher towers don't fire bullets - they only provide support effects
		if (self.id === 'slow') {
			return;
		}
		// Healer towers don't fire bullets - they only provide healing/protection effects
		if (self.id === 'poison') {
			return;
		}
		// Trench towers don't fire bullets - they only provide support effects
		if (self.towerSet === 'trench') {
			return;
		}
		// Builds towers (house, Farm, build 3,4,5,6) don't fire bullets
		if (self.towerSet === 'builds') {
			return;
		}
		if (self.targetEnemy) {
			var potentialDamage = 0;
			for (var i = 0; i < self.targetEnemy.bulletsTargetingThis.length; i++) {
				potentialDamage += self.targetEnemy.bulletsTargetingThis[i].damage;
			}
			if (self.targetEnemy.health > potentialDamage) {
				var bulletX = self.x + Math.cos(gunContainer.rotation) * 40;
				var bulletY = self.y + Math.sin(gunContainer.rotation) * 40;
				var bulletDamage = self.damage;
				// Apply Ottoman empire bonus: 20% more damage
				if (gameSettings.selectedEmpire === 'Ottoman') {
					bulletDamage = Math.ceil(bulletDamage * 1.2); // 20% more damage
				}
				var bullet = new Bullet(bulletX, bulletY, self.targetEnemy, bulletDamage, self.bulletSpeed);
				// Set bullet type based on tower type
				bullet.type = self.id;
				// Customize bullet appearance based on tower type
				switch (self.id) {
					case 'rapid':
						bullet.children[0].tint = 0x00AAFF;
						bullet.children[0].width = 20;
						bullet.children[0].height = 20;
						break;
					case 'sniper':
						bullet.children[0].tint = 0xFF5500;
						bullet.children[0].width = 15;
						bullet.children[0].height = 15;
						break;
					case 'splash':
						bullet.children[0].tint = 0x33CC00;
						bullet.children[0].width = 40;
						bullet.children[0].height = 40;
						break;
					case 'poison':
						bullet.children[0].tint = 0x00FFAA;
						bullet.children[0].width = 35;
						bullet.children[0].height = 35;
						break;
				}
				game.addChild(bullet);
				bullets.push(bullet);
				self.targetEnemy.bulletsTargetingThis.push(bullet);
				// --- Fire recoil effect for gunContainer ---
				// Stop any ongoing recoil tweens before starting a new one
				tween.stop(gunContainer, {
					x: true,
					y: true,
					scaleX: true,
					scaleY: true
				});
				// Always use the original resting position for recoil, never accumulate offset
				if (gunContainer._restX === undefined) {
					gunContainer._restX = 0;
				}
				if (gunContainer._restY === undefined) {
					gunContainer._restY = 0;
				}
				if (gunContainer._restScaleX === undefined) {
					gunContainer._restScaleX = 1;
				}
				if (gunContainer._restScaleY === undefined) {
					gunContainer._restScaleY = 1;
				}
				// Reset to resting position before animating (in case of interrupted tweens)
				gunContainer.x = gunContainer._restX;
				gunContainer.y = gunContainer._restY;
				gunContainer.scaleX = gunContainer._restScaleX;
				gunContainer.scaleY = gunContainer._restScaleY;
				// Calculate recoil offset (recoil back along the gun's rotation)
				var recoilDistance = 8;
				var recoilX = -Math.cos(gunContainer.rotation) * recoilDistance;
				var recoilY = -Math.sin(gunContainer.rotation) * recoilDistance;
				// Animate recoil back from the resting position
				tween(gunContainer, {
					x: gunContainer._restX + recoilX,
					y: gunContainer._restY + recoilY
				}, {
					duration: 60,
					easing: tween.cubicOut,
					onFinish: function onFinish() {
						// Animate return to original position/scale
						tween(gunContainer, {
							x: gunContainer._restX,
							y: gunContainer._restY
						}, {
							duration: 90,
							easing: tween.cubicIn
						});
					}
				});
			}
		}
	};
	self.placeOnGrid = function (gridX, gridY) {
		self.gridX = gridX;
		self.gridY = gridY;
		self.x = grid.x + gridX * CELL_SIZE + CELL_SIZE / 2;
		self.y = grid.y + gridY * CELL_SIZE + CELL_SIZE / 2;
		for (var i = 0; i < 2; i++) {
			for (var j = 0; j < 2; j++) {
				var cell = grid.getCell(gridX + i, gridY + j);
				if (cell) {
					// All towers block enemy movement except Trapper
					if (self.isTrapper) {
						// Trapper allows enemies to pass through
						cell.type = 0;
					} else {
						// All other structures block enemy movement
						cell.type = 1;
					}
				}
			}
		}
		self.refreshCellsInRange();
		// Completely destroy and recreate tower preview when tower is successfully placed
		if (towerPreview && towerPreview.parent) {
			game.removeChild(towerPreview);
			towerPreview.destroy();
			towerPreview = new TowerPreview();
			towerPreview.visible = false;
		}
	};
	return self;
});
var TowerPreview = Container.expand(function () {
	var self = Container.call(this);
	var towerRange = 3;
	var rangeInPixels = towerRange * CELL_SIZE;
	self.towerType = 'default';
	self.hasEnoughGold = true;
	var rangeIndicator = new Container();
	self.addChild(rangeIndicator);
	var rangeGraphics = rangeIndicator.attachAsset('rangeCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	rangeGraphics.alpha = 0.3;
	var previewGraphics = self.attachAsset(towerSet === 'futuristic' ? 'futurep' : towerSet === 'trench' ? 'builds' : towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'Farmland' : 'builds' : 'rare', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	previewGraphics.width = CELL_SIZE * 2;
	previewGraphics.height = CELL_SIZE * 2;
	self.canPlace = false;
	self.gridX = 0;
	self.gridY = 0;
	self.blockedByEnemy = false;
	self.update = function () {
		var previousHasEnoughGold = self.hasEnoughGold;
		var towerOreCost = getTowerOreCost(self.towerType);
		self.hasEnoughGold = gold >= getTowerCost(self.towerType) && ore >= towerOreCost;
		// Only update appearance if the affordability status has changed
		if (previousHasEnoughGold !== self.hasEnoughGold) {
			self.updateAppearance();
		}
	};
	self.updateAppearance = function () {
		// Use Tower class to get the source of truth for range
		var tempTower = new Tower(self.towerType);
		var previewRange = tempTower.getRange();
		// Clean up tempTower to avoid memory leaks
		if (tempTower && tempTower.destroy) {
			tempTower.destroy();
		}
		// Set range indicator using unified range logic
		rangeGraphics.width = rangeGraphics.height = previewRange * 2;
		switch (self.towerType) {
			case 'rapid':
				previewGraphics.tint = 0x00AAFF;
				break;
			case 'sniper':
				previewGraphics.tint = 0xFF5500;
				break;
			case 'splash':
				previewGraphics.tint = 0x33CC00;
				break;
			case 'slow':
				previewGraphics.tint = 0x9900FF;
				break;
			case 'poison':
				previewGraphics.tint = 0x00FFAA;
				break;
			default:
				previewGraphics.tint = 0xAAAAAA;
		}
		if (!self.canPlace || !self.hasEnoughGold) {
			previewGraphics.tint = 0xFF0000;
		}
	};
	self.updatePlacementStatus = function () {
		var validGridPlacement = true;
		if (self.gridY <= 4 || self.gridY + 1 >= grid.cells[0].length - 4) {
			validGridPlacement = false;
		} else {
			for (var i = 0; i < 2; i++) {
				for (var j = 0; j < 2; j++) {
					var cell = grid.getCell(self.gridX + i, self.gridY + j);
					// Allow placement only on regular floor (type 0)
					if (!cell || cell.type !== 0) {
						validGridPlacement = false;
						break;
					}
				}
				if (!validGridPlacement) {
					break;
				}
			}
		}
		self.blockedByEnemy = false;
		if (validGridPlacement) {
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				if (enemy.currentCellY < 4) {
					continue;
				}
				// Only check non-flying enemies, flying enemies can pass over towers
				if (!enemy.isFlying) {
					if (enemy.cellX >= self.gridX && enemy.cellX < self.gridX + 2 && enemy.cellY >= self.gridY && enemy.cellY < self.gridY + 2) {
						self.blockedByEnemy = true;
						break;
					}
					if (enemy.currentTarget) {
						var targetX = enemy.currentTarget.x;
						var targetY = enemy.currentTarget.y;
						if (targetX >= self.gridX && targetX < self.gridX + 2 && targetY >= self.gridY && targetY < self.gridY + 2) {
							self.blockedByEnemy = true;
							break;
						}
					}
				}
			}
		}
		self.canPlace = validGridPlacement && !self.blockedByEnemy;
		self.hasEnoughGold = gold >= getTowerCost(self.towerType);
		self.updateAppearance();
	};
	self.checkPlacement = function () {
		self.updatePlacementStatus();
	};
	self.snapToGrid = function (x, y) {
		var gridPosX = x - grid.x;
		var gridPosY = y - grid.y;
		self.gridX = Math.floor(gridPosX / CELL_SIZE);
		self.gridY = Math.floor(gridPosY / CELL_SIZE);
		self.x = grid.x + self.gridX * CELL_SIZE + CELL_SIZE / 2;
		self.y = grid.y + self.gridY * CELL_SIZE + CELL_SIZE / 2;
		self.checkPlacement();
	};
	return self;
});
var Tutorial = Container.expand(function (difficulty) {
	var self = Container.call(this);
	self.difficulty = difficulty;
	self.currentStep = 0;
	self.tutorialSteps = [];
	self.isActive = false;
	// Tutorial overlay background
	var tutorialOverlay = self.attachAsset('notification', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	tutorialOverlay.width = 2048;
	tutorialOverlay.height = 2732;
	tutorialOverlay.tint = 0x000000;
	tutorialOverlay.alpha = 0.7;
	// Tutorial text box
	var textBox = new Container();
	var textBG = textBox.attachAsset('menu', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	textBG.width = 1600;
	textBG.height = 400;
	textBG.alpha = 0.95;
	var tutorialText = new Text2("", {
		size: 60,
		fill: 0xFFFFFF,
		weight: 600
	});
	tutorialText.anchor.set(0.5, 0.5);
	textBox.addChild(tutorialText);
	textBox.x = 0;
	textBox.y = -200;
	self.addChild(textBox);
	// Next button
	var nextButton = new Container();
	var nextBG = nextButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	nextBG.width = 300;
	nextBG.height = 100;
	nextBG.tint = 0x00AA00;
	var nextText = new Text2("Next", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	nextText.anchor.set(0.5, 0.5);
	nextButton.addChild(nextText);
	nextButton.x = 0;
	nextButton.y = 150;
	nextButton.down = function () {
		self.nextStep();
	};
	self.addChild(nextButton);
	// Define tutorial steps based on difficulty
	if (difficulty === 'easy') {
		self.tutorialSteps = [{
			text: "Welcome to HONORBOUND!\nThis is Easy Mode - perfect for learning.\nTowers cost 50% less and enemies are easier.",
			indicator: {
				x: 0,
				y: 0,
				visible: false
			}
		}, {
			text: "This is your gold (top right).\nYou spend gold to build towers.\nYou earn gold by defeating enemies.",
			indicator: {
				x: 1500,
				y: -1200,
				visible: true
			}
		}, {
			text: "These are your lives (top left).\nYou lose lives when enemies reach the bottom.\nDon't let them reach zero!",
			indicator: {
				x: -1500,
				y: -1200,
				visible: true
			}
		}, {
			text: "These are tower types you can build.\nDrag them onto the battlefield to place towers.\nEach has different abilities and costs.",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Advanced Technology: Futuristic towers unlock\nat wave 4. They have\n3x faster fire rate and\nspecial abilities. Robot, Lazerer,\nEaglebot, Fwacha, f-Bullet, Hospital.",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Click 'Start Game' to begin the first wave.\nEnemies will spawn from the top and try to reach the bottom.",
			indicator: {
				x: 0,
				y: 800,
				visible: true
			}
		}, {
			text: "Good luck, Commander!\nBuild towers to stop the enemies.\nUpgrade towers by clicking on them.",
			indicator: {
				x: 0,
				y: 0,
				visible: false
			}
		}];
	} else {
		self.tutorialSteps = [{
			text: "Welcome to HONORBOUND!\nYou are the last defender of the empire.\nStop the advancing enemies at all costs!",
			indicator: {
				x: 0,
				y: 0,
				visible: false
			}
		}, {
			text: "Gold (top right) is your main resource.\nSpend it wisely on towers and upgrades.\nEarn more by defeating enemies.",
			indicator: {
				x: 1500,
				y: -1200,
				visible: true
			}
		}, {
			text: "Lives (top left) represent your defenses.\nEach enemy that escapes costs 1 life.\nBoss enemies cost more lives!",
			indicator: {
				x: -1500,
				y: -1200,
				visible: true
			}
		}, {
			text: "Tower Selection: Drag towers to build them.\nInfantry: Balanced • Catapult: Fast\nArcher: Long range • Hwacha: Area damage",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Advanced towers: Bullet (slows enemies)\nHealer (protects nearby towers)\nClick built towers to upgrade them.",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Speed Control (top center): Adjust game speed.\nMusic Control: Change background music.\nUse these to manage your strategy.",
			indicator: {
				x: 0,
				y: -1200,
				visible: true
			}
		}, {
			text: "Futuristic Technology: At wave 4,\nunlock advanced towers! Robot, Lazerer,\nEaglebot, Fwacha, f-Bullet, Hospital.\nThey fire 3x faster\nwith special abilities.",
			indicator: {
				x: 0,
				y: 1200,
				visible: true
			}
		}, {
			text: "Wave System: Enemies come in waves.\nEach wave gets stronger.\nPrepare defenses between waves!",
			indicator: {
				x: 0,
				y: 800,
				visible: true
			}
		}, {
			text: "Strategic Tips:\n• Block enemy paths with towers\n• Upgrade key towers\n• Use terrain to your advantage",
			indicator: {
				x: 0,
				y: 0,
				visible: false
			}
		}, {
			text: "The fate of the empire rests with you!\nClick 'Start Game' when ready.\nMay victory be yours, Commander!",
			indicator: {
				x: 0,
				y: 800,
				visible: true
			}
		}];
	}
	self.startTutorial = function () {
		self.isActive = true;
		self.currentStep = 0;
		self.showCurrentStep();
	};
	self.showCurrentStep = function () {
		if (self.currentStep >= self.tutorialSteps.length) {
			self.endTutorial();
			return;
		}
		var step = self.tutorialSteps[self.currentStep];
		tutorialText.setText(step.text);
		// Remove existing indicators
		for (var i = self.children.length - 1; i >= 0; i--) {
			if (self.children[i].isTutorialIndicator) {
				self.removeChild(self.children[i]);
			}
		}
		// Add indicators based on tutorial step
		if (self.difficulty === 'easy') {
			if (self.currentStep === 1) {
				// Gold instruction
				var goldIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				goldIndicator.x = 500;
				goldIndicator.y = -1150;
				goldIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 2) {
				// Lives instruction  
				var livesIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				livesIndicator.x = -500;
				livesIndicator.y = -1150;
				livesIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 4) {
				// Futuristic towers instruction
				var futuristicIndicator = self.attachAsset('isaret2', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				futuristicIndicator.x = 0;
				futuristicIndicator.y = 1050;
				futuristicIndicator.isTutorialIndicator = true;
			}
		} else {
			// Normal difficulty
			if (self.currentStep === 1) {
				// Gold instruction
				var goldIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				goldIndicator.x = 500;
				goldIndicator.y = -1150;
				goldIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 2) {
				// Lives instruction
				var livesIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				livesIndicator.x = -500;
				livesIndicator.y = -1150;
				livesIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 5) {
				// Speed Control and Music instruction
				var speedIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				speedIndicator.x = -100;
				speedIndicator.y = -1150;
				speedIndicator.isTutorialIndicator = true;
				var musicIndicator = self.attachAsset('isaret', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				musicIndicator.x = 100;
				musicIndicator.y = -1150;
				musicIndicator.isTutorialIndicator = true;
			} else if (self.currentStep === 6) {
				// Futuristic towers instruction
				var futuristicIndicator = self.attachAsset('isaret2', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				futuristicIndicator.x = 0;
				futuristicIndicator.y = 1050;
				futuristicIndicator.isTutorialIndicator = true;
			}
		}
		// Update next button text
		if (self.currentStep === self.tutorialSteps.length - 1) {
			nextText.setText("Start!");
		} else {
			nextText.setText("Next");
		}
	};
	self.nextStep = function () {
		self.currentStep++;
		if (self.currentStep >= self.tutorialSteps.length) {
			self.endTutorial();
		} else {
			self.showCurrentStep();
		}
	};
	self.endTutorial = function () {
		self.isActive = false;
		// Mark tutorial as completed and save to storage
		storage.tutorialCompleted = true;
		// Remove any tutorial indicators
		for (var i = self.children.length - 1; i >= 0; i--) {
			if (self.children[i].isTutorialIndicator) {
				self.removeChild(self.children[i]);
			}
		}
		self.destroy();
		// Return to main menu after tutorial completion
		var mainMenu = new MainMenu();
		game.addChild(mainMenu);
	};
	return self;
});
var UpgradeMenu = Container.expand(function (tower) {
	var self = Container.call(this);
	self.tower = tower;
	self.y = 2732 + 225;
	var menuBackground = self.attachAsset('menu', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	menuBackground.width = 2048;
	menuBackground.height = 500;
	menuBackground.alpha = 0.9;
	var towerDisplayName = self.tower.id === 'default' ? self.tower.towerSet === 'futuristic' ? 'Robot' : self.tower.towerSet === 'trench' ? 'Blocker' : self.tower.towerSet === 'builds' ? gameSettings.difficulty === 'ultra' ? 'House' : 'Build1' : 'Infantry' : self.tower.id === 'rapid' ? self.tower.towerSet === 'futuristic' ? 'Lazerer' : self.tower.towerSet === 'trench' ? 'Trapper' : self.tower.towerSet === 'builds' ? 'Farm' : 'Catapult' : self.tower.id === 'splash' ? self.tower.towerSet === 'futuristic' ? 'Fwacha' : self.tower.towerSet === 'builds' ? 'Research' : 'Hwacha' : self.tower.id === 'sniper' ? self.tower.towerSet === 'futuristic' ? 'Eaglebot' : self.tower.towerSet === 'trench' ? 'Money' : self.tower.towerSet === 'builds' ? 'Miner' : 'Archer' : self.tower.id === 'slow' ? self.tower.towerSet === 'futuristic' ? 'f-Bullet' : self.tower.towerSet === 'builds' ? 'Upgrader' : 'Bullet' : self.tower.id === 'poison' ? self.tower.towerSet === 'futuristic' ? 'Hospital' : self.tower.towerSet === 'builds' ? 'Smith' : 'Healer' : self.tower.id.charAt(0).toUpperCase() + self.tower.id.slice(1);
	var towerTypeText = new Text2(towerDisplayName + ' Tower', {
		size: 80,
		fill: 0xFFFFFF,
		weight: 800
	});
	towerTypeText.anchor.set(0, 0);
	towerTypeText.x = -840;
	towerTypeText.y = -160;
	self.addChild(towerTypeText);
	var statsText = new Text2('Level: ' + self.tower.level + '/' + self.tower.maxLevel + '\nDamage: ' + self.tower.damage + '\nFire Rate: ' + (60 / self.tower.fireRate).toFixed(1) + '/s', {
		size: 70,
		fill: 0xFFFFFF,
		weight: 400
	});
	statsText.anchor.set(0, 0.5);
	statsText.x = -840;
	statsText.y = 50;
	self.addChild(statsText);
	var buttonsContainer = new Container();
	buttonsContainer.x = 500;
	self.addChild(buttonsContainer);
	var upgradeButton = new Container();
	buttonsContainer.addChild(upgradeButton);
	var buttonBackground = upgradeButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	buttonBackground.width = 500;
	buttonBackground.height = 150;
	var isMaxLevel = self.tower.level >= self.tower.maxLevel;
	// Exponential upgrade cost: base cost * (2 ^ (level-1)), scaled by tower base cost
	var baseUpgradeCost = getTowerCost(self.tower.id);
	var upgradeCost;
	if (isMaxLevel) {
		upgradeCost = 0;
	} else if (self.tower.level === self.tower.maxLevel - 1) {
		upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1) * 3.5 / 2);
	} else {
		upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1));
	}
	buttonBackground.tint = isMaxLevel ? 0x888888 : gold >= upgradeCost ? 0x00AA00 : 0x888888;
	var buttonText = new Text2(isMaxLevel ? 'Max Level' : 'Upgrade: ' + upgradeCost + ' gold', {
		size: 60,
		fill: 0xFFFFFF,
		weight: 800
	});
	buttonText.anchor.set(0.5, 0.5);
	upgradeButton.addChild(buttonText);
	var sellButton = new Container();
	buttonsContainer.addChild(sellButton);
	var sellButtonBackground = sellButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	sellButtonBackground.width = 500;
	sellButtonBackground.height = 150;
	sellButtonBackground.tint = 0xCC0000;
	var totalInvestment = self.tower.getTotalValue ? self.tower.getTotalValue() : 0;
	var sellValue = getTowerSellValue(totalInvestment);
	var sellButtonText = new Text2('Sell: +' + sellValue + ' gold', {
		size: 60,
		fill: 0xFFFFFF,
		weight: 800
	});
	sellButtonText.anchor.set(0.5, 0.5);
	sellButton.addChild(sellButtonText);
	upgradeButton.y = -85;
	sellButton.y = 85;
	var closeButton = new Container();
	self.addChild(closeButton);
	var closeBackground = closeButton.attachAsset('Buton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	closeBackground.width = 90;
	closeBackground.height = 90;
	closeBackground.tint = 0xAA0000;
	var closeText = new Text2('X', {
		size: 68,
		fill: 0xFFFFFF,
		weight: 800
	});
	closeText.anchor.set(0.5, 0.5);
	closeButton.addChild(closeText);
	closeButton.x = menuBackground.width / 2 - 57;
	closeButton.y = -menuBackground.height / 2 + 57;
	upgradeButton.down = function (x, y, obj) {
		if (self.tower.level >= self.tower.maxLevel) {
			var notification = game.addChild(new Notification("Tower is already at max level!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
			return;
		}
		if (self.tower.upgrade()) {
			// Exponential upgrade cost: base cost * (2 ^ (level-1)), scaled by tower base cost
			var baseUpgradeCost = getTowerCost(self.tower.id);
			if (self.tower.level >= self.tower.maxLevel) {
				upgradeCost = 0;
			} else if (self.tower.level === self.tower.maxLevel - 1) {
				upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1) * 3.5 / 2);
			} else {
				upgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1));
			}
			statsText.setText('Level: ' + self.tower.level + '/' + self.tower.maxLevel + '\nDamage: ' + self.tower.damage + '\nFire Rate: ' + (60 / self.tower.fireRate).toFixed(1) + '/s');
			buttonText.setText('Upgrade: ' + upgradeCost + ' gold');
			var totalInvestment = self.tower.getTotalValue ? self.tower.getTotalValue() : 0;
			var sellValue = Math.floor(totalInvestment * 0.6);
			sellButtonText.setText('Sell: +' + sellValue + ' gold');
			if (self.tower.level >= self.tower.maxLevel) {
				buttonBackground.tint = 0x888888;
				buttonText.setText('Max Level');
			}
			var rangeCircle = null;
			for (var i = 0; i < game.children.length; i++) {
				if (game.children[i].isTowerRange && game.children[i].tower === self.tower) {
					rangeCircle = game.children[i];
					break;
				}
			}
			if (rangeCircle) {
				var rangeGraphics = rangeCircle.children[0];
				rangeGraphics.width = rangeGraphics.height = self.tower.getRange() * 2;
			} else {
				var newRangeIndicator = new Container();
				newRangeIndicator.isTowerRange = true;
				newRangeIndicator.tower = self.tower;
				game.addChildAt(newRangeIndicator, 0);
				newRangeIndicator.x = self.tower.x;
				newRangeIndicator.y = self.tower.y;
				var rangeGraphics = newRangeIndicator.attachAsset('rangeCircle', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				rangeGraphics.width = rangeGraphics.height = self.tower.getRange() * 2;
				rangeGraphics.alpha = 0.3;
			}
			tween(self, {
				scaleX: 1.05,
				scaleY: 1.05
			}, {
				duration: 100,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					tween(self, {
						scaleX: 1,
						scaleY: 1
					}, {
						duration: 100,
						easing: tween.easeIn
					});
				}
			});
		}
	};
	sellButton.down = function (x, y, obj) {
		var totalInvestment = self.tower.getTotalValue ? self.tower.getTotalValue() : 0;
		var sellValue = getTowerSellValue(totalInvestment);
		setGold(gold + sellValue);
		var notification = game.addChild(new Notification("Tower sold for " + sellValue + " gold!"));
		notification.x = 2048 / 2;
		notification.y = grid.height - 50;
		// Handle population logic for houses in ultra mode
		if (gameSettings.difficulty === 'ultra' && self.tower.towerSet === 'builds' && self.tower.id === 'default') {
			// This was a house - reduce population by 1000
			population = Math.max(0, population - 1000);
			var popNotification = game.addChild(new Notification("-1000 population"));
			popNotification.x = 2048 / 2;
			popNotification.y = grid.height - 100;
		}
		updateUI();
		var gridX = self.tower.gridX;
		var gridY = self.tower.gridY;
		for (var i = 0; i < 2; i++) {
			for (var j = 0; j < 2; j++) {
				var cell = grid.getCell(gridX + i, gridY + j);
				if (cell) {
					// Only reset to floor if it's not a castle wall
					if (cell.type !== 4) {
						cell.type = 0;
					}
					var towerIndex = cell.towersInRange.indexOf(self.tower);
					if (towerIndex !== -1) {
						cell.towersInRange.splice(towerIndex, 1);
					}
				}
			}
		}
		if (selectedTower === self.tower) {
			selectedTower = null;
		}
		var towerIndex = towers.indexOf(self.tower);
		if (towerIndex !== -1) {
			towers.splice(towerIndex, 1);
		}
		towerLayer.removeChild(self.tower);
		grid.pathFind();
		grid.renderDebug();
		self.destroy();
		for (var i = 0; i < game.children.length; i++) {
			if (game.children[i].isTowerRange && game.children[i].tower === self.tower) {
				game.removeChild(game.children[i]);
				break;
			}
		}
	};
	closeButton.down = function (x, y, obj) {
		hideUpgradeMenu(self);
		selectedTower = null;
		grid.renderDebug();
	};
	self.update = function () {
		if (self.tower.level >= self.tower.maxLevel) {
			if (buttonText.text !== 'Max Level') {
				buttonText.setText('Max Level');
				buttonBackground.tint = 0x888888;
			}
			return;
		}
		// Exponential upgrade cost: base cost * (2 ^ (level-1)), scaled by tower base cost
		var baseUpgradeCost = getTowerCost(self.tower.id);
		var currentUpgradeCost;
		if (self.tower.level >= self.tower.maxLevel) {
			currentUpgradeCost = 0;
		} else if (self.tower.level === self.tower.maxLevel - 1) {
			currentUpgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1) * 3.5 / 2);
		} else {
			currentUpgradeCost = Math.floor(baseUpgradeCost * Math.pow(2, self.tower.level - 1));
		}
		var canAfford = gold >= currentUpgradeCost;
		buttonBackground.tint = canAfford ? 0x00AA00 : 0x888888;
		var newText = 'Upgrade: ' + currentUpgradeCost + ' gold';
		if (buttonText.text !== newText) {
			buttonText.setText(newText);
		}
	};
	return self;
});
var WaveIndicator = Container.expand(function () {
	var self = Container.call(this);
	self.gameStarted = false;
	self.waveMarkers = [];
	self.waveTypes = [];
	self.enemyCounts = [];
	self.indicatorWidth = 0;
	self.lastBossType = null; // Track the last boss type to avoid repeating
	var blockWidth = 400;
	var totalBlocksWidth = blockWidth * totalWaves;
	var startMarker = new Container();
	var startBlock = startMarker.attachAsset('hi', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	startBlock.width = blockWidth - 10;
	startBlock.height = 70 * 2;
	startBlock.tint = 0x00AA00;
	// Add shadow for start text
	var startTextShadow = new Text2("Start Game", {
		size: 50,
		fill: 0x000000,
		weight: 800
	});
	startTextShadow.anchor.set(0.5, 0.5);
	startTextShadow.x = 4;
	startTextShadow.y = 4;
	startMarker.addChild(startTextShadow);
	var startText = new Text2("Start Game", {
		size: 50,
		fill: 0xFFFFFF,
		weight: 800
	});
	startText.anchor.set(0.5, 0.5);
	startMarker.addChild(startText);
	startMarker.x = -self.indicatorWidth;
	self.addChild(startMarker);
	self.waveMarkers.push(startMarker);
	startMarker.down = function () {
		// Block game start if difficulty not selected
		if (!gameStartAllowed) {
			return;
		}
		if (!self.gameStarted) {
			self.gameStarted = true;
			currentWave = 0;
			waveTimer = nextWaveTime;
			startBlock.tint = 0x00FF00;
			startText.setText("Started!");
			startTextShadow.setText("Started!");
			// Make sure shadow position remains correct after text change
			startTextShadow.x = 4;
			startTextShadow.y = 4;
			// Reset to medieval towers at game start
			if (towerSet === 'futuristic') {
				towerSet = 'medieval';
				updateSourceTowers();
				medievalBG.tint = 0x8B4513;
				medievalBG.alpha = 0.5; // Keep transparency
				futuristicBG.tint = 0x222222;
				futuristicBG.alpha = 0.5; // Keep transparency
			}
			var notification = game.addChild(new Notification("Game started! Wave 1 incoming!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 150;
			// Start music when game begins
			LK.playMusic('warmusic');
		}
	};
	for (var i = 0; i < totalWaves; i++) {
		var marker = new Container();
		var block = marker.attachAsset('hi', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		block.width = blockWidth - 10;
		block.height = 70 * 2;
		// All waves are normal enemy waves
		var waveType = "Dawn";
		var enemyType = "normal";
		var enemyCount = 10;
		block.tint = 0xAAAAAA;
		// Store the wave type and enemy count
		self.waveTypes[i] = enemyType;
		self.enemyCounts[i] = enemyCount;
		// Add shadow for wave type - 30% smaller than before
		var waveTypeShadow = new Text2(waveType, {
			size: 56,
			fill: 0x000000,
			weight: 800
		});
		waveTypeShadow.anchor.set(0.5, 0.5);
		waveTypeShadow.x = 4;
		waveTypeShadow.y = 4;
		marker.addChild(waveTypeShadow);
		// Add wave type text - 30% smaller than before
		var waveTypeText = new Text2(waveType, {
			size: 56,
			fill: 0xFFFFFF,
			weight: 800
		});
		waveTypeText.anchor.set(0.5, 0.5);
		waveTypeText.y = 0;
		marker.addChild(waveTypeText);
		// Add shadow for wave number - 20% larger than before
		var waveNumShadow = new Text2((i + 1).toString(), {
			size: 48,
			fill: 0x000000,
			weight: 800
		});
		waveNumShadow.anchor.set(1.0, 1.0);
		waveNumShadow.x = blockWidth / 2 - 16 + 5;
		waveNumShadow.y = block.height / 2 - 12 + 5;
		marker.addChild(waveNumShadow);
		// Main wave number text - 20% larger than before
		var waveNum = new Text2((i + 1).toString(), {
			size: 48,
			fill: 0xFFFFFF,
			weight: 800
		});
		waveNum.anchor.set(1.0, 1.0);
		waveNum.x = blockWidth / 2 - 16;
		waveNum.y = block.height / 2 - 12;
		marker.addChild(waveNum);
		marker.x = -self.indicatorWidth + (i + 1) * blockWidth;
		self.addChild(marker);
		self.waveMarkers.push(marker);
	}
	// Get wave type for a specific wave number
	self.getWaveType = function (waveNumber) {
		if (waveNumber < 1 || waveNumber > totalWaves) {
			return "normal";
		}
		// If this is a boss wave (waveNumber % 10 === 0), and the type is the same as lastBossType
		// then we should return a different boss type
		var waveType = self.waveTypes[waveNumber - 1];
		return waveType;
	};
	// Get enemy count for a specific wave number
	self.getEnemyCount = function (waveNumber) {
		if (waveNumber < 1 || waveNumber > totalWaves) {
			return 10;
		}
		return self.enemyCounts[waveNumber - 1];
	};
	// Get display name for a wave type
	self.getWaveTypeName = function (waveNumber) {
		var type = self.getWaveType(waveNumber);
		var typeName = type.charAt(0).toUpperCase() + type.slice(1);
		// Boss spawning disabled - no boss prefix for waves 10, 20, 30
		// if (waveNumber % 10 === 0 && waveNumber > 0 && type !== 'swarm') {
		//     typeName = "BOSS";
		// }
		return typeName;
	};
	self.positionIndicator = new Container();
	var indicator = self.positionIndicator.attachAsset('towerLevelIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	indicator.width = blockWidth - 10;
	indicator.height = 16;
	indicator.tint = 0xffad0e;
	indicator.y = -65;
	var indicator2 = self.positionIndicator.attachAsset('towerLevelIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	indicator2.width = blockWidth - 10;
	indicator2.height = 16;
	indicator2.tint = 0xffad0e;
	indicator2.y = 65;
	var leftWall = self.positionIndicator.attachAsset('towerLevelIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	leftWall.width = 16;
	leftWall.height = 146;
	leftWall.tint = 0xffad0e;
	leftWall.x = -(blockWidth - 16) / 2;
	var rightWall = self.positionIndicator.attachAsset('towerLevelIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	rightWall.width = 16;
	rightWall.height = 146;
	rightWall.tint = 0xffad0e;
	rightWall.x = (blockWidth - 16) / 2;
	self.addChild(self.positionIndicator);
	self.update = function () {
		var progress = waveTimer / nextWaveTime;
		var moveAmount = (progress + currentWave) * blockWidth;
		for (var i = 0; i < self.waveMarkers.length; i++) {
			var marker = self.waveMarkers[i];
			marker.x = -moveAmount + i * blockWidth;
		}
		self.positionIndicator.x = 0;
		for (var i = 0; i < totalWaves + 1; i++) {
			var marker = self.waveMarkers[i];
			if (i === 0) {
				continue;
			}
			var block = marker.children[0];
			// Only apply red tint after game has started
			if (self.gameStarted) {
				if (i - 1 < currentWave) {
					// Completed waves: red tint with reduced alpha
					block.alpha = .5;
					tween(block, {
						tint: 0xFF0000
					}, {
						duration: 300,
						easing: tween.easeOut
					});
				}
			}
		}
		self.handleWaveProgression = function () {
			if (!self.gameStarted) {
				return;
			}
			// Skip wave progression when game is paused (gameSpeed = 0)
			if (gameSpeed === 0) {
				return;
			}
			if (currentWave < totalWaves) {
				waveTimer += gameSpeed;
				if (waveTimer >= nextWaveTime) {
					waveTimer = 0;
					currentWave++;
					waveInProgress = true;
					waveSpawned = false;
					if (currentWave != 1) {
						var notification = game.addChild(new Notification("Wave " + currentWave + " incoming!"));
						notification.x = 2048 / 2;
						notification.y = grid.height - 150;
					}
				}
			}
		};
		self.handleWaveProgression();
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x333333
});
/**** 
* Game Code
****/ 
// Initialize gameSettings early to prevent undefined access
var gameSettings = {
	difficulty: 'normal',
	selectedEmpire: 'Normal'
};
var isHidingUpgradeMenu = false;
function hideUpgradeMenu(menu) {
	if (isHidingUpgradeMenu) {
		return;
	}
	isHidingUpgradeMenu = true;
	tween(menu, {
		y: 2732 + 225
	}, {
		duration: 150,
		easing: tween.easeIn,
		onFinish: function onFinish() {
			menu.destroy();
			isHidingUpgradeMenu = false;
		}
	});
}
var CELL_SIZE = 76;
var pathId = 1;
var maxScore = 0;
var enemies = [];
var towers = [];
var bullets = [];
var defenses = [];
var selectedTower = null;
// --- Population-based gold income for ultra mode ---
if (gameSettings.difficulty === 'ultra') {
	var populationGoldTimer = 0;
	game.update = function (origUpdate) {
		return function () {
			// Call original update
			if (typeof origUpdate === "function") origUpdate.apply(this, arguments);
			// Only run if game is started and not paused
			if (waveIndicator && waveIndicator.gameStarted && gameSpeed > 0) {
				populationGoldTimer += gameSpeed;
				if (populationGoldTimer >= 1800) {
					// 30 seconds at 60 FPS
					populationGoldTimer = 0;
					var popK = Math.floor(population / 1000);
					if (popK > 0) {
						var goldToAdd = popK * 3;
						setGold(gold + goldToAdd);
						var note = game.addChild(new Notification("+" + goldToAdd + " gold from population!"));
						note.x = 2048 / 2;
						note.y = grid.height - 180;
					}
				}
			}
		};
	}(game.update);
}
// Update gameSettings with stored values
gameSettings.difficulty = 'normal';
gameSettings.selectedEmpire = 'Normal';
var goldMines = [];
var gold = gameSettings.selectedEmpire === 'Ottoman' ? 100 : 80;
// Leaderboard system for ultra mode
var playerScore = 0;
var playerName = "";
// Leaderboard functionality removed
var leaderboardData = [];
// Population system for ultra mode
if (gameSettings.difficulty === 'ultra') {
	var population = 0; // Start with 0 population
	var ultraEnemyKills = 0;
	var ore = 0; // Ore resource for ultra mode only - starts at 0
} else {
	var population = 0;
	var ore = 0; // Initialize ore for all modes to prevent undefined
}
// Generate a new session seed on each reload/restart
var reloadCounter = 0;
reloadCounter++;
var gameSessionSeed = reloadCounter * 12345 + Math.floor(Date.now() / 1000); // Unique seed per reload
// Track if difficulty has been selected and game can start
var gameStartAllowed = false;
var lives = 10;
var currentWave = 0;
var totalWaves = gameSettings.difficulty === 'ultra' ? 30 : gameSettings.difficulty === 'hardcore' ? 10 : 5;
var waveTimer = 0;
var waveInProgress = false;
var waveSpawned = false;
var nextWaveTime = 12000 / 2;
var gameSpeed = 1.0; // 1.0 = normal, 0.5 = slow, 2.0 = fast
var gameSpeedOptions = ['slow', 'normal', 'fast', 'ultra', 'paused'];
var currentSpeedIndex = 1; // Start with normal (index 1)
var sourceTower = null;
var enemiesToSpawn = 10; // Default number of enemies per wave
var goldText = new Text2('Gold: ' + gold, {
	size: 60,
	fill: 0xFFD700,
	weight: 800
});
goldText.anchor.set(0.5, 0.5);
var livesText = new Text2('Lives: ' + lives, {
	size: 60,
	fill: 0x00FF00,
	weight: 800
});
livesText.anchor.set(0.5, 0.5);
var populationText = new Text2('Population: ' + population, {
	size: 60,
	fill: 0x00FFFF,
	weight: 800
});
populationText.anchor.set(0.5, 0.5);
var oreText = new Text2('Ore: ' + ore, {
	size: 60,
	fill: 0x888888,
	weight: 800
});
oreText.anchor.set(0.5, 0.5);
var topMargin = 50;
var centerX = 2048 / 2;
var spacing = 400;
// Hide these elements initially in menu
goldText.visible = false;
livesText.visible = false;
LK.gui.top.addChild(goldText);
LK.gui.top.addChild(livesText);
// Only show populationText in ultra mode
if (gameSettings.difficulty === 'ultra') {
	LK.gui.top.addChild(populationText);
	LK.gui.top.addChild(oreText);
	populationText.x = spacing;
	populationText.y = topMargin + 80; // Position below gold
	populationText.visible = true;
	oreText.x = spacing;
	oreText.y = topMargin + 160; // Position below population text
	oreText.visible = true;
} else {
	populationText.visible = false;
	oreText.visible = false;
}
livesText.x = -spacing;
livesText.y = topMargin;
goldText.x = spacing;
goldText.y = topMargin;
function updateTotalWaves() {
	totalWaves = gameSettings.difficulty === 'ultra' ? 30 : gameSettings.difficulty === 'hardcore' ? 10 : 5;
	// Recreate wave indicator with correct number of waves
	if (waveIndicator && waveIndicator.parent) {
		waveIndicator.parent.removeChild(waveIndicator);
		waveIndicator.destroy();
	}
	waveIndicator = new WaveIndicator();
	waveIndicator.x = 2048 / 2;
	waveIndicator.y = 2732 - 80;
	game.addChild(waveIndicator);
}
function updateUI() {
	goldText.setText('Gold: ' + gold);
	livesText.setText('Lives: ' + lives);
	if (gameSettings.difficulty === 'ultra') {
		// Ensure population and ore UI elements are added to GUI if not already present
		if (!populationText.parent) {
			LK.gui.top.addChild(populationText);
			populationText.x = spacing;
			populationText.y = topMargin + 80;
		}
		if (!oreText.parent) {
			LK.gui.top.addChild(oreText);
			oreText.x = spacing;
			oreText.y = topMargin + 160;
		}
		populationText.setText('Population: ' + population);
		oreText.setText('Ore: ' + ore);
		populationText.visible = true;
		oreText.visible = true;
	} else {
		populationText.visible = false;
		oreText.visible = false;
	}
}
function setGold(value) {
	gold = value;
	updateUI();
}
function addScore(points) {
	if (gameSettings.difficulty === 'ultra') {
		playerScore += points;
	}
}
var debugLayer = new Container();
var towerLayer = new Container();
// Create three separate layers for enemy hierarchy
var enemyLayerBottom = new Container(); // For normal enemies
var enemyLayerMiddle = new Container(); // For shadows
var enemyLayerTop = new Container(); // For flying enemies
var enemyLayer = new Container(); // Main container to hold all enemy layers
// Add layers in correct order (bottom first, then middle for shadows, then top)
enemyLayer.addChild(enemyLayerBottom);
enemyLayer.addChild(enemyLayerMiddle);
enemyLayer.addChild(enemyLayerTop);
// Create background tile grid (12x15)
var backgroundContainer = new Container();
var bgTileWidth = 2048 / 12; // Divide screen width by 12
var bgTileHeight = 2732 / 15; // Divide screen height by 15
for (var row = 0; row < 15; row++) {
	for (var col = 0; col < 12; col++) {
		var bgTile = backgroundContainer.attachAsset('background', {
			anchorX: 0,
			anchorY: 0,
			width: bgTileWidth,
			height: bgTileHeight
		});
		bgTile.x = col * bgTileWidth;
		bgTile.y = row * bgTileHeight;
	}
}
// Add background container first (behind everything else)
game.addChild(backgroundContainer);
var grid = new Grid(24, 29 + 6);
grid.x = 150;
grid.y = 200 - CELL_SIZE * 4;
grid.pathFind();
grid.renderDebug();
debugLayer.addChild(grid);
game.addChild(debugLayer);
game.addChild(towerLayer);
game.addChild(enemyLayer);
var offset = 0;
var towerPreview = new TowerPreview();
game.addChild(towerPreview);
towerPreview.visible = false;
var isDragging = false;
function wouldBlockPath(gridX, gridY) {
	// Trapper towers don't block paths
	if (towerPreview && towerPreview.towerType === 'rapid' && towerSet === 'trench') {
		return false;
	}
	var cells = [];
	for (var i = 0; i < 2; i++) {
		for (var j = 0; j < 2; j++) {
			var cell = grid.getCell(gridX + i, gridY + j);
			if (cell) {
				cells.push({
					cell: cell,
					originalType: cell.type
				});
				cell.type = 1;
			}
		}
	}
	var blocked = grid.pathFind();
	for (var i = 0; i < cells.length; i++) {
		cells[i].cell.type = cells[i].originalType;
	}
	grid.pathFind();
	grid.renderDebug();
	return blocked;
}
function getTowerCost(towerType) {
	var cost = 10;
	switch (towerType) {
		case 'rapid':
			// Different costs for trench vs medieval/futuristic
			if (towerSet === 'trench') {
				cost = 50; // Trapper cost
			} else {
				cost = 30; // Original catapult cost
			}
			break;
		case 'sniper':
			// Different costs for trench vs medieval/futuristic
			if (towerSet === 'trench') {
				cost = 120; // Money tower cost
			} else {
				cost = 50; // Original archer cost
			}
			break;
		case 'splash':
			cost = 50;
			break;
		case 'slow':
			cost = gameSettings.difficulty === 'hardcore' ? 100 : 50;
			break;
		case 'poison':
			cost = gameSettings.difficulty === 'hardcore' ? 100 : 50;
			break;
	}
	// Apply Easy mode discount
	if (gameSettings.difficulty === 'easy') {
		cost = Math.floor(cost / 2);
	}
	// Apply Hungary empire bonus: 5 gold less on normal and higher difficulties
	if (gameSettings.selectedEmpire === 'Hungary' && gameSettings.difficulty !== 'easy') {
		cost = Math.max(5, cost - 5); // Minimum cost of 5 gold
	}
	// Apply Scotch empire bonus: 3 gold less for all towers
	if (gameSettings.selectedEmpire === 'Scotch') {
		cost = Math.max(5, cost - 3); // Minimum cost of 5 gold
	}
	// Remove price doubling - research no longer increases costs
	return cost;
}
function getTowerOreCost(towerType) {
	// Upgrader (Build5) in builds set always costs 10 ore in ultra mode
	if (towerSet === 'builds' && gameSettings.difficulty === 'ultra' && towerType === 'slow') {
		return 10;
	}
	// Smith (Build6) in builds set always costs 15 ore in ultra mode
	if (towerSet === 'builds' && gameSettings.difficulty === 'ultra' && towerType === 'poison') {
		return 15;
	}
	// Only futuristic towers in ultra mode require ore
	if (towerSet === 'futuristic' && gameSettings.difficulty === 'ultra') {
		switch (towerType) {
			case 'default':
				return 5;
			case 'rapid':
				return 3;
			case 'sniper':
				return 8;
			case 'splash':
				return 7;
			case 'slow':
				return 6;
			case 'poison':
				return 9;
			default:
				return 5;
		}
	}
	return 0;
}
function getTowerSellValue(totalValue) {
	return waveIndicator && waveIndicator.gameStarted ? Math.floor(totalValue * 0.6) : totalValue;
}
function placeTower(gridX, gridY, towerType) {
	var towerCost = getTowerCost(towerType);
	var towerOreCost = getTowerOreCost(towerType);
	if (gold >= towerCost && ore >= towerOreCost) {
		// Check if this is a house (Build1 in Ultra mode)
		var isHouse = towerSet === 'builds' && towerType === 'default' && gameSettings.difficulty === 'ultra';
		var tower = new Tower(towerType || 'default');
		tower.placeOnGrid(gridX, gridY);
		towerLayer.addChild(tower);
		towers.push(tower);
		setGold(gold - towerCost);
		ore -= towerOreCost;
		// Handle population logic only in ultra mode
		if (gameSettings.difficulty === 'ultra') {
			if (isHouse) {
				// Each house gives 1000 population
				population += 1000;
				var note = game.addChild(new Notification("+1000 population!"));
				note.x = 2048 / 2;
				note.y = grid.height - 100;
			}
		}
		updateUI();
		grid.pathFind();
		grid.renderDebug();
		return true;
	} else {
		var notification = game.addChild(new Notification("Not enough gold!"));
		notification.x = 2048 / 2;
		notification.y = grid.height - 50;
		return false;
	}
}
game.down = function (x, y, obj) {
	// Block all interactions if difficulty not selected
	if (!gameStartAllowed) {
		return;
	}
	var upgradeMenuVisible = game.children.some(function (child) {
		return child instanceof UpgradeMenu;
	});
	if (upgradeMenuVisible) {
		return;
	}
	for (var i = 0; i < sourceTowers.length; i++) {
		var tower = sourceTowers[i];
		if (x >= tower.x - tower.width / 2 && x <= tower.x + tower.width / 2 && y >= tower.y - tower.height / 2 && y <= tower.y + tower.height / 2) {
			// Completely recreate tower preview to ensure clean state
			if (towerPreview && towerPreview.parent) {
				game.removeChild(towerPreview);
				towerPreview.destroy();
			}
			towerPreview = new TowerPreview();
			game.addChild(towerPreview);
			towerPreview.visible = true;
			isDragging = true;
			towerPreview.towerType = tower.towerType;
			towerPreview.updateAppearance();
			// Apply the same offset as in move handler to ensure consistency when starting drag
			towerPreview.snapToGrid(x, y - CELL_SIZE * 1.5);
			break;
		}
	}
};
game.move = function (x, y, obj) {
	// Block all interactions if difficulty not selected
	if (!gameStartAllowed) {
		return;
	}
	if (isDragging) {
		// Shift the y position upward by 1.5 tiles to show preview above finger
		towerPreview.snapToGrid(x, y - CELL_SIZE * 1.5);
	}
};
game.up = function (x, y, obj) {
	// Block all interactions if difficulty not selected
	if (!gameStartAllowed) {
		return;
	}
	var clickedOnTower = false;
	for (var i = 0; i < towers.length; i++) {
		var tower = towers[i];
		var towerLeft = tower.x - tower.width / 2;
		var towerRight = tower.x + tower.width / 2;
		var towerTop = tower.y - tower.height / 2;
		var towerBottom = tower.y + tower.height / 2;
		if (x >= towerLeft && x <= towerRight && y >= towerTop && y <= towerBottom) {
			clickedOnTower = true;
			break;
		}
	}
	var upgradeMenus = game.children.filter(function (child) {
		return child instanceof UpgradeMenu;
	});
	if (upgradeMenus.length > 0 && !isDragging && !clickedOnTower) {
		var clickedOnMenu = false;
		for (var i = 0; i < upgradeMenus.length; i++) {
			var menu = upgradeMenus[i];
			var menuWidth = 2048;
			var menuHeight = 450;
			var menuLeft = menu.x - menuWidth / 2;
			var menuRight = menu.x + menuWidth / 2;
			var menuTop = menu.y - menuHeight / 2;
			var menuBottom = menu.y + menuHeight / 2;
			if (x >= menuLeft && x <= menuRight && y >= menuTop && y <= menuBottom) {
				clickedOnMenu = true;
				break;
			}
		}
		if (!clickedOnMenu) {
			for (var i = 0; i < upgradeMenus.length; i++) {
				var menu = upgradeMenus[i];
				hideUpgradeMenu(menu);
			}
			for (var i = game.children.length - 1; i >= 0; i--) {
				if (game.children[i].isTowerRange) {
					game.removeChild(game.children[i]);
				}
			}
			selectedTower = null;
			grid.renderDebug();
		}
	}
	if (isDragging) {
		isDragging = false;
		if (towerPreview.canPlace) {
			if (!wouldBlockPath(towerPreview.gridX, towerPreview.gridY)) {
				placeTower(towerPreview.gridX, towerPreview.gridY, towerPreview.towerType);
			} else {
				var notification = game.addChild(new Notification("Tower would block the path!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 50;
			}
		} else if (towerPreview.blockedByEnemy) {
			var notification = game.addChild(new Notification("Cannot build: Enemy in the way!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
		} else if (towerPreview.visible) {
			var notification = game.addChild(new Notification("Cannot build here!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
		}
		towerPreview.visible = false;
		// Completely destroy and recreate tower preview to ensure it's completely clean
		if (towerPreview.parent) {
			game.removeChild(towerPreview);
			towerPreview.destroy();
			towerPreview = new TowerPreview();
			towerPreview.visible = false;
		}
		if (isDragging) {
			var upgradeMenus = game.children.filter(function (child) {
				return child instanceof UpgradeMenu;
			});
			for (var i = 0; i < upgradeMenus.length; i++) {
				upgradeMenus[i].destroy();
			}
		}
	}
};
var waveIndicator = new WaveIndicator();
waveIndicator.x = 2048 / 2;
waveIndicator.y = 2732 - 80;
game.addChild(waveIndicator);
// Create tower set buttons first (they will be behind the menu)
// Tower set buttons are already created above
// Always show start menu at game start with PLAY button
// --- Layered, non-interactive, behind-menu text labels ---
// Create a container for background labels
var menuBackgroundLabels = new Container();
menuBackgroundLabels.x = 2048 / 2;
menuBackgroundLabels.y = 2732 / 2;
menuBackgroundLabels.alpha = 0.13; // Faint, but visible behind menu
// Helper to add a label
function addMenuBGLabel(text, x, y, size, color, rotation) {
	var label = new Text2(text, {
		size: size,
		fill: color,
		weight: 800
	});
	label.anchor.set(0.5, 0.5);
	label.x = x;
	label.y = y;
	if (rotation) label.rotation = rotation;
	label.interactive = false;
	label.buttonMode = false;
	menuBackgroundLabels.addChild(label);
}
// Add the requested labels, spaced and sized for background effect
addMenuBGLabel("Medieval", -600, -700, 220, 0x8B4513, -0.08);
addMenuBGLabel("locked", 600, -700, 180, 0x888888, 0.07);
addMenuBGLabel("Trench", -600, 0, 200, 0x8B4513, 0.05);
addMenuBGLabel("lives", 600, 0, 180, 0x00FF00, -0.06);
addMenuBGLabel("normal", -600, 700, 200, 0x0088FF, 0.08);
addMenuBGLabel("music1", 600, 700, 180, 0xFF8800, -0.07);
addMenuBGLabel("Gold", 0, 0, 300, 0xFFD700, 0);
// Place the label container behind the menu
game.addChildAt(menuBackgroundLabels, 0);
var startMenu = new StartMenu();
game.addChild(startMenu);
var speedControl = new SpeedControl();
speedControl.x = -100; // Position closer to center to be adjacent to music control
speedControl.y = topMargin;
// Hide speed control in menu initially
speedControl.visible = false;
LK.gui.top.addChild(speedControl);
var musicControl = new MusicControl();
musicControl.x = 100; // Position closer to center to be adjacent to speed control
musicControl.y = topMargin;
// Hide music control in menu initially
musicControl.visible = false;
LK.gui.top.addChild(musicControl);
// Leaderboard functionality removed
// --- Tower Set Toggle Buttons ---
var towerSet = 'medieval'; // 'medieval', 'futuristic', or 'trench'
var futuristicUnlocked = false; // Track if futuristic towers have been unlocked
// Define tower types for each set
var medievalTowerTypes = ['default', 'rapid', 'sniper', 'splash', 'slow', 'poison'];
var futuristicTowerTypes = ['default', 'rapid', 'sniper', 'splash', 'slow', 'poison']; // Placeholder, can be changed later
var trenchTowerTypes = ['default', 'rapid', 'sniper']; // Blocker, Trapper, Money
var buildsTowerTypes = ['default', 'rapid', 'sniper', 'splash', 'slow', 'poison']; // 6 build options for Ultra mode
var sourceTowers = [];
var towerSpacing = 300; // Increase spacing for larger towers
var towerY = 2732 - CELL_SIZE * 3 - 90;
// Button container - add to game so it's in front of towers
var towerSetButtonContainer = new Container();
towerSetButtonContainer.x = 2048 / 2;
// Move the button container up by the button height (100px) so the buttons are higher by their own height
towerSetButtonContainer.y = towerY - 60 - 100; // Move up by button height
game.addChild(towerSetButtonContainer);
// Move to top of display list so it's in front of towers
if (towerSetButtonContainer.parent) {
	towerSetButtonContainer.parent.removeChild(towerSetButtonContainer);
}
game.addChild(towerSetButtonContainer);
// Medieval Button
var medievalButton = new Container();
var medievalBG = medievalButton.attachAsset('Buton', {
	anchorX: 0.5,
	anchorY: 0.5
});
medievalBG.width = 350;
medievalBG.height = 100;
medievalBG.tint = 0x8B4513;
medievalBG.alpha = 0.8; // Reduce transparency
var medievalText = new Text2("Medieval", {
	size: 55,
	fill: 0xFFFFFF,
	weight: 800
});
medievalText.anchor.set(0.5, 0.5);
medievalText.alpha = 0.9; // Reduce transparency
medievalButton.addChild(medievalText);
// Arrange tower set buttons side by side, not overlapping
var buttonSpacing = 400; // Enough to avoid overlap, adjust as needed for visuals
medievalButton.x = -buttonSpacing;
medievalButton.y = 0;
medievalButton.down = function () {
	LK.getSound('Click').play();
	if (towerSet !== 'medieval') {
		towerSet = 'medieval';
		updateSourceTowers();
		medievalBG.tint = 0x8B4513;
		medievalBG.alpha = 0.8; // Reduce transparency
		futuristicBG.tint = 0x000080; // Dark blue color
		futuristicBG.alpha = 0.8; // Reduce transparency
		trenchBG.tint = 0x8B4513;
		trenchBG.alpha = 0.8; // Reduce transparency
	}
};
// Hide medieval button in menu initially
medievalButton.visible = false;
towerSetButtonContainer.addChild(medievalButton);
// Futuristic Button
var futuristicButton = new Container();
var futuristicBG = futuristicButton.attachAsset('Buton', {
	anchorX: 0.5,
	anchorY: 0.5
});
futuristicBG.width = 350;
futuristicBG.height = 100;
futuristicBG.tint = 0x000080; // Dark blue color
futuristicBG.alpha = 0.8; // Reduce transparency
var futuristicText = new Text2("Futuristic", {
	size: 55,
	fill: 0xFFFFFF,
	weight: 800
});
futuristicText.anchor.set(0.5, 0.5);
futuristicText.alpha = 0.9; // Reduce transparency
futuristicButton.addChild(futuristicText);
futuristicButton.x = 0;
futuristicButton.y = 0;
// Hide futuristic button in menu initially
futuristicButton.visible = false;
// Trench Button
var trenchButton = new Container();
var trenchBG = trenchButton.attachAsset('Buton', {
	anchorX: 0.5,
	anchorY: 0.5
});
trenchButton.x = buttonSpacing;
trenchBG.width = 350;
trenchBG.height = 100;
trenchBG.tint = 0x8B4513; // Same as medieval
trenchBG.alpha = 0.8; // Reduce transparency
var trenchText = new Text2("Builds", {
	size: 55,
	fill: 0xFFFFFF,
	weight: 800
});
trenchText.anchor.set(0.5, 0.5);
trenchText.alpha = 0.9; // Reduce transparency
trenchButton.addChild(trenchText);
trenchButton.y = 0;
futuristicButton.down = function () {
	LK.getSound('Click').play();
	// Always block futuristic towers in story mode
	if (gameSettings.storyMode) {
		var notification = game.addChild(new Notification("Futuristic towers are permanently locked in Story Mode!"));
		notification.x = 2048 / 2;
		notification.y = grid.height - 50;
		return;
	}
	// Block futuristic towers until wave 4 OR Research (Build3) is completed (except in Ultra mode)
	if (gameSettings.difficulty === 'ultra' && !futuristicUnlocked) {
		// In ultra mode, only allow if Research (Build3) is built and not destroyed
		var researchBuilt = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchBuilt = true;
				break;
			}
		}
		if (!researchBuilt) {
			var notification = game.addChild(new Notification("Futuristic towers are locked until you build Research!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
			return;
		}
	} else if (gameSettings.difficulty !== 'ultra' && currentWave < 4 && !futuristicUnlocked) {
		var notification = game.addChild(new Notification("Futuristic towers unlock at wave 4 or by building Build3!"));
		notification.x = 2048 / 2;
		notification.y = grid.height - 50;
		return;
	}
	// --- NEW: Prevent Futuristic if Research was destroyed in Ultra mode ---
	if (gameSettings.difficulty === 'ultra' && !futuristicUnlocked) {
		var researchExists = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchExists = true;
				break;
			}
		}
		if (!researchExists) {
			var notification = game.addChild(new Notification("Futuristic towers are locked until you build Research!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 50;
			return;
		}
	}
	if (towerSet !== 'futuristic') {
		towerSet = 'futuristic';
		futuristicUnlocked = true; // Mark futuristic as unlocked
		updateSourceTowers();
		medievalBG.tint = 0x000080; // Dark blue color
		medievalBG.alpha = 0.8; // Reduce transparency
		futuristicBG.tint = 0x1976D2;
		futuristicBG.alpha = 0.8; // Reduce transparency
		trenchBG.tint = 0x8B4513;
		trenchBG.alpha = 0.8; // Reduce transparency
	}
};
futuristicButton.update = function () {
	// Always show locked state in story mode
	if (gameSettings.storyMode) {
		futuristicBG.tint = 0x000080; // Dark blue when locked
		futuristicBG.alpha = 0.3; // More transparent when locked
		futuristicText.setText("Locked");
		return;
	}
	// Update button appearance based on wave progress OR Research (Build3) in Ultra mode
	if (gameSettings.difficulty === 'ultra' && !futuristicUnlocked) {
		// In ultra mode, only allow if Research (Build3) is built and not destroyed
		var researchBuilt = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchBuilt = true;
				break;
			}
		}
		if (!researchBuilt) {
			futuristicBG.tint = 0x000080; // Dark blue when locked
			futuristicBG.alpha = 0.3; // More transparent when locked
			futuristicText.setText("Locked");
			return;
		}
	}
	if (gameSettings.difficulty !== 'ultra' && currentWave < 4 && !futuristicUnlocked) {
		futuristicBG.tint = 0x000080; // Dark blue when locked
		futuristicBG.alpha = 0.3; // More transparent when locked
		futuristicText.setText("Locked");
	} else {
		if (towerSet === 'futuristic') {
			futuristicBG.tint = 0x1976D2;
		} else {
			futuristicBG.tint = 0x000080; // Dark blue when not selected
		}
		futuristicBG.alpha = 0.8; // Reduce transparency
		futuristicText.setText("Futuristic");
	}
	// --- NEW: Lock Futuristic if Research was destroyed in Ultra mode ---
	if (gameSettings.difficulty === 'ultra' && !futuristicUnlocked) {
		// If Research was destroyed, lock the button
		var researchExists = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchExists = true;
				break;
			}
		}
		if (!researchExists) {
			futuristicBG.tint = 0x000080;
			futuristicBG.alpha = 0.3;
			futuristicText.setText("Locked");
		}
	}
};
towerSetButtonContainer.addChild(futuristicButton);
trenchButton.down = function () {
	LK.getSound('Click').play();
	var targetSet = gameSettings.difficulty === 'ultra' ? 'builds' : 'trench';
	if (towerSet !== targetSet) {
		towerSet = targetSet;
		updateSourceTowers();
		medievalBG.tint = 0x8B4513;
		medievalBG.alpha = 0.8; // Reduce transparency
		futuristicBG.tint = 0x000080; // Dark blue color
		futuristicBG.alpha = 0.8; // Reduce transparency
		trenchBG.tint = 0x8B4513;
		trenchBG.alpha = 0.8; // Reduce transparency
	}
};
// Hide trench button in menu initially
trenchButton.visible = false;
towerSetButtonContainer.addChild(trenchButton);
// Helper to clear and re-create source towers
// Leaderboard input functionality removed
// Save to leaderboard functionality removed
// Show leaderboard functionality removed
function updateSourceTowers() {
	// Remove old source towers
	for (var i = 0; i < sourceTowers.length; i++) {
		if (sourceTowers[i].parent) {
			sourceTowers[i].parent.removeChild(sourceTowers[i]);
		}
		sourceTowers[i].destroy && sourceTowers[i].destroy();
	}
	sourceTowers = [];
	// Pick correct tower types
	var types = towerSet === 'medieval' ? medievalTowerTypes : towerSet === 'futuristic' ? futuristicTowerTypes : towerSet === 'trench' ? trenchTowerTypes : towerSet === 'builds' ? buildsTowerTypes : medievalTowerTypes;
	var startX = 2048 / 2 - types.length * towerSpacing / 2 + towerSpacing / 2;
	for (var i = 0; i < types.length; i++) {
		var tower = new SourceTower(types[i]);
		tower.x = startX + i * towerSpacing;
		tower.y = towerY;
		towerLayer.addChild(tower);
		sourceTowers.push(tower);
	}
}
updateSourceTowers();
sourceTower = null;
enemiesToSpawn = 10;
// Always keep tower set button container above towers visually
if (towerSetButtonContainer && towerSetButtonContainer.parent) {
	towerSetButtonContainer.parent.removeChild(towerSetButtonContainer);
	game.addChild(towerSetButtonContainer);
}
game.update = function () {
	// --- NEW: Lock futuristic towers immediately if no Research exists in ultra mode ---
	if (gameSettings.difficulty === 'ultra') {
		var researchExists = false;
		for (var i = 0; i < towers.length; i++) {
			if (towers[i].towerSet === 'builds' && towers[i].id === 'splash') {
				researchExists = true;
				break;
			}
		}
		if (!researchExists && futuristicUnlocked) {
			futuristicUnlocked = false;
			// Switch back to medieval towers if currently on futuristic
			if (towerSet === 'futuristic') {
				towerSet = 'medieval';
				updateSourceTowers();
				if (typeof medievalBG !== "undefined") {
					medievalBG.tint = 0x8B4513;
					medievalBG.alpha = 0.5;
				}
				if (typeof futuristicBG !== "undefined") {
					futuristicBG.tint = 0x222222;
					futuristicBG.alpha = 0.5;
				}
			}
		}
	}
	if (waveInProgress) {
		if (!waveSpawned) {
			waveSpawned = true;
			grid.pathFind();
			grid.renderDebug();
			// --- ULTRA MODE SPECIAL WAVES ---
			if (gameSettings.difficulty === 'ultra' && currentWave > 7) {
				// After wave 7, spawn Modern + 10 Angry + 2 Immune
				var enemyTypes = [];
				// Add 10 Angry enemies
				for (var i = 0; i < 10; i++) {
					enemyTypes.push('angry');
				}
				// Add 2 Immune enemies
				for (var i = 0; i < 2; i++) {
					enemyTypes.push('immune');
				}
				// --- Modern enemy logic for Ultra mode ---
				var modernCount = 0;
				if (currentWave % 10 === 0) {
					modernCount = 3;
				} else {
					modernCount = 1;
				}
				// Add modern enemies to the enemyTypes array
				for (var i = 0; i < modernCount; i++) {
					enemyTypes.push('modern');
				}
				// Shuffle enemyTypes for randomness
				for (var i = enemyTypes.length - 1; i > 0; i--) {
					var j = Math.floor(Math.random() * (i + 1));
					var temp = enemyTypes[i];
					enemyTypes[i] = enemyTypes[j];
					enemyTypes[j] = temp;
				}
				// Spawn enemies
				for (var i = 0; i < enemyTypes.length; i++) {
					var waveType = enemyTypes[i];
					var enemy = new Enemy(waveType);
					enemyLayerBottom.addChild(enemy);
					var healthMultiplier = Math.pow(1.12, currentWave);
					enemy.maxHealth = Math.round(enemy.maxHealth * healthMultiplier);
					enemy.health = enemy.maxHealth;
					var gridWidth = 24;
					var midPoint = Math.floor(gridWidth / 2);
					var availableColumns = [];
					for (var col = midPoint - 3; col < midPoint + 3; col++) {
						var columnOccupied = false;
						for (var e = 0; e < enemies.length; e++) {
							if (enemies[e].cellX === col && enemies[e].currentCellY < 4) {
								columnOccupied = true;
								break;
							}
						}
						if (!columnOccupied) {
							availableColumns.push(col);
						}
					}
					var spawnX;
					if (availableColumns.length > 0) {
						spawnX = availableColumns[Math.floor(Math.random() * availableColumns.length)];
					} else {
						spawnX = midPoint - 3 + Math.floor(Math.random() * 6);
					}
					var spawnY = -1 - Math.random() * 5;
					enemy.cellX = spawnX;
					enemy.cellY = 5;
					enemy.currentCellX = spawnX;
					enemy.currentCellY = spawnY;
					enemy.waveNumber = currentWave;
					enemies.push(enemy);
				}
			} else if ((gameSettings.difficulty === 'hardcore' || gameSettings.difficulty === 'ultra') && currentWave > 7) {
				// --- Modern enemy logic for Hardcore mode (and Ultra fallback for <=10) ---
				// Insert after normal spawn logic, so after all other enemies are spawned
				// This block will be reached for hardcore and for ultra waves <= 10
				// (for ultra > 10, handled above)
				// Determine how many modern enemies to spawn
				var modernCount = 0;
				if (currentWave % 10 === 0) {
					modernCount = 3;
				} else {
					modernCount = 1;
				}
				for (var m = 0; m < modernCount; m++) {
					var modernEnemy = new Enemy('modern');
					enemyLayerBottom.addChild(modernEnemy);
					var healthMultiplier = Math.pow(1.12, currentWave);
					modernEnemy.maxHealth = Math.round(modernEnemy.maxHealth * healthMultiplier);
					modernEnemy.health = modernEnemy.maxHealth;
					var gridWidth = 24;
					var midPoint = Math.floor(gridWidth / 2);
					var availableColumns = [];
					for (var col = midPoint - 3; col < midPoint + 3; col++) {
						var columnOccupied = false;
						for (var e = 0; e < enemies.length; e++) {
							if (enemies[e].cellX === col && enemies[e].currentCellY < 4) {
								columnOccupied = true;
								break;
							}
						}
						if (!columnOccupied) {
							availableColumns.push(col);
						}
					}
					var spawnX;
					if (availableColumns.length > 0) {
						spawnX = availableColumns[Math.floor(Math.random() * availableColumns.length)];
					} else {
						spawnX = midPoint - 3 + Math.floor(Math.random() * 6);
					}
					var spawnY = -1 - Math.random() * 5;
					modernEnemy.cellX = spawnX;
					modernEnemy.cellY = 5;
					modernEnemy.currentCellX = spawnX;
					modernEnemy.currentCellY = spawnY;
					modernEnemy.waveNumber = currentWave;
					enemies.push(modernEnemy);
				}
			} else {
				// --- ORIGINAL SPAWN LOGIC FOR NON-ULTRA OR <=10 ---
				// Every wave spawns 10 enemies on wave 1, then 25% more each wave
				var enemyCount = Math.floor(10 * Math.pow(1.25, currentWave - 1));
				// England empire: 3 fewer normal enemies per wave
				if (gameSettings.selectedEmpire === 'England') {
					enemyCount = Math.max(1, enemyCount - 3); // Minimum 1 enemy
				}
				// Byzantine empire: 3 more enemies per wave
				if (gameSettings.selectedEmpire === 'Byzantine') {
					enemyCount = enemyCount + 3;
				}
				// Determine flying enemy count based on wave number
				var flyingEnemyCount = 0;
				if (currentWave === 1) {
					flyingEnemyCount = 0;
				} else if (currentWave === 2) {
					flyingEnemyCount = 1;
				} else if (currentWave === 3 || currentWave === 4) {
					flyingEnemyCount = 3;
				} else if (currentWave === 5) {
					flyingEnemyCount = 5;
					enemyCount = 9; // Total enemies for wave 5
				} else if (currentWave === 6) {
					flyingEnemyCount = 0; // No flying enemies in wave 6
					enemyCount = 18; // 5 normal + 3 angry + 10 immune = 18 total enemies
				} else if (currentWave === 7) {
					flyingEnemyCount = 0; // No flying enemies in wave 7
					enemyCount = 15; // 10 angry + 5 immune = 15 total enemies
				} else if (currentWave === 8) {
					flyingEnemyCount = 0; // No flying enemies in wave 8
					enemyCount = 25; // 25 normal enemies
				} else if (currentWave === 9) {
					flyingEnemyCount = 0; // No flying enemies in wave 9
					enemyCount = 25; // 25 normal enemies
				}
				// Spawn the appropriate number of enemies
				for (var i = 0; i < enemyCount; i++) {
					// Determine enemy type based on specific wave requirements
					var waveType = 'normal'; // Default to normal
					var immuneCount = 0;
					var angryCount = 0;
					// Set specific immune enemy counts per wave
					if (currentWave === 2 || currentWave === 3 || currentWave === 4 || currentWave === 5) {
						immuneCount = 3;
					} else if (currentWave === 6) {
						immuneCount = 10; // Wave 6: 10 immune enemies
					} else if (currentWave === 7) {
						immuneCount = 5; // Wave 7: 5 immune enemies
					} else if (currentWave === 8 || currentWave === 9) {
						immuneCount = 0; // Wave 8 and 9: 0 immune enemies
					}
					// Hard mode: more immune and angry enemies
					if (gameSettings.difficulty === 'hard') {
						// Wave 1: 2 immune enemies
						if (currentWave === 1) {
							immuneCount = 2;
						}
						// Waves 2,3,4: 3 angry enemies each
						if (currentWave === 2 || currentWave === 3 || currentWave === 4) {
							angryCount = 3;
							immuneCount = 3;
						}
						// Wave 5: keep existing counts
						if (currentWave === 5) {
							angryCount = 3;
							immuneCount = 5;
						}
					} else {
						// Set angry enemy spawning: 0 in waves 1-3, 2 in waves 4-5, 3 in wave 6
						if (currentWave === 4) {
							angryCount = 2;
						} else if (currentWave === 5) {
							angryCount = 2;
						} else if (currentWave === 6) {
							angryCount = 3; // Wave 6: 3 angry enemies
						} else if (currentWave === 7) {
							angryCount = 10; // Wave 7: 10 angry enemies
						} else if (currentWave === 8 || currentWave === 9) {
							angryCount = 0; // Wave 8 and 9: 0 angry enemies
						}
					}
					// Set bad enemy spawning: only in wave 5, but not in Ultra mode
					var badCount = 0;
					if (currentWave === 5 && gameSettings.difficulty !== 'ultra') {
						badCount = 1; // 1 bad enemy - same for all empires including England
						immuneCount = 5; // 5 immune enemies
						angryCount = 3; // 3 angry enemies
					}
					// Set super enemy spawning: only in wave 10 for hardcore mode, but not in Ultra mode
					var superCount = 0;
					if (currentWave === 10 && gameSettings.difficulty === 'hardcore') {
						superCount = 0; // No super enemy in wave 10
						badCount = 3; // 3 bad enemies in wave 10
						angryCount = 0; // No angry enemies in wave 10
						immuneCount = 0; // No immune enemies in wave 10
						enemyCount = 3; // 3 bad enemies total
					}
					// Make the first 'angryCount' enemies angry for this wave
					if (i < angryCount) {
						waveType = 'angry';
					}
					// Make the next 'badCount' enemies bad for this wave (after angry enemies)
					else if (i >= angryCount && i < angryCount + badCount) {
						waveType = 'bad';
					}
					// Make the next 'superCount' enemies super for this wave (after bad enemies)
					else if (i >= angryCount + badCount && i < angryCount + badCount + superCount) {
						waveType = 'super';
					}
					// Make the last 'immuneCount' enemies immune for this wave (but not if already angry, bad, or super)
					else if (i >= enemyCount - immuneCount) {
						waveType = 'immune';
					}
					var enemy = new Enemy(waveType);
					enemyLayerBottom.addChild(enemy);
					var healthMultiplier = Math.pow(1.12, currentWave);
					enemy.maxHealth = Math.round(enemy.maxHealth * healthMultiplier);
					enemy.health = enemy.maxHealth;
					var gridWidth = 24;
					var midPoint = Math.floor(gridWidth / 2);
					var availableColumns = [];
					for (var col = midPoint - 3; col < midPoint + 3; col++) {
						var columnOccupied = false;
						for (var e = 0; e < enemies.length; e++) {
							if (enemies[e].cellX === col && enemies[e].currentCellY < 4) {
								columnOccupied = true;
								break;
							}
						}
						if (!columnOccupied) {
							availableColumns.push(col);
						}
					}
					var spawnX;
					if (availableColumns.length > 0) {
						spawnX = availableColumns[Math.floor(Math.random() * availableColumns.length)];
					} else {
						spawnX = midPoint - 3 + Math.floor(Math.random() * 6); // x from 9 to 14
					}
					var spawnY = -1 - Math.random() * 5; // Random distance above the grid for spreading
					enemy.cellX = spawnX;
					enemy.cellY = 5; // Position after entry
					enemy.currentCellX = spawnX;
					enemy.currentCellY = spawnY;
					enemy.waveNumber = currentWave;
					enemies.push(enemy);
				}
			} // end else (original spawn logic)
		}
		var currentWaveEnemiesRemaining = false;
		for (var i = 0; i < enemies.length; i++) {
			if (enemies[i].waveNumber === currentWave) {
				currentWaveEnemiesRemaining = true;
				break;
			}
		}
		if (waveSpawned && !currentWaveEnemiesRemaining) {
			waveInProgress = false;
			waveSpawned = false;
			var notification = game.addChild(new Notification("Wave " + currentWave + " completed!"));
			notification.x = 2048 / 2;
			notification.y = grid.height - 150;
			// Add 10 points for completing each wave in ultra mode
			if (gameSettings.difficulty === 'ultra') {
				addScore(10);
				// Add all enemy kills for this wave to score (already counted per kill)
				// (No extra code needed here, as kills are counted above)
			}
			// Automatically advance to next wave if all enemies are gone
			if (currentWave < totalWaves) {
				waveTimer = nextWaveTime; // Trigger next wave immediately
			}
		}
	}
	for (var a = enemies.length - 1; a >= 0; a--) {
		var enemy = enemies[a];
		if (enemy.health <= 0) {
			for (var i = 0; i < enemy.bulletsTargetingThis.length; i++) {
				var bullet = enemy.bulletsTargetingThis[i];
				bullet.targetEnemy = null;
			}
			// Give gold for every enemy killed - Hard mode gives 5 gold, others give 10
			var goldEarned = gameSettings.difficulty === 'hard' ? 5 : 10;
			var goldIndicator = new GoldIndicator(goldEarned, enemy.x, enemy.y);
			game.addChild(goldIndicator);
			setGold(gold + goldEarned);
			// Add 1 point for each enemy killed in ultra mode and count kills
			if (gameSettings.difficulty === 'ultra') {
				addScore(1);
				if (typeof ultraEnemyKills !== "undefined") {
					ultraEnemyKills++;
				}
			}
			// Add a notification for boss defeat
			if (enemy.isBoss) {
				var notification = game.addChild(new Notification("Boss defeated! +" + goldEarned + " gold!"));
				notification.x = 2048 / 2;
				notification.y = grid.height - 150;
			}
			updateUI();
			// Clean up shadow if it's a flying enemy
			if (enemy.isFlying && enemy.shadow) {
				enemyLayerMiddle.removeChild(enemy.shadow);
				enemy.shadow = null;
			}
			// Remove enemy from the appropriate layer
			if (enemy.isFlying) {
				enemyLayerTop.removeChild(enemy);
			} else {
				enemyLayerBottom.removeChild(enemy);
			}
			enemies.splice(a, 1);
			continue;
		}
		if (grid.updateEnemy(enemy)) {
			// Clean up shadow if it's a flying enemy
			if (enemy.isFlying && enemy.shadow) {
				enemyLayerMiddle.removeChild(enemy.shadow);
				enemy.shadow = null;
			}
			// Remove enemy from the appropriate layer
			if (enemy.isFlying) {
				enemyLayerTop.removeChild(enemy);
			} else {
				enemyLayerBottom.removeChild(enemy);
			}
			enemies.splice(a, 1);
			lives = Math.max(0, lives - (enemy.type === 'bad' ? 10 : 1));
			updateUI();
			if (lives <= 0) {
				LK.showGameOver();
			}
		}
	}
	for (var i = bullets.length - 1; i >= 0; i--) {
		if (!bullets[i].parent) {
			if (bullets[i].targetEnemy) {
				var targetEnemy = bullets[i].targetEnemy;
				var bulletIndex = targetEnemy.bulletsTargetingThis.indexOf(bullets[i]);
				if (bulletIndex !== -1) {
					targetEnemy.bulletsTargetingThis.splice(bulletIndex, 1);
				}
			}
			bullets.splice(i, 1);
		}
	}
	if (towerPreview.visible) {
		towerPreview.checkPlacement();
	}
	if (currentWave >= totalWaves && enemies.length === 0 && !waveInProgress) {
		LK.showYouWin();
	}
};
 
 
 White circle with two eyes, seen from above.. In-Game asset. 2d. High contrast. No shadows
 
 tower from top. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
 tower from top. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
 White simple circular enemy seen from above, black outline. Black eyes, with a single Sword in-font of it. Black and white only. Blue background.
 White simple circular enemy seen from above, black outline. Black eyes, on a white horse. Black and white only. Blue background.
 crown. In-Game asset. 2d. High contrast. No shadows
 information İ. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
 gece yarısı eski ve gerçekçi bir kale resmi. In-Game asset. 2d. High contrast
 fire in a circle. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
 money in a circle. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
 bu kulenin rasgele noktalarına parlak yeşil ışıklar ekle (duvarlarına sadece!) duvarları mavi yap
 kale olmasın. Top down bir orta çağ demirci evi olsun
 make it medieval style and not colorful
 gold mines. In-Game asset. 2d. High contrast. No shadows
 eline parlak yeşil bir kılıç ekle
 Butonun yerinde açılmış bir orta çağ stilinde bir yırtık pırtık kağıt olsun
 2 boyutlu üstten görülme bir savaş topu. In-Game asset. 2d. High contrast. No shadows
 tekerleri mavi olsun ve demir gövdenin üzerinde yeşil yeşil ışık gibi benekler olsun
 buna bir savaş topu havası kat
 realistic stone wall. In-Game asset. 2d. High contrast. No shadows
 karşıdan gözüken bir dağ. In-Game asset. 2d. High contrast. No shadows
 ağaç. In-Game asset. 2d. High contrast. No shadows
 mükemmel bir kare şeklinde olsun
 taştan değil de tahtadan olsun