/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Boss = Container.expand(function (bossType, succubusRank) {
var self = Container.call(this);
self.type = bossType || 'slimekung';
self.succubusRank = succubusRank || 0;
self.rank = succubusRank; // Boss rank matches succubus rank
self.isBoss = true;
// Boss asset mapping
var bossAssets = {
'slimeking': 'slime',
// Will be scaled up
'orcking': 'goblin',
// Will be scaled up
'darkelflord': 'skeleton',
// Will be scaled up
'darkgolem': 'firemonster',
// Will be scaled up
'demonking': 'demonking',
'fallenangel': 'fallenangel',
'chaosgod': 'chaosgod'
};
var assetName = bossAssets[self.type] || 'slime';
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Scale up boss
graphics.scaleX = 1.5;
graphics.scaleY = 1.5;
// Boss health is much higher
self.maxHealth = 150 + self.rank * 50;
self.health = self.maxHealth;
self.speed = 1 + self.rank * 0.1;
// Boss gives massive experience
self.experience = 50 + self.rank * 25;
self.lastX = self.x;
self.lastY = self.y;
// Boss AI - more aggressive and smarter
self.chooseAction = function () {
// Bosses never miss turns and prefer attacking
var rand = Math.random();
if (rand < 0.6) return 'attack';
if (rand < 0.8) return 'defend';
return 'heal';
};
self.attack = function () {
var damage = 20 + self.rank * 5 + Math.floor(Math.random() * 15);
return damage;
};
self.defend = function () {
self.defending = true;
};
self.heal = function () {
var healAmount = 25 + self.rank * 3;
self.health = Math.min(self.maxHealth, self.health + healAmount);
return healAmount;
};
self.getName = function () {
var names = {
'slimeking': 'Slime King',
'orcking': 'Orc King',
'darkelflord': 'Dark Elf Lord',
'darkgolem': 'Dark Golem',
'demonking': 'Demon King',
'fallenangel': 'Fallen Angel',
'chaosgod': 'Chaos God'
};
return names[self.type] || 'Unknown Boss';
};
self.getRankName = function () {
var ranks = ['F', 'E', 'D', 'C', 'B', 'A', 'S', 'T', 'H', 'I', 'K', 'L', 'O', 'P'];
if (self.rank < 14) {
return ranks[self.rank] + ' BOSS';
} else {
var zPlusLevel = self.rank - 13;
return 'Z' + '+'.repeat(zPlusLevel) + ' BOSS';
}
};
self.takeDamage = function (damage) {
if (self.defending) {
damage = Math.floor(damage * 0.5);
self.defending = false;
}
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('hit').play();
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
var Enemy = Container.expand(function (type, succubusRank) {
var self = Container.call(this);
self.type = type || 'slime';
self.succubusRank = succubusRank || 0;
// Calculate enemy rank based on succubus rank
var enemyRank = Math.floor(self.succubusRank / 3) + 1; // Enemy rank increases every 3 succubus ranks
self.rank = enemyRank;
var graphics = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5
});
// Health scales with rank
self.maxHealth = 50 + self.rank * 30;
self.health = self.maxHealth;
self.speed = 1 + self.rank * 0.2;
// Experience scales based on enemy rank: F=5, E=7, D=10, C=12, B=15, A=18, S=22, etc.
var baseExp = 5;
if (self.rank === 0) {
// F rank
self.experience = 5;
} else if (self.rank === 1) {
// E rank
self.experience = 7;
} else if (self.rank === 2) {
// D rank
self.experience = 10;
} else if (self.rank === 3) {
// C rank
self.experience = 12;
} else if (self.rank === 4) {
// B rank
self.experience = 15;
} else if (self.rank === 5) {
// A rank
self.experience = 18;
} else if (self.rank === 6) {
// S rank
self.experience = 22;
} else {
// T-Z+ ranks
self.experience = 25 + (self.rank - 6) * 3;
}
self.lastX = self.x;
self.lastY = self.y;
// Enemy AI - can attack, defend, or heal
self.chooseAction = function () {
// F-rank enemies (succubus rank 0-2) have poor AI and sometimes miss turns
if (self.succubusRank <= 2 && Math.random() < 0.3) {
return 'miss'; // 30% chance to miss turn for F-rank enemies
}
var actions = ['attack', 'defend', 'heal'];
return actions[Math.floor(Math.random() * actions.length)];
};
self.attack = function () {
var damage = 10 + self.rank * 3 + Math.floor(Math.random() * 10);
return damage;
};
self.defend = function () {
// Reduce incoming damage by 50% next turn
self.defending = true;
};
self.heal = function () {
var healAmount = 15 + self.rank * 2;
self.health = Math.min(self.maxHealth, self.health + healAmount);
return healAmount;
};
self.getName = function () {
var names = {
'slime': 'Slime',
'goblin': 'Goblin',
'zombie': 'Zombie',
'skeleton': 'Skeleton',
'firemonster': 'Fire Monster',
'icemonster': 'Ice Monster',
'giantbat': 'Giant Bat',
'ghost': 'Ghost',
'enemysuccubus': 'Enemy Succubus',
'demon': 'Demon',
'demonking': 'Demon King',
'orc': 'Orc',
'darkelf': 'Dark Elf',
'giantrat': 'Giant Rat',
'giantspider': 'Giant Spider',
'wolf': 'Wolf',
'stonegolem': 'Stone Golem'
};
return names[self.type] || 'Unknown Enemy';
};
self.getRankName = function () {
var ranks = ['F', 'E', 'D', 'C', 'B', 'A', 'S', 'T', 'H', 'I', 'K', 'L', 'O', 'P'];
if (self.rank < 14) {
return ranks[self.rank];
} else {
var zPlusLevel = self.rank - 13;
return 'Z' + '+'.repeat(zPlusLevel);
}
};
self.takeDamage = function (damage) {
if (self.defending) {
damage = Math.floor(damage * 0.5);
self.defending = false;
}
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('hit').play();
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
var Projectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.targetX = 0;
self.targetY = 0;
self.damage = 10;
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 > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
var Succubus = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('succubus', {
anchorX: 0.5,
anchorY: 0.5
});
self.rank = 0; // F rank (0-22 = F to Z+)
self.experience = 0;
self.experienceToNext = 50; // Start at 50 exp needed for D rank
self.baseDamage = 15;
self.maxHealth = 50;
self.health = 50;
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
};
self.takeDamage = function (damage) {
if (self.shieldTurns > 0) {
// Shield blocks all damage
LK.effects.flashObject(self, 0x4169E1, 200); // Blue flash for shield
return false;
}
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0 && !self.isDead) {
self.isDead = true;
self.recoveryTurns = 2; // Will recover after 2 turns
LK.effects.flashObject(self, 0x800080, 1000); // Purple flash for death
}
return false;
};
self.gainExperience = function (exp) {
self.experience += exp;
if (self.experience >= self.experienceToNext) {
self.levelUp();
}
};
self.levelUp = function () {
if (self.rank < 22) {
// Max rank Z+
self.rank++;
self.experience = 0;
// Experience requirements: 50, 100, 150, 200, etc.
self.experienceToNext = 50 + self.rank * 50;
self.baseDamage = Math.floor(self.baseDamage * 1.2);
self.maxHealth += 15;
self.health = self.maxHealth;
LK.getSound('levelup').play();
LK.effects.flashObject(self, 0xffd700, 1000);
// Update visual appearance based on rank
var newScale = 1 + self.rank * 0.05;
var newAsset = 'succubus';
// Change appearance at specific ranks
if (self.rank >= 17) {
// G rank - celestial form
newAsset = 'succubusG';
} else if (self.rank >= 14) {
// Z rank - supremely crazy form
newAsset = 'succubusZ';
} else if (self.rank >= 6) {
// S rank - crown and peculiar form
newAsset = 'succubusS';
} else if (self.rank >= 5) {
// A rank - more beautiful appearance
newAsset = 'succubusA';
}
// If appearance changed, replace the graphics
if (newAsset !== 'succubus' || newAsset === 'succubus' && self.rank >= 5) {
self.removeChild(graphics);
graphics = self.attachAsset(newAsset, {
anchorX: 0.5,
anchorY: 0.5
});
}
tween(graphics, {
scaleX: newScale,
scaleY: newScale
}, {
duration: 500
});
// Spawn boss when leveling up
shouldSpawnBoss = true;
// Unlock new backgrounds at S rank
unlockNewBackgrounds();
}
};
self.isDead = false;
self.recoveryTurns = 0;
self.shieldTurns = 0;
self.hasIncrement = false;
self.processRecovery = function () {
if (self.isDead && self.recoveryTurns > 0) {
self.recoveryTurns--;
if (self.recoveryTurns === 0) {
// Recover to 25% health
self.health = Math.floor(self.maxHealth * 0.25);
self.isDead = false;
LK.effects.flashObject(self, 0x00ff00, 1000); // Green flash for recovery
}
}
// Process shield duration
if (self.shieldTurns > 0) {
self.shieldTurns--;
}
};
self.getRankName = function () {
// F(0), E(1), D(2), C(3), B(4), A(5), S(6), T(7), H(8), I(9), K(10), L(11), O(12), P(13), Z(14-22)
var ranks = ['F', 'E', 'D', 'C', 'B', 'A', 'S', 'T', 'H', 'I', 'K', 'L', 'O', 'P'];
if (self.rank < 14) {
return ranks[self.rank];
} else {
var zPlusLevel = self.rank - 13;
return 'Z' + '+'.repeat(zPlusLevel);
}
};
return self;
});
var Summoner = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('summoner', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.maxHealth = 120;
self.health = 120;
self.magic = 0;
self.lastX = self.x;
self.lastY = self.y;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return true;
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Dark/spooky music for dark versions of zones
// Peaceful music for sky, mountain zones
// Strange/weird music for snow, hot, underwater zones
// Rock music for dungeon, maze, castle, demon castle zones
// Happy/cheerful music for meadow, city, forest zones
var summoner = null;
var succubus = null;
var currentEnemy = null;
var enemyTypes = ['slime', 'goblin', 'zombie', 'skeleton', 'firemonster', 'icemonster', 'giantbat', 'ghost', 'enemysuccubus', 'demon', 'demonking', 'orc', 'darkelf', 'giantrat', 'giantspider', 'wolf', 'stonegolem'];
var currentWave = 1;
var enemiesKilled = 0;
var isPlayerTurn = true;
var gameState = 'menu'; // 'menu', 'battle' or 'gameover'
var turnCounter = 0; // Track total turns for health regeneration
var shouldSpawnBoss = false;
var currentBoss = null;
var combatCounter = 0; // Track combats for boss spawning every 10
var currentBackground = 0; // Track current background zone
var backgroundNames = ['Dungeon', 'Meadow', 'Mountain', 'City', 'Castle', 'Demon Castle', 'Sky', 'Underwater', 'Snow', 'Forest', 'Maze', 'Hot Zone', 'Space', 'White'];
var backgroundMusic = ['rockmusic', 'happymusic', 'peacefulmusic', 'happymusic', 'rockmusic', 'rockmusic', 'peacefulmusic', 'strangemusic', 'strangemusic', 'happymusic', 'rockmusic', 'strangemusic', 'peacefulmusic', 'peacefulmusic'];
var darkBackgroundMusic = ['darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic'];
var unlockedBackgrounds = storage.unlockedBackgrounds || [0]; // Start with dungeon unlocked
// Start Menu UI
var titleText = new Text2('SUCCUBUS SUMMONER', {
size: 80,
fill: 0xFF69B4
});
titleText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(titleText);
var startButton = new Text2('TAP TO START', {
size: 60,
fill: 0xFFFFFF
});
startButton.anchor.set(0.5, 0.5);
startButton.y = 200;
LK.gui.center.addChild(startButton);
var backgroundSelectText = new Text2('Background: Dungeon', {
size: 40,
fill: 0x4ECDC4
});
backgroundSelectText.anchor.set(0.5, 0.5);
backgroundSelectText.y = 300;
LK.gui.center.addChild(backgroundSelectText);
var backgroundChangeButton = new Text2('Change Background', {
size: 35,
fill: 0x45B7D1
});
backgroundChangeButton.anchor.set(0.5, 0.5);
backgroundChangeButton.y = 380;
LK.gui.center.addChild(backgroundChangeButton);
var bossWarningText = new Text2('BOSS APPROACHING!', {
size: 60,
fill: 0xFF0000
});
bossWarningText.anchor.set(0.5, 0.5);
bossWarningText.alpha = 0;
LK.gui.center.addChild(bossWarningText);
// UI Elements
var summonerHealthText = new Text2('Summoner HP: 120/120', {
size: 40,
fill: 0x00FF00
});
summonerHealthText.anchor.set(0, 0);
summonerHealthText.x = 50;
summonerHealthText.y = 100;
summonerHealthText.alpha = 0;
LK.gui.topLeft.addChild(summonerHealthText);
var succubusHealthText = new Text2('Succubus HP: 50/50 | Rank: F (0/50)', {
size: 35,
fill: 0xFF69B4
});
succubusHealthText.anchor.set(0, 0);
succubusHealthText.x = 50;
succubusHealthText.y = 150;
succubusHealthText.alpha = 0;
LK.gui.topLeft.addChild(succubusHealthText);
var magicText = new Text2('Magic: 0', {
size: 40,
fill: 0x4169E1
});
magicText.anchor.set(0, 0);
magicText.x = 50;
magicText.y = 200;
magicText.alpha = 0;
LK.gui.topLeft.addChild(magicText);
var enemyHealthText = new Text2('Enemy HP: 0/0 | Rank: F', {
size: 35,
fill: 0xFF0000
});
enemyHealthText.anchor.set(1, 0);
enemyHealthText.x = -50;
enemyHealthText.y = 100;
enemyHealthText.alpha = 0;
LK.gui.topRight.addChild(enemyHealthText);
var enemyNameText = new Text2('Enemy: None', {
size: 30,
fill: 0xFFFFFF
});
enemyNameText.anchor.set(1, 0);
enemyNameText.x = -50;
enemyNameText.y = 140;
enemyNameText.alpha = 0;
LK.gui.topRight.addChild(enemyNameText);
var turnText = new Text2('Your Turn - Choose Action:', {
size: 50,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
turnText.alpha = 0;
LK.gui.top.addChild(turnText);
var currentBackgroundText = new Text2('Zone: Dungeon', {
size: 30,
fill: 0xFFD700
});
currentBackgroundText.anchor.set(0.5, 0);
currentBackgroundText.y = 50;
LK.gui.top.addChild(currentBackgroundText);
// Action buttons
var attackButton = new Text2('1. Sword Attack (15 + Magic damage)', {
size: 45,
fill: 0xFF6B6B
});
attackButton.anchor.set(0.5, 0);
attackButton.x = 0;
attackButton.y = 300;
attackButton.alpha = 0;
LK.gui.center.addChild(attackButton);
var healButton = new Text2('2. Heal Succubus (Cost: 35 Summoner HP)', {
size: 45,
fill: 0x4ECDC4
});
healButton.anchor.set(0.5, 0);
healButton.x = 0;
healButton.y = 380;
healButton.alpha = 0;
LK.gui.center.addChild(healButton);
var defendButton = new Text2('3. Defend (Gain +10 Magic)', {
size: 45,
fill: 0x45B7D1
});
defendButton.anchor.set(0.5, 0);
defendButton.x = 0;
defendButton.y = 460;
defendButton.alpha = 0;
LK.gui.center.addChild(defendButton);
var basicHealButton = new Text2('4. Basic Healing (Cost: 20 Magic)', {
size: 45,
fill: 0x90EE90
});
basicHealButton.anchor.set(0.5, 0);
basicHealButton.x = 0;
basicHealButton.y = 540;
basicHealButton.alpha = 0;
LK.gui.center.addChild(basicHealButton);
var basicMagicButton = new Text2('5. Basic Magic Attack (Cost: 5 Magic)', {
size: 45,
fill: 0x9370DB
});
basicMagicButton.anchor.set(0.5, 0);
basicMagicButton.x = 0;
basicMagicButton.y = 620;
basicMagicButton.alpha = 0;
LK.gui.center.addChild(basicMagicButton);
var eternalKissButton = new Text2('6. Eternal Kiss (Cost: 500 Magic)', {
size: 45,
fill: 0xFF1493
});
eternalKissButton.anchor.set(0.5, 0);
eternalKissButton.x = 0;
eternalKissButton.y = 700;
eternalKissButton.alpha = 0;
LK.gui.center.addChild(eternalKissButton);
var incrementButton = new Text2('7. Increment (Cost: 30 Magic)', {
size: 45,
fill: 0xFFD700
});
incrementButton.anchor.set(0.5, 0);
incrementButton.x = 0;
incrementButton.y = 780;
incrementButton.alpha = 0;
LK.gui.center.addChild(incrementButton);
// Initialize characters (hidden initially)
summoner = game.addChild(new Summoner());
summoner.x = 800;
summoner.y = 1800;
summoner.alpha = 0;
succubus = game.addChild(new Succubus());
succubus.x = 1200;
succubus.y = 1800;
succubus.alpha = 0;
function spawnNewEnemy() {
if (currentEnemy) {
currentEnemy.destroy();
}
if (currentBoss) {
currentBoss.destroy();
currentBoss = null;
}
// Check for boss every 10 combats
combatCounter++;
if (combatCounter % 10 === 0) {
showBossWarning();
LK.setTimeout(spawnBoss, 2000);
return;
}
// Check if we should spawn a boss
if (shouldSpawnBoss) {
shouldSpawnBoss = false;
spawnBoss();
return;
}
// Enemy selection based on succubus rank
var succubusRank = succubus.rank;
var availableEnemies = [];
// F rank: slime, goblin, zombie, wolf
if (succubusRank === 0) {
availableEnemies = ['slime', 'goblin', 'zombie', 'wolf'];
}
// E rank: add darkelf, giantrat, giantspider
else if (succubusRank === 1) {
availableEnemies = ['slime', 'goblin', 'zombie', 'wolf', 'darkelf', 'giantrat', 'giantspider'];
}
// D+ ranks: add orc after D rank
else if (succubusRank >= 2 && succubusRank <= 5) {
availableEnemies = ['slime', 'goblin', 'zombie', 'wolf', 'darkelf', 'giantrat', 'giantspider', 'orc', 'skeleton', 'firemonster', 'icemonster'];
}
// A+ ranks: add stonegolem after A rank
else if (succubusRank >= 5 && succubusRank <= 8) {
availableEnemies = ['slime', 'goblin', 'zombie', 'wolf', 'darkelf', 'giantrat', 'giantspider', 'orc', 'skeleton', 'firemonster', 'icemonster', 'stonegolem', 'giantbat', 'ghost', 'enemysuccubus'];
}
// S to Z+ ranks: all enemies including demon and demonking
else {
availableEnemies = enemyTypes;
}
var enemyType = availableEnemies[Math.floor(Math.random() * availableEnemies.length)];
currentEnemy = new Enemy(enemyType, succubusRank);
// Position enemy closer to player
currentEnemy.x = 1024;
currentEnemy.y = 1200;
game.addChild(currentEnemy);
LK.getSound('enemyspawn').play();
}
function startGame() {
gameState = 'battle';
// Hide menu UI
titleText.alpha = 0;
startButton.alpha = 0;
backgroundSelectText.alpha = 0;
backgroundChangeButton.alpha = 0;
// Show battle UI
summonerHealthText.alpha = 1;
succubusHealthText.alpha = 1;
magicText.alpha = 1;
enemyHealthText.alpha = 1;
enemyNameText.alpha = 1;
turnText.alpha = 1;
attackButton.alpha = 1;
healButton.alpha = 1;
defendButton.alpha = 1;
basicHealButton.alpha = 1;
basicMagicButton.alpha = 1;
eternalKissButton.alpha = 1;
incrementButton.alpha = 1;
// Show characters
summoner.alpha = 1;
succubus.alpha = 1;
// Start background music based on zone type
var isDarkVersion = succubus.rank >= 6 && currentBackground >= 9;
var musicToPlay;
if (isDarkVersion) {
musicToPlay = darkBackgroundMusic[currentBackground];
} else {
musicToPlay = backgroundMusic[currentBackground];
}
LK.playMusic(musicToPlay);
// Spawn first enemy
spawnNewEnemy();
updateUI();
}
function changeBackground() {
var nextIndex = 0;
for (var i = 0; i < unlockedBackgrounds.length; i++) {
if (unlockedBackgrounds[i] === currentBackground) {
nextIndex = (i + 1) % unlockedBackgrounds.length;
break;
}
}
currentBackground = unlockedBackgrounds[nextIndex];
var displayName = backgroundNames[currentBackground];
// Check if this is a dark version (unlocked at S rank)
var isDarkVersion = succubus && succubus.rank >= 6 && currentBackground >= 9;
if (isDarkVersion) {
displayName = 'Dark ' + displayName;
}
backgroundSelectText.setText('Background: ' + displayName);
currentBackgroundText.setText('Zone: ' + displayName);
// Update background color based on zone
var backgroundColors = [0x2c1810, 0x4a5c2a, 0x5d4e37, 0x708090, 0x8b4513, 0x4b0000, 0x87ceeb, 0x006994, 0xf0f8ff, 0x228b22, 0x1a1a1a, 0xff4500, 0x000000, 0xffffff];
game.setBackgroundColor(backgroundColors[currentBackground]);
// Play appropriate music based on zone and if it's dark version
var musicToPlay;
if (isDarkVersion) {
musicToPlay = darkBackgroundMusic[currentBackground];
} else {
musicToPlay = backgroundMusic[currentBackground];
}
if (gameState === 'battle') {
LK.playMusic(musicToPlay);
}
// Save current background
storage.currentBackground = currentBackground;
}
function unlockNewBackgrounds() {
// Unlock all backgrounds when reaching S rank, including dark versions
if (succubus.rank >= 6) {
var allBackgrounds = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
for (var i = 0; i < allBackgrounds.length; i++) {
if (unlockedBackgrounds.indexOf(allBackgrounds[i]) === -1) {
unlockedBackgrounds.push(allBackgrounds[i]);
}
}
storage.unlockedBackgrounds = unlockedBackgrounds;
}
}
function showBossWarning() {
bossWarningText.alpha = 1;
tween(bossWarningText, {
alpha: 0
}, {
duration: 2000
});
LK.playMusic('bossmusic');
}
function updateUI() {
summonerHealthText.setText('Summoner HP: ' + summoner.health + '/' + summoner.maxHealth);
if (succubus.isDead) {
succubusHealthText.setText('Succubus: DEAD (Recovery in ' + succubus.recoveryTurns + ' turns)');
} else {
var expNeeded = succubus.experienceToNext - succubus.experience;
var shieldText = succubus.shieldTurns > 0 ? ' | SHIELD: ' + succubus.shieldTurns + ' turns' : '';
var incrementText = succubus.hasIncrement ? ' | NEXT ATTACK x2' : '';
succubusHealthText.setText('Succubus HP: ' + succubus.health + '/' + succubus.maxHealth + ' | Rank: ' + succubus.getRankName() + ' (' + succubus.experience + '/' + succubus.experienceToNext + ')' + shieldText + incrementText);
}
magicText.setText('Magic: ' + summoner.magic);
if (currentEnemy) {
enemyHealthText.setText('Enemy HP: ' + currentEnemy.health + '/' + currentEnemy.maxHealth + ' | Rank: ' + currentEnemy.getRankName());
enemyNameText.setText('Enemy: ' + currentEnemy.getName());
} else {
enemyNameText.setText('Enemy: None');
}
if (isPlayerTurn) {
if (succubus.isDead) {
turnText.setText('Succubus is dead! Only defend available:');
attackButton.alpha = 0.3;
healButton.alpha = 0.3;
defendButton.alpha = 1;
basicHealButton.alpha = 0.3;
basicMagicButton.alpha = 0.3;
eternalKissButton.alpha = 0.3;
incrementButton.alpha = 0.3;
} else {
turnText.setText('Your Turn - Choose Action:');
attackButton.alpha = summoner.health > 35 ? 1 : 0.3;
healButton.alpha = summoner.health > 35 ? 1 : 0.3;
defendButton.alpha = 1;
basicHealButton.alpha = summoner.magic >= 20 ? 1 : 0.3;
basicMagicButton.alpha = summoner.magic >= 5 ? 1 : 0.3;
eternalKissButton.alpha = summoner.magic >= 500 && summoner.health >= 100 ? 1 : 0.3;
incrementButton.alpha = summoner.magic >= 30 ? 1 : 0.3;
}
} else {
turnText.setText('Enemy Turn...');
attackButton.alpha = 0.3;
healButton.alpha = 0.3;
defendButton.alpha = 0.3;
basicHealButton.alpha = 0.3;
basicMagicButton.alpha = 0.3;
eternalKissButton.alpha = 0.3;
incrementButton.alpha = 0.3;
}
}
function playerAttack() {
if (!isPlayerTurn || !currentEnemy || succubus.isDead) return; // Can't attack if succubus is dead
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
var damage = succubus.baseDamage + summoner.magic;
if (succubus.hasIncrement) {
damage *= 2;
succubus.hasIncrement = false;
LK.effects.flashObject(succubus, 0xFFD700, 500); // Gold flash for increment
}
summoner.magic = 0; // Magic is consumed
LK.getSound('hit').play();
if (currentEnemy.takeDamage(damage)) {
// Enemy died
succubus.gainExperience(currentEnemy.experience);
enemiesKilled++;
LK.setScore(enemiesKilled);
currentWave++;
spawnNewEnemy();
} else {
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
}
updateUI();
}
function playerHeal() {
if (!isPlayerTurn || summoner.health <= 35 || succubus.isDead) return; // Can't heal dead succubus
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.health -= 35;
succubus.heal(35);
LK.getSound('levelup').play();
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
function playerDefend() {
if (!isPlayerTurn) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic += 10;
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
function enemyTurn() {
if (!currentEnemy || !succubus) return;
// Process succubus recovery first
succubus.processRecovery();
var action = currentEnemy.chooseAction();
var message = '';
if (action === 'miss') {
message = 'Enemy failed to act this turn!';
} else if (action === 'attack') {
var damage = currentEnemy.attack();
// If succubus is dead, attack summoner instead
if (succubus.isDead) {
summoner.takeDamage(damage);
message = 'Enemy attacks summoner for ' + damage + ' damage!';
} else {
succubus.takeDamage(damage);
message = 'Enemy attacks succubus for ' + damage + ' damage!';
}
} else if (action === 'defend') {
currentEnemy.defend();
message = 'Enemy is defending!';
} else if (action === 'heal') {
var healAmount = currentEnemy.heal();
message = 'Enemy heals for ' + healAmount + ' HP!';
}
// Show action message briefly
turnText.setText(message);
LK.setTimeout(function () {
isPlayerTurn = true;
updateUI();
}, 1500);
}
function basicHeal() {
if (!isPlayerTurn || summoner.magic < 20) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic -= 20;
summoner.health = Math.min(summoner.maxHealth, summoner.health + 10);
if (!succubus.isDead) {
succubus.heal(10);
}
LK.getSound('levelup').play();
LK.effects.flashObject(summoner, 0x90EE90, 500);
if (!succubus.isDead) {
LK.effects.flashObject(succubus, 0x90EE90, 500);
}
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
function basicMagic() {
if (!isPlayerTurn || !currentEnemy || summoner.magic < 5) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic -= 5;
var damage = 5;
LK.getSound('hit').play();
LK.effects.flashObject(summoner, 0x9370DB, 500);
if (currentEnemy.takeDamage(damage)) {
// Enemy died
succubus.gainExperience(currentEnemy.experience);
enemiesKilled++;
LK.setScore(enemiesKilled);
currentWave++;
spawnNewEnemy();
} else {
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
}
updateUI();
}
function eternalKiss() {
if (!isPlayerTurn || summoner.magic < 500 || summoner.health < 100 || succubus.isDead) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic -= 500;
summoner.health -= 100;
succubus.health = 999999;
succubus.maxHealth = 999999;
succubus.shieldTurns = 25;
succubus.baseDamage = Math.floor(succubus.baseDamage * 5); // Enormous strength
LK.getSound('levelup').play();
LK.effects.flashObject(summoner, 0xFF1493, 1000);
LK.effects.flashObject(succubus, 0xFF1493, 1000);
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
function increment() {
if (!isPlayerTurn || summoner.magic < 30 || succubus.isDead) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic -= 30;
succubus.hasIncrement = true;
LK.getSound('levelup').play();
LK.effects.flashObject(succubus, 0xFFD700, 500);
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
// Event handlers
attackButton.down = playerAttack;
healButton.down = playerHeal;
defendButton.down = playerDefend;
basicHealButton.down = basicHeal;
basicMagicButton.down = basicMagic;
eternalKissButton.down = eternalKiss;
incrementButton.down = increment;
startButton.down = startGame;
backgroundChangeButton.down = changeBackground;
// Load saved data
currentBackground = storage.currentBackground || 0;
backgroundSelectText.setText('Background: ' + backgroundNames[currentBackground]);
currentBackgroundText.setText('Zone: ' + backgroundNames[currentBackground]);
var backgroundColors = [0x2c1810, 0x4a5c2a, 0x5d4e37, 0x708090, 0x8b4513, 0x4b0000, 0x87ceeb, 0x006994, 0xf0f8ff, 0x228b22, 0x1a1a1a, 0xff4500, 0x000000, 0xffffff];
game.setBackgroundColor(backgroundColors[currentBackground]);
// Play menu music
LK.playMusic('menumusic');
game.update = function () {
if (gameState === 'battle') {
updateUI();
}
};
function spawnBoss() {
var succubusRank = succubus.rank;
var bossType = '';
// Determine boss type based on succubus rank
if (succubusRank === 1) {
// E rank -> Slime King
bossType = 'slimeking';
} else if (succubusRank === 2) {
// D rank -> Orc King
bossType = 'orcking';
} else if (succubusRank === 3) {
// C rank -> Dark Elf Lord
bossType = 'darkelflord';
} else if (succubusRank === 5) {
// A rank -> Dark Golem
bossType = 'darkgolem';
} else if (succubusRank === 6) {
// S rank -> Demon King
bossType = 'demonking';
} else if (succubusRank >= 14) {
// Z rank -> Fallen Angel
bossType = 'fallenangel';
} else if (succubusRank >= 17) {
// G rank (new rank) -> Chaos God
bossType = 'chaosgod';
} else {
// For other ranks, repeat boss cycle
var bossIndex = succubusRank % 6;
var bossCycle = ['slimeking', 'orcking', 'darkelflord', 'darkgolem', 'demonking', 'fallenangel'];
bossType = bossCycle[bossIndex];
}
currentBoss = new Boss(bossType, succubusRank);
currentEnemy = currentBoss; // Use same reference for combat system
currentEnemy.x = 1024;
currentEnemy.y = 1200;
game.addChild(currentEnemy);
LK.getSound('enemyspawn').play();
LK.effects.flashScreen(0xff0000, 500); // Red flash for boss spawn
} /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Boss = Container.expand(function (bossType, succubusRank) {
var self = Container.call(this);
self.type = bossType || 'slimekung';
self.succubusRank = succubusRank || 0;
self.rank = succubusRank; // Boss rank matches succubus rank
self.isBoss = true;
// Boss asset mapping
var bossAssets = {
'slimeking': 'slime',
// Will be scaled up
'orcking': 'goblin',
// Will be scaled up
'darkelflord': 'skeleton',
// Will be scaled up
'darkgolem': 'firemonster',
// Will be scaled up
'demonking': 'demonking',
'fallenangel': 'fallenangel',
'chaosgod': 'chaosgod'
};
var assetName = bossAssets[self.type] || 'slime';
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Scale up boss
graphics.scaleX = 1.5;
graphics.scaleY = 1.5;
// Boss health is much higher
self.maxHealth = 150 + self.rank * 50;
self.health = self.maxHealth;
self.speed = 1 + self.rank * 0.1;
// Boss gives massive experience
self.experience = 50 + self.rank * 25;
self.lastX = self.x;
self.lastY = self.y;
// Boss AI - more aggressive and smarter
self.chooseAction = function () {
// Bosses never miss turns and prefer attacking
var rand = Math.random();
if (rand < 0.6) return 'attack';
if (rand < 0.8) return 'defend';
return 'heal';
};
self.attack = function () {
var damage = 20 + self.rank * 5 + Math.floor(Math.random() * 15);
return damage;
};
self.defend = function () {
self.defending = true;
};
self.heal = function () {
var healAmount = 25 + self.rank * 3;
self.health = Math.min(self.maxHealth, self.health + healAmount);
return healAmount;
};
self.getName = function () {
var names = {
'slimeking': 'Slime King',
'orcking': 'Orc King',
'darkelflord': 'Dark Elf Lord',
'darkgolem': 'Dark Golem',
'demonking': 'Demon King',
'fallenangel': 'Fallen Angel',
'chaosgod': 'Chaos God'
};
return names[self.type] || 'Unknown Boss';
};
self.getRankName = function () {
var ranks = ['F', 'E', 'D', 'C', 'B', 'A', 'S', 'T', 'H', 'I', 'K', 'L', 'O', 'P'];
if (self.rank < 14) {
return ranks[self.rank] + ' BOSS';
} else {
var zPlusLevel = self.rank - 13;
return 'Z' + '+'.repeat(zPlusLevel) + ' BOSS';
}
};
self.takeDamage = function (damage) {
if (self.defending) {
damage = Math.floor(damage * 0.5);
self.defending = false;
}
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('hit').play();
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
var Enemy = Container.expand(function (type, succubusRank) {
var self = Container.call(this);
self.type = type || 'slime';
self.succubusRank = succubusRank || 0;
// Calculate enemy rank based on succubus rank
var enemyRank = Math.floor(self.succubusRank / 3) + 1; // Enemy rank increases every 3 succubus ranks
self.rank = enemyRank;
var graphics = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5
});
// Health scales with rank
self.maxHealth = 50 + self.rank * 30;
self.health = self.maxHealth;
self.speed = 1 + self.rank * 0.2;
// Experience scales based on enemy rank: F=5, E=7, D=10, C=12, B=15, A=18, S=22, etc.
var baseExp = 5;
if (self.rank === 0) {
// F rank
self.experience = 5;
} else if (self.rank === 1) {
// E rank
self.experience = 7;
} else if (self.rank === 2) {
// D rank
self.experience = 10;
} else if (self.rank === 3) {
// C rank
self.experience = 12;
} else if (self.rank === 4) {
// B rank
self.experience = 15;
} else if (self.rank === 5) {
// A rank
self.experience = 18;
} else if (self.rank === 6) {
// S rank
self.experience = 22;
} else {
// T-Z+ ranks
self.experience = 25 + (self.rank - 6) * 3;
}
self.lastX = self.x;
self.lastY = self.y;
// Enemy AI - can attack, defend, or heal
self.chooseAction = function () {
// F-rank enemies (succubus rank 0-2) have poor AI and sometimes miss turns
if (self.succubusRank <= 2 && Math.random() < 0.3) {
return 'miss'; // 30% chance to miss turn for F-rank enemies
}
var actions = ['attack', 'defend', 'heal'];
return actions[Math.floor(Math.random() * actions.length)];
};
self.attack = function () {
var damage = 10 + self.rank * 3 + Math.floor(Math.random() * 10);
return damage;
};
self.defend = function () {
// Reduce incoming damage by 50% next turn
self.defending = true;
};
self.heal = function () {
var healAmount = 15 + self.rank * 2;
self.health = Math.min(self.maxHealth, self.health + healAmount);
return healAmount;
};
self.getName = function () {
var names = {
'slime': 'Slime',
'goblin': 'Goblin',
'zombie': 'Zombie',
'skeleton': 'Skeleton',
'firemonster': 'Fire Monster',
'icemonster': 'Ice Monster',
'giantbat': 'Giant Bat',
'ghost': 'Ghost',
'enemysuccubus': 'Enemy Succubus',
'demon': 'Demon',
'demonking': 'Demon King',
'orc': 'Orc',
'darkelf': 'Dark Elf',
'giantrat': 'Giant Rat',
'giantspider': 'Giant Spider',
'wolf': 'Wolf',
'stonegolem': 'Stone Golem'
};
return names[self.type] || 'Unknown Enemy';
};
self.getRankName = function () {
var ranks = ['F', 'E', 'D', 'C', 'B', 'A', 'S', 'T', 'H', 'I', 'K', 'L', 'O', 'P'];
if (self.rank < 14) {
return ranks[self.rank];
} else {
var zPlusLevel = self.rank - 13;
return 'Z' + '+'.repeat(zPlusLevel);
}
};
self.takeDamage = function (damage) {
if (self.defending) {
damage = Math.floor(damage * 0.5);
self.defending = false;
}
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('hit').play();
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
var Projectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.targetX = 0;
self.targetY = 0;
self.damage = 10;
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 > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
var Succubus = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('succubus', {
anchorX: 0.5,
anchorY: 0.5
});
self.rank = 0; // F rank (0-22 = F to Z+)
self.experience = 0;
self.experienceToNext = 50; // Start at 50 exp needed for D rank
self.baseDamage = 15;
self.maxHealth = 50;
self.health = 50;
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
};
self.takeDamage = function (damage) {
if (self.shieldTurns > 0) {
// Shield blocks all damage
LK.effects.flashObject(self, 0x4169E1, 200); // Blue flash for shield
return false;
}
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0 && !self.isDead) {
self.isDead = true;
self.recoveryTurns = 2; // Will recover after 2 turns
LK.effects.flashObject(self, 0x800080, 1000); // Purple flash for death
}
return false;
};
self.gainExperience = function (exp) {
self.experience += exp;
if (self.experience >= self.experienceToNext) {
self.levelUp();
}
};
self.levelUp = function () {
if (self.rank < 22) {
// Max rank Z+
self.rank++;
self.experience = 0;
// Experience requirements: 50, 100, 150, 200, etc.
self.experienceToNext = 50 + self.rank * 50;
self.baseDamage = Math.floor(self.baseDamage * 1.2);
self.maxHealth += 15;
self.health = self.maxHealth;
LK.getSound('levelup').play();
LK.effects.flashObject(self, 0xffd700, 1000);
// Update visual appearance based on rank
var newScale = 1 + self.rank * 0.05;
var newAsset = 'succubus';
// Change appearance at specific ranks
if (self.rank >= 17) {
// G rank - celestial form
newAsset = 'succubusG';
} else if (self.rank >= 14) {
// Z rank - supremely crazy form
newAsset = 'succubusZ';
} else if (self.rank >= 6) {
// S rank - crown and peculiar form
newAsset = 'succubusS';
} else if (self.rank >= 5) {
// A rank - more beautiful appearance
newAsset = 'succubusA';
}
// If appearance changed, replace the graphics
if (newAsset !== 'succubus' || newAsset === 'succubus' && self.rank >= 5) {
self.removeChild(graphics);
graphics = self.attachAsset(newAsset, {
anchorX: 0.5,
anchorY: 0.5
});
}
tween(graphics, {
scaleX: newScale,
scaleY: newScale
}, {
duration: 500
});
// Spawn boss when leveling up
shouldSpawnBoss = true;
// Unlock new backgrounds at S rank
unlockNewBackgrounds();
}
};
self.isDead = false;
self.recoveryTurns = 0;
self.shieldTurns = 0;
self.hasIncrement = false;
self.processRecovery = function () {
if (self.isDead && self.recoveryTurns > 0) {
self.recoveryTurns--;
if (self.recoveryTurns === 0) {
// Recover to 25% health
self.health = Math.floor(self.maxHealth * 0.25);
self.isDead = false;
LK.effects.flashObject(self, 0x00ff00, 1000); // Green flash for recovery
}
}
// Process shield duration
if (self.shieldTurns > 0) {
self.shieldTurns--;
}
};
self.getRankName = function () {
// F(0), E(1), D(2), C(3), B(4), A(5), S(6), T(7), H(8), I(9), K(10), L(11), O(12), P(13), Z(14-22)
var ranks = ['F', 'E', 'D', 'C', 'B', 'A', 'S', 'T', 'H', 'I', 'K', 'L', 'O', 'P'];
if (self.rank < 14) {
return ranks[self.rank];
} else {
var zPlusLevel = self.rank - 13;
return 'Z' + '+'.repeat(zPlusLevel);
}
};
return self;
});
var Summoner = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('summoner', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.maxHealth = 120;
self.health = 120;
self.magic = 0;
self.lastX = self.x;
self.lastY = self.y;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return true;
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Dark/spooky music for dark versions of zones
// Peaceful music for sky, mountain zones
// Strange/weird music for snow, hot, underwater zones
// Rock music for dungeon, maze, castle, demon castle zones
// Happy/cheerful music for meadow, city, forest zones
var summoner = null;
var succubus = null;
var currentEnemy = null;
var enemyTypes = ['slime', 'goblin', 'zombie', 'skeleton', 'firemonster', 'icemonster', 'giantbat', 'ghost', 'enemysuccubus', 'demon', 'demonking', 'orc', 'darkelf', 'giantrat', 'giantspider', 'wolf', 'stonegolem'];
var currentWave = 1;
var enemiesKilled = 0;
var isPlayerTurn = true;
var gameState = 'menu'; // 'menu', 'battle' or 'gameover'
var turnCounter = 0; // Track total turns for health regeneration
var shouldSpawnBoss = false;
var currentBoss = null;
var combatCounter = 0; // Track combats for boss spawning every 10
var currentBackground = 0; // Track current background zone
var backgroundNames = ['Dungeon', 'Meadow', 'Mountain', 'City', 'Castle', 'Demon Castle', 'Sky', 'Underwater', 'Snow', 'Forest', 'Maze', 'Hot Zone', 'Space', 'White'];
var backgroundMusic = ['rockmusic', 'happymusic', 'peacefulmusic', 'happymusic', 'rockmusic', 'rockmusic', 'peacefulmusic', 'strangemusic', 'strangemusic', 'happymusic', 'rockmusic', 'strangemusic', 'peacefulmusic', 'peacefulmusic'];
var darkBackgroundMusic = ['darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic', 'darkmusic'];
var unlockedBackgrounds = storage.unlockedBackgrounds || [0]; // Start with dungeon unlocked
// Start Menu UI
var titleText = new Text2('SUCCUBUS SUMMONER', {
size: 80,
fill: 0xFF69B4
});
titleText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(titleText);
var startButton = new Text2('TAP TO START', {
size: 60,
fill: 0xFFFFFF
});
startButton.anchor.set(0.5, 0.5);
startButton.y = 200;
LK.gui.center.addChild(startButton);
var backgroundSelectText = new Text2('Background: Dungeon', {
size: 40,
fill: 0x4ECDC4
});
backgroundSelectText.anchor.set(0.5, 0.5);
backgroundSelectText.y = 300;
LK.gui.center.addChild(backgroundSelectText);
var backgroundChangeButton = new Text2('Change Background', {
size: 35,
fill: 0x45B7D1
});
backgroundChangeButton.anchor.set(0.5, 0.5);
backgroundChangeButton.y = 380;
LK.gui.center.addChild(backgroundChangeButton);
var bossWarningText = new Text2('BOSS APPROACHING!', {
size: 60,
fill: 0xFF0000
});
bossWarningText.anchor.set(0.5, 0.5);
bossWarningText.alpha = 0;
LK.gui.center.addChild(bossWarningText);
// UI Elements
var summonerHealthText = new Text2('Summoner HP: 120/120', {
size: 40,
fill: 0x00FF00
});
summonerHealthText.anchor.set(0, 0);
summonerHealthText.x = 50;
summonerHealthText.y = 100;
summonerHealthText.alpha = 0;
LK.gui.topLeft.addChild(summonerHealthText);
var succubusHealthText = new Text2('Succubus HP: 50/50 | Rank: F (0/50)', {
size: 35,
fill: 0xFF69B4
});
succubusHealthText.anchor.set(0, 0);
succubusHealthText.x = 50;
succubusHealthText.y = 150;
succubusHealthText.alpha = 0;
LK.gui.topLeft.addChild(succubusHealthText);
var magicText = new Text2('Magic: 0', {
size: 40,
fill: 0x4169E1
});
magicText.anchor.set(0, 0);
magicText.x = 50;
magicText.y = 200;
magicText.alpha = 0;
LK.gui.topLeft.addChild(magicText);
var enemyHealthText = new Text2('Enemy HP: 0/0 | Rank: F', {
size: 35,
fill: 0xFF0000
});
enemyHealthText.anchor.set(1, 0);
enemyHealthText.x = -50;
enemyHealthText.y = 100;
enemyHealthText.alpha = 0;
LK.gui.topRight.addChild(enemyHealthText);
var enemyNameText = new Text2('Enemy: None', {
size: 30,
fill: 0xFFFFFF
});
enemyNameText.anchor.set(1, 0);
enemyNameText.x = -50;
enemyNameText.y = 140;
enemyNameText.alpha = 0;
LK.gui.topRight.addChild(enemyNameText);
var turnText = new Text2('Your Turn - Choose Action:', {
size: 50,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0);
turnText.alpha = 0;
LK.gui.top.addChild(turnText);
var currentBackgroundText = new Text2('Zone: Dungeon', {
size: 30,
fill: 0xFFD700
});
currentBackgroundText.anchor.set(0.5, 0);
currentBackgroundText.y = 50;
LK.gui.top.addChild(currentBackgroundText);
// Action buttons
var attackButton = new Text2('1. Sword Attack (15 + Magic damage)', {
size: 45,
fill: 0xFF6B6B
});
attackButton.anchor.set(0.5, 0);
attackButton.x = 0;
attackButton.y = 300;
attackButton.alpha = 0;
LK.gui.center.addChild(attackButton);
var healButton = new Text2('2. Heal Succubus (Cost: 35 Summoner HP)', {
size: 45,
fill: 0x4ECDC4
});
healButton.anchor.set(0.5, 0);
healButton.x = 0;
healButton.y = 380;
healButton.alpha = 0;
LK.gui.center.addChild(healButton);
var defendButton = new Text2('3. Defend (Gain +10 Magic)', {
size: 45,
fill: 0x45B7D1
});
defendButton.anchor.set(0.5, 0);
defendButton.x = 0;
defendButton.y = 460;
defendButton.alpha = 0;
LK.gui.center.addChild(defendButton);
var basicHealButton = new Text2('4. Basic Healing (Cost: 20 Magic)', {
size: 45,
fill: 0x90EE90
});
basicHealButton.anchor.set(0.5, 0);
basicHealButton.x = 0;
basicHealButton.y = 540;
basicHealButton.alpha = 0;
LK.gui.center.addChild(basicHealButton);
var basicMagicButton = new Text2('5. Basic Magic Attack (Cost: 5 Magic)', {
size: 45,
fill: 0x9370DB
});
basicMagicButton.anchor.set(0.5, 0);
basicMagicButton.x = 0;
basicMagicButton.y = 620;
basicMagicButton.alpha = 0;
LK.gui.center.addChild(basicMagicButton);
var eternalKissButton = new Text2('6. Eternal Kiss (Cost: 500 Magic)', {
size: 45,
fill: 0xFF1493
});
eternalKissButton.anchor.set(0.5, 0);
eternalKissButton.x = 0;
eternalKissButton.y = 700;
eternalKissButton.alpha = 0;
LK.gui.center.addChild(eternalKissButton);
var incrementButton = new Text2('7. Increment (Cost: 30 Magic)', {
size: 45,
fill: 0xFFD700
});
incrementButton.anchor.set(0.5, 0);
incrementButton.x = 0;
incrementButton.y = 780;
incrementButton.alpha = 0;
LK.gui.center.addChild(incrementButton);
// Initialize characters (hidden initially)
summoner = game.addChild(new Summoner());
summoner.x = 800;
summoner.y = 1800;
summoner.alpha = 0;
succubus = game.addChild(new Succubus());
succubus.x = 1200;
succubus.y = 1800;
succubus.alpha = 0;
function spawnNewEnemy() {
if (currentEnemy) {
currentEnemy.destroy();
}
if (currentBoss) {
currentBoss.destroy();
currentBoss = null;
}
// Check for boss every 10 combats
combatCounter++;
if (combatCounter % 10 === 0) {
showBossWarning();
LK.setTimeout(spawnBoss, 2000);
return;
}
// Check if we should spawn a boss
if (shouldSpawnBoss) {
shouldSpawnBoss = false;
spawnBoss();
return;
}
// Enemy selection based on succubus rank
var succubusRank = succubus.rank;
var availableEnemies = [];
// F rank: slime, goblin, zombie, wolf
if (succubusRank === 0) {
availableEnemies = ['slime', 'goblin', 'zombie', 'wolf'];
}
// E rank: add darkelf, giantrat, giantspider
else if (succubusRank === 1) {
availableEnemies = ['slime', 'goblin', 'zombie', 'wolf', 'darkelf', 'giantrat', 'giantspider'];
}
// D+ ranks: add orc after D rank
else if (succubusRank >= 2 && succubusRank <= 5) {
availableEnemies = ['slime', 'goblin', 'zombie', 'wolf', 'darkelf', 'giantrat', 'giantspider', 'orc', 'skeleton', 'firemonster', 'icemonster'];
}
// A+ ranks: add stonegolem after A rank
else if (succubusRank >= 5 && succubusRank <= 8) {
availableEnemies = ['slime', 'goblin', 'zombie', 'wolf', 'darkelf', 'giantrat', 'giantspider', 'orc', 'skeleton', 'firemonster', 'icemonster', 'stonegolem', 'giantbat', 'ghost', 'enemysuccubus'];
}
// S to Z+ ranks: all enemies including demon and demonking
else {
availableEnemies = enemyTypes;
}
var enemyType = availableEnemies[Math.floor(Math.random() * availableEnemies.length)];
currentEnemy = new Enemy(enemyType, succubusRank);
// Position enemy closer to player
currentEnemy.x = 1024;
currentEnemy.y = 1200;
game.addChild(currentEnemy);
LK.getSound('enemyspawn').play();
}
function startGame() {
gameState = 'battle';
// Hide menu UI
titleText.alpha = 0;
startButton.alpha = 0;
backgroundSelectText.alpha = 0;
backgroundChangeButton.alpha = 0;
// Show battle UI
summonerHealthText.alpha = 1;
succubusHealthText.alpha = 1;
magicText.alpha = 1;
enemyHealthText.alpha = 1;
enemyNameText.alpha = 1;
turnText.alpha = 1;
attackButton.alpha = 1;
healButton.alpha = 1;
defendButton.alpha = 1;
basicHealButton.alpha = 1;
basicMagicButton.alpha = 1;
eternalKissButton.alpha = 1;
incrementButton.alpha = 1;
// Show characters
summoner.alpha = 1;
succubus.alpha = 1;
// Start background music based on zone type
var isDarkVersion = succubus.rank >= 6 && currentBackground >= 9;
var musicToPlay;
if (isDarkVersion) {
musicToPlay = darkBackgroundMusic[currentBackground];
} else {
musicToPlay = backgroundMusic[currentBackground];
}
LK.playMusic(musicToPlay);
// Spawn first enemy
spawnNewEnemy();
updateUI();
}
function changeBackground() {
var nextIndex = 0;
for (var i = 0; i < unlockedBackgrounds.length; i++) {
if (unlockedBackgrounds[i] === currentBackground) {
nextIndex = (i + 1) % unlockedBackgrounds.length;
break;
}
}
currentBackground = unlockedBackgrounds[nextIndex];
var displayName = backgroundNames[currentBackground];
// Check if this is a dark version (unlocked at S rank)
var isDarkVersion = succubus && succubus.rank >= 6 && currentBackground >= 9;
if (isDarkVersion) {
displayName = 'Dark ' + displayName;
}
backgroundSelectText.setText('Background: ' + displayName);
currentBackgroundText.setText('Zone: ' + displayName);
// Update background color based on zone
var backgroundColors = [0x2c1810, 0x4a5c2a, 0x5d4e37, 0x708090, 0x8b4513, 0x4b0000, 0x87ceeb, 0x006994, 0xf0f8ff, 0x228b22, 0x1a1a1a, 0xff4500, 0x000000, 0xffffff];
game.setBackgroundColor(backgroundColors[currentBackground]);
// Play appropriate music based on zone and if it's dark version
var musicToPlay;
if (isDarkVersion) {
musicToPlay = darkBackgroundMusic[currentBackground];
} else {
musicToPlay = backgroundMusic[currentBackground];
}
if (gameState === 'battle') {
LK.playMusic(musicToPlay);
}
// Save current background
storage.currentBackground = currentBackground;
}
function unlockNewBackgrounds() {
// Unlock all backgrounds when reaching S rank, including dark versions
if (succubus.rank >= 6) {
var allBackgrounds = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
for (var i = 0; i < allBackgrounds.length; i++) {
if (unlockedBackgrounds.indexOf(allBackgrounds[i]) === -1) {
unlockedBackgrounds.push(allBackgrounds[i]);
}
}
storage.unlockedBackgrounds = unlockedBackgrounds;
}
}
function showBossWarning() {
bossWarningText.alpha = 1;
tween(bossWarningText, {
alpha: 0
}, {
duration: 2000
});
LK.playMusic('bossmusic');
}
function updateUI() {
summonerHealthText.setText('Summoner HP: ' + summoner.health + '/' + summoner.maxHealth);
if (succubus.isDead) {
succubusHealthText.setText('Succubus: DEAD (Recovery in ' + succubus.recoveryTurns + ' turns)');
} else {
var expNeeded = succubus.experienceToNext - succubus.experience;
var shieldText = succubus.shieldTurns > 0 ? ' | SHIELD: ' + succubus.shieldTurns + ' turns' : '';
var incrementText = succubus.hasIncrement ? ' | NEXT ATTACK x2' : '';
succubusHealthText.setText('Succubus HP: ' + succubus.health + '/' + succubus.maxHealth + ' | Rank: ' + succubus.getRankName() + ' (' + succubus.experience + '/' + succubus.experienceToNext + ')' + shieldText + incrementText);
}
magicText.setText('Magic: ' + summoner.magic);
if (currentEnemy) {
enemyHealthText.setText('Enemy HP: ' + currentEnemy.health + '/' + currentEnemy.maxHealth + ' | Rank: ' + currentEnemy.getRankName());
enemyNameText.setText('Enemy: ' + currentEnemy.getName());
} else {
enemyNameText.setText('Enemy: None');
}
if (isPlayerTurn) {
if (succubus.isDead) {
turnText.setText('Succubus is dead! Only defend available:');
attackButton.alpha = 0.3;
healButton.alpha = 0.3;
defendButton.alpha = 1;
basicHealButton.alpha = 0.3;
basicMagicButton.alpha = 0.3;
eternalKissButton.alpha = 0.3;
incrementButton.alpha = 0.3;
} else {
turnText.setText('Your Turn - Choose Action:');
attackButton.alpha = summoner.health > 35 ? 1 : 0.3;
healButton.alpha = summoner.health > 35 ? 1 : 0.3;
defendButton.alpha = 1;
basicHealButton.alpha = summoner.magic >= 20 ? 1 : 0.3;
basicMagicButton.alpha = summoner.magic >= 5 ? 1 : 0.3;
eternalKissButton.alpha = summoner.magic >= 500 && summoner.health >= 100 ? 1 : 0.3;
incrementButton.alpha = summoner.magic >= 30 ? 1 : 0.3;
}
} else {
turnText.setText('Enemy Turn...');
attackButton.alpha = 0.3;
healButton.alpha = 0.3;
defendButton.alpha = 0.3;
basicHealButton.alpha = 0.3;
basicMagicButton.alpha = 0.3;
eternalKissButton.alpha = 0.3;
incrementButton.alpha = 0.3;
}
}
function playerAttack() {
if (!isPlayerTurn || !currentEnemy || succubus.isDead) return; // Can't attack if succubus is dead
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
var damage = succubus.baseDamage + summoner.magic;
if (succubus.hasIncrement) {
damage *= 2;
succubus.hasIncrement = false;
LK.effects.flashObject(succubus, 0xFFD700, 500); // Gold flash for increment
}
summoner.magic = 0; // Magic is consumed
LK.getSound('hit').play();
if (currentEnemy.takeDamage(damage)) {
// Enemy died
succubus.gainExperience(currentEnemy.experience);
enemiesKilled++;
LK.setScore(enemiesKilled);
currentWave++;
spawnNewEnemy();
} else {
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
}
updateUI();
}
function playerHeal() {
if (!isPlayerTurn || summoner.health <= 35 || succubus.isDead) return; // Can't heal dead succubus
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.health -= 35;
succubus.heal(35);
LK.getSound('levelup').play();
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
function playerDefend() {
if (!isPlayerTurn) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic += 10;
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
function enemyTurn() {
if (!currentEnemy || !succubus) return;
// Process succubus recovery first
succubus.processRecovery();
var action = currentEnemy.chooseAction();
var message = '';
if (action === 'miss') {
message = 'Enemy failed to act this turn!';
} else if (action === 'attack') {
var damage = currentEnemy.attack();
// If succubus is dead, attack summoner instead
if (succubus.isDead) {
summoner.takeDamage(damage);
message = 'Enemy attacks summoner for ' + damage + ' damage!';
} else {
succubus.takeDamage(damage);
message = 'Enemy attacks succubus for ' + damage + ' damage!';
}
} else if (action === 'defend') {
currentEnemy.defend();
message = 'Enemy is defending!';
} else if (action === 'heal') {
var healAmount = currentEnemy.heal();
message = 'Enemy heals for ' + healAmount + ' HP!';
}
// Show action message briefly
turnText.setText(message);
LK.setTimeout(function () {
isPlayerTurn = true;
updateUI();
}, 1500);
}
function basicHeal() {
if (!isPlayerTurn || summoner.magic < 20) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic -= 20;
summoner.health = Math.min(summoner.maxHealth, summoner.health + 10);
if (!succubus.isDead) {
succubus.heal(10);
}
LK.getSound('levelup').play();
LK.effects.flashObject(summoner, 0x90EE90, 500);
if (!succubus.isDead) {
LK.effects.flashObject(succubus, 0x90EE90, 500);
}
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
function basicMagic() {
if (!isPlayerTurn || !currentEnemy || summoner.magic < 5) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic -= 5;
var damage = 5;
LK.getSound('hit').play();
LK.effects.flashObject(summoner, 0x9370DB, 500);
if (currentEnemy.takeDamage(damage)) {
// Enemy died
succubus.gainExperience(currentEnemy.experience);
enemiesKilled++;
LK.setScore(enemiesKilled);
currentWave++;
spawnNewEnemy();
} else {
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
}
updateUI();
}
function eternalKiss() {
if (!isPlayerTurn || summoner.magic < 500 || summoner.health < 100 || succubus.isDead) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic -= 500;
summoner.health -= 100;
succubus.health = 999999;
succubus.maxHealth = 999999;
succubus.shieldTurns = 25;
succubus.baseDamage = Math.floor(succubus.baseDamage * 5); // Enormous strength
LK.getSound('levelup').play();
LK.effects.flashObject(summoner, 0xFF1493, 1000);
LK.effects.flashObject(succubus, 0xFF1493, 1000);
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
function increment() {
if (!isPlayerTurn || summoner.magic < 30 || succubus.isDead) return;
turnCounter++;
// Player health regeneration every 5 turns
if (turnCounter % 5 === 0) {
summoner.health = Math.min(summoner.maxHealth, summoner.health + 5);
LK.effects.flashObject(summoner, 0x00ff00, 500); // Green flash for regen
}
summoner.magic -= 30;
succubus.hasIncrement = true;
LK.getSound('levelup').play();
LK.effects.flashObject(succubus, 0xFFD700, 500);
isPlayerTurn = false;
LK.setTimeout(enemyTurn, 1000);
updateUI();
}
// Event handlers
attackButton.down = playerAttack;
healButton.down = playerHeal;
defendButton.down = playerDefend;
basicHealButton.down = basicHeal;
basicMagicButton.down = basicMagic;
eternalKissButton.down = eternalKiss;
incrementButton.down = increment;
startButton.down = startGame;
backgroundChangeButton.down = changeBackground;
// Load saved data
currentBackground = storage.currentBackground || 0;
backgroundSelectText.setText('Background: ' + backgroundNames[currentBackground]);
currentBackgroundText.setText('Zone: ' + backgroundNames[currentBackground]);
var backgroundColors = [0x2c1810, 0x4a5c2a, 0x5d4e37, 0x708090, 0x8b4513, 0x4b0000, 0x87ceeb, 0x006994, 0xf0f8ff, 0x228b22, 0x1a1a1a, 0xff4500, 0x000000, 0xffffff];
game.setBackgroundColor(backgroundColors[currentBackground]);
// Play menu music
LK.playMusic('menumusic');
game.update = function () {
if (gameState === 'battle') {
updateUI();
}
};
function spawnBoss() {
var succubusRank = succubus.rank;
var bossType = '';
// Determine boss type based on succubus rank
if (succubusRank === 1) {
// E rank -> Slime King
bossType = 'slimeking';
} else if (succubusRank === 2) {
// D rank -> Orc King
bossType = 'orcking';
} else if (succubusRank === 3) {
// C rank -> Dark Elf Lord
bossType = 'darkelflord';
} else if (succubusRank === 5) {
// A rank -> Dark Golem
bossType = 'darkgolem';
} else if (succubusRank === 6) {
// S rank -> Demon King
bossType = 'demonking';
} else if (succubusRank >= 14) {
// Z rank -> Fallen Angel
bossType = 'fallenangel';
} else if (succubusRank >= 17) {
// G rank (new rank) -> Chaos God
bossType = 'chaosgod';
} else {
// For other ranks, repeat boss cycle
var bossIndex = succubusRank % 6;
var bossCycle = ['slimeking', 'orcking', 'darkelflord', 'darkgolem', 'demonking', 'fallenangel'];
bossType = bossCycle[bossIndex];
}
currentBoss = new Boss(bossType, succubusRank);
currentEnemy = currentBoss; // Use same reference for combat system
currentEnemy.x = 1024;
currentEnemy.y = 1200;
game.addChild(currentEnemy);
LK.getSound('enemyspawn').play();
LK.effects.flashScreen(0xff0000, 500); // Red flash for boss spawn
}