/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var AreaDamageBullet = Container.expand(function (startX, startY, target, damage, isFromPlayer, areaRadius) {
	var self = Container.call(this);
	self.x = startX;
	self.y = startY;
	self.target = target;
	self.damage = damage;
	self.speed = 6;
	self.isFromPlayer = isFromPlayer;
	self.areaRadius = areaRadius || 100; // Default area damage radius
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bulletGraphics.tint = isFromPlayer ? 0xFF9800 : 0xFF5722; // Orange tint for area damage bullets
	bulletGraphics.scaleX = 1.3;
	bulletGraphics.scaleY = 1.3;
	self.update = function () {
		if (!self.target || self.target.isDead) {
			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 < 30) {
			// Apply direct damage to the target first
			self.target.takeDamage(self.damage);
			// Then area damage explosion
			self.explode();
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
	};
	self.explode = function () {
		// Visual explosion effect (removed screen flash to prevent bugs)
		LK.getSound('explosion').play();
		// Create visual circle around the hit target
		var explosionCircle = LK.getAsset('bullet', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 13,
			scaleY: 13
		});
		explosionCircle.x = self.target.x;
		explosionCircle.y = self.target.y;
		explosionCircle.tint = 0xFF9800;
		explosionCircle.alpha = 0.6;
		game.addChild(explosionCircle);
		// Animate the circle to fade out
		tween(explosionCircle, {
			alpha: 0,
			scaleX: 15,
			scaleY: 15
		}, {
			duration: 500,
			onFinish: function onFinish() {
				explosionCircle.destroy();
			}
		});
		// Get all possible targets for area damage
		var allTargets = [];
		if (self.isFromPlayer) {
			allTargets = allTargets.concat(enemyUnits, enemyTowers);
		} else {
			allTargets = allTargets.concat(playerUnits, playerTowers);
		}
		// Apply damage to all units within area radius (100 units as requested)
		for (var i = 0; i < allTargets.length; i++) {
			var targetUnit = allTargets[i];
			if (!targetUnit.isDead && targetUnit !== self.target) {
				// Exclude the initial target from area damage
				var distance = Math.sqrt(Math.pow(self.target.x - targetUnit.x, 2) + Math.pow(self.target.y - targetUnit.y, 2));
				if (distance <= 100) {
					targetUnit.takeDamage(140);
					// Flash each affected unit
					tween(targetUnit, {
						tint: 0xFF9800
					}, {
						duration: 300,
						onFinish: function onFinish() {
							tween(targetUnit, {
								tint: 0xFFFFFF
							}, {
								duration: 200
							});
						}
					});
				}
			}
		}
	};
	return self;
});
var Bullet = Container.expand(function (startX, startY, target, damage, isFromPlayer) {
	var self = Container.call(this);
	self.x = startX;
	self.y = startY;
	self.target = target;
	self.damage = damage;
	self.speed = 8;
	self.isFromPlayer = isFromPlayer;
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bulletGraphics.tint = isFromPlayer ? 0x4CAF50 : 0xF44336;
	self.update = function () {
		if (!self.target || self.target.isDead) {
			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 < 20) {
			self.target.takeDamage(self.damage);
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
	};
	return self;
});
var Cannon = Container.expand(function (isPlayer) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = 'cannon';
	self.maxHealth = 600;
	self.currentHealth = 600;
	self.isDead = false;
	self.damage = 90;
	self.range = 500;
	self.attackSpeed = 50;
	self.lastAttackTime = 0;
	self.target = null;
	self.isAttacking = false;
	// Spawn delay properties
	self.spawnDelay = 60; // 1 second
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var cannonGraphics = self.attachAsset('cannon', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.25,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.25,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = 0.25;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false;
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return;
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Find closest enemy units first
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				// Cannon cannot attack aerial units
				if (targetUnits[i].isAerial) {
					continue;
				}
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		self.target = closestTarget;
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		if (distance <= self.range && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			self.isAttacking = true;
			var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't attack while stunned
		}
		// Lose 3% of total health per second (60 ticks = 1 second)
		if (LK.ticks % 20 === 0) {
			// Every 20 ticks = 3 times per second = 1% each time = 3% per second
			self.currentHealth -= self.maxHealth * 0.01;
			if (self.currentHealth <= 0) {
				self.currentHealth = 0;
				self.isDead = true;
			}
			// Update health bar without flash effect for natural decay
			var healthPercent = self.currentHealth / self.maxHealth;
			self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		}
		self.findTarget();
		self.attack();
	};
	return self;
});
var Card = Container.expand(function (cardType) {
	var self = Container.call(this);
	self.cardType = cardType;
	self.cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
	var cardBg = self.attachAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var cardIcon = LK.getAsset(cardType === 'discharge' ? 'descarga_descardina' : cardType, {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.8,
		scaleY: 0.8
	});
	self.addChild(cardIcon);
	var costText = new Text2(self.cost.toString(), {
		size: 30,
		fill: 0xFFFFFF
	});
	costText.anchor.set(0.5, 0.5);
	costText.x = 120;
	costText.y = -40;
	self.addChild(costText);
	return self;
});
var Discharge = Container.expand(function (targetX, targetY, isFromPlayer) {
	var self = Container.call(this);
	self.targetX = targetX;
	self.targetY = targetY;
	self.isFromPlayer = isFromPlayer;
	self.damage = 200;
	self.stunDuration = 60; // 1 second stun (60 ticks)
	// Discharge appears instantly at target location
	self.x = targetX;
	self.y = targetY;
	// Define explode method BEFORE calling it
	self.explode = function () {
		// Visual explosion effect - blue circle of 150 units radius
		var explosionCircle = LK.getAsset('dischargeExplosion', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 1.2,
			// Scale to make it 150 units radius (250 * 1.2 / 2 = 150)
			scaleY: 1.2
		});
		explosionCircle.x = self.targetX;
		explosionCircle.y = self.targetY;
		explosionCircle.tint = 0x0080FF; // Blue color
		explosionCircle.alpha = 0.9;
		game.addChild(explosionCircle);
		// Animate explosion
		tween(explosionCircle, {
			alpha: 0,
			scaleX: 1.8,
			scaleY: 1.8
		}, {
			duration: 800,
			onFinish: function onFinish() {
				explosionCircle.destroy();
			}
		});
		// Play explosion sound
		LK.getSound('explosion').play();
		// Get all possible targets for damage
		var allTargets = [];
		if (self.isFromPlayer) {
			allTargets = allTargets.concat(enemyUnits, enemyTowers);
		} else {
			allTargets = allTargets.concat(playerUnits, playerTowers);
		}
		// Apply damage and stun to all units within explosion radius of 150 units
		var explosionRadius = 150; // 150 units as requested
		for (var i = 0; i < allTargets.length; i++) {
			var targetUnit = allTargets[i];
			if (!targetUnit.isDead) {
				var distance = Math.sqrt(Math.pow(self.targetX - targetUnit.x, 2) + Math.pow(self.targetY - targetUnit.y, 2));
				if (distance <= explosionRadius) {
					// Apply 200 damage
					targetUnit.takeDamage(self.damage);
					// Apply stun effect (immobilize for 1 second)
					targetUnit.stunTimer = self.stunDuration;
					targetUnit.isStunned = true;
					// Visual effect for stunned units (blue tint)
					tween(targetUnit, {
						tint: 0x0080FF
					}, {
						duration: 1000,
						onFinish: function onFinish() {
							tween(targetUnit, {
								tint: 0xFFFFFF
							}, {
								duration: 200
							});
						}
					});
				}
			}
		}
		// Destroy discharge immediately after explosion
		self.destroy();
	};
	// Create instant explosion effect - NOW we can call explode since it's defined
	self.explode();
	return self;
});
var Fireball = Container.expand(function (targetX, targetY, isFromPlayer) {
	var self = Container.call(this);
	self.targetX = targetX;
	self.targetY = targetY;
	self.isFromPlayer = isFromPlayer;
	self.speed = 13;
	self.damage = 415;
	self.explosionRadius = 150;
	// Start from king tower position
	if (isFromPlayer) {
		self.x = 1024; // Player king tower x
		self.y = 2600; // Player king tower y
	} else {
		self.x = 1024; // Enemy king tower x
		self.y = 200; // Enemy king tower y
	}
	var fireballGraphics = self.attachAsset('fireball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	fireballGraphics.tint = 0xFF6600;
	self.update = function () {
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < 30) {
			// Explode at target location
			self.explode();
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
	};
	self.explode = function () {
		// Visual explosion effect
		var explosionCircle = LK.getAsset('fireballExplosion', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		explosionCircle.x = self.targetX;
		explosionCircle.y = self.targetY;
		explosionCircle.tint = 0xFF3300;
		explosionCircle.alpha = 0.8;
		game.addChild(explosionCircle);
		// Animate explosion
		tween(explosionCircle, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 1000,
			onFinish: function onFinish() {
				explosionCircle.destroy();
			}
		});
		// Play explosion sound
		LK.getSound('explosion').play();
		// Get all possible targets for damage
		var allTargets = [];
		if (self.isFromPlayer) {
			allTargets = allTargets.concat(enemyUnits, enemyTowers);
		} else {
			allTargets = allTargets.concat(playerUnits, playerTowers);
		}
		// Apply damage and knockback to all units within explosion radius
		for (var i = 0; i < allTargets.length; i++) {
			var targetUnit = allTargets[i];
			if (!targetUnit.isDead) {
				var distance = Math.sqrt(Math.pow(self.targetX - targetUnit.x, 2) + Math.pow(self.targetY - targetUnit.y, 2));
				if (distance <= self.explosionRadius) {
					// Check if target is a tower
					var isTower = false;
					if (self.isFromPlayer) {
						isTower = enemyTowers.indexOf(targetUnit) !== -1;
					} else {
						isTower = playerTowers.indexOf(targetUnit) !== -1;
					}
					// Apply damage - 50% less to towers
					var damageToApply = isTower ? self.damage * 0.5 : self.damage;
					targetUnit.takeDamage(damageToApply);
					// Apply knockback only to non-tower units
					if (!isTower) {
						var knockbackDistance = 100;
						var knockbackDx = targetUnit.x - self.targetX;
						var knockbackDy = targetUnit.y - self.targetY;
						var knockbackLength = Math.sqrt(knockbackDx * knockbackDx + knockbackDy * knockbackDy);
						if (knockbackLength > 0) {
							var normalizedDx = knockbackDx / knockbackLength;
							var normalizedDy = knockbackDy / knockbackLength;
							var newX = targetUnit.x + normalizedDx * knockbackDistance;
							var newY = targetUnit.y + normalizedDy * knockbackDistance;
							// Animate knockback
							tween(targetUnit, {
								x: newX,
								y: newY
							}, {
								duration: 300,
								easing: tween.easeOut
							});
						}
					}
					// Flash effect on hit units
					tween(targetUnit, {
						tint: 0xFF6600
					}, {
						duration: 300,
						onFinish: function onFinish() {
							tween(targetUnit, {
								tint: 0xFFFFFF
							}, {
								duration: 200
							});
						}
					});
				}
			}
		}
	};
	return self;
});
var MaquinaVoladora = Container.expand(function (isPlayer) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = 'maquinaVoladora';
	self.isAerial = true; // Mark as aerial unit
	self.maxHealth = 500;
	self.currentHealth = 500;
	self.damage = 85;
	self.attackSpeed = 90; // 90 ticks
	self.range = 500; // Detection range
	self.attackRange = 475; // Attack range
	self.speed = 1.5;
	self.target = null;
	self.lastAttackTime = 0;
	self.isDead = false;
	self.isAttacking = false;
	// Spawn delay properties
	self.spawnDelay = 60; // 1 second
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var maquinaGraphics = self.attachAsset('flying_machine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarScale = 0.2;
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = healthBarScale;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false;
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return;
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Find closest enemy units first
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		// Find closest enemy towers if no units in range
		if (!closestTarget) {
			var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
			for (var i = 0; i < targetTowers.length; i++) {
				if (!targetTowers[i].isDead) {
					var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
					if (distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetTowers[i];
					}
				}
			}
		}
		self.target = closestTarget;
	};
	self.moveToTarget = function () {
		if (!self.target || self.target.isDead) {
			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 > self.attackRange) {
			var moveX = dx / distance * self.speed;
			var moveY = dy / distance * self.speed;
			self.x += moveX;
			self.y += moveY;
		}
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		if (distance <= self.attackRange && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			self.isAttacking = true;
			// Create purple bullet
			var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
			bullet.children[0].tint = 0x9C27B0; // Purple color
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't move or attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't move or attack while stunned
		}
		self.findTarget();
		self.moveToTarget();
		self.attack();
	};
	return self;
});
var Megaesbirro = Container.expand(function (isPlayer) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = 'megaesbirro';
	self.isAerial = true; // Mark as aerial unit
	self.maxHealth = 625; // 500 + 125
	self.currentHealth = 625;
	self.damage = 120; // 85 + 35
	self.attackSpeed = 90; // 90 ticks
	self.range = 500; // Detection range
	self.attackRange = 150; // Attack range
	self.speed = 1.75;
	self.target = null;
	self.lastAttackTime = 0;
	self.isDead = false;
	self.isAttacking = false;
	// Spawn delay properties
	self.spawnDelay = 60; // 1 second
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var megaesbirroGraphics = self.attachAsset('megaesbirro', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarScale = 0.2;
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = healthBarScale;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false;
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return;
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Find closest enemy units first
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		// Find closest enemy towers if no units in range
		if (!closestTarget) {
			var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
			for (var i = 0; i < targetTowers.length; i++) {
				if (!targetTowers[i].isDead) {
					var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
					if (distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetTowers[i];
					}
				}
			}
		}
		self.target = closestTarget;
	};
	self.moveToTarget = function () {
		if (!self.target || self.target.isDead) {
			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 > self.attackRange) {
			var moveX = dx / distance * self.speed;
			var moveY = dy / distance * self.speed;
			self.x += moveX;
			self.y += moveY;
		}
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		if (distance <= self.attackRange && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			self.isAttacking = true;
			// Create purple bullet
			var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
			bullet.children[0].tint = 0x9C27B0; // Purple color
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't move or attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't move or attack while stunned
		}
		self.findTarget();
		self.moveToTarget();
		self.attack();
	};
	return self;
});
var Minion = Container.expand(function (isPlayer) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = 'minion';
	self.isAerial = true; // Mark as aerial unit
	self.maxHealth = 400;
	self.currentHealth = 400;
	self.damage = 85;
	self.attackSpeed = 90; // 90 ticks
	self.range = 500; // Detection range
	self.attackRange = 150; // Attack range
	self.speed = 1.75;
	self.target = null;
	self.lastAttackTime = 0;
	self.isDead = false;
	self.isAttacking = false;
	// Spawn delay properties
	self.spawnDelay = 60; // 1 second
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var minionGraphics = self.attachAsset('minion', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarScale = 0.2;
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = healthBarScale;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false;
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return;
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Find closest enemy units first
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		// Find closest enemy towers if no units in range
		if (!closestTarget) {
			var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
			for (var i = 0; i < targetTowers.length; i++) {
				if (!targetTowers[i].isDead) {
					var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
					if (distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetTowers[i];
					}
				}
			}
		}
		self.target = closestTarget;
	};
	self.moveToTarget = function () {
		if (!self.target || self.target.isDead) {
			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 > self.attackRange) {
			var moveX = dx / distance * self.speed;
			var moveY = dy / distance * self.speed;
			self.x += moveX;
			self.y += moveY;
		}
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		if (distance <= self.attackRange && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			self.isAttacking = true;
			// Create purple bullet
			var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
			bullet.children[0].tint = 0x9C27B0; // Purple color
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't move or attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't move or attack while stunned
		}
		self.findTarget();
		self.moveToTarget();
		self.attack();
	};
	return self;
});
var Tower = Container.expand(function (isPlayer, isKing) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.isKing = isKing;
	self.maxHealth = isKing ? 3700 : 2400;
	self.currentHealth = self.maxHealth;
	self.isDead = false;
	self.range = 800;
	self.damage = 75;
	self.attackSpeed = 67; // 50% slower than 45 ticks (45 * 1.5 = 67.5, rounded to 67)
	self.lastAttackTime = 0;
	var towerGraphics = self.attachAsset(isKing ? 'kingTower' : 'tower', {
		anchorX: 0.5,
		anchorY: 1
	});
	towerGraphics.tint = self.isPlayer ? 0x4CAF50 : 0xF44336;
	// Health display
	var healthText = new Text2(self.currentHealth.toString(), {
		size: 40,
		fill: 0xFFFFFF
	});
	healthText.anchor.set(0.5, 0.5);
	healthText.y = -75;
	self.addChild(healthText);
	self.healthText = healthText;
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
			towersDestroyed++;
			LK.effects.flashObject(self, 0xFF0000, 1000);
			LK.getSound('towerDestroy').play();
			if (self.isPlayer) {
				enemyTowersDestroyed++;
			} else {
				playerTowersDestroyed++;
			}
		}
		self.healthText.setText(self.currentHealth.toString());
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.attack = function () {
		if (self.isDead) {
			return;
		}
		// King towers cannot attack until at least one Princess tower is destroyed
		if (self.isKing) {
			var teamTowers = self.isPlayer ? playerTowers : enemyTowers;
			var princessTowersAlive = 0;
			for (var i = 0; i < teamTowers.length; i++) {
				if (!teamTowers[i].isKing && !teamTowers[i].isDead) {
					princessTowersAlive++;
				}
			}
			if (princessTowersAlive === 2) {
				return; // King tower cannot attack while both Princess towers are alive
			}
		}
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		var closestTarget = null;
		var closestDistance = Infinity;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		if (closestTarget && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			var bullet = new Bullet(self.x, self.y - 50, closestTarget, self.damage, self.isPlayer);
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		self.attack();
	};
	return self;
});
var Unit = Container.expand(function (isPlayer, unitType, health, damage, attackSpeed, range, speed) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = unitType;
	self.maxHealth = health;
	self.currentHealth = health;
	self.damage = damage;
	self.attackSpeed = attackSpeed;
	self.range = range;
	self.speed = speed;
	self.target = null;
	self.lastAttackTime = 0;
	self.isDead = false;
	self.isAttacking = false; // Track if unit has started attacking current target
	// Spawn delay properties
	self.spawnDelay = unitType === 'giant' ? 180 : 60; // 3 seconds for giant, 1 second for others (60 ticks = 1 second)
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var unitGraphics = self.attachAsset(unitType, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarScale = unitType === 'giant' ? 0.4 : 0.2;
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = healthBarScale;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false; // Reset attacking state when target dies
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return; // Keep current target while attacking
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Giant (wincondition unit) targets structures within detection range, then towers
		if (self.unitType === 'giant') {
			// First check for structures (cannons) within detection range (538)
			var targetStructures = self.isPlayer ? enemyUnits : playerUnits;
			for (var i = 0; i < targetStructures.length; i++) {
				if (!targetStructures[i].isDead && targetStructures[i].unitType === 'cannon') {
					var distance = Math.sqrt(Math.pow(self.x - targetStructures[i].x, 2) + Math.pow(self.y - targetStructures[i].y, 2));
					if (distance <= 538 && distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetStructures[i];
					}
				}
			}
			// If no structures in detection range, target closest tower
			if (!closestTarget) {
				var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
				for (var i = 0; i < targetTowers.length; i++) {
					if (!targetTowers[i].isDead) {
						var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
						if (distance < closestDistance) {
							closestDistance = distance;
							closestTarget = targetTowers[i];
						}
					}
				}
			}
		} else {
			// Normal units: First priority - Find closest enemy units and structures (they are more immediate threats)
			var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
			for (var i = 0; i < targetUnits.length; i++) {
				if (!targetUnits[i].isDead) {
					// Skip aerial units if this unit cannot attack air (only archers and towers can attack air)
					if (targetUnits[i].isAerial && self.unitType !== 'archer') {
						continue;
					}
					var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
					if (distance <= self.range && distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetUnits[i];
					}
				}
			}
			// Second priority: Find closest enemy towers if no units in range
			if (!closestTarget) {
				var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
				for (var i = 0; i < targetTowers.length; i++) {
					if (!targetTowers[i].isDead) {
						var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
						if (distance < closestDistance) {
							closestDistance = distance;
							closestTarget = targetTowers[i];
						}
					}
				}
			}
		}
		self.target = closestTarget;
	};
	self.moveToTarget = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		var dx = self.target.x - self.x;
		var dy = self.target.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Use proper attack range for movement positioning
		var attackRange = self.attackRange || (self.unitType === 'knight' ? 168 : self.unitType === 'giant' ? 60 : self.range);
		if (distance > attackRange) {
			var moveX = dx / distance * self.speed;
			var moveY = dy / distance * self.speed;
			self.x += moveX;
			self.y += moveY;
		}
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		// Use different ranges for detection vs attack
		var attackRange = self.attackRange || (self.unitType === 'knight' ? 168 : self.unitType === 'giant' ? 60 : self.range); // Use attackRange property if defined, otherwise use unit-specific ranges
		if (distance <= attackRange && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			// Set attacking flag when first attack begins
			self.isAttacking = true;
			// Knight, Giant, and Skeleton use melee attack - direct damage without bullet
			if (self.unitType === 'knight' || self.unitType === 'giant' || self.unitType === 'skeleton') {
				self.target.takeDamage(self.damage);
				// Visual effect for melee strike
				LK.effects.flashObject(self, 0xFFFFFF, 200);
				// Flash target red when hit by Giant
				if (self.unitType === 'giant') {
					tween(self.target, {
						tint: 0xFF0000
					}, {
						duration: 200,
						onFinish: function onFinish() {
							tween(self.target, {
								tint: 0xFFFFFF
							}, {
								duration: 100
							});
						}
					});
				}
				// Knight and Skeleton no longer apply knockback to units
			} else {
				// Other units (like archers, wizard) still use bullets
				var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
				bullets.push(bullet);
				game.addChild(bullet);
			}
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't move or attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't move or attack while stunned
		}
		// Always find targets every frame to ensure units never ignore enemies
		self.findTarget();
		self.moveToTarget();
		self.attack();
	};
	return self;
});
var Wizard = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'wizard', 550, 140, 100, 530, 1.25);
	// Override the attack function to use area damage
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		// Wizard uses ranged attack with area damage projectile (use detection range for attacking)
		if (distance <= self.range && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			// Set attacking flag when first attack begins
			self.isAttacking = true;
			// Create area damage bullet with 100 unit area radius
			var areaBullet = new AreaDamageBullet(self.x, self.y, self.target, self.damage, self.isPlayer, 100);
			bullets.push(areaBullet);
			game.addChild(areaBullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	return self;
});
var Skeleton = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'skeleton', 25, 45, 60, 500, 2);
	// Skeleton: 25 HP, 45 damage, 60 tick attack speed, 500 detection range, speed 2
	// Attacks ground units and structures only (same targeting as other units)
	// Override attack range to be 150 instead of detection range
	self.attackRange = 150;
	return self;
});
var Knight = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'knight', 825, 160, 60, 538, 1.75);
	// Detection range set to 538 (same as archer for consistent detection)
	// Attack range remains at melee distance in attack function
	return self;
});
var Giant = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'giant', 4000, 175, 90, 538, 0.85);
	// Giant is a wincondition unit that only attacks structures and towers
	// Detection range set to 538 (same as archer), attack range remains at 60 in attack function
	return self;
});
var Archer = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'archer', 425, 75, 90, 538, 1.5);
	// Range reduced by 30% from 756 to 538 (25% + 5%)
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x228B22
});
/**** 
* Game Code
****/ 
// Game state variables
/*
CARD AND TOWER STATS:
TOWERS:
- Princess Towers: 2400 HP, 75 damage, attacks every 1.1s (67 ticks), range 800 units
- King Tower: 3700 HP, 75 damage, attacks every 1.1s (67 ticks), range 800 units
* King tower cannot attack until at least one Princess tower is destroyed
CARDS:
- Archers: 3 elixir cost, 425 HP each, 75 damage, attacks every 1.5s (90 ticks), range 567 units, speed 1.5
* Deploys 2 archers, can attack air and ground targets
- Knight: 3 elixir cost, 825 HP, 160 damage, attacks every 1s (60 ticks), range 168 units, speed 2
* Single melee unit, ground targets only
- Giant: 5 elixir cost, 4000 HP, 175 damage, attacks every 1.5s (90 ticks), range 300 units, speed 1
* Wincondition unit that only attacks structures and towers, ground unit
UNIT SPEEDS:
- Knight: speed 2 (medium)
- Archer: speed 1.5 (medium-slow)
- Giant: speed 1 (slow)
ELIXIR SYSTEM:
- Maximum: 10 elixir
- Regeneration: 1 elixir every 2.0 seconds (120 ticks at 60fps)
- Starting amount: 5 elixir
GAME RULES:
- Match duration: 2 minutes (120 seconds)
- Victory: Most towers destroyed wins
- Tiebreaker: Remaining tower health
- Draw: Equal towers destroyed and equal remaining health
*/
var gameStarted = false;
var gameTime = 120; // 2 minutes in seconds
var elixir = 5; // Starting elixir
var maxElixir = 10;
var elixirRegenRate = 120; // Ticks for 2.0 seconds at 60fps
var lastElixirRegen = 0;
var aiElixir = 5; // AI starting elixir
var aiMaxElixir = 10;
var aiElixirRegenRate = 120; // Ticks for 2 seconds at 60fps (faster than player)
var lastAiElixirRegen = 0;
var playerUnits = [];
var enemyUnits = [];
var bullets = [];
var playerTowers = [];
var enemyTowers = [];
var playerTowersDestroyed = 0;
var enemyTowersDestroyed = 0;
var towersDestroyed = 0;
var gameEnded = false;
var aiLastDeploy = 0;
var aiDeployInterval = 240; // 4 seconds
// Card and UI variables
var draggedCard = null;
var menuElements = [];
var deckMenuElements = [];
var deckCards = [];
var archerCard, knightCard, giantCard, wizardCard, cannonCard;
var timerText, elixirText;
var battlefieldLine;
var showingDeckSelection = false;
var selectedDeck = ['archer', 'knight', 'giant', 'wizard', 'cannon']; // Default deck (minimum 5 cards)
var availableCards = ['archer', 'knight', 'giant', 'wizard', 'cannon', 'skeleton', 'skeletonArmy', 'fireball', 'minion', 'maquinaVoladora', 'megaesbirro', 'discharge'];
// Card system variables
var activeCards = []; // Currently displayed 4 cards
var cardQueue = []; // Queue of remaining cards
var maxActiveCards = 4;
// Create main menu
function createMenu() {
	// Title
	var titleText = new Text2('CLASH ROYALE', {
		size: 120,
		fill: 0xFFD700
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 1024;
	titleText.y = 800;
	game.addChild(titleText);
	menuElements.push(titleText);
	// Play button background
	var playButton = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 0.8,
		x: 1024,
		y: 1400
	});
	playButton.tint = 0x4CAF50;
	game.addChild(playButton);
	menuElements.push(playButton);
	// Play button text
	var playText = new Text2('JUGAR', {
		size: 80,
		fill: 0xFFFFFF
	});
	playText.anchor.set(0.5, 0.5);
	playText.x = 1024;
	playText.y = 1400;
	game.addChild(playText);
	menuElements.push(playText);
	// Mazo button background
	var mazoButton = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 0.8,
		x: 1024,
		y: 1600
	});
	mazoButton.tint = 0x9C27B0;
	game.addChild(mazoButton);
	menuElements.push(mazoButton);
	// Mazo button text
	var mazoText = new Text2('MAZO', {
		size: 80,
		fill: 0xFFFFFF
	});
	mazoText.anchor.set(0.5, 0.5);
	mazoText.x = 1024;
	mazoText.y = 1600;
	game.addChild(mazoText);
	menuElements.push(mazoText);
	// Instructions
	var instructionsText = new Text2('Arrastra las cartas al campo de batalla', {
		size: 40,
		fill: 0xFFFFFF
	});
	instructionsText.anchor.set(0.5, 0.5);
	instructionsText.x = 1024;
	instructionsText.y = 1800;
	game.addChild(instructionsText);
	menuElements.push(instructionsText);
	// Make play button clickable
	playButton.down = function (x, y, obj) {
		startGame();
	};
	playText.down = function (x, y, obj) {
		startGame();
	};
	// Make mazo button clickable
	mazoButton.down = function (x, y, obj) {
		showDeckSelection();
	};
	mazoText.down = function (x, y, obj) {
		showDeckSelection();
	};
}
function showDeckSelection() {
	// Hide main menu
	for (var i = 0; i < menuElements.length; i++) {
		menuElements[i].alpha = 0.3;
	}
	showingDeckSelection = true;
	createDeckMenu();
}
function createDeckMenu() {
	// Title
	var deckTitle = new Text2('SELECCIONA TU MAZO', {
		size: 80,
		fill: 0xFFD700
	});
	deckTitle.anchor.set(0.5, 0.5);
	deckTitle.x = 1024;
	deckTitle.y = 600;
	game.addChild(deckTitle);
	deckMenuElements.push(deckTitle);
	// Instructions
	var instructions = new Text2('Toca las cartas para añadir/quitar del mazo (min 5, max 8)', {
		size: 35,
		fill: 0xFFFFFF
	});
	instructions.anchor.set(0.5, 0.5);
	instructions.x = 1024;
	instructions.y = 700;
	game.addChild(instructions);
	deckMenuElements.push(instructions);
	// Available cards display
	var cardStartX = 300;
	var cardSpacing = 350;
	for (var i = 0; i < availableCards.length; i++) {
		var cardType = availableCards[i];
		var cardContainer = new Container();
		cardContainer.x = cardStartX + i * cardSpacing;
		// Position skeleton card 100px below archer, skeleton army 100px below knight, fireball 100px below giant, minion 100px below wizard, maquina voladora 100px below skeleton, discharge 100px below cannon
		if (cardType === 'skeleton') {
			var archerIndex = availableCards.indexOf('archer');
			cardContainer.x = cardStartX + archerIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below archer
		} else if (cardType === 'skeletonArmy') {
			var knightIndex = availableCards.indexOf('knight');
			cardContainer.x = cardStartX + knightIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below knight
		} else if (cardType === 'fireball') {
			var giantIndex = availableCards.indexOf('giant');
			cardContainer.x = cardStartX + giantIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below giant
		} else if (cardType === 'minion') {
			var wizardIndex = availableCards.indexOf('wizard');
			cardContainer.x = cardStartX + wizardIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below wizard
		} else if (cardType === 'maquinaVoladora') {
			var skeletonIndex = availableCards.indexOf('skeleton');
			var archerIndex = availableCards.indexOf('archer');
			cardContainer.x = cardStartX + archerIndex * cardSpacing;
			cardContainer.y = 1100; // 100px below skeleton (200px total below archer)
		} else if (cardType === 'megaesbirro') {
			var skeletonArmyIndex = availableCards.indexOf('skeletonArmy');
			var knightIndex = availableCards.indexOf('knight');
			cardContainer.x = cardStartX + knightIndex * cardSpacing;
			cardContainer.y = 1100; // 100px below skeleton army (200px total below knight)
		} else if (cardType === 'discharge') {
			var cannonIndex = availableCards.indexOf('cannon');
			cardContainer.x = cardStartX + cannonIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below cannon
		} else {
			cardContainer.y = 900;
		}
		// Card background
		var cardBg = cardContainer.attachAsset('cardSlot', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		// Check if card is in selected deck
		var isSelected = selectedDeck.indexOf(cardType) !== -1;
		cardBg.tint = isSelected ? 0x4CAF50 : 0x607d8b;
		// Card icon
		var cardIcon = LK.getAsset(cardType === 'discharge' ? 'descarga_descardina' : cardType, {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.6,
			scaleY: 0.6
		});
		cardContainer.addChild(cardIcon);
		// Card cost
		var cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
		var costText = new Text2(cost.toString(), {
			size: 25,
			fill: 0xFFFFFF
		});
		costText.anchor.set(0.5, 0.5);
		costText.x = 120;
		costText.y = -40;
		cardContainer.addChild(costText);
		// Selection indicator
		if (isSelected) {
			var checkmark = new Text2('✓', {
				size: 40,
				fill: 0xFFFFFF
			});
			checkmark.anchor.set(0.5, 0.5);
			checkmark.x = 0;
			checkmark.y = 80;
			cardContainer.addChild(checkmark);
		}
		// Make card clickable
		cardContainer.cardType = cardType;
		cardContainer.down = function (x, y, obj) {
			toggleCardInDeck(this.cardType);
		};
		game.addChild(cardContainer);
		deckMenuElements.push(cardContainer);
	}
	// Selected deck display
	var deckTitle2 = new Text2('MAZO ACTUAL (' + selectedDeck.length + '/8)', {
		size: 60,
		fill: 0x4CAF50
	});
	deckTitle2.anchor.set(0.5, 0.5);
	deckTitle2.x = 1024;
	deckTitle2.y = 1200;
	game.addChild(deckTitle2);
	deckMenuElements.push(deckTitle2);
	// Display selected cards
	var selectedStartX = 424;
	var selectedSpacing = 240;
	for (var i = 0; i < selectedDeck.length && i < 8; i++) {
		var cardType = selectedDeck[i];
		var selectedCardContainer = new Container();
		selectedCardContainer.x = selectedStartX + i * selectedSpacing;
		selectedCardContainer.y = 1400;
		// Small card background
		var selectedCardBg = selectedCardContainer.attachAsset('cardSlot', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.7,
			scaleY: 0.7
		});
		selectedCardBg.tint = 0x2196F3;
		// Small card icon
		var selectedCardIcon = LK.getAsset(cardType, {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.4,
			scaleY: 0.4
		});
		selectedCardContainer.addChild(selectedCardIcon);
		game.addChild(selectedCardContainer);
		deckMenuElements.push(selectedCardContainer);
	}
	// Back button
	var backButton = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.2,
		scaleY: 0.6,
		x: 1024,
		y: 1650
	});
	backButton.tint = 0xFF9800;
	game.addChild(backButton);
	deckMenuElements.push(backButton);
	var backText = new Text2('VOLVER', {
		size: 50,
		fill: 0xFFFFFF
	});
	backText.anchor.set(0.5, 0.5);
	backText.x = 1024;
	backText.y = 1650;
	game.addChild(backText);
	deckMenuElements.push(backText);
	// Make back button clickable
	backButton.down = function (x, y, obj) {
		hideDeckSelection();
	};
	backText.down = function (x, y, obj) {
		hideDeckSelection();
	};
}
function toggleCardInDeck(cardType) {
	var cardIndex = selectedDeck.indexOf(cardType);
	if (cardIndex !== -1) {
		// Only allow removal if deck has more than 5 cards
		if (selectedDeck.length > 5) {
			selectedDeck.splice(cardIndex, 1);
		}
	} else if (selectedDeck.length < 8) {
		// Add card to deck if not full (max 8 cards)
		selectedDeck.push(cardType);
	}
	// Refresh deck menu
	refreshDeckMenu();
}
function refreshDeckMenu() {
	// Remove current deck menu elements
	for (var i = 0; i < deckMenuElements.length; i++) {
		deckMenuElements[i].destroy();
	}
	deckMenuElements = [];
	// Recreate deck menu
	createDeckMenu();
}
function hideDeckSelection() {
	// Remove deck menu elements
	for (var i = 0; i < deckMenuElements.length; i++) {
		deckMenuElements[i].destroy();
	}
	deckMenuElements = [];
	// Show main menu again
	for (var i = 0; i < menuElements.length; i++) {
		menuElements[i].alpha = 1;
	}
	showingDeckSelection = false;
}
function startGame() {
	// Remove menu elements
	for (var i = 0; i < menuElements.length; i++) {
		menuElements[i].destroy();
	}
	menuElements = [];
	// Start the actual game
	gameStarted = true;
	initializeGame();
}
function initializeGame() {
	// Generate AI's randomized deck for this match
	generateAIDeck();
	// Create battlefield divider
	battlefieldLine = game.addChild(LK.getAsset('battlefield', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1366
	}));
	battlefieldLine.tint = 0x000000;
	battlefieldLine.alpha = 0.3;
	// Create towers
	// Player towers (bottom)
	var playerLeftTower = game.addChild(new Tower(true, false));
	playerLeftTower.x = 512;
	playerLeftTower.y = 2400;
	playerTowers.push(playerLeftTower);
	var playerRightTower = game.addChild(new Tower(true, false));
	playerRightTower.x = 1536;
	playerRightTower.y = 2400;
	playerTowers.push(playerRightTower);
	var playerKingTower = game.addChild(new Tower(true, true));
	playerKingTower.x = 1024;
	playerKingTower.y = 2600;
	playerTowers.push(playerKingTower);
	// Enemy towers (top)
	var enemyLeftTower = game.addChild(new Tower(false, false));
	enemyLeftTower.x = 512;
	enemyLeftTower.y = 400;
	enemyTowers.push(enemyLeftTower);
	var enemyRightTower = game.addChild(new Tower(false, false));
	enemyRightTower.x = 1536;
	enemyRightTower.y = 400;
	enemyTowers.push(enemyRightTower);
	var enemyKingTower = game.addChild(new Tower(false, true));
	enemyKingTower.x = 1024;
	enemyKingTower.y = 200;
	enemyTowers.push(enemyKingTower);
	// UI Elements
	timerText = new Text2(gameTime.toString(), {
		size: 60,
		fill: 0xFFFFFF
	});
	timerText.anchor.set(0.5, 0);
	LK.gui.top.addChild(timerText);
	elixirText = new Text2(elixir + "/" + maxElixir, {
		size: 40,
		fill: 0xE91E63
	});
	elixirText.anchor.set(0, 1);
	elixirText.x = 50;
	LK.gui.bottomLeft.addChild(elixirText);
	// Initialize card system
	activeCards = [];
	cardQueue = [];
	deckCards = [];
	// Setup active cards (first 4) and queue (remaining)
	for (var i = 0; i < selectedDeck.length; i++) {
		if (i < maxActiveCards) {
			activeCards.push(selectedDeck[i]);
		} else {
			cardQueue.push(selectedDeck[i]);
		}
	}
	// Create visual cards for active cards only
	var cardSpacing = 300;
	var startX = -(maxActiveCards - 1) * cardSpacing / 2;
	for (var i = 0; i < activeCards.length; i++) {
		var cardType = activeCards[i];
		var newCard = LK.gui.bottom.addChild(new Card(cardType));
		newCard.x = startX + i * cardSpacing;
		newCard.y = -100;
		newCard.cardType = cardType; // Store card type for event handling
		newCard.cardIndex = i; // Store index for replacement
		deckCards.push(newCard);
	}
	// Store references for backward compatibility
	if (activeCards.indexOf('archer') !== -1) {
		archerCard = deckCards[activeCards.indexOf('archer')];
	}
	if (activeCards.indexOf('knight') !== -1) {
		knightCard = deckCards[activeCards.indexOf('knight')];
	}
	if (activeCards.indexOf('giant') !== -1) {
		giantCard = deckCards[activeCards.indexOf('giant')];
	}
	if (activeCards.indexOf('wizard') !== -1) {
		wizardCard = deckCards[activeCards.indexOf('wizard')];
	}
	if (activeCards.indexOf('cannon') !== -1) {
		cannonCard = deckCards[activeCards.indexOf('cannon')];
	}
	// Setup event handlers
	setupEventHandlers();
}
function rotateCard(usedCardIndex) {
	if (cardQueue.length === 0) {
		return;
	} // No cards in queue to rotate
	// Get the next card from queue
	var nextCard = cardQueue.shift(); // Remove first card from queue
	var usedCard = activeCards[usedCardIndex]; // Get the used card
	// Add used card to end of queue
	cardQueue.push(usedCard);
	// Replace active card with next card
	activeCards[usedCardIndex] = nextCard;
	// Update visual card
	var cardToUpdate = deckCards[usedCardIndex];
	if (cardToUpdate) {
		// Store position and index
		var cardX = cardToUpdate.x;
		var cardY = cardToUpdate.y;
		var cardIndex = cardToUpdate.cardIndex;
		// Remove old card
		cardToUpdate.destroy();
		// Create new card with next card type
		var newCard = LK.gui.bottom.addChild(new Card(nextCard));
		newCard.x = cardX;
		newCard.y = cardY;
		newCard.cardType = nextCard;
		newCard.cardIndex = cardIndex;
		// Update references
		deckCards[usedCardIndex] = newCard;
		// Update event handler for new card
		var cardType = newCard.cardType;
		var cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
		newCard.down = function (x, y, obj) {
			if (elixir >= cost) {
				draggedCard = cardType;
			}
		};
	}
}
function deployUnit(cardType, x, y, isPlayer) {
	var cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
	if (isPlayer && elixir < cost) {
		return false;
	}
	if (!isPlayer && aiElixir < cost) {
		return false;
	} // AI also needs elixir
	// Check if position is in correct half (except for spells)
	if (cardType !== 'fireball') {
		if (isPlayer && y < 1366) {
			return false;
		} // Player can only deploy in bottom half
		if (!isPlayer && y > 1366) {
			return false;
		} // AI can only deploy in top half
	}
	var unit = null;
	if (cardType === 'archer') {
		// Deploy 2 archers
		var archer1 = new Archer(isPlayer);
		var archer2 = new Archer(isPlayer);
		archer1.x = x - 40; // Left archer
		archer1.y = y;
		archer2.x = x + 40; // Right archer
		archer2.y = y;
		if (isPlayer) {
			playerUnits.push(archer1);
			playerUnits.push(archer2);
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			enemyUnits.push(archer1);
			enemyUnits.push(archer2);
			aiElixir -= cost; // Deduct AI elixir
		}
		game.addChild(archer1);
		game.addChild(archer2);
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'knight') {
		unit = new Knight(isPlayer);
	} else if (cardType === 'giant') {
		unit = new Giant(isPlayer);
	} else if (cardType === 'wizard') {
		unit = new Wizard(isPlayer);
	} else if (cardType === 'skeleton') {
		// Deploy 3 skeletons in formation: front, back-right, back-left
		var skeleton1 = new Skeleton(isPlayer); // Front skeleton
		var skeleton2 = new Skeleton(isPlayer); // Back-right skeleton  
		var skeleton3 = new Skeleton(isPlayer); // Back-left skeleton
		skeleton1.x = x; // Front skeleton at deployment position
		skeleton1.y = y;
		skeleton2.x = x + 60; // Back-right skeleton
		skeleton2.y = isPlayer ? y + 60 : y - 60; // Adjust based on player side
		skeleton3.x = x - 60; // Back-left skeleton
		skeleton3.y = isPlayer ? y + 60 : y - 60; // Adjust based on player side
		if (isPlayer) {
			playerUnits.push(skeleton1);
			playerUnits.push(skeleton2);
			playerUnits.push(skeleton3);
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			enemyUnits.push(skeleton1);
			enemyUnits.push(skeleton2);
			enemyUnits.push(skeleton3);
			aiElixir -= cost; // Deduct AI elixir
		}
		game.addChild(skeleton1);
		game.addChild(skeleton2);
		game.addChild(skeleton3);
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'skeletonArmy') {
		// Deploy 12 skeletons in a 3x4 formation
		var skeletons = [];
		for (var row = 0; row < 3; row++) {
			for (var col = 0; col < 4; col++) {
				var skeleton = new Skeleton(isPlayer);
				skeleton.x = x + (col - 1.5) * 40; // Spread horizontally
				skeleton.y = y + (row - 1) * 40; // Spread vertically
				skeletons.push(skeleton);
				game.addChild(skeleton);
			}
		}
		if (isPlayer) {
			for (var s = 0; s < skeletons.length; s++) {
				playerUnits.push(skeletons[s]);
			}
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			for (var s = 0; s < skeletons.length; s++) {
				enemyUnits.push(skeletons[s]);
			}
			aiElixir -= cost; // Deduct AI elixir
		}
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'fireball') {
		// Fireball is a spell - can be deployed anywhere on the map
		var fireball = new Fireball(x, y, isPlayer);
		bullets.push(fireball); // Add to bullets array for cleanup
		game.addChild(fireball);
		if (isPlayer) {
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			aiElixir -= cost; // Deduct AI elixir
		}
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'discharge') {
		// Discharge is a spell - can be deployed anywhere on the map, appears instantly
		var discharge = new Discharge(x, y, isPlayer);
		// Don't add to bullets array since it destroys itself immediately
		game.addChild(discharge);
		if (isPlayer) {
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			aiElixir -= cost; // Deduct AI elixir
		}
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'minion') {
		// Deploy 3 minions in formation like skeletons: front, back-right, back-left
		var minion1 = new Minion(isPlayer); // Front minion
		var minion2 = new Minion(isPlayer); // Back-right minion
		var minion3 = new Minion(isPlayer); // Back-left minion
		minion1.x = x; // Front minion at deployment position
		minion1.y = y;
		minion2.x = x + 60; // Back-right minion
		minion2.y = isPlayer ? y + 60 : y - 60; // Adjust based on player side
		minion3.x = x - 60; // Back-left minion
		minion3.y = isPlayer ? y + 60 : y - 60; // Adjust based on player side
		if (isPlayer) {
			playerUnits.push(minion1);
			playerUnits.push(minion2);
			playerUnits.push(minion3);
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			enemyUnits.push(minion1);
			enemyUnits.push(minion2);
			enemyUnits.push(minion3);
			aiElixir -= cost; // Deduct AI elixir
		}
		game.addChild(minion1);
		game.addChild(minion2);
		game.addChild(minion3);
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'maquinaVoladora') {
		// Deploy single maquina voladora
		unit = new MaquinaVoladora(isPlayer);
	} else if (cardType === 'megaesbirro') {
		// Deploy single megaesbirro
		unit = new Megaesbirro(isPlayer);
	} else if (cardType === 'cannon') {
		unit = new Cannon(isPlayer);
	}
	if (unit) {
		unit.x = x;
		unit.y = y;
		if (isPlayer) {
			playerUnits.push(unit);
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			enemyUnits.push(unit);
			aiElixir -= cost; // Deduct AI elixir
		}
		game.addChild(unit);
		LK.getSound('deploy').play();
		return true;
	}
	return false;
}
// AI deployment variables
var aiLastUsedCard = null;
var aiCardCooldown = {};
var aiDeck = []; // AI's randomized deck for the match
// Generate AI deck with required constraints
function generateAIDeck() {
	aiDeck = [];
	// Required cards (must have)
	var requiredCards = {
		aerial: 'archer',
		// Card that can attack aerial units
		wincondition: 'giant',
		// Wincondition card
		spell: Math.random() < 0.5 ? 'fireball' : 'discharge',
		// Spell card (randomly choose between fireball and discharge)
		structure: 'cannon' // Structure card
	};
	// Add required cards to AI deck
	aiDeck.push(requiredCards.aerial);
	aiDeck.push(requiredCards.wincondition);
	aiDeck.push(requiredCards.spell);
	aiDeck.push(requiredCards.structure);
	// Remaining card pool (excluding already added required cards)
	var remainingCards = ['knight', 'wizard', 'skeleton', 'skeletonArmy', 'minion', 'maquinaVoladora', 'megaesbirro'];
	// Fill remaining 4 slots with random cards from remaining pool
	while (aiDeck.length < 8) {
		var randomIndex = Math.floor(Math.random() * remainingCards.length);
		var randomCard = remainingCards[randomIndex];
		aiDeck.push(randomCard);
		// Don't remove from remainingCards to allow duplicates
	}
	// Shuffle the deck to randomize order
	for (var i = aiDeck.length - 1; i > 0; i--) {
		var j = Math.floor(Math.random() * (i + 1));
		var temp = aiDeck[i];
		aiDeck[i] = aiDeck[j];
		aiDeck[j] = temp;
	}
}
// AI deployment function
function aiDeploy() {
	// Check if AI is being attacked (player units in AI territory)
	var isUnderAttack = false;
	var playerUnitsInAITerritory = 0;
	for (var i = 0; i < playerUnits.length; i++) {
		if (playerUnits[i].y < 1366) {
			// Player units in AI half
			isUnderAttack = true;
			playerUnitsInAITerritory++;
		}
	}
	// Check if AI towers are taking damage
	var aiTowersUnderAttack = false;
	for (var i = 0; i < enemyTowers.length; i++) {
		if (enemyTowers[i].currentHealth < enemyTowers[i].maxHealth) {
			aiTowersUnderAttack = true;
			break;
		}
	}
	if (isUnderAttack || aiTowersUnderAttack) {
		// DEFENSE MODE: Deploy defensive units quickly if being attacked
		if (LK.ticks - aiLastDeploy > 60 && aiElixir >= 3) {
			// Deploy faster when defending
			var defensiveCards = [];
			// Check if player has used wincondition (giant) or if towers are damaged
			var playerHasWincondition = false;
			for (var i = 0; i < playerUnits.length; i++) {
				if (playerUnits[i].unitType === 'giant') {
					playerHasWincondition = true;
					break;
				}
			}
			if (aiElixir >= 3) {
				// Use cards from AI's deck for defense
				for (var d = 0; d < aiDeck.length; d++) {
					var deckCard = aiDeck[d];
					var cardCost = deckCard === 'giant' ? 5 : deckCard === 'wizard' ? 5 : deckCard === 'skeleton' ? 1 : deckCard === 'skeletonArmy' ? 3 : deckCard === 'fireball' ? 4 : deckCard === 'discharge' ? 2 : deckCard === 'minion' ? 3 : deckCard === 'maquinaVoladora' ? 4 : deckCard === 'megaesbirro' ? 3 : 3;
					if (aiElixir >= cardCost) {
						// Add defensive units (not spells for defense)
						if (deckCard !== 'fireball' && deckCard !== 'discharge') {
							defensiveCards.push(deckCard);
						}
					}
				}
			}
			// Check for spell usage opportunities (discharge and fireball)
			var spellCards = [];
			for (var s = 0; s < aiDeck.length; s++) {
				var spellCard = aiDeck[s];
				if (spellCard === 'discharge' || spellCard === 'fireball') {
					var spellCost = spellCard === 'discharge' ? 2 : 4;
					if (aiElixir >= spellCost) {
						spellCards.push(spellCard);
					}
				}
			}
			if (spellCards.length > 0 && playerUnits.length > 0) {
				// Find player unit with most enemies nearby for spell targeting
				var bestTarget = null;
				var maxNearbyUnits = 0;
				for (var p = 0; p < playerUnits.length; p++) {
					var playerUnit = playerUnits[p];
					if (!playerUnit.isDead) {
						var nearbyCount = 0;
						// Count nearby player units
						for (var n = 0; n < playerUnits.length; n++) {
							var otherUnit = playerUnits[n];
							if (!otherUnit.isDead && otherUnit !== playerUnit) {
								var distance = Math.sqrt(Math.pow(playerUnit.x - otherUnit.x, 2) + Math.pow(playerUnit.y - otherUnit.y, 2));
								if (distance <= 200) {
									// Within spell effect range
									nearbyCount++;
								}
							}
						}
						if (nearbyCount > maxNearbyUnits) {
							maxNearbyUnits = nearbyCount;
							bestTarget = playerUnit;
						}
					}
				}
				// Use spell if we found a good target (at least 1 nearby unit or any unit if no clusters)
				if (bestTarget && (maxNearbyUnits > 0 || playerUnits.length > 0)) {
					var chosenSpell = spellCards[Math.floor(Math.random() * spellCards.length)];
					if (deployUnit(chosenSpell, bestTarget.x, bestTarget.y, false)) {
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 120 + Math.random() * 60;
						return; // Exit early after using spell
					}
				}
			}
			if (defensiveCards.length > 0) {
				var randomCard = defensiveCards[Math.floor(Math.random() * defensiveCards.length)];
				// Deploy near threatened area
				var deployX = 300 + Math.random() * 1448;
				var deployY = 800 + Math.random() * 400; // Deploy in middle-upper area
				if (deployUnit(randomCard, deployX, deployY, false)) {
					aiLastDeploy = LK.ticks;
					aiDeployInterval = 120 + Math.random() * 60; // Quick deploy interval when defending
				}
			}
		}
	} else {
		// ATTACK MODE: Use wincondition strategy when not under attack
		// Check for spell usage opportunities in attack mode
		if (aiElixir >= 2 && playerUnits.length > 0 && Math.random() < 0.3) {
			// 30% chance to use spells in attack
			var attackSpellCards = [];
			for (var s = 0; s < aiDeck.length; s++) {
				var spellCard = aiDeck[s];
				if (spellCard === 'discharge' || spellCard === 'fireball') {
					var spellCost = spellCard === 'discharge' ? 2 : 4;
					if (aiElixir >= spellCost) {
						attackSpellCards.push(spellCard);
					}
				}
			}
			if (attackSpellCards.length > 0) {
				// Target strongest or most clustered player units
				var bestAttackTarget = null;
				var maxValue = 0;
				for (var p = 0; p < playerUnits.length; p++) {
					var playerUnit = playerUnits[p];
					if (!playerUnit.isDead) {
						// Calculate value based on unit health + nearby units
						var unitValue = playerUnit.currentHealth;
						// Count nearby player units for cluster bonus
						for (var n = 0; n < playerUnits.length; n++) {
							var otherUnit = playerUnits[n];
							if (!otherUnit.isDead && otherUnit !== playerUnit) {
								var distance = Math.sqrt(Math.pow(playerUnit.x - otherUnit.x, 2) + Math.pow(playerUnit.y - otherUnit.y, 2));
								if (distance <= 200) {
									unitValue += otherUnit.currentHealth * 0.5; // Bonus for clustered units
								}
							}
						}
						if (unitValue > maxValue) {
							maxValue = unitValue;
							bestAttackTarget = playerUnit;
						}
					}
				}
				if (bestAttackTarget) {
					var chosenAttackSpell = attackSpellCards[Math.floor(Math.random() * attackSpellCards.length)];
					if (deployUnit(chosenAttackSpell, bestAttackTarget.x, bestAttackTarget.y, false)) {
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 180 + Math.random() * 120;
						return; // Exit after using spell
					}
				}
			}
		}
		// Check if AI already has giants on the field
		var giantsOnField = 0;
		for (var i = 0; i < enemyUnits.length; i++) {
			if (enemyUnits[i].unitType === 'giant' && !enemyUnits[i].isDead) {
				giantsOnField++;
			}
		}
		if (aiElixir >= 8 && LK.ticks - aiLastDeploy > aiDeployInterval && giantsOnField < 2) {
			// Big push with wincondition + support (max 2 giants on field)
			if (aiElixir >= 8 && Math.random() < 0.9) {
				// 90% chance for big attack when having 8+ elixir
				// Find wincondition card in AI deck
				var winconditionCard = null;
				for (var w = 0; w < aiDeck.length; w++) {
					if (aiDeck[w] === 'giant') {
						winconditionCard = 'giant';
						break;
					}
				}
				if (winconditionCard) {
					// Deploy wincondition first
					var deployX = 300 + Math.random() * 1448;
					var deployY = 200 + Math.random() * 600;
					if (deployUnit(winconditionCard, deployX, deployY, false)) {
						var winconditionCost = winconditionCard === 'giant' ? 5 : 3;
						aiElixir -= winconditionCost;
						// Wait a bit then deploy support unit behind wincondition
						LK.setTimeout(function () {
							if (aiElixir >= 3) {
								var supportCards = [];
								// Get support cards from AI deck
								for (var s = 0; s < aiDeck.length; s++) {
									var supportCard = aiDeck[s];
									var supportCost = supportCard === 'giant' ? 5 : supportCard === 'wizard' ? 5 : supportCard === 'skeleton' ? 1 : supportCard === 'skeletonArmy' ? 3 : supportCard === 'fireball' ? 4 : supportCard === 'discharge' ? 2 : supportCard === 'minion' ? 3 : 3;
									if (aiElixir >= supportCost && supportCard !== 'fireball' && supportCard !== 'discharge' && supportCard !== winconditionCard) {
										supportCards.push(supportCard);
									}
								}
								if (supportCards.length > 0) {
									var chosenSupport = supportCards[Math.floor(Math.random() * supportCards.length)];
									var supportX = deployX + (Math.random() - 0.5) * 200; // Near wincondition
									var supportY = deployY + 100 + Math.random() * 200; // Behind wincondition
									deployUnit(chosenSupport, supportX, supportY, false);
								}
							}
						}, 1000); // 1 second delay
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 300 + Math.random() * 180; // Longer interval after big push
					}
				}
			}
		} else if (aiElixir >= 5 && aiElixir < 8 && LK.ticks - aiLastDeploy > aiDeployInterval && giantsOnField < 2) {
			// Single wincondition deploy when having 5-7 elixir (more likely to save)
			if (Math.random() < 0.4) {
				// 40% chance to use wincondition (reduced from 60% to encourage saving)
				var winconditionCard = null;
				for (var w = 0; w < aiDeck.length; w++) {
					if (aiDeck[w] === 'giant') {
						winconditionCard = 'giant';
						break;
					}
				}
				if (winconditionCard) {
					var deployX = 300 + Math.random() * 1448;
					var deployY = 200 + Math.random() * 600;
					if (deployUnit(winconditionCard, deployX, deployY, false)) {
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 240 + Math.random() * 120;
					}
				}
			} else {
				// Regular unit deployment (less likely when saving)
				if (aiElixir >= 3 && Math.random() < 0.3) {
					var availableCards = [];
					for (var a = 0; a < aiDeck.length; a++) {
						var deckCard = aiDeck[a];
						var cardCost = deckCard === 'giant' ? 5 : deckCard === 'wizard' ? 5 : deckCard === 'skeleton' ? 1 : deckCard === 'skeletonArmy' ? 3 : deckCard === 'fireball' ? 4 : deckCard === 'discharge' ? 2 : deckCard === 'minion' ? 3 : deckCard === 'maquinaVoladora' ? 4 : deckCard === 'megaesbirro' ? 3 : 3;
						if (aiElixir >= cardCost && deckCard !== 'fireball' && deckCard !== 'discharge') {
							availableCards.push(deckCard);
						}
					}
					if (availableCards.length > 0) {
						var randomCard = availableCards[Math.floor(Math.random() * availableCards.length)];
						var deployX = 300 + Math.random() * 1448;
						var deployY = 200 + Math.random() * 1000;
						if (deployUnit(randomCard, deployX, deployY, false)) {
							aiLastDeploy = LK.ticks;
							aiDeployInterval = 180 + Math.random() * 120;
						}
					}
				}
			}
		} else if (aiElixir >= 3 && aiElixir < 5 && LK.ticks - aiLastDeploy > aiDeployInterval * 3) {
			// Wait even longer when having low elixir (3-4), prioritize saving for wincondition
			// Only deploy if waiting for too long or in emergency
			if (Math.random() < 0.15) {
				// Only 15% chance to deploy regular units when saving (reduced from 30%)
				var lowCostCards = [];
				for (var l = 0; l < aiDeck.length; l++) {
					var deckCard = aiDeck[l];
					var cardCost = deckCard === 'giant' ? 5 : deckCard === 'wizard' ? 5 : deckCard === 'skeleton' ? 1 : deckCard === 'skeletonArmy' ? 3 : deckCard === 'fireball' ? 4 : deckCard === 'discharge' ? 2 : deckCard === 'minion' ? 3 : deckCard === 'maquinaVoladora' ? 4 : deckCard === 'megaesbirro' ? 3 : 3;
					if (aiElixir >= cardCost && deckCard !== 'fireball' && deckCard !== 'discharge' && cardCost <= 4) {
						lowCostCards.push(deckCard);
					}
				}
				if (lowCostCards.length > 0) {
					var randomCard = lowCostCards[Math.floor(Math.random() * lowCostCards.length)];
					var deployX = 300 + Math.random() * 1448;
					var deployY = 200 + Math.random() * 1000;
					if (deployUnit(randomCard, deployX, deployY, false)) {
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 240 + Math.random() * 120;
					}
				}
			}
		}
	}
}
function checkGameEnd() {
	if (gameTime <= 0 && !gameEnded) {
		gameEnded = true;
		if (playerTowersDestroyed > enemyTowersDestroyed) {
			LK.showGameOver();
		} else if (enemyTowersDestroyed > playerTowersDestroyed) {
			LK.showYouWin();
		} else {
			// Tie-breaker: check tower health
			var playerTotalHealth = 0;
			var enemyTotalHealth = 0;
			for (var i = 0; i < playerTowers.length; i++) {
				playerTotalHealth += playerTowers[i].currentHealth;
			}
			for (var i = 0; i < enemyTowers.length; i++) {
				enemyTotalHealth += enemyTowers[i].currentHealth;
			}
			if (playerTotalHealth > enemyTotalHealth) {
				LK.showYouWin();
			} else if (enemyTotalHealth > playerTotalHealth) {
				LK.showGameOver();
			} else {
				LK.showGameOver(); // Draw counts as loss
			}
		}
	}
}
function setupEventHandlers() {
	// Event handlers for active deck cards only
	for (var i = 0; i < deckCards.length; i++) {
		var card = deckCards[i];
		var cardType = card.cardType;
		var cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
		// Create closure to capture cardType and cost
		(function (type, cardCost, index) {
			card.down = function (x, y, obj) {
				if (elixir >= cardCost) {
					draggedCard = type;
				}
			};
		})(cardType, cost, i);
	}
	game.down = function (x, y, obj) {
		// Only handle game events if game has started
		if (!gameStarted) {
			return;
		}
		// This will handle deployment when clicking on the battlefield
	};
	game.up = function (x, y, obj) {
		// Only handle game events if game has started
		if (!gameStarted) {
			return;
		}
		if (draggedCard) {
			// Convert coordinates to game space
			var gamePos = {
				x: x,
				y: y
			};
			if (obj && obj.parent) {
				var globalPos = obj.parent.toGlobal ? obj.parent.toGlobal(obj.position) : {
					x: x,
					y: y
				};
				gamePos = game.toLocal ? game.toLocal(globalPos) : {
					x: x,
					y: y
				};
			}
			if (deployUnit(draggedCard, gamePos.x, gamePos.y, true)) {
				// Unit deployed successfully
			}
			draggedCard = null;
		}
	};
}
// Initialize menu
createMenu();
game.update = function () {
	// Only run game logic if game has started
	if (!gameStarted) {
		return;
	}
	if (gameEnded) {
		return;
	}
	// Update timer
	if (LK.ticks % 60 === 0 && gameTime > 0) {
		gameTime--;
		timerText.setText(gameTime.toString());
	}
	// Regenerate elixir
	if (LK.ticks - lastElixirRegen >= elixirRegenRate && elixir < maxElixir) {
		elixir++;
		elixirText.setText(elixir + "/" + maxElixir);
		lastElixirRegen = LK.ticks;
	}
	// Regenerate AI elixir
	if (LK.ticks - lastAiElixirRegen >= aiElixirRegenRate && aiElixir < aiMaxElixir) {
		aiElixir++;
		lastAiElixirRegen = LK.ticks;
	}
	// AI deployment
	aiDeploy();
	// Clean up dead units
	for (var i = playerUnits.length - 1; i >= 0; i--) {
		if (playerUnits[i].isDead) {
			playerUnits[i].destroy();
			playerUnits.splice(i, 1);
		}
	}
	for (var i = enemyUnits.length - 1; i >= 0; i--) {
		if (enemyUnits[i].isDead) {
			enemyUnits[i].destroy();
			enemyUnits.splice(i, 1);
		}
	}
	// Clean up bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		if (bullets[i].destroyed || bullets[i].y < -100 || bullets[i].y > 2800) {
			bullets[i].destroy();
			bullets.splice(i, 1);
		}
	}
	// Check for immediate game end conditions
	var allPlayerTowersDead = true;
	var allEnemyTowersDead = true;
	for (var i = 0; i < playerTowers.length; i++) {
		if (!playerTowers[i].isDead) {
			allPlayerTowersDead = false;
			break;
		}
	}
	for (var i = 0; i < enemyTowers.length; i++) {
		if (!enemyTowers[i].isDead) {
			allEnemyTowersDead = false;
			break;
		}
	}
	if (allPlayerTowersDead && !gameEnded) {
		gameEnded = true;
		LK.showGameOver();
	} else if (allEnemyTowersDead && !gameEnded) {
		gameEnded = true;
		LK.showYouWin();
	}
	checkGameEnd();
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var AreaDamageBullet = Container.expand(function (startX, startY, target, damage, isFromPlayer, areaRadius) {
	var self = Container.call(this);
	self.x = startX;
	self.y = startY;
	self.target = target;
	self.damage = damage;
	self.speed = 6;
	self.isFromPlayer = isFromPlayer;
	self.areaRadius = areaRadius || 100; // Default area damage radius
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bulletGraphics.tint = isFromPlayer ? 0xFF9800 : 0xFF5722; // Orange tint for area damage bullets
	bulletGraphics.scaleX = 1.3;
	bulletGraphics.scaleY = 1.3;
	self.update = function () {
		if (!self.target || self.target.isDead) {
			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 < 30) {
			// Apply direct damage to the target first
			self.target.takeDamage(self.damage);
			// Then area damage explosion
			self.explode();
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
	};
	self.explode = function () {
		// Visual explosion effect (removed screen flash to prevent bugs)
		LK.getSound('explosion').play();
		// Create visual circle around the hit target
		var explosionCircle = LK.getAsset('bullet', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 13,
			scaleY: 13
		});
		explosionCircle.x = self.target.x;
		explosionCircle.y = self.target.y;
		explosionCircle.tint = 0xFF9800;
		explosionCircle.alpha = 0.6;
		game.addChild(explosionCircle);
		// Animate the circle to fade out
		tween(explosionCircle, {
			alpha: 0,
			scaleX: 15,
			scaleY: 15
		}, {
			duration: 500,
			onFinish: function onFinish() {
				explosionCircle.destroy();
			}
		});
		// Get all possible targets for area damage
		var allTargets = [];
		if (self.isFromPlayer) {
			allTargets = allTargets.concat(enemyUnits, enemyTowers);
		} else {
			allTargets = allTargets.concat(playerUnits, playerTowers);
		}
		// Apply damage to all units within area radius (100 units as requested)
		for (var i = 0; i < allTargets.length; i++) {
			var targetUnit = allTargets[i];
			if (!targetUnit.isDead && targetUnit !== self.target) {
				// Exclude the initial target from area damage
				var distance = Math.sqrt(Math.pow(self.target.x - targetUnit.x, 2) + Math.pow(self.target.y - targetUnit.y, 2));
				if (distance <= 100) {
					targetUnit.takeDamage(140);
					// Flash each affected unit
					tween(targetUnit, {
						tint: 0xFF9800
					}, {
						duration: 300,
						onFinish: function onFinish() {
							tween(targetUnit, {
								tint: 0xFFFFFF
							}, {
								duration: 200
							});
						}
					});
				}
			}
		}
	};
	return self;
});
var Bullet = Container.expand(function (startX, startY, target, damage, isFromPlayer) {
	var self = Container.call(this);
	self.x = startX;
	self.y = startY;
	self.target = target;
	self.damage = damage;
	self.speed = 8;
	self.isFromPlayer = isFromPlayer;
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bulletGraphics.tint = isFromPlayer ? 0x4CAF50 : 0xF44336;
	self.update = function () {
		if (!self.target || self.target.isDead) {
			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 < 20) {
			self.target.takeDamage(self.damage);
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
	};
	return self;
});
var Cannon = Container.expand(function (isPlayer) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = 'cannon';
	self.maxHealth = 600;
	self.currentHealth = 600;
	self.isDead = false;
	self.damage = 90;
	self.range = 500;
	self.attackSpeed = 50;
	self.lastAttackTime = 0;
	self.target = null;
	self.isAttacking = false;
	// Spawn delay properties
	self.spawnDelay = 60; // 1 second
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var cannonGraphics = self.attachAsset('cannon', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.25,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.25,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = 0.25;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false;
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return;
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Find closest enemy units first
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				// Cannon cannot attack aerial units
				if (targetUnits[i].isAerial) {
					continue;
				}
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		self.target = closestTarget;
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		if (distance <= self.range && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			self.isAttacking = true;
			var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't attack while stunned
		}
		// Lose 3% of total health per second (60 ticks = 1 second)
		if (LK.ticks % 20 === 0) {
			// Every 20 ticks = 3 times per second = 1% each time = 3% per second
			self.currentHealth -= self.maxHealth * 0.01;
			if (self.currentHealth <= 0) {
				self.currentHealth = 0;
				self.isDead = true;
			}
			// Update health bar without flash effect for natural decay
			var healthPercent = self.currentHealth / self.maxHealth;
			self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		}
		self.findTarget();
		self.attack();
	};
	return self;
});
var Card = Container.expand(function (cardType) {
	var self = Container.call(this);
	self.cardType = cardType;
	self.cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
	var cardBg = self.attachAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var cardIcon = LK.getAsset(cardType === 'discharge' ? 'descarga_descardina' : cardType, {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.8,
		scaleY: 0.8
	});
	self.addChild(cardIcon);
	var costText = new Text2(self.cost.toString(), {
		size: 30,
		fill: 0xFFFFFF
	});
	costText.anchor.set(0.5, 0.5);
	costText.x = 120;
	costText.y = -40;
	self.addChild(costText);
	return self;
});
var Discharge = Container.expand(function (targetX, targetY, isFromPlayer) {
	var self = Container.call(this);
	self.targetX = targetX;
	self.targetY = targetY;
	self.isFromPlayer = isFromPlayer;
	self.damage = 200;
	self.stunDuration = 60; // 1 second stun (60 ticks)
	// Discharge appears instantly at target location
	self.x = targetX;
	self.y = targetY;
	// Define explode method BEFORE calling it
	self.explode = function () {
		// Visual explosion effect - blue circle of 150 units radius
		var explosionCircle = LK.getAsset('dischargeExplosion', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 1.2,
			// Scale to make it 150 units radius (250 * 1.2 / 2 = 150)
			scaleY: 1.2
		});
		explosionCircle.x = self.targetX;
		explosionCircle.y = self.targetY;
		explosionCircle.tint = 0x0080FF; // Blue color
		explosionCircle.alpha = 0.9;
		game.addChild(explosionCircle);
		// Animate explosion
		tween(explosionCircle, {
			alpha: 0,
			scaleX: 1.8,
			scaleY: 1.8
		}, {
			duration: 800,
			onFinish: function onFinish() {
				explosionCircle.destroy();
			}
		});
		// Play explosion sound
		LK.getSound('explosion').play();
		// Get all possible targets for damage
		var allTargets = [];
		if (self.isFromPlayer) {
			allTargets = allTargets.concat(enemyUnits, enemyTowers);
		} else {
			allTargets = allTargets.concat(playerUnits, playerTowers);
		}
		// Apply damage and stun to all units within explosion radius of 150 units
		var explosionRadius = 150; // 150 units as requested
		for (var i = 0; i < allTargets.length; i++) {
			var targetUnit = allTargets[i];
			if (!targetUnit.isDead) {
				var distance = Math.sqrt(Math.pow(self.targetX - targetUnit.x, 2) + Math.pow(self.targetY - targetUnit.y, 2));
				if (distance <= explosionRadius) {
					// Apply 200 damage
					targetUnit.takeDamage(self.damage);
					// Apply stun effect (immobilize for 1 second)
					targetUnit.stunTimer = self.stunDuration;
					targetUnit.isStunned = true;
					// Visual effect for stunned units (blue tint)
					tween(targetUnit, {
						tint: 0x0080FF
					}, {
						duration: 1000,
						onFinish: function onFinish() {
							tween(targetUnit, {
								tint: 0xFFFFFF
							}, {
								duration: 200
							});
						}
					});
				}
			}
		}
		// Destroy discharge immediately after explosion
		self.destroy();
	};
	// Create instant explosion effect - NOW we can call explode since it's defined
	self.explode();
	return self;
});
var Fireball = Container.expand(function (targetX, targetY, isFromPlayer) {
	var self = Container.call(this);
	self.targetX = targetX;
	self.targetY = targetY;
	self.isFromPlayer = isFromPlayer;
	self.speed = 13;
	self.damage = 415;
	self.explosionRadius = 150;
	// Start from king tower position
	if (isFromPlayer) {
		self.x = 1024; // Player king tower x
		self.y = 2600; // Player king tower y
	} else {
		self.x = 1024; // Enemy king tower x
		self.y = 200; // Enemy king tower y
	}
	var fireballGraphics = self.attachAsset('fireball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	fireballGraphics.tint = 0xFF6600;
	self.update = function () {
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < 30) {
			// Explode at target location
			self.explode();
			self.destroy();
			return;
		}
		var moveX = dx / distance * self.speed;
		var moveY = dy / distance * self.speed;
		self.x += moveX;
		self.y += moveY;
	};
	self.explode = function () {
		// Visual explosion effect
		var explosionCircle = LK.getAsset('fireballExplosion', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		explosionCircle.x = self.targetX;
		explosionCircle.y = self.targetY;
		explosionCircle.tint = 0xFF3300;
		explosionCircle.alpha = 0.8;
		game.addChild(explosionCircle);
		// Animate explosion
		tween(explosionCircle, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 1000,
			onFinish: function onFinish() {
				explosionCircle.destroy();
			}
		});
		// Play explosion sound
		LK.getSound('explosion').play();
		// Get all possible targets for damage
		var allTargets = [];
		if (self.isFromPlayer) {
			allTargets = allTargets.concat(enemyUnits, enemyTowers);
		} else {
			allTargets = allTargets.concat(playerUnits, playerTowers);
		}
		// Apply damage and knockback to all units within explosion radius
		for (var i = 0; i < allTargets.length; i++) {
			var targetUnit = allTargets[i];
			if (!targetUnit.isDead) {
				var distance = Math.sqrt(Math.pow(self.targetX - targetUnit.x, 2) + Math.pow(self.targetY - targetUnit.y, 2));
				if (distance <= self.explosionRadius) {
					// Check if target is a tower
					var isTower = false;
					if (self.isFromPlayer) {
						isTower = enemyTowers.indexOf(targetUnit) !== -1;
					} else {
						isTower = playerTowers.indexOf(targetUnit) !== -1;
					}
					// Apply damage - 50% less to towers
					var damageToApply = isTower ? self.damage * 0.5 : self.damage;
					targetUnit.takeDamage(damageToApply);
					// Apply knockback only to non-tower units
					if (!isTower) {
						var knockbackDistance = 100;
						var knockbackDx = targetUnit.x - self.targetX;
						var knockbackDy = targetUnit.y - self.targetY;
						var knockbackLength = Math.sqrt(knockbackDx * knockbackDx + knockbackDy * knockbackDy);
						if (knockbackLength > 0) {
							var normalizedDx = knockbackDx / knockbackLength;
							var normalizedDy = knockbackDy / knockbackLength;
							var newX = targetUnit.x + normalizedDx * knockbackDistance;
							var newY = targetUnit.y + normalizedDy * knockbackDistance;
							// Animate knockback
							tween(targetUnit, {
								x: newX,
								y: newY
							}, {
								duration: 300,
								easing: tween.easeOut
							});
						}
					}
					// Flash effect on hit units
					tween(targetUnit, {
						tint: 0xFF6600
					}, {
						duration: 300,
						onFinish: function onFinish() {
							tween(targetUnit, {
								tint: 0xFFFFFF
							}, {
								duration: 200
							});
						}
					});
				}
			}
		}
	};
	return self;
});
var MaquinaVoladora = Container.expand(function (isPlayer) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = 'maquinaVoladora';
	self.isAerial = true; // Mark as aerial unit
	self.maxHealth = 500;
	self.currentHealth = 500;
	self.damage = 85;
	self.attackSpeed = 90; // 90 ticks
	self.range = 500; // Detection range
	self.attackRange = 475; // Attack range
	self.speed = 1.5;
	self.target = null;
	self.lastAttackTime = 0;
	self.isDead = false;
	self.isAttacking = false;
	// Spawn delay properties
	self.spawnDelay = 60; // 1 second
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var maquinaGraphics = self.attachAsset('flying_machine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarScale = 0.2;
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = healthBarScale;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false;
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return;
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Find closest enemy units first
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		// Find closest enemy towers if no units in range
		if (!closestTarget) {
			var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
			for (var i = 0; i < targetTowers.length; i++) {
				if (!targetTowers[i].isDead) {
					var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
					if (distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetTowers[i];
					}
				}
			}
		}
		self.target = closestTarget;
	};
	self.moveToTarget = function () {
		if (!self.target || self.target.isDead) {
			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 > self.attackRange) {
			var moveX = dx / distance * self.speed;
			var moveY = dy / distance * self.speed;
			self.x += moveX;
			self.y += moveY;
		}
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		if (distance <= self.attackRange && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			self.isAttacking = true;
			// Create purple bullet
			var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
			bullet.children[0].tint = 0x9C27B0; // Purple color
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't move or attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't move or attack while stunned
		}
		self.findTarget();
		self.moveToTarget();
		self.attack();
	};
	return self;
});
var Megaesbirro = Container.expand(function (isPlayer) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = 'megaesbirro';
	self.isAerial = true; // Mark as aerial unit
	self.maxHealth = 625; // 500 + 125
	self.currentHealth = 625;
	self.damage = 120; // 85 + 35
	self.attackSpeed = 90; // 90 ticks
	self.range = 500; // Detection range
	self.attackRange = 150; // Attack range
	self.speed = 1.75;
	self.target = null;
	self.lastAttackTime = 0;
	self.isDead = false;
	self.isAttacking = false;
	// Spawn delay properties
	self.spawnDelay = 60; // 1 second
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var megaesbirroGraphics = self.attachAsset('megaesbirro', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarScale = 0.2;
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = healthBarScale;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false;
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return;
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Find closest enemy units first
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		// Find closest enemy towers if no units in range
		if (!closestTarget) {
			var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
			for (var i = 0; i < targetTowers.length; i++) {
				if (!targetTowers[i].isDead) {
					var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
					if (distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetTowers[i];
					}
				}
			}
		}
		self.target = closestTarget;
	};
	self.moveToTarget = function () {
		if (!self.target || self.target.isDead) {
			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 > self.attackRange) {
			var moveX = dx / distance * self.speed;
			var moveY = dy / distance * self.speed;
			self.x += moveX;
			self.y += moveY;
		}
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		if (distance <= self.attackRange && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			self.isAttacking = true;
			// Create purple bullet
			var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
			bullet.children[0].tint = 0x9C27B0; // Purple color
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't move or attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't move or attack while stunned
		}
		self.findTarget();
		self.moveToTarget();
		self.attack();
	};
	return self;
});
var Minion = Container.expand(function (isPlayer) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = 'minion';
	self.isAerial = true; // Mark as aerial unit
	self.maxHealth = 400;
	self.currentHealth = 400;
	self.damage = 85;
	self.attackSpeed = 90; // 90 ticks
	self.range = 500; // Detection range
	self.attackRange = 150; // Attack range
	self.speed = 1.75;
	self.target = null;
	self.lastAttackTime = 0;
	self.isDead = false;
	self.isAttacking = false;
	// Spawn delay properties
	self.spawnDelay = 60; // 1 second
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var minionGraphics = self.attachAsset('minion', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarScale = 0.2;
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = healthBarScale;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false;
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return;
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Find closest enemy units first
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		// Find closest enemy towers if no units in range
		if (!closestTarget) {
			var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
			for (var i = 0; i < targetTowers.length; i++) {
				if (!targetTowers[i].isDead) {
					var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
					if (distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetTowers[i];
					}
				}
			}
		}
		self.target = closestTarget;
	};
	self.moveToTarget = function () {
		if (!self.target || self.target.isDead) {
			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 > self.attackRange) {
			var moveX = dx / distance * self.speed;
			var moveY = dy / distance * self.speed;
			self.x += moveX;
			self.y += moveY;
		}
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		if (distance <= self.attackRange && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			self.isAttacking = true;
			// Create purple bullet
			var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
			bullet.children[0].tint = 0x9C27B0; // Purple color
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't move or attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't move or attack while stunned
		}
		self.findTarget();
		self.moveToTarget();
		self.attack();
	};
	return self;
});
var Tower = Container.expand(function (isPlayer, isKing) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.isKing = isKing;
	self.maxHealth = isKing ? 3700 : 2400;
	self.currentHealth = self.maxHealth;
	self.isDead = false;
	self.range = 800;
	self.damage = 75;
	self.attackSpeed = 67; // 50% slower than 45 ticks (45 * 1.5 = 67.5, rounded to 67)
	self.lastAttackTime = 0;
	var towerGraphics = self.attachAsset(isKing ? 'kingTower' : 'tower', {
		anchorX: 0.5,
		anchorY: 1
	});
	towerGraphics.tint = self.isPlayer ? 0x4CAF50 : 0xF44336;
	// Health display
	var healthText = new Text2(self.currentHealth.toString(), {
		size: 40,
		fill: 0xFFFFFF
	});
	healthText.anchor.set(0.5, 0.5);
	healthText.y = -75;
	self.addChild(healthText);
	self.healthText = healthText;
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
			towersDestroyed++;
			LK.effects.flashObject(self, 0xFF0000, 1000);
			LK.getSound('towerDestroy').play();
			if (self.isPlayer) {
				enemyTowersDestroyed++;
			} else {
				playerTowersDestroyed++;
			}
		}
		self.healthText.setText(self.currentHealth.toString());
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.attack = function () {
		if (self.isDead) {
			return;
		}
		// King towers cannot attack until at least one Princess tower is destroyed
		if (self.isKing) {
			var teamTowers = self.isPlayer ? playerTowers : enemyTowers;
			var princessTowersAlive = 0;
			for (var i = 0; i < teamTowers.length; i++) {
				if (!teamTowers[i].isKing && !teamTowers[i].isDead) {
					princessTowersAlive++;
				}
			}
			if (princessTowersAlive === 2) {
				return; // King tower cannot attack while both Princess towers are alive
			}
		}
		var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
		var closestTarget = null;
		var closestDistance = Infinity;
		for (var i = 0; i < targetUnits.length; i++) {
			if (!targetUnits[i].isDead) {
				var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
				if (distance <= self.range && distance < closestDistance) {
					closestDistance = distance;
					closestTarget = targetUnits[i];
				}
			}
		}
		if (closestTarget && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			var bullet = new Bullet(self.x, self.y - 50, closestTarget, self.damage, self.isPlayer);
			bullets.push(bullet);
			game.addChild(bullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		self.attack();
	};
	return self;
});
var Unit = Container.expand(function (isPlayer, unitType, health, damage, attackSpeed, range, speed) {
	var self = Container.call(this);
	self.isPlayer = isPlayer;
	self.unitType = unitType;
	self.maxHealth = health;
	self.currentHealth = health;
	self.damage = damage;
	self.attackSpeed = attackSpeed;
	self.range = range;
	self.speed = speed;
	self.target = null;
	self.lastAttackTime = 0;
	self.isDead = false;
	self.isAttacking = false; // Track if unit has started attacking current target
	// Spawn delay properties
	self.spawnDelay = unitType === 'giant' ? 180 : 60; // 3 seconds for giant, 1 second for others (60 ticks = 1 second)
	self.spawnTimer = self.spawnDelay;
	self.isSpawning = true;
	var unitGraphics = self.attachAsset(unitType, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Health bar background
	var healthBarScale = unitType === 'giant' ? 0.4 : 0.2;
	var healthBarBg = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBarBg.tint = 0x000000;
	self.addChild(healthBarBg);
	// Health bar
	var healthBar = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: healthBarScale,
		scaleY: 0.1,
		y: -50
	});
	healthBar.tint = self.isPlayer ? 0x2196F3 : 0xF44336;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	self.healthBarMaxScale = healthBarScale;
	// Spawn timer text
	self.spawnTimerText = new Text2('', {
		size: 30,
		fill: 0xFFFFFF
	});
	self.spawnTimerText.anchor.set(0.5, 0.5);
	self.spawnTimerText.y = 30;
	self.addChild(self.spawnTimerText);
	self.takeDamage = function (damage) {
		self.currentHealth -= damage;
		if (self.currentHealth <= 0) {
			self.currentHealth = 0;
			self.isDead = true;
		}
		// Update health bar
		var healthPercent = self.currentHealth / self.maxHealth;
		self.healthBar.scaleX = self.healthBarMaxScale * healthPercent;
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xFF0000, 300);
	};
	self.findTarget = function () {
		// Reset target if current target is dead or invalid
		if (self.target && self.target.isDead) {
			self.target = null;
			self.isAttacking = false; // Reset attacking state when target dies
		}
		// If already attacking a target, don't change targets
		if (self.isAttacking && self.target && !self.target.isDead) {
			return; // Keep current target while attacking
		}
		var closestDistance = Infinity;
		var closestTarget = null;
		// Giant (wincondition unit) targets structures within detection range, then towers
		if (self.unitType === 'giant') {
			// First check for structures (cannons) within detection range (538)
			var targetStructures = self.isPlayer ? enemyUnits : playerUnits;
			for (var i = 0; i < targetStructures.length; i++) {
				if (!targetStructures[i].isDead && targetStructures[i].unitType === 'cannon') {
					var distance = Math.sqrt(Math.pow(self.x - targetStructures[i].x, 2) + Math.pow(self.y - targetStructures[i].y, 2));
					if (distance <= 538 && distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetStructures[i];
					}
				}
			}
			// If no structures in detection range, target closest tower
			if (!closestTarget) {
				var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
				for (var i = 0; i < targetTowers.length; i++) {
					if (!targetTowers[i].isDead) {
						var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
						if (distance < closestDistance) {
							closestDistance = distance;
							closestTarget = targetTowers[i];
						}
					}
				}
			}
		} else {
			// Normal units: First priority - Find closest enemy units and structures (they are more immediate threats)
			var targetUnits = self.isPlayer ? enemyUnits : playerUnits;
			for (var i = 0; i < targetUnits.length; i++) {
				if (!targetUnits[i].isDead) {
					// Skip aerial units if this unit cannot attack air (only archers and towers can attack air)
					if (targetUnits[i].isAerial && self.unitType !== 'archer') {
						continue;
					}
					var distance = Math.sqrt(Math.pow(self.x - targetUnits[i].x, 2) + Math.pow(self.y - targetUnits[i].y, 2));
					if (distance <= self.range && distance < closestDistance) {
						closestDistance = distance;
						closestTarget = targetUnits[i];
					}
				}
			}
			// Second priority: Find closest enemy towers if no units in range
			if (!closestTarget) {
				var targetTowers = self.isPlayer ? enemyTowers : playerTowers;
				for (var i = 0; i < targetTowers.length; i++) {
					if (!targetTowers[i].isDead) {
						var distance = Math.sqrt(Math.pow(self.x - targetTowers[i].x, 2) + Math.pow(self.y - targetTowers[i].y, 2));
						if (distance < closestDistance) {
							closestDistance = distance;
							closestTarget = targetTowers[i];
						}
					}
				}
			}
		}
		self.target = closestTarget;
	};
	self.moveToTarget = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		var dx = self.target.x - self.x;
		var dy = self.target.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Use proper attack range for movement positioning
		var attackRange = self.attackRange || (self.unitType === 'knight' ? 168 : self.unitType === 'giant' ? 60 : self.range);
		if (distance > attackRange) {
			var moveX = dx / distance * self.speed;
			var moveY = dy / distance * self.speed;
			self.x += moveX;
			self.y += moveY;
		}
	};
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		// Use different ranges for detection vs attack
		var attackRange = self.attackRange || (self.unitType === 'knight' ? 168 : self.unitType === 'giant' ? 60 : self.range); // Use attackRange property if defined, otherwise use unit-specific ranges
		if (distance <= attackRange && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			// Set attacking flag when first attack begins
			self.isAttacking = true;
			// Knight, Giant, and Skeleton use melee attack - direct damage without bullet
			if (self.unitType === 'knight' || self.unitType === 'giant' || self.unitType === 'skeleton') {
				self.target.takeDamage(self.damage);
				// Visual effect for melee strike
				LK.effects.flashObject(self, 0xFFFFFF, 200);
				// Flash target red when hit by Giant
				if (self.unitType === 'giant') {
					tween(self.target, {
						tint: 0xFF0000
					}, {
						duration: 200,
						onFinish: function onFinish() {
							tween(self.target, {
								tint: 0xFFFFFF
							}, {
								duration: 100
							});
						}
					});
				}
				// Knight and Skeleton no longer apply knockback to units
			} else {
				// Other units (like archers, wizard) still use bullets
				var bullet = new Bullet(self.x, self.y, self.target, self.damage, self.isPlayer);
				bullets.push(bullet);
				game.addChild(bullet);
			}
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Handle spawn delay
		if (self.isSpawning) {
			self.spawnTimer--;
			if (self.spawnTimer <= 0) {
				self.isSpawning = false;
				self.spawnTimerText.setText('');
			} else {
				// Show remaining time in seconds
				var secondsLeft = Math.ceil(self.spawnTimer / 60);
				self.spawnTimerText.setText(secondsLeft.toString());
			}
			return; // Don't move or attack while spawning
		}
		// Handle stun effect
		if (self.stunTimer > 0) {
			self.stunTimer--;
			if (self.stunTimer <= 0) {
				self.isStunned = false;
			}
			return; // Don't move or attack while stunned
		}
		// Always find targets every frame to ensure units never ignore enemies
		self.findTarget();
		self.moveToTarget();
		self.attack();
	};
	return self;
});
var Wizard = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'wizard', 550, 140, 100, 530, 1.25);
	// Override the attack function to use area damage
	self.attack = function () {
		if (!self.target || self.target.isDead) {
			return;
		}
		// Verify target is from opposing team before attacking
		var isValidTarget = false;
		if (self.isPlayer && enemyUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (self.isPlayer && enemyTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerUnits.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!self.isPlayer && playerTowers.indexOf(self.target) !== -1) {
			isValidTarget = true;
		}
		if (!isValidTarget) {
			self.target = null;
			return;
		}
		var distance = Math.sqrt(Math.pow(self.x - self.target.x, 2) + Math.pow(self.y - self.target.y, 2));
		// Wizard uses ranged attack with area damage projectile (use detection range for attacking)
		if (distance <= self.range && LK.ticks - self.lastAttackTime > self.attackSpeed) {
			// Set attacking flag when first attack begins
			self.isAttacking = true;
			// Create area damage bullet with 100 unit area radius
			var areaBullet = new AreaDamageBullet(self.x, self.y, self.target, self.damage, self.isPlayer, 100);
			bullets.push(areaBullet);
			game.addChild(areaBullet);
			self.lastAttackTime = LK.ticks;
			LK.getSound('attack').play();
		}
	};
	return self;
});
var Skeleton = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'skeleton', 25, 45, 60, 500, 2);
	// Skeleton: 25 HP, 45 damage, 60 tick attack speed, 500 detection range, speed 2
	// Attacks ground units and structures only (same targeting as other units)
	// Override attack range to be 150 instead of detection range
	self.attackRange = 150;
	return self;
});
var Knight = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'knight', 825, 160, 60, 538, 1.75);
	// Detection range set to 538 (same as archer for consistent detection)
	// Attack range remains at melee distance in attack function
	return self;
});
var Giant = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'giant', 4000, 175, 90, 538, 0.85);
	// Giant is a wincondition unit that only attacks structures and towers
	// Detection range set to 538 (same as archer), attack range remains at 60 in attack function
	return self;
});
var Archer = Unit.expand(function (isPlayer) {
	var self = Unit.call(this, isPlayer, 'archer', 425, 75, 90, 538, 1.5);
	// Range reduced by 30% from 756 to 538 (25% + 5%)
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x228B22
});
/**** 
* Game Code
****/ 
// Game state variables
/*
CARD AND TOWER STATS:
TOWERS:
- Princess Towers: 2400 HP, 75 damage, attacks every 1.1s (67 ticks), range 800 units
- King Tower: 3700 HP, 75 damage, attacks every 1.1s (67 ticks), range 800 units
* King tower cannot attack until at least one Princess tower is destroyed
CARDS:
- Archers: 3 elixir cost, 425 HP each, 75 damage, attacks every 1.5s (90 ticks), range 567 units, speed 1.5
* Deploys 2 archers, can attack air and ground targets
- Knight: 3 elixir cost, 825 HP, 160 damage, attacks every 1s (60 ticks), range 168 units, speed 2
* Single melee unit, ground targets only
- Giant: 5 elixir cost, 4000 HP, 175 damage, attacks every 1.5s (90 ticks), range 300 units, speed 1
* Wincondition unit that only attacks structures and towers, ground unit
UNIT SPEEDS:
- Knight: speed 2 (medium)
- Archer: speed 1.5 (medium-slow)
- Giant: speed 1 (slow)
ELIXIR SYSTEM:
- Maximum: 10 elixir
- Regeneration: 1 elixir every 2.0 seconds (120 ticks at 60fps)
- Starting amount: 5 elixir
GAME RULES:
- Match duration: 2 minutes (120 seconds)
- Victory: Most towers destroyed wins
- Tiebreaker: Remaining tower health
- Draw: Equal towers destroyed and equal remaining health
*/
var gameStarted = false;
var gameTime = 120; // 2 minutes in seconds
var elixir = 5; // Starting elixir
var maxElixir = 10;
var elixirRegenRate = 120; // Ticks for 2.0 seconds at 60fps
var lastElixirRegen = 0;
var aiElixir = 5; // AI starting elixir
var aiMaxElixir = 10;
var aiElixirRegenRate = 120; // Ticks for 2 seconds at 60fps (faster than player)
var lastAiElixirRegen = 0;
var playerUnits = [];
var enemyUnits = [];
var bullets = [];
var playerTowers = [];
var enemyTowers = [];
var playerTowersDestroyed = 0;
var enemyTowersDestroyed = 0;
var towersDestroyed = 0;
var gameEnded = false;
var aiLastDeploy = 0;
var aiDeployInterval = 240; // 4 seconds
// Card and UI variables
var draggedCard = null;
var menuElements = [];
var deckMenuElements = [];
var deckCards = [];
var archerCard, knightCard, giantCard, wizardCard, cannonCard;
var timerText, elixirText;
var battlefieldLine;
var showingDeckSelection = false;
var selectedDeck = ['archer', 'knight', 'giant', 'wizard', 'cannon']; // Default deck (minimum 5 cards)
var availableCards = ['archer', 'knight', 'giant', 'wizard', 'cannon', 'skeleton', 'skeletonArmy', 'fireball', 'minion', 'maquinaVoladora', 'megaesbirro', 'discharge'];
// Card system variables
var activeCards = []; // Currently displayed 4 cards
var cardQueue = []; // Queue of remaining cards
var maxActiveCards = 4;
// Create main menu
function createMenu() {
	// Title
	var titleText = new Text2('CLASH ROYALE', {
		size: 120,
		fill: 0xFFD700
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 1024;
	titleText.y = 800;
	game.addChild(titleText);
	menuElements.push(titleText);
	// Play button background
	var playButton = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 0.8,
		x: 1024,
		y: 1400
	});
	playButton.tint = 0x4CAF50;
	game.addChild(playButton);
	menuElements.push(playButton);
	// Play button text
	var playText = new Text2('JUGAR', {
		size: 80,
		fill: 0xFFFFFF
	});
	playText.anchor.set(0.5, 0.5);
	playText.x = 1024;
	playText.y = 1400;
	game.addChild(playText);
	menuElements.push(playText);
	// Mazo button background
	var mazoButton = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 0.8,
		x: 1024,
		y: 1600
	});
	mazoButton.tint = 0x9C27B0;
	game.addChild(mazoButton);
	menuElements.push(mazoButton);
	// Mazo button text
	var mazoText = new Text2('MAZO', {
		size: 80,
		fill: 0xFFFFFF
	});
	mazoText.anchor.set(0.5, 0.5);
	mazoText.x = 1024;
	mazoText.y = 1600;
	game.addChild(mazoText);
	menuElements.push(mazoText);
	// Instructions
	var instructionsText = new Text2('Arrastra las cartas al campo de batalla', {
		size: 40,
		fill: 0xFFFFFF
	});
	instructionsText.anchor.set(0.5, 0.5);
	instructionsText.x = 1024;
	instructionsText.y = 1800;
	game.addChild(instructionsText);
	menuElements.push(instructionsText);
	// Make play button clickable
	playButton.down = function (x, y, obj) {
		startGame();
	};
	playText.down = function (x, y, obj) {
		startGame();
	};
	// Make mazo button clickable
	mazoButton.down = function (x, y, obj) {
		showDeckSelection();
	};
	mazoText.down = function (x, y, obj) {
		showDeckSelection();
	};
}
function showDeckSelection() {
	// Hide main menu
	for (var i = 0; i < menuElements.length; i++) {
		menuElements[i].alpha = 0.3;
	}
	showingDeckSelection = true;
	createDeckMenu();
}
function createDeckMenu() {
	// Title
	var deckTitle = new Text2('SELECCIONA TU MAZO', {
		size: 80,
		fill: 0xFFD700
	});
	deckTitle.anchor.set(0.5, 0.5);
	deckTitle.x = 1024;
	deckTitle.y = 600;
	game.addChild(deckTitle);
	deckMenuElements.push(deckTitle);
	// Instructions
	var instructions = new Text2('Toca las cartas para añadir/quitar del mazo (min 5, max 8)', {
		size: 35,
		fill: 0xFFFFFF
	});
	instructions.anchor.set(0.5, 0.5);
	instructions.x = 1024;
	instructions.y = 700;
	game.addChild(instructions);
	deckMenuElements.push(instructions);
	// Available cards display
	var cardStartX = 300;
	var cardSpacing = 350;
	for (var i = 0; i < availableCards.length; i++) {
		var cardType = availableCards[i];
		var cardContainer = new Container();
		cardContainer.x = cardStartX + i * cardSpacing;
		// Position skeleton card 100px below archer, skeleton army 100px below knight, fireball 100px below giant, minion 100px below wizard, maquina voladora 100px below skeleton, discharge 100px below cannon
		if (cardType === 'skeleton') {
			var archerIndex = availableCards.indexOf('archer');
			cardContainer.x = cardStartX + archerIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below archer
		} else if (cardType === 'skeletonArmy') {
			var knightIndex = availableCards.indexOf('knight');
			cardContainer.x = cardStartX + knightIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below knight
		} else if (cardType === 'fireball') {
			var giantIndex = availableCards.indexOf('giant');
			cardContainer.x = cardStartX + giantIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below giant
		} else if (cardType === 'minion') {
			var wizardIndex = availableCards.indexOf('wizard');
			cardContainer.x = cardStartX + wizardIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below wizard
		} else if (cardType === 'maquinaVoladora') {
			var skeletonIndex = availableCards.indexOf('skeleton');
			var archerIndex = availableCards.indexOf('archer');
			cardContainer.x = cardStartX + archerIndex * cardSpacing;
			cardContainer.y = 1100; // 100px below skeleton (200px total below archer)
		} else if (cardType === 'megaesbirro') {
			var skeletonArmyIndex = availableCards.indexOf('skeletonArmy');
			var knightIndex = availableCards.indexOf('knight');
			cardContainer.x = cardStartX + knightIndex * cardSpacing;
			cardContainer.y = 1100; // 100px below skeleton army (200px total below knight)
		} else if (cardType === 'discharge') {
			var cannonIndex = availableCards.indexOf('cannon');
			cardContainer.x = cardStartX + cannonIndex * cardSpacing;
			cardContainer.y = 1000; // 100px below cannon
		} else {
			cardContainer.y = 900;
		}
		// Card background
		var cardBg = cardContainer.attachAsset('cardSlot', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		// Check if card is in selected deck
		var isSelected = selectedDeck.indexOf(cardType) !== -1;
		cardBg.tint = isSelected ? 0x4CAF50 : 0x607d8b;
		// Card icon
		var cardIcon = LK.getAsset(cardType === 'discharge' ? 'descarga_descardina' : cardType, {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.6,
			scaleY: 0.6
		});
		cardContainer.addChild(cardIcon);
		// Card cost
		var cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
		var costText = new Text2(cost.toString(), {
			size: 25,
			fill: 0xFFFFFF
		});
		costText.anchor.set(0.5, 0.5);
		costText.x = 120;
		costText.y = -40;
		cardContainer.addChild(costText);
		// Selection indicator
		if (isSelected) {
			var checkmark = new Text2('✓', {
				size: 40,
				fill: 0xFFFFFF
			});
			checkmark.anchor.set(0.5, 0.5);
			checkmark.x = 0;
			checkmark.y = 80;
			cardContainer.addChild(checkmark);
		}
		// Make card clickable
		cardContainer.cardType = cardType;
		cardContainer.down = function (x, y, obj) {
			toggleCardInDeck(this.cardType);
		};
		game.addChild(cardContainer);
		deckMenuElements.push(cardContainer);
	}
	// Selected deck display
	var deckTitle2 = new Text2('MAZO ACTUAL (' + selectedDeck.length + '/8)', {
		size: 60,
		fill: 0x4CAF50
	});
	deckTitle2.anchor.set(0.5, 0.5);
	deckTitle2.x = 1024;
	deckTitle2.y = 1200;
	game.addChild(deckTitle2);
	deckMenuElements.push(deckTitle2);
	// Display selected cards
	var selectedStartX = 424;
	var selectedSpacing = 240;
	for (var i = 0; i < selectedDeck.length && i < 8; i++) {
		var cardType = selectedDeck[i];
		var selectedCardContainer = new Container();
		selectedCardContainer.x = selectedStartX + i * selectedSpacing;
		selectedCardContainer.y = 1400;
		// Small card background
		var selectedCardBg = selectedCardContainer.attachAsset('cardSlot', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.7,
			scaleY: 0.7
		});
		selectedCardBg.tint = 0x2196F3;
		// Small card icon
		var selectedCardIcon = LK.getAsset(cardType, {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.4,
			scaleY: 0.4
		});
		selectedCardContainer.addChild(selectedCardIcon);
		game.addChild(selectedCardContainer);
		deckMenuElements.push(selectedCardContainer);
	}
	// Back button
	var backButton = LK.getAsset('cardSlot', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.2,
		scaleY: 0.6,
		x: 1024,
		y: 1650
	});
	backButton.tint = 0xFF9800;
	game.addChild(backButton);
	deckMenuElements.push(backButton);
	var backText = new Text2('VOLVER', {
		size: 50,
		fill: 0xFFFFFF
	});
	backText.anchor.set(0.5, 0.5);
	backText.x = 1024;
	backText.y = 1650;
	game.addChild(backText);
	deckMenuElements.push(backText);
	// Make back button clickable
	backButton.down = function (x, y, obj) {
		hideDeckSelection();
	};
	backText.down = function (x, y, obj) {
		hideDeckSelection();
	};
}
function toggleCardInDeck(cardType) {
	var cardIndex = selectedDeck.indexOf(cardType);
	if (cardIndex !== -1) {
		// Only allow removal if deck has more than 5 cards
		if (selectedDeck.length > 5) {
			selectedDeck.splice(cardIndex, 1);
		}
	} else if (selectedDeck.length < 8) {
		// Add card to deck if not full (max 8 cards)
		selectedDeck.push(cardType);
	}
	// Refresh deck menu
	refreshDeckMenu();
}
function refreshDeckMenu() {
	// Remove current deck menu elements
	for (var i = 0; i < deckMenuElements.length; i++) {
		deckMenuElements[i].destroy();
	}
	deckMenuElements = [];
	// Recreate deck menu
	createDeckMenu();
}
function hideDeckSelection() {
	// Remove deck menu elements
	for (var i = 0; i < deckMenuElements.length; i++) {
		deckMenuElements[i].destroy();
	}
	deckMenuElements = [];
	// Show main menu again
	for (var i = 0; i < menuElements.length; i++) {
		menuElements[i].alpha = 1;
	}
	showingDeckSelection = false;
}
function startGame() {
	// Remove menu elements
	for (var i = 0; i < menuElements.length; i++) {
		menuElements[i].destroy();
	}
	menuElements = [];
	// Start the actual game
	gameStarted = true;
	initializeGame();
}
function initializeGame() {
	// Generate AI's randomized deck for this match
	generateAIDeck();
	// Create battlefield divider
	battlefieldLine = game.addChild(LK.getAsset('battlefield', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1366
	}));
	battlefieldLine.tint = 0x000000;
	battlefieldLine.alpha = 0.3;
	// Create towers
	// Player towers (bottom)
	var playerLeftTower = game.addChild(new Tower(true, false));
	playerLeftTower.x = 512;
	playerLeftTower.y = 2400;
	playerTowers.push(playerLeftTower);
	var playerRightTower = game.addChild(new Tower(true, false));
	playerRightTower.x = 1536;
	playerRightTower.y = 2400;
	playerTowers.push(playerRightTower);
	var playerKingTower = game.addChild(new Tower(true, true));
	playerKingTower.x = 1024;
	playerKingTower.y = 2600;
	playerTowers.push(playerKingTower);
	// Enemy towers (top)
	var enemyLeftTower = game.addChild(new Tower(false, false));
	enemyLeftTower.x = 512;
	enemyLeftTower.y = 400;
	enemyTowers.push(enemyLeftTower);
	var enemyRightTower = game.addChild(new Tower(false, false));
	enemyRightTower.x = 1536;
	enemyRightTower.y = 400;
	enemyTowers.push(enemyRightTower);
	var enemyKingTower = game.addChild(new Tower(false, true));
	enemyKingTower.x = 1024;
	enemyKingTower.y = 200;
	enemyTowers.push(enemyKingTower);
	// UI Elements
	timerText = new Text2(gameTime.toString(), {
		size: 60,
		fill: 0xFFFFFF
	});
	timerText.anchor.set(0.5, 0);
	LK.gui.top.addChild(timerText);
	elixirText = new Text2(elixir + "/" + maxElixir, {
		size: 40,
		fill: 0xE91E63
	});
	elixirText.anchor.set(0, 1);
	elixirText.x = 50;
	LK.gui.bottomLeft.addChild(elixirText);
	// Initialize card system
	activeCards = [];
	cardQueue = [];
	deckCards = [];
	// Setup active cards (first 4) and queue (remaining)
	for (var i = 0; i < selectedDeck.length; i++) {
		if (i < maxActiveCards) {
			activeCards.push(selectedDeck[i]);
		} else {
			cardQueue.push(selectedDeck[i]);
		}
	}
	// Create visual cards for active cards only
	var cardSpacing = 300;
	var startX = -(maxActiveCards - 1) * cardSpacing / 2;
	for (var i = 0; i < activeCards.length; i++) {
		var cardType = activeCards[i];
		var newCard = LK.gui.bottom.addChild(new Card(cardType));
		newCard.x = startX + i * cardSpacing;
		newCard.y = -100;
		newCard.cardType = cardType; // Store card type for event handling
		newCard.cardIndex = i; // Store index for replacement
		deckCards.push(newCard);
	}
	// Store references for backward compatibility
	if (activeCards.indexOf('archer') !== -1) {
		archerCard = deckCards[activeCards.indexOf('archer')];
	}
	if (activeCards.indexOf('knight') !== -1) {
		knightCard = deckCards[activeCards.indexOf('knight')];
	}
	if (activeCards.indexOf('giant') !== -1) {
		giantCard = deckCards[activeCards.indexOf('giant')];
	}
	if (activeCards.indexOf('wizard') !== -1) {
		wizardCard = deckCards[activeCards.indexOf('wizard')];
	}
	if (activeCards.indexOf('cannon') !== -1) {
		cannonCard = deckCards[activeCards.indexOf('cannon')];
	}
	// Setup event handlers
	setupEventHandlers();
}
function rotateCard(usedCardIndex) {
	if (cardQueue.length === 0) {
		return;
	} // No cards in queue to rotate
	// Get the next card from queue
	var nextCard = cardQueue.shift(); // Remove first card from queue
	var usedCard = activeCards[usedCardIndex]; // Get the used card
	// Add used card to end of queue
	cardQueue.push(usedCard);
	// Replace active card with next card
	activeCards[usedCardIndex] = nextCard;
	// Update visual card
	var cardToUpdate = deckCards[usedCardIndex];
	if (cardToUpdate) {
		// Store position and index
		var cardX = cardToUpdate.x;
		var cardY = cardToUpdate.y;
		var cardIndex = cardToUpdate.cardIndex;
		// Remove old card
		cardToUpdate.destroy();
		// Create new card with next card type
		var newCard = LK.gui.bottom.addChild(new Card(nextCard));
		newCard.x = cardX;
		newCard.y = cardY;
		newCard.cardType = nextCard;
		newCard.cardIndex = cardIndex;
		// Update references
		deckCards[usedCardIndex] = newCard;
		// Update event handler for new card
		var cardType = newCard.cardType;
		var cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
		newCard.down = function (x, y, obj) {
			if (elixir >= cost) {
				draggedCard = cardType;
			}
		};
	}
}
function deployUnit(cardType, x, y, isPlayer) {
	var cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
	if (isPlayer && elixir < cost) {
		return false;
	}
	if (!isPlayer && aiElixir < cost) {
		return false;
	} // AI also needs elixir
	// Check if position is in correct half (except for spells)
	if (cardType !== 'fireball') {
		if (isPlayer && y < 1366) {
			return false;
		} // Player can only deploy in bottom half
		if (!isPlayer && y > 1366) {
			return false;
		} // AI can only deploy in top half
	}
	var unit = null;
	if (cardType === 'archer') {
		// Deploy 2 archers
		var archer1 = new Archer(isPlayer);
		var archer2 = new Archer(isPlayer);
		archer1.x = x - 40; // Left archer
		archer1.y = y;
		archer2.x = x + 40; // Right archer
		archer2.y = y;
		if (isPlayer) {
			playerUnits.push(archer1);
			playerUnits.push(archer2);
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			enemyUnits.push(archer1);
			enemyUnits.push(archer2);
			aiElixir -= cost; // Deduct AI elixir
		}
		game.addChild(archer1);
		game.addChild(archer2);
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'knight') {
		unit = new Knight(isPlayer);
	} else if (cardType === 'giant') {
		unit = new Giant(isPlayer);
	} else if (cardType === 'wizard') {
		unit = new Wizard(isPlayer);
	} else if (cardType === 'skeleton') {
		// Deploy 3 skeletons in formation: front, back-right, back-left
		var skeleton1 = new Skeleton(isPlayer); // Front skeleton
		var skeleton2 = new Skeleton(isPlayer); // Back-right skeleton  
		var skeleton3 = new Skeleton(isPlayer); // Back-left skeleton
		skeleton1.x = x; // Front skeleton at deployment position
		skeleton1.y = y;
		skeleton2.x = x + 60; // Back-right skeleton
		skeleton2.y = isPlayer ? y + 60 : y - 60; // Adjust based on player side
		skeleton3.x = x - 60; // Back-left skeleton
		skeleton3.y = isPlayer ? y + 60 : y - 60; // Adjust based on player side
		if (isPlayer) {
			playerUnits.push(skeleton1);
			playerUnits.push(skeleton2);
			playerUnits.push(skeleton3);
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			enemyUnits.push(skeleton1);
			enemyUnits.push(skeleton2);
			enemyUnits.push(skeleton3);
			aiElixir -= cost; // Deduct AI elixir
		}
		game.addChild(skeleton1);
		game.addChild(skeleton2);
		game.addChild(skeleton3);
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'skeletonArmy') {
		// Deploy 12 skeletons in a 3x4 formation
		var skeletons = [];
		for (var row = 0; row < 3; row++) {
			for (var col = 0; col < 4; col++) {
				var skeleton = new Skeleton(isPlayer);
				skeleton.x = x + (col - 1.5) * 40; // Spread horizontally
				skeleton.y = y + (row - 1) * 40; // Spread vertically
				skeletons.push(skeleton);
				game.addChild(skeleton);
			}
		}
		if (isPlayer) {
			for (var s = 0; s < skeletons.length; s++) {
				playerUnits.push(skeletons[s]);
			}
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			for (var s = 0; s < skeletons.length; s++) {
				enemyUnits.push(skeletons[s]);
			}
			aiElixir -= cost; // Deduct AI elixir
		}
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'fireball') {
		// Fireball is a spell - can be deployed anywhere on the map
		var fireball = new Fireball(x, y, isPlayer);
		bullets.push(fireball); // Add to bullets array for cleanup
		game.addChild(fireball);
		if (isPlayer) {
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			aiElixir -= cost; // Deduct AI elixir
		}
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'discharge') {
		// Discharge is a spell - can be deployed anywhere on the map, appears instantly
		var discharge = new Discharge(x, y, isPlayer);
		// Don't add to bullets array since it destroys itself immediately
		game.addChild(discharge);
		if (isPlayer) {
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			aiElixir -= cost; // Deduct AI elixir
		}
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'minion') {
		// Deploy 3 minions in formation like skeletons: front, back-right, back-left
		var minion1 = new Minion(isPlayer); // Front minion
		var minion2 = new Minion(isPlayer); // Back-right minion
		var minion3 = new Minion(isPlayer); // Back-left minion
		minion1.x = x; // Front minion at deployment position
		minion1.y = y;
		minion2.x = x + 60; // Back-right minion
		minion2.y = isPlayer ? y + 60 : y - 60; // Adjust based on player side
		minion3.x = x - 60; // Back-left minion
		minion3.y = isPlayer ? y + 60 : y - 60; // Adjust based on player side
		if (isPlayer) {
			playerUnits.push(minion1);
			playerUnits.push(minion2);
			playerUnits.push(minion3);
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			enemyUnits.push(minion1);
			enemyUnits.push(minion2);
			enemyUnits.push(minion3);
			aiElixir -= cost; // Deduct AI elixir
		}
		game.addChild(minion1);
		game.addChild(minion2);
		game.addChild(minion3);
		LK.getSound('deploy').play();
		return true;
	} else if (cardType === 'maquinaVoladora') {
		// Deploy single maquina voladora
		unit = new MaquinaVoladora(isPlayer);
	} else if (cardType === 'megaesbirro') {
		// Deploy single megaesbirro
		unit = new Megaesbirro(isPlayer);
	} else if (cardType === 'cannon') {
		unit = new Cannon(isPlayer);
	}
	if (unit) {
		unit.x = x;
		unit.y = y;
		if (isPlayer) {
			playerUnits.push(unit);
			elixir -= cost;
			elixirText.setText(elixir + "/" + maxElixir);
			// Rotate card if player used it
			var cardIndex = activeCards.indexOf(cardType);
			if (cardIndex !== -1) {
				rotateCard(cardIndex);
			}
		} else {
			enemyUnits.push(unit);
			aiElixir -= cost; // Deduct AI elixir
		}
		game.addChild(unit);
		LK.getSound('deploy').play();
		return true;
	}
	return false;
}
// AI deployment variables
var aiLastUsedCard = null;
var aiCardCooldown = {};
var aiDeck = []; // AI's randomized deck for the match
// Generate AI deck with required constraints
function generateAIDeck() {
	aiDeck = [];
	// Required cards (must have)
	var requiredCards = {
		aerial: 'archer',
		// Card that can attack aerial units
		wincondition: 'giant',
		// Wincondition card
		spell: Math.random() < 0.5 ? 'fireball' : 'discharge',
		// Spell card (randomly choose between fireball and discharge)
		structure: 'cannon' // Structure card
	};
	// Add required cards to AI deck
	aiDeck.push(requiredCards.aerial);
	aiDeck.push(requiredCards.wincondition);
	aiDeck.push(requiredCards.spell);
	aiDeck.push(requiredCards.structure);
	// Remaining card pool (excluding already added required cards)
	var remainingCards = ['knight', 'wizard', 'skeleton', 'skeletonArmy', 'minion', 'maquinaVoladora', 'megaesbirro'];
	// Fill remaining 4 slots with random cards from remaining pool
	while (aiDeck.length < 8) {
		var randomIndex = Math.floor(Math.random() * remainingCards.length);
		var randomCard = remainingCards[randomIndex];
		aiDeck.push(randomCard);
		// Don't remove from remainingCards to allow duplicates
	}
	// Shuffle the deck to randomize order
	for (var i = aiDeck.length - 1; i > 0; i--) {
		var j = Math.floor(Math.random() * (i + 1));
		var temp = aiDeck[i];
		aiDeck[i] = aiDeck[j];
		aiDeck[j] = temp;
	}
}
// AI deployment function
function aiDeploy() {
	// Check if AI is being attacked (player units in AI territory)
	var isUnderAttack = false;
	var playerUnitsInAITerritory = 0;
	for (var i = 0; i < playerUnits.length; i++) {
		if (playerUnits[i].y < 1366) {
			// Player units in AI half
			isUnderAttack = true;
			playerUnitsInAITerritory++;
		}
	}
	// Check if AI towers are taking damage
	var aiTowersUnderAttack = false;
	for (var i = 0; i < enemyTowers.length; i++) {
		if (enemyTowers[i].currentHealth < enemyTowers[i].maxHealth) {
			aiTowersUnderAttack = true;
			break;
		}
	}
	if (isUnderAttack || aiTowersUnderAttack) {
		// DEFENSE MODE: Deploy defensive units quickly if being attacked
		if (LK.ticks - aiLastDeploy > 60 && aiElixir >= 3) {
			// Deploy faster when defending
			var defensiveCards = [];
			// Check if player has used wincondition (giant) or if towers are damaged
			var playerHasWincondition = false;
			for (var i = 0; i < playerUnits.length; i++) {
				if (playerUnits[i].unitType === 'giant') {
					playerHasWincondition = true;
					break;
				}
			}
			if (aiElixir >= 3) {
				// Use cards from AI's deck for defense
				for (var d = 0; d < aiDeck.length; d++) {
					var deckCard = aiDeck[d];
					var cardCost = deckCard === 'giant' ? 5 : deckCard === 'wizard' ? 5 : deckCard === 'skeleton' ? 1 : deckCard === 'skeletonArmy' ? 3 : deckCard === 'fireball' ? 4 : deckCard === 'discharge' ? 2 : deckCard === 'minion' ? 3 : deckCard === 'maquinaVoladora' ? 4 : deckCard === 'megaesbirro' ? 3 : 3;
					if (aiElixir >= cardCost) {
						// Add defensive units (not spells for defense)
						if (deckCard !== 'fireball' && deckCard !== 'discharge') {
							defensiveCards.push(deckCard);
						}
					}
				}
			}
			// Check for spell usage opportunities (discharge and fireball)
			var spellCards = [];
			for (var s = 0; s < aiDeck.length; s++) {
				var spellCard = aiDeck[s];
				if (spellCard === 'discharge' || spellCard === 'fireball') {
					var spellCost = spellCard === 'discharge' ? 2 : 4;
					if (aiElixir >= spellCost) {
						spellCards.push(spellCard);
					}
				}
			}
			if (spellCards.length > 0 && playerUnits.length > 0) {
				// Find player unit with most enemies nearby for spell targeting
				var bestTarget = null;
				var maxNearbyUnits = 0;
				for (var p = 0; p < playerUnits.length; p++) {
					var playerUnit = playerUnits[p];
					if (!playerUnit.isDead) {
						var nearbyCount = 0;
						// Count nearby player units
						for (var n = 0; n < playerUnits.length; n++) {
							var otherUnit = playerUnits[n];
							if (!otherUnit.isDead && otherUnit !== playerUnit) {
								var distance = Math.sqrt(Math.pow(playerUnit.x - otherUnit.x, 2) + Math.pow(playerUnit.y - otherUnit.y, 2));
								if (distance <= 200) {
									// Within spell effect range
									nearbyCount++;
								}
							}
						}
						if (nearbyCount > maxNearbyUnits) {
							maxNearbyUnits = nearbyCount;
							bestTarget = playerUnit;
						}
					}
				}
				// Use spell if we found a good target (at least 1 nearby unit or any unit if no clusters)
				if (bestTarget && (maxNearbyUnits > 0 || playerUnits.length > 0)) {
					var chosenSpell = spellCards[Math.floor(Math.random() * spellCards.length)];
					if (deployUnit(chosenSpell, bestTarget.x, bestTarget.y, false)) {
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 120 + Math.random() * 60;
						return; // Exit early after using spell
					}
				}
			}
			if (defensiveCards.length > 0) {
				var randomCard = defensiveCards[Math.floor(Math.random() * defensiveCards.length)];
				// Deploy near threatened area
				var deployX = 300 + Math.random() * 1448;
				var deployY = 800 + Math.random() * 400; // Deploy in middle-upper area
				if (deployUnit(randomCard, deployX, deployY, false)) {
					aiLastDeploy = LK.ticks;
					aiDeployInterval = 120 + Math.random() * 60; // Quick deploy interval when defending
				}
			}
		}
	} else {
		// ATTACK MODE: Use wincondition strategy when not under attack
		// Check for spell usage opportunities in attack mode
		if (aiElixir >= 2 && playerUnits.length > 0 && Math.random() < 0.3) {
			// 30% chance to use spells in attack
			var attackSpellCards = [];
			for (var s = 0; s < aiDeck.length; s++) {
				var spellCard = aiDeck[s];
				if (spellCard === 'discharge' || spellCard === 'fireball') {
					var spellCost = spellCard === 'discharge' ? 2 : 4;
					if (aiElixir >= spellCost) {
						attackSpellCards.push(spellCard);
					}
				}
			}
			if (attackSpellCards.length > 0) {
				// Target strongest or most clustered player units
				var bestAttackTarget = null;
				var maxValue = 0;
				for (var p = 0; p < playerUnits.length; p++) {
					var playerUnit = playerUnits[p];
					if (!playerUnit.isDead) {
						// Calculate value based on unit health + nearby units
						var unitValue = playerUnit.currentHealth;
						// Count nearby player units for cluster bonus
						for (var n = 0; n < playerUnits.length; n++) {
							var otherUnit = playerUnits[n];
							if (!otherUnit.isDead && otherUnit !== playerUnit) {
								var distance = Math.sqrt(Math.pow(playerUnit.x - otherUnit.x, 2) + Math.pow(playerUnit.y - otherUnit.y, 2));
								if (distance <= 200) {
									unitValue += otherUnit.currentHealth * 0.5; // Bonus for clustered units
								}
							}
						}
						if (unitValue > maxValue) {
							maxValue = unitValue;
							bestAttackTarget = playerUnit;
						}
					}
				}
				if (bestAttackTarget) {
					var chosenAttackSpell = attackSpellCards[Math.floor(Math.random() * attackSpellCards.length)];
					if (deployUnit(chosenAttackSpell, bestAttackTarget.x, bestAttackTarget.y, false)) {
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 180 + Math.random() * 120;
						return; // Exit after using spell
					}
				}
			}
		}
		// Check if AI already has giants on the field
		var giantsOnField = 0;
		for (var i = 0; i < enemyUnits.length; i++) {
			if (enemyUnits[i].unitType === 'giant' && !enemyUnits[i].isDead) {
				giantsOnField++;
			}
		}
		if (aiElixir >= 8 && LK.ticks - aiLastDeploy > aiDeployInterval && giantsOnField < 2) {
			// Big push with wincondition + support (max 2 giants on field)
			if (aiElixir >= 8 && Math.random() < 0.9) {
				// 90% chance for big attack when having 8+ elixir
				// Find wincondition card in AI deck
				var winconditionCard = null;
				for (var w = 0; w < aiDeck.length; w++) {
					if (aiDeck[w] === 'giant') {
						winconditionCard = 'giant';
						break;
					}
				}
				if (winconditionCard) {
					// Deploy wincondition first
					var deployX = 300 + Math.random() * 1448;
					var deployY = 200 + Math.random() * 600;
					if (deployUnit(winconditionCard, deployX, deployY, false)) {
						var winconditionCost = winconditionCard === 'giant' ? 5 : 3;
						aiElixir -= winconditionCost;
						// Wait a bit then deploy support unit behind wincondition
						LK.setTimeout(function () {
							if (aiElixir >= 3) {
								var supportCards = [];
								// Get support cards from AI deck
								for (var s = 0; s < aiDeck.length; s++) {
									var supportCard = aiDeck[s];
									var supportCost = supportCard === 'giant' ? 5 : supportCard === 'wizard' ? 5 : supportCard === 'skeleton' ? 1 : supportCard === 'skeletonArmy' ? 3 : supportCard === 'fireball' ? 4 : supportCard === 'discharge' ? 2 : supportCard === 'minion' ? 3 : 3;
									if (aiElixir >= supportCost && supportCard !== 'fireball' && supportCard !== 'discharge' && supportCard !== winconditionCard) {
										supportCards.push(supportCard);
									}
								}
								if (supportCards.length > 0) {
									var chosenSupport = supportCards[Math.floor(Math.random() * supportCards.length)];
									var supportX = deployX + (Math.random() - 0.5) * 200; // Near wincondition
									var supportY = deployY + 100 + Math.random() * 200; // Behind wincondition
									deployUnit(chosenSupport, supportX, supportY, false);
								}
							}
						}, 1000); // 1 second delay
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 300 + Math.random() * 180; // Longer interval after big push
					}
				}
			}
		} else if (aiElixir >= 5 && aiElixir < 8 && LK.ticks - aiLastDeploy > aiDeployInterval && giantsOnField < 2) {
			// Single wincondition deploy when having 5-7 elixir (more likely to save)
			if (Math.random() < 0.4) {
				// 40% chance to use wincondition (reduced from 60% to encourage saving)
				var winconditionCard = null;
				for (var w = 0; w < aiDeck.length; w++) {
					if (aiDeck[w] === 'giant') {
						winconditionCard = 'giant';
						break;
					}
				}
				if (winconditionCard) {
					var deployX = 300 + Math.random() * 1448;
					var deployY = 200 + Math.random() * 600;
					if (deployUnit(winconditionCard, deployX, deployY, false)) {
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 240 + Math.random() * 120;
					}
				}
			} else {
				// Regular unit deployment (less likely when saving)
				if (aiElixir >= 3 && Math.random() < 0.3) {
					var availableCards = [];
					for (var a = 0; a < aiDeck.length; a++) {
						var deckCard = aiDeck[a];
						var cardCost = deckCard === 'giant' ? 5 : deckCard === 'wizard' ? 5 : deckCard === 'skeleton' ? 1 : deckCard === 'skeletonArmy' ? 3 : deckCard === 'fireball' ? 4 : deckCard === 'discharge' ? 2 : deckCard === 'minion' ? 3 : deckCard === 'maquinaVoladora' ? 4 : deckCard === 'megaesbirro' ? 3 : 3;
						if (aiElixir >= cardCost && deckCard !== 'fireball' && deckCard !== 'discharge') {
							availableCards.push(deckCard);
						}
					}
					if (availableCards.length > 0) {
						var randomCard = availableCards[Math.floor(Math.random() * availableCards.length)];
						var deployX = 300 + Math.random() * 1448;
						var deployY = 200 + Math.random() * 1000;
						if (deployUnit(randomCard, deployX, deployY, false)) {
							aiLastDeploy = LK.ticks;
							aiDeployInterval = 180 + Math.random() * 120;
						}
					}
				}
			}
		} else if (aiElixir >= 3 && aiElixir < 5 && LK.ticks - aiLastDeploy > aiDeployInterval * 3) {
			// Wait even longer when having low elixir (3-4), prioritize saving for wincondition
			// Only deploy if waiting for too long or in emergency
			if (Math.random() < 0.15) {
				// Only 15% chance to deploy regular units when saving (reduced from 30%)
				var lowCostCards = [];
				for (var l = 0; l < aiDeck.length; l++) {
					var deckCard = aiDeck[l];
					var cardCost = deckCard === 'giant' ? 5 : deckCard === 'wizard' ? 5 : deckCard === 'skeleton' ? 1 : deckCard === 'skeletonArmy' ? 3 : deckCard === 'fireball' ? 4 : deckCard === 'discharge' ? 2 : deckCard === 'minion' ? 3 : deckCard === 'maquinaVoladora' ? 4 : deckCard === 'megaesbirro' ? 3 : 3;
					if (aiElixir >= cardCost && deckCard !== 'fireball' && deckCard !== 'discharge' && cardCost <= 4) {
						lowCostCards.push(deckCard);
					}
				}
				if (lowCostCards.length > 0) {
					var randomCard = lowCostCards[Math.floor(Math.random() * lowCostCards.length)];
					var deployX = 300 + Math.random() * 1448;
					var deployY = 200 + Math.random() * 1000;
					if (deployUnit(randomCard, deployX, deployY, false)) {
						aiLastDeploy = LK.ticks;
						aiDeployInterval = 240 + Math.random() * 120;
					}
				}
			}
		}
	}
}
function checkGameEnd() {
	if (gameTime <= 0 && !gameEnded) {
		gameEnded = true;
		if (playerTowersDestroyed > enemyTowersDestroyed) {
			LK.showGameOver();
		} else if (enemyTowersDestroyed > playerTowersDestroyed) {
			LK.showYouWin();
		} else {
			// Tie-breaker: check tower health
			var playerTotalHealth = 0;
			var enemyTotalHealth = 0;
			for (var i = 0; i < playerTowers.length; i++) {
				playerTotalHealth += playerTowers[i].currentHealth;
			}
			for (var i = 0; i < enemyTowers.length; i++) {
				enemyTotalHealth += enemyTowers[i].currentHealth;
			}
			if (playerTotalHealth > enemyTotalHealth) {
				LK.showYouWin();
			} else if (enemyTotalHealth > playerTotalHealth) {
				LK.showGameOver();
			} else {
				LK.showGameOver(); // Draw counts as loss
			}
		}
	}
}
function setupEventHandlers() {
	// Event handlers for active deck cards only
	for (var i = 0; i < deckCards.length; i++) {
		var card = deckCards[i];
		var cardType = card.cardType;
		var cost = cardType === 'giant' ? 5 : cardType === 'wizard' ? 5 : cardType === 'skeleton' ? 1 : cardType === 'skeletonArmy' ? 3 : cardType === 'fireball' ? 4 : cardType === 'discharge' ? 2 : cardType === 'minion' ? 3 : cardType === 'maquinaVoladora' ? 4 : cardType === 'megaesbirro' ? 3 : 3;
		// Create closure to capture cardType and cost
		(function (type, cardCost, index) {
			card.down = function (x, y, obj) {
				if (elixir >= cardCost) {
					draggedCard = type;
				}
			};
		})(cardType, cost, i);
	}
	game.down = function (x, y, obj) {
		// Only handle game events if game has started
		if (!gameStarted) {
			return;
		}
		// This will handle deployment when clicking on the battlefield
	};
	game.up = function (x, y, obj) {
		// Only handle game events if game has started
		if (!gameStarted) {
			return;
		}
		if (draggedCard) {
			// Convert coordinates to game space
			var gamePos = {
				x: x,
				y: y
			};
			if (obj && obj.parent) {
				var globalPos = obj.parent.toGlobal ? obj.parent.toGlobal(obj.position) : {
					x: x,
					y: y
				};
				gamePos = game.toLocal ? game.toLocal(globalPos) : {
					x: x,
					y: y
				};
			}
			if (deployUnit(draggedCard, gamePos.x, gamePos.y, true)) {
				// Unit deployed successfully
			}
			draggedCard = null;
		}
	};
}
// Initialize menu
createMenu();
game.update = function () {
	// Only run game logic if game has started
	if (!gameStarted) {
		return;
	}
	if (gameEnded) {
		return;
	}
	// Update timer
	if (LK.ticks % 60 === 0 && gameTime > 0) {
		gameTime--;
		timerText.setText(gameTime.toString());
	}
	// Regenerate elixir
	if (LK.ticks - lastElixirRegen >= elixirRegenRate && elixir < maxElixir) {
		elixir++;
		elixirText.setText(elixir + "/" + maxElixir);
		lastElixirRegen = LK.ticks;
	}
	// Regenerate AI elixir
	if (LK.ticks - lastAiElixirRegen >= aiElixirRegenRate && aiElixir < aiMaxElixir) {
		aiElixir++;
		lastAiElixirRegen = LK.ticks;
	}
	// AI deployment
	aiDeploy();
	// Clean up dead units
	for (var i = playerUnits.length - 1; i >= 0; i--) {
		if (playerUnits[i].isDead) {
			playerUnits[i].destroy();
			playerUnits.splice(i, 1);
		}
	}
	for (var i = enemyUnits.length - 1; i >= 0; i--) {
		if (enemyUnits[i].isDead) {
			enemyUnits[i].destroy();
			enemyUnits.splice(i, 1);
		}
	}
	// Clean up bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		if (bullets[i].destroyed || bullets[i].y < -100 || bullets[i].y > 2800) {
			bullets[i].destroy();
			bullets.splice(i, 1);
		}
	}
	// Check for immediate game end conditions
	var allPlayerTowersDead = true;
	var allEnemyTowersDead = true;
	for (var i = 0; i < playerTowers.length; i++) {
		if (!playerTowers[i].isDead) {
			allPlayerTowersDead = false;
			break;
		}
	}
	for (var i = 0; i < enemyTowers.length; i++) {
		if (!enemyTowers[i].isDead) {
			allEnemyTowersDead = false;
			break;
		}
	}
	if (allPlayerTowersDead && !gameEnded) {
		gameEnded = true;
		LK.showGameOver();
	} else if (allEnemyTowersDead && !gameEnded) {
		gameEnded = true;
		LK.showYouWin();
	}
	checkGameEnd();
};