/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var AttackInfo = Container.expand(function () {
	var self = Container.call(this);
	var background = self.attachAsset('bench_area_bg', {
		anchorX: 0,
		anchorY: 0,
		width: 300,
		height: 150
	});
	background.alpha = 0.8;
	self.attackerText = new Text2('', {
		size: 36,
		fill: 0xFFFFFF
	});
	self.attackerText.anchor.set(0, 0.5);
	self.attackerText.x = 10;
	self.attackerText.y = 25;
	self.addChild(self.attackerText);
	self.damageText = new Text2('', {
		size: 36,
		fill: 0xFF0000
	});
	self.damageText.anchor.set(0, 0.5);
	self.damageText.x = 10;
	self.damageText.y = 100;
	self.addChild(self.damageText);
	self.updateInfo = function (attacker, damage) {
		self.attackerText.setText('Attacker: ' + attacker);
		self.damageText.setText('Damage: ' + damage);
	};
	return self;
});
var BenchSlot = Container.expand(function (index) {
	var self = Container.call(this);
	var slotGraphics = self.attachAsset('bench_slot', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.index = index;
	self.unit = null;
	slotGraphics.alpha = 0.5;
	self.down = function (x, y, obj) {
		if (self.unit && gameState === 'planning') {
			draggedUnit = self.unit;
			// Start dragging from current position, not mouse position
			draggedUnit.x = self.x;
			draggedUnit.y = self.y;
			// Store original position and slot
			draggedUnit.originalX = self.x;
			draggedUnit.originalY = self.y;
			draggedUnit.originalSlot = self;
			// Free the bench slot immediately when dragging starts
			self.unit = null;
		}
	};
	return self;
});
var Bullet = Container.expand(function (damage, target) {
	var self = Container.call(this);
	// Default bullet type
	self.bulletType = 'default';
	self.damage = damage;
	self.target = target;
	self.speed = 8;
	// Create bullet graphics based on type
	self.createGraphics = function () {
		// Clear any existing graphics
		self.removeChildren();
		if (self.bulletType === 'arrow') {
			// Create arrow projectile
			var arrowShaft = self.attachAsset('arrow', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			// Arrow head
			var arrowHead = self.attachAsset('arrow_head', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			arrowHead.x = 15;
			arrowHead.rotation = 0.785; // 45 degrees
			// Arrow fletching
			var fletching1 = self.attachAsset('arrow_feather', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			fletching1.x = -10;
			fletching1.y = -3;
			var fletching2 = self.attachAsset('arrow_feather', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			fletching2.x = -10;
			fletching2.y = 3;
			self.speed = 10; // Arrows are faster
		} else if (self.bulletType === 'magic') {
			// Create magic projectile
			var magicCore = self.attachAsset('magic_core', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			// Magic aura
			var magicAura = self.attachAsset('magic_aura', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			magicAura.alpha = 0.5;
			// Magic sparkles
			var sparkle1 = self.attachAsset('magic_sparkle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			sparkle1.x = -10;
			sparkle1.y = -10;
			var sparkle2 = self.attachAsset('magic_sparkle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			sparkle2.x = 10;
			sparkle2.y = 10;
			// Add tween for magic glow effect
			tween(magicAura, {
				scaleX: 1.2,
				scaleY: 1.2,
				alpha: 0.3
			}, {
				duration: 300,
				easing: tween.easeInOut,
				onFinish: function onFinish() {
					tween(magicAura, {
						scaleX: 1.0,
						scaleY: 1.0,
						alpha: 0.5
					}, {
						duration: 300,
						easing: tween.easeInOut,
						onFinish: onFinish
					});
				}
			});
			self.speed = 6; // Magic is slower but more visible
		} else {
			// Default bullet
			var bulletGraphics = self.attachAsset('bullet', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		}
	};
	// Create initial graphics
	self.createGraphics();
	self.update = function () {
		if (!self.target || self.target.health <= 0) {
			self.destroy();
			return;
		}
		var dx = self.target.x - self.x;
		var dy = self.target.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < 10) {
			var killed = self.target.takeDamage(self.damage);
			if (killed) {
				// Don't give gold for killing enemies
				// Update enemies defeated count in storage
				storage.enemiesDefeated = (storage.enemiesDefeated || 0) + 1;
				LK.getSound('enemyDeath').play();
				for (var i = enemies.length - 1; i >= 0; i--) {
					if (enemies[i] === self.target) {
						// Trigger death animation instead of immediate destroy
						enemies[i].deathAnimation();
						enemies.splice(i, 1);
						break;
					}
				}
			}
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
		// Rotate arrow to face target
		if (self.bulletType === 'arrow') {
			self.rotation = Math.atan2(dy, dx);
		}
	};
	return self;
});
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	// Create pixelart enemy character
	var enemyContainer = new Container();
	self.addChild(enemyContainer);
	// Body (red goblin)
	var body = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 60;
	body.height = 60;
	body.y = 10;
	body.tint = 0xFF4444; // Red tint to match goblin theme
	// Head (darker red)
	var head = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 35
	});
	head.y = -30;
	head.tint = 0xcc0000;
	// Eyes (white dots)
	var leftEye = enemyContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 8
	});
	leftEye.x = -10;
	leftEye.y = -30;
	leftEye.tint = 0xFFFFFF;
	var rightEye = enemyContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 8
	});
	rightEye.x = 10;
	rightEye.y = -30;
	rightEye.tint = 0xFFFFFF;
	// Claws
	var leftClaw = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 15
	});
	leftClaw.x = -25;
	leftClaw.y = 5;
	leftClaw.rotation = 0.5;
	leftClaw.tint = 0x800000;
	var rightClaw = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 15
	});
	rightClaw.x = 25;
	rightClaw.y = 5;
	rightClaw.rotation = -0.5;
	rightClaw.tint = 0x800000;
	// Initial attributes for the enemy
	self.health = 25;
	self.maxHealth = 25;
	self.damage = 15;
	self.armor = 3;
	self.criticalChance = 0.15;
	self.magicResist = 3;
	self.mana = 40;
	self.speed = 2;
	self.range = 1; // Enemy always melee (adjacent cell)
	self.goldValue = 2;
	self.name = "Enemy";
	self.healthBar = null; // Initialize health bar as null
	self.isAttacking = false; // Flag to track if enemy is currently attacking
	self.baseScale = 1.3; // Base scale multiplier for all enemies (30% larger)
	// Apply base scale
	self.scaleX = self.baseScale;
	self.scaleY = self.baseScale;
	self.showHealthBar = function () {
		if (!self.healthBar) {
			self.healthBar = new HealthBar(60, 8); // Create a health bar instance (smaller than units)
			self.healthBar.x = -30; // Position relative to the enemy's center
			self.healthBar.y = -60; // Position above the enemy
			self.addChild(self.healthBar);
		}
		self.healthBar.visible = true; // Ensure health bar is visible
		self.healthBar.updateHealth(self.health, self.maxHealth);
	};
	self.updateHealthBar = function () {
		if (self.healthBar) {
			self.healthBar.updateHealth(self.health, self.maxHealth);
		}
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		self.updateHealthBar(); // Update health bar when taking damage
		if (self.health <= 0) {
			self.health = 0;
			return true;
		}
		return false;
	};
	self.deathAnimation = function () {
		// Hide health bar immediately
		if (self.healthBar) {
			self.healthBar.destroy();
			self.healthBar = null;
		}
		// Create particle explosion effect
		var particleContainer = new Container();
		particleContainer.x = self.x;
		particleContainer.y = self.y;
		self.parent.addChild(particleContainer);
		// Number of particles based on enemy type
		var particleCount = 12; // Default for regular enemies
		var particleColors = [0xFF4444, 0xFF6666, 0xFF8888, 0xFFAAAA]; // Red shades for regular enemies
		var particleSize = 15;
		var explosionRadius = 80;
		// Customize based on enemy type
		if (self.name === "Ranged Enemy") {
			particleColors = [0x8A2BE2, 0x9370DB, 0xBA55D3, 0xDDA0DD]; // Purple shades
			particleCount = 10;
		} else if (self.name === "Boss Monster") {
			particleColors = [0x800000, 0xA52A2A, 0xDC143C, 0xFF0000]; // Dark red to bright red
			particleCount = 20; // More particles for boss
			particleSize = 20;
			explosionRadius = 120;
		}
		// Create particles
		var particles = [];
		for (var i = 0; i < particleCount; i++) {
			var particle = particleContainer.attachAsset('bullet', {
				anchorX: 0.5,
				anchorY: 0.5,
				width: particleSize + Math.random() * 10,
				height: particleSize + Math.random() * 10
			});
			// Set particle color
			particle.tint = particleColors[Math.floor(Math.random() * particleColors.length)];
			particle.alpha = 0.8 + Math.random() * 0.2;
			// Calculate random direction
			var angle = Math.PI * 2 * i / particleCount + (Math.random() - 0.5) * 0.5;
			var speed = explosionRadius * (0.7 + Math.random() * 0.3);
			// Store particle data
			particles.push({
				sprite: particle,
				targetX: Math.cos(angle) * speed,
				targetY: Math.sin(angle) * speed,
				rotationSpeed: (Math.random() - 0.5) * 0.2
			});
		}
		// Animate enemy shrinking and fading
		tween(self, {
			alpha: 0,
			scaleX: self.scaleX * 0.5,
			scaleY: self.scaleY * 0.5
		}, {
			duration: 200,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				// Destroy the enemy
				self.destroy();
			}
		});
		// Animate particles bursting outward
		for (var i = 0; i < particles.length; i++) {
			var particleData = particles[i];
			var particle = particleData.sprite;
			// Burst outward animation
			tween(particle, {
				x: particleData.targetX,
				y: particleData.targetY,
				scaleX: 0.1,
				scaleY: 0.1,
				alpha: 0,
				rotation: particle.rotation + particleData.rotationSpeed * 10
			}, {
				duration: 600 + Math.random() * 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Clean up after last particle
					if (i === particles.length - 1) {
						particleContainer.destroy();
					}
				}
			});
		}
		// Add a brief flash effect at the center
		var flash = particleContainer.attachAsset('bullet', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: particleSize * 3,
			height: particleSize * 3
		});
		flash.tint = 0xFFFFFF;
		flash.alpha = 0.8;
		tween(flash, {
			scaleX: 3,
			scaleY: 3,
			alpha: 0
		}, {
			duration: 300,
			easing: tween.easeOut
		});
	};
	self.update = function () {
		if (!self.gridMovement) {
			self.gridMovement = new GridMovement(self, grid);
		}
		self.gridMovement.update();
		// Castle is now treated as a unit on the grid, no special collision logic needed
		// Find and attack units within range (cell-based)
		var closestUnit = null;
		var closestCellDistance = self.range + 1; // Only units within range (cell count) are valid
		// Only recalculate targets every 15 ticks or if position changed
		if (!self._targetCache || LK.ticks % 15 === 0 || self._lastTargetX !== self.gridX || self._lastTargetY !== self.gridY) {
			self._lastTargetX = self.gridX;
			self._lastTargetY = self.gridY;
			// Smart targeting - collect all units in range
			var targetsInRange = [];
			// First check if king exists and is in range
			if (kings.length > 0 && kings[0]) {
				var king = kings[0];
				if (typeof king.gridX === "number" && typeof king.gridY === "number") {
					var kingCellDist = Math.abs(self.gridX - king.gridX) + Math.abs(self.gridY - king.gridY);
					if (kingCellDist <= self.range && self.gridMovement.isMoving === false) {
						targetsInRange.push({
							unit: king,
							distance: kingCellDist,
							priority: 3,
							// Medium priority for king
							healthRatio: king.health / king.maxHealth
						});
					}
				}
			}
			// Then check other units on the grid
			for (var y = Math.max(0, self.gridY - self.range); y <= Math.min(GRID_ROWS - 1, self.gridY + self.range); y++) {
				for (var x = Math.max(0, self.gridX - self.range); x <= Math.min(GRID_COLS - 1, self.gridX + self.range); x++) {
					if (grid[y] && grid[y][x]) {
						var gridSlot = grid[y][x];
						if (gridSlot.unit) {
							// Calculate cell-based Manhattan distance
							var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
							// Check if the enemy is completely inside the adjacent cell before attacking
							if (cellDist <= self.range && self.gridMovement.isMoving === false) {
								var unit = gridSlot.unit;
								var priority = 5; // Default priority
								var healthRatio = unit.health / unit.maxHealth;
								// Smart prioritization
								if (healthRatio <= 0.3) {
									priority = 1; // Highest priority - can finish off quickly
								} else if (unit.name === "Wizard" || unit.name === "Ranger") {
									priority = 2; // High priority - dangerous units
								} else if (unit.name === "Wall") {
									priority = 8; // Lowest priority - defensive units
								} else if (unit.name === "Paladin" || unit.name === "Knight") {
									priority = 6; // Low priority - tanky units
								}
								targetsInRange.push({
									unit: unit,
									distance: cellDist,
									priority: priority,
									healthRatio: healthRatio
								});
							}
						}
					}
				}
			}
			self._targetCache = targetsInRange;
		} else {
			// Use cached targets
			var targetsInRange = self._targetCache || [];
		}
		// Sort targets by priority first, then by health ratio, then by distance
		targetsInRange.sort(function (a, b) {
			if (a.priority !== b.priority) {
				return a.priority - b.priority;
			}
			if (Math.abs(a.healthRatio - b.healthRatio) > 0.1) {
				return a.healthRatio - b.healthRatio; // Lower health first
			}
			return a.distance - b.distance;
		});
		// Select best target
		if (targetsInRange.length > 0) {
			closestUnit = targetsInRange[0].unit;
		}
		// Attack the closest unit if found
		if (closestUnit) {
			if (!self.lastAttack) {
				self.lastAttack = 0;
			}
			if (LK.ticks - self.lastAttack >= 60) {
				self.lastAttack = LK.ticks;
				// Add tween animation for enemy attack
				var originalX = self.x;
				var originalY = self.y;
				// Calculate lunge direction towards target
				var dx = closestUnit.x - self.x;
				var dy = closestUnit.y - self.y;
				var dist = Math.sqrt(dx * dx + dy * dy);
				var offset = Math.min(30, dist * 0.25);
				var lungeX = self.x + (dist > 0 ? dx / dist * offset : 0);
				var lungeY = self.y + (dist > 0 ? dy / dist * offset : 0);
				// Prevent multiple attack tweens at once
				if (!self._isAttackTweening) {
					self._isAttackTweening = true;
					self.isAttacking = true; // Set attacking flag
					// Flash enemy red briefly during attack using LK effects
					LK.effects.flashObject(self, 0xFF4444, 300);
					// Lunge towards target
					tween(self, {
						x: lungeX,
						y: lungeY
					}, {
						duration: 120,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							// Apply damage after lunge
							// Play melee attack sound
							LK.getSound('melee_attack').play();
							var killed = closestUnit.takeDamage(self.damage);
							if (killed) {
								self.isAttacking = false; // Clear attacking flag if target dies
								for (var y = 0; y < GRID_ROWS; y++) {
									for (var x = 0; x < GRID_COLS; x++) {
										if (grid[y] && grid[y][x]) {
											var gridSlot = grid[y][x];
											if (gridSlot.unit === closestUnit) {
												gridSlot.unit = null;
												// Trigger death animation instead of immediate destroy
												closestUnit.deathAnimation();
												for (var i = bench.length - 1; i >= 0; i--) {
													if (bench[i] === closestUnit) {
														bench.splice(i, 1);
														break;
													}
												}
												break;
											}
										}
									}
								}
							}
							// Return to original position
							tween(self, {
								x: originalX,
								y: originalY
							}, {
								duration: 100,
								easing: tween.easeIn,
								onFinish: function onFinish() {
									self._isAttackTweening = false;
									self.isAttacking = false; // Clear attacking flag after animation
								}
							});
						}
					});
				}
			}
		}
	};
	return self;
});
var RangedEnemy = Enemy.expand(function () {
	var self = Enemy.call(this);
	// Remove default enemy graphics
	self.removeChildren();
	// Create pixelart ranged enemy character
	var enemyContainer = new Container();
	self.addChild(enemyContainer);
	// Body (purple archer)
	var body = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 55;
	body.height = 70;
	body.y = 10;
	body.tint = 0x8A2BE2; // Purple tint to match archer theme
	// Head with hood
	var head = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 35,
		height: 30
	});
	head.y = -35;
	head.tint = 0x6A1B9A;
	// Eyes (glowing yellow)
	var leftEye = enemyContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 6,
		height: 6
	});
	leftEye.x = -8;
	leftEye.y = -35;
	leftEye.tint = 0xFFFF00;
	var rightEye = enemyContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 6,
		height: 6
	});
	rightEye.x = 8;
	rightEye.y = -35;
	rightEye.tint = 0xFFFF00;
	// Bow
	var bow = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 45,
		height: 12
	});
	bow.x = -25;
	bow.y = 0;
	bow.rotation = 1.57; // 90 degrees
	bow.tint = 0x4B0082;
	// Bowstring
	var bowstring = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 2,
		height: 40
	});
	bowstring.x = -25;
	bowstring.y = 0;
	bowstring.rotation = 1.57;
	bowstring.tint = 0xDDDDDD; // Light grey string
	// Quiver on back
	var quiver = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 30
	});
	quiver.x = 20;
	quiver.y = -10;
	quiver.tint = 0x2B0040; // Dark purple
	// Override attributes for ranged enemy
	self.health = 20;
	self.maxHealth = 20;
	self.damage = 12;
	self.armor = 2;
	self.criticalChance = 0.1;
	self.magicResist = 2;
	self.mana = 30;
	self.speed = 1.5; // Slightly slower movement
	self.range = 4; // Long range for shooting
	self.goldValue = 3; // More valuable than melee enemies
	self.name = "Ranged Enemy";
	self.fireRate = 75; // Shoots faster - every 1.25 seconds
	self.lastShot = 0;
	self.baseScale = 1.3; // Base scale multiplier for all enemies (30% larger)
	// Apply base scale
	self.scaleX = self.baseScale;
	self.scaleY = self.baseScale;
	// Override update to include ranged attack behavior
	self.update = function () {
		if (!self.gridMovement) {
			self.gridMovement = new GridMovement(self, grid);
		}
		self.gridMovement.update();
		// Smart positioning - try to stay behind melee enemies
		var meleeFrontline = GRID_ROWS;
		for (var i = 0; i < enemies.length; i++) {
			var enemy = enemies[i];
			if (enemy !== self && enemy.range <= 1) {
				// Melee enemy
				if (enemy.gridY > self.gridY && enemy.gridY < meleeFrontline) {
					meleeFrontline = enemy.gridY;
				}
			}
		}
		// If we're ahead of melee units, consider retreating
		if (self.gridY > meleeFrontline && !self.isAttacking && Math.random() < 0.5) {
			// Try to move back if possible
			var backY = self.gridY - 1;
			if (backY >= 0 && !self.gridMovement.isCellOccupied(self.gridX, backY)) {
				// Override normal movement to retreat
				self.gridMovement.targetCell.y = backY;
			}
		}
		// Find and attack units within range (cell-based)
		var closestUnit = null;
		var closestCellDistance = self.range + 1; // Only units within range (cell count) are valid
		// First check if king exists and is in range
		if (kings.length > 0 && kings[0]) {
			var king = kings[0];
			if (typeof king.gridX === "number" && typeof king.gridY === "number") {
				var kingCellDist = Math.abs(self.gridX - king.gridX) + Math.abs(self.gridY - king.gridY);
				if (kingCellDist <= self.range && kingCellDist < closestCellDistance) {
					closestCellDistance = kingCellDist;
					closestUnit = king;
				}
			}
		}
		// Then check other units on the grid
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				if (grid[y] && grid[y][x]) {
					var gridSlot = grid[y][x];
					if (gridSlot.unit) {
						// Calculate cell-based Manhattan distance
						var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
						// Check if the enemy can shoot (doesn't need to be stationary like melee)
						if (cellDist <= self.range && cellDist < closestCellDistance) {
							closestCellDistance = cellDist;
							closestUnit = gridSlot.unit;
						}
					}
				}
			}
		}
		// Attack the closest unit if found
		if (closestUnit) {
			if (!self.lastShot) {
				self.lastShot = 0;
			}
			if (LK.ticks - self.lastShot >= self.fireRate) {
				self.lastShot = LK.ticks;
				// Create projectile
				var projectile = new EnemyProjectile(self.damage, closestUnit);
				projectile.x = self.x;
				projectile.y = self.y;
				enemyProjectiles.push(projectile);
				enemyContainer.addChild(projectile);
				// Play ranged attack sound
				LK.getSound('shoot').play();
				// Add shooting animation
				if (!self._isShootingTweening) {
					self._isShootingTweening = true;
					// Flash enemy blue briefly during shooting using LK effects
					LK.effects.flashObject(self, 0x4444FF, 200);
					self._isShootingTweening = false;
				}
			}
		}
	};
	return self;
});
var Boss = Enemy.expand(function () {
	var self = Enemy.call(this);
	// Remove default enemy graphics
	self.removeChildren();
	// Create massive boss container
	var bossContainer = new Container();
	self.addChild(bossContainer);
	// Main body (much larger and darker)
	var body = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 120;
	body.height = 120;
	body.y = 15;
	body.tint = 0x800000; // Dark red
	// Boss head (menacing)
	var head = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 80,
		height: 70
	});
	head.y = -60;
	head.tint = 0x4a0000; // Very dark red
	// Glowing eyes (intimidating)
	var leftEye = bossContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 15
	});
	leftEye.x = -20;
	leftEye.y = -60;
	leftEye.tint = 0xFF0000; // Bright red glowing eyes
	var rightEye = bossContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 15
	});
	rightEye.x = 20;
	rightEye.y = -60;
	rightEye.tint = 0xFF0000;
	// Massive claws (larger and more threatening)
	var leftClaw = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 30
	});
	leftClaw.x = -50;
	leftClaw.y = 10;
	leftClaw.rotation = 0.7;
	leftClaw.tint = 0x2a0000; // Very dark
	var rightClaw = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 30
	});
	rightClaw.x = 50;
	rightClaw.y = 10;
	rightClaw.rotation = -0.7;
	rightClaw.tint = 0x2a0000;
	// Boss spikes on shoulders
	var leftSpike = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 40
	});
	leftSpike.x = -40;
	leftSpike.y = -20;
	leftSpike.rotation = 0.3;
	leftSpike.tint = 0x1a1a1a; // Dark spikes
	var rightSpike = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 40
	});
	rightSpike.x = 40;
	rightSpike.y = -20;
	rightSpike.rotation = -0.3;
	rightSpike.tint = 0x1a1a1a;
	// Boss crown/horns
	var horn1 = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 35
	});
	horn1.x = -15;
	horn1.y = -85;
	horn1.rotation = 0.2;
	horn1.tint = 0x000000; // Black horns
	var horn2 = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 35
	});
	horn2.x = 15;
	horn2.y = -85;
	horn2.rotation = -0.2;
	horn2.tint = 0x000000;
	// Override boss attributes - much more powerful
	self.health = 200;
	self.maxHealth = 200;
	self.damage = 60;
	self.armor = 15;
	self.criticalChance = 0.35;
	self.magicResist = 15;
	self.mana = 100;
	self.speed = 1.2; // Slightly slower but hits harder
	self.range = 3; // Even longer reach than normal enemies
	self.goldValue = 25; // Very high reward for defeating boss
	self.name = "Boss Monster";
	self.fireRate = 75; // Faster attack rate with devastating damage
	self.baseScale = 2.0; // Much larger than regular enemies (100% larger)
	// Boss special abilities
	self.lastSpecialAttack = 0;
	self.specialAttackCooldown = 300; // 5 seconds
	self.isEnraged = false;
	self.rageThreshold = 0.3; // Enrage when below 30% health
	// Apply base scale
	self.scaleX = self.baseScale;
	self.scaleY = self.baseScale;
	// Add menacing glow effect to eyes
	tween(leftEye, {
		scaleX: 1.3,
		scaleY: 1.3,
		alpha: 0.7
	}, {
		duration: 800,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(leftEye, {
				scaleX: 1.0,
				scaleY: 1.0,
				alpha: 1.0
			}, {
				duration: 800,
				easing: tween.easeInOut,
				onFinish: onFinish
			});
		}
	});
	tween(rightEye, {
		scaleX: 1.3,
		scaleY: 1.3,
		alpha: 0.7
	}, {
		duration: 800,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(rightEye, {
				scaleX: 1.0,
				scaleY: 1.0,
				alpha: 1.0
			}, {
				duration: 800,
				easing: tween.easeInOut,
				onFinish: onFinish
			});
		}
	});
	// Boss special attack - area damage
	self.performAreaAttack = function () {
		// Get all units within 2 cells
		var affectedUnits = [];
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				if (grid[y] && grid[y][x] && grid[y][x].unit) {
					var unit = grid[y][x].unit;
					var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
					if (cellDist <= 2) {
						affectedUnits.push(unit);
					}
				}
			}
		}
		// Check king separately
		if (kings.length > 0 && kings[0]) {
			var king = kings[0];
			if (typeof king.gridX === "number" && typeof king.gridY === "number") {
				var kingCellDist = Math.abs(self.gridX - king.gridX) + Math.abs(self.gridY - king.gridY);
				if (kingCellDist <= 2) {
					affectedUnits.push(king);
				}
			}
		}
		// Visual warning effect
		LK.effects.flashScreen(0x660000, 200);
		// Perform ground slam animation
		var originalScale = self.baseScale * (self.isEnraged ? 1.2 : 1.0);
		tween(self, {
			scaleX: originalScale * 0.8,
			scaleY: originalScale * 1.3
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Damage all nearby units
				for (var i = 0; i < affectedUnits.length; i++) {
					var unit = affectedUnits[i];
					var areaDamage = Math.floor(self.damage * 0.5); // Half damage for area attack
					var killed = unit.takeDamage(areaDamage);
					if (killed) {
						// Handle unit death
						for (var y = 0; y < GRID_ROWS; y++) {
							for (var x = 0; x < GRID_COLS; x++) {
								if (grid[y] && grid[y][x] && grid[y][x].unit === unit) {
									grid[y][x].unit = null;
									// Trigger death animation instead of immediate destroy
									unit.deathAnimation();
									for (var j = bench.length - 1; j >= 0; j--) {
										if (bench[j] === unit) {
											bench.splice(j, 1);
											break;
										}
									}
									break;
								}
							}
						}
					}
					// Flash effect on damaged unit
					LK.effects.flashObject(unit, 0xFF0000, 300);
				}
				// Return to normal size
				tween(self, {
					scaleX: originalScale,
					scaleY: originalScale
				}, {
					duration: 150,
					easing: tween.easeIn
				});
			}
		});
	};
	// Override takeDamage to handle enrage mechanic
	self.takeDamage = function (damage) {
		self.health -= damage;
		self.updateHealthBar();
		// Check for enrage
		if (!self.isEnraged && self.health / self.maxHealth <= self.rageThreshold) {
			self.isEnraged = true;
			// Visual enrage effect
			body.tint = 0xFF0000; // Bright red when enraged
			head.tint = 0x990000; // Dark red head
			// Increase stats when enraged
			self.damage = Math.floor(self.damage * 1.5);
			self.fireRate = Math.floor(self.fireRate * 0.7); // Attack faster
			self.speed = self.speed * 1.3;
			// Scale up slightly
			var enragedScale = self.baseScale * 1.2;
			tween(self, {
				scaleX: enragedScale,
				scaleY: enragedScale
			}, {
				duration: 500,
				easing: tween.easeOut
			});
			// Flash effect
			LK.effects.flashObject(self, 0xFF0000, 1000);
			LK.effects.flashScreen(0x660000, 500);
		}
		if (self.health <= 0) {
			self.health = 0;
			return true;
		}
		return false;
	};
	// Override attack with more devastating effects
	self.update = function () {
		if (!self.gridMovement) {
			self.gridMovement = new GridMovement(self, grid);
		}
		self.gridMovement.update();
		// Check for special area attack
		if (LK.ticks - self.lastSpecialAttack >= self.specialAttackCooldown) {
			// Check if there are multiple units nearby
			var nearbyUnits = 0;
			for (var y = 0; y < GRID_ROWS; y++) {
				for (var x = 0; x < GRID_COLS; x++) {
					if (grid[y] && grid[y][x] && grid[y][x].unit) {
						var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
						if (cellDist <= 2) {
							nearbyUnits++;
						}
					}
				}
			}
			// Perform area attack if 2+ units are nearby
			if (nearbyUnits >= 2) {
				self.lastSpecialAttack = LK.ticks;
				self.performAreaAttack();
				return; // Skip normal attack this frame
			}
		}
		// Find and attack units within range (cell-based)
		var closestUnit = null;
		var closestCellDistance = self.range + 1; // Only units within range (cell count) are valid
		// Smart target prioritization
		var targets = [];
		// First check if king exists and is in range
		if (kings.length > 0 && kings[0]) {
			var king = kings[0];
			if (typeof king.gridX === "number" && typeof king.gridY === "number") {
				var kingCellDist = Math.abs(self.gridX - king.gridX) + Math.abs(self.gridY - king.gridY);
				if (kingCellDist <= self.range && self.gridMovement.isMoving === false) {
					targets.push({
						unit: king,
						distance: kingCellDist,
						priority: 2 // Medium priority for king
					});
				}
			}
		}
		// Then check other units on the grid
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				if (grid[y] && grid[y][x]) {
					var gridSlot = grid[y][x];
					if (gridSlot.unit) {
						// Calculate cell-based Manhattan distance
						var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
						// Check if the enemy is completely inside the adjacent cell before attacking
						if (cellDist <= self.range && self.gridMovement.isMoving === false) {
							var unit = gridSlot.unit;
							var priority = 3; // Default priority
							// Prioritize high-damage units
							if (unit.name === "Wizard" || unit.name === "Ranger") {
								priority = 1; // Highest priority
							} else if (unit.name === "Wall") {
								priority = 4; // Lowest priority
							}
							targets.push({
								unit: unit,
								distance: cellDist,
								priority: priority
							});
						}
					}
				}
			}
		}
		// Sort targets by priority, then by distance
		targets.sort(function (a, b) {
			if (a.priority !== b.priority) {
				return a.priority - b.priority;
			}
			return a.distance - b.distance;
		});
		// Select best target
		if (targets.length > 0) {
			closestUnit = targets[0].unit;
		}
		// Attack the closest unit if found
		if (closestUnit) {
			if (!self.lastAttack) {
				self.lastAttack = 0;
			}
			if (LK.ticks - self.lastAttack >= self.fireRate) {
				self.lastAttack = LK.ticks;
				// Add devastating boss attack animation
				var originalX = self.x;
				var originalY = self.y;
				// Calculate lunge direction towards target
				var dx = closestUnit.x - self.x;
				var dy = closestUnit.y - self.y;
				var dist = Math.sqrt(dx * dx + dy * dy);
				var offset = Math.min(60, dist * 0.5); // Even larger lunge for boss
				var lungeX = self.x + (dist > 0 ? dx / dist * offset : 0);
				var lungeY = self.y + (dist > 0 ? dy / dist * offset : 0);
				// Prevent multiple attack tweens at once
				if (!self._isAttackTweening) {
					self._isAttackTweening = true;
					self.isAttacking = true; // Set attacking flag
					// Flash boss with intense red and shake screen
					LK.effects.flashObject(self, 0xFF0000, 500);
					if (self.isEnraged) {
						LK.effects.flashScreen(0x880000, 400); // Darker red screen flash when enraged
					} else {
						LK.effects.flashScreen(0x440000, 300); // Dark red screen flash
					}
					// Lunge towards target with more force
					tween(self, {
						x: lungeX,
						y: lungeY,
						rotation: self.rotation + (Math.random() > 0.5 ? 0.1 : -0.1)
					}, {
						duration: 120,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							// Apply massive damage after lunge
							// Play melee attack sound
							LK.getSound('melee_attack').play();
							var actualDamage = self.damage;
							// Critical hit chance
							if (Math.random() < self.criticalChance) {
								actualDamage = Math.floor(actualDamage * 2);
								LK.effects.flashObject(closestUnit, 0xFFFF00, 200); // Yellow flash for crit
							}
							var killed = closestUnit.takeDamage(actualDamage);
							if (killed) {
								self.isAttacking = false; // Clear attacking flag if target dies
								for (var y = 0; y < GRID_ROWS; y++) {
									for (var x = 0; x < GRID_COLS; x++) {
										if (grid[y] && grid[y][x]) {
											var gridSlot = grid[y][x];
											if (gridSlot.unit === closestUnit) {
												gridSlot.unit = null;
												// Trigger death animation instead of immediate destroy
												closestUnit.deathAnimation();
												for (var i = bench.length - 1; i >= 0; i--) {
													if (bench[i] === closestUnit) {
														bench.splice(i, 1);
														break;
													}
												}
												break;
											}
										}
									}
								}
							}
							// Return to original position
							tween(self, {
								x: originalX,
								y: originalY,
								rotation: 0
							}, {
								duration: 100,
								easing: tween.easeIn,
								onFinish: function onFinish() {
									self._isAttackTweening = false;
									self.isAttacking = false; // Clear attacking flag after animation
								}
							});
						}
					});
				}
			}
		}
	};
	return self;
});
var EnemyProjectile = Container.expand(function (damage, target) {
	var self = Container.call(this);
	// Create arrow projectile for enemies
	var arrowContainer = new Container();
	self.addChild(arrowContainer);
	// Arrow shaft
	var arrowShaft = arrowContainer.attachAsset('arrow', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 25,
		height: 6
	});
	arrowShaft.tint = 0x4B0082; // Dark purple for enemy arrows
	// Arrow head
	var arrowHead = arrowContainer.attachAsset('arrow_head', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 10
	});
	arrowHead.x = 12;
	arrowHead.rotation = 0.785; // 45 degrees
	arrowHead.tint = 0xFF0000; // Red tip for enemy
	// Arrow fletching
	var fletching = arrowContainer.attachAsset('arrow_feather', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 5
	});
	fletching.x = -8;
	fletching.tint = 0x8B008B; // Dark magenta feathers
	self.damage = damage;
	self.target = target;
	self.speed = 6;
	self.update = function () {
		if (!self.target || self.target.health <= 0) {
			self.destroy();
			return;
		}
		var dx = self.target.x - self.x;
		var dy = self.target.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < 15) {
			// Hit target
			var killed = self.target.takeDamage(self.damage);
			if (killed) {
				// Handle target death - remove from grid if it's a unit
				for (var y = 0; y < GRID_ROWS; y++) {
					for (var x = 0; x < GRID_COLS; x++) {
						if (grid[y] && grid[y][x]) {
							var gridSlot = grid[y][x];
							if (gridSlot.unit === self.target) {
								gridSlot.unit = null;
								// Trigger death animation instead of immediate destroy
								self.target.deathAnimation();
								for (var i = bench.length - 1; i >= 0; i--) {
									if (bench[i] === self.target) {
										bench.splice(i, 1);
										break;
									}
								}
								break;
							}
						}
					}
				}
			}
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
		// Rotate arrow to face target
		self.rotation = Math.atan2(dy, dx);
	};
	return self;
});
var GridMovement = Container.expand(function (entity, gridRef) {
	var self = Container.call(this);
	self.entity = entity;
	self.gridRef = gridRef;
	self.currentCell = {
		x: entity.gridX,
		y: entity.gridY
	};
	self.targetCell = {
		x: entity.gridX,
		y: entity.gridY
	};
	self.moveSpeed = 2; // Pixels per frame for continuous movement
	self.isMoving = false; // Track if entity is currently moving
	self.pathToTarget = []; // Store calculated path
	self.pathIndex = 0; // Current position in path
	// Helper method to check if a cell is occupied
	self.isCellOccupied = function (x, y) {
		// Check if out of bounds
		if (x < 0 || x >= GRID_COLS || y < 0 || y >= GRID_ROWS) {
			return true;
		}
		// Check if position is occupied by any entity using position tracking
		if (isPositionOccupied(x, y, self.entity)) {
			return true;
		}
		// Check if cell is reserved by another entity
		var cellKey = x + ',' + y;
		if (cellReservations[cellKey] && cellReservations[cellKey] !== self.entity) {
			return true;
		}
		// Check if occupied by a player unit on grid
		if (self.gridRef[y] && self.gridRef[y][x] && self.gridRef[y][x].unit && self.gridRef[y][x].unit !== self.entity) {
			return true;
		}
		return false;
	};
	// A* pathfinding implementation
	self.findPath = function (startX, startY, goalX, goalY) {
		var openSet = [];
		var closedSet = [];
		var cameFrom = {};
		// Helper to create node
		function createNode(x, y, g, h) {
			return {
				x: x,
				y: y,
				g: g,
				// Cost from start
				h: h,
				// Heuristic cost to goal
				f: g + h // Total cost
			};
		}
		// Manhattan distance heuristic
		function heuristic(x1, y1, x2, y2) {
			return Math.abs(x2 - x1) + Math.abs(y2 - y1);
		}
		// Cache directions array at class level to avoid recreation
		if (!self.directions) {
			self.directions = [{
				x: 0,
				y: -1
			},
			// Up
			{
				x: 1,
				y: 0
			},
			// Right
			{
				x: 0,
				y: 1
			},
			// Down
			{
				x: -1,
				y: 0
			} // Left
			];
		}
		// Get neighbors of a cell
		function getNeighbors(x, y) {
			var neighbors = [];
			// Check if this entity is a player unit
			var isPlayerUnit = self.entity.isPlayerUnit !== undefined ? self.entity.isPlayerUnit : self.entity.name && (self.entity.name === "Soldier" || self.entity.name === "Knight" || self.entity.name === "Wizard" || self.entity.name === "Paladin" || self.entity.name === "Ranger" || self.entity.name === "King" || self.entity.name === "Wall" || self.entity.name === "Crossbow Tower");
			// Cache this value on entity for future use
			if (self.entity.isPlayerUnit === undefined) {
				self.entity.isPlayerUnit = isPlayerUnit;
			}
			for (var i = 0; i < self.directions.length; i++) {
				var newX = x + self.directions[i].x;
				var newY = y + self.directions[i].y;
				// Player units cannot path into fog of war (top 2 rows)
				if (isPlayerUnit && newY < 2) {
					continue;
				}
				// Skip if occupied (but allow goal position even if occupied)
				if (newX === goalX && newY === goalY || !self.isCellOccupied(newX, newY)) {
					neighbors.push({
						x: newX,
						y: newY
					});
				}
			}
			return neighbors;
		}
		// Initialize start node
		var startNode = createNode(startX, startY, 0, heuristic(startX, startY, goalX, goalY));
		openSet.push(startNode);
		// Track best g scores
		var gScore = {};
		gScore[startX + ',' + startY] = 0;
		while (openSet.length > 0) {
			// Find node with lowest f score
			var current = openSet[0];
			var currentIndex = 0;
			for (var i = 1; i < openSet.length; i++) {
				if (openSet[i].f < current.f) {
					current = openSet[i];
					currentIndex = i;
				}
			}
			// Check if we reached goal
			if (current.x === goalX && current.y === goalY) {
				// Reconstruct path
				var path = [];
				var key = current.x + ',' + current.y;
				while (key && key !== startX + ',' + startY) {
					var coords = key.split(',');
					path.unshift({
						x: parseInt(coords[0]),
						y: parseInt(coords[1])
					});
					key = cameFrom[key];
				}
				return path;
			}
			// Move current from open to closed
			openSet.splice(currentIndex, 1);
			closedSet.push(current);
			// Check neighbors
			var neighbors = getNeighbors(current.x, current.y);
			for (var i = 0; i < neighbors.length; i++) {
				var neighbor = neighbors[i];
				var neighborKey = neighbor.x + ',' + neighbor.y;
				// Skip if in closed set
				var inClosed = false;
				for (var j = 0; j < closedSet.length; j++) {
					if (closedSet[j].x === neighbor.x && closedSet[j].y === neighbor.y) {
						inClosed = true;
						break;
					}
				}
				if (inClosed) {
					continue;
				}
				// Calculate tentative g score
				var tentativeG = current.g + 1;
				// Check if this path is better
				if (!gScore[neighborKey] || tentativeG < gScore[neighborKey]) {
					// Record best path
					cameFrom[neighborKey] = current.x + ',' + current.y;
					gScore[neighborKey] = tentativeG;
					// Add to open set if not already there
					var inOpen = false;
					for (var j = 0; j < openSet.length; j++) {
						if (openSet[j].x === neighbor.x && openSet[j].y === neighbor.y) {
							inOpen = true;
							openSet[j].g = tentativeG;
							openSet[j].f = tentativeG + openSet[j].h;
							break;
						}
					}
					if (!inOpen) {
						var h = heuristic(neighbor.x, neighbor.y, goalX, goalY);
						openSet.push(createNode(neighbor.x, neighbor.y, tentativeG, h));
					}
				}
			}
		}
		// No path found - try simple alternative
		return self.findAlternativePath(goalX, goalY);
	};
	// Helper method to find alternative paths (fallback for when A* fails)
	self.findAlternativePath = function (targetX, targetY) {
		var currentX = self.currentCell.x;
		var currentY = self.currentCell.y;
		// Calculate primary direction
		var dx = targetX - currentX;
		var dy = targetY - currentY;
		// Try moving in the primary direction first
		var moves = [];
		if (Math.abs(dx) > Math.abs(dy)) {
			// Prioritize horizontal movement
			if (dx > 0 && !self.isCellOccupied(currentX + 1, currentY)) {
				return [{
					x: currentX + 1,
					y: currentY
				}];
			}
			if (dx < 0 && !self.isCellOccupied(currentX - 1, currentY)) {
				return [{
					x: currentX - 1,
					y: currentY
				}];
			}
			// Try vertical as alternative
			if (dy > 0 && !self.isCellOccupied(currentX, currentY + 1)) {
				return [{
					x: currentX,
					y: currentY + 1
				}];
			}
			if (dy < 0 && !self.isCellOccupied(currentX, currentY - 1)) {
				return [{
					x: currentX,
					y: currentY - 1
				}];
			}
		} else {
			// Prioritize vertical movement
			if (dy > 0 && !self.isCellOccupied(currentX, currentY + 1)) {
				return [{
					x: currentX,
					y: currentY + 1
				}];
			}
			if (dy < 0 && !self.isCellOccupied(currentX, currentY - 1)) {
				return [{
					x: currentX,
					y: currentY - 1
				}];
			}
			// Try horizontal as alternative
			if (dx > 0 && !self.isCellOccupied(currentX + 1, currentY)) {
				return [{
					x: currentX + 1,
					y: currentY
				}];
			}
			if (dx < 0 && !self.isCellOccupied(currentX - 1, currentY)) {
				return [{
					x: currentX - 1,
					y: currentY
				}];
			}
		}
		return null;
	};
	self.moveToNextCell = function () {
		// Check if this is a structure unit that shouldn't move
		if (self.entity.isStructure) {
			return false; // Structures don't move
		}
		// Check if this is a player unit or enemy
		var isPlayerUnit = self.entity.name && (self.entity.name === "Soldier" || self.entity.name === "Knight" || self.entity.name === "Wizard" || self.entity.name === "Paladin" || self.entity.name === "Ranger" || self.entity.name === "King");
		var targetGridX = -1;
		var targetGridY = -1;
		var shouldMove = false;
		if (isPlayerUnit) {
			// Player units move towards enemies
			var closestEnemy = null;
			var closestDist = 99999;
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				if (typeof enemy.gridX === "number" && typeof enemy.gridY === "number") {
					var dx = enemy.gridX - self.currentCell.x;
					var dy = enemy.gridY - self.currentCell.y;
					var dist = Math.abs(dx) + Math.abs(dy);
					if (dist < closestDist) {
						closestDist = dist;
						closestEnemy = enemy;
						targetGridX = enemy.gridX;
						targetGridY = enemy.gridY;
					}
				}
			}
			// Only move if enemy found and not in range
			if (closestEnemy && closestDist > self.entity.range) {
				// Check if unit is currently attacking
				if (self.entity.isAttacking) {
					return false; // Don't move while attacking
				}
				shouldMove = true;
			} else {
				// Already in range or no enemy, don't move
				return false;
			}
		} else {
			// Smarter enemy movement logic
			// First, check if enemy is currently in combat (attacking or being attacked)
			if (self.entity.isAttacking) {
				// Stay in place while attacking
				return false;
			}
			// Enemy coordination - wait for nearby allies before advancing
			var nearbyAllies = 0;
			var shouldWait = false;
			for (var i = 0; i < enemies.length; i++) {
				var ally = enemies[i];
				if (ally !== self.entity && ally.gridY === self.entity.gridY) {
					// Check if ally is in same row
					var allyDist = Math.abs(ally.gridX - self.entity.gridX);
					if (allyDist <= 2) {
						nearbyAllies++;
						// If ally is behind us, wait for them
						if (ally.gridY < self.entity.gridY) {
							shouldWait = true;
						}
					}
				}
			}
			// Wait if we're too far ahead of our allies
			if (shouldWait && nearbyAllies < 2 && Math.random() < 0.7) {
				return false; // 70% chance to wait for allies
			}
			// Find closest player unit (excluding king initially)
			var closestUnit = null;
			var closestDist = 99999;
			var kingUnit = null;
			var kingDist = 99999;
			for (var y = 0; y < GRID_ROWS; y++) {
				for (var x = 0; x < GRID_COLS; x++) {
					if (self.gridRef[y] && self.gridRef[y][x] && self.gridRef[y][x].unit) {
						var unit = self.gridRef[y][x].unit;
						var dx = x - self.currentCell.x;
						var dy = y - self.currentCell.y;
						var dist = Math.abs(dx) + Math.abs(dy);
						if (unit.name === "King") {
							// Track king separately
							if (dist < kingDist) {
								kingDist = dist;
								kingUnit = unit;
							}
						} else {
							// Track other player units
							if (dist < closestDist) {
								closestDist = dist;
								closestUnit = unit;
								targetGridX = x;
								targetGridY = y;
							}
						}
					}
				}
			}
			// Determine target based on smart AI logic
			if (closestUnit) {
				// Found a non-king player unit
				var entityRange = self.entity.range || 1;
				// If enemy is within range, stay and fight
				if (closestDist <= entityRange) {
					// Stay in current position - engage in combat
					return false;
				}
				// Move towards the closest player unit
				shouldMove = true;
			} else if (kingUnit) {
				// No other player units remaining, go for the king
				targetGridX = kingUnit.gridX;
				targetGridY = kingUnit.gridY;
				var entityRange = self.entity.range || 1;
				// If enemy is within range of king, stay and fight
				if (kingDist <= entityRange) {
					// Stay in current position - engage king in combat
					return false;
				}
				// Move towards the king
				shouldMove = true;
			} else {
				// No target found, move down as fallback
				targetGridX = self.currentCell.x;
				targetGridY = self.currentCell.y + 1;
				shouldMove = true;
			}
		}
		if (!shouldMove) {
			return false;
		}
		// Use A* pathfinding to find best path
		if (!self.pathToTarget || self.pathToTarget.length === 0 || self.pathIndex >= self.pathToTarget.length) {
			// Calculate new path
			var path = self.findPath(self.currentCell.x, self.currentCell.y, targetGridX, targetGridY);
			if (path && path.length > 0) {
				self.pathToTarget = path;
				self.pathIndex = 0;
			} else {
				// No path found
				return false;
			}
		}
		// Get next cell from path
		var nextCell = self.pathToTarget[self.pathIndex];
		if (!nextCell) {
			return false;
		}
		var nextX = nextCell.x;
		var nextY = nextCell.y;
		// Check if desired cell is still unoccupied
		if (self.isCellOccupied(nextX, nextY)) {
			// Path is blocked, recalculate
			self.pathToTarget = [];
			self.pathIndex = 0;
			return false;
		}
		// Final check if the cell is valid and unoccupied
		if (!self.isCellOccupied(nextX, nextY) && self.gridRef[nextY] && self.gridRef[nextY][nextX]) {
			// Prevent player units from moving into fog of war (top 2 rows)
			var isPlayerUnit = self.entity.name && (self.entity.name === "Soldier" || self.entity.name === "Knight" || self.entity.name === "Wizard" || self.entity.name === "Paladin" || self.entity.name === "Ranger" || self.entity.name === "King" || self.entity.name === "Wall" || self.entity.name === "Crossbow Tower");
			if (isPlayerUnit && nextY < 2) {
				// Player units cannot move into fog of war
				self.pathToTarget = [];
				self.pathIndex = 0;
				return false;
			}
			var targetGridCell = self.gridRef[nextY][nextX];
			// Double-check that no other entity is trying to move to same position at same time
			if (isPositionOccupied(nextX, nextY, self.entity)) {
				return false;
			}
			// Unregister old position
			unregisterEntityPosition(self.entity, self.currentCell.x, self.currentCell.y);
			// Register new position immediately to prevent conflicts
			registerEntityPosition(self.entity);
			// Release old reservation
			var oldCellKey = self.currentCell.x + ',' + self.currentCell.y;
			if (cellReservations[oldCellKey] === self.entity) {
				delete cellReservations[oldCellKey];
			}
			// Reserve new cell
			var newCellKey = nextX + ',' + nextY;
			cellReservations[newCellKey] = self.entity;
			// Update logical position immediately
			self.currentCell.x = nextX;
			self.currentCell.y = nextY;
			self.entity.gridX = nextX;
			self.entity.gridY = nextY;
			// Set target position for smooth movement
			self.targetCell.x = targetGridCell.x;
			self.targetCell.y = targetGridCell.y;
			self.isMoving = true;
			// Add smooth transition animation when starting movement
			if (!self.entity._isMoveTweening) {
				self.entity._isMoveTweening = true;
				// Get base scale (default to 1 if not set)
				var baseScale = self.entity.baseScale || 1;
				// Slight scale and rotation animation when moving
				tween(self.entity, {
					scaleX: baseScale * 1.1,
					scaleY: baseScale * 0.9,
					rotation: self.entity.rotation + (Math.random() > 0.5 ? 0.05 : -0.05)
				}, {
					duration: 150,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						tween(self.entity, {
							scaleX: baseScale,
							scaleY: baseScale,
							rotation: 0
						}, {
							duration: 150,
							easing: tween.easeIn,
							onFinish: function onFinish() {
								self.entity._isMoveTweening = false;
							}
						});
					}
				});
			}
			return true;
		}
		return false;
	};
	self.update = function () {
		// Periodically check if we need to recalculate path (every 30 ticks)
		if (LK.ticks % 30 === 0 && self.pathToTarget && self.pathToTarget.length > 0) {
			// Check if current path is still valid
			var stillValid = true;
			for (var i = self.pathIndex; i < self.pathToTarget.length && i < self.pathIndex + 3; i++) {
				if (self.pathToTarget[i] && self.isCellOccupied(self.pathToTarget[i].x, self.pathToTarget[i].y)) {
					stillValid = false;
					break;
				}
			}
			if (!stillValid) {
				// Path blocked, clear it to force recalculation
				self.pathToTarget = [];
				self.pathIndex = 0;
			}
		}
		// If we have a target position, move towards it smoothly
		if (self.isMoving) {
			var dx = self.targetCell.x - self.entity.x;
			var dy = self.targetCell.y - self.entity.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > self.moveSpeed) {
				// Continue moving towards target
				var moveX = dx / distance * self.moveSpeed;
				var moveY = dy / distance * self.moveSpeed;
				self.entity.x += moveX;
				self.entity.y += moveY;
			} else {
				// Reached target cell - ensure exact grid alignment
				var finalGridX = self.currentCell.x;
				var finalGridY = self.currentCell.y;
				var finalX = GRID_START_X + finalGridX * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
				var finalY = GRID_START_Y + finalGridY * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
				self.entity.x = finalX;
				self.entity.y = finalY;
				self.isMoving = false;
				self.pathIndex++; // Move to next cell in path
				// Wait a tick before trying next move to avoid simultaneous conflicts
				if (LK.ticks % 2 === 0) {
					// Immediately try to move to next cell for continuous movement
					self.moveToNextCell();
				}
			}
		} else {
			// Not moving, try to start moving to next cell
			// Add slight randomization to prevent all entities from moving at exact same time
			if (LK.ticks % (2 + Math.floor(Math.random() * 3)) === 0) {
				self.moveToNextCell();
			}
		}
	};
	return self;
});
var GridSlot = Container.expand(function (lane, gridX, gridY) {
	var self = Container.call(this);
	var slotGraphics = self.attachAsset('grid_slot', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.lane = lane;
	self.gridX = gridX;
	self.gridY = gridY;
	self.unit = null;
	slotGraphics.alpha = 0.3;
	self.down = function (x, y, obj) {
		if (self.unit && !draggedUnit && gameState === 'planning') {
			// Allow dragging any unit during planning phase
			draggedUnit = self.unit;
			draggedUnit.originalX = self.x;
			draggedUnit.originalY = self.y;
			draggedUnit.originalGridSlot = self;
			draggedFromGrid = true;
		}
	};
	self.up = function (x, y, obj) {
		if (draggedUnit && !self.unit) {
			self.placeUnit(draggedUnit);
			draggedUnit = null;
		}
	};
	self.placeUnit = function (unit) {
		if (self.unit) {
			// Swap units if the slot is occupied
			var tempUnit = self.unit;
			self.unit = unit;
			unit.originalGridSlot.unit = tempUnit;
			tempUnit.x = unit.originalGridSlot.x;
			tempUnit.y = unit.originalGridSlot.y;
			tempUnit.gridX = unit.originalGridSlot.gridX;
			tempUnit.gridY = unit.originalGridSlot.gridY;
			tempUnit.lane = unit.originalGridSlot.lane;
			return true;
		}
		// Prevent placement in fog of war (top 2 rows)
		if (self.gridY < 2) {
			// Show message about fog of war
			var fogMessage = new Text2('Cannot place units in the fog of war!', {
				size: 72,
				fill: 0xFF4444
			});
			fogMessage.anchor.set(0.5, 0.5);
			fogMessage.x = 1024; // Center of screen
			fogMessage.y = 800; // Middle of screen
			game.addChild(fogMessage);
			// Flash the message and fade it out
			LK.effects.flashObject(fogMessage, 0xFFFFFF, 300);
			tween(fogMessage, {
				alpha: 0,
				y: 700
			}, {
				duration: 3000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					fogMessage.destroy();
				}
			});
			// Return unit to bench if it was being dragged
			if (unit.originalSlot) {
				unit.originalSlot.unit = unit;
				unit.x = unit.originalSlot.x;
				unit.y = unit.originalSlot.y;
			} else {
				// Find first available bench slot
				for (var i = 0; i < benchSlots.length; i++) {
					if (!benchSlots[i].unit) {
						benchSlots[i].unit = unit;
						unit.x = benchSlots[i].x;
						unit.y = benchSlots[i].y;
						unit.gridX = -1;
						unit.gridY = -1;
						unit.lane = -1;
						unit.hideHealthBar();
						unit.hideStarIndicator();
						updateBenchDisplay();
						break;
					}
				}
			}
			return false;
		}
		// Check if position is already occupied by another entity
		if (isPositionOccupied(self.gridX, self.gridY, unit)) {
			return false;
		}
		// Check unit placement limits (don't apply to king)
		if (unit.name !== "King" && !canPlaceMoreUnits(unit.isStructure)) {
			// Show message about reaching unit limit
			var limitType = unit.isStructure ? 'structures' : 'units';
			var limitMessage = new Text2('You have no more room for ' + limitType + ' in the battlefield, level up to increase it!', {
				size: 72,
				fill: 0xFF4444
			});
			limitMessage.anchor.set(0.5, 0.5);
			limitMessage.x = 1024; // Center of screen
			limitMessage.y = 800; // Middle of screen
			game.addChild(limitMessage);
			// Flash the message and fade it out
			LK.effects.flashObject(limitMessage, 0xFFFFFF, 300);
			tween(limitMessage, {
				alpha: 0,
				y: 700
			}, {
				duration: 5000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					limitMessage.destroy();
				}
			});
			// Return unit to bench - find first available bench slot
			for (var i = 0; i < benchSlots.length; i++) {
				if (!benchSlots[i].unit) {
					benchSlots[i].unit = unit;
					unit.x = benchSlots[i].x;
					unit.y = benchSlots[i].y;
					unit.gridX = -1;
					unit.gridY = -1;
					unit.lane = -1;
					unit.hideHealthBar();
					unit.hideStarIndicator();
					updateBenchDisplay();
					break;
				}
			}
			return false; // Can't place more units
		}
		self.unit = unit;
		// Unregister old position if unit was previously on grid
		if (unit.gridX >= 0 && unit.gridY >= 0) {
			unregisterEntityPosition(unit, unit.gridX, unit.gridY);
		}
		// Calculate exact grid cell center position
		var gridCenterX = GRID_START_X + self.gridX * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		var gridCenterY = GRID_START_Y + self.gridY * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		// Update unit's grid coordinates
		unit.gridX = self.gridX;
		unit.gridY = self.gridY;
		unit.lane = self.lane;
		// Force unit to exact grid position (snap to grid)
		unit.x = gridCenterX;
		unit.y = gridCenterY;
		// Ensure the grid slot also has the correct position
		self.x = gridCenterX;
		self.y = gridCenterY;
		// Add placement animation with bounce effect
		var targetScale = unit.baseScale || 1.3; // Use base scale or default to 1.3
		if (unit.tier === 2) {
			targetScale = (unit.baseScale || 1.3) * 1.2;
		} else if (unit.tier === 3) {
			targetScale = (unit.baseScale || 1.3) * 1.3;
		}
		// Stop any ongoing scale tweens before starting new bounce
		tween.stop(unit, {
			scaleX: true,
			scaleY: true
		});
		// Always reset scale to 0 before bounce (fixes bug where scale is not reset)
		unit.scaleX = 0;
		unit.scaleY = 0;
		// Capture unit reference before any async operations
		var unitToAnimate = unit;
		// Start bounce animation immediately
		// Set bounce animation flag to prevent updateUnitScale interference
		unitToAnimate._isBounceAnimating = true;
		tween(unitToAnimate, {
			scaleX: targetScale * 1.2,
			scaleY: targetScale * 1.2
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(unitToAnimate, {
					scaleX: targetScale,
					scaleY: targetScale
				}, {
					duration: 150,
					easing: tween.easeIn
				});
			}
		});
		// Register new position
		registerEntityPosition(unit);
		unit.showHealthBar(); // Show health bar when placed on grid
		unit.updateHealthBar(); // Update health bar to show current health
		// Delay showStarIndicator until after bounce animation completes
		LK.setTimeout(function () {
			if (unitToAnimate && unitToAnimate.parent) {
				// Check if unit still exists
				unitToAnimate.showStarIndicator(); // Show star indicator after bounce animation
			}
		}, 400); // Wait for bounce animation to complete (200ms + 150ms + small buffer)
		// Don't remove from bench - units stay in both places
		updateBenchDisplay();
		countUnitsOnField(); // Update unit counts
		return true;
	};
	return self;
});
var HealthBar = Container.expand(function (width, height) {
	var self = Container.call(this);
	self.maxWidth = width;
	// Background of the health bar
	self.background = self.attachAsset('healthbar_bg', {
		anchorX: 0,
		anchorY: 0.5,
		width: width,
		height: height
	});
	// Foreground of the health bar
	self.foreground = self.attachAsset('healthbar_fg', {
		anchorX: 0,
		anchorY: 0.5,
		width: width,
		height: height
	});
	self.updateHealth = function (currentHealth, maxHealth) {
		var healthRatio = currentHealth / maxHealth;
		self.foreground.width = self.maxWidth * healthRatio;
		if (healthRatio > 0.6) {
			self.foreground.tint = 0x00ff00; // Green
		} else if (healthRatio > 0.3) {
			self.foreground.tint = 0xffff00; // Yellow
		} else {
			self.foreground.tint = 0xff0000; // Red
		}
	};
	return self;
});
var StarIndicator = Container.expand(function (tier) {
	var self = Container.call(this);
	self.tier = tier || 1;
	self.dots = [];
	self.updateStars = function (newTier) {
		self.tier = newTier;
		// Remove existing dots
		for (var i = 0; i < self.dots.length; i++) {
			self.dots[i].destroy();
		}
		self.dots = [];
		// Create new dots based on tier
		var dotSpacing = 12;
		var totalWidth = (self.tier - 1) * dotSpacing;
		var startX = -totalWidth / 2;
		for (var i = 0; i < self.tier; i++) {
			var dot = self.attachAsset('star_dot', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			dot.x = startX + i * dotSpacing;
			dot.y = 0;
			self.dots.push(dot);
		}
	};
	// Initialize with current tier
	self.updateStars(self.tier);
	return self;
});
var Unit = Container.expand(function (tier) {
	var self = Container.call(this);
	self.tier = tier || 1;
	var assetName = 'unit_tier' + self.tier;
	var unitGraphics = self.attachAsset(assetName, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 100;
	self.maxHealth = 100;
	self.damage = self.tier;
	self.speed = 1; // Attack speed multiplier
	self.fireRate = 60; // Base fire rate in ticks
	self.lastShot = 0;
	self.gridX = -1;
	self.gridY = -1;
	self.lane = -1;
	self.range = 1; // Default range in cells (adjacent/melee). Override in subclasses for ranged units.
	self.healthBar = null; // Initialize health bar as null
	self.starIndicator = null; // Initialize star indicator as null
	self.isAttacking = false; // Flag to track if unit is currently attacking
	self.baseScale = 1.3; // Base scale multiplier for all units (30% larger)
	// Apply base scale
	self.scaleX = self.baseScale;
	self.scaleY = self.baseScale;
	self.showHealthBar = function () {
		if (!self.healthBar) {
			self.healthBar = new HealthBar(80, 10); // Create a health bar instance
			self.healthBar.x = -40; // Position relative to the unit's center
			self.healthBar.y = -60; // Position above the unit
			self.addChild(self.healthBar);
			self.healthBar._lastVisible = false; // Track visibility state
		}
		// Only update if visibility changed
		if (!self.healthBar._lastVisible) {
			self.healthBar.visible = true; // Ensure health bar is visible
			self.healthBar._lastVisible = true;
		}
		self.healthBar.updateHealth(self.health, self.maxHealth);
	};
	self.showStarIndicator = function () {
		if (!self.starIndicator) {
			self.starIndicator = new StarIndicator(self.tier);
			self.starIndicator.x = 0; // Center relative to unit
			self.starIndicator.y = 55; // Position below the unit
			self.addChild(self.starIndicator);
		}
		self.starIndicator.visible = true;
		self.starIndicator.updateStars(self.tier);
		// Scale unit based on tier - two star units are 30% larger
		self.updateUnitScale();
	};
	self.updateUnitScale = function () {
		// Check if bounce animation is in progress - if so, don't interfere
		if (self._isBounceAnimating) {
			return; // Skip scale update during bounce animation
		}
		// Stop any ongoing scale tweens first
		tween.stop(self, {
			scaleX: true,
			scaleY: true
		});
		if (self.tier === 2) {
			// Two star units are 20% larger on top of base scale
			var targetScale = self.baseScale * 1.2;
			self.scaleX = targetScale;
			self.scaleY = targetScale;
			tween(self, {
				scaleX: targetScale,
				scaleY: targetScale
			}, {
				duration: 300,
				easing: tween.easeOut
			});
		} else if (self.tier === 3) {
			// Three star units are 30% larger on top of base scale
			var targetScale = self.baseScale * 1.3;
			self.scaleX = targetScale;
			self.scaleY = targetScale;
			tween(self, {
				scaleX: targetScale,
				scaleY: targetScale
			}, {
				duration: 300,
				easing: tween.easeOut
			});
		} else {
			// Tier 1 units use base scale
			self.scaleX = self.baseScale;
			self.scaleY = self.baseScale;
			tween(self, {
				scaleX: self.baseScale,
				scaleY: self.baseScale
			}, {
				duration: 300,
				easing: tween.easeOut
			});
		}
	};
	self.hideHealthBar = function () {
		if (self.healthBar) {
			self.healthBar.destroy();
			self.healthBar = null;
		}
	};
	self.hideStarIndicator = function () {
		if (self.starIndicator) {
			self.starIndicator.destroy();
			self.starIndicator = null;
		}
	};
	self.updateHealthBar = function () {
		if (self.healthBar) {
			self.healthBar.updateHealth(self.health, self.maxHealth);
		}
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		if (self.health < 0) {
			self.health = 0;
		} // Ensure health doesn't go below 0
		self.updateHealthBar(); // Update health bar when taking damage
		if (self.health <= 0) {
			self.hideHealthBar(); // Hide health bar when destroyed
			return true;
		}
		return false;
	};
	self.deathAnimation = function () {
		// Hide health bar and star indicator immediately
		if (self.healthBar) {
			self.healthBar.destroy();
			self.healthBar = null;
		}
		if (self.starIndicator) {
			self.starIndicator.destroy();
			self.starIndicator = null;
		}
		// Create particle explosion effect
		var particleContainer = new Container();
		particleContainer.x = self.x;
		particleContainer.y = self.y;
		self.parent.addChild(particleContainer);
		// Number of particles based on unit type
		var particleCount = 10; // Default for regular units
		var particleColors = [];
		var particleSize = 12;
		var explosionRadius = 60;
		// Customize particle colors based on unit type
		if (self.name === "Soldier" || self.name === "Knight") {
			particleColors = [0x32CD32, 0x228B22, 0x66ff66, 0x4da24d]; // Green shades
		} else if (self.name === "Wizard") {
			particleColors = [0x191970, 0x000066, 0x00FFFF, 0x4444FF]; // Blue/cyan shades
		} else if (self.name === "Ranger") {
			particleColors = [0x87CEEB, 0x9d9dff, 0x4169E1, 0x6495ED]; // Light blue shades
		} else if (self.name === "Paladin") {
			particleColors = [0x4169E1, 0x4444FF, 0xFFD700, 0x1E90FF]; // Royal blue with gold
		} else if (self.name === "Wall") {
			particleColors = [0x808080, 0x696969, 0x606060, 0x505050]; // Grey stone shades
			particleSize = 15;
		} else if (self.name === "Crossbow Tower") {
			particleColors = [0x8B4513, 0x654321, 0x696969, 0x5C4033]; // Brown/grey shades
			particleSize = 15;
		} else if (self.name === "King") {
			// King gets special treatment
			particleColors = [0xFFD700, 0xFFFF00, 0xFF0000, 0x4B0082]; // Gold, yellow, red, purple
			particleCount = 20;
			particleSize = 18;
			explosionRadius = 100;
		} else {
			// Default colors
			particleColors = [0xFFFFFF, 0xCCCCCC, 0x999999, 0x666666];
		}
		// Create particles
		var particles = [];
		// Pre-calculate common values
		var angleStep = Math.PI * 2 / particleCount;
		var colorCount = particleColors.length;
		for (var i = 0; i < particleCount; i++) {
			var size = particleSize + Math.random() * 8;
			var particle = particleContainer.attachAsset('bullet', {
				anchorX: 0.5,
				anchorY: 0.5,
				width: size,
				height: size
			});
			// Set particle color
			particle.tint = particleColors[i % colorCount];
			particle.alpha = 0.8 + Math.random() * 0.2;
			// Calculate random direction
			var angle = angleStep * i + (Math.random() - 0.5) * 0.5;
			var speed = explosionRadius * (0.7 + Math.random() * 0.3);
			// Store particle data
			particles.push({
				sprite: particle,
				targetX: Math.cos(angle) * speed,
				targetY: Math.sin(angle) * speed,
				rotationSpeed: (Math.random() - 0.5) * 0.2
			});
		}
		// Animate unit shrinking and fading
		tween(self, {
			alpha: 0,
			scaleX: self.scaleX * 0.5,
			scaleY: self.scaleY * 0.5
		}, {
			duration: 200,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				// Destroy the unit
				self.destroy();
			}
		});
		// Animate particles bursting outward
		for (var i = 0; i < particles.length; i++) {
			var particleData = particles[i];
			var particle = particleData.sprite;
			// Burst outward animation
			tween(particle, {
				x: particleData.targetX,
				y: particleData.targetY,
				scaleX: 0.1,
				scaleY: 0.1,
				alpha: 0,
				rotation: particle.rotation + particleData.rotationSpeed * 10
			}, {
				duration: 600 + Math.random() * 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Clean up after last particle
					if (i === particles.length - 1) {
						particleContainer.destroy();
					}
				}
			});
		}
		// Add a brief flash effect at the center
		var flash = particleContainer.attachAsset('bullet', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: particleSize * 3,
			height: particleSize * 3
		});
		flash.tint = 0xFFFFFF;
		flash.alpha = 0.8;
		tween(flash, {
			scaleX: 3,
			scaleY: 3,
			alpha: 0
		}, {
			duration: 300,
			easing: tween.easeOut
		});
	};
	self.canShoot = function () {
		// Use speed to modify fire rate - higher speed means faster attacks
		var adjustedFireRate = Math.floor(self.fireRate / self.speed);
		return LK.ticks - self.lastShot >= adjustedFireRate;
	};
	self.shoot = function (target) {
		if (!self.canShoot()) {
			return null;
		}
		self.lastShot = LK.ticks;
		// For melee units (range 1), don't create bullets
		if (self.range <= 1) {
			// Melee attack: do incline movement using tween, then apply damage
			var originalX = self.x;
			var originalY = self.y;
			// Calculate incline offset (move 30% toward target, max 40px)
			var dx = target.x - self.x;
			var dy = target.y - self.y;
			var dist = Math.sqrt(dx * dx + dy * dy);
			var offset = Math.min(40, dist * 0.3);
			var inclineX = self.x + (dist > 0 ? dx / dist * offset : 0);
			var inclineY = self.y + (dist > 0 ? dy / dist * offset : 0);
			// Prevent multiple tweens at once
			if (!self._isMeleeTweening) {
				self._isMeleeTweening = true;
				self.isAttacking = true; // Set attacking flag
				tween(self, {
					x: inclineX,
					y: inclineY
				}, {
					duration: 80,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Apply damage after lunge
						// Play melee attack sound
						LK.getSound('melee_attack').play();
						var killed = target.takeDamage(self.damage);
						if (killed) {
							self.isAttacking = false; // Clear attacking flag if target dies
							// Don't give gold for killing enemies
							// Update enemies defeated count in storage
							storage.enemiesDefeated = (storage.enemiesDefeated || 0) + 1;
							LK.getSound('enemyDeath').play();
							for (var i = enemies.length - 1; i >= 0; i--) {
								if (enemies[i] === target) {
									// Trigger death animation instead of immediate destroy
									enemies[i].deathAnimation();
									enemies.splice(i, 1);
									break;
								}
							}
						}
						// Tween back to original position
						tween(self, {
							x: originalX,
							y: originalY
						}, {
							duration: 100,
							easing: tween.easeIn,
							onFinish: function onFinish() {
								self._isMeleeTweening = false;
								self.isAttacking = false; // Clear attacking flag after animation
							}
						});
					}
				});
			}
			return null; // No bullet for melee
		}
		// Ranged attack - create bullet
		var bullet = new Bullet(self.damage, target);
		bullet.x = self.x;
		bullet.y = self.y;
		// Customize bullet appearance based on unit type
		if (self.name === "Ranger") {
			// Archer units shoot arrows
			bullet.bulletType = 'arrow';
			bullet.createGraphics(); // Recreate graphics with correct type
		} else if (self.name === "Wizard") {
			// Wizard units shoot magic
			bullet.bulletType = 'magic';
			bullet.createGraphics(); // Recreate graphics with correct type
		}
		return bullet;
	};
	self.findTarget = function () {
		var closestEnemy = null;
		var closestCellDistance = self.range + 1; // Only enemies within range (cell count) are valid
		var targetsInRange = [];
		for (var i = 0; i < enemies.length; i++) {
			var enemy = enemies[i];
			// Calculate cell-based Manhattan distance
			var cellDist = -1;
			if (typeof self.gridX === "number" && typeof self.gridY === "number" && typeof enemy.gridX === "number" && typeof enemy.gridY === "number") {
				cellDist = Math.abs(self.gridX - enemy.gridX) + Math.abs(self.gridY - enemy.gridY);
			}
			if (cellDist >= 0 && cellDist <= self.range) {
				var healthRatio = enemy.health / enemy.maxHealth;
				var priority = 5; // Default priority
				// Smart target prioritization
				if (healthRatio <= 0.2) {
					priority = 1; // Highest priority - almost dead
				} else if (enemy.name === "Boss Monster") {
					priority = 2; // High priority - dangerous
				} else if (enemy.name === "Ranged Enemy") {
					priority = 3; // Medium-high priority
				} else if (healthRatio <= 0.5) {
					priority = 4; // Medium priority - damaged
				}
				targetsInRange.push({
					enemy: enemy,
					distance: cellDist,
					priority: priority,
					healthRatio: healthRatio,
					threat: enemy.damage // Consider enemy threat level
				});
			}
		}
		// Sort targets by priority, then by health ratio, then by threat level
		targetsInRange.sort(function (a, b) {
			if (a.priority !== b.priority) {
				return a.priority - b.priority;
			}
			if (Math.abs(a.healthRatio - b.healthRatio) > 0.1) {
				return a.healthRatio - b.healthRatio; // Lower health first
			}
			if (a.threat !== b.threat) {
				return b.threat - a.threat; // Higher threat first
			}
			return a.distance - b.distance;
		});
		// Select best target
		if (targetsInRange.length > 0) {
			closestEnemy = targetsInRange[0].enemy;
		}
		return closestEnemy;
	};
	self.update = function () {
		// Only initialize and update GridMovement if unit is placed on grid and during battle phase
		if (self.gridX >= 0 && self.gridY >= 0 && gameState === 'battle') {
			if (!self.gridMovement) {
				self.gridMovement = new GridMovement(self, grid);
			}
			self.gridMovement.update();
		}
		// Add idle animation when not attacking
		if (!self.isAttacking && self.gridX >= 0 && self.gridY >= 0) {
			// Only start idle animation if not already animating
			if (!self._isIdleAnimating) {
				self._isIdleAnimating = true;
				// Random delay before starting idle animation
				var delay = Math.random() * 2000;
				LK.setTimeout(function () {
					if (!self.isAttacking && self._isIdleAnimating) {
						// Calculate target scale based on tier
						var targetScale = self.baseScale;
						if (self.tier === 2) {
							targetScale = self.baseScale * 1.2;
						} else if (self.tier === 3) {
							targetScale = self.baseScale * 1.3;
						}
						// Gentle bobbing animation that respects tier scale
						tween(self, {
							scaleX: targetScale * 1.05,
							scaleY: targetScale * 0.95
						}, {
							duration: 800,
							easing: tween.easeInOut,
							onFinish: function onFinish() {
								tween(self, {
									scaleX: targetScale,
									scaleY: targetScale
								}, {
									duration: 800,
									easing: tween.easeInOut,
									onFinish: function onFinish() {
										self._isIdleAnimating = false;
									}
								});
							}
						});
					}
				}, delay);
			}
		}
	};
	return self;
});
var Wizard = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (blue mage robe)
	var body = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 65;
	body.height = 85;
	body.y = 10;
	body.tint = 0x191970; // Midnight blue to match mage robe theme
	// Head with wizard hat
	var head = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 30
	});
	head.y = -35;
	head.tint = 0xFFDBB5; // Skin color
	// Wizard hat (triangle)
	var hat = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 35
	});
	hat.y = -55;
	hat.tint = 0x000066;
	// Staff (right side)
	var staff = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 80
	});
	staff.x = 35;
	staff.y = -10;
	staff.tint = 0x8B4513;
	// Staff crystal
	var staffCrystal = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 20
	});
	staffCrystal.x = 35;
	staffCrystal.y = -50;
	staffCrystal.tint = 0x00FFFF; // Cyan crystal
	// Initial attributes for the unit
	self.health = 150;
	self.maxHealth = 150;
	self.damage = 15;
	self.armor = 8;
	self.criticalChance = 0.18;
	self.magicResist = 8;
	self.mana = 70;
	self.speed = 0.7;
	self.range = 3; // Example: medium range (3 cells)
	self.name = "Wizard";
	return self;
});
var Wall = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart wall structure
	var wallContainer = new Container();
	self.addChild(wallContainer);
	// Wall base (stone blocks)
	var wallBase = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	wallBase.width = 90;
	wallBase.height = 80;
	wallBase.y = 10;
	wallBase.tint = 0x808080; // Grey stone
	// Wall top section
	var wallTop = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 100,
		height: 30
	});
	wallTop.y = -35;
	wallTop.tint = 0x696969; // Darker grey
	// Stone texture details (left)
	var stoneLeft = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 25,
		height: 20
	});
	stoneLeft.x = -25;
	stoneLeft.y = 0;
	stoneLeft.tint = 0x606060;
	// Stone texture details (right)
	var stoneRight = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 25,
		height: 20
	});
	stoneRight.x = 25;
	stoneRight.y = 0;
	stoneRight.tint = 0x606060;
	// Stone texture details (center)
	var stoneCenter = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 15
	});
	stoneCenter.x = 0;
	stoneCenter.y = 20;
	stoneCenter.tint = 0x505050;
	// Initial attributes for the wall
	self.health = 300;
	self.maxHealth = 300;
	self.damage = 0; // Walls don't attack
	self.armor = 20; // High defense
	self.criticalChance = 0; // No critical chance
	self.magicResist = 15;
	self.mana = 0; // No mana
	self.speed = 0; // Doesn't attack
	self.range = 0; // No range
	self.name = "Wall";
	self.isStructure = true; // Mark as structure
	// Override update to prevent movement
	self.update = function () {
		// Walls don't move or attack, just exist as obstacles
		// Still need to show health bar during battle
		if (gameState === 'battle' && self.gridX >= 0 && self.gridY >= 0) {
			self.showHealthBar();
			self.updateHealthBar();
			self.showStarIndicator();
		}
	};
	// Override shoot to prevent attacking
	self.shoot = function (target) {
		return null; // Walls can't shoot
	};
	// Override findTarget since walls don't attack
	self.findTarget = function () {
		return null;
	};
	return self;
});
var Soldier = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (green base)
	var body = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 60,
		height: 80
	});
	body.y = 10;
	body.tint = 0x32CD32; // Lime green to match theme
	// Head (lighter green circle)
	var head = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 40
	});
	head.y = -30;
	head.tint = 0x66ff66;
	// Arms (small rectangles)
	var leftArm = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 40
	});
	leftArm.x = -30;
	leftArm.y = 0;
	leftArm.rotation = 0.3;
	var rightArm = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 40
	});
	rightArm.x = 30;
	rightArm.y = 0;
	rightArm.rotation = -0.3;
	// Sword (held in right hand)
	var sword = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 50
	});
	sword.x = 35;
	sword.y = -10;
	sword.rotation = -0.2;
	sword.tint = 0xC0C0C0; // Silver color
	// Sword hilt
	var swordHilt = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 8
	});
	swordHilt.x = 35;
	swordHilt.y = 15;
	swordHilt.rotation = -0.2;
	swordHilt.tint = 0x8B4513; // Brown hilt
	// Initial attributes for the unit
	self.health = 120;
	self.maxHealth = 120;
	self.damage = 12;
	self.armor = 6;
	self.criticalChance = 0.15;
	self.magicResist = 6;
	self.mana = 60;
	self.speed = 0.7;
	self.range = 1; // Melee (adjacent cell)
	self.name = "Soldier";
	return self;
});
var Ranger = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (light blue ranger outfit)
	var body = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 60;
	body.height = 80;
	body.y = 10;
	body.tint = 0x87CEEB; // Sky blue to match ranger theme
	// Head with hood
	var head = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 30
	});
	head.y = -35;
	head.tint = 0xFFDBB5; // Skin color
	// Hood
	var hood = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 50,
		height: 40
	});
	hood.y = -40;
	hood.tint = 0x9d9dff;
	// Bow (left side)
	var bow = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 50,
		height: 15
	});
	bow.x = -30;
	bow.y = 0;
	bow.rotation = 1.57; // 90 degrees
	bow.tint = 0x8B4513;
	// Bowstring
	var bowstring = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 2,
		height: 45
	});
	bowstring.x = -30;
	bowstring.y = 0;
	bowstring.rotation = 1.57;
	bowstring.tint = 0xFFFFFF; // White string
	// Arrow on right hand
	var arrow = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 4,
		height: 35
	});
	arrow.x = 25;
	arrow.y = -5;
	arrow.rotation = -0.1;
	arrow.tint = 0x654321; // Dark brown arrow
	// Arrow tip
	var arrowTip = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 8
	});
	arrowTip.x = 25;
	arrowTip.y = -22;
	arrowTip.rotation = 0.785; // 45 degrees
	arrowTip.tint = 0x808080; // Grey tip
	// Initial attributes for the unit
	self.health = 170;
	self.maxHealth = 170;
	self.damage = 17;
	self.armor = 10;
	self.criticalChance = 0.22;
	self.magicResist = 10;
	self.mana = 80;
	self.speed = 0.7;
	self.range = 2; // Example: short range (2 cells)
	self.name = "Ranger";
	return self;
});
var Paladin = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (blue armor)
	var body = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 75;
	body.height = 75;
	body.y = 10;
	body.tint = 0x4169E1; // Royal blue to match armor theme
	// Head
	var head = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 35,
		height: 35
	});
	head.y = -35;
	head.tint = 0xFFDBB5; // Skin color
	// Helmet
	var helmet = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 45,
		height: 25
	});
	helmet.y = -45;
	helmet.tint = 0x4444FF;
	// Sword (right side)
	var sword = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 60
	});
	sword.x = 35;
	sword.y = -5;
	sword.rotation = -0.2;
	sword.tint = 0xC0C0C0;
	// Sword pommel
	var swordPommel = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 12
	});
	swordPommel.x = 35;
	swordPommel.y = 20;
	swordPommel.tint = 0xFFD700; // Gold pommel
	// Initial attributes for the unit
	self.health = 160;
	self.maxHealth = 160;
	self.damage = 16;
	self.armor = 9;
	self.criticalChance = 0.2;
	self.magicResist = 9;
	self.mana = 75;
	self.speed = 0.7;
	self.range = 1; // Example: short range (2 cells)
	self.name = "Paladin";
	return self;
});
var Knight = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (darker green base)
	var body = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 70,
		height: 70
	});
	body.y = 10;
	body.tint = 0x228B22; // Forest green to match theme
	// Head (round shape)
	var head = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 35,
		height: 35
	});
	head.y = -35;
	head.tint = 0x4da24d;
	// Shield (left side)
	var shield = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 45
	});
	shield.x = -35;
	shield.y = 0;
	shield.tint = 0x666666;
	// Sword (right side)
	var sword = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 45
	});
	sword.x = 30;
	sword.y = -5;
	sword.rotation = -0.15;
	sword.tint = 0xC0C0C0; // Silver color
	// Sword guard
	var swordGuard = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 18,
		height: 6
	});
	swordGuard.x = 30;
	swordGuard.y = 13;
	swordGuard.rotation = -0.15;
	swordGuard.tint = 0x808080; // Dark grey
	// Initial attributes for the unit
	self.health = 110;
	self.maxHealth = 110;
	self.damage = 11;
	self.armor = 5;
	self.criticalChance = 0.12;
	self.magicResist = 5;
	self.mana = 55;
	self.speed = 0.7;
	self.range = 1; // Melee (adjacent cell)
	self.name = "Knight";
	return self;
});
var King = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart king character
	var kingContainer = new Container();
	self.addChild(kingContainer);
	// King body (royal robe)
	var body = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 80;
	body.height = 100;
	body.y = 15;
	body.tint = 0x4B0082; // Royal purple
	// King head (flesh tone)
	var head = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 50,
		height: 50
	});
	head.x = 0;
	head.y = -40;
	head.tint = 0xFFDBB5; // Skin color
	// Crown base
	var crownBase = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 60,
		height: 20
	});
	crownBase.x = 0;
	crownBase.y = -65;
	crownBase.tint = 0xFFFF00; // Yellow
	// Crown points (left)
	var crownLeft = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 25
	});
	crownLeft.x = -20;
	crownLeft.y = -75;
	crownLeft.tint = 0xFFFF00; // Yellow
	// Crown points (center - tallest)
	var crownCenter = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 35
	});
	crownCenter.x = 0;
	crownCenter.y = -80;
	crownCenter.tint = 0xFFFF00; // Yellow
	// Crown points (right)
	var crownRight = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 25
	});
	crownRight.x = 20;
	crownRight.y = -75;
	crownRight.tint = 0xFFFF00; // Yellow
	// Crown jewel (center)
	var crownJewel = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 8
	});
	crownJewel.x = 0;
	crownJewel.y = -80;
	crownJewel.tint = 0xFF0000; // Red jewel
	// Beard
	var beard = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 20
	});
	beard.x = 0;
	beard.y = -25;
	beard.tint = 0xC0C0C0; // Grey beard
	// Sword (right hand)
	var sword = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 80
	});
	sword.x = 45;
	sword.y = 0;
	sword.rotation = -0.2;
	sword.tint = 0xC0C0C0; // Silver blade
	// Sword hilt
	var swordHilt = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 25,
		height: 12
	});
	swordHilt.x = 45;
	swordHilt.y = 35;
	swordHilt.rotation = -0.2;
	swordHilt.tint = 0xC0C0C0; // Silver hilt
	// Royal cape/cloak
	var cape = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 70,
		height: 80
	});
	cape.x = -5;
	cape.y = 20;
	cape.tint = 0x8B0000; // Dark red cape
	// Initial attributes for the king (like a very strong unit)
	self.health = 500;
	self.maxHealth = 500;
	self.damage = 100;
	self.armor = 10;
	self.criticalChance = 0.05;
	self.magicResist = 8;
	self.mana = 100;
	self.speed = 0.5; // Slower attack speed
	self.range = 1; // Melee range
	self.name = "King";
	self.fireRate = 120; // Slower fire rate
	// Override takeDamage to handle king-specific game over
	self.takeDamage = function (damage) {
		self.health -= damage;
		if (self.health < 0) {
			self.health = 0;
		}
		self.updateHealthBar();
		if (self.health <= 0) {
			LK.effects.flashScreen(0xFF0000, 500);
			LK.showGameOver();
			return true;
		}
		return false;
	};
	// Override update - King can move if it's the only unit left
	self.update = function () {
		// Check if king is the only player unit left on the battlefield
		var playerUnitsOnGrid = 0;
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				if (grid[y] && grid[y][x] && grid[y][x].unit) {
					playerUnitsOnGrid++;
				}
			}
		}
		// If king is the only unit left, allow movement
		if (playerUnitsOnGrid === 1) {
			// Only initialize and update GridMovement if unit is placed on grid
			if (self.gridX >= 0 && self.gridY >= 0) {
				if (!self.gridMovement) {
					self.gridMovement = new GridMovement(self, grid);
				}
				self.gridMovement.update();
			}
		}
		// King stays in place if other units exist
	};
	// Override showStarIndicator to prevent King from showing stars
	self.showStarIndicator = function () {
		// King doesn't show star indicators
	};
	// Override showHealthBar for king-specific styling
	self.showHealthBar = function () {
		if (!self.healthBar) {
			self.healthBar = new HealthBar(150, 10); // Larger health bar for king
			self.healthBar.x = -75; // Position relative to the king's center
			self.healthBar.y = -110; // Position above the king (higher due to crown)
			self.addChild(self.healthBar);
		}
		self.healthBar.visible = true;
		self.healthBar.updateHealth(self.health, self.maxHealth);
	};
	// Override hideStarIndicator to handle the case where it might be called
	self.hideStarIndicator = function () {
		// King doesn't have star indicators, so nothing to hide
	};
	// Override updateUnitScale to prevent tier-based scaling for King
	self.updateUnitScale = function () {
		// King doesn't scale based on tier, only through levelUpKing function
	};
	return self;
});
var CrossbowTower = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart crossbow tower structure
	var towerContainer = new Container();
	self.addChild(towerContainer);
	// Tower base (stone foundation)
	var towerBase = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	towerBase.width = 80;
	towerBase.height = 60;
	towerBase.y = 30;
	towerBase.tint = 0x696969; // Dark grey stone
	// Tower middle section
	var towerMiddle = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 70,
		height: 50
	});
	towerMiddle.y = -10;
	towerMiddle.tint = 0x808080; // Grey stone
	// Tower top platform
	var towerTop = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 90,
		height: 20
	});
	towerTop.y = -40;
	towerTop.tint = 0x5C4033; // Brown wood platform
	// Crossbow mechanism (horizontal)
	var crossbowBase = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 60,
		height: 15
	});
	crossbowBase.y = -55;
	crossbowBase.rotation = 0;
	crossbowBase.tint = 0x8B4513; // Saddle brown
	// Crossbow arms (vertical)
	var crossbowArms = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 50
	});
	crossbowArms.y = -55;
	crossbowArms.rotation = 1.57; // 90 degrees
	crossbowArms.tint = 0x654321; // Dark brown
	// Crossbow string
	var crossbowString = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 2,
		height: 48
	});
	crossbowString.y = -55;
	crossbowString.rotation = 1.57;
	crossbowString.tint = 0xDDDDDD; // Light grey string
	// Loaded bolt
	var loadedBolt = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 4,
		height: 30
	});
	loadedBolt.x = 0;
	loadedBolt.y = -55;
	loadedBolt.rotation = 0;
	loadedBolt.tint = 0x4B0082; // Dark purple bolt
	// Initial attributes for the crossbow tower
	self.health = 200;
	self.maxHealth = 200;
	self.damage = 25; // Higher damage than regular ranged units
	self.armor = 12;
	self.criticalChance = 0.25; // High critical chance
	self.magicResist = 10;
	self.mana = 0; // No mana
	self.speed = 0.8; // Slower attack speed
	self.range = 4; // Long range
	self.name = "Crossbow Tower";
	self.isStructure = true; // Mark as structure
	self.fireRate = 90; // Slower fire rate than mobile units
	// Override update to prevent movement but allow shooting
	self.update = function () {
		// Towers don't move but can attack
		if (gameState === 'battle' && self.gridX >= 0 && self.gridY >= 0) {
			self.showHealthBar();
			self.updateHealthBar();
			self.showStarIndicator();
		}
	};
	// Override shoot to create arrow projectiles
	self.shoot = function (target) {
		if (!self.canShoot()) {
			return null;
		}
		self.lastShot = LK.ticks;
		// Create arrow projectile
		var bullet = new Bullet(self.damage, target);
		bullet.x = self.x;
		bullet.y = self.y - 55; // Shoot from crossbow position
		// Crossbow towers shoot arrows
		bullet.bulletType = 'arrow';
		bullet.createGraphics();
		// Add shooting animation - rotate crossbow slightly
		tween(crossbowBase, {
			rotation: -0.1
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(crossbowBase, {
					rotation: 0
				}, {
					duration: 200,
					easing: tween.easeIn
				});
			}
		});
		return bullet;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x2F4F2F
});
/**** 
* Game Code
****/ 
// Create game title overlay that appears on top of everything
var titleOverlay = new Container();
// Create gradient-like background effect with multiple layers
var titleOverlayBg = titleOverlay.attachAsset('shop_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 2048,
	height: 2732
});
titleOverlayBg.alpha = 0.95;
titleOverlayBg.tint = 0x0a0a1a; // Deep dark blue instead of pure black
titleOverlayBg.x = 0; // Center relative to parent
titleOverlayBg.y = 0; // Center relative to parent
// Add subtle vignette effect
var vignette = titleOverlay.attachAsset('shop_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 2200,
	height: 2900
});
vignette.alpha = 0.3;
vignette.tint = 0x000000;
vignette.x = 0;
vignette.y = 0;
// Create magical particle system for background
var particleContainer = new Container();
titleOverlay.addChild(particleContainer);
// Create floating magical particles
function createMagicalParticle() {
	var particle = particleContainer.attachAsset('star_dot', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 6 + Math.random() * 8,
		height: 6 + Math.random() * 8
	});
	// Random colors for magical effect
	var colors = [0xFFD700, 0x4169E1, 0xFF69B4, 0x00CED1, 0xFFA500];
	particle.tint = colors[Math.floor(Math.random() * colors.length)];
	particle.alpha = 0;
	// Random starting position
	particle.x = (Math.random() - 0.5) * 2048;
	particle.y = 1366 + Math.random() * 800;
	// Animate particle floating up with glow
	tween(particle, {
		y: particle.y - 2000,
		alpha: 0.8
	}, {
		duration: 2000,
		easing: tween.easeIn,
		onFinish: function onFinish() {
			tween(particle, {
				alpha: 0
			}, {
				duration: 1000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					particle.destroy();
				}
			});
		}
	});
	// Add gentle horizontal sway
	tween(particle, {
		x: particle.x + (Math.random() - 0.5) * 200
	}, {
		duration: 4000,
		easing: tween.easeInOut
	});
}
// Create particles periodically
var particleTimer = LK.setInterval(function () {
	if (titleOverlay.parent) {
		createMagicalParticle();
	} else {
		LK.clearInterval(particleTimer);
	}
}, 200);
// Create title container for effects
var titleContainer = new Container();
titleOverlay.addChild(titleContainer);
titleContainer.y = -566;
// Add golden glow behind title
var titleGlow = titleContainer.attachAsset('shop_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 800,
	height: 200
});
titleGlow.alpha = 0.3;
titleGlow.tint = 0xFFD700;
// Animate glow pulse
tween(titleGlow, {
	scaleX: 1.2,
	scaleY: 1.2,
	alpha: 0.5
}, {
	duration: 2000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(titleGlow, {
			scaleX: 1.0,
			scaleY: 1.0,
			alpha: 0.3
		}, {
			duration: 2000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Game title with shadow effect
var gameTitleShadow = new Text2('Protect Your King!', {
	size: 120,
	fill: 0x000000
});
gameTitleShadow.anchor.set(0.5, 0.5);
gameTitleShadow.x = 4;
gameTitleShadow.y = 4;
gameTitleShadow.alpha = 0.5;
titleContainer.addChild(gameTitleShadow);
// Add subtle animation to shadow
tween(gameTitleShadow, {
	x: 6,
	y: 6,
	alpha: 0.3
}, {
	duration: 3000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(gameTitleShadow, {
			x: 2,
			y: 2,
			alpha: 0.6
		}, {
			duration: 3000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Main game title
var gameTitle = new Text2('Protect Your King!', {
	size: 120,
	fill: 0xFFD700
});
gameTitle.anchor.set(0.5, 0.5);
gameTitle.x = 0;
gameTitle.y = 0;
titleContainer.addChild(gameTitle);
// Add sparkle effects around title
function createTitleSparkle() {
	var sparkle = titleContainer.attachAsset('star_dot', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 10
	});
	sparkle.tint = 0xFFFFFF;
	sparkle.alpha = 0;
	sparkle.x = (Math.random() - 0.5) * 600;
	sparkle.y = (Math.random() - 0.5) * 150;
	tween(sparkle, {
		alpha: 1,
		scaleX: 1.5,
		scaleY: 1.5
	}, {
		duration: 500,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(sparkle, {
				alpha: 0,
				scaleX: 0.5,
				scaleY: 0.5
			}, {
				duration: 500,
				easing: tween.easeIn,
				onFinish: function onFinish() {
					sparkle.destroy();
				}
			});
		}
	});
}
// Create sparkles periodically
var sparkleTimer = LK.setInterval(function () {
	if (titleOverlay.parent) {
		createTitleSparkle();
	} else {
		LK.clearInterval(sparkleTimer);
	}
}, 300);
// Subtitle with shadow
var subtitleShadow = new Text2('Tower Defense', {
	size: 60,
	fill: 0x000000
});
subtitleShadow.anchor.set(0.5, 0.5);
subtitleShadow.x = 2;
subtitleShadow.y = -464;
subtitleShadow.alpha = 0.5;
titleOverlay.addChild(subtitleShadow);
// Subtitle
var gameSubtitle = new Text2('Tower Defense', {
	size: 60,
	fill: 0x87CEEB
});
gameSubtitle.anchor.set(0.5, 0.5);
gameSubtitle.x = 0; // Center relative to overlay
gameSubtitle.y = -466; // Adjusted position relative to center
titleOverlay.addChild(gameSubtitle);
// Add continuous floating animation to subtitle
function startSubtitleAnimation() {
	tween(gameSubtitle, {
		scaleX: 1.05,
		scaleY: 1.05,
		y: -456,
		alpha: 0.9
	}, {
		duration: 2500,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(gameSubtitle, {
				scaleX: 0.95,
				scaleY: 0.95,
				y: -476,
				alpha: 1.0
			}, {
				duration: 2500,
				easing: tween.easeInOut,
				onFinish: startSubtitleAnimation
			});
		}
	});
}
startSubtitleAnimation();
// Add decorative statistics container
var statsContainer = new Container();
titleOverlay.addChild(statsContainer);
statsContainer.y = 450;
// Best wave text
var bestWaveText = new Text2('Best Wave: ' + (storage.bestWave || 0), {
	size: 36,
	fill: 0xFFD700
});
bestWaveText.anchor.set(0.5, 0.5);
bestWaveText.x = -300;
statsContainer.addChild(bestWaveText);
// Units defeated text
var unitsDefeatedText = new Text2('Enemies Defeated: ' + (storage.enemiesDefeated || 0), {
	size: 36,
	fill: 0xFF6666
});
unitsDefeatedText.anchor.set(0.5, 0.5);
unitsDefeatedText.x = 300;
statsContainer.addChild(unitsDefeatedText);
// Add subtle animation to stats
tween(statsContainer, {
	alpha: 0.8
}, {
	duration: 2000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(statsContainer, {
			alpha: 1.0
		}, {
			duration: 2000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Start Game button container
var startGameButton = new Container();
// Button shadow
var startButtonShadow = startGameButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 100
});
startButtonShadow.tint = 0x000000;
startButtonShadow.alpha = 0.3;
startButtonShadow.x = 4;
startButtonShadow.y = 4;
// Button gradient effect background
var startButtonGlow = startGameButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 420,
	height: 120
});
startButtonGlow.tint = 0x66FF66;
startButtonGlow.alpha = 0;
// Main button background
var startGameButtonBg = startGameButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 100
});
startGameButtonBg.tint = 0x4169E1; // Royal blue to match theme better
// Button text with shadow
var startButtonTextShadow = new Text2('Start Game', {
	size: 60,
	fill: 0x000000
});
startButtonTextShadow.anchor.set(0.5, 0.5);
startButtonTextShadow.x = 2;
startButtonTextShadow.y = 2;
startButtonTextShadow.alpha = 0.5;
startGameButton.addChild(startButtonTextShadow);
var startGameButtonText = new Text2('Start Game', {
	size: 60,
	fill: 0xFFFFFF
});
startGameButtonText.anchor.set(0.5, 0.5);
startGameButton.addChild(startGameButtonText);
startGameButton.x = 0; // Center relative to overlay
startGameButton.y = -66; // Move lower, more centered
titleOverlay.addChild(startGameButton);
// Add floating animation to start button
tween(startGameButton, {
	y: -56,
	scaleX: 1.05,
	scaleY: 1.05
}, {
	duration: 2000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(startGameButton, {
			y: -66,
			scaleX: 1.0,
			scaleY: 1.0
		}, {
			duration: 2000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Add continuous pulsing glow effect to start button
function pulseStartButton() {
	tween(startButtonGlow, {
		alpha: 0.3,
		scaleX: 1.1,
		scaleY: 1.1
	}, {
		duration: 1000,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(startButtonGlow, {
				alpha: 0,
				scaleX: 1.0,
				scaleY: 1.0
			}, {
				duration: 1000,
				easing: tween.easeIn,
				onFinish: pulseStartButton
			});
		}
	});
}
pulseStartButton();
// Add hover animation
startGameButton.down = function () {
	tween(startGameButtonBg, {
		scaleX: 0.95,
		scaleY: 0.95
	}, {
		duration: 100,
		easing: tween.easeOut
	});
	tween(startButtonGlow, {
		alpha: 0.7,
		scaleX: 1.2,
		scaleY: 1.2
	}, {
		duration: 200,
		easing: tween.easeOut
	});
};
// How to Play button container
var howToPlayButton = new Container();
// Button shadow
var howToPlayShadow = howToPlayButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 100
});
howToPlayShadow.tint = 0x000000;
howToPlayShadow.alpha = 0.3;
howToPlayShadow.x = 4;
howToPlayShadow.y = 4;
// Button glow effect
var howToPlayGlow = howToPlayButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 420,
	height: 120
});
howToPlayGlow.tint = 0x6666FF;
howToPlayGlow.alpha = 0;
// Main button background
var howToPlayButtonBg = howToPlayButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 100
});
howToPlayButtonBg.tint = 0x8A2BE2; // Blue violet for distinction
// Button text with shadow
var howToPlayTextShadow = new Text2('How to Play', {
	size: 60,
	fill: 0x000000
});
howToPlayTextShadow.anchor.set(0.5, 0.5);
howToPlayTextShadow.x = 2;
howToPlayTextShadow.y = 2;
howToPlayTextShadow.alpha = 0.5;
howToPlayButton.addChild(howToPlayTextShadow);
var howToPlayButtonText = new Text2('How to Play', {
	size: 60,
	fill: 0xFFFFFF
});
howToPlayButtonText.anchor.set(0.5, 0.5);
howToPlayButton.addChild(howToPlayButtonText);
howToPlayButton.x = 0; // Center relative to overlay
howToPlayButton.y = 84; // Move lower, more centered
titleOverlay.addChild(howToPlayButton);
// Add floating animation to how to play button with slight offset
tween(howToPlayButton, {
	y: 94,
	scaleX: 1.05,
	scaleY: 1.05
}, {
	duration: 2300,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(howToPlayButton, {
			y: 84,
			scaleX: 1.0,
			scaleY: 1.0
		}, {
			duration: 2300,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Create settings button
var settingsButton = new Container();
var settingsShadow = settingsButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 100,
	height: 100
});
settingsShadow.tint = 0x000000;
settingsShadow.alpha = 0.3;
settingsShadow.x = 4;
settingsShadow.y = 4;
var settingsGlow = settingsButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 120,
	height: 120
});
settingsGlow.tint = 0x6666FF;
settingsGlow.alpha = 0;
var settingsButtonBg = settingsButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 100,
	height: 100
});
settingsButtonBg.tint = 0x4B0082;
// Create gear icon using shapes
var gearIcon = new Container();
settingsButton.addChild(gearIcon);
// Gear center
var gearCenter = gearIcon.attachAsset('bullet', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 30,
	height: 30
});
gearCenter.tint = 0xFFFFFF;
// Gear teeth
for (var i = 0; i < 8; i++) {
	var tooth = gearIcon.attachAsset('shop_button', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 20
	});
	var angle = i * Math.PI / 4;
	tooth.x = Math.cos(angle) * 20;
	tooth.y = Math.sin(angle) * 20;
	tooth.rotation = angle;
	tooth.tint = 0xFFFFFF;
}
settingsButton.x = -800;
settingsButton.y = -1100;
titleOverlay.addChild(settingsButton);
// Animate gear rotation
tween(gearIcon, {
	rotation: Math.PI * 2
}, {
	duration: 10000,
	easing: tween.linear,
	onFinish: function onFinish() {
		gearIcon.rotation = 0;
		tween(gearIcon, {
			rotation: Math.PI * 2
		}, {
			duration: 10000,
			easing: tween.linear,
			onFinish: onFinish
		});
	}
});
settingsButton.down = function () {
	tween(settingsButtonBg, {
		scaleX: 0.9,
		scaleY: 0.9
	}, {
		duration: 100,
		easing: tween.easeOut
	});
};
settingsButton.up = function () {
	tween(settingsButtonBg, {
		scaleX: 1.0,
		scaleY: 1.0
	}, {
		duration: 100,
		easing: tween.easeIn
	});
	LK.getSound('purchase').play();
};
// Add hover animation
howToPlayButton.down = function () {
	tween(howToPlayButtonBg, {
		scaleX: 0.95,
		scaleY: 0.95
	}, {
		duration: 100,
		easing: tween.easeOut
	});
	tween(howToPlayGlow, {
		alpha: 0.7,
		scaleX: 1.2,
		scaleY: 1.2
	}, {
		duration: 200,
		easing: tween.easeOut
	});
};
// Add version and credits text
var versionText = new Text2('v1.0', {
	size: 24,
	fill: 0x666666
});
versionText.anchor.set(1, 1);
versionText.x = 900;
versionText.y = 1300;
titleOverlay.addChild(versionText);
// Add credits text
var creditsText = new Text2('Made with FRVR', {
	size: 24,
	fill: 0x666666
});
creditsText.anchor.set(0, 1);
creditsText.x = -900;
creditsText.y = 1300;
titleOverlay.addChild(creditsText);
// How to Play button click handler
howToPlayButton.up = function () {
	// Reset button scale
	tween(howToPlayButtonBg, {
		scaleX: 1.0,
		scaleY: 1.0
	}, {
		duration: 100,
		easing: tween.easeIn
	});
	tween(howToPlayGlow, {
		alpha: 0
	}, {
		duration: 200,
		easing: tween.easeIn
	});
	// Play sound effect
	LK.getSound('purchase').play();
	// Create how to play modal
	var howToPlayModal = new Container();
	var howToPlayModalBg = howToPlayModal.attachAsset('shop_area_bg', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 1600,
		height: 2000
	});
	howToPlayModalBg.alpha = 0.95;
	howToPlayModalBg.tint = 0x1a1a2e; // Dark blue theme
	howToPlayModalBg.x = 0;
	howToPlayModalBg.y = 0;
	// Modal title with fun subtitle
	var modalTitle = new Text2('How to Play', {
		size: 80,
		fill: 0xFFD700
	});
	modalTitle.anchor.set(0.5, 0.5);
	modalTitle.x = 0; // Center relative to modal
	modalTitle.y = -900; // Adjusted position relative to center
	howToPlayModal.addChild(modalTitle);
	// Fun subtitle
	var subtitle = new Text2('Master the Art of Tower Defense!', {
		size: 40,
		fill: 0x87CEEB // Sky blue for planning
	});
	subtitle.anchor.set(0.5, 0.5);
	subtitle.x = 0;
	subtitle.y = -820;
	howToPlayModal.addChild(subtitle);
	// Game mechanics section
	var mechanicsTitle = new Text2('— Game Basics —', {
		size: 48,
		fill: 0xFFD700
	});
	mechanicsTitle.anchor.set(0.5, 0.5);
	mechanicsTitle.x = 0;
	mechanicsTitle.y = -700;
	howToPlayModal.addChild(mechanicsTitle);
	// Instructions with better spacing
	var basicInstructions = ['💰 Purchase units from the shop using gold', '🎯 Drag units to the battlefield grid', '⚔️ Units auto-battle enemies in range', '⭐ Merge 3 identical units for upgrades', '👑 Level up your King for more capacity', '🛡️ Protect your King at all costs!', '🌊 Survive 10 waves to claim victory!'];
	for (var i = 0; i < basicInstructions.length; i++) {
		var instructionText = new Text2(basicInstructions[i], {
			size: 36,
			fill: 0xFFFFFF
		});
		instructionText.anchor.set(0.5, 0.5);
		instructionText.x = 0; // Horizontally centered
		instructionText.y = -550 + i * 60; // Better spacing
		howToPlayModal.addChild(instructionText);
	}
	// Unit showcase title
	var unitsTitle = new Text2('— Meet Your Units —', {
		size: 48,
		fill: 0xFFD700
	});
	unitsTitle.anchor.set(0.5, 0.5);
	unitsTitle.x = 0;
	unitsTitle.y = -50;
	howToPlayModal.addChild(unitsTitle);
	// Create unit showcase with actual unit graphics
	var unitShowcase = [{
		unit: new Soldier(),
		desc: 'Soldier: Swift melee warrior',
		x: -600,
		y: 100
	}, {
		unit: new Knight(),
		desc: 'Knight: Tanky defender',
		x: -200,
		y: 100
	}, {
		unit: new Wizard(),
		desc: 'Wizard: Magic damage dealer',
		x: 200,
		y: 100
	}, {
		unit: new Ranger(),
		desc: 'Ranger: Long-range archer',
		x: 600,
		y: 100
	}, {
		unit: new Paladin(),
		desc: 'Paladin: Elite warrior',
		x: -400,
		y: 350
	}, {
		unit: new Wall(),
		desc: 'Wall: Defensive structure',
		x: 0,
		y: 350
	}, {
		unit: new CrossbowTower(),
		desc: 'Tower: Area controller',
		x: 400,
		y: 350
	}];
	// Add units with animations
	for (var i = 0; i < unitShowcase.length; i++) {
		var showcase = unitShowcase[i];
		var unitDisplay = showcase.unit;
		unitDisplay.x = showcase.x;
		unitDisplay.y = showcase.y;
		unitDisplay.scaleX = 0.8;
		unitDisplay.scaleY = 0.8;
		howToPlayModal.addChild(unitDisplay);
		// Add floating animation
		var baseY = unitDisplay.y;
		tween(unitDisplay, {
			y: baseY - 15,
			scaleX: 0.85,
			scaleY: 0.85
		}, {
			duration: 1500 + Math.random() * 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(unitDisplay, {
					y: baseY,
					scaleX: 0.8,
					scaleY: 0.8
				}, {
					duration: 1500 + Math.random() * 500,
					easing: tween.easeInOut,
					onFinish: onFinish
				});
			}
		});
		// Add unit description
		var unitDesc = new Text2(showcase.desc, {
			size: 28,
			fill: 0xFFFFFF
		});
		unitDesc.anchor.set(0.5, 0);
		unitDesc.x = showcase.x;
		unitDesc.y = showcase.y + 60;
		howToPlayModal.addChild(unitDesc);
	}
	// Enemy warning section
	var enemyWarning = new Text2('⚠️ Enemies spawn from the fog of war above! ⚠️', {
		size: 40,
		fill: 0xFF4444
	});
	enemyWarning.anchor.set(0.5, 0.5);
	enemyWarning.x = 0;
	enemyWarning.y = 600;
	howToPlayModal.addChild(enemyWarning);
	// Tips section
	var tipsText = new Text2('💡 Pro Tip: Save gold for interest bonus!', {
		size: 36,
		fill: 0x44FF44
	});
	tipsText.anchor.set(0.5, 0.5);
	tipsText.x = 0;
	tipsText.y = 700;
	howToPlayModal.addChild(tipsText);
	// Close button
	var closeButton = new Container();
	var closeButtonBg = closeButton.attachAsset('shop_button', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 300,
		height: 100
	});
	closeButtonBg.tint = 0xFF4444;
	var closeButtonText = new Text2('Got it!', {
		size: 60,
		fill: 0xFFFFFF
	});
	closeButtonText.anchor.set(0.5, 0.5);
	closeButton.addChild(closeButtonText);
	closeButton.x = 0; // Center relative to modal
	closeButton.y = 850; // Bottom of modal
	howToPlayModal.addChild(closeButton);
	closeButton.up = function () {
		howToPlayModal.destroy();
	};
	titleOverlay.addChild(howToPlayModal);
};
// Start Game button click handler
startGameButton.up = function () {
	// Reset button scale
	tween(startGameButtonBg, {
		scaleX: 1.0,
		scaleY: 1.0
	}, {
		duration: 100,
		easing: tween.easeIn
	});
	tween(startButtonGlow, {
		alpha: 0
	}, {
		duration: 200,
		easing: tween.easeIn
	});
	// Play purchase sound for feedback
	LK.getSound('purchase').play();
	// Stop main menu music and play background music when battle actually starts
	// Create expanding circle transition effect
	var transitionCircle = titleOverlay.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 50,
		height: 50
	});
	transitionCircle.tint = 0xFFD700;
	transitionCircle.x = 0;
	transitionCircle.y = -266; // Start from button position
	tween(transitionCircle, {
		scaleX: 100,
		scaleY: 100,
		alpha: 0.8
	}, {
		duration: 600,
		easing: tween.easeOut
	});
	// Hide title overlay with fade animation
	tween(titleOverlay, {
		alpha: 0
	}, {
		duration: 500,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			// Clear timers
			LK.clearInterval(particleTimer);
			LK.clearInterval(sparkleTimer);
			titleOverlay.destroy();
		}
	});
};
// Add title overlay to LK.gui.center to ensure it renders above all game elements
LK.gui.center.addChild(titleOverlay);
// Play main menu music when title overlay is shown
LK.playMusic('mainmenu_music');
// Create animated castle silhouette in background
var castleContainer = new Container();
titleOverlay.addChild(castleContainer);
castleContainer.y = 300;
castleContainer.alpha = 0.3;
// Create castle towers
var leftTower = castleContainer.attachAsset('wall', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 150,
	height: 300
});
leftTower.x = -400;
leftTower.tint = 0x1a1a2e;
var centerTower = castleContainer.attachAsset('wall', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 200,
	height: 400
});
centerTower.x = 0;
centerTower.tint = 0x16213e;
var rightTower = castleContainer.attachAsset('wall', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 150,
	height: 300
});
rightTower.x = 400;
rightTower.tint = 0x1a1a2e;
// Animate castle floating
tween(castleContainer, {
	y: 320,
	alpha: 0.25
}, {
	duration: 4000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(castleContainer, {
			y: 300,
			alpha: 0.3
		}, {
			duration: 4000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// No need to set x,y as gui.center is already centered
// Add enhanced title animation with rotation - constant loop
function startTitleAnimation() {
	tween(titleContainer, {
		scaleX: 1.05,
		scaleY: 1.05,
		rotation: 0.02
	}, {
		duration: 2000,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(titleContainer, {
				scaleX: 0.95,
				scaleY: 0.95,
				rotation: -0.02
			}, {
				duration: 2000,
				easing: tween.easeInOut,
				onFinish: startTitleAnimation
			});
		}
	});
}
startTitleAnimation();
// Add decorative crown above title
var crownContainer = new Container();
titleOverlay.addChild(crownContainer);
crownContainer.y = -666;
// Create pixelart crown
var crownBase = crownContainer.attachAsset('king', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 80,
	height: 30
});
crownBase.tint = 0xFFD700;
var crownLeft = crownContainer.attachAsset('king', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 20,
	height: 40
});
crownLeft.x = -25;
crownLeft.y = -20;
crownLeft.tint = 0xFFD700;
var crownCenter = crownContainer.attachAsset('king', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 25,
	height: 50
});
crownCenter.x = 0;
crownCenter.y = -25;
crownCenter.tint = 0xFFD700;
var crownRight = crownContainer.attachAsset('king', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 20,
	height: 40
});
crownRight.x = 25;
crownRight.y = -20;
crownRight.tint = 0xFFD700;
// Add jewels to crown
var jewelLeft = crownContainer.attachAsset('bullet', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 12,
	height: 12
});
jewelLeft.x = -25;
jewelLeft.y = -35;
jewelLeft.tint = 0xFF0000;
var jewelCenter = crownContainer.attachAsset('bullet', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 15,
	height: 15
});
jewelCenter.x = 0;
jewelCenter.y = -45;
jewelCenter.tint = 0x4169E1;
var jewelRight = crownContainer.attachAsset('bullet', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 12,
	height: 12
});
jewelRight.x = 25;
jewelRight.y = -35;
jewelRight.tint = 0xFF0000;
// Add sparkle animations to jewels
tween(jewelLeft, {
	scaleX: 1.3,
	scaleY: 1.3,
	alpha: 0.8
}, {
	duration: 1000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(jewelLeft, {
			scaleX: 1.0,
			scaleY: 1.0,
			alpha: 1.0
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Offset timing for center jewel
LK.setTimeout(function () {
	tween(jewelCenter, {
		scaleX: 1.4,
		scaleY: 1.4,
		alpha: 0.7
	}, {
		duration: 1200,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(jewelCenter, {
				scaleX: 1.0,
				scaleY: 1.0,
				alpha: 1.0
			}, {
				duration: 1200,
				easing: tween.easeInOut,
				onFinish: onFinish
			});
		}
	});
}, 400);
// Offset timing for right jewel
LK.setTimeout(function () {
	tween(jewelRight, {
		scaleX: 1.3,
		scaleY: 1.3,
		alpha: 0.8
	}, {
		duration: 1000,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(jewelRight, {
				scaleX: 1.0,
				scaleY: 1.0,
				alpha: 1.0
			}, {
				duration: 1000,
				easing: tween.easeInOut,
				onFinish: onFinish
			});
		}
	});
}, 800);
// Animate crown floating with enhanced effects
function startCrownAnimation() {
	tween(crownContainer, {
		y: -656,
		rotation: 0.08,
		scaleX: 1.1,
		scaleY: 1.1
	}, {
		duration: 2200,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(crownContainer, {
				y: -676,
				rotation: -0.08,
				scaleX: 0.9,
				scaleY: 0.9
			}, {
				duration: 2200,
				easing: tween.easeInOut,
				onFinish: startCrownAnimation
			});
		}
	});
}
startCrownAnimation();
// Add enemy preview showcase
var enemyShowcase = new Container();
titleOverlay.addChild(enemyShowcase);
enemyShowcase.y = 700;
enemyShowcase.alpha = 0.6;
// Create actual enemy units for showcase
var showcaseEnemies = [];
var enemyTypes = [{
	type: 'regular',
	x: -400,
	constructor: Enemy
}, {
	type: 'ranged',
	x: 0,
	constructor: RangedEnemy
}, {
	type: 'boss',
	x: 400,
	constructor: Boss
}];
var _loop = function _loop() {
		enemyData = enemyTypes[i]; // Create actual enemy unit
		showcaseEnemy = new enemyData.constructor();
		showcaseEnemy.x = enemyData.x;
		showcaseEnemy.y = 0;
		// Scale down the enemy for showcase
		showcaseEnemy.scaleX = 0.6;
		showcaseEnemy.scaleY = 0.6;
		enemyShowcase.addChild(showcaseEnemy);
		showcaseEnemies.push(showcaseEnemy);
		// Add floating animation with different timing for each enemy
		baseY = showcaseEnemy.y;
		floatDelay = i * 300; // Stagger the animations
		floatDuration = 2000 + Math.random() * 1000; // Randomize duration slightly
		function startFloatingAnimation(enemy, baseY, delay) {
			LK.setTimeout(function () {
				function floatUp() {
					tween(enemy, {
						y: baseY - 20,
						scaleX: 0.66,
						scaleY: 0.66,
						rotation: 0.08
					}, {
						duration: floatDuration,
						easing: tween.easeInOut,
						onFinish: floatDown
					});
				}
				function floatDown() {
					tween(enemy, {
						y: baseY + 10,
						scaleX: 0.54,
						scaleY: 0.54,
						rotation: -0.08
					}, {
						duration: floatDuration,
						easing: tween.easeInOut,
						onFinish: floatUp
					});
				}
				floatUp(); // Start the animation cycle
			}, delay);
		}
		// Start floating animation for this enemy
		startFloatingAnimation(showcaseEnemy, baseY, floatDelay);
		// Add breathing/idle animation - slight scale pulsing
		function startBreathingAnimation(enemy, delay) {
			LK.setTimeout(function () {
				function breatheIn() {
					tween(enemy, {
						scaleX: enemy.scaleX * 1.05,
						scaleY: enemy.scaleY * 1.05
					}, {
						duration: 800,
						easing: tween.easeInOut,
						onFinish: breatheOut
					});
				}
				function breatheOut() {
					tween(enemy, {
						scaleX: enemy.scaleX / 1.05,
						scaleY: enemy.scaleY / 1.05
					}, {
						duration: 800,
						easing: tween.easeInOut,
						onFinish: breatheIn
					});
				}
				breatheIn(); // Start the breathing cycle
			}, delay + 400); // Offset from floating animation
		}
		// Start breathing animation for this enemy
		startBreathingAnimation(showcaseEnemy, floatDelay);
		// Add menacing glow effect for boss enemy
		if (enemyData.type === 'boss') {
			var startGlowAnimation = function startGlowAnimation(enemy) {
				function glowUp() {
					LK.effects.flashObject(enemy, 0xFF0000, 300); // Red flash
					LK.setTimeout(glowDown, 300);
				}
				function glowDown() {
					LK.setTimeout(glowUp, 2000 + Math.random() * 1000); // Random interval
				}
				LK.setTimeout(glowUp, 1000); // Start after 1 second
			};
			startGlowAnimation(showcaseEnemy);
		}
		// Add special effect for ranged enemy - slight weapon sway
		if (enemyData.type === 'ranged') {
			var startWeaponSway = function startWeaponSway(enemy) {
				function swayLeft() {
					tween(enemy, {
						rotation: enemy.rotation - 0.05
					}, {
						duration: 1500,
						easing: tween.easeInOut,
						onFinish: swayRight
					});
				}
				function swayRight() {
					tween(enemy, {
						rotation: enemy.rotation + 0.1
					}, {
						duration: 1500,
						easing: tween.easeInOut,
						onFinish: swayLeft
					});
				}
				LK.setTimeout(swayLeft, floatDelay + 600);
			};
			startWeaponSway(showcaseEnemy);
		}
	},
	enemyData,
	showcaseEnemy,
	baseY,
	floatDelay,
	floatDuration;
for (var i = 0; i < enemyTypes.length; i++) {
	_loop();
}
var GRID_COLS = 9;
var GRID_ROWS = 9;
var GRID_CELL_SIZE = 227; // 2048 / 9 ≈ 227
var GRID_START_X = (2048 - GRID_COLS * GRID_CELL_SIZE) / 2;
var GRID_START_Y = 100;
var PLAYABLE_HEIGHT = 2400; // Define playable game area
var enemies = [];
var units = [];
var bullets = [];
var enemyProjectiles = [];
var bench = [];
var grid = [];
var benchSlots = [];
var gold = 5;
var wave = 1;
var enemiesSpawned = 0;
var enemiesPerWave = 5;
var waveDelay = 0;
var draggedUnit = null;
var draggedFromGrid = false;
var gameState = 'planning'; // 'planning' or 'battle'
var stateText = new Text2('', {
	size: 40,
	fill: 0x44FF44 // Default to green for planning phase
});
stateText.anchor.set(0.5, 0.5);
stateText.x = 0; // Center relative to topUIContainer
stateText.y = 140; // Adjusted for bigger UI
topUIContainer = new Container(); // Container for top UI elements
topUIContainer.addChild(stateText);
var waveText = new Text2('Wave: 1', {
	size: 40,
	fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0.5);
waveText.x = 0; // Center relative to topUIContainer
waveText.y = 140; // Adjusted for bigger UI
topUIContainer.addChild(waveText);
var goldText; // Declare goldText variable
var kingInfoButton; // Declare kingInfoButton variable
var cellReservations = {}; // Track reserved cells during movement
var entityPositions = {}; // Track exact entity positions to prevent overlap
var movementQueue = []; // Queue movements to prevent simultaneous conflicts
var playerLevel = 1; // Player's current level
var maxUnitsOnField = 2; // Starting with 2 units max
var maxStructuresOnField = 2; // Starting with 2 structures max
var structuresOnField = 0; // Track structures placed
var unitsOnField = 0; // Track regular units placed
var enemyContainer = new Container(); // Container for enemies to render below fog
topUIContainer = new Container(); // Container for top UI elements
var isUIMinimized = false; // Track UI state
// Helper function to register entity position
function registerEntityPosition(entity) {
	if (entity.gridX >= 0 && entity.gridY >= 0) {
		var posKey = entity.gridX + ',' + entity.gridY;
		entityPositions[posKey] = entity;
	}
}
// Helper function to unregister entity position
function unregisterEntityPosition(entity, oldGridX, oldGridY) {
	var posKey = oldGridX + ',' + oldGridY;
	if (entityPositions[posKey] === entity) {
		delete entityPositions[posKey];
	}
}
// Helper function to check if position is occupied by any entity
function isPositionOccupied(gridX, gridY, excludeEntity) {
	var posKey = gridX + ',' + gridY;
	var occupant = entityPositions[posKey];
	return occupant && occupant !== excludeEntity;
}
// Function to calculate level up cost
function getLevelUpCost(level) {
	return level * 4; // Cost increases by 4 gold per level
}
// Function to count units on field
function countUnitsOnField() {
	structuresOnField = 0;
	unitsOnField = 0;
	for (var y = 0; y < GRID_ROWS; y++) {
		for (var x = 0; x < GRID_COLS; x++) {
			if (grid[y] && grid[y][x] && grid[y][x].unit) {
				var unit = grid[y][x].unit;
				// Skip king - it doesn't count towards any limit
				if (unit.name === "King") {
					continue; // Don't count king
				}
				if (unit.isStructure) {
					structuresOnField++;
				} else {
					unitsOnField++;
				}
			}
		}
	}
	// Update the max units text display
	maxUnitsText.setText('Units: ' + unitsOnField + '/' + maxUnitsOnField + ' | Structures: ' + structuresOnField + '/' + maxStructuresOnField);
}
// Function to check if can place more units
function canPlaceMoreUnits(isStructure) {
	countUnitsOnField();
	if (isStructure) {
		return structuresOnField < maxStructuresOnField;
	} else {
		return unitsOnField < maxUnitsOnField;
	}
}
// Function to level up player
function levelUpPlayer() {
	var cost = getLevelUpCost(playerLevel);
	if (gold >= cost) {
		gold -= cost;
		playerLevel++;
		maxUnitsOnField++; // Increase unit limit by 1
		maxStructuresOnField++; // Increase structure limit by 1
		goldText.setText(gold.toString());
		levelText.setText('King Lvl: ' + playerLevel);
		countUnitsOnField(); // Update counts and display
		// Level up the king
		levelUpKing();
		// Play purchase sound
		LK.getSound('purchase').play();
		// Visual effect
		LK.effects.flashScreen(0xFFD700, 500);
	}
}
// Function to level up king
function levelUpKing() {
	if (kings.length > 0) {
		var king = kings[0];
		// Increase king stats
		king.health = Math.floor(king.health * 1.1);
		king.maxHealth = Math.floor(king.maxHealth * 1.1);
		king.damage = Math.floor(king.damage * 1.1);
		king.armor = Math.floor(king.armor * 1.1);
		king.magicResist = Math.floor(king.magicResist * 1.1);
		// Increase king scale by 10%
		var currentScale = king.scaleX;
		var newScale = currentScale * 1.1;
		tween(king, {
			scaleX: newScale,
			scaleY: newScale
		}, {
			duration: 500,
			easing: tween.easeOut
		});
		// Update health bar
		king.updateHealthBar();
		// Flash effect
		LK.effects.flashObject(king, 0xFFD700, 800);
	}
}
// AttackInfo display removed
// Double-tap detection variables
var lastTapTime = 0;
var lastTapX = 0;
var lastTapY = 0;
var doubleTapDelay = 300; // 300ms window for double tap
var doubleTapDistance = 50; // Max distance between taps
// Add enemy container to game first (so it renders below everything else)
game.addChild(enemyContainer);
// Create grid slots
for (var y = 0; y < GRID_ROWS; y++) {
	grid[y] = [];
	for (var x = 0; x < GRID_COLS; x++) {
		var gridSlot = game.addChild(new GridSlot(0, x, y)); // Using lane 0 for all slots
		// Calculate exact position for grid slot
		var slotX = GRID_START_X + x * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		var slotY = GRID_START_Y + y * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		gridSlot.x = slotX;
		gridSlot.y = slotY;
		grid[y][x] = gridSlot;
	}
}
// Create fog of war containers array to add later (after enemies spawn)
var fogOverlays = [];
// Create fog of war for top two rows
for (var y = 0; y < 2; y++) {
	for (var x = 0; x < GRID_COLS; x++) {
		var fogOverlay = new Container();
		var fogGraphics = fogOverlay.attachAsset('grid_slot', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: GRID_CELL_SIZE - 10,
			height: GRID_CELL_SIZE - 10
		});
		fogGraphics.tint = 0x000000; // Black fog
		fogGraphics.alpha = 0.3; // More transparent to see enemies underneath
		fogOverlay.x = GRID_START_X + x * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		fogOverlay.y = GRID_START_Y + y * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		// Add some fog texture variation
		var fogDetail = fogOverlay.attachAsset('grid_slot', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: GRID_CELL_SIZE * 0.8,
			height: GRID_CELL_SIZE * 0.8
		});
		fogDetail.tint = 0x222222;
		fogDetail.alpha = 0.2; // More transparent detail layer
		fogDetail.rotation = Math.random() * 0.2 - 0.1;
		// Store fog overlays to add later
		fogOverlays.push(fogOverlay);
	}
}
// Create king at bottom center of grid
var kings = [];
var king = game.addChild(new King());
// Place king at center column (column 4 for 9x9 grid)
var kingGridX = 4;
var kingGridY = GRID_ROWS - 1;
// Get the exact grid slot and place king there
var kingSlot = grid[kingGridY][kingGridX];
kingSlot.unit = king;
king.gridX = kingGridX;
king.gridY = kingGridY;
king.lane = 0;
// Set king position to match grid slot exactly
king.x = kingSlot.x;
king.y = kingSlot.y;
// King already has baseScale from Unit class, ensure it's applied
king.updateUnitScale();
king.showHealthBar(); // Show health bar for king from start
kings.push(king);
// Register king position
registerEntityPosition(king);
// Create info button for king
var kingInfoButton = new Container();
var kingInfoButtonBg = kingInfoButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 80,
	height: 40
});
kingInfoButtonBg.tint = 0x4444FF;
var kingInfoButtonText = new Text2('Info', {
	size: 32,
	fill: 0xFFFFFF
});
kingInfoButtonText.anchor.set(0.5, 0.5);
kingInfoButton.addChild(kingInfoButtonText);
kingInfoButton.x = king.x;
kingInfoButton.y = king.y + 100; // Position below king
game.addChild(kingInfoButton);
kingInfoButton.up = function () {
	showUnitInfoModal(king);
};
// Create bench area background
var benchAreaBg = game.addChild(LK.getAsset('bench_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5
}));
benchAreaBg.x = 1024; // Center of screen
benchAreaBg.y = PLAYABLE_HEIGHT - 120; // Move bench up by 40px
benchAreaBg.alpha = 0.7;
// Create bench slots
var benchTotalWidth = 9 * 120 + 8 * 40; // 9 slots of 120px width with 40px spacing
var benchStartX = (2048 - benchTotalWidth) / 2 + 60; // Center horizontally
for (var i = 0; i < 9; i++) {
	var benchSlot = game.addChild(new BenchSlot(i));
	benchSlot.x = benchStartX + i * 160;
	benchSlot.y = PLAYABLE_HEIGHT - 120; // Move bench up by 40px
	benchSlots[i] = benchSlot;
}
// Shop configuration
var shopSlots = [];
var unitPool = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2]; // Pool of available unit tiers
var refreshCost = 2;
// Calculate shop area dimensions
var benchBottomY = PLAYABLE_HEIGHT - 120 + 100; // Bench center + half height
var screenBottomY = 2732; // Full screen height
var shopAreaHeight = screenBottomY - benchBottomY;
var shopCenterY = benchBottomY + shopAreaHeight / 2;
// Create shop area background
var shopAreaBg = game.addChild(LK.getAsset('shop_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 2048,
	height: shopAreaHeight
}));
shopAreaBg.x = 1024; // Center of screen
shopAreaBg.y = shopCenterY; // Center vertically in available space
shopAreaBg.alpha = 0.6;
// Create shop slots
var shopTotalWidth = 5 * 200 + 4 * 40; // 5 slots of 200px width with 40px spacing
var shopStartX = (2048 - shopTotalWidth) / 2 + 60; // Center horizontally
for (var i = 0; i < 5; i++) {
	var shopSlot = game.addChild(new Container());
	shopSlot.x = shopStartX + i * 240;
	shopSlot.y = PLAYABLE_HEIGHT + 150; // Position shop units further down
	shopSlot.index = i;
	shopSlot.unit = null;
	shopSlot.tierText = null;
	shopSlot.nameText = null;
	shopSlots.push(shopSlot);
}
// Create refresh button
var refreshButton = game.addChild(new Container());
var refreshButtonBg = refreshButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 280,
	height: 120
});
refreshButtonBg.tint = 0xFF8800;
var refreshText1 = new Text2('Refresh', {
	size: 48,
	fill: 0xFFFFFF
});
refreshText1.anchor.set(0.5, 0.5);
refreshText1.y = -20;
refreshButton.addChild(refreshButtonBg);
refreshButton.addChild(refreshText1);
var refreshText2 = new Text2('Shop', {
	size: 48,
	fill: 0xFFFFFF
});
refreshText2.anchor.set(0.5, 0.5);
refreshText2.y = 20;
refreshButton.addChild(refreshText2);
refreshButton.x = 2048 - 200;
refreshButton.y = PLAYABLE_HEIGHT + 100; // Move button higher
refreshButton.up = function () {
	if (gold >= refreshCost) {
		gold -= refreshCost;
		goldText.setText(gold.toString());
		refreshShop();
		LK.getSound('purchase').play();
	}
};
// Create level up button
var levelUpButton = game.addChild(new Container());
var levelUpButtonBg = levelUpButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 280,
	height: 120
});
levelUpButtonBg.tint = 0xFF8800;
var levelUpText = new Text2('Level Up', {
	size: 48,
	fill: 0xFFFFFF
});
levelUpText.anchor.set(0.5, 0.5);
levelUpButton.addChild(levelUpText);
levelUpButton.x = 200;
levelUpButton.y = PLAYABLE_HEIGHT + 100; // Move button higher
levelUpButton.up = function () {
	levelUpPlayer();
};
// Create level up cost text
var levelUpCostText = new Text2('Cost: ' + getLevelUpCost(playerLevel) + 'g', {
	size: 42,
	fill: 0xFFD700
});
levelUpCostText.anchor.set(0.5, 0);
levelUpCostText.x = 200;
levelUpCostText.y = PLAYABLE_HEIGHT + 200;
game.addChild(levelUpCostText);
// Create refresh cost text
var refreshCostText = new Text2('Cost: ' + refreshCost + 'g', {
	size: 42,
	fill: 0xFFD700
});
refreshCostText.anchor.set(0.5, 0);
refreshCostText.x = 2048 - 200;
refreshCostText.y = PLAYABLE_HEIGHT + 200;
game.addChild(refreshCostText);
// Function to refresh shop with new units
function refreshShop() {
	// Clear existing shop units
	for (var i = 0; i < shopSlots.length; i++) {
		if (shopSlots[i].unit) {
			shopSlots[i].unit.destroy();
			shopSlots[i].unit = null;
		}
		if (shopSlots[i].tierText) {
			shopSlots[i].tierText.destroy();
			shopSlots[i].tierText = null;
		}
		if (shopSlots[i].nameText) {
			shopSlots[i].nameText.destroy();
			shopSlots[i].nameText = null;
		}
		if (shopSlots[i].infoButton) {
			shopSlots[i].infoButton.destroy();
			shopSlots[i].infoButton = null;
		}
	}
	// Fill shop with new random units
	for (var i = 0; i < shopSlots.length; i++) {
		var randomTier = unitPool[Math.floor(Math.random() * unitPool.length)];
		var shopUnit;
		var unitConstructor;
		switch (randomTier) {
			case 1:
				var unitTypes = [Soldier, Knight, Wall];
				unitConstructor = unitTypes[Math.floor(Math.random() * unitTypes.length)];
				shopUnit = new unitConstructor();
				break;
			case 2:
				var unitTypes = [Wizard, Paladin, Ranger, CrossbowTower];
				unitConstructor = unitTypes[Math.floor(Math.random() * unitTypes.length)];
				shopUnit = new unitConstructor();
				break;
		}
		shopUnit.x = shopSlots[i].x;
		shopUnit.y = shopSlots[i].y; // Center the unit in the shop slot
		game.addChild(shopUnit);
		shopSlots[i].unit = shopUnit;
		shopSlots[i].unitConstructor = unitConstructor; // Store the constructor reference
		// Add gentle floating animation for shop units
		var baseY = shopUnit.y;
		tween(shopUnit, {
			y: baseY - 10
		}, {
			duration: 1000 + Math.random() * 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(shopUnit, {
					y: baseY
				}, {
					duration: 1000 + Math.random() * 500,
					easing: tween.easeInOut,
					onFinish: onFinish
				});
			}
		});
		// Add unit name text above the image with more spacing
		var nameText = new Text2(shopUnit.name, {
			size: 36,
			fill: 0xFFFFFF
		});
		nameText.anchor.set(0.5, 1); //{3P} // Anchor to bottom center
		nameText.x = shopSlots[i].x;
		nameText.y = shopSlots[i].y - 100; // Position higher above the unit image
		game.addChild(nameText);
		shopSlots[i].nameText = nameText;
		// Add cost text below the image with more spacing
		var cost = randomTier;
		// Special cost for Wall (1g) and CrossbowTower (2g)
		if (shopUnit.name === "Wall") {
			cost = 1;
		} else if (shopUnit.name === "CrossbowTower") {
			cost = 2;
		}
		var costText = new Text2(cost + 'g', {
			size: 36,
			fill: 0xFFD700
		});
		costText.anchor.set(0.5, 0);
		costText.x = shopSlots[i].x;
		costText.y = shopSlots[i].y + 70; // Position well below the unit image
		game.addChild(costText);
		shopSlots[i].tierText = costText;
		// Add info button below cost
		var infoButton = new Container();
		var infoButtonBg = infoButton.attachAsset('shop_button', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 80,
			height: 40
		});
		infoButtonBg.tint = 0x4444FF;
		var infoButtonText = new Text2('Info', {
			size: 32,
			fill: 0xFFFFFF
		});
		infoButtonText.anchor.set(0.5, 0.5);
		infoButton.addChild(infoButtonText);
		infoButton.x = shopSlots[i].x;
		infoButton.y = shopSlots[i].y + 130; // Position below cost text with more spacing
		game.addChild(infoButton);
		shopSlots[i].infoButton = infoButton;
		// Store unit reference on info button for click handler
		infoButton.shopUnit = shopUnit;
		infoButton.up = function () {
			showUnitInfoModal(this.shopUnit);
		};
	}
}
// Function to show unit info modal
function showUnitInfoModal(unit) {
	// Create modal overlay
	var modalOverlay = game.addChild(new Container());
	modalOverlay.x = 1024; // Center of screen
	modalOverlay.y = 1366; // Center of screen
	// Create modal background
	var modalBg = modalOverlay.attachAsset('shop_area_bg', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 600,
		height: 800
	});
	modalBg.alpha = 0.95;
	// Add title
	var titleText = new Text2(unit.name, {
		size: 48,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.y = -350;
	modalOverlay.addChild(titleText);
	// Add attributes
	var attributes = ['Health: ' + unit.maxHealth, 'Damage: ' + unit.damage, 'Armor: ' + unit.armor, 'Magic Resist: ' + unit.magicResist, 'Critical Chance: ' + unit.criticalChance * 100 + '%', 'Mana: ' + unit.mana, 'Attack Speed: ' + unit.speed, 'Range: ' + unit.range];
	for (var i = 0; i < attributes.length; i++) {
		var attrText = new Text2(attributes[i], {
			size: 36,
			fill: 0xFFFFFF
		});
		attrText.anchor.set(0.5, 0.5);
		attrText.y = -250 + i * 60;
		modalOverlay.addChild(attrText);
	}
	// Add close button
	var closeButton = new Container();
	var closeButtonBg = closeButton.attachAsset('shop_button', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 150,
		height: 60
	});
	closeButtonBg.tint = 0xFF4444;
	var closeButtonText = new Text2('Close', {
		size: 36,
		fill: 0xFFFFFF
	});
	closeButtonText.anchor.set(0.5, 0.5);
	closeButton.addChild(closeButtonText);
	closeButton.y = 330;
	modalOverlay.addChild(closeButton);
	closeButton.up = function () {
		modalOverlay.destroy();
	};
}
// Initialize shop with units
refreshShop();
// Add fog overlays on top of everything to ensure they render above enemies
for (var i = 0; i < fogOverlays.length; i++) {
	game.addChild(fogOverlays[i]);
}
// Create top UI container
topUIContainer = game.addChild(topUIContainer);
topUIContainer.x = 1024; // Center of screen
topUIContainer.y = 10; // Top of screen with small margin
// Create top UI container background - bigger initially for planning phase
var topUIBg = topUIContainer.addChild(LK.getAsset('bench_area_bg', {
	anchorX: 0.5,
	anchorY: 0,
	width: 1800,
	height: 240 // Bigger height for planning phase
}));
topUIBg.alpha = 0.7;
topUIBg.tint = 0x0a0a1a; // Match the deep dark blue of the title screen
// Create top row elements (Coin, Level, Max Units)
var goldContainer = new Container();
goldContainer.x = 650; // Relative to topUIContainer
goldContainer.y = 60; // Adjusted for bigger UI
topUIContainer.addChild(goldContainer);
// Create detailed pixelart coin
var coinContainer = new Container();
goldContainer.addChild(coinContainer);
coinContainer.x = -50; // Move coin further left to increase spacing
// Coin base (outer ring)
var coinBase = coinContainer.attachAsset('coin_base', {
	anchorX: 0.5,
	anchorY: 0.5
});
// Coin inner ring
var coinInner = coinContainer.attachAsset('coin_inner', {
	anchorX: 0.5,
	anchorY: 0.5
});
// Coin center
var coinCenter = coinContainer.attachAsset('coin_center', {
	anchorX: 0.5,
	anchorY: 0.5
});
// Coin highlight for shine effect
var coinHighlight = coinContainer.attachAsset('coin_highlight', {
	anchorX: 0.5,
	anchorY: 0.5
});
coinHighlight.x = -6;
coinHighlight.y = -6;
// Add subtle rotation animation to make coin feel alive
tween(coinContainer, {
	rotation: 0.1
}, {
	duration: 2000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(coinContainer, {
			rotation: -0.1
		}, {
			duration: 2000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
goldText = new Text2(gold.toString(), {
	size: 50,
	fill: 0xFFD700
});
goldText.anchor.set(0.5, 0.5);
goldText.x = 40; // Move number further right to create more space
goldContainer.addChild(goldText);
var levelText = new Text2('King Lvl: ' + playerLevel, {
	size: 50,
	fill: 0x87CEEB
});
levelText.anchor.set(0.5, 0.5);
levelText.x = 0; // Center relative to topUIContainer
levelText.y = 60; // Adjusted for bigger UI
topUIContainer.addChild(levelText);
var maxUnitsText = new Text2('Units: 0/' + maxUnitsOnField + ' | Structures: 0/' + maxStructuresOnField, {
	size: 50,
	fill: 0xFFD700
});
maxUnitsText.anchor.set(0.5, 0.5);
maxUnitsText.x = -500; // Left of center relative to topUIContainer
maxUnitsText.y = 60; // Adjusted for bigger UI
topUIContainer.addChild(maxUnitsText);
// Create bottom row elements (Planning Phase, Next Wave)
// Function to minimize UI during battle
function minimizeUI() {
	// Tween background to smaller size
	tween(topUIBg, {
		height: 120
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	// Move ready button up
	tween(readyButton, {
		y: 90
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	// Move state and wave text up
	tween(stateText, {
		y: 90
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	tween(waveText, {
		y: 90
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
}
// Function to maximize UI during planning
function maximizeUI() {
	// Tween background to bigger size
	tween(topUIBg, {
		height: 240
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	// Move ready button down
	tween(readyButton, {
		y: 190
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	// Move state and wave text down
	tween(stateText, {
		y: 140
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	tween(waveText, {
		y: 140
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
}
// Function to update state indicator
function updateStateIndicator() {
	if (gameState === 'planning') {
		stateText.setText('Planning Phase');
		// Remove old text and create new one with correct color
		var parent = stateText.parent;
		var x = stateText.x;
		var y = stateText.y;
		stateText.destroy();
		stateText = new Text2('Planning Phase', {
			size: 40,
			fill: 0x44FF44 // Green for planning
		});
		stateText.anchor.set(0.5, 0.5);
		stateText.x = x;
		stateText.y = y;
		parent.addChild(stateText);
		// Enable ready button during planning
		readyButtonBg.tint = 0x44AA44; // Green tint
		readyButtonText.setText('Ready!');
		// Allow unit movement during planning phase
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				var gridSlot = grid[y][x];
				if (gridSlot.unit) {
					gridSlot.unit.interactive = true;
				}
			}
		}
		// Show king info button during planning
		if (kingInfoButton) {
			kingInfoButton.visible = true;
		}
		// Maximize UI for planning phase
		if (isUIMinimized) {
			isUIMinimized = false;
			maximizeUI();
		}
	} else {
		stateText.setText('Battle Phase');
		// Remove old text and create new one with correct color
		var parent = stateText.parent;
		var x = stateText.x;
		var y = stateText.y;
		stateText.destroy();
		stateText = new Text2('Battle Phase', {
			size: 40,
			fill: 0xFF4444 // Red for battle
		});
		stateText.anchor.set(0.5, 0.5);
		stateText.x = x;
		stateText.y = y;
		parent.addChild(stateText);
		// Grey out ready button during battle
		readyButtonBg.tint = 0x666666; // Grey tint
		readyButtonText.setText('Battle');
		// Disable unit movement during battle phase
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				var gridSlot = grid[y][x];
				if (gridSlot.unit) {
					gridSlot.unit.interactive = false;
				}
			}
		}
		// Hide king info button during battle
		if (kingInfoButton) {
			kingInfoButton.visible = false;
		}
		// Minimize UI for battle phase
		if (!isUIMinimized) {
			isUIMinimized = true;
			minimizeUI();
		}
	}
}
var readyButton = new Container();
var readyButtonBg = LK.getAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 300,
	height: 100
});
readyButtonBg.tint = 0x44AA44;
var readyButtonText = new Text2('Ready!', {
	size: 72,
	fill: 0xFFFFFF
});
readyButtonText.anchor.set(0.5, 0.5);
readyButton.addChild(readyButtonBg);
readyButton.addChild(readyButtonText);
topUIContainer.addChild(readyButton);
readyButton.x = 0; // Center relative to topUIContainer
readyButton.y = 190; // Position in bigger UI
readyButton.up = function () {
	if (gameState === 'planning') {
		// Check for upgrades before starting battle
		checkAndUpgradeUnits();
		gameState = 'battle';
		waveDelay = 0;
		enemiesSpawned = 0; // Reset enemies spawned for new wave
		updateStateIndicator(); // Update UI to show battle phase
		// Stop main menu music and play background music when battle actually starts
		LK.stopMusic();
		LK.playMusic('backgroundmusic');
	}
	// Do nothing if gameState is 'battle' (button is disabled)
};
// Function to check and perform unit upgrades
function checkAndUpgradeUnits() {
	// Group units by name and type
	var unitGroups = {};
	// Count units in bench
	for (var i = 0; i < bench.length; i++) {
		var unit = bench[i];
		if (unit.gridX === -1 && unit.gridY === -1) {
			// Only count bench units
			var key = unit.name + '_' + unit.tier;
			if (!unitGroups[key]) {
				unitGroups[key] = [];
			}
			unitGroups[key].push({
				unit: unit,
				location: 'bench',
				index: i
			});
		}
	}
	// Count units on grid
	for (var y = 0; y < GRID_ROWS; y++) {
		for (var x = 0; x < GRID_COLS; x++) {
			var gridSlot = grid[y][x];
			if (gridSlot.unit) {
				var unit = gridSlot.unit;
				var key = unit.name + '_' + unit.tier;
				if (!unitGroups[key]) {
					unitGroups[key] = [];
				}
				unitGroups[key].push({
					unit: unit,
					location: 'grid',
					gridX: x,
					gridY: y,
					slot: gridSlot
				});
			}
		}
	}
	// Check for upgrades
	for (var key in unitGroups) {
		var group = unitGroups[key];
		if (group.length >= 3) {
			// Find upgrade priority: bench first, then grid
			var benchUnits = group.filter(function (item) {
				return item.location === 'bench';
			});
			var gridUnits = group.filter(function (item) {
				return item.location === 'grid';
			});
			var unitsToMerge = [];
			var upgradeTarget = null;
			var upgradeLocation = null;
			if (gridUnits.length >= 2 && benchUnits.length >= 1) {
				// Priority: Upgrade units on grid when 2 are on field and 1 in bench
				unitsToMerge = gridUnits.slice(0, 2).concat(benchUnits.slice(0, 1));
				upgradeTarget = unitsToMerge[0];
				upgradeLocation = 'grid';
			} else if (gridUnits.length >= 1 && benchUnits.length >= 2) {
				// Upgrade unit on grid using bench units
				unitsToMerge = [gridUnits[0]].concat(benchUnits.slice(0, 2));
				upgradeTarget = unitsToMerge[0];
				upgradeLocation = 'grid';
			} else if (benchUnits.length >= 3) {
				// Upgrade in bench
				unitsToMerge = benchUnits.slice(0, 3);
				upgradeTarget = unitsToMerge[0];
				upgradeLocation = 'bench';
			}
			if (upgradeTarget && unitsToMerge.length === 3) {
				// Perform upgrade
				var baseUnit = upgradeTarget.unit;
				// Upgrade attributes based on tier
				if (baseUnit.tier === 2) {
					// Three star upgrade - multiply stats by 3
					baseUnit.health = Math.floor(baseUnit.health * 3);
					baseUnit.maxHealth = Math.floor(baseUnit.maxHealth * 3);
					baseUnit.damage = Math.floor(baseUnit.damage * 3);
					baseUnit.armor = Math.floor(baseUnit.armor * 3);
					baseUnit.magicResist = Math.floor(baseUnit.magicResist * 3);
					baseUnit.mana = Math.floor(baseUnit.mana * 3);
				} else {
					// Two star upgrade - multiply by 1.8x
					baseUnit.health = Math.floor(baseUnit.health * 1.8);
					baseUnit.maxHealth = Math.floor(baseUnit.maxHealth * 1.8);
					baseUnit.damage = Math.floor(baseUnit.damage * 1.8);
					baseUnit.armor = Math.floor(baseUnit.armor * 1.8);
					baseUnit.magicResist = Math.floor(baseUnit.magicResist * 1.8);
					baseUnit.mana = Math.floor(baseUnit.mana * 1.8);
				}
				baseUnit.tier = baseUnit.tier + 1;
				// Update health bar to reflect new max health
				if (baseUnit.healthBar) {
					baseUnit.updateHealthBar();
				}
				// Update star indicator to reflect new tier
				if (baseUnit.starIndicator) {
					baseUnit.starIndicator.updateStars(baseUnit.tier);
				}
				// Force immediate scale application by stopping any ongoing scale tweens
				tween.stop(baseUnit, {
					scaleX: true,
					scaleY: true
				});
				// Apply the scale immediately based on tier
				var baseScale = baseUnit.baseScale || 1.3;
				var finalScale = baseScale;
				if (baseUnit.tier === 2) {
					finalScale = baseScale * 1.2;
				} else if (baseUnit.tier === 3) {
					finalScale = baseScale * 1.3;
				}
				// Set scale immediately
				baseUnit.scaleX = finalScale;
				baseUnit.scaleY = finalScale;
				// Update unit scale method to ensure consistency
				baseUnit.updateUnitScale();
				// Visual upgrade effect with bounce animation that respects final scale
				LK.effects.flashObject(baseUnit, 0xFFD700, 800); // Gold flash
				tween(baseUnit, {
					scaleX: finalScale * 1.2,
					scaleY: finalScale * 1.2
				}, {
					duration: 300,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						tween(baseUnit, {
							scaleX: finalScale,
							scaleY: finalScale
						}, {
							duration: 200,
							easing: tween.easeIn
						});
					}
				});
				// Remove the other two units
				for (var i = 1; i < unitsToMerge.length; i++) {
					var unitToRemove = unitsToMerge[i];
					if (unitToRemove.location === 'bench') {
						// Remove from bench
						for (var j = bench.length - 1; j >= 0; j--) {
							if (bench[j] === unitToRemove.unit) {
								bench[j].destroy();
								bench.splice(j, 1);
								break;
							}
						}
					} else if (unitToRemove.location === 'grid') {
						// Remove from grid
						unitToRemove.slot.unit = null;
						unregisterEntityPosition(unitToRemove.unit, unitToRemove.gridX, unitToRemove.gridY);
						unitToRemove.unit.destroy();
					}
				}
				// Update displays
				updateBenchDisplay();
			}
		}
	}
}
// Function to move units to closest grid spots after battle
function moveUnitsToClosestGridSpots() {
	for (var y = 0; y < GRID_ROWS; y++) {
		for (var x = 0; x < GRID_COLS; x++) {
			var gridSlot = grid[y][x];
			if (gridSlot.unit && !gridSlot.unit.isStructure && gridSlot.unit.name !== "King") {
				var unit = gridSlot.unit;
				var currentGridX = unit.gridX;
				var currentGridY = unit.gridY;
				// Find closest valid grid position
				var closestGridX = currentGridX;
				var closestGridY = currentGridY;
				var minDistance = 999;
				for (var checkY = 2; checkY < GRID_ROWS; checkY++) {
					// Start from row 2 to avoid fog of war
					for (var checkX = 0; checkX < GRID_COLS; checkX++) {
						var checkSlot = grid[checkY][checkX];
						// Check if position is valid (not occupied or same unit)
						if (!checkSlot.unit || checkSlot.unit === unit) {
							var distance = Math.abs(checkX - currentGridX) + Math.abs(checkY - currentGridY);
							if (distance < minDistance) {
								minDistance = distance;
								closestGridX = checkX;
								closestGridY = checkY;
							}
						}
					}
				}
				// Only move if we found a different position
				if (closestGridX !== currentGridX || closestGridY !== currentGridY) {
					var targetSlot = grid[closestGridY][closestGridX];
					var targetX = targetSlot.x;
					var targetY = targetSlot.y;
					// Clear old position
					gridSlot.unit = null;
					unregisterEntityPosition(unit, currentGridX, currentGridY);
					// Set new position
					targetSlot.unit = unit;
					unit.gridX = closestGridX;
					unit.gridY = closestGridY;
					registerEntityPosition(unit);
					// Animate unit to new position
					tween(unit, {
						x: targetX,
						y: targetY
					}, {
						duration: 800,
						easing: tween.easeInOut
					});
				}
			}
		}
	}
}
// Function to show ready button for next wave
function showReadyButton() {
	if (gameState === 'battle') {
		readyButtonBg.tint = 0x666666; // Grey tint during battle
		readyButtonText.setText('Battle');
	} else {
		readyButtonBg.tint = 0x44AA44; // Green tint for next wave
		readyButtonText.setText('Next Wave');
	}
	readyButton.visible = true;
}
// Hide ready button initially (will show after first wave)
function hideReadyButton() {
	readyButton.visible = false;
}
function updateBenchDisplay() {
	// Clear all bench slot references
	for (var i = 0; i < benchSlots.length; i++) {
		benchSlots[i].unit = null;
	}
	// Only display units in bench that are not on the battlefield
	for (var i = 0; i < bench.length; i++) {
		// Skip units that are already placed on the grid
		if (bench[i].gridX !== -1 && bench[i].gridY !== -1) {
			continue;
		}
		// Find the first empty bench slot
		for (var j = 0; j < benchSlots.length; j++) {
			if (!benchSlots[j].unit) {
				benchSlots[j].unit = bench[i];
				// Center the unit in the bench slot
				bench[i].x = benchSlots[j].x;
				bench[i].y = benchSlots[j].y;
				// Show star indicator for units in bench
				bench[i].showStarIndicator();
				break;
			}
		}
	}
}
function spawnEnemy() {
	var spawnX = Math.floor(Math.random() * GRID_COLS);
	var enemy;
	// Spawn boss monster every 5 waves
	if (wave % 5 === 0 && enemiesSpawned === Math.floor(enemiesPerWave / 2)) {
		enemy = new Boss();
		// Scale boss stats based on wave
		if (wave > 1) {
			var waveMultiplier = 1 + (wave - 1) * 0.2;
			enemy.health = Math.floor(enemy.health * waveMultiplier);
			enemy.maxHealth = enemy.health;
			enemy.damage = Math.floor(enemy.damage * waveMultiplier);
			enemy.armor = Math.floor(enemy.armor * (1 + (wave - 1) * 0.1));
			enemy.magicResist = Math.floor(enemy.magicResist * (1 + (wave - 1) * 0.1));
			enemy.goldValue = Math.floor(enemy.goldValue * waveMultiplier);
		}
	} else {
		// Increase ranged enemy chance as waves progress
		var rangedChance = Math.min(0.3 + wave * 0.05, 0.7);
		if (Math.random() < rangedChance) {
			enemy = new RangedEnemy();
		} else {
			enemy = new Enemy();
		}
		// Significantly increase enemy scaling per wave
		enemy.health = 20 + Math.floor(wave * 10) + Math.floor(Math.pow(wave, 1.5) * 5);
		enemy.maxHealth = enemy.health;
		enemy.damage = 15 + Math.floor(wave * 5) + Math.floor(Math.pow(wave, 1.3) * 3);
		enemy.goldValue = Math.max(2, Math.floor(wave * 1.5));
	}
	// Try to spawn in a strategic position
	var bestSpawnX = spawnX;
	var minPlayerUnits = 999;
	// Check each column for player units
	for (var x = 0; x < GRID_COLS; x++) {
		var playerUnitsInColumn = 0;
		for (var y = 0; y < GRID_ROWS; y++) {
			if (grid[y] && grid[y][x] && grid[y][x].unit) {
				playerUnitsInColumn++;
			}
		}
		// Boss prefers columns with fewer player units
		if (enemy.name === "Boss Monster" && playerUnitsInColumn < minPlayerUnits) {
			minPlayerUnits = playerUnitsInColumn;
			bestSpawnX = x;
		}
	}
	// Position enemy at the first row (top) of the grid
	enemy.gridX = enemy.name === "Boss Monster" ? bestSpawnX : spawnX;
	enemy.gridY = 0;
	// Set visual position to match grid position
	var topCell = grid[0][enemy.gridX];
	enemy.x = topCell.x;
	enemy.y = topCell.y;
	enemy.lane = 0; // Single grid, so lane is always 0
	// Apply base scale
	if (enemy.name !== "Boss Monster") {
		// Scale up enemy by 30%
		enemy.scaleX = 1.3;
		enemy.scaleY = 1.3;
	}
	enemy.showHealthBar(); // Show health bar when enemy is spawned
	enemy.updateHealthBar();
	// Initialize GridMovement immediately for the enemy
	enemy.gridMovement = new GridMovement(enemy, grid);
	enemies.push(enemy);
	enemyContainer.addChild(enemy);
	// Add spawn animation
	enemy.alpha = 0;
	var baseScale = enemy.baseScale || 1.3;
	enemy.scaleX = baseScale * 0.5;
	enemy.scaleY = baseScale * 1.5;
	tween(enemy, {
		alpha: 1,
		scaleX: baseScale,
		scaleY: baseScale
	}, {
		duration: 300,
		easing: tween.easeOut
	});
	// Register enemy position
	registerEntityPosition(enemy);
}
game.move = function (x, y, obj) {
	if (draggedUnit) {
		draggedUnit.x = x;
		draggedUnit.y = y;
	}
};
game.up = function (x, y, obj) {
	// Check for double-tap on grid units when not dragging
	if (!draggedUnit) {
		var currentTime = Date.now();
		var timeDiff = currentTime - lastTapTime;
		var dx = x - lastTapX;
		var dy = y - lastTapY;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Check if this is a double-tap (within time window and close to last tap)
		if (timeDiff < doubleTapDelay && distance < doubleTapDistance) {
			// Check if double-tap is on a unit in the grid
			for (var gridY = 0; gridY < GRID_ROWS; gridY++) {
				for (var gridX = 0; gridX < GRID_COLS; gridX++) {
					var slot = grid[gridY][gridX];
					if (slot.unit) {
						var unitDx = x - slot.x;
						var unitDy = y - slot.y;
						var unitDistance = Math.sqrt(unitDx * unitDx + unitDy * unitDy);
						if (unitDistance < GRID_CELL_SIZE / 2) {
							// Double-tapped on this unit - show info modal
							showUnitInfoModal(slot.unit);
							lastTapTime = 0; // Reset to prevent triple-tap
							return;
						}
					}
				}
			}
			// Check if double-tap is on a unit in the bench during planning phase
			if (gameState === 'planning') {
				for (var i = 0; i < benchSlots.length; i++) {
					var benchSlot = benchSlots[i];
					if (benchSlot.unit) {
						var unitDx = x - benchSlot.x;
						var unitDy = y - benchSlot.y;
						var unitDistance = Math.sqrt(unitDx * unitDx + unitDy * unitDy);
						if (unitDistance < 60) {
							// Double-tapped on this bench unit - show info modal
							showUnitInfoModal(benchSlot.unit);
							lastTapTime = 0; // Reset to prevent triple-tap
							return;
						}
					}
				}
			}
			// Check if double-tap is on an enemy
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				var enemyDx = x - enemy.x;
				var enemyDy = y - enemy.y;
				var enemyDistance = Math.sqrt(enemyDx * enemyDx + enemyDy * enemyDy);
				if (enemyDistance < 60) {
					// Double-tapped on this enemy - show info modal
					showUnitInfoModal(enemy);
					lastTapTime = 0; // Reset to prevent triple-tap
					return;
				}
			}
		}
		// Update last tap info for next potential double-tap
		lastTapTime = currentTime;
		lastTapX = x;
		lastTapY = y;
	}
	if (draggedUnit) {
		var dropped = false;
		// Check if dropped on a valid grid slot
		for (var gridY = 0; gridY < GRID_ROWS; gridY++) {
			for (var gridX = 0; gridX < GRID_COLS; gridX++) {
				var slot = grid[gridY][gridX];
				var dx = x - slot.x;
				var dy = y - slot.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				if (distance < GRID_CELL_SIZE / 2 && !slot.unit) {
					// Valid empty grid slot - ensure exact positioning
					slot.placeUnit(draggedUnit);
					if (draggedFromGrid && draggedUnit.originalGridSlot) {
						// Unregister from old position before clearing slot
						unregisterEntityPosition(draggedUnit, draggedUnit.originalGridSlot.gridX, draggedUnit.originalGridSlot.gridY);
						draggedUnit.originalGridSlot.unit = null;
					}
					dropped = true;
					break;
				}
			}
			if (dropped) {
				break;
			}
		}
		// Check if dropped on bench slot
		if (!dropped) {
			// Prevent King from being moved to bench
			if (draggedUnit.name !== 'King') {
				for (var i = 0; i < benchSlots.length; i++) {
					var benchSlot = benchSlots[i];
					var dx = x - benchSlot.x;
					var dy = y - benchSlot.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					if (distance < 60 && !benchSlot.unit) {
						// Valid empty bench slot
						benchSlot.unit = draggedUnit;
						draggedUnit.x = benchSlot.x;
						draggedUnit.y = benchSlot.y;
						// Remove from grid if it was on grid
						if (draggedFromGrid && draggedUnit.originalGridSlot) {
							// Unregister from position tracking
							unregisterEntityPosition(draggedUnit, draggedUnit.originalGridSlot.gridX, draggedUnit.originalGridSlot.gridY);
							draggedUnit.originalGridSlot.unit = null;
						}
						draggedUnit.gridX = -1;
						draggedUnit.gridY = -1;
						draggedUnit.lane = -1;
						draggedUnit.hideHealthBar(); // Hide health bar when moved to bench
						draggedUnit.hideStarIndicator(); // Hide star indicator when moved to bench
						dropped = true;
						updateBenchDisplay();
						// Add bounce effect when unit is moved to bench
						var targetScale = draggedUnit.baseScale || 1.3;
						if (draggedUnit.tier === 2) {
							targetScale = draggedUnit.baseScale * 1.2;
						} else if (draggedUnit.tier === 3) {
							targetScale = draggedUnit.baseScale * 1.3;
						}
						draggedUnit.scaleX = targetScale * 0.8;
						draggedUnit.scaleY = targetScale * 0.8;
						// Capture unit reference before clearing draggedUnit
						var unitToAnimate = draggedUnit;
						tween(unitToAnimate, {
							scaleX: targetScale * 1.2,
							scaleY: targetScale * 1.2
						}, {
							duration: 200,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								tween(unitToAnimate, {
									scaleX: targetScale,
									scaleY: targetScale
								}, {
									duration: 150,
									easing: tween.easeIn,
									onFinish: function onFinish() {
										// Clear bounce animation flag when bounce is complete
										unitToAnimate._isBounceAnimating = false;
									}
								});
							}
						});
						break;
					}
				}
			}
		}
		// If not dropped on valid slot, return to original position
		if (!dropped) {
			// Handle King separately - must return to grid
			if (draggedUnit.name === 'King') {
				// King must return to original grid position
				if (draggedFromGrid && draggedUnit.originalGridSlot) {
					draggedUnit.x = draggedUnit.originalX;
					draggedUnit.y = draggedUnit.originalY;
					draggedUnit.originalGridSlot.unit = draggedUnit; // Restore unit to original grid slot
				}
			} else {
				// Always return to bench if not placed in a valid cell
				if (draggedUnit.originalSlot) {
					// Return to original bench slot
					draggedUnit.x = draggedUnit.originalX;
					draggedUnit.y = draggedUnit.originalY;
					draggedUnit.originalSlot.unit = draggedUnit;
				} else if (draggedFromGrid && draggedUnit.originalGridSlot) {
					// Unit was dragged from grid but not placed in valid cell - return to bench
					// Find first available bench slot
					var returnedToBench = false;
					for (var i = 0; i < benchSlots.length; i++) {
						if (!benchSlots[i].unit) {
							benchSlots[i].unit = draggedUnit;
							draggedUnit.x = benchSlots[i].x;
							draggedUnit.y = benchSlots[i].y;
							// Unregister from grid position
							unregisterEntityPosition(draggedUnit, draggedUnit.originalGridSlot.gridX, draggedUnit.originalGridSlot.gridY);
							draggedUnit.originalGridSlot.unit = null;
							draggedUnit.gridX = -1;
							draggedUnit.gridY = -1;
							draggedUnit.lane = -1;
							draggedUnit.hideHealthBar();
							draggedUnit.hideStarIndicator(); // Hide star indicator when moved to bench
							returnedToBench = true;
							updateBenchDisplay();
							// Add bounce effect when unit is returned to bench
							var targetScale = draggedUnit.baseScale || 1.3;
							if (draggedUnit.tier === 2) {
								targetScale = draggedUnit.baseScale * 1.2;
							} else if (draggedUnit.tier === 3) {
								targetScale = draggedUnit.baseScale * 1.3;
							}
							draggedUnit.scaleX = targetScale * 0.8;
							draggedUnit.scaleY = targetScale * 0.8;
							// Capture unit reference before clearing draggedUnit
							var unitToAnimate = draggedUnit;
							tween(unitToAnimate, {
								scaleX: targetScale * 1.2,
								scaleY: targetScale * 1.2
							}, {
								duration: 200,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									tween(unitToAnimate, {
										scaleX: targetScale,
										scaleY: targetScale
									}, {
										duration: 150,
										easing: tween.easeIn
									});
								}
							});
							break;
						}
					}
					// If no bench slot available, return to original grid position
					if (!returnedToBench) {
						draggedUnit.x = draggedUnit.originalX;
						draggedUnit.y = draggedUnit.originalY;
						draggedUnit.originalGridSlot.unit = draggedUnit; // Restore unit to original grid slot
					}
				} else {
					// Unit doesn't have original position - find first available bench slot
					for (var i = 0; i < benchSlots.length; i++) {
						if (!benchSlots[i].unit) {
							benchSlots[i].unit = draggedUnit;
							draggedUnit.x = benchSlots[i].x;
							draggedUnit.y = benchSlots[i].y;
							draggedUnit.gridX = -1;
							draggedUnit.gridY = -1;
							draggedUnit.lane = -1;
							draggedUnit.hideHealthBar();
							draggedUnit.hideStarIndicator(); // Hide star indicator when moved to bench
							updateBenchDisplay();
							break;
						}
					}
				}
			}
		}
		// Clean up
		draggedUnit.originalX = undefined;
		draggedUnit.originalY = undefined;
		draggedUnit.originalSlot = undefined;
		draggedUnit.originalGridSlot = undefined;
		draggedUnit = null;
		draggedFromGrid = false;
	} else {
		// Check if clicking on a shop unit
		for (var i = 0; i < shopSlots.length; i++) {
			var slot = shopSlots[i];
			if (slot.unit) {
				var dx = x - slot.x;
				var dy = y - slot.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				if (distance < 80) {
					// Increase click area for better usability
					// Within click range of shop unit
					var unitCost = slot.unit.tier;
					// Special cost for Wall (1g) and CrossbowTower (2g)
					if (slot.unit.name === "Wall") {
						unitCost = 1;
					} else if (slot.unit.name === "CrossbowTower") {
						unitCost = 2;
					}
					var currentTime = Date.now();
					var timeDiff = currentTime - lastTapTime;
					var dx = x - lastTapX;
					var dy = y - lastTapY;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Check if this is a double-tap
					if (timeDiff < doubleTapDelay && distance < doubleTapDistance) {
						// This is a double-tap - check if we can purchase
						if (gold >= unitCost) {
							// Find available bench slot
							var availableBenchSlot = false;
							for (var slotIndex = 0; slotIndex < benchSlots.length; slotIndex++) {
								if (!benchSlots[slotIndex].unit) {
									availableBenchSlot = true;
									break;
								}
							}
							if (availableBenchSlot) {
								gold -= unitCost;
								goldText.setText(gold.toString());
								// Create new unit for bench using the same constructor as the shop unit
								var newUnit = new slot.unitConstructor();
								// All units purchased from shop start at tier 1 (1 star) regardless of unit type
								newUnit.tier = 1;
								// Update star indicator to show tier 1
								if (newUnit.starIndicator) {
									newUnit.starIndicator.updateStars(1);
								}
								// Initialize grid position properties
								newUnit.gridX = -1;
								newUnit.gridY = -1;
								newUnit.lane = -1;
								bench.push(newUnit);
								game.addChild(newUnit);
								updateBenchDisplay();
								// Add bounce effect when unit is added to bench
								newUnit.scaleX = 0;
								newUnit.scaleY = 0;
								// Capture unit reference for animation
								var unitToAnimate = newUnit;
								var targetScale = unitToAnimate.baseScale || 1.3;
								tween(unitToAnimate, {
									scaleX: targetScale * 1.2,
									scaleY: targetScale * 1.2
								}, {
									duration: 200,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										tween(unitToAnimate, {
											scaleX: targetScale,
											scaleY: targetScale
										}, {
											duration: 150,
											easing: tween.easeIn
										});
									}
								});
								// Remove purchased unit from shop
								slot.unit.destroy();
								slot.unit = null;
								if (slot.tierText) {
									slot.tierText.destroy();
									slot.tierText = null;
								}
								if (slot.nameText) {
									slot.nameText.destroy();
									slot.nameText = null;
								}
								if (slot.infoButton) {
									slot.infoButton.destroy();
									slot.infoButton = null;
								}
								LK.getSound('purchase').play();
								// Check for upgrades after purchasing a unit
								checkAndUpgradeUnits();
							} else {
								// No bench space available - could add visual feedback here
							}
						}
						// Reset tap tracking after double-tap to prevent triple-tap
						lastTapTime = 0;
						lastTapX = 0;
						lastTapY = 0;
						break;
					} else {
						// Not a double-tap: just update last tap info for next potential double-tap
						lastTapTime = currentTime;
						lastTapX = x;
						lastTapY = y;
						break;
					}
				}
			}
		}
	}
};
game.update = function () {
	// Spawn enemies
	if (gameState === 'battle') {
		// Ensure health bars are visible for all enemies
		for (var i = 0; i < enemies.length; i++) {
			enemies[i].showHealthBar();
		}
		// Ensure health bars are visible for all units on the grid
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				var gridSlot = grid[y][x];
				if (gridSlot.unit) {
					gridSlot.unit.showHealthBar();
				}
			}
		}
		if (waveDelay <= 0) {
			if (enemiesSpawned < enemiesPerWave) {
				if (LK.ticks % 60 === 0) {
					spawnEnemy();
					enemiesSpawned++;
				}
			} else if (enemies.length === 0) {
				// Wave complete - move units to closest grid spots first
				moveUnitsToClosestGridSpots();
				// Update best wave in storage
				if (wave > (storage.bestWave || 0)) {
					storage.bestWave = wave;
				}
				// Transition to planning phase
				gameState = 'planning';
				wave++;
				enemiesPerWave = Math.min(5 + wave * 2, 30);
				waveText.setText('Wave: ' + wave);
				// Calculate interest: 1 gold per 10 saved, max 5
				var interest = Math.min(Math.floor(gold / 10), 5);
				var waveReward = 5 + interest;
				gold += waveReward;
				goldText.setText(gold.toString());
				// Check for unit upgrades when entering planning phase
				checkAndUpgradeUnits();
				// Switch to main menu music when no enemies remain (planning phase)
				LK.stopMusic();
				LK.playMusic('mainmenu_music');
				// Show reward message
				var rewardText = new Text2('Wave Complete! +' + waveReward + ' Gold (5 + ' + interest + ' interest)', {
					size: 96,
					fill: 0xFFD700
				});
				rewardText.anchor.set(0.5, 0.5);
				rewardText.x = 1024;
				rewardText.y = 800;
				game.addChild(rewardText);
				// Fade out reward text with longer duration
				tween(rewardText, {
					alpha: 0,
					y: 700
				}, {
					duration: 4000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						rewardText.destroy();
					}
				});
				// Refresh shop with new units after wave completion
				refreshShop();
				showReadyButton(); // Show button for next wave
				updateStateIndicator(); // Update UI to show planning phase
			}
		} else {
			waveDelay--;
		}
		// Castle health bar is now handled as a regular unit
	}
	// Update enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		enemy.update();
		// Castle is now a regular unit on the grid, no special handling needed
		enemy.updateHealthBar();
		enemy.showHealthBar(); // Ensure health bar is shown during battle
	}
	// Update unit counts in case any units were destroyed
	countUnitsOnField();
	// Clean up reservations and position tracking for destroyed entities
	var keysToRemove = [];
	for (var key in cellReservations) {
		var entity = cellReservations[key];
		if (!entity.parent) {
			keysToRemove.push(key);
		}
	}
	for (var i = 0; i < keysToRemove.length; i++) {
		delete cellReservations[keysToRemove[i]];
	}
	// Clean up position tracking for destroyed entities
	var posKeysToRemove = [];
	for (var posKey in entityPositions) {
		var entity = entityPositions[posKey];
		if (!entity.parent) {
			posKeysToRemove.push(posKey);
		}
	}
	for (var i = 0; i < posKeysToRemove.length; i++) {
		delete entityPositions[posKeysToRemove[i]];
	}
	// Update units
	var unitsToUpdate = [];
	for (var y = 0; y < GRID_ROWS; y++) {
		for (var x = 0; x < GRID_COLS; x++) {
			var gridSlot = grid[y][x];
			if (gridSlot.unit) {
				unitsToUpdate.push(gridSlot.unit);
			}
		}
	}
	// Process all units in a single loop
	for (var i = 0; i < unitsToUpdate.length; i++) {
		var unit = unitsToUpdate[i];
		unit.update();
		if (gameState === 'battle') {
			unit.showHealthBar(); // Ensure health bar is shown during battle
			unit.updateHealthBar();
			unit.showStarIndicator(); // Ensure star indicator is shown during battle
		} else {
			// Hide health bars during planning phase
			if (unit.healthBar) {
				unit.healthBar.visible = false;
			}
			// Show star indicators during planning phase for easy tier identification
			unit.showStarIndicator();
		}
		// Update king info button position if this is the king
		if (unit.name === 'King' && kingInfoButton) {
			kingInfoButton.x = unit.x;
			kingInfoButton.y = unit.y + 100; // Position below king
		}
	}
	// Unit shooting (only during battle)
	if (gameState === 'battle') {
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				var gridSlot = grid[y][x];
				if (gridSlot.unit) {
					var target = gridSlot.unit.findTarget();
					if (target) {
						var bullet = gridSlot.unit.shoot(target);
						if (bullet) {
							bullets.push(bullet);
							game.addChild(bullet);
							LK.getSound('shoot').play();
						} else if (gridSlot.unit.range <= 100) {
							// Melee attack sound effect (no bullet created)
							if (gridSlot.unit.canShoot()) {
								LK.getSound('shoot').play();
							}
						}
					}
				}
			}
		}
	}
	// Update bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		if (bullet && bullet.update) {
			bullet.update();
		}
		if (!bullet.parent) {
			bullets.splice(i, 1);
		}
	}
	// Update enemy projectiles
	for (var i = enemyProjectiles.length - 1; i >= 0; i--) {
		var projectile = enemyProjectiles[i];
		if (projectile && projectile.update) {
			projectile.update();
		}
		if (!projectile.parent) {
			enemyProjectiles.splice(i, 1);
		}
	}
	// Update level up cost text
	levelUpCostText.setText('Cost: ' + getLevelUpCost(playerLevel) + 'g');
	// Check win condition
	if (wave >= 10 && enemies.length === 0 && enemiesSpawned >= enemiesPerWave) {
		LK.showYouWin();
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var AttackInfo = Container.expand(function () {
	var self = Container.call(this);
	var background = self.attachAsset('bench_area_bg', {
		anchorX: 0,
		anchorY: 0,
		width: 300,
		height: 150
	});
	background.alpha = 0.8;
	self.attackerText = new Text2('', {
		size: 36,
		fill: 0xFFFFFF
	});
	self.attackerText.anchor.set(0, 0.5);
	self.attackerText.x = 10;
	self.attackerText.y = 25;
	self.addChild(self.attackerText);
	self.damageText = new Text2('', {
		size: 36,
		fill: 0xFF0000
	});
	self.damageText.anchor.set(0, 0.5);
	self.damageText.x = 10;
	self.damageText.y = 100;
	self.addChild(self.damageText);
	self.updateInfo = function (attacker, damage) {
		self.attackerText.setText('Attacker: ' + attacker);
		self.damageText.setText('Damage: ' + damage);
	};
	return self;
});
var BenchSlot = Container.expand(function (index) {
	var self = Container.call(this);
	var slotGraphics = self.attachAsset('bench_slot', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.index = index;
	self.unit = null;
	slotGraphics.alpha = 0.5;
	self.down = function (x, y, obj) {
		if (self.unit && gameState === 'planning') {
			draggedUnit = self.unit;
			// Start dragging from current position, not mouse position
			draggedUnit.x = self.x;
			draggedUnit.y = self.y;
			// Store original position and slot
			draggedUnit.originalX = self.x;
			draggedUnit.originalY = self.y;
			draggedUnit.originalSlot = self;
			// Free the bench slot immediately when dragging starts
			self.unit = null;
		}
	};
	return self;
});
var Bullet = Container.expand(function (damage, target) {
	var self = Container.call(this);
	// Default bullet type
	self.bulletType = 'default';
	self.damage = damage;
	self.target = target;
	self.speed = 8;
	// Create bullet graphics based on type
	self.createGraphics = function () {
		// Clear any existing graphics
		self.removeChildren();
		if (self.bulletType === 'arrow') {
			// Create arrow projectile
			var arrowShaft = self.attachAsset('arrow', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			// Arrow head
			var arrowHead = self.attachAsset('arrow_head', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			arrowHead.x = 15;
			arrowHead.rotation = 0.785; // 45 degrees
			// Arrow fletching
			var fletching1 = self.attachAsset('arrow_feather', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			fletching1.x = -10;
			fletching1.y = -3;
			var fletching2 = self.attachAsset('arrow_feather', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			fletching2.x = -10;
			fletching2.y = 3;
			self.speed = 10; // Arrows are faster
		} else if (self.bulletType === 'magic') {
			// Create magic projectile
			var magicCore = self.attachAsset('magic_core', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			// Magic aura
			var magicAura = self.attachAsset('magic_aura', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			magicAura.alpha = 0.5;
			// Magic sparkles
			var sparkle1 = self.attachAsset('magic_sparkle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			sparkle1.x = -10;
			sparkle1.y = -10;
			var sparkle2 = self.attachAsset('magic_sparkle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			sparkle2.x = 10;
			sparkle2.y = 10;
			// Add tween for magic glow effect
			tween(magicAura, {
				scaleX: 1.2,
				scaleY: 1.2,
				alpha: 0.3
			}, {
				duration: 300,
				easing: tween.easeInOut,
				onFinish: function onFinish() {
					tween(magicAura, {
						scaleX: 1.0,
						scaleY: 1.0,
						alpha: 0.5
					}, {
						duration: 300,
						easing: tween.easeInOut,
						onFinish: onFinish
					});
				}
			});
			self.speed = 6; // Magic is slower but more visible
		} else {
			// Default bullet
			var bulletGraphics = self.attachAsset('bullet', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		}
	};
	// Create initial graphics
	self.createGraphics();
	self.update = function () {
		if (!self.target || self.target.health <= 0) {
			self.destroy();
			return;
		}
		var dx = self.target.x - self.x;
		var dy = self.target.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < 10) {
			var killed = self.target.takeDamage(self.damage);
			if (killed) {
				// Don't give gold for killing enemies
				// Update enemies defeated count in storage
				storage.enemiesDefeated = (storage.enemiesDefeated || 0) + 1;
				LK.getSound('enemyDeath').play();
				for (var i = enemies.length - 1; i >= 0; i--) {
					if (enemies[i] === self.target) {
						// Trigger death animation instead of immediate destroy
						enemies[i].deathAnimation();
						enemies.splice(i, 1);
						break;
					}
				}
			}
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
		// Rotate arrow to face target
		if (self.bulletType === 'arrow') {
			self.rotation = Math.atan2(dy, dx);
		}
	};
	return self;
});
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	// Create pixelart enemy character
	var enemyContainer = new Container();
	self.addChild(enemyContainer);
	// Body (red goblin)
	var body = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 60;
	body.height = 60;
	body.y = 10;
	body.tint = 0xFF4444; // Red tint to match goblin theme
	// Head (darker red)
	var head = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 35
	});
	head.y = -30;
	head.tint = 0xcc0000;
	// Eyes (white dots)
	var leftEye = enemyContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 8
	});
	leftEye.x = -10;
	leftEye.y = -30;
	leftEye.tint = 0xFFFFFF;
	var rightEye = enemyContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 8
	});
	rightEye.x = 10;
	rightEye.y = -30;
	rightEye.tint = 0xFFFFFF;
	// Claws
	var leftClaw = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 15
	});
	leftClaw.x = -25;
	leftClaw.y = 5;
	leftClaw.rotation = 0.5;
	leftClaw.tint = 0x800000;
	var rightClaw = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 15
	});
	rightClaw.x = 25;
	rightClaw.y = 5;
	rightClaw.rotation = -0.5;
	rightClaw.tint = 0x800000;
	// Initial attributes for the enemy
	self.health = 25;
	self.maxHealth = 25;
	self.damage = 15;
	self.armor = 3;
	self.criticalChance = 0.15;
	self.magicResist = 3;
	self.mana = 40;
	self.speed = 2;
	self.range = 1; // Enemy always melee (adjacent cell)
	self.goldValue = 2;
	self.name = "Enemy";
	self.healthBar = null; // Initialize health bar as null
	self.isAttacking = false; // Flag to track if enemy is currently attacking
	self.baseScale = 1.3; // Base scale multiplier for all enemies (30% larger)
	// Apply base scale
	self.scaleX = self.baseScale;
	self.scaleY = self.baseScale;
	self.showHealthBar = function () {
		if (!self.healthBar) {
			self.healthBar = new HealthBar(60, 8); // Create a health bar instance (smaller than units)
			self.healthBar.x = -30; // Position relative to the enemy's center
			self.healthBar.y = -60; // Position above the enemy
			self.addChild(self.healthBar);
		}
		self.healthBar.visible = true; // Ensure health bar is visible
		self.healthBar.updateHealth(self.health, self.maxHealth);
	};
	self.updateHealthBar = function () {
		if (self.healthBar) {
			self.healthBar.updateHealth(self.health, self.maxHealth);
		}
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		self.updateHealthBar(); // Update health bar when taking damage
		if (self.health <= 0) {
			self.health = 0;
			return true;
		}
		return false;
	};
	self.deathAnimation = function () {
		// Hide health bar immediately
		if (self.healthBar) {
			self.healthBar.destroy();
			self.healthBar = null;
		}
		// Create particle explosion effect
		var particleContainer = new Container();
		particleContainer.x = self.x;
		particleContainer.y = self.y;
		self.parent.addChild(particleContainer);
		// Number of particles based on enemy type
		var particleCount = 12; // Default for regular enemies
		var particleColors = [0xFF4444, 0xFF6666, 0xFF8888, 0xFFAAAA]; // Red shades for regular enemies
		var particleSize = 15;
		var explosionRadius = 80;
		// Customize based on enemy type
		if (self.name === "Ranged Enemy") {
			particleColors = [0x8A2BE2, 0x9370DB, 0xBA55D3, 0xDDA0DD]; // Purple shades
			particleCount = 10;
		} else if (self.name === "Boss Monster") {
			particleColors = [0x800000, 0xA52A2A, 0xDC143C, 0xFF0000]; // Dark red to bright red
			particleCount = 20; // More particles for boss
			particleSize = 20;
			explosionRadius = 120;
		}
		// Create particles
		var particles = [];
		for (var i = 0; i < particleCount; i++) {
			var particle = particleContainer.attachAsset('bullet', {
				anchorX: 0.5,
				anchorY: 0.5,
				width: particleSize + Math.random() * 10,
				height: particleSize + Math.random() * 10
			});
			// Set particle color
			particle.tint = particleColors[Math.floor(Math.random() * particleColors.length)];
			particle.alpha = 0.8 + Math.random() * 0.2;
			// Calculate random direction
			var angle = Math.PI * 2 * i / particleCount + (Math.random() - 0.5) * 0.5;
			var speed = explosionRadius * (0.7 + Math.random() * 0.3);
			// Store particle data
			particles.push({
				sprite: particle,
				targetX: Math.cos(angle) * speed,
				targetY: Math.sin(angle) * speed,
				rotationSpeed: (Math.random() - 0.5) * 0.2
			});
		}
		// Animate enemy shrinking and fading
		tween(self, {
			alpha: 0,
			scaleX: self.scaleX * 0.5,
			scaleY: self.scaleY * 0.5
		}, {
			duration: 200,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				// Destroy the enemy
				self.destroy();
			}
		});
		// Animate particles bursting outward
		for (var i = 0; i < particles.length; i++) {
			var particleData = particles[i];
			var particle = particleData.sprite;
			// Burst outward animation
			tween(particle, {
				x: particleData.targetX,
				y: particleData.targetY,
				scaleX: 0.1,
				scaleY: 0.1,
				alpha: 0,
				rotation: particle.rotation + particleData.rotationSpeed * 10
			}, {
				duration: 600 + Math.random() * 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Clean up after last particle
					if (i === particles.length - 1) {
						particleContainer.destroy();
					}
				}
			});
		}
		// Add a brief flash effect at the center
		var flash = particleContainer.attachAsset('bullet', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: particleSize * 3,
			height: particleSize * 3
		});
		flash.tint = 0xFFFFFF;
		flash.alpha = 0.8;
		tween(flash, {
			scaleX: 3,
			scaleY: 3,
			alpha: 0
		}, {
			duration: 300,
			easing: tween.easeOut
		});
	};
	self.update = function () {
		if (!self.gridMovement) {
			self.gridMovement = new GridMovement(self, grid);
		}
		self.gridMovement.update();
		// Castle is now treated as a unit on the grid, no special collision logic needed
		// Find and attack units within range (cell-based)
		var closestUnit = null;
		var closestCellDistance = self.range + 1; // Only units within range (cell count) are valid
		// Only recalculate targets every 15 ticks or if position changed
		if (!self._targetCache || LK.ticks % 15 === 0 || self._lastTargetX !== self.gridX || self._lastTargetY !== self.gridY) {
			self._lastTargetX = self.gridX;
			self._lastTargetY = self.gridY;
			// Smart targeting - collect all units in range
			var targetsInRange = [];
			// First check if king exists and is in range
			if (kings.length > 0 && kings[0]) {
				var king = kings[0];
				if (typeof king.gridX === "number" && typeof king.gridY === "number") {
					var kingCellDist = Math.abs(self.gridX - king.gridX) + Math.abs(self.gridY - king.gridY);
					if (kingCellDist <= self.range && self.gridMovement.isMoving === false) {
						targetsInRange.push({
							unit: king,
							distance: kingCellDist,
							priority: 3,
							// Medium priority for king
							healthRatio: king.health / king.maxHealth
						});
					}
				}
			}
			// Then check other units on the grid
			for (var y = Math.max(0, self.gridY - self.range); y <= Math.min(GRID_ROWS - 1, self.gridY + self.range); y++) {
				for (var x = Math.max(0, self.gridX - self.range); x <= Math.min(GRID_COLS - 1, self.gridX + self.range); x++) {
					if (grid[y] && grid[y][x]) {
						var gridSlot = grid[y][x];
						if (gridSlot.unit) {
							// Calculate cell-based Manhattan distance
							var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
							// Check if the enemy is completely inside the adjacent cell before attacking
							if (cellDist <= self.range && self.gridMovement.isMoving === false) {
								var unit = gridSlot.unit;
								var priority = 5; // Default priority
								var healthRatio = unit.health / unit.maxHealth;
								// Smart prioritization
								if (healthRatio <= 0.3) {
									priority = 1; // Highest priority - can finish off quickly
								} else if (unit.name === "Wizard" || unit.name === "Ranger") {
									priority = 2; // High priority - dangerous units
								} else if (unit.name === "Wall") {
									priority = 8; // Lowest priority - defensive units
								} else if (unit.name === "Paladin" || unit.name === "Knight") {
									priority = 6; // Low priority - tanky units
								}
								targetsInRange.push({
									unit: unit,
									distance: cellDist,
									priority: priority,
									healthRatio: healthRatio
								});
							}
						}
					}
				}
			}
			self._targetCache = targetsInRange;
		} else {
			// Use cached targets
			var targetsInRange = self._targetCache || [];
		}
		// Sort targets by priority first, then by health ratio, then by distance
		targetsInRange.sort(function (a, b) {
			if (a.priority !== b.priority) {
				return a.priority - b.priority;
			}
			if (Math.abs(a.healthRatio - b.healthRatio) > 0.1) {
				return a.healthRatio - b.healthRatio; // Lower health first
			}
			return a.distance - b.distance;
		});
		// Select best target
		if (targetsInRange.length > 0) {
			closestUnit = targetsInRange[0].unit;
		}
		// Attack the closest unit if found
		if (closestUnit) {
			if (!self.lastAttack) {
				self.lastAttack = 0;
			}
			if (LK.ticks - self.lastAttack >= 60) {
				self.lastAttack = LK.ticks;
				// Add tween animation for enemy attack
				var originalX = self.x;
				var originalY = self.y;
				// Calculate lunge direction towards target
				var dx = closestUnit.x - self.x;
				var dy = closestUnit.y - self.y;
				var dist = Math.sqrt(dx * dx + dy * dy);
				var offset = Math.min(30, dist * 0.25);
				var lungeX = self.x + (dist > 0 ? dx / dist * offset : 0);
				var lungeY = self.y + (dist > 0 ? dy / dist * offset : 0);
				// Prevent multiple attack tweens at once
				if (!self._isAttackTweening) {
					self._isAttackTweening = true;
					self.isAttacking = true; // Set attacking flag
					// Flash enemy red briefly during attack using LK effects
					LK.effects.flashObject(self, 0xFF4444, 300);
					// Lunge towards target
					tween(self, {
						x: lungeX,
						y: lungeY
					}, {
						duration: 120,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							// Apply damage after lunge
							// Play melee attack sound
							LK.getSound('melee_attack').play();
							var killed = closestUnit.takeDamage(self.damage);
							if (killed) {
								self.isAttacking = false; // Clear attacking flag if target dies
								for (var y = 0; y < GRID_ROWS; y++) {
									for (var x = 0; x < GRID_COLS; x++) {
										if (grid[y] && grid[y][x]) {
											var gridSlot = grid[y][x];
											if (gridSlot.unit === closestUnit) {
												gridSlot.unit = null;
												// Trigger death animation instead of immediate destroy
												closestUnit.deathAnimation();
												for (var i = bench.length - 1; i >= 0; i--) {
													if (bench[i] === closestUnit) {
														bench.splice(i, 1);
														break;
													}
												}
												break;
											}
										}
									}
								}
							}
							// Return to original position
							tween(self, {
								x: originalX,
								y: originalY
							}, {
								duration: 100,
								easing: tween.easeIn,
								onFinish: function onFinish() {
									self._isAttackTweening = false;
									self.isAttacking = false; // Clear attacking flag after animation
								}
							});
						}
					});
				}
			}
		}
	};
	return self;
});
var RangedEnemy = Enemy.expand(function () {
	var self = Enemy.call(this);
	// Remove default enemy graphics
	self.removeChildren();
	// Create pixelart ranged enemy character
	var enemyContainer = new Container();
	self.addChild(enemyContainer);
	// Body (purple archer)
	var body = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 55;
	body.height = 70;
	body.y = 10;
	body.tint = 0x8A2BE2; // Purple tint to match archer theme
	// Head with hood
	var head = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 35,
		height: 30
	});
	head.y = -35;
	head.tint = 0x6A1B9A;
	// Eyes (glowing yellow)
	var leftEye = enemyContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 6,
		height: 6
	});
	leftEye.x = -8;
	leftEye.y = -35;
	leftEye.tint = 0xFFFF00;
	var rightEye = enemyContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 6,
		height: 6
	});
	rightEye.x = 8;
	rightEye.y = -35;
	rightEye.tint = 0xFFFF00;
	// Bow
	var bow = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 45,
		height: 12
	});
	bow.x = -25;
	bow.y = 0;
	bow.rotation = 1.57; // 90 degrees
	bow.tint = 0x4B0082;
	// Bowstring
	var bowstring = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 2,
		height: 40
	});
	bowstring.x = -25;
	bowstring.y = 0;
	bowstring.rotation = 1.57;
	bowstring.tint = 0xDDDDDD; // Light grey string
	// Quiver on back
	var quiver = enemyContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 30
	});
	quiver.x = 20;
	quiver.y = -10;
	quiver.tint = 0x2B0040; // Dark purple
	// Override attributes for ranged enemy
	self.health = 20;
	self.maxHealth = 20;
	self.damage = 12;
	self.armor = 2;
	self.criticalChance = 0.1;
	self.magicResist = 2;
	self.mana = 30;
	self.speed = 1.5; // Slightly slower movement
	self.range = 4; // Long range for shooting
	self.goldValue = 3; // More valuable than melee enemies
	self.name = "Ranged Enemy";
	self.fireRate = 75; // Shoots faster - every 1.25 seconds
	self.lastShot = 0;
	self.baseScale = 1.3; // Base scale multiplier for all enemies (30% larger)
	// Apply base scale
	self.scaleX = self.baseScale;
	self.scaleY = self.baseScale;
	// Override update to include ranged attack behavior
	self.update = function () {
		if (!self.gridMovement) {
			self.gridMovement = new GridMovement(self, grid);
		}
		self.gridMovement.update();
		// Smart positioning - try to stay behind melee enemies
		var meleeFrontline = GRID_ROWS;
		for (var i = 0; i < enemies.length; i++) {
			var enemy = enemies[i];
			if (enemy !== self && enemy.range <= 1) {
				// Melee enemy
				if (enemy.gridY > self.gridY && enemy.gridY < meleeFrontline) {
					meleeFrontline = enemy.gridY;
				}
			}
		}
		// If we're ahead of melee units, consider retreating
		if (self.gridY > meleeFrontline && !self.isAttacking && Math.random() < 0.5) {
			// Try to move back if possible
			var backY = self.gridY - 1;
			if (backY >= 0 && !self.gridMovement.isCellOccupied(self.gridX, backY)) {
				// Override normal movement to retreat
				self.gridMovement.targetCell.y = backY;
			}
		}
		// Find and attack units within range (cell-based)
		var closestUnit = null;
		var closestCellDistance = self.range + 1; // Only units within range (cell count) are valid
		// First check if king exists and is in range
		if (kings.length > 0 && kings[0]) {
			var king = kings[0];
			if (typeof king.gridX === "number" && typeof king.gridY === "number") {
				var kingCellDist = Math.abs(self.gridX - king.gridX) + Math.abs(self.gridY - king.gridY);
				if (kingCellDist <= self.range && kingCellDist < closestCellDistance) {
					closestCellDistance = kingCellDist;
					closestUnit = king;
				}
			}
		}
		// Then check other units on the grid
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				if (grid[y] && grid[y][x]) {
					var gridSlot = grid[y][x];
					if (gridSlot.unit) {
						// Calculate cell-based Manhattan distance
						var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
						// Check if the enemy can shoot (doesn't need to be stationary like melee)
						if (cellDist <= self.range && cellDist < closestCellDistance) {
							closestCellDistance = cellDist;
							closestUnit = gridSlot.unit;
						}
					}
				}
			}
		}
		// Attack the closest unit if found
		if (closestUnit) {
			if (!self.lastShot) {
				self.lastShot = 0;
			}
			if (LK.ticks - self.lastShot >= self.fireRate) {
				self.lastShot = LK.ticks;
				// Create projectile
				var projectile = new EnemyProjectile(self.damage, closestUnit);
				projectile.x = self.x;
				projectile.y = self.y;
				enemyProjectiles.push(projectile);
				enemyContainer.addChild(projectile);
				// Play ranged attack sound
				LK.getSound('shoot').play();
				// Add shooting animation
				if (!self._isShootingTweening) {
					self._isShootingTweening = true;
					// Flash enemy blue briefly during shooting using LK effects
					LK.effects.flashObject(self, 0x4444FF, 200);
					self._isShootingTweening = false;
				}
			}
		}
	};
	return self;
});
var Boss = Enemy.expand(function () {
	var self = Enemy.call(this);
	// Remove default enemy graphics
	self.removeChildren();
	// Create massive boss container
	var bossContainer = new Container();
	self.addChild(bossContainer);
	// Main body (much larger and darker)
	var body = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 120;
	body.height = 120;
	body.y = 15;
	body.tint = 0x800000; // Dark red
	// Boss head (menacing)
	var head = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 80,
		height: 70
	});
	head.y = -60;
	head.tint = 0x4a0000; // Very dark red
	// Glowing eyes (intimidating)
	var leftEye = bossContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 15
	});
	leftEye.x = -20;
	leftEye.y = -60;
	leftEye.tint = 0xFF0000; // Bright red glowing eyes
	var rightEye = bossContainer.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 15
	});
	rightEye.x = 20;
	rightEye.y = -60;
	rightEye.tint = 0xFF0000;
	// Massive claws (larger and more threatening)
	var leftClaw = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 30
	});
	leftClaw.x = -50;
	leftClaw.y = 10;
	leftClaw.rotation = 0.7;
	leftClaw.tint = 0x2a0000; // Very dark
	var rightClaw = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 30
	});
	rightClaw.x = 50;
	rightClaw.y = 10;
	rightClaw.rotation = -0.7;
	rightClaw.tint = 0x2a0000;
	// Boss spikes on shoulders
	var leftSpike = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 40
	});
	leftSpike.x = -40;
	leftSpike.y = -20;
	leftSpike.rotation = 0.3;
	leftSpike.tint = 0x1a1a1a; // Dark spikes
	var rightSpike = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 40
	});
	rightSpike.x = 40;
	rightSpike.y = -20;
	rightSpike.rotation = -0.3;
	rightSpike.tint = 0x1a1a1a;
	// Boss crown/horns
	var horn1 = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 35
	});
	horn1.x = -15;
	horn1.y = -85;
	horn1.rotation = 0.2;
	horn1.tint = 0x000000; // Black horns
	var horn2 = bossContainer.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 35
	});
	horn2.x = 15;
	horn2.y = -85;
	horn2.rotation = -0.2;
	horn2.tint = 0x000000;
	// Override boss attributes - much more powerful
	self.health = 200;
	self.maxHealth = 200;
	self.damage = 60;
	self.armor = 15;
	self.criticalChance = 0.35;
	self.magicResist = 15;
	self.mana = 100;
	self.speed = 1.2; // Slightly slower but hits harder
	self.range = 3; // Even longer reach than normal enemies
	self.goldValue = 25; // Very high reward for defeating boss
	self.name = "Boss Monster";
	self.fireRate = 75; // Faster attack rate with devastating damage
	self.baseScale = 2.0; // Much larger than regular enemies (100% larger)
	// Boss special abilities
	self.lastSpecialAttack = 0;
	self.specialAttackCooldown = 300; // 5 seconds
	self.isEnraged = false;
	self.rageThreshold = 0.3; // Enrage when below 30% health
	// Apply base scale
	self.scaleX = self.baseScale;
	self.scaleY = self.baseScale;
	// Add menacing glow effect to eyes
	tween(leftEye, {
		scaleX: 1.3,
		scaleY: 1.3,
		alpha: 0.7
	}, {
		duration: 800,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(leftEye, {
				scaleX: 1.0,
				scaleY: 1.0,
				alpha: 1.0
			}, {
				duration: 800,
				easing: tween.easeInOut,
				onFinish: onFinish
			});
		}
	});
	tween(rightEye, {
		scaleX: 1.3,
		scaleY: 1.3,
		alpha: 0.7
	}, {
		duration: 800,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(rightEye, {
				scaleX: 1.0,
				scaleY: 1.0,
				alpha: 1.0
			}, {
				duration: 800,
				easing: tween.easeInOut,
				onFinish: onFinish
			});
		}
	});
	// Boss special attack - area damage
	self.performAreaAttack = function () {
		// Get all units within 2 cells
		var affectedUnits = [];
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				if (grid[y] && grid[y][x] && grid[y][x].unit) {
					var unit = grid[y][x].unit;
					var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
					if (cellDist <= 2) {
						affectedUnits.push(unit);
					}
				}
			}
		}
		// Check king separately
		if (kings.length > 0 && kings[0]) {
			var king = kings[0];
			if (typeof king.gridX === "number" && typeof king.gridY === "number") {
				var kingCellDist = Math.abs(self.gridX - king.gridX) + Math.abs(self.gridY - king.gridY);
				if (kingCellDist <= 2) {
					affectedUnits.push(king);
				}
			}
		}
		// Visual warning effect
		LK.effects.flashScreen(0x660000, 200);
		// Perform ground slam animation
		var originalScale = self.baseScale * (self.isEnraged ? 1.2 : 1.0);
		tween(self, {
			scaleX: originalScale * 0.8,
			scaleY: originalScale * 1.3
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Damage all nearby units
				for (var i = 0; i < affectedUnits.length; i++) {
					var unit = affectedUnits[i];
					var areaDamage = Math.floor(self.damage * 0.5); // Half damage for area attack
					var killed = unit.takeDamage(areaDamage);
					if (killed) {
						// Handle unit death
						for (var y = 0; y < GRID_ROWS; y++) {
							for (var x = 0; x < GRID_COLS; x++) {
								if (grid[y] && grid[y][x] && grid[y][x].unit === unit) {
									grid[y][x].unit = null;
									// Trigger death animation instead of immediate destroy
									unit.deathAnimation();
									for (var j = bench.length - 1; j >= 0; j--) {
										if (bench[j] === unit) {
											bench.splice(j, 1);
											break;
										}
									}
									break;
								}
							}
						}
					}
					// Flash effect on damaged unit
					LK.effects.flashObject(unit, 0xFF0000, 300);
				}
				// Return to normal size
				tween(self, {
					scaleX: originalScale,
					scaleY: originalScale
				}, {
					duration: 150,
					easing: tween.easeIn
				});
			}
		});
	};
	// Override takeDamage to handle enrage mechanic
	self.takeDamage = function (damage) {
		self.health -= damage;
		self.updateHealthBar();
		// Check for enrage
		if (!self.isEnraged && self.health / self.maxHealth <= self.rageThreshold) {
			self.isEnraged = true;
			// Visual enrage effect
			body.tint = 0xFF0000; // Bright red when enraged
			head.tint = 0x990000; // Dark red head
			// Increase stats when enraged
			self.damage = Math.floor(self.damage * 1.5);
			self.fireRate = Math.floor(self.fireRate * 0.7); // Attack faster
			self.speed = self.speed * 1.3;
			// Scale up slightly
			var enragedScale = self.baseScale * 1.2;
			tween(self, {
				scaleX: enragedScale,
				scaleY: enragedScale
			}, {
				duration: 500,
				easing: tween.easeOut
			});
			// Flash effect
			LK.effects.flashObject(self, 0xFF0000, 1000);
			LK.effects.flashScreen(0x660000, 500);
		}
		if (self.health <= 0) {
			self.health = 0;
			return true;
		}
		return false;
	};
	// Override attack with more devastating effects
	self.update = function () {
		if (!self.gridMovement) {
			self.gridMovement = new GridMovement(self, grid);
		}
		self.gridMovement.update();
		// Check for special area attack
		if (LK.ticks - self.lastSpecialAttack >= self.specialAttackCooldown) {
			// Check if there are multiple units nearby
			var nearbyUnits = 0;
			for (var y = 0; y < GRID_ROWS; y++) {
				for (var x = 0; x < GRID_COLS; x++) {
					if (grid[y] && grid[y][x] && grid[y][x].unit) {
						var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
						if (cellDist <= 2) {
							nearbyUnits++;
						}
					}
				}
			}
			// Perform area attack if 2+ units are nearby
			if (nearbyUnits >= 2) {
				self.lastSpecialAttack = LK.ticks;
				self.performAreaAttack();
				return; // Skip normal attack this frame
			}
		}
		// Find and attack units within range (cell-based)
		var closestUnit = null;
		var closestCellDistance = self.range + 1; // Only units within range (cell count) are valid
		// Smart target prioritization
		var targets = [];
		// First check if king exists and is in range
		if (kings.length > 0 && kings[0]) {
			var king = kings[0];
			if (typeof king.gridX === "number" && typeof king.gridY === "number") {
				var kingCellDist = Math.abs(self.gridX - king.gridX) + Math.abs(self.gridY - king.gridY);
				if (kingCellDist <= self.range && self.gridMovement.isMoving === false) {
					targets.push({
						unit: king,
						distance: kingCellDist,
						priority: 2 // Medium priority for king
					});
				}
			}
		}
		// Then check other units on the grid
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				if (grid[y] && grid[y][x]) {
					var gridSlot = grid[y][x];
					if (gridSlot.unit) {
						// Calculate cell-based Manhattan distance
						var cellDist = Math.abs(self.gridX - x) + Math.abs(self.gridY - y);
						// Check if the enemy is completely inside the adjacent cell before attacking
						if (cellDist <= self.range && self.gridMovement.isMoving === false) {
							var unit = gridSlot.unit;
							var priority = 3; // Default priority
							// Prioritize high-damage units
							if (unit.name === "Wizard" || unit.name === "Ranger") {
								priority = 1; // Highest priority
							} else if (unit.name === "Wall") {
								priority = 4; // Lowest priority
							}
							targets.push({
								unit: unit,
								distance: cellDist,
								priority: priority
							});
						}
					}
				}
			}
		}
		// Sort targets by priority, then by distance
		targets.sort(function (a, b) {
			if (a.priority !== b.priority) {
				return a.priority - b.priority;
			}
			return a.distance - b.distance;
		});
		// Select best target
		if (targets.length > 0) {
			closestUnit = targets[0].unit;
		}
		// Attack the closest unit if found
		if (closestUnit) {
			if (!self.lastAttack) {
				self.lastAttack = 0;
			}
			if (LK.ticks - self.lastAttack >= self.fireRate) {
				self.lastAttack = LK.ticks;
				// Add devastating boss attack animation
				var originalX = self.x;
				var originalY = self.y;
				// Calculate lunge direction towards target
				var dx = closestUnit.x - self.x;
				var dy = closestUnit.y - self.y;
				var dist = Math.sqrt(dx * dx + dy * dy);
				var offset = Math.min(60, dist * 0.5); // Even larger lunge for boss
				var lungeX = self.x + (dist > 0 ? dx / dist * offset : 0);
				var lungeY = self.y + (dist > 0 ? dy / dist * offset : 0);
				// Prevent multiple attack tweens at once
				if (!self._isAttackTweening) {
					self._isAttackTweening = true;
					self.isAttacking = true; // Set attacking flag
					// Flash boss with intense red and shake screen
					LK.effects.flashObject(self, 0xFF0000, 500);
					if (self.isEnraged) {
						LK.effects.flashScreen(0x880000, 400); // Darker red screen flash when enraged
					} else {
						LK.effects.flashScreen(0x440000, 300); // Dark red screen flash
					}
					// Lunge towards target with more force
					tween(self, {
						x: lungeX,
						y: lungeY,
						rotation: self.rotation + (Math.random() > 0.5 ? 0.1 : -0.1)
					}, {
						duration: 120,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							// Apply massive damage after lunge
							// Play melee attack sound
							LK.getSound('melee_attack').play();
							var actualDamage = self.damage;
							// Critical hit chance
							if (Math.random() < self.criticalChance) {
								actualDamage = Math.floor(actualDamage * 2);
								LK.effects.flashObject(closestUnit, 0xFFFF00, 200); // Yellow flash for crit
							}
							var killed = closestUnit.takeDamage(actualDamage);
							if (killed) {
								self.isAttacking = false; // Clear attacking flag if target dies
								for (var y = 0; y < GRID_ROWS; y++) {
									for (var x = 0; x < GRID_COLS; x++) {
										if (grid[y] && grid[y][x]) {
											var gridSlot = grid[y][x];
											if (gridSlot.unit === closestUnit) {
												gridSlot.unit = null;
												// Trigger death animation instead of immediate destroy
												closestUnit.deathAnimation();
												for (var i = bench.length - 1; i >= 0; i--) {
													if (bench[i] === closestUnit) {
														bench.splice(i, 1);
														break;
													}
												}
												break;
											}
										}
									}
								}
							}
							// Return to original position
							tween(self, {
								x: originalX,
								y: originalY,
								rotation: 0
							}, {
								duration: 100,
								easing: tween.easeIn,
								onFinish: function onFinish() {
									self._isAttackTweening = false;
									self.isAttacking = false; // Clear attacking flag after animation
								}
							});
						}
					});
				}
			}
		}
	};
	return self;
});
var EnemyProjectile = Container.expand(function (damage, target) {
	var self = Container.call(this);
	// Create arrow projectile for enemies
	var arrowContainer = new Container();
	self.addChild(arrowContainer);
	// Arrow shaft
	var arrowShaft = arrowContainer.attachAsset('arrow', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 25,
		height: 6
	});
	arrowShaft.tint = 0x4B0082; // Dark purple for enemy arrows
	// Arrow head
	var arrowHead = arrowContainer.attachAsset('arrow_head', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 10
	});
	arrowHead.x = 12;
	arrowHead.rotation = 0.785; // 45 degrees
	arrowHead.tint = 0xFF0000; // Red tip for enemy
	// Arrow fletching
	var fletching = arrowContainer.attachAsset('arrow_feather', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 5
	});
	fletching.x = -8;
	fletching.tint = 0x8B008B; // Dark magenta feathers
	self.damage = damage;
	self.target = target;
	self.speed = 6;
	self.update = function () {
		if (!self.target || self.target.health <= 0) {
			self.destroy();
			return;
		}
		var dx = self.target.x - self.x;
		var dy = self.target.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < 15) {
			// Hit target
			var killed = self.target.takeDamage(self.damage);
			if (killed) {
				// Handle target death - remove from grid if it's a unit
				for (var y = 0; y < GRID_ROWS; y++) {
					for (var x = 0; x < GRID_COLS; x++) {
						if (grid[y] && grid[y][x]) {
							var gridSlot = grid[y][x];
							if (gridSlot.unit === self.target) {
								gridSlot.unit = null;
								// Trigger death animation instead of immediate destroy
								self.target.deathAnimation();
								for (var i = bench.length - 1; i >= 0; i--) {
									if (bench[i] === self.target) {
										bench.splice(i, 1);
										break;
									}
								}
								break;
							}
						}
					}
				}
			}
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
		// Rotate arrow to face target
		self.rotation = Math.atan2(dy, dx);
	};
	return self;
});
var GridMovement = Container.expand(function (entity, gridRef) {
	var self = Container.call(this);
	self.entity = entity;
	self.gridRef = gridRef;
	self.currentCell = {
		x: entity.gridX,
		y: entity.gridY
	};
	self.targetCell = {
		x: entity.gridX,
		y: entity.gridY
	};
	self.moveSpeed = 2; // Pixels per frame for continuous movement
	self.isMoving = false; // Track if entity is currently moving
	self.pathToTarget = []; // Store calculated path
	self.pathIndex = 0; // Current position in path
	// Helper method to check if a cell is occupied
	self.isCellOccupied = function (x, y) {
		// Check if out of bounds
		if (x < 0 || x >= GRID_COLS || y < 0 || y >= GRID_ROWS) {
			return true;
		}
		// Check if position is occupied by any entity using position tracking
		if (isPositionOccupied(x, y, self.entity)) {
			return true;
		}
		// Check if cell is reserved by another entity
		var cellKey = x + ',' + y;
		if (cellReservations[cellKey] && cellReservations[cellKey] !== self.entity) {
			return true;
		}
		// Check if occupied by a player unit on grid
		if (self.gridRef[y] && self.gridRef[y][x] && self.gridRef[y][x].unit && self.gridRef[y][x].unit !== self.entity) {
			return true;
		}
		return false;
	};
	// A* pathfinding implementation
	self.findPath = function (startX, startY, goalX, goalY) {
		var openSet = [];
		var closedSet = [];
		var cameFrom = {};
		// Helper to create node
		function createNode(x, y, g, h) {
			return {
				x: x,
				y: y,
				g: g,
				// Cost from start
				h: h,
				// Heuristic cost to goal
				f: g + h // Total cost
			};
		}
		// Manhattan distance heuristic
		function heuristic(x1, y1, x2, y2) {
			return Math.abs(x2 - x1) + Math.abs(y2 - y1);
		}
		// Cache directions array at class level to avoid recreation
		if (!self.directions) {
			self.directions = [{
				x: 0,
				y: -1
			},
			// Up
			{
				x: 1,
				y: 0
			},
			// Right
			{
				x: 0,
				y: 1
			},
			// Down
			{
				x: -1,
				y: 0
			} // Left
			];
		}
		// Get neighbors of a cell
		function getNeighbors(x, y) {
			var neighbors = [];
			// Check if this entity is a player unit
			var isPlayerUnit = self.entity.isPlayerUnit !== undefined ? self.entity.isPlayerUnit : self.entity.name && (self.entity.name === "Soldier" || self.entity.name === "Knight" || self.entity.name === "Wizard" || self.entity.name === "Paladin" || self.entity.name === "Ranger" || self.entity.name === "King" || self.entity.name === "Wall" || self.entity.name === "Crossbow Tower");
			// Cache this value on entity for future use
			if (self.entity.isPlayerUnit === undefined) {
				self.entity.isPlayerUnit = isPlayerUnit;
			}
			for (var i = 0; i < self.directions.length; i++) {
				var newX = x + self.directions[i].x;
				var newY = y + self.directions[i].y;
				// Player units cannot path into fog of war (top 2 rows)
				if (isPlayerUnit && newY < 2) {
					continue;
				}
				// Skip if occupied (but allow goal position even if occupied)
				if (newX === goalX && newY === goalY || !self.isCellOccupied(newX, newY)) {
					neighbors.push({
						x: newX,
						y: newY
					});
				}
			}
			return neighbors;
		}
		// Initialize start node
		var startNode = createNode(startX, startY, 0, heuristic(startX, startY, goalX, goalY));
		openSet.push(startNode);
		// Track best g scores
		var gScore = {};
		gScore[startX + ',' + startY] = 0;
		while (openSet.length > 0) {
			// Find node with lowest f score
			var current = openSet[0];
			var currentIndex = 0;
			for (var i = 1; i < openSet.length; i++) {
				if (openSet[i].f < current.f) {
					current = openSet[i];
					currentIndex = i;
				}
			}
			// Check if we reached goal
			if (current.x === goalX && current.y === goalY) {
				// Reconstruct path
				var path = [];
				var key = current.x + ',' + current.y;
				while (key && key !== startX + ',' + startY) {
					var coords = key.split(',');
					path.unshift({
						x: parseInt(coords[0]),
						y: parseInt(coords[1])
					});
					key = cameFrom[key];
				}
				return path;
			}
			// Move current from open to closed
			openSet.splice(currentIndex, 1);
			closedSet.push(current);
			// Check neighbors
			var neighbors = getNeighbors(current.x, current.y);
			for (var i = 0; i < neighbors.length; i++) {
				var neighbor = neighbors[i];
				var neighborKey = neighbor.x + ',' + neighbor.y;
				// Skip if in closed set
				var inClosed = false;
				for (var j = 0; j < closedSet.length; j++) {
					if (closedSet[j].x === neighbor.x && closedSet[j].y === neighbor.y) {
						inClosed = true;
						break;
					}
				}
				if (inClosed) {
					continue;
				}
				// Calculate tentative g score
				var tentativeG = current.g + 1;
				// Check if this path is better
				if (!gScore[neighborKey] || tentativeG < gScore[neighborKey]) {
					// Record best path
					cameFrom[neighborKey] = current.x + ',' + current.y;
					gScore[neighborKey] = tentativeG;
					// Add to open set if not already there
					var inOpen = false;
					for (var j = 0; j < openSet.length; j++) {
						if (openSet[j].x === neighbor.x && openSet[j].y === neighbor.y) {
							inOpen = true;
							openSet[j].g = tentativeG;
							openSet[j].f = tentativeG + openSet[j].h;
							break;
						}
					}
					if (!inOpen) {
						var h = heuristic(neighbor.x, neighbor.y, goalX, goalY);
						openSet.push(createNode(neighbor.x, neighbor.y, tentativeG, h));
					}
				}
			}
		}
		// No path found - try simple alternative
		return self.findAlternativePath(goalX, goalY);
	};
	// Helper method to find alternative paths (fallback for when A* fails)
	self.findAlternativePath = function (targetX, targetY) {
		var currentX = self.currentCell.x;
		var currentY = self.currentCell.y;
		// Calculate primary direction
		var dx = targetX - currentX;
		var dy = targetY - currentY;
		// Try moving in the primary direction first
		var moves = [];
		if (Math.abs(dx) > Math.abs(dy)) {
			// Prioritize horizontal movement
			if (dx > 0 && !self.isCellOccupied(currentX + 1, currentY)) {
				return [{
					x: currentX + 1,
					y: currentY
				}];
			}
			if (dx < 0 && !self.isCellOccupied(currentX - 1, currentY)) {
				return [{
					x: currentX - 1,
					y: currentY
				}];
			}
			// Try vertical as alternative
			if (dy > 0 && !self.isCellOccupied(currentX, currentY + 1)) {
				return [{
					x: currentX,
					y: currentY + 1
				}];
			}
			if (dy < 0 && !self.isCellOccupied(currentX, currentY - 1)) {
				return [{
					x: currentX,
					y: currentY - 1
				}];
			}
		} else {
			// Prioritize vertical movement
			if (dy > 0 && !self.isCellOccupied(currentX, currentY + 1)) {
				return [{
					x: currentX,
					y: currentY + 1
				}];
			}
			if (dy < 0 && !self.isCellOccupied(currentX, currentY - 1)) {
				return [{
					x: currentX,
					y: currentY - 1
				}];
			}
			// Try horizontal as alternative
			if (dx > 0 && !self.isCellOccupied(currentX + 1, currentY)) {
				return [{
					x: currentX + 1,
					y: currentY
				}];
			}
			if (dx < 0 && !self.isCellOccupied(currentX - 1, currentY)) {
				return [{
					x: currentX - 1,
					y: currentY
				}];
			}
		}
		return null;
	};
	self.moveToNextCell = function () {
		// Check if this is a structure unit that shouldn't move
		if (self.entity.isStructure) {
			return false; // Structures don't move
		}
		// Check if this is a player unit or enemy
		var isPlayerUnit = self.entity.name && (self.entity.name === "Soldier" || self.entity.name === "Knight" || self.entity.name === "Wizard" || self.entity.name === "Paladin" || self.entity.name === "Ranger" || self.entity.name === "King");
		var targetGridX = -1;
		var targetGridY = -1;
		var shouldMove = false;
		if (isPlayerUnit) {
			// Player units move towards enemies
			var closestEnemy = null;
			var closestDist = 99999;
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				if (typeof enemy.gridX === "number" && typeof enemy.gridY === "number") {
					var dx = enemy.gridX - self.currentCell.x;
					var dy = enemy.gridY - self.currentCell.y;
					var dist = Math.abs(dx) + Math.abs(dy);
					if (dist < closestDist) {
						closestDist = dist;
						closestEnemy = enemy;
						targetGridX = enemy.gridX;
						targetGridY = enemy.gridY;
					}
				}
			}
			// Only move if enemy found and not in range
			if (closestEnemy && closestDist > self.entity.range) {
				// Check if unit is currently attacking
				if (self.entity.isAttacking) {
					return false; // Don't move while attacking
				}
				shouldMove = true;
			} else {
				// Already in range or no enemy, don't move
				return false;
			}
		} else {
			// Smarter enemy movement logic
			// First, check if enemy is currently in combat (attacking or being attacked)
			if (self.entity.isAttacking) {
				// Stay in place while attacking
				return false;
			}
			// Enemy coordination - wait for nearby allies before advancing
			var nearbyAllies = 0;
			var shouldWait = false;
			for (var i = 0; i < enemies.length; i++) {
				var ally = enemies[i];
				if (ally !== self.entity && ally.gridY === self.entity.gridY) {
					// Check if ally is in same row
					var allyDist = Math.abs(ally.gridX - self.entity.gridX);
					if (allyDist <= 2) {
						nearbyAllies++;
						// If ally is behind us, wait for them
						if (ally.gridY < self.entity.gridY) {
							shouldWait = true;
						}
					}
				}
			}
			// Wait if we're too far ahead of our allies
			if (shouldWait && nearbyAllies < 2 && Math.random() < 0.7) {
				return false; // 70% chance to wait for allies
			}
			// Find closest player unit (excluding king initially)
			var closestUnit = null;
			var closestDist = 99999;
			var kingUnit = null;
			var kingDist = 99999;
			for (var y = 0; y < GRID_ROWS; y++) {
				for (var x = 0; x < GRID_COLS; x++) {
					if (self.gridRef[y] && self.gridRef[y][x] && self.gridRef[y][x].unit) {
						var unit = self.gridRef[y][x].unit;
						var dx = x - self.currentCell.x;
						var dy = y - self.currentCell.y;
						var dist = Math.abs(dx) + Math.abs(dy);
						if (unit.name === "King") {
							// Track king separately
							if (dist < kingDist) {
								kingDist = dist;
								kingUnit = unit;
							}
						} else {
							// Track other player units
							if (dist < closestDist) {
								closestDist = dist;
								closestUnit = unit;
								targetGridX = x;
								targetGridY = y;
							}
						}
					}
				}
			}
			// Determine target based on smart AI logic
			if (closestUnit) {
				// Found a non-king player unit
				var entityRange = self.entity.range || 1;
				// If enemy is within range, stay and fight
				if (closestDist <= entityRange) {
					// Stay in current position - engage in combat
					return false;
				}
				// Move towards the closest player unit
				shouldMove = true;
			} else if (kingUnit) {
				// No other player units remaining, go for the king
				targetGridX = kingUnit.gridX;
				targetGridY = kingUnit.gridY;
				var entityRange = self.entity.range || 1;
				// If enemy is within range of king, stay and fight
				if (kingDist <= entityRange) {
					// Stay in current position - engage king in combat
					return false;
				}
				// Move towards the king
				shouldMove = true;
			} else {
				// No target found, move down as fallback
				targetGridX = self.currentCell.x;
				targetGridY = self.currentCell.y + 1;
				shouldMove = true;
			}
		}
		if (!shouldMove) {
			return false;
		}
		// Use A* pathfinding to find best path
		if (!self.pathToTarget || self.pathToTarget.length === 0 || self.pathIndex >= self.pathToTarget.length) {
			// Calculate new path
			var path = self.findPath(self.currentCell.x, self.currentCell.y, targetGridX, targetGridY);
			if (path && path.length > 0) {
				self.pathToTarget = path;
				self.pathIndex = 0;
			} else {
				// No path found
				return false;
			}
		}
		// Get next cell from path
		var nextCell = self.pathToTarget[self.pathIndex];
		if (!nextCell) {
			return false;
		}
		var nextX = nextCell.x;
		var nextY = nextCell.y;
		// Check if desired cell is still unoccupied
		if (self.isCellOccupied(nextX, nextY)) {
			// Path is blocked, recalculate
			self.pathToTarget = [];
			self.pathIndex = 0;
			return false;
		}
		// Final check if the cell is valid and unoccupied
		if (!self.isCellOccupied(nextX, nextY) && self.gridRef[nextY] && self.gridRef[nextY][nextX]) {
			// Prevent player units from moving into fog of war (top 2 rows)
			var isPlayerUnit = self.entity.name && (self.entity.name === "Soldier" || self.entity.name === "Knight" || self.entity.name === "Wizard" || self.entity.name === "Paladin" || self.entity.name === "Ranger" || self.entity.name === "King" || self.entity.name === "Wall" || self.entity.name === "Crossbow Tower");
			if (isPlayerUnit && nextY < 2) {
				// Player units cannot move into fog of war
				self.pathToTarget = [];
				self.pathIndex = 0;
				return false;
			}
			var targetGridCell = self.gridRef[nextY][nextX];
			// Double-check that no other entity is trying to move to same position at same time
			if (isPositionOccupied(nextX, nextY, self.entity)) {
				return false;
			}
			// Unregister old position
			unregisterEntityPosition(self.entity, self.currentCell.x, self.currentCell.y);
			// Register new position immediately to prevent conflicts
			registerEntityPosition(self.entity);
			// Release old reservation
			var oldCellKey = self.currentCell.x + ',' + self.currentCell.y;
			if (cellReservations[oldCellKey] === self.entity) {
				delete cellReservations[oldCellKey];
			}
			// Reserve new cell
			var newCellKey = nextX + ',' + nextY;
			cellReservations[newCellKey] = self.entity;
			// Update logical position immediately
			self.currentCell.x = nextX;
			self.currentCell.y = nextY;
			self.entity.gridX = nextX;
			self.entity.gridY = nextY;
			// Set target position for smooth movement
			self.targetCell.x = targetGridCell.x;
			self.targetCell.y = targetGridCell.y;
			self.isMoving = true;
			// Add smooth transition animation when starting movement
			if (!self.entity._isMoveTweening) {
				self.entity._isMoveTweening = true;
				// Get base scale (default to 1 if not set)
				var baseScale = self.entity.baseScale || 1;
				// Slight scale and rotation animation when moving
				tween(self.entity, {
					scaleX: baseScale * 1.1,
					scaleY: baseScale * 0.9,
					rotation: self.entity.rotation + (Math.random() > 0.5 ? 0.05 : -0.05)
				}, {
					duration: 150,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						tween(self.entity, {
							scaleX: baseScale,
							scaleY: baseScale,
							rotation: 0
						}, {
							duration: 150,
							easing: tween.easeIn,
							onFinish: function onFinish() {
								self.entity._isMoveTweening = false;
							}
						});
					}
				});
			}
			return true;
		}
		return false;
	};
	self.update = function () {
		// Periodically check if we need to recalculate path (every 30 ticks)
		if (LK.ticks % 30 === 0 && self.pathToTarget && self.pathToTarget.length > 0) {
			// Check if current path is still valid
			var stillValid = true;
			for (var i = self.pathIndex; i < self.pathToTarget.length && i < self.pathIndex + 3; i++) {
				if (self.pathToTarget[i] && self.isCellOccupied(self.pathToTarget[i].x, self.pathToTarget[i].y)) {
					stillValid = false;
					break;
				}
			}
			if (!stillValid) {
				// Path blocked, clear it to force recalculation
				self.pathToTarget = [];
				self.pathIndex = 0;
			}
		}
		// If we have a target position, move towards it smoothly
		if (self.isMoving) {
			var dx = self.targetCell.x - self.entity.x;
			var dy = self.targetCell.y - self.entity.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > self.moveSpeed) {
				// Continue moving towards target
				var moveX = dx / distance * self.moveSpeed;
				var moveY = dy / distance * self.moveSpeed;
				self.entity.x += moveX;
				self.entity.y += moveY;
			} else {
				// Reached target cell - ensure exact grid alignment
				var finalGridX = self.currentCell.x;
				var finalGridY = self.currentCell.y;
				var finalX = GRID_START_X + finalGridX * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
				var finalY = GRID_START_Y + finalGridY * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
				self.entity.x = finalX;
				self.entity.y = finalY;
				self.isMoving = false;
				self.pathIndex++; // Move to next cell in path
				// Wait a tick before trying next move to avoid simultaneous conflicts
				if (LK.ticks % 2 === 0) {
					// Immediately try to move to next cell for continuous movement
					self.moveToNextCell();
				}
			}
		} else {
			// Not moving, try to start moving to next cell
			// Add slight randomization to prevent all entities from moving at exact same time
			if (LK.ticks % (2 + Math.floor(Math.random() * 3)) === 0) {
				self.moveToNextCell();
			}
		}
	};
	return self;
});
var GridSlot = Container.expand(function (lane, gridX, gridY) {
	var self = Container.call(this);
	var slotGraphics = self.attachAsset('grid_slot', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.lane = lane;
	self.gridX = gridX;
	self.gridY = gridY;
	self.unit = null;
	slotGraphics.alpha = 0.3;
	self.down = function (x, y, obj) {
		if (self.unit && !draggedUnit && gameState === 'planning') {
			// Allow dragging any unit during planning phase
			draggedUnit = self.unit;
			draggedUnit.originalX = self.x;
			draggedUnit.originalY = self.y;
			draggedUnit.originalGridSlot = self;
			draggedFromGrid = true;
		}
	};
	self.up = function (x, y, obj) {
		if (draggedUnit && !self.unit) {
			self.placeUnit(draggedUnit);
			draggedUnit = null;
		}
	};
	self.placeUnit = function (unit) {
		if (self.unit) {
			// Swap units if the slot is occupied
			var tempUnit = self.unit;
			self.unit = unit;
			unit.originalGridSlot.unit = tempUnit;
			tempUnit.x = unit.originalGridSlot.x;
			tempUnit.y = unit.originalGridSlot.y;
			tempUnit.gridX = unit.originalGridSlot.gridX;
			tempUnit.gridY = unit.originalGridSlot.gridY;
			tempUnit.lane = unit.originalGridSlot.lane;
			return true;
		}
		// Prevent placement in fog of war (top 2 rows)
		if (self.gridY < 2) {
			// Show message about fog of war
			var fogMessage = new Text2('Cannot place units in the fog of war!', {
				size: 72,
				fill: 0xFF4444
			});
			fogMessage.anchor.set(0.5, 0.5);
			fogMessage.x = 1024; // Center of screen
			fogMessage.y = 800; // Middle of screen
			game.addChild(fogMessage);
			// Flash the message and fade it out
			LK.effects.flashObject(fogMessage, 0xFFFFFF, 300);
			tween(fogMessage, {
				alpha: 0,
				y: 700
			}, {
				duration: 3000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					fogMessage.destroy();
				}
			});
			// Return unit to bench if it was being dragged
			if (unit.originalSlot) {
				unit.originalSlot.unit = unit;
				unit.x = unit.originalSlot.x;
				unit.y = unit.originalSlot.y;
			} else {
				// Find first available bench slot
				for (var i = 0; i < benchSlots.length; i++) {
					if (!benchSlots[i].unit) {
						benchSlots[i].unit = unit;
						unit.x = benchSlots[i].x;
						unit.y = benchSlots[i].y;
						unit.gridX = -1;
						unit.gridY = -1;
						unit.lane = -1;
						unit.hideHealthBar();
						unit.hideStarIndicator();
						updateBenchDisplay();
						break;
					}
				}
			}
			return false;
		}
		// Check if position is already occupied by another entity
		if (isPositionOccupied(self.gridX, self.gridY, unit)) {
			return false;
		}
		// Check unit placement limits (don't apply to king)
		if (unit.name !== "King" && !canPlaceMoreUnits(unit.isStructure)) {
			// Show message about reaching unit limit
			var limitType = unit.isStructure ? 'structures' : 'units';
			var limitMessage = new Text2('You have no more room for ' + limitType + ' in the battlefield, level up to increase it!', {
				size: 72,
				fill: 0xFF4444
			});
			limitMessage.anchor.set(0.5, 0.5);
			limitMessage.x = 1024; // Center of screen
			limitMessage.y = 800; // Middle of screen
			game.addChild(limitMessage);
			// Flash the message and fade it out
			LK.effects.flashObject(limitMessage, 0xFFFFFF, 300);
			tween(limitMessage, {
				alpha: 0,
				y: 700
			}, {
				duration: 5000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					limitMessage.destroy();
				}
			});
			// Return unit to bench - find first available bench slot
			for (var i = 0; i < benchSlots.length; i++) {
				if (!benchSlots[i].unit) {
					benchSlots[i].unit = unit;
					unit.x = benchSlots[i].x;
					unit.y = benchSlots[i].y;
					unit.gridX = -1;
					unit.gridY = -1;
					unit.lane = -1;
					unit.hideHealthBar();
					unit.hideStarIndicator();
					updateBenchDisplay();
					break;
				}
			}
			return false; // Can't place more units
		}
		self.unit = unit;
		// Unregister old position if unit was previously on grid
		if (unit.gridX >= 0 && unit.gridY >= 0) {
			unregisterEntityPosition(unit, unit.gridX, unit.gridY);
		}
		// Calculate exact grid cell center position
		var gridCenterX = GRID_START_X + self.gridX * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		var gridCenterY = GRID_START_Y + self.gridY * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		// Update unit's grid coordinates
		unit.gridX = self.gridX;
		unit.gridY = self.gridY;
		unit.lane = self.lane;
		// Force unit to exact grid position (snap to grid)
		unit.x = gridCenterX;
		unit.y = gridCenterY;
		// Ensure the grid slot also has the correct position
		self.x = gridCenterX;
		self.y = gridCenterY;
		// Add placement animation with bounce effect
		var targetScale = unit.baseScale || 1.3; // Use base scale or default to 1.3
		if (unit.tier === 2) {
			targetScale = (unit.baseScale || 1.3) * 1.2;
		} else if (unit.tier === 3) {
			targetScale = (unit.baseScale || 1.3) * 1.3;
		}
		// Stop any ongoing scale tweens before starting new bounce
		tween.stop(unit, {
			scaleX: true,
			scaleY: true
		});
		// Always reset scale to 0 before bounce (fixes bug where scale is not reset)
		unit.scaleX = 0;
		unit.scaleY = 0;
		// Capture unit reference before any async operations
		var unitToAnimate = unit;
		// Start bounce animation immediately
		// Set bounce animation flag to prevent updateUnitScale interference
		unitToAnimate._isBounceAnimating = true;
		tween(unitToAnimate, {
			scaleX: targetScale * 1.2,
			scaleY: targetScale * 1.2
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(unitToAnimate, {
					scaleX: targetScale,
					scaleY: targetScale
				}, {
					duration: 150,
					easing: tween.easeIn
				});
			}
		});
		// Register new position
		registerEntityPosition(unit);
		unit.showHealthBar(); // Show health bar when placed on grid
		unit.updateHealthBar(); // Update health bar to show current health
		// Delay showStarIndicator until after bounce animation completes
		LK.setTimeout(function () {
			if (unitToAnimate && unitToAnimate.parent) {
				// Check if unit still exists
				unitToAnimate.showStarIndicator(); // Show star indicator after bounce animation
			}
		}, 400); // Wait for bounce animation to complete (200ms + 150ms + small buffer)
		// Don't remove from bench - units stay in both places
		updateBenchDisplay();
		countUnitsOnField(); // Update unit counts
		return true;
	};
	return self;
});
var HealthBar = Container.expand(function (width, height) {
	var self = Container.call(this);
	self.maxWidth = width;
	// Background of the health bar
	self.background = self.attachAsset('healthbar_bg', {
		anchorX: 0,
		anchorY: 0.5,
		width: width,
		height: height
	});
	// Foreground of the health bar
	self.foreground = self.attachAsset('healthbar_fg', {
		anchorX: 0,
		anchorY: 0.5,
		width: width,
		height: height
	});
	self.updateHealth = function (currentHealth, maxHealth) {
		var healthRatio = currentHealth / maxHealth;
		self.foreground.width = self.maxWidth * healthRatio;
		if (healthRatio > 0.6) {
			self.foreground.tint = 0x00ff00; // Green
		} else if (healthRatio > 0.3) {
			self.foreground.tint = 0xffff00; // Yellow
		} else {
			self.foreground.tint = 0xff0000; // Red
		}
	};
	return self;
});
var StarIndicator = Container.expand(function (tier) {
	var self = Container.call(this);
	self.tier = tier || 1;
	self.dots = [];
	self.updateStars = function (newTier) {
		self.tier = newTier;
		// Remove existing dots
		for (var i = 0; i < self.dots.length; i++) {
			self.dots[i].destroy();
		}
		self.dots = [];
		// Create new dots based on tier
		var dotSpacing = 12;
		var totalWidth = (self.tier - 1) * dotSpacing;
		var startX = -totalWidth / 2;
		for (var i = 0; i < self.tier; i++) {
			var dot = self.attachAsset('star_dot', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			dot.x = startX + i * dotSpacing;
			dot.y = 0;
			self.dots.push(dot);
		}
	};
	// Initialize with current tier
	self.updateStars(self.tier);
	return self;
});
var Unit = Container.expand(function (tier) {
	var self = Container.call(this);
	self.tier = tier || 1;
	var assetName = 'unit_tier' + self.tier;
	var unitGraphics = self.attachAsset(assetName, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 100;
	self.maxHealth = 100;
	self.damage = self.tier;
	self.speed = 1; // Attack speed multiplier
	self.fireRate = 60; // Base fire rate in ticks
	self.lastShot = 0;
	self.gridX = -1;
	self.gridY = -1;
	self.lane = -1;
	self.range = 1; // Default range in cells (adjacent/melee). Override in subclasses for ranged units.
	self.healthBar = null; // Initialize health bar as null
	self.starIndicator = null; // Initialize star indicator as null
	self.isAttacking = false; // Flag to track if unit is currently attacking
	self.baseScale = 1.3; // Base scale multiplier for all units (30% larger)
	// Apply base scale
	self.scaleX = self.baseScale;
	self.scaleY = self.baseScale;
	self.showHealthBar = function () {
		if (!self.healthBar) {
			self.healthBar = new HealthBar(80, 10); // Create a health bar instance
			self.healthBar.x = -40; // Position relative to the unit's center
			self.healthBar.y = -60; // Position above the unit
			self.addChild(self.healthBar);
			self.healthBar._lastVisible = false; // Track visibility state
		}
		// Only update if visibility changed
		if (!self.healthBar._lastVisible) {
			self.healthBar.visible = true; // Ensure health bar is visible
			self.healthBar._lastVisible = true;
		}
		self.healthBar.updateHealth(self.health, self.maxHealth);
	};
	self.showStarIndicator = function () {
		if (!self.starIndicator) {
			self.starIndicator = new StarIndicator(self.tier);
			self.starIndicator.x = 0; // Center relative to unit
			self.starIndicator.y = 55; // Position below the unit
			self.addChild(self.starIndicator);
		}
		self.starIndicator.visible = true;
		self.starIndicator.updateStars(self.tier);
		// Scale unit based on tier - two star units are 30% larger
		self.updateUnitScale();
	};
	self.updateUnitScale = function () {
		// Check if bounce animation is in progress - if so, don't interfere
		if (self._isBounceAnimating) {
			return; // Skip scale update during bounce animation
		}
		// Stop any ongoing scale tweens first
		tween.stop(self, {
			scaleX: true,
			scaleY: true
		});
		if (self.tier === 2) {
			// Two star units are 20% larger on top of base scale
			var targetScale = self.baseScale * 1.2;
			self.scaleX = targetScale;
			self.scaleY = targetScale;
			tween(self, {
				scaleX: targetScale,
				scaleY: targetScale
			}, {
				duration: 300,
				easing: tween.easeOut
			});
		} else if (self.tier === 3) {
			// Three star units are 30% larger on top of base scale
			var targetScale = self.baseScale * 1.3;
			self.scaleX = targetScale;
			self.scaleY = targetScale;
			tween(self, {
				scaleX: targetScale,
				scaleY: targetScale
			}, {
				duration: 300,
				easing: tween.easeOut
			});
		} else {
			// Tier 1 units use base scale
			self.scaleX = self.baseScale;
			self.scaleY = self.baseScale;
			tween(self, {
				scaleX: self.baseScale,
				scaleY: self.baseScale
			}, {
				duration: 300,
				easing: tween.easeOut
			});
		}
	};
	self.hideHealthBar = function () {
		if (self.healthBar) {
			self.healthBar.destroy();
			self.healthBar = null;
		}
	};
	self.hideStarIndicator = function () {
		if (self.starIndicator) {
			self.starIndicator.destroy();
			self.starIndicator = null;
		}
	};
	self.updateHealthBar = function () {
		if (self.healthBar) {
			self.healthBar.updateHealth(self.health, self.maxHealth);
		}
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		if (self.health < 0) {
			self.health = 0;
		} // Ensure health doesn't go below 0
		self.updateHealthBar(); // Update health bar when taking damage
		if (self.health <= 0) {
			self.hideHealthBar(); // Hide health bar when destroyed
			return true;
		}
		return false;
	};
	self.deathAnimation = function () {
		// Hide health bar and star indicator immediately
		if (self.healthBar) {
			self.healthBar.destroy();
			self.healthBar = null;
		}
		if (self.starIndicator) {
			self.starIndicator.destroy();
			self.starIndicator = null;
		}
		// Create particle explosion effect
		var particleContainer = new Container();
		particleContainer.x = self.x;
		particleContainer.y = self.y;
		self.parent.addChild(particleContainer);
		// Number of particles based on unit type
		var particleCount = 10; // Default for regular units
		var particleColors = [];
		var particleSize = 12;
		var explosionRadius = 60;
		// Customize particle colors based on unit type
		if (self.name === "Soldier" || self.name === "Knight") {
			particleColors = [0x32CD32, 0x228B22, 0x66ff66, 0x4da24d]; // Green shades
		} else if (self.name === "Wizard") {
			particleColors = [0x191970, 0x000066, 0x00FFFF, 0x4444FF]; // Blue/cyan shades
		} else if (self.name === "Ranger") {
			particleColors = [0x87CEEB, 0x9d9dff, 0x4169E1, 0x6495ED]; // Light blue shades
		} else if (self.name === "Paladin") {
			particleColors = [0x4169E1, 0x4444FF, 0xFFD700, 0x1E90FF]; // Royal blue with gold
		} else if (self.name === "Wall") {
			particleColors = [0x808080, 0x696969, 0x606060, 0x505050]; // Grey stone shades
			particleSize = 15;
		} else if (self.name === "Crossbow Tower") {
			particleColors = [0x8B4513, 0x654321, 0x696969, 0x5C4033]; // Brown/grey shades
			particleSize = 15;
		} else if (self.name === "King") {
			// King gets special treatment
			particleColors = [0xFFD700, 0xFFFF00, 0xFF0000, 0x4B0082]; // Gold, yellow, red, purple
			particleCount = 20;
			particleSize = 18;
			explosionRadius = 100;
		} else {
			// Default colors
			particleColors = [0xFFFFFF, 0xCCCCCC, 0x999999, 0x666666];
		}
		// Create particles
		var particles = [];
		// Pre-calculate common values
		var angleStep = Math.PI * 2 / particleCount;
		var colorCount = particleColors.length;
		for (var i = 0; i < particleCount; i++) {
			var size = particleSize + Math.random() * 8;
			var particle = particleContainer.attachAsset('bullet', {
				anchorX: 0.5,
				anchorY: 0.5,
				width: size,
				height: size
			});
			// Set particle color
			particle.tint = particleColors[i % colorCount];
			particle.alpha = 0.8 + Math.random() * 0.2;
			// Calculate random direction
			var angle = angleStep * i + (Math.random() - 0.5) * 0.5;
			var speed = explosionRadius * (0.7 + Math.random() * 0.3);
			// Store particle data
			particles.push({
				sprite: particle,
				targetX: Math.cos(angle) * speed,
				targetY: Math.sin(angle) * speed,
				rotationSpeed: (Math.random() - 0.5) * 0.2
			});
		}
		// Animate unit shrinking and fading
		tween(self, {
			alpha: 0,
			scaleX: self.scaleX * 0.5,
			scaleY: self.scaleY * 0.5
		}, {
			duration: 200,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				// Destroy the unit
				self.destroy();
			}
		});
		// Animate particles bursting outward
		for (var i = 0; i < particles.length; i++) {
			var particleData = particles[i];
			var particle = particleData.sprite;
			// Burst outward animation
			tween(particle, {
				x: particleData.targetX,
				y: particleData.targetY,
				scaleX: 0.1,
				scaleY: 0.1,
				alpha: 0,
				rotation: particle.rotation + particleData.rotationSpeed * 10
			}, {
				duration: 600 + Math.random() * 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Clean up after last particle
					if (i === particles.length - 1) {
						particleContainer.destroy();
					}
				}
			});
		}
		// Add a brief flash effect at the center
		var flash = particleContainer.attachAsset('bullet', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: particleSize * 3,
			height: particleSize * 3
		});
		flash.tint = 0xFFFFFF;
		flash.alpha = 0.8;
		tween(flash, {
			scaleX: 3,
			scaleY: 3,
			alpha: 0
		}, {
			duration: 300,
			easing: tween.easeOut
		});
	};
	self.canShoot = function () {
		// Use speed to modify fire rate - higher speed means faster attacks
		var adjustedFireRate = Math.floor(self.fireRate / self.speed);
		return LK.ticks - self.lastShot >= adjustedFireRate;
	};
	self.shoot = function (target) {
		if (!self.canShoot()) {
			return null;
		}
		self.lastShot = LK.ticks;
		// For melee units (range 1), don't create bullets
		if (self.range <= 1) {
			// Melee attack: do incline movement using tween, then apply damage
			var originalX = self.x;
			var originalY = self.y;
			// Calculate incline offset (move 30% toward target, max 40px)
			var dx = target.x - self.x;
			var dy = target.y - self.y;
			var dist = Math.sqrt(dx * dx + dy * dy);
			var offset = Math.min(40, dist * 0.3);
			var inclineX = self.x + (dist > 0 ? dx / dist * offset : 0);
			var inclineY = self.y + (dist > 0 ? dy / dist * offset : 0);
			// Prevent multiple tweens at once
			if (!self._isMeleeTweening) {
				self._isMeleeTweening = true;
				self.isAttacking = true; // Set attacking flag
				tween(self, {
					x: inclineX,
					y: inclineY
				}, {
					duration: 80,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Apply damage after lunge
						// Play melee attack sound
						LK.getSound('melee_attack').play();
						var killed = target.takeDamage(self.damage);
						if (killed) {
							self.isAttacking = false; // Clear attacking flag if target dies
							// Don't give gold for killing enemies
							// Update enemies defeated count in storage
							storage.enemiesDefeated = (storage.enemiesDefeated || 0) + 1;
							LK.getSound('enemyDeath').play();
							for (var i = enemies.length - 1; i >= 0; i--) {
								if (enemies[i] === target) {
									// Trigger death animation instead of immediate destroy
									enemies[i].deathAnimation();
									enemies.splice(i, 1);
									break;
								}
							}
						}
						// Tween back to original position
						tween(self, {
							x: originalX,
							y: originalY
						}, {
							duration: 100,
							easing: tween.easeIn,
							onFinish: function onFinish() {
								self._isMeleeTweening = false;
								self.isAttacking = false; // Clear attacking flag after animation
							}
						});
					}
				});
			}
			return null; // No bullet for melee
		}
		// Ranged attack - create bullet
		var bullet = new Bullet(self.damage, target);
		bullet.x = self.x;
		bullet.y = self.y;
		// Customize bullet appearance based on unit type
		if (self.name === "Ranger") {
			// Archer units shoot arrows
			bullet.bulletType = 'arrow';
			bullet.createGraphics(); // Recreate graphics with correct type
		} else if (self.name === "Wizard") {
			// Wizard units shoot magic
			bullet.bulletType = 'magic';
			bullet.createGraphics(); // Recreate graphics with correct type
		}
		return bullet;
	};
	self.findTarget = function () {
		var closestEnemy = null;
		var closestCellDistance = self.range + 1; // Only enemies within range (cell count) are valid
		var targetsInRange = [];
		for (var i = 0; i < enemies.length; i++) {
			var enemy = enemies[i];
			// Calculate cell-based Manhattan distance
			var cellDist = -1;
			if (typeof self.gridX === "number" && typeof self.gridY === "number" && typeof enemy.gridX === "number" && typeof enemy.gridY === "number") {
				cellDist = Math.abs(self.gridX - enemy.gridX) + Math.abs(self.gridY - enemy.gridY);
			}
			if (cellDist >= 0 && cellDist <= self.range) {
				var healthRatio = enemy.health / enemy.maxHealth;
				var priority = 5; // Default priority
				// Smart target prioritization
				if (healthRatio <= 0.2) {
					priority = 1; // Highest priority - almost dead
				} else if (enemy.name === "Boss Monster") {
					priority = 2; // High priority - dangerous
				} else if (enemy.name === "Ranged Enemy") {
					priority = 3; // Medium-high priority
				} else if (healthRatio <= 0.5) {
					priority = 4; // Medium priority - damaged
				}
				targetsInRange.push({
					enemy: enemy,
					distance: cellDist,
					priority: priority,
					healthRatio: healthRatio,
					threat: enemy.damage // Consider enemy threat level
				});
			}
		}
		// Sort targets by priority, then by health ratio, then by threat level
		targetsInRange.sort(function (a, b) {
			if (a.priority !== b.priority) {
				return a.priority - b.priority;
			}
			if (Math.abs(a.healthRatio - b.healthRatio) > 0.1) {
				return a.healthRatio - b.healthRatio; // Lower health first
			}
			if (a.threat !== b.threat) {
				return b.threat - a.threat; // Higher threat first
			}
			return a.distance - b.distance;
		});
		// Select best target
		if (targetsInRange.length > 0) {
			closestEnemy = targetsInRange[0].enemy;
		}
		return closestEnemy;
	};
	self.update = function () {
		// Only initialize and update GridMovement if unit is placed on grid and during battle phase
		if (self.gridX >= 0 && self.gridY >= 0 && gameState === 'battle') {
			if (!self.gridMovement) {
				self.gridMovement = new GridMovement(self, grid);
			}
			self.gridMovement.update();
		}
		// Add idle animation when not attacking
		if (!self.isAttacking && self.gridX >= 0 && self.gridY >= 0) {
			// Only start idle animation if not already animating
			if (!self._isIdleAnimating) {
				self._isIdleAnimating = true;
				// Random delay before starting idle animation
				var delay = Math.random() * 2000;
				LK.setTimeout(function () {
					if (!self.isAttacking && self._isIdleAnimating) {
						// Calculate target scale based on tier
						var targetScale = self.baseScale;
						if (self.tier === 2) {
							targetScale = self.baseScale * 1.2;
						} else if (self.tier === 3) {
							targetScale = self.baseScale * 1.3;
						}
						// Gentle bobbing animation that respects tier scale
						tween(self, {
							scaleX: targetScale * 1.05,
							scaleY: targetScale * 0.95
						}, {
							duration: 800,
							easing: tween.easeInOut,
							onFinish: function onFinish() {
								tween(self, {
									scaleX: targetScale,
									scaleY: targetScale
								}, {
									duration: 800,
									easing: tween.easeInOut,
									onFinish: function onFinish() {
										self._isIdleAnimating = false;
									}
								});
							}
						});
					}
				}, delay);
			}
		}
	};
	return self;
});
var Wizard = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (blue mage robe)
	var body = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 65;
	body.height = 85;
	body.y = 10;
	body.tint = 0x191970; // Midnight blue to match mage robe theme
	// Head with wizard hat
	var head = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 30
	});
	head.y = -35;
	head.tint = 0xFFDBB5; // Skin color
	// Wizard hat (triangle)
	var hat = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 35
	});
	hat.y = -55;
	hat.tint = 0x000066;
	// Staff (right side)
	var staff = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 80
	});
	staff.x = 35;
	staff.y = -10;
	staff.tint = 0x8B4513;
	// Staff crystal
	var staffCrystal = characterContainer.attachAsset('wizard', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 20
	});
	staffCrystal.x = 35;
	staffCrystal.y = -50;
	staffCrystal.tint = 0x00FFFF; // Cyan crystal
	// Initial attributes for the unit
	self.health = 150;
	self.maxHealth = 150;
	self.damage = 15;
	self.armor = 8;
	self.criticalChance = 0.18;
	self.magicResist = 8;
	self.mana = 70;
	self.speed = 0.7;
	self.range = 3; // Example: medium range (3 cells)
	self.name = "Wizard";
	return self;
});
var Wall = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart wall structure
	var wallContainer = new Container();
	self.addChild(wallContainer);
	// Wall base (stone blocks)
	var wallBase = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	wallBase.width = 90;
	wallBase.height = 80;
	wallBase.y = 10;
	wallBase.tint = 0x808080; // Grey stone
	// Wall top section
	var wallTop = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 100,
		height: 30
	});
	wallTop.y = -35;
	wallTop.tint = 0x696969; // Darker grey
	// Stone texture details (left)
	var stoneLeft = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 25,
		height: 20
	});
	stoneLeft.x = -25;
	stoneLeft.y = 0;
	stoneLeft.tint = 0x606060;
	// Stone texture details (right)
	var stoneRight = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 25,
		height: 20
	});
	stoneRight.x = 25;
	stoneRight.y = 0;
	stoneRight.tint = 0x606060;
	// Stone texture details (center)
	var stoneCenter = wallContainer.attachAsset('wall', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 15
	});
	stoneCenter.x = 0;
	stoneCenter.y = 20;
	stoneCenter.tint = 0x505050;
	// Initial attributes for the wall
	self.health = 300;
	self.maxHealth = 300;
	self.damage = 0; // Walls don't attack
	self.armor = 20; // High defense
	self.criticalChance = 0; // No critical chance
	self.magicResist = 15;
	self.mana = 0; // No mana
	self.speed = 0; // Doesn't attack
	self.range = 0; // No range
	self.name = "Wall";
	self.isStructure = true; // Mark as structure
	// Override update to prevent movement
	self.update = function () {
		// Walls don't move or attack, just exist as obstacles
		// Still need to show health bar during battle
		if (gameState === 'battle' && self.gridX >= 0 && self.gridY >= 0) {
			self.showHealthBar();
			self.updateHealthBar();
			self.showStarIndicator();
		}
	};
	// Override shoot to prevent attacking
	self.shoot = function (target) {
		return null; // Walls can't shoot
	};
	// Override findTarget since walls don't attack
	self.findTarget = function () {
		return null;
	};
	return self;
});
var Soldier = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (green base)
	var body = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 60,
		height: 80
	});
	body.y = 10;
	body.tint = 0x32CD32; // Lime green to match theme
	// Head (lighter green circle)
	var head = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 40
	});
	head.y = -30;
	head.tint = 0x66ff66;
	// Arms (small rectangles)
	var leftArm = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 40
	});
	leftArm.x = -30;
	leftArm.y = 0;
	leftArm.rotation = 0.3;
	var rightArm = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 40
	});
	rightArm.x = 30;
	rightArm.y = 0;
	rightArm.rotation = -0.3;
	// Sword (held in right hand)
	var sword = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 50
	});
	sword.x = 35;
	sword.y = -10;
	sword.rotation = -0.2;
	sword.tint = 0xC0C0C0; // Silver color
	// Sword hilt
	var swordHilt = characterContainer.attachAsset('soldier', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 8
	});
	swordHilt.x = 35;
	swordHilt.y = 15;
	swordHilt.rotation = -0.2;
	swordHilt.tint = 0x8B4513; // Brown hilt
	// Initial attributes for the unit
	self.health = 120;
	self.maxHealth = 120;
	self.damage = 12;
	self.armor = 6;
	self.criticalChance = 0.15;
	self.magicResist = 6;
	self.mana = 60;
	self.speed = 0.7;
	self.range = 1; // Melee (adjacent cell)
	self.name = "Soldier";
	return self;
});
var Ranger = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (light blue ranger outfit)
	var body = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 60;
	body.height = 80;
	body.y = 10;
	body.tint = 0x87CEEB; // Sky blue to match ranger theme
	// Head with hood
	var head = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 30
	});
	head.y = -35;
	head.tint = 0xFFDBB5; // Skin color
	// Hood
	var hood = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 50,
		height: 40
	});
	hood.y = -40;
	hood.tint = 0x9d9dff;
	// Bow (left side)
	var bow = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 50,
		height: 15
	});
	bow.x = -30;
	bow.y = 0;
	bow.rotation = 1.57; // 90 degrees
	bow.tint = 0x8B4513;
	// Bowstring
	var bowstring = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 2,
		height: 45
	});
	bowstring.x = -30;
	bowstring.y = 0;
	bowstring.rotation = 1.57;
	bowstring.tint = 0xFFFFFF; // White string
	// Arrow on right hand
	var arrow = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 4,
		height: 35
	});
	arrow.x = 25;
	arrow.y = -5;
	arrow.rotation = -0.1;
	arrow.tint = 0x654321; // Dark brown arrow
	// Arrow tip
	var arrowTip = characterContainer.attachAsset('ranger', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 8
	});
	arrowTip.x = 25;
	arrowTip.y = -22;
	arrowTip.rotation = 0.785; // 45 degrees
	arrowTip.tint = 0x808080; // Grey tip
	// Initial attributes for the unit
	self.health = 170;
	self.maxHealth = 170;
	self.damage = 17;
	self.armor = 10;
	self.criticalChance = 0.22;
	self.magicResist = 10;
	self.mana = 80;
	self.speed = 0.7;
	self.range = 2; // Example: short range (2 cells)
	self.name = "Ranger";
	return self;
});
var Paladin = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (blue armor)
	var body = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 75;
	body.height = 75;
	body.y = 10;
	body.tint = 0x4169E1; // Royal blue to match armor theme
	// Head
	var head = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 35,
		height: 35
	});
	head.y = -35;
	head.tint = 0xFFDBB5; // Skin color
	// Helmet
	var helmet = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 45,
		height: 25
	});
	helmet.y = -45;
	helmet.tint = 0x4444FF;
	// Sword (right side)
	var sword = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 60
	});
	sword.x = 35;
	sword.y = -5;
	sword.rotation = -0.2;
	sword.tint = 0xC0C0C0;
	// Sword pommel
	var swordPommel = characterContainer.attachAsset('paladin', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 12
	});
	swordPommel.x = 35;
	swordPommel.y = 20;
	swordPommel.tint = 0xFFD700; // Gold pommel
	// Initial attributes for the unit
	self.health = 160;
	self.maxHealth = 160;
	self.damage = 16;
	self.armor = 9;
	self.criticalChance = 0.2;
	self.magicResist = 9;
	self.mana = 75;
	self.speed = 0.7;
	self.range = 1; // Example: short range (2 cells)
	self.name = "Paladin";
	return self;
});
var Knight = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart character container
	var characterContainer = new Container();
	self.addChild(characterContainer);
	// Body (darker green base)
	var body = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 70,
		height: 70
	});
	body.y = 10;
	body.tint = 0x228B22; // Forest green to match theme
	// Head (round shape)
	var head = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 35,
		height: 35
	});
	head.y = -35;
	head.tint = 0x4da24d;
	// Shield (left side)
	var shield = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 45
	});
	shield.x = -35;
	shield.y = 0;
	shield.tint = 0x666666;
	// Sword (right side)
	var sword = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 45
	});
	sword.x = 30;
	sword.y = -5;
	sword.rotation = -0.15;
	sword.tint = 0xC0C0C0; // Silver color
	// Sword guard
	var swordGuard = characterContainer.attachAsset('knight', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 18,
		height: 6
	});
	swordGuard.x = 30;
	swordGuard.y = 13;
	swordGuard.rotation = -0.15;
	swordGuard.tint = 0x808080; // Dark grey
	// Initial attributes for the unit
	self.health = 110;
	self.maxHealth = 110;
	self.damage = 11;
	self.armor = 5;
	self.criticalChance = 0.12;
	self.magicResist = 5;
	self.mana = 55;
	self.speed = 0.7;
	self.range = 1; // Melee (adjacent cell)
	self.name = "Knight";
	return self;
});
var King = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart king character
	var kingContainer = new Container();
	self.addChild(kingContainer);
	// King body (royal robe)
	var body = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	body.width = 80;
	body.height = 100;
	body.y = 15;
	body.tint = 0x4B0082; // Royal purple
	// King head (flesh tone)
	var head = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 50,
		height: 50
	});
	head.x = 0;
	head.y = -40;
	head.tint = 0xFFDBB5; // Skin color
	// Crown base
	var crownBase = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 60,
		height: 20
	});
	crownBase.x = 0;
	crownBase.y = -65;
	crownBase.tint = 0xFFFF00; // Yellow
	// Crown points (left)
	var crownLeft = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 25
	});
	crownLeft.x = -20;
	crownLeft.y = -75;
	crownLeft.tint = 0xFFFF00; // Yellow
	// Crown points (center - tallest)
	var crownCenter = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 35
	});
	crownCenter.x = 0;
	crownCenter.y = -80;
	crownCenter.tint = 0xFFFF00; // Yellow
	// Crown points (right)
	var crownRight = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 12,
		height: 25
	});
	crownRight.x = 20;
	crownRight.y = -75;
	crownRight.tint = 0xFFFF00; // Yellow
	// Crown jewel (center)
	var crownJewel = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 8
	});
	crownJewel.x = 0;
	crownJewel.y = -80;
	crownJewel.tint = 0xFF0000; // Red jewel
	// Beard
	var beard = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 30,
		height: 20
	});
	beard.x = 0;
	beard.y = -25;
	beard.tint = 0xC0C0C0; // Grey beard
	// Sword (right hand)
	var sword = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 15,
		height: 80
	});
	sword.x = 45;
	sword.y = 0;
	sword.rotation = -0.2;
	sword.tint = 0xC0C0C0; // Silver blade
	// Sword hilt
	var swordHilt = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 25,
		height: 12
	});
	swordHilt.x = 45;
	swordHilt.y = 35;
	swordHilt.rotation = -0.2;
	swordHilt.tint = 0xC0C0C0; // Silver hilt
	// Royal cape/cloak
	var cape = kingContainer.attachAsset('king', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 70,
		height: 80
	});
	cape.x = -5;
	cape.y = 20;
	cape.tint = 0x8B0000; // Dark red cape
	// Initial attributes for the king (like a very strong unit)
	self.health = 500;
	self.maxHealth = 500;
	self.damage = 100;
	self.armor = 10;
	self.criticalChance = 0.05;
	self.magicResist = 8;
	self.mana = 100;
	self.speed = 0.5; // Slower attack speed
	self.range = 1; // Melee range
	self.name = "King";
	self.fireRate = 120; // Slower fire rate
	// Override takeDamage to handle king-specific game over
	self.takeDamage = function (damage) {
		self.health -= damage;
		if (self.health < 0) {
			self.health = 0;
		}
		self.updateHealthBar();
		if (self.health <= 0) {
			LK.effects.flashScreen(0xFF0000, 500);
			LK.showGameOver();
			return true;
		}
		return false;
	};
	// Override update - King can move if it's the only unit left
	self.update = function () {
		// Check if king is the only player unit left on the battlefield
		var playerUnitsOnGrid = 0;
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				if (grid[y] && grid[y][x] && grid[y][x].unit) {
					playerUnitsOnGrid++;
				}
			}
		}
		// If king is the only unit left, allow movement
		if (playerUnitsOnGrid === 1) {
			// Only initialize and update GridMovement if unit is placed on grid
			if (self.gridX >= 0 && self.gridY >= 0) {
				if (!self.gridMovement) {
					self.gridMovement = new GridMovement(self, grid);
				}
				self.gridMovement.update();
			}
		}
		// King stays in place if other units exist
	};
	// Override showStarIndicator to prevent King from showing stars
	self.showStarIndicator = function () {
		// King doesn't show star indicators
	};
	// Override showHealthBar for king-specific styling
	self.showHealthBar = function () {
		if (!self.healthBar) {
			self.healthBar = new HealthBar(150, 10); // Larger health bar for king
			self.healthBar.x = -75; // Position relative to the king's center
			self.healthBar.y = -110; // Position above the king (higher due to crown)
			self.addChild(self.healthBar);
		}
		self.healthBar.visible = true;
		self.healthBar.updateHealth(self.health, self.maxHealth);
	};
	// Override hideStarIndicator to handle the case where it might be called
	self.hideStarIndicator = function () {
		// King doesn't have star indicators, so nothing to hide
	};
	// Override updateUnitScale to prevent tier-based scaling for King
	self.updateUnitScale = function () {
		// King doesn't scale based on tier, only through levelUpKing function
	};
	return self;
});
var CrossbowTower = Unit.expand(function () {
	var self = Unit.call(this, 1);
	// Remove default unit graphics
	self.removeChildren();
	// Create pixelart crossbow tower structure
	var towerContainer = new Container();
	self.addChild(towerContainer);
	// Tower base (stone foundation)
	var towerBase = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	towerBase.width = 80;
	towerBase.height = 60;
	towerBase.y = 30;
	towerBase.tint = 0x696969; // Dark grey stone
	// Tower middle section
	var towerMiddle = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 70,
		height: 50
	});
	towerMiddle.y = -10;
	towerMiddle.tint = 0x808080; // Grey stone
	// Tower top platform
	var towerTop = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 90,
		height: 20
	});
	towerTop.y = -40;
	towerTop.tint = 0x5C4033; // Brown wood platform
	// Crossbow mechanism (horizontal)
	var crossbowBase = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 60,
		height: 15
	});
	crossbowBase.y = -55;
	crossbowBase.rotation = 0;
	crossbowBase.tint = 0x8B4513; // Saddle brown
	// Crossbow arms (vertical)
	var crossbowArms = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 8,
		height: 50
	});
	crossbowArms.y = -55;
	crossbowArms.rotation = 1.57; // 90 degrees
	crossbowArms.tint = 0x654321; // Dark brown
	// Crossbow string
	var crossbowString = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 2,
		height: 48
	});
	crossbowString.y = -55;
	crossbowString.rotation = 1.57;
	crossbowString.tint = 0xDDDDDD; // Light grey string
	// Loaded bolt
	var loadedBolt = towerContainer.attachAsset('crossbow_tower', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 4,
		height: 30
	});
	loadedBolt.x = 0;
	loadedBolt.y = -55;
	loadedBolt.rotation = 0;
	loadedBolt.tint = 0x4B0082; // Dark purple bolt
	// Initial attributes for the crossbow tower
	self.health = 200;
	self.maxHealth = 200;
	self.damage = 25; // Higher damage than regular ranged units
	self.armor = 12;
	self.criticalChance = 0.25; // High critical chance
	self.magicResist = 10;
	self.mana = 0; // No mana
	self.speed = 0.8; // Slower attack speed
	self.range = 4; // Long range
	self.name = "Crossbow Tower";
	self.isStructure = true; // Mark as structure
	self.fireRate = 90; // Slower fire rate than mobile units
	// Override update to prevent movement but allow shooting
	self.update = function () {
		// Towers don't move but can attack
		if (gameState === 'battle' && self.gridX >= 0 && self.gridY >= 0) {
			self.showHealthBar();
			self.updateHealthBar();
			self.showStarIndicator();
		}
	};
	// Override shoot to create arrow projectiles
	self.shoot = function (target) {
		if (!self.canShoot()) {
			return null;
		}
		self.lastShot = LK.ticks;
		// Create arrow projectile
		var bullet = new Bullet(self.damage, target);
		bullet.x = self.x;
		bullet.y = self.y - 55; // Shoot from crossbow position
		// Crossbow towers shoot arrows
		bullet.bulletType = 'arrow';
		bullet.createGraphics();
		// Add shooting animation - rotate crossbow slightly
		tween(crossbowBase, {
			rotation: -0.1
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(crossbowBase, {
					rotation: 0
				}, {
					duration: 200,
					easing: tween.easeIn
				});
			}
		});
		return bullet;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x2F4F2F
});
/**** 
* Game Code
****/ 
// Create game title overlay that appears on top of everything
var titleOverlay = new Container();
// Create gradient-like background effect with multiple layers
var titleOverlayBg = titleOverlay.attachAsset('shop_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 2048,
	height: 2732
});
titleOverlayBg.alpha = 0.95;
titleOverlayBg.tint = 0x0a0a1a; // Deep dark blue instead of pure black
titleOverlayBg.x = 0; // Center relative to parent
titleOverlayBg.y = 0; // Center relative to parent
// Add subtle vignette effect
var vignette = titleOverlay.attachAsset('shop_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 2200,
	height: 2900
});
vignette.alpha = 0.3;
vignette.tint = 0x000000;
vignette.x = 0;
vignette.y = 0;
// Create magical particle system for background
var particleContainer = new Container();
titleOverlay.addChild(particleContainer);
// Create floating magical particles
function createMagicalParticle() {
	var particle = particleContainer.attachAsset('star_dot', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 6 + Math.random() * 8,
		height: 6 + Math.random() * 8
	});
	// Random colors for magical effect
	var colors = [0xFFD700, 0x4169E1, 0xFF69B4, 0x00CED1, 0xFFA500];
	particle.tint = colors[Math.floor(Math.random() * colors.length)];
	particle.alpha = 0;
	// Random starting position
	particle.x = (Math.random() - 0.5) * 2048;
	particle.y = 1366 + Math.random() * 800;
	// Animate particle floating up with glow
	tween(particle, {
		y: particle.y - 2000,
		alpha: 0.8
	}, {
		duration: 2000,
		easing: tween.easeIn,
		onFinish: function onFinish() {
			tween(particle, {
				alpha: 0
			}, {
				duration: 1000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					particle.destroy();
				}
			});
		}
	});
	// Add gentle horizontal sway
	tween(particle, {
		x: particle.x + (Math.random() - 0.5) * 200
	}, {
		duration: 4000,
		easing: tween.easeInOut
	});
}
// Create particles periodically
var particleTimer = LK.setInterval(function () {
	if (titleOverlay.parent) {
		createMagicalParticle();
	} else {
		LK.clearInterval(particleTimer);
	}
}, 200);
// Create title container for effects
var titleContainer = new Container();
titleOverlay.addChild(titleContainer);
titleContainer.y = -566;
// Add golden glow behind title
var titleGlow = titleContainer.attachAsset('shop_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 800,
	height: 200
});
titleGlow.alpha = 0.3;
titleGlow.tint = 0xFFD700;
// Animate glow pulse
tween(titleGlow, {
	scaleX: 1.2,
	scaleY: 1.2,
	alpha: 0.5
}, {
	duration: 2000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(titleGlow, {
			scaleX: 1.0,
			scaleY: 1.0,
			alpha: 0.3
		}, {
			duration: 2000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Game title with shadow effect
var gameTitleShadow = new Text2('Protect Your King!', {
	size: 120,
	fill: 0x000000
});
gameTitleShadow.anchor.set(0.5, 0.5);
gameTitleShadow.x = 4;
gameTitleShadow.y = 4;
gameTitleShadow.alpha = 0.5;
titleContainer.addChild(gameTitleShadow);
// Add subtle animation to shadow
tween(gameTitleShadow, {
	x: 6,
	y: 6,
	alpha: 0.3
}, {
	duration: 3000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(gameTitleShadow, {
			x: 2,
			y: 2,
			alpha: 0.6
		}, {
			duration: 3000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Main game title
var gameTitle = new Text2('Protect Your King!', {
	size: 120,
	fill: 0xFFD700
});
gameTitle.anchor.set(0.5, 0.5);
gameTitle.x = 0;
gameTitle.y = 0;
titleContainer.addChild(gameTitle);
// Add sparkle effects around title
function createTitleSparkle() {
	var sparkle = titleContainer.attachAsset('star_dot', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 10
	});
	sparkle.tint = 0xFFFFFF;
	sparkle.alpha = 0;
	sparkle.x = (Math.random() - 0.5) * 600;
	sparkle.y = (Math.random() - 0.5) * 150;
	tween(sparkle, {
		alpha: 1,
		scaleX: 1.5,
		scaleY: 1.5
	}, {
		duration: 500,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(sparkle, {
				alpha: 0,
				scaleX: 0.5,
				scaleY: 0.5
			}, {
				duration: 500,
				easing: tween.easeIn,
				onFinish: function onFinish() {
					sparkle.destroy();
				}
			});
		}
	});
}
// Create sparkles periodically
var sparkleTimer = LK.setInterval(function () {
	if (titleOverlay.parent) {
		createTitleSparkle();
	} else {
		LK.clearInterval(sparkleTimer);
	}
}, 300);
// Subtitle with shadow
var subtitleShadow = new Text2('Tower Defense', {
	size: 60,
	fill: 0x000000
});
subtitleShadow.anchor.set(0.5, 0.5);
subtitleShadow.x = 2;
subtitleShadow.y = -464;
subtitleShadow.alpha = 0.5;
titleOverlay.addChild(subtitleShadow);
// Subtitle
var gameSubtitle = new Text2('Tower Defense', {
	size: 60,
	fill: 0x87CEEB
});
gameSubtitle.anchor.set(0.5, 0.5);
gameSubtitle.x = 0; // Center relative to overlay
gameSubtitle.y = -466; // Adjusted position relative to center
titleOverlay.addChild(gameSubtitle);
// Add continuous floating animation to subtitle
function startSubtitleAnimation() {
	tween(gameSubtitle, {
		scaleX: 1.05,
		scaleY: 1.05,
		y: -456,
		alpha: 0.9
	}, {
		duration: 2500,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(gameSubtitle, {
				scaleX: 0.95,
				scaleY: 0.95,
				y: -476,
				alpha: 1.0
			}, {
				duration: 2500,
				easing: tween.easeInOut,
				onFinish: startSubtitleAnimation
			});
		}
	});
}
startSubtitleAnimation();
// Add decorative statistics container
var statsContainer = new Container();
titleOverlay.addChild(statsContainer);
statsContainer.y = 450;
// Best wave text
var bestWaveText = new Text2('Best Wave: ' + (storage.bestWave || 0), {
	size: 36,
	fill: 0xFFD700
});
bestWaveText.anchor.set(0.5, 0.5);
bestWaveText.x = -300;
statsContainer.addChild(bestWaveText);
// Units defeated text
var unitsDefeatedText = new Text2('Enemies Defeated: ' + (storage.enemiesDefeated || 0), {
	size: 36,
	fill: 0xFF6666
});
unitsDefeatedText.anchor.set(0.5, 0.5);
unitsDefeatedText.x = 300;
statsContainer.addChild(unitsDefeatedText);
// Add subtle animation to stats
tween(statsContainer, {
	alpha: 0.8
}, {
	duration: 2000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(statsContainer, {
			alpha: 1.0
		}, {
			duration: 2000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Start Game button container
var startGameButton = new Container();
// Button shadow
var startButtonShadow = startGameButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 100
});
startButtonShadow.tint = 0x000000;
startButtonShadow.alpha = 0.3;
startButtonShadow.x = 4;
startButtonShadow.y = 4;
// Button gradient effect background
var startButtonGlow = startGameButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 420,
	height: 120
});
startButtonGlow.tint = 0x66FF66;
startButtonGlow.alpha = 0;
// Main button background
var startGameButtonBg = startGameButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 100
});
startGameButtonBg.tint = 0x4169E1; // Royal blue to match theme better
// Button text with shadow
var startButtonTextShadow = new Text2('Start Game', {
	size: 60,
	fill: 0x000000
});
startButtonTextShadow.anchor.set(0.5, 0.5);
startButtonTextShadow.x = 2;
startButtonTextShadow.y = 2;
startButtonTextShadow.alpha = 0.5;
startGameButton.addChild(startButtonTextShadow);
var startGameButtonText = new Text2('Start Game', {
	size: 60,
	fill: 0xFFFFFF
});
startGameButtonText.anchor.set(0.5, 0.5);
startGameButton.addChild(startGameButtonText);
startGameButton.x = 0; // Center relative to overlay
startGameButton.y = -66; // Move lower, more centered
titleOverlay.addChild(startGameButton);
// Add floating animation to start button
tween(startGameButton, {
	y: -56,
	scaleX: 1.05,
	scaleY: 1.05
}, {
	duration: 2000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(startGameButton, {
			y: -66,
			scaleX: 1.0,
			scaleY: 1.0
		}, {
			duration: 2000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Add continuous pulsing glow effect to start button
function pulseStartButton() {
	tween(startButtonGlow, {
		alpha: 0.3,
		scaleX: 1.1,
		scaleY: 1.1
	}, {
		duration: 1000,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(startButtonGlow, {
				alpha: 0,
				scaleX: 1.0,
				scaleY: 1.0
			}, {
				duration: 1000,
				easing: tween.easeIn,
				onFinish: pulseStartButton
			});
		}
	});
}
pulseStartButton();
// Add hover animation
startGameButton.down = function () {
	tween(startGameButtonBg, {
		scaleX: 0.95,
		scaleY: 0.95
	}, {
		duration: 100,
		easing: tween.easeOut
	});
	tween(startButtonGlow, {
		alpha: 0.7,
		scaleX: 1.2,
		scaleY: 1.2
	}, {
		duration: 200,
		easing: tween.easeOut
	});
};
// How to Play button container
var howToPlayButton = new Container();
// Button shadow
var howToPlayShadow = howToPlayButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 100
});
howToPlayShadow.tint = 0x000000;
howToPlayShadow.alpha = 0.3;
howToPlayShadow.x = 4;
howToPlayShadow.y = 4;
// Button glow effect
var howToPlayGlow = howToPlayButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 420,
	height: 120
});
howToPlayGlow.tint = 0x6666FF;
howToPlayGlow.alpha = 0;
// Main button background
var howToPlayButtonBg = howToPlayButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 100
});
howToPlayButtonBg.tint = 0x8A2BE2; // Blue violet for distinction
// Button text with shadow
var howToPlayTextShadow = new Text2('How to Play', {
	size: 60,
	fill: 0x000000
});
howToPlayTextShadow.anchor.set(0.5, 0.5);
howToPlayTextShadow.x = 2;
howToPlayTextShadow.y = 2;
howToPlayTextShadow.alpha = 0.5;
howToPlayButton.addChild(howToPlayTextShadow);
var howToPlayButtonText = new Text2('How to Play', {
	size: 60,
	fill: 0xFFFFFF
});
howToPlayButtonText.anchor.set(0.5, 0.5);
howToPlayButton.addChild(howToPlayButtonText);
howToPlayButton.x = 0; // Center relative to overlay
howToPlayButton.y = 84; // Move lower, more centered
titleOverlay.addChild(howToPlayButton);
// Add floating animation to how to play button with slight offset
tween(howToPlayButton, {
	y: 94,
	scaleX: 1.05,
	scaleY: 1.05
}, {
	duration: 2300,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(howToPlayButton, {
			y: 84,
			scaleX: 1.0,
			scaleY: 1.0
		}, {
			duration: 2300,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Create settings button
var settingsButton = new Container();
var settingsShadow = settingsButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 100,
	height: 100
});
settingsShadow.tint = 0x000000;
settingsShadow.alpha = 0.3;
settingsShadow.x = 4;
settingsShadow.y = 4;
var settingsGlow = settingsButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 120,
	height: 120
});
settingsGlow.tint = 0x6666FF;
settingsGlow.alpha = 0;
var settingsButtonBg = settingsButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 100,
	height: 100
});
settingsButtonBg.tint = 0x4B0082;
// Create gear icon using shapes
var gearIcon = new Container();
settingsButton.addChild(gearIcon);
// Gear center
var gearCenter = gearIcon.attachAsset('bullet', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 30,
	height: 30
});
gearCenter.tint = 0xFFFFFF;
// Gear teeth
for (var i = 0; i < 8; i++) {
	var tooth = gearIcon.attachAsset('shop_button', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 10,
		height: 20
	});
	var angle = i * Math.PI / 4;
	tooth.x = Math.cos(angle) * 20;
	tooth.y = Math.sin(angle) * 20;
	tooth.rotation = angle;
	tooth.tint = 0xFFFFFF;
}
settingsButton.x = -800;
settingsButton.y = -1100;
titleOverlay.addChild(settingsButton);
// Animate gear rotation
tween(gearIcon, {
	rotation: Math.PI * 2
}, {
	duration: 10000,
	easing: tween.linear,
	onFinish: function onFinish() {
		gearIcon.rotation = 0;
		tween(gearIcon, {
			rotation: Math.PI * 2
		}, {
			duration: 10000,
			easing: tween.linear,
			onFinish: onFinish
		});
	}
});
settingsButton.down = function () {
	tween(settingsButtonBg, {
		scaleX: 0.9,
		scaleY: 0.9
	}, {
		duration: 100,
		easing: tween.easeOut
	});
};
settingsButton.up = function () {
	tween(settingsButtonBg, {
		scaleX: 1.0,
		scaleY: 1.0
	}, {
		duration: 100,
		easing: tween.easeIn
	});
	LK.getSound('purchase').play();
};
// Add hover animation
howToPlayButton.down = function () {
	tween(howToPlayButtonBg, {
		scaleX: 0.95,
		scaleY: 0.95
	}, {
		duration: 100,
		easing: tween.easeOut
	});
	tween(howToPlayGlow, {
		alpha: 0.7,
		scaleX: 1.2,
		scaleY: 1.2
	}, {
		duration: 200,
		easing: tween.easeOut
	});
};
// Add version and credits text
var versionText = new Text2('v1.0', {
	size: 24,
	fill: 0x666666
});
versionText.anchor.set(1, 1);
versionText.x = 900;
versionText.y = 1300;
titleOverlay.addChild(versionText);
// Add credits text
var creditsText = new Text2('Made with FRVR', {
	size: 24,
	fill: 0x666666
});
creditsText.anchor.set(0, 1);
creditsText.x = -900;
creditsText.y = 1300;
titleOverlay.addChild(creditsText);
// How to Play button click handler
howToPlayButton.up = function () {
	// Reset button scale
	tween(howToPlayButtonBg, {
		scaleX: 1.0,
		scaleY: 1.0
	}, {
		duration: 100,
		easing: tween.easeIn
	});
	tween(howToPlayGlow, {
		alpha: 0
	}, {
		duration: 200,
		easing: tween.easeIn
	});
	// Play sound effect
	LK.getSound('purchase').play();
	// Create how to play modal
	var howToPlayModal = new Container();
	var howToPlayModalBg = howToPlayModal.attachAsset('shop_area_bg', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 1600,
		height: 2000
	});
	howToPlayModalBg.alpha = 0.95;
	howToPlayModalBg.tint = 0x1a1a2e; // Dark blue theme
	howToPlayModalBg.x = 0;
	howToPlayModalBg.y = 0;
	// Modal title with fun subtitle
	var modalTitle = new Text2('How to Play', {
		size: 80,
		fill: 0xFFD700
	});
	modalTitle.anchor.set(0.5, 0.5);
	modalTitle.x = 0; // Center relative to modal
	modalTitle.y = -900; // Adjusted position relative to center
	howToPlayModal.addChild(modalTitle);
	// Fun subtitle
	var subtitle = new Text2('Master the Art of Tower Defense!', {
		size: 40,
		fill: 0x87CEEB // Sky blue for planning
	});
	subtitle.anchor.set(0.5, 0.5);
	subtitle.x = 0;
	subtitle.y = -820;
	howToPlayModal.addChild(subtitle);
	// Game mechanics section
	var mechanicsTitle = new Text2('— Game Basics —', {
		size: 48,
		fill: 0xFFD700
	});
	mechanicsTitle.anchor.set(0.5, 0.5);
	mechanicsTitle.x = 0;
	mechanicsTitle.y = -700;
	howToPlayModal.addChild(mechanicsTitle);
	// Instructions with better spacing
	var basicInstructions = ['💰 Purchase units from the shop using gold', '🎯 Drag units to the battlefield grid', '⚔️ Units auto-battle enemies in range', '⭐ Merge 3 identical units for upgrades', '👑 Level up your King for more capacity', '🛡️ Protect your King at all costs!', '🌊 Survive 10 waves to claim victory!'];
	for (var i = 0; i < basicInstructions.length; i++) {
		var instructionText = new Text2(basicInstructions[i], {
			size: 36,
			fill: 0xFFFFFF
		});
		instructionText.anchor.set(0.5, 0.5);
		instructionText.x = 0; // Horizontally centered
		instructionText.y = -550 + i * 60; // Better spacing
		howToPlayModal.addChild(instructionText);
	}
	// Unit showcase title
	var unitsTitle = new Text2('— Meet Your Units —', {
		size: 48,
		fill: 0xFFD700
	});
	unitsTitle.anchor.set(0.5, 0.5);
	unitsTitle.x = 0;
	unitsTitle.y = -50;
	howToPlayModal.addChild(unitsTitle);
	// Create unit showcase with actual unit graphics
	var unitShowcase = [{
		unit: new Soldier(),
		desc: 'Soldier: Swift melee warrior',
		x: -600,
		y: 100
	}, {
		unit: new Knight(),
		desc: 'Knight: Tanky defender',
		x: -200,
		y: 100
	}, {
		unit: new Wizard(),
		desc: 'Wizard: Magic damage dealer',
		x: 200,
		y: 100
	}, {
		unit: new Ranger(),
		desc: 'Ranger: Long-range archer',
		x: 600,
		y: 100
	}, {
		unit: new Paladin(),
		desc: 'Paladin: Elite warrior',
		x: -400,
		y: 350
	}, {
		unit: new Wall(),
		desc: 'Wall: Defensive structure',
		x: 0,
		y: 350
	}, {
		unit: new CrossbowTower(),
		desc: 'Tower: Area controller',
		x: 400,
		y: 350
	}];
	// Add units with animations
	for (var i = 0; i < unitShowcase.length; i++) {
		var showcase = unitShowcase[i];
		var unitDisplay = showcase.unit;
		unitDisplay.x = showcase.x;
		unitDisplay.y = showcase.y;
		unitDisplay.scaleX = 0.8;
		unitDisplay.scaleY = 0.8;
		howToPlayModal.addChild(unitDisplay);
		// Add floating animation
		var baseY = unitDisplay.y;
		tween(unitDisplay, {
			y: baseY - 15,
			scaleX: 0.85,
			scaleY: 0.85
		}, {
			duration: 1500 + Math.random() * 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(unitDisplay, {
					y: baseY,
					scaleX: 0.8,
					scaleY: 0.8
				}, {
					duration: 1500 + Math.random() * 500,
					easing: tween.easeInOut,
					onFinish: onFinish
				});
			}
		});
		// Add unit description
		var unitDesc = new Text2(showcase.desc, {
			size: 28,
			fill: 0xFFFFFF
		});
		unitDesc.anchor.set(0.5, 0);
		unitDesc.x = showcase.x;
		unitDesc.y = showcase.y + 60;
		howToPlayModal.addChild(unitDesc);
	}
	// Enemy warning section
	var enemyWarning = new Text2('⚠️ Enemies spawn from the fog of war above! ⚠️', {
		size: 40,
		fill: 0xFF4444
	});
	enemyWarning.anchor.set(0.5, 0.5);
	enemyWarning.x = 0;
	enemyWarning.y = 600;
	howToPlayModal.addChild(enemyWarning);
	// Tips section
	var tipsText = new Text2('💡 Pro Tip: Save gold for interest bonus!', {
		size: 36,
		fill: 0x44FF44
	});
	tipsText.anchor.set(0.5, 0.5);
	tipsText.x = 0;
	tipsText.y = 700;
	howToPlayModal.addChild(tipsText);
	// Close button
	var closeButton = new Container();
	var closeButtonBg = closeButton.attachAsset('shop_button', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 300,
		height: 100
	});
	closeButtonBg.tint = 0xFF4444;
	var closeButtonText = new Text2('Got it!', {
		size: 60,
		fill: 0xFFFFFF
	});
	closeButtonText.anchor.set(0.5, 0.5);
	closeButton.addChild(closeButtonText);
	closeButton.x = 0; // Center relative to modal
	closeButton.y = 850; // Bottom of modal
	howToPlayModal.addChild(closeButton);
	closeButton.up = function () {
		howToPlayModal.destroy();
	};
	titleOverlay.addChild(howToPlayModal);
};
// Start Game button click handler
startGameButton.up = function () {
	// Reset button scale
	tween(startGameButtonBg, {
		scaleX: 1.0,
		scaleY: 1.0
	}, {
		duration: 100,
		easing: tween.easeIn
	});
	tween(startButtonGlow, {
		alpha: 0
	}, {
		duration: 200,
		easing: tween.easeIn
	});
	// Play purchase sound for feedback
	LK.getSound('purchase').play();
	// Stop main menu music and play background music when battle actually starts
	// Create expanding circle transition effect
	var transitionCircle = titleOverlay.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 50,
		height: 50
	});
	transitionCircle.tint = 0xFFD700;
	transitionCircle.x = 0;
	transitionCircle.y = -266; // Start from button position
	tween(transitionCircle, {
		scaleX: 100,
		scaleY: 100,
		alpha: 0.8
	}, {
		duration: 600,
		easing: tween.easeOut
	});
	// Hide title overlay with fade animation
	tween(titleOverlay, {
		alpha: 0
	}, {
		duration: 500,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			// Clear timers
			LK.clearInterval(particleTimer);
			LK.clearInterval(sparkleTimer);
			titleOverlay.destroy();
		}
	});
};
// Add title overlay to LK.gui.center to ensure it renders above all game elements
LK.gui.center.addChild(titleOverlay);
// Play main menu music when title overlay is shown
LK.playMusic('mainmenu_music');
// Create animated castle silhouette in background
var castleContainer = new Container();
titleOverlay.addChild(castleContainer);
castleContainer.y = 300;
castleContainer.alpha = 0.3;
// Create castle towers
var leftTower = castleContainer.attachAsset('wall', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 150,
	height: 300
});
leftTower.x = -400;
leftTower.tint = 0x1a1a2e;
var centerTower = castleContainer.attachAsset('wall', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 200,
	height: 400
});
centerTower.x = 0;
centerTower.tint = 0x16213e;
var rightTower = castleContainer.attachAsset('wall', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 150,
	height: 300
});
rightTower.x = 400;
rightTower.tint = 0x1a1a2e;
// Animate castle floating
tween(castleContainer, {
	y: 320,
	alpha: 0.25
}, {
	duration: 4000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(castleContainer, {
			y: 300,
			alpha: 0.3
		}, {
			duration: 4000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// No need to set x,y as gui.center is already centered
// Add enhanced title animation with rotation - constant loop
function startTitleAnimation() {
	tween(titleContainer, {
		scaleX: 1.05,
		scaleY: 1.05,
		rotation: 0.02
	}, {
		duration: 2000,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(titleContainer, {
				scaleX: 0.95,
				scaleY: 0.95,
				rotation: -0.02
			}, {
				duration: 2000,
				easing: tween.easeInOut,
				onFinish: startTitleAnimation
			});
		}
	});
}
startTitleAnimation();
// Add decorative crown above title
var crownContainer = new Container();
titleOverlay.addChild(crownContainer);
crownContainer.y = -666;
// Create pixelart crown
var crownBase = crownContainer.attachAsset('king', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 80,
	height: 30
});
crownBase.tint = 0xFFD700;
var crownLeft = crownContainer.attachAsset('king', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 20,
	height: 40
});
crownLeft.x = -25;
crownLeft.y = -20;
crownLeft.tint = 0xFFD700;
var crownCenter = crownContainer.attachAsset('king', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 25,
	height: 50
});
crownCenter.x = 0;
crownCenter.y = -25;
crownCenter.tint = 0xFFD700;
var crownRight = crownContainer.attachAsset('king', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 20,
	height: 40
});
crownRight.x = 25;
crownRight.y = -20;
crownRight.tint = 0xFFD700;
// Add jewels to crown
var jewelLeft = crownContainer.attachAsset('bullet', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 12,
	height: 12
});
jewelLeft.x = -25;
jewelLeft.y = -35;
jewelLeft.tint = 0xFF0000;
var jewelCenter = crownContainer.attachAsset('bullet', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 15,
	height: 15
});
jewelCenter.x = 0;
jewelCenter.y = -45;
jewelCenter.tint = 0x4169E1;
var jewelRight = crownContainer.attachAsset('bullet', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 12,
	height: 12
});
jewelRight.x = 25;
jewelRight.y = -35;
jewelRight.tint = 0xFF0000;
// Add sparkle animations to jewels
tween(jewelLeft, {
	scaleX: 1.3,
	scaleY: 1.3,
	alpha: 0.8
}, {
	duration: 1000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(jewelLeft, {
			scaleX: 1.0,
			scaleY: 1.0,
			alpha: 1.0
		}, {
			duration: 1000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
// Offset timing for center jewel
LK.setTimeout(function () {
	tween(jewelCenter, {
		scaleX: 1.4,
		scaleY: 1.4,
		alpha: 0.7
	}, {
		duration: 1200,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(jewelCenter, {
				scaleX: 1.0,
				scaleY: 1.0,
				alpha: 1.0
			}, {
				duration: 1200,
				easing: tween.easeInOut,
				onFinish: onFinish
			});
		}
	});
}, 400);
// Offset timing for right jewel
LK.setTimeout(function () {
	tween(jewelRight, {
		scaleX: 1.3,
		scaleY: 1.3,
		alpha: 0.8
	}, {
		duration: 1000,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(jewelRight, {
				scaleX: 1.0,
				scaleY: 1.0,
				alpha: 1.0
			}, {
				duration: 1000,
				easing: tween.easeInOut,
				onFinish: onFinish
			});
		}
	});
}, 800);
// Animate crown floating with enhanced effects
function startCrownAnimation() {
	tween(crownContainer, {
		y: -656,
		rotation: 0.08,
		scaleX: 1.1,
		scaleY: 1.1
	}, {
		duration: 2200,
		easing: tween.easeInOut,
		onFinish: function onFinish() {
			tween(crownContainer, {
				y: -676,
				rotation: -0.08,
				scaleX: 0.9,
				scaleY: 0.9
			}, {
				duration: 2200,
				easing: tween.easeInOut,
				onFinish: startCrownAnimation
			});
		}
	});
}
startCrownAnimation();
// Add enemy preview showcase
var enemyShowcase = new Container();
titleOverlay.addChild(enemyShowcase);
enemyShowcase.y = 700;
enemyShowcase.alpha = 0.6;
// Create actual enemy units for showcase
var showcaseEnemies = [];
var enemyTypes = [{
	type: 'regular',
	x: -400,
	constructor: Enemy
}, {
	type: 'ranged',
	x: 0,
	constructor: RangedEnemy
}, {
	type: 'boss',
	x: 400,
	constructor: Boss
}];
var _loop = function _loop() {
		enemyData = enemyTypes[i]; // Create actual enemy unit
		showcaseEnemy = new enemyData.constructor();
		showcaseEnemy.x = enemyData.x;
		showcaseEnemy.y = 0;
		// Scale down the enemy for showcase
		showcaseEnemy.scaleX = 0.6;
		showcaseEnemy.scaleY = 0.6;
		enemyShowcase.addChild(showcaseEnemy);
		showcaseEnemies.push(showcaseEnemy);
		// Add floating animation with different timing for each enemy
		baseY = showcaseEnemy.y;
		floatDelay = i * 300; // Stagger the animations
		floatDuration = 2000 + Math.random() * 1000; // Randomize duration slightly
		function startFloatingAnimation(enemy, baseY, delay) {
			LK.setTimeout(function () {
				function floatUp() {
					tween(enemy, {
						y: baseY - 20,
						scaleX: 0.66,
						scaleY: 0.66,
						rotation: 0.08
					}, {
						duration: floatDuration,
						easing: tween.easeInOut,
						onFinish: floatDown
					});
				}
				function floatDown() {
					tween(enemy, {
						y: baseY + 10,
						scaleX: 0.54,
						scaleY: 0.54,
						rotation: -0.08
					}, {
						duration: floatDuration,
						easing: tween.easeInOut,
						onFinish: floatUp
					});
				}
				floatUp(); // Start the animation cycle
			}, delay);
		}
		// Start floating animation for this enemy
		startFloatingAnimation(showcaseEnemy, baseY, floatDelay);
		// Add breathing/idle animation - slight scale pulsing
		function startBreathingAnimation(enemy, delay) {
			LK.setTimeout(function () {
				function breatheIn() {
					tween(enemy, {
						scaleX: enemy.scaleX * 1.05,
						scaleY: enemy.scaleY * 1.05
					}, {
						duration: 800,
						easing: tween.easeInOut,
						onFinish: breatheOut
					});
				}
				function breatheOut() {
					tween(enemy, {
						scaleX: enemy.scaleX / 1.05,
						scaleY: enemy.scaleY / 1.05
					}, {
						duration: 800,
						easing: tween.easeInOut,
						onFinish: breatheIn
					});
				}
				breatheIn(); // Start the breathing cycle
			}, delay + 400); // Offset from floating animation
		}
		// Start breathing animation for this enemy
		startBreathingAnimation(showcaseEnemy, floatDelay);
		// Add menacing glow effect for boss enemy
		if (enemyData.type === 'boss') {
			var startGlowAnimation = function startGlowAnimation(enemy) {
				function glowUp() {
					LK.effects.flashObject(enemy, 0xFF0000, 300); // Red flash
					LK.setTimeout(glowDown, 300);
				}
				function glowDown() {
					LK.setTimeout(glowUp, 2000 + Math.random() * 1000); // Random interval
				}
				LK.setTimeout(glowUp, 1000); // Start after 1 second
			};
			startGlowAnimation(showcaseEnemy);
		}
		// Add special effect for ranged enemy - slight weapon sway
		if (enemyData.type === 'ranged') {
			var startWeaponSway = function startWeaponSway(enemy) {
				function swayLeft() {
					tween(enemy, {
						rotation: enemy.rotation - 0.05
					}, {
						duration: 1500,
						easing: tween.easeInOut,
						onFinish: swayRight
					});
				}
				function swayRight() {
					tween(enemy, {
						rotation: enemy.rotation + 0.1
					}, {
						duration: 1500,
						easing: tween.easeInOut,
						onFinish: swayLeft
					});
				}
				LK.setTimeout(swayLeft, floatDelay + 600);
			};
			startWeaponSway(showcaseEnemy);
		}
	},
	enemyData,
	showcaseEnemy,
	baseY,
	floatDelay,
	floatDuration;
for (var i = 0; i < enemyTypes.length; i++) {
	_loop();
}
var GRID_COLS = 9;
var GRID_ROWS = 9;
var GRID_CELL_SIZE = 227; // 2048 / 9 ≈ 227
var GRID_START_X = (2048 - GRID_COLS * GRID_CELL_SIZE) / 2;
var GRID_START_Y = 100;
var PLAYABLE_HEIGHT = 2400; // Define playable game area
var enemies = [];
var units = [];
var bullets = [];
var enemyProjectiles = [];
var bench = [];
var grid = [];
var benchSlots = [];
var gold = 5;
var wave = 1;
var enemiesSpawned = 0;
var enemiesPerWave = 5;
var waveDelay = 0;
var draggedUnit = null;
var draggedFromGrid = false;
var gameState = 'planning'; // 'planning' or 'battle'
var stateText = new Text2('', {
	size: 40,
	fill: 0x44FF44 // Default to green for planning phase
});
stateText.anchor.set(0.5, 0.5);
stateText.x = 0; // Center relative to topUIContainer
stateText.y = 140; // Adjusted for bigger UI
topUIContainer = new Container(); // Container for top UI elements
topUIContainer.addChild(stateText);
var waveText = new Text2('Wave: 1', {
	size: 40,
	fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0.5);
waveText.x = 0; // Center relative to topUIContainer
waveText.y = 140; // Adjusted for bigger UI
topUIContainer.addChild(waveText);
var goldText; // Declare goldText variable
var kingInfoButton; // Declare kingInfoButton variable
var cellReservations = {}; // Track reserved cells during movement
var entityPositions = {}; // Track exact entity positions to prevent overlap
var movementQueue = []; // Queue movements to prevent simultaneous conflicts
var playerLevel = 1; // Player's current level
var maxUnitsOnField = 2; // Starting with 2 units max
var maxStructuresOnField = 2; // Starting with 2 structures max
var structuresOnField = 0; // Track structures placed
var unitsOnField = 0; // Track regular units placed
var enemyContainer = new Container(); // Container for enemies to render below fog
topUIContainer = new Container(); // Container for top UI elements
var isUIMinimized = false; // Track UI state
// Helper function to register entity position
function registerEntityPosition(entity) {
	if (entity.gridX >= 0 && entity.gridY >= 0) {
		var posKey = entity.gridX + ',' + entity.gridY;
		entityPositions[posKey] = entity;
	}
}
// Helper function to unregister entity position
function unregisterEntityPosition(entity, oldGridX, oldGridY) {
	var posKey = oldGridX + ',' + oldGridY;
	if (entityPositions[posKey] === entity) {
		delete entityPositions[posKey];
	}
}
// Helper function to check if position is occupied by any entity
function isPositionOccupied(gridX, gridY, excludeEntity) {
	var posKey = gridX + ',' + gridY;
	var occupant = entityPositions[posKey];
	return occupant && occupant !== excludeEntity;
}
// Function to calculate level up cost
function getLevelUpCost(level) {
	return level * 4; // Cost increases by 4 gold per level
}
// Function to count units on field
function countUnitsOnField() {
	structuresOnField = 0;
	unitsOnField = 0;
	for (var y = 0; y < GRID_ROWS; y++) {
		for (var x = 0; x < GRID_COLS; x++) {
			if (grid[y] && grid[y][x] && grid[y][x].unit) {
				var unit = grid[y][x].unit;
				// Skip king - it doesn't count towards any limit
				if (unit.name === "King") {
					continue; // Don't count king
				}
				if (unit.isStructure) {
					structuresOnField++;
				} else {
					unitsOnField++;
				}
			}
		}
	}
	// Update the max units text display
	maxUnitsText.setText('Units: ' + unitsOnField + '/' + maxUnitsOnField + ' | Structures: ' + structuresOnField + '/' + maxStructuresOnField);
}
// Function to check if can place more units
function canPlaceMoreUnits(isStructure) {
	countUnitsOnField();
	if (isStructure) {
		return structuresOnField < maxStructuresOnField;
	} else {
		return unitsOnField < maxUnitsOnField;
	}
}
// Function to level up player
function levelUpPlayer() {
	var cost = getLevelUpCost(playerLevel);
	if (gold >= cost) {
		gold -= cost;
		playerLevel++;
		maxUnitsOnField++; // Increase unit limit by 1
		maxStructuresOnField++; // Increase structure limit by 1
		goldText.setText(gold.toString());
		levelText.setText('King Lvl: ' + playerLevel);
		countUnitsOnField(); // Update counts and display
		// Level up the king
		levelUpKing();
		// Play purchase sound
		LK.getSound('purchase').play();
		// Visual effect
		LK.effects.flashScreen(0xFFD700, 500);
	}
}
// Function to level up king
function levelUpKing() {
	if (kings.length > 0) {
		var king = kings[0];
		// Increase king stats
		king.health = Math.floor(king.health * 1.1);
		king.maxHealth = Math.floor(king.maxHealth * 1.1);
		king.damage = Math.floor(king.damage * 1.1);
		king.armor = Math.floor(king.armor * 1.1);
		king.magicResist = Math.floor(king.magicResist * 1.1);
		// Increase king scale by 10%
		var currentScale = king.scaleX;
		var newScale = currentScale * 1.1;
		tween(king, {
			scaleX: newScale,
			scaleY: newScale
		}, {
			duration: 500,
			easing: tween.easeOut
		});
		// Update health bar
		king.updateHealthBar();
		// Flash effect
		LK.effects.flashObject(king, 0xFFD700, 800);
	}
}
// AttackInfo display removed
// Double-tap detection variables
var lastTapTime = 0;
var lastTapX = 0;
var lastTapY = 0;
var doubleTapDelay = 300; // 300ms window for double tap
var doubleTapDistance = 50; // Max distance between taps
// Add enemy container to game first (so it renders below everything else)
game.addChild(enemyContainer);
// Create grid slots
for (var y = 0; y < GRID_ROWS; y++) {
	grid[y] = [];
	for (var x = 0; x < GRID_COLS; x++) {
		var gridSlot = game.addChild(new GridSlot(0, x, y)); // Using lane 0 for all slots
		// Calculate exact position for grid slot
		var slotX = GRID_START_X + x * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		var slotY = GRID_START_Y + y * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		gridSlot.x = slotX;
		gridSlot.y = slotY;
		grid[y][x] = gridSlot;
	}
}
// Create fog of war containers array to add later (after enemies spawn)
var fogOverlays = [];
// Create fog of war for top two rows
for (var y = 0; y < 2; y++) {
	for (var x = 0; x < GRID_COLS; x++) {
		var fogOverlay = new Container();
		var fogGraphics = fogOverlay.attachAsset('grid_slot', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: GRID_CELL_SIZE - 10,
			height: GRID_CELL_SIZE - 10
		});
		fogGraphics.tint = 0x000000; // Black fog
		fogGraphics.alpha = 0.3; // More transparent to see enemies underneath
		fogOverlay.x = GRID_START_X + x * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		fogOverlay.y = GRID_START_Y + y * GRID_CELL_SIZE + GRID_CELL_SIZE / 2;
		// Add some fog texture variation
		var fogDetail = fogOverlay.attachAsset('grid_slot', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: GRID_CELL_SIZE * 0.8,
			height: GRID_CELL_SIZE * 0.8
		});
		fogDetail.tint = 0x222222;
		fogDetail.alpha = 0.2; // More transparent detail layer
		fogDetail.rotation = Math.random() * 0.2 - 0.1;
		// Store fog overlays to add later
		fogOverlays.push(fogOverlay);
	}
}
// Create king at bottom center of grid
var kings = [];
var king = game.addChild(new King());
// Place king at center column (column 4 for 9x9 grid)
var kingGridX = 4;
var kingGridY = GRID_ROWS - 1;
// Get the exact grid slot and place king there
var kingSlot = grid[kingGridY][kingGridX];
kingSlot.unit = king;
king.gridX = kingGridX;
king.gridY = kingGridY;
king.lane = 0;
// Set king position to match grid slot exactly
king.x = kingSlot.x;
king.y = kingSlot.y;
// King already has baseScale from Unit class, ensure it's applied
king.updateUnitScale();
king.showHealthBar(); // Show health bar for king from start
kings.push(king);
// Register king position
registerEntityPosition(king);
// Create info button for king
var kingInfoButton = new Container();
var kingInfoButtonBg = kingInfoButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 80,
	height: 40
});
kingInfoButtonBg.tint = 0x4444FF;
var kingInfoButtonText = new Text2('Info', {
	size: 32,
	fill: 0xFFFFFF
});
kingInfoButtonText.anchor.set(0.5, 0.5);
kingInfoButton.addChild(kingInfoButtonText);
kingInfoButton.x = king.x;
kingInfoButton.y = king.y + 100; // Position below king
game.addChild(kingInfoButton);
kingInfoButton.up = function () {
	showUnitInfoModal(king);
};
// Create bench area background
var benchAreaBg = game.addChild(LK.getAsset('bench_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5
}));
benchAreaBg.x = 1024; // Center of screen
benchAreaBg.y = PLAYABLE_HEIGHT - 120; // Move bench up by 40px
benchAreaBg.alpha = 0.7;
// Create bench slots
var benchTotalWidth = 9 * 120 + 8 * 40; // 9 slots of 120px width with 40px spacing
var benchStartX = (2048 - benchTotalWidth) / 2 + 60; // Center horizontally
for (var i = 0; i < 9; i++) {
	var benchSlot = game.addChild(new BenchSlot(i));
	benchSlot.x = benchStartX + i * 160;
	benchSlot.y = PLAYABLE_HEIGHT - 120; // Move bench up by 40px
	benchSlots[i] = benchSlot;
}
// Shop configuration
var shopSlots = [];
var unitPool = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2]; // Pool of available unit tiers
var refreshCost = 2;
// Calculate shop area dimensions
var benchBottomY = PLAYABLE_HEIGHT - 120 + 100; // Bench center + half height
var screenBottomY = 2732; // Full screen height
var shopAreaHeight = screenBottomY - benchBottomY;
var shopCenterY = benchBottomY + shopAreaHeight / 2;
// Create shop area background
var shopAreaBg = game.addChild(LK.getAsset('shop_area_bg', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 2048,
	height: shopAreaHeight
}));
shopAreaBg.x = 1024; // Center of screen
shopAreaBg.y = shopCenterY; // Center vertically in available space
shopAreaBg.alpha = 0.6;
// Create shop slots
var shopTotalWidth = 5 * 200 + 4 * 40; // 5 slots of 200px width with 40px spacing
var shopStartX = (2048 - shopTotalWidth) / 2 + 60; // Center horizontally
for (var i = 0; i < 5; i++) {
	var shopSlot = game.addChild(new Container());
	shopSlot.x = shopStartX + i * 240;
	shopSlot.y = PLAYABLE_HEIGHT + 150; // Position shop units further down
	shopSlot.index = i;
	shopSlot.unit = null;
	shopSlot.tierText = null;
	shopSlot.nameText = null;
	shopSlots.push(shopSlot);
}
// Create refresh button
var refreshButton = game.addChild(new Container());
var refreshButtonBg = refreshButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 280,
	height: 120
});
refreshButtonBg.tint = 0xFF8800;
var refreshText1 = new Text2('Refresh', {
	size: 48,
	fill: 0xFFFFFF
});
refreshText1.anchor.set(0.5, 0.5);
refreshText1.y = -20;
refreshButton.addChild(refreshButtonBg);
refreshButton.addChild(refreshText1);
var refreshText2 = new Text2('Shop', {
	size: 48,
	fill: 0xFFFFFF
});
refreshText2.anchor.set(0.5, 0.5);
refreshText2.y = 20;
refreshButton.addChild(refreshText2);
refreshButton.x = 2048 - 200;
refreshButton.y = PLAYABLE_HEIGHT + 100; // Move button higher
refreshButton.up = function () {
	if (gold >= refreshCost) {
		gold -= refreshCost;
		goldText.setText(gold.toString());
		refreshShop();
		LK.getSound('purchase').play();
	}
};
// Create level up button
var levelUpButton = game.addChild(new Container());
var levelUpButtonBg = levelUpButton.attachAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 280,
	height: 120
});
levelUpButtonBg.tint = 0xFF8800;
var levelUpText = new Text2('Level Up', {
	size: 48,
	fill: 0xFFFFFF
});
levelUpText.anchor.set(0.5, 0.5);
levelUpButton.addChild(levelUpText);
levelUpButton.x = 200;
levelUpButton.y = PLAYABLE_HEIGHT + 100; // Move button higher
levelUpButton.up = function () {
	levelUpPlayer();
};
// Create level up cost text
var levelUpCostText = new Text2('Cost: ' + getLevelUpCost(playerLevel) + 'g', {
	size: 42,
	fill: 0xFFD700
});
levelUpCostText.anchor.set(0.5, 0);
levelUpCostText.x = 200;
levelUpCostText.y = PLAYABLE_HEIGHT + 200;
game.addChild(levelUpCostText);
// Create refresh cost text
var refreshCostText = new Text2('Cost: ' + refreshCost + 'g', {
	size: 42,
	fill: 0xFFD700
});
refreshCostText.anchor.set(0.5, 0);
refreshCostText.x = 2048 - 200;
refreshCostText.y = PLAYABLE_HEIGHT + 200;
game.addChild(refreshCostText);
// Function to refresh shop with new units
function refreshShop() {
	// Clear existing shop units
	for (var i = 0; i < shopSlots.length; i++) {
		if (shopSlots[i].unit) {
			shopSlots[i].unit.destroy();
			shopSlots[i].unit = null;
		}
		if (shopSlots[i].tierText) {
			shopSlots[i].tierText.destroy();
			shopSlots[i].tierText = null;
		}
		if (shopSlots[i].nameText) {
			shopSlots[i].nameText.destroy();
			shopSlots[i].nameText = null;
		}
		if (shopSlots[i].infoButton) {
			shopSlots[i].infoButton.destroy();
			shopSlots[i].infoButton = null;
		}
	}
	// Fill shop with new random units
	for (var i = 0; i < shopSlots.length; i++) {
		var randomTier = unitPool[Math.floor(Math.random() * unitPool.length)];
		var shopUnit;
		var unitConstructor;
		switch (randomTier) {
			case 1:
				var unitTypes = [Soldier, Knight, Wall];
				unitConstructor = unitTypes[Math.floor(Math.random() * unitTypes.length)];
				shopUnit = new unitConstructor();
				break;
			case 2:
				var unitTypes = [Wizard, Paladin, Ranger, CrossbowTower];
				unitConstructor = unitTypes[Math.floor(Math.random() * unitTypes.length)];
				shopUnit = new unitConstructor();
				break;
		}
		shopUnit.x = shopSlots[i].x;
		shopUnit.y = shopSlots[i].y; // Center the unit in the shop slot
		game.addChild(shopUnit);
		shopSlots[i].unit = shopUnit;
		shopSlots[i].unitConstructor = unitConstructor; // Store the constructor reference
		// Add gentle floating animation for shop units
		var baseY = shopUnit.y;
		tween(shopUnit, {
			y: baseY - 10
		}, {
			duration: 1000 + Math.random() * 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(shopUnit, {
					y: baseY
				}, {
					duration: 1000 + Math.random() * 500,
					easing: tween.easeInOut,
					onFinish: onFinish
				});
			}
		});
		// Add unit name text above the image with more spacing
		var nameText = new Text2(shopUnit.name, {
			size: 36,
			fill: 0xFFFFFF
		});
		nameText.anchor.set(0.5, 1); //{3P} // Anchor to bottom center
		nameText.x = shopSlots[i].x;
		nameText.y = shopSlots[i].y - 100; // Position higher above the unit image
		game.addChild(nameText);
		shopSlots[i].nameText = nameText;
		// Add cost text below the image with more spacing
		var cost = randomTier;
		// Special cost for Wall (1g) and CrossbowTower (2g)
		if (shopUnit.name === "Wall") {
			cost = 1;
		} else if (shopUnit.name === "CrossbowTower") {
			cost = 2;
		}
		var costText = new Text2(cost + 'g', {
			size: 36,
			fill: 0xFFD700
		});
		costText.anchor.set(0.5, 0);
		costText.x = shopSlots[i].x;
		costText.y = shopSlots[i].y + 70; // Position well below the unit image
		game.addChild(costText);
		shopSlots[i].tierText = costText;
		// Add info button below cost
		var infoButton = new Container();
		var infoButtonBg = infoButton.attachAsset('shop_button', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: 80,
			height: 40
		});
		infoButtonBg.tint = 0x4444FF;
		var infoButtonText = new Text2('Info', {
			size: 32,
			fill: 0xFFFFFF
		});
		infoButtonText.anchor.set(0.5, 0.5);
		infoButton.addChild(infoButtonText);
		infoButton.x = shopSlots[i].x;
		infoButton.y = shopSlots[i].y + 130; // Position below cost text with more spacing
		game.addChild(infoButton);
		shopSlots[i].infoButton = infoButton;
		// Store unit reference on info button for click handler
		infoButton.shopUnit = shopUnit;
		infoButton.up = function () {
			showUnitInfoModal(this.shopUnit);
		};
	}
}
// Function to show unit info modal
function showUnitInfoModal(unit) {
	// Create modal overlay
	var modalOverlay = game.addChild(new Container());
	modalOverlay.x = 1024; // Center of screen
	modalOverlay.y = 1366; // Center of screen
	// Create modal background
	var modalBg = modalOverlay.attachAsset('shop_area_bg', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 600,
		height: 800
	});
	modalBg.alpha = 0.95;
	// Add title
	var titleText = new Text2(unit.name, {
		size: 48,
		fill: 0xFFFFFF
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.y = -350;
	modalOverlay.addChild(titleText);
	// Add attributes
	var attributes = ['Health: ' + unit.maxHealth, 'Damage: ' + unit.damage, 'Armor: ' + unit.armor, 'Magic Resist: ' + unit.magicResist, 'Critical Chance: ' + unit.criticalChance * 100 + '%', 'Mana: ' + unit.mana, 'Attack Speed: ' + unit.speed, 'Range: ' + unit.range];
	for (var i = 0; i < attributes.length; i++) {
		var attrText = new Text2(attributes[i], {
			size: 36,
			fill: 0xFFFFFF
		});
		attrText.anchor.set(0.5, 0.5);
		attrText.y = -250 + i * 60;
		modalOverlay.addChild(attrText);
	}
	// Add close button
	var closeButton = new Container();
	var closeButtonBg = closeButton.attachAsset('shop_button', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 150,
		height: 60
	});
	closeButtonBg.tint = 0xFF4444;
	var closeButtonText = new Text2('Close', {
		size: 36,
		fill: 0xFFFFFF
	});
	closeButtonText.anchor.set(0.5, 0.5);
	closeButton.addChild(closeButtonText);
	closeButton.y = 330;
	modalOverlay.addChild(closeButton);
	closeButton.up = function () {
		modalOverlay.destroy();
	};
}
// Initialize shop with units
refreshShop();
// Add fog overlays on top of everything to ensure they render above enemies
for (var i = 0; i < fogOverlays.length; i++) {
	game.addChild(fogOverlays[i]);
}
// Create top UI container
topUIContainer = game.addChild(topUIContainer);
topUIContainer.x = 1024; // Center of screen
topUIContainer.y = 10; // Top of screen with small margin
// Create top UI container background - bigger initially for planning phase
var topUIBg = topUIContainer.addChild(LK.getAsset('bench_area_bg', {
	anchorX: 0.5,
	anchorY: 0,
	width: 1800,
	height: 240 // Bigger height for planning phase
}));
topUIBg.alpha = 0.7;
topUIBg.tint = 0x0a0a1a; // Match the deep dark blue of the title screen
// Create top row elements (Coin, Level, Max Units)
var goldContainer = new Container();
goldContainer.x = 650; // Relative to topUIContainer
goldContainer.y = 60; // Adjusted for bigger UI
topUIContainer.addChild(goldContainer);
// Create detailed pixelart coin
var coinContainer = new Container();
goldContainer.addChild(coinContainer);
coinContainer.x = -50; // Move coin further left to increase spacing
// Coin base (outer ring)
var coinBase = coinContainer.attachAsset('coin_base', {
	anchorX: 0.5,
	anchorY: 0.5
});
// Coin inner ring
var coinInner = coinContainer.attachAsset('coin_inner', {
	anchorX: 0.5,
	anchorY: 0.5
});
// Coin center
var coinCenter = coinContainer.attachAsset('coin_center', {
	anchorX: 0.5,
	anchorY: 0.5
});
// Coin highlight for shine effect
var coinHighlight = coinContainer.attachAsset('coin_highlight', {
	anchorX: 0.5,
	anchorY: 0.5
});
coinHighlight.x = -6;
coinHighlight.y = -6;
// Add subtle rotation animation to make coin feel alive
tween(coinContainer, {
	rotation: 0.1
}, {
	duration: 2000,
	easing: tween.easeInOut,
	onFinish: function onFinish() {
		tween(coinContainer, {
			rotation: -0.1
		}, {
			duration: 2000,
			easing: tween.easeInOut,
			onFinish: onFinish
		});
	}
});
goldText = new Text2(gold.toString(), {
	size: 50,
	fill: 0xFFD700
});
goldText.anchor.set(0.5, 0.5);
goldText.x = 40; // Move number further right to create more space
goldContainer.addChild(goldText);
var levelText = new Text2('King Lvl: ' + playerLevel, {
	size: 50,
	fill: 0x87CEEB
});
levelText.anchor.set(0.5, 0.5);
levelText.x = 0; // Center relative to topUIContainer
levelText.y = 60; // Adjusted for bigger UI
topUIContainer.addChild(levelText);
var maxUnitsText = new Text2('Units: 0/' + maxUnitsOnField + ' | Structures: 0/' + maxStructuresOnField, {
	size: 50,
	fill: 0xFFD700
});
maxUnitsText.anchor.set(0.5, 0.5);
maxUnitsText.x = -500; // Left of center relative to topUIContainer
maxUnitsText.y = 60; // Adjusted for bigger UI
topUIContainer.addChild(maxUnitsText);
// Create bottom row elements (Planning Phase, Next Wave)
// Function to minimize UI during battle
function minimizeUI() {
	// Tween background to smaller size
	tween(topUIBg, {
		height: 120
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	// Move ready button up
	tween(readyButton, {
		y: 90
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	// Move state and wave text up
	tween(stateText, {
		y: 90
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	tween(waveText, {
		y: 90
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
}
// Function to maximize UI during planning
function maximizeUI() {
	// Tween background to bigger size
	tween(topUIBg, {
		height: 240
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	// Move ready button down
	tween(readyButton, {
		y: 190
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	// Move state and wave text down
	tween(stateText, {
		y: 140
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
	tween(waveText, {
		y: 140
	}, {
		duration: 400,
		easing: tween.easeInOut
	});
}
// Function to update state indicator
function updateStateIndicator() {
	if (gameState === 'planning') {
		stateText.setText('Planning Phase');
		// Remove old text and create new one with correct color
		var parent = stateText.parent;
		var x = stateText.x;
		var y = stateText.y;
		stateText.destroy();
		stateText = new Text2('Planning Phase', {
			size: 40,
			fill: 0x44FF44 // Green for planning
		});
		stateText.anchor.set(0.5, 0.5);
		stateText.x = x;
		stateText.y = y;
		parent.addChild(stateText);
		// Enable ready button during planning
		readyButtonBg.tint = 0x44AA44; // Green tint
		readyButtonText.setText('Ready!');
		// Allow unit movement during planning phase
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				var gridSlot = grid[y][x];
				if (gridSlot.unit) {
					gridSlot.unit.interactive = true;
				}
			}
		}
		// Show king info button during planning
		if (kingInfoButton) {
			kingInfoButton.visible = true;
		}
		// Maximize UI for planning phase
		if (isUIMinimized) {
			isUIMinimized = false;
			maximizeUI();
		}
	} else {
		stateText.setText('Battle Phase');
		// Remove old text and create new one with correct color
		var parent = stateText.parent;
		var x = stateText.x;
		var y = stateText.y;
		stateText.destroy();
		stateText = new Text2('Battle Phase', {
			size: 40,
			fill: 0xFF4444 // Red for battle
		});
		stateText.anchor.set(0.5, 0.5);
		stateText.x = x;
		stateText.y = y;
		parent.addChild(stateText);
		// Grey out ready button during battle
		readyButtonBg.tint = 0x666666; // Grey tint
		readyButtonText.setText('Battle');
		// Disable unit movement during battle phase
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				var gridSlot = grid[y][x];
				if (gridSlot.unit) {
					gridSlot.unit.interactive = false;
				}
			}
		}
		// Hide king info button during battle
		if (kingInfoButton) {
			kingInfoButton.visible = false;
		}
		// Minimize UI for battle phase
		if (!isUIMinimized) {
			isUIMinimized = true;
			minimizeUI();
		}
	}
}
var readyButton = new Container();
var readyButtonBg = LK.getAsset('shop_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 300,
	height: 100
});
readyButtonBg.tint = 0x44AA44;
var readyButtonText = new Text2('Ready!', {
	size: 72,
	fill: 0xFFFFFF
});
readyButtonText.anchor.set(0.5, 0.5);
readyButton.addChild(readyButtonBg);
readyButton.addChild(readyButtonText);
topUIContainer.addChild(readyButton);
readyButton.x = 0; // Center relative to topUIContainer
readyButton.y = 190; // Position in bigger UI
readyButton.up = function () {
	if (gameState === 'planning') {
		// Check for upgrades before starting battle
		checkAndUpgradeUnits();
		gameState = 'battle';
		waveDelay = 0;
		enemiesSpawned = 0; // Reset enemies spawned for new wave
		updateStateIndicator(); // Update UI to show battle phase
		// Stop main menu music and play background music when battle actually starts
		LK.stopMusic();
		LK.playMusic('backgroundmusic');
	}
	// Do nothing if gameState is 'battle' (button is disabled)
};
// Function to check and perform unit upgrades
function checkAndUpgradeUnits() {
	// Group units by name and type
	var unitGroups = {};
	// Count units in bench
	for (var i = 0; i < bench.length; i++) {
		var unit = bench[i];
		if (unit.gridX === -1 && unit.gridY === -1) {
			// Only count bench units
			var key = unit.name + '_' + unit.tier;
			if (!unitGroups[key]) {
				unitGroups[key] = [];
			}
			unitGroups[key].push({
				unit: unit,
				location: 'bench',
				index: i
			});
		}
	}
	// Count units on grid
	for (var y = 0; y < GRID_ROWS; y++) {
		for (var x = 0; x < GRID_COLS; x++) {
			var gridSlot = grid[y][x];
			if (gridSlot.unit) {
				var unit = gridSlot.unit;
				var key = unit.name + '_' + unit.tier;
				if (!unitGroups[key]) {
					unitGroups[key] = [];
				}
				unitGroups[key].push({
					unit: unit,
					location: 'grid',
					gridX: x,
					gridY: y,
					slot: gridSlot
				});
			}
		}
	}
	// Check for upgrades
	for (var key in unitGroups) {
		var group = unitGroups[key];
		if (group.length >= 3) {
			// Find upgrade priority: bench first, then grid
			var benchUnits = group.filter(function (item) {
				return item.location === 'bench';
			});
			var gridUnits = group.filter(function (item) {
				return item.location === 'grid';
			});
			var unitsToMerge = [];
			var upgradeTarget = null;
			var upgradeLocation = null;
			if (gridUnits.length >= 2 && benchUnits.length >= 1) {
				// Priority: Upgrade units on grid when 2 are on field and 1 in bench
				unitsToMerge = gridUnits.slice(0, 2).concat(benchUnits.slice(0, 1));
				upgradeTarget = unitsToMerge[0];
				upgradeLocation = 'grid';
			} else if (gridUnits.length >= 1 && benchUnits.length >= 2) {
				// Upgrade unit on grid using bench units
				unitsToMerge = [gridUnits[0]].concat(benchUnits.slice(0, 2));
				upgradeTarget = unitsToMerge[0];
				upgradeLocation = 'grid';
			} else if (benchUnits.length >= 3) {
				// Upgrade in bench
				unitsToMerge = benchUnits.slice(0, 3);
				upgradeTarget = unitsToMerge[0];
				upgradeLocation = 'bench';
			}
			if (upgradeTarget && unitsToMerge.length === 3) {
				// Perform upgrade
				var baseUnit = upgradeTarget.unit;
				// Upgrade attributes based on tier
				if (baseUnit.tier === 2) {
					// Three star upgrade - multiply stats by 3
					baseUnit.health = Math.floor(baseUnit.health * 3);
					baseUnit.maxHealth = Math.floor(baseUnit.maxHealth * 3);
					baseUnit.damage = Math.floor(baseUnit.damage * 3);
					baseUnit.armor = Math.floor(baseUnit.armor * 3);
					baseUnit.magicResist = Math.floor(baseUnit.magicResist * 3);
					baseUnit.mana = Math.floor(baseUnit.mana * 3);
				} else {
					// Two star upgrade - multiply by 1.8x
					baseUnit.health = Math.floor(baseUnit.health * 1.8);
					baseUnit.maxHealth = Math.floor(baseUnit.maxHealth * 1.8);
					baseUnit.damage = Math.floor(baseUnit.damage * 1.8);
					baseUnit.armor = Math.floor(baseUnit.armor * 1.8);
					baseUnit.magicResist = Math.floor(baseUnit.magicResist * 1.8);
					baseUnit.mana = Math.floor(baseUnit.mana * 1.8);
				}
				baseUnit.tier = baseUnit.tier + 1;
				// Update health bar to reflect new max health
				if (baseUnit.healthBar) {
					baseUnit.updateHealthBar();
				}
				// Update star indicator to reflect new tier
				if (baseUnit.starIndicator) {
					baseUnit.starIndicator.updateStars(baseUnit.tier);
				}
				// Force immediate scale application by stopping any ongoing scale tweens
				tween.stop(baseUnit, {
					scaleX: true,
					scaleY: true
				});
				// Apply the scale immediately based on tier
				var baseScale = baseUnit.baseScale || 1.3;
				var finalScale = baseScale;
				if (baseUnit.tier === 2) {
					finalScale = baseScale * 1.2;
				} else if (baseUnit.tier === 3) {
					finalScale = baseScale * 1.3;
				}
				// Set scale immediately
				baseUnit.scaleX = finalScale;
				baseUnit.scaleY = finalScale;
				// Update unit scale method to ensure consistency
				baseUnit.updateUnitScale();
				// Visual upgrade effect with bounce animation that respects final scale
				LK.effects.flashObject(baseUnit, 0xFFD700, 800); // Gold flash
				tween(baseUnit, {
					scaleX: finalScale * 1.2,
					scaleY: finalScale * 1.2
				}, {
					duration: 300,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						tween(baseUnit, {
							scaleX: finalScale,
							scaleY: finalScale
						}, {
							duration: 200,
							easing: tween.easeIn
						});
					}
				});
				// Remove the other two units
				for (var i = 1; i < unitsToMerge.length; i++) {
					var unitToRemove = unitsToMerge[i];
					if (unitToRemove.location === 'bench') {
						// Remove from bench
						for (var j = bench.length - 1; j >= 0; j--) {
							if (bench[j] === unitToRemove.unit) {
								bench[j].destroy();
								bench.splice(j, 1);
								break;
							}
						}
					} else if (unitToRemove.location === 'grid') {
						// Remove from grid
						unitToRemove.slot.unit = null;
						unregisterEntityPosition(unitToRemove.unit, unitToRemove.gridX, unitToRemove.gridY);
						unitToRemove.unit.destroy();
					}
				}
				// Update displays
				updateBenchDisplay();
			}
		}
	}
}
// Function to move units to closest grid spots after battle
function moveUnitsToClosestGridSpots() {
	for (var y = 0; y < GRID_ROWS; y++) {
		for (var x = 0; x < GRID_COLS; x++) {
			var gridSlot = grid[y][x];
			if (gridSlot.unit && !gridSlot.unit.isStructure && gridSlot.unit.name !== "King") {
				var unit = gridSlot.unit;
				var currentGridX = unit.gridX;
				var currentGridY = unit.gridY;
				// Find closest valid grid position
				var closestGridX = currentGridX;
				var closestGridY = currentGridY;
				var minDistance = 999;
				for (var checkY = 2; checkY < GRID_ROWS; checkY++) {
					// Start from row 2 to avoid fog of war
					for (var checkX = 0; checkX < GRID_COLS; checkX++) {
						var checkSlot = grid[checkY][checkX];
						// Check if position is valid (not occupied or same unit)
						if (!checkSlot.unit || checkSlot.unit === unit) {
							var distance = Math.abs(checkX - currentGridX) + Math.abs(checkY - currentGridY);
							if (distance < minDistance) {
								minDistance = distance;
								closestGridX = checkX;
								closestGridY = checkY;
							}
						}
					}
				}
				// Only move if we found a different position
				if (closestGridX !== currentGridX || closestGridY !== currentGridY) {
					var targetSlot = grid[closestGridY][closestGridX];
					var targetX = targetSlot.x;
					var targetY = targetSlot.y;
					// Clear old position
					gridSlot.unit = null;
					unregisterEntityPosition(unit, currentGridX, currentGridY);
					// Set new position
					targetSlot.unit = unit;
					unit.gridX = closestGridX;
					unit.gridY = closestGridY;
					registerEntityPosition(unit);
					// Animate unit to new position
					tween(unit, {
						x: targetX,
						y: targetY
					}, {
						duration: 800,
						easing: tween.easeInOut
					});
				}
			}
		}
	}
}
// Function to show ready button for next wave
function showReadyButton() {
	if (gameState === 'battle') {
		readyButtonBg.tint = 0x666666; // Grey tint during battle
		readyButtonText.setText('Battle');
	} else {
		readyButtonBg.tint = 0x44AA44; // Green tint for next wave
		readyButtonText.setText('Next Wave');
	}
	readyButton.visible = true;
}
// Hide ready button initially (will show after first wave)
function hideReadyButton() {
	readyButton.visible = false;
}
function updateBenchDisplay() {
	// Clear all bench slot references
	for (var i = 0; i < benchSlots.length; i++) {
		benchSlots[i].unit = null;
	}
	// Only display units in bench that are not on the battlefield
	for (var i = 0; i < bench.length; i++) {
		// Skip units that are already placed on the grid
		if (bench[i].gridX !== -1 && bench[i].gridY !== -1) {
			continue;
		}
		// Find the first empty bench slot
		for (var j = 0; j < benchSlots.length; j++) {
			if (!benchSlots[j].unit) {
				benchSlots[j].unit = bench[i];
				// Center the unit in the bench slot
				bench[i].x = benchSlots[j].x;
				bench[i].y = benchSlots[j].y;
				// Show star indicator for units in bench
				bench[i].showStarIndicator();
				break;
			}
		}
	}
}
function spawnEnemy() {
	var spawnX = Math.floor(Math.random() * GRID_COLS);
	var enemy;
	// Spawn boss monster every 5 waves
	if (wave % 5 === 0 && enemiesSpawned === Math.floor(enemiesPerWave / 2)) {
		enemy = new Boss();
		// Scale boss stats based on wave
		if (wave > 1) {
			var waveMultiplier = 1 + (wave - 1) * 0.2;
			enemy.health = Math.floor(enemy.health * waveMultiplier);
			enemy.maxHealth = enemy.health;
			enemy.damage = Math.floor(enemy.damage * waveMultiplier);
			enemy.armor = Math.floor(enemy.armor * (1 + (wave - 1) * 0.1));
			enemy.magicResist = Math.floor(enemy.magicResist * (1 + (wave - 1) * 0.1));
			enemy.goldValue = Math.floor(enemy.goldValue * waveMultiplier);
		}
	} else {
		// Increase ranged enemy chance as waves progress
		var rangedChance = Math.min(0.3 + wave * 0.05, 0.7);
		if (Math.random() < rangedChance) {
			enemy = new RangedEnemy();
		} else {
			enemy = new Enemy();
		}
		// Significantly increase enemy scaling per wave
		enemy.health = 20 + Math.floor(wave * 10) + Math.floor(Math.pow(wave, 1.5) * 5);
		enemy.maxHealth = enemy.health;
		enemy.damage = 15 + Math.floor(wave * 5) + Math.floor(Math.pow(wave, 1.3) * 3);
		enemy.goldValue = Math.max(2, Math.floor(wave * 1.5));
	}
	// Try to spawn in a strategic position
	var bestSpawnX = spawnX;
	var minPlayerUnits = 999;
	// Check each column for player units
	for (var x = 0; x < GRID_COLS; x++) {
		var playerUnitsInColumn = 0;
		for (var y = 0; y < GRID_ROWS; y++) {
			if (grid[y] && grid[y][x] && grid[y][x].unit) {
				playerUnitsInColumn++;
			}
		}
		// Boss prefers columns with fewer player units
		if (enemy.name === "Boss Monster" && playerUnitsInColumn < minPlayerUnits) {
			minPlayerUnits = playerUnitsInColumn;
			bestSpawnX = x;
		}
	}
	// Position enemy at the first row (top) of the grid
	enemy.gridX = enemy.name === "Boss Monster" ? bestSpawnX : spawnX;
	enemy.gridY = 0;
	// Set visual position to match grid position
	var topCell = grid[0][enemy.gridX];
	enemy.x = topCell.x;
	enemy.y = topCell.y;
	enemy.lane = 0; // Single grid, so lane is always 0
	// Apply base scale
	if (enemy.name !== "Boss Monster") {
		// Scale up enemy by 30%
		enemy.scaleX = 1.3;
		enemy.scaleY = 1.3;
	}
	enemy.showHealthBar(); // Show health bar when enemy is spawned
	enemy.updateHealthBar();
	// Initialize GridMovement immediately for the enemy
	enemy.gridMovement = new GridMovement(enemy, grid);
	enemies.push(enemy);
	enemyContainer.addChild(enemy);
	// Add spawn animation
	enemy.alpha = 0;
	var baseScale = enemy.baseScale || 1.3;
	enemy.scaleX = baseScale * 0.5;
	enemy.scaleY = baseScale * 1.5;
	tween(enemy, {
		alpha: 1,
		scaleX: baseScale,
		scaleY: baseScale
	}, {
		duration: 300,
		easing: tween.easeOut
	});
	// Register enemy position
	registerEntityPosition(enemy);
}
game.move = function (x, y, obj) {
	if (draggedUnit) {
		draggedUnit.x = x;
		draggedUnit.y = y;
	}
};
game.up = function (x, y, obj) {
	// Check for double-tap on grid units when not dragging
	if (!draggedUnit) {
		var currentTime = Date.now();
		var timeDiff = currentTime - lastTapTime;
		var dx = x - lastTapX;
		var dy = y - lastTapY;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Check if this is a double-tap (within time window and close to last tap)
		if (timeDiff < doubleTapDelay && distance < doubleTapDistance) {
			// Check if double-tap is on a unit in the grid
			for (var gridY = 0; gridY < GRID_ROWS; gridY++) {
				for (var gridX = 0; gridX < GRID_COLS; gridX++) {
					var slot = grid[gridY][gridX];
					if (slot.unit) {
						var unitDx = x - slot.x;
						var unitDy = y - slot.y;
						var unitDistance = Math.sqrt(unitDx * unitDx + unitDy * unitDy);
						if (unitDistance < GRID_CELL_SIZE / 2) {
							// Double-tapped on this unit - show info modal
							showUnitInfoModal(slot.unit);
							lastTapTime = 0; // Reset to prevent triple-tap
							return;
						}
					}
				}
			}
			// Check if double-tap is on a unit in the bench during planning phase
			if (gameState === 'planning') {
				for (var i = 0; i < benchSlots.length; i++) {
					var benchSlot = benchSlots[i];
					if (benchSlot.unit) {
						var unitDx = x - benchSlot.x;
						var unitDy = y - benchSlot.y;
						var unitDistance = Math.sqrt(unitDx * unitDx + unitDy * unitDy);
						if (unitDistance < 60) {
							// Double-tapped on this bench unit - show info modal
							showUnitInfoModal(benchSlot.unit);
							lastTapTime = 0; // Reset to prevent triple-tap
							return;
						}
					}
				}
			}
			// Check if double-tap is on an enemy
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				var enemyDx = x - enemy.x;
				var enemyDy = y - enemy.y;
				var enemyDistance = Math.sqrt(enemyDx * enemyDx + enemyDy * enemyDy);
				if (enemyDistance < 60) {
					// Double-tapped on this enemy - show info modal
					showUnitInfoModal(enemy);
					lastTapTime = 0; // Reset to prevent triple-tap
					return;
				}
			}
		}
		// Update last tap info for next potential double-tap
		lastTapTime = currentTime;
		lastTapX = x;
		lastTapY = y;
	}
	if (draggedUnit) {
		var dropped = false;
		// Check if dropped on a valid grid slot
		for (var gridY = 0; gridY < GRID_ROWS; gridY++) {
			for (var gridX = 0; gridX < GRID_COLS; gridX++) {
				var slot = grid[gridY][gridX];
				var dx = x - slot.x;
				var dy = y - slot.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				if (distance < GRID_CELL_SIZE / 2 && !slot.unit) {
					// Valid empty grid slot - ensure exact positioning
					slot.placeUnit(draggedUnit);
					if (draggedFromGrid && draggedUnit.originalGridSlot) {
						// Unregister from old position before clearing slot
						unregisterEntityPosition(draggedUnit, draggedUnit.originalGridSlot.gridX, draggedUnit.originalGridSlot.gridY);
						draggedUnit.originalGridSlot.unit = null;
					}
					dropped = true;
					break;
				}
			}
			if (dropped) {
				break;
			}
		}
		// Check if dropped on bench slot
		if (!dropped) {
			// Prevent King from being moved to bench
			if (draggedUnit.name !== 'King') {
				for (var i = 0; i < benchSlots.length; i++) {
					var benchSlot = benchSlots[i];
					var dx = x - benchSlot.x;
					var dy = y - benchSlot.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					if (distance < 60 && !benchSlot.unit) {
						// Valid empty bench slot
						benchSlot.unit = draggedUnit;
						draggedUnit.x = benchSlot.x;
						draggedUnit.y = benchSlot.y;
						// Remove from grid if it was on grid
						if (draggedFromGrid && draggedUnit.originalGridSlot) {
							// Unregister from position tracking
							unregisterEntityPosition(draggedUnit, draggedUnit.originalGridSlot.gridX, draggedUnit.originalGridSlot.gridY);
							draggedUnit.originalGridSlot.unit = null;
						}
						draggedUnit.gridX = -1;
						draggedUnit.gridY = -1;
						draggedUnit.lane = -1;
						draggedUnit.hideHealthBar(); // Hide health bar when moved to bench
						draggedUnit.hideStarIndicator(); // Hide star indicator when moved to bench
						dropped = true;
						updateBenchDisplay();
						// Add bounce effect when unit is moved to bench
						var targetScale = draggedUnit.baseScale || 1.3;
						if (draggedUnit.tier === 2) {
							targetScale = draggedUnit.baseScale * 1.2;
						} else if (draggedUnit.tier === 3) {
							targetScale = draggedUnit.baseScale * 1.3;
						}
						draggedUnit.scaleX = targetScale * 0.8;
						draggedUnit.scaleY = targetScale * 0.8;
						// Capture unit reference before clearing draggedUnit
						var unitToAnimate = draggedUnit;
						tween(unitToAnimate, {
							scaleX: targetScale * 1.2,
							scaleY: targetScale * 1.2
						}, {
							duration: 200,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								tween(unitToAnimate, {
									scaleX: targetScale,
									scaleY: targetScale
								}, {
									duration: 150,
									easing: tween.easeIn,
									onFinish: function onFinish() {
										// Clear bounce animation flag when bounce is complete
										unitToAnimate._isBounceAnimating = false;
									}
								});
							}
						});
						break;
					}
				}
			}
		}
		// If not dropped on valid slot, return to original position
		if (!dropped) {
			// Handle King separately - must return to grid
			if (draggedUnit.name === 'King') {
				// King must return to original grid position
				if (draggedFromGrid && draggedUnit.originalGridSlot) {
					draggedUnit.x = draggedUnit.originalX;
					draggedUnit.y = draggedUnit.originalY;
					draggedUnit.originalGridSlot.unit = draggedUnit; // Restore unit to original grid slot
				}
			} else {
				// Always return to bench if not placed in a valid cell
				if (draggedUnit.originalSlot) {
					// Return to original bench slot
					draggedUnit.x = draggedUnit.originalX;
					draggedUnit.y = draggedUnit.originalY;
					draggedUnit.originalSlot.unit = draggedUnit;
				} else if (draggedFromGrid && draggedUnit.originalGridSlot) {
					// Unit was dragged from grid but not placed in valid cell - return to bench
					// Find first available bench slot
					var returnedToBench = false;
					for (var i = 0; i < benchSlots.length; i++) {
						if (!benchSlots[i].unit) {
							benchSlots[i].unit = draggedUnit;
							draggedUnit.x = benchSlots[i].x;
							draggedUnit.y = benchSlots[i].y;
							// Unregister from grid position
							unregisterEntityPosition(draggedUnit, draggedUnit.originalGridSlot.gridX, draggedUnit.originalGridSlot.gridY);
							draggedUnit.originalGridSlot.unit = null;
							draggedUnit.gridX = -1;
							draggedUnit.gridY = -1;
							draggedUnit.lane = -1;
							draggedUnit.hideHealthBar();
							draggedUnit.hideStarIndicator(); // Hide star indicator when moved to bench
							returnedToBench = true;
							updateBenchDisplay();
							// Add bounce effect when unit is returned to bench
							var targetScale = draggedUnit.baseScale || 1.3;
							if (draggedUnit.tier === 2) {
								targetScale = draggedUnit.baseScale * 1.2;
							} else if (draggedUnit.tier === 3) {
								targetScale = draggedUnit.baseScale * 1.3;
							}
							draggedUnit.scaleX = targetScale * 0.8;
							draggedUnit.scaleY = targetScale * 0.8;
							// Capture unit reference before clearing draggedUnit
							var unitToAnimate = draggedUnit;
							tween(unitToAnimate, {
								scaleX: targetScale * 1.2,
								scaleY: targetScale * 1.2
							}, {
								duration: 200,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									tween(unitToAnimate, {
										scaleX: targetScale,
										scaleY: targetScale
									}, {
										duration: 150,
										easing: tween.easeIn
									});
								}
							});
							break;
						}
					}
					// If no bench slot available, return to original grid position
					if (!returnedToBench) {
						draggedUnit.x = draggedUnit.originalX;
						draggedUnit.y = draggedUnit.originalY;
						draggedUnit.originalGridSlot.unit = draggedUnit; // Restore unit to original grid slot
					}
				} else {
					// Unit doesn't have original position - find first available bench slot
					for (var i = 0; i < benchSlots.length; i++) {
						if (!benchSlots[i].unit) {
							benchSlots[i].unit = draggedUnit;
							draggedUnit.x = benchSlots[i].x;
							draggedUnit.y = benchSlots[i].y;
							draggedUnit.gridX = -1;
							draggedUnit.gridY = -1;
							draggedUnit.lane = -1;
							draggedUnit.hideHealthBar();
							draggedUnit.hideStarIndicator(); // Hide star indicator when moved to bench
							updateBenchDisplay();
							break;
						}
					}
				}
			}
		}
		// Clean up
		draggedUnit.originalX = undefined;
		draggedUnit.originalY = undefined;
		draggedUnit.originalSlot = undefined;
		draggedUnit.originalGridSlot = undefined;
		draggedUnit = null;
		draggedFromGrid = false;
	} else {
		// Check if clicking on a shop unit
		for (var i = 0; i < shopSlots.length; i++) {
			var slot = shopSlots[i];
			if (slot.unit) {
				var dx = x - slot.x;
				var dy = y - slot.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				if (distance < 80) {
					// Increase click area for better usability
					// Within click range of shop unit
					var unitCost = slot.unit.tier;
					// Special cost for Wall (1g) and CrossbowTower (2g)
					if (slot.unit.name === "Wall") {
						unitCost = 1;
					} else if (slot.unit.name === "CrossbowTower") {
						unitCost = 2;
					}
					var currentTime = Date.now();
					var timeDiff = currentTime - lastTapTime;
					var dx = x - lastTapX;
					var dy = y - lastTapY;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Check if this is a double-tap
					if (timeDiff < doubleTapDelay && distance < doubleTapDistance) {
						// This is a double-tap - check if we can purchase
						if (gold >= unitCost) {
							// Find available bench slot
							var availableBenchSlot = false;
							for (var slotIndex = 0; slotIndex < benchSlots.length; slotIndex++) {
								if (!benchSlots[slotIndex].unit) {
									availableBenchSlot = true;
									break;
								}
							}
							if (availableBenchSlot) {
								gold -= unitCost;
								goldText.setText(gold.toString());
								// Create new unit for bench using the same constructor as the shop unit
								var newUnit = new slot.unitConstructor();
								// All units purchased from shop start at tier 1 (1 star) regardless of unit type
								newUnit.tier = 1;
								// Update star indicator to show tier 1
								if (newUnit.starIndicator) {
									newUnit.starIndicator.updateStars(1);
								}
								// Initialize grid position properties
								newUnit.gridX = -1;
								newUnit.gridY = -1;
								newUnit.lane = -1;
								bench.push(newUnit);
								game.addChild(newUnit);
								updateBenchDisplay();
								// Add bounce effect when unit is added to bench
								newUnit.scaleX = 0;
								newUnit.scaleY = 0;
								// Capture unit reference for animation
								var unitToAnimate = newUnit;
								var targetScale = unitToAnimate.baseScale || 1.3;
								tween(unitToAnimate, {
									scaleX: targetScale * 1.2,
									scaleY: targetScale * 1.2
								}, {
									duration: 200,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										tween(unitToAnimate, {
											scaleX: targetScale,
											scaleY: targetScale
										}, {
											duration: 150,
											easing: tween.easeIn
										});
									}
								});
								// Remove purchased unit from shop
								slot.unit.destroy();
								slot.unit = null;
								if (slot.tierText) {
									slot.tierText.destroy();
									slot.tierText = null;
								}
								if (slot.nameText) {
									slot.nameText.destroy();
									slot.nameText = null;
								}
								if (slot.infoButton) {
									slot.infoButton.destroy();
									slot.infoButton = null;
								}
								LK.getSound('purchase').play();
								// Check for upgrades after purchasing a unit
								checkAndUpgradeUnits();
							} else {
								// No bench space available - could add visual feedback here
							}
						}
						// Reset tap tracking after double-tap to prevent triple-tap
						lastTapTime = 0;
						lastTapX = 0;
						lastTapY = 0;
						break;
					} else {
						// Not a double-tap: just update last tap info for next potential double-tap
						lastTapTime = currentTime;
						lastTapX = x;
						lastTapY = y;
						break;
					}
				}
			}
		}
	}
};
game.update = function () {
	// Spawn enemies
	if (gameState === 'battle') {
		// Ensure health bars are visible for all enemies
		for (var i = 0; i < enemies.length; i++) {
			enemies[i].showHealthBar();
		}
		// Ensure health bars are visible for all units on the grid
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				var gridSlot = grid[y][x];
				if (gridSlot.unit) {
					gridSlot.unit.showHealthBar();
				}
			}
		}
		if (waveDelay <= 0) {
			if (enemiesSpawned < enemiesPerWave) {
				if (LK.ticks % 60 === 0) {
					spawnEnemy();
					enemiesSpawned++;
				}
			} else if (enemies.length === 0) {
				// Wave complete - move units to closest grid spots first
				moveUnitsToClosestGridSpots();
				// Update best wave in storage
				if (wave > (storage.bestWave || 0)) {
					storage.bestWave = wave;
				}
				// Transition to planning phase
				gameState = 'planning';
				wave++;
				enemiesPerWave = Math.min(5 + wave * 2, 30);
				waveText.setText('Wave: ' + wave);
				// Calculate interest: 1 gold per 10 saved, max 5
				var interest = Math.min(Math.floor(gold / 10), 5);
				var waveReward = 5 + interest;
				gold += waveReward;
				goldText.setText(gold.toString());
				// Check for unit upgrades when entering planning phase
				checkAndUpgradeUnits();
				// Switch to main menu music when no enemies remain (planning phase)
				LK.stopMusic();
				LK.playMusic('mainmenu_music');
				// Show reward message
				var rewardText = new Text2('Wave Complete! +' + waveReward + ' Gold (5 + ' + interest + ' interest)', {
					size: 96,
					fill: 0xFFD700
				});
				rewardText.anchor.set(0.5, 0.5);
				rewardText.x = 1024;
				rewardText.y = 800;
				game.addChild(rewardText);
				// Fade out reward text with longer duration
				tween(rewardText, {
					alpha: 0,
					y: 700
				}, {
					duration: 4000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						rewardText.destroy();
					}
				});
				// Refresh shop with new units after wave completion
				refreshShop();
				showReadyButton(); // Show button for next wave
				updateStateIndicator(); // Update UI to show planning phase
			}
		} else {
			waveDelay--;
		}
		// Castle health bar is now handled as a regular unit
	}
	// Update enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		enemy.update();
		// Castle is now a regular unit on the grid, no special handling needed
		enemy.updateHealthBar();
		enemy.showHealthBar(); // Ensure health bar is shown during battle
	}
	// Update unit counts in case any units were destroyed
	countUnitsOnField();
	// Clean up reservations and position tracking for destroyed entities
	var keysToRemove = [];
	for (var key in cellReservations) {
		var entity = cellReservations[key];
		if (!entity.parent) {
			keysToRemove.push(key);
		}
	}
	for (var i = 0; i < keysToRemove.length; i++) {
		delete cellReservations[keysToRemove[i]];
	}
	// Clean up position tracking for destroyed entities
	var posKeysToRemove = [];
	for (var posKey in entityPositions) {
		var entity = entityPositions[posKey];
		if (!entity.parent) {
			posKeysToRemove.push(posKey);
		}
	}
	for (var i = 0; i < posKeysToRemove.length; i++) {
		delete entityPositions[posKeysToRemove[i]];
	}
	// Update units
	var unitsToUpdate = [];
	for (var y = 0; y < GRID_ROWS; y++) {
		for (var x = 0; x < GRID_COLS; x++) {
			var gridSlot = grid[y][x];
			if (gridSlot.unit) {
				unitsToUpdate.push(gridSlot.unit);
			}
		}
	}
	// Process all units in a single loop
	for (var i = 0; i < unitsToUpdate.length; i++) {
		var unit = unitsToUpdate[i];
		unit.update();
		if (gameState === 'battle') {
			unit.showHealthBar(); // Ensure health bar is shown during battle
			unit.updateHealthBar();
			unit.showStarIndicator(); // Ensure star indicator is shown during battle
		} else {
			// Hide health bars during planning phase
			if (unit.healthBar) {
				unit.healthBar.visible = false;
			}
			// Show star indicators during planning phase for easy tier identification
			unit.showStarIndicator();
		}
		// Update king info button position if this is the king
		if (unit.name === 'King' && kingInfoButton) {
			kingInfoButton.x = unit.x;
			kingInfoButton.y = unit.y + 100; // Position below king
		}
	}
	// Unit shooting (only during battle)
	if (gameState === 'battle') {
		for (var y = 0; y < GRID_ROWS; y++) {
			for (var x = 0; x < GRID_COLS; x++) {
				var gridSlot = grid[y][x];
				if (gridSlot.unit) {
					var target = gridSlot.unit.findTarget();
					if (target) {
						var bullet = gridSlot.unit.shoot(target);
						if (bullet) {
							bullets.push(bullet);
							game.addChild(bullet);
							LK.getSound('shoot').play();
						} else if (gridSlot.unit.range <= 100) {
							// Melee attack sound effect (no bullet created)
							if (gridSlot.unit.canShoot()) {
								LK.getSound('shoot').play();
							}
						}
					}
				}
			}
		}
	}
	// Update bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		if (bullet && bullet.update) {
			bullet.update();
		}
		if (!bullet.parent) {
			bullets.splice(i, 1);
		}
	}
	// Update enemy projectiles
	for (var i = enemyProjectiles.length - 1; i >= 0; i--) {
		var projectile = enemyProjectiles[i];
		if (projectile && projectile.update) {
			projectile.update();
		}
		if (!projectile.parent) {
			enemyProjectiles.splice(i, 1);
		}
	}
	// Update level up cost text
	levelUpCostText.setText('Cost: ' + getLevelUpCost(playerLevel) + 'g');
	// Check win condition
	if (wave >= 10 && enemies.length === 0 && enemiesSpawned >= enemiesPerWave) {
		LK.showYouWin();
	}
};