111 lines
3.2 KiB
JavaScript
111 lines
3.2 KiB
JavaScript
class HybridSkillSystem {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
|
|
this.level = 1;
|
|
this.xp = 0;
|
|
this.maxXp = 100;
|
|
|
|
// Skills
|
|
this.skills = {
|
|
'translation': { level: 0, max: 5, name: 'Zombie Language', desc: 'Understand zombie groans.' },
|
|
'strength': { level: 0, max: 5, name: 'Mutant Strength', desc: 'Deal more damage.' },
|
|
'resilience': { level: 0, max: 5, name: 'Rot Resistance', desc: 'Less damage from poison/decay.' },
|
|
'command': { level: 0, max: 3, name: 'Horde Command', desc: 'Control more zombie workers.' }
|
|
};
|
|
|
|
this.points = 0; // Available skill points
|
|
}
|
|
|
|
addXP(amount) {
|
|
this.xp += amount;
|
|
if (this.xp >= this.maxXp) {
|
|
this.levelUp();
|
|
}
|
|
// UI Notification
|
|
this.scene.events.emit('show-floating-text', {
|
|
x: this.scene.player.sprite.x,
|
|
y: this.scene.player.sprite.y - 50,
|
|
text: `+${amount} Hybrid XP`,
|
|
color: '#00FF00'
|
|
});
|
|
}
|
|
|
|
levelUp() {
|
|
this.xp -= this.maxXp;
|
|
this.level++;
|
|
this.maxXp = Math.floor(this.maxXp * 1.5);
|
|
this.points++;
|
|
console.log(`🧬 Hybrid Level Up! Level: ${this.level}, Points: ${this.points}`);
|
|
|
|
this.scene.soundManager.playSuccess(); // Reuse success sound
|
|
|
|
this.scene.events.emit('show-floating-text', {
|
|
x: this.scene.player.sprite.x,
|
|
y: this.scene.player.sprite.y - 80,
|
|
text: `LEVEL UP! (${this.level})`,
|
|
color: '#FFFF00'
|
|
});
|
|
}
|
|
|
|
tryUpgradeSkill(skillId) {
|
|
const skill = this.skills[skillId];
|
|
if (!skill) return false;
|
|
|
|
if (this.points > 0 && skill.level < skill.max) {
|
|
this.points--;
|
|
skill.level++;
|
|
console.log(`🧬 Upgraded ${skill.name} to Lv ${skill.level}`);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
getSpeechTranslation(text) {
|
|
const lvl = this.skills['translation'].level;
|
|
if (lvl >= 5) return text; // Perfect translation
|
|
|
|
// Obfuscate text based on level
|
|
// Lv 0: 100% garbled
|
|
// Lv 1: 80% garbled
|
|
// ...
|
|
const garbleChance = 1.0 - (lvl * 0.2);
|
|
|
|
return text.split(' ').map(word => {
|
|
if (Math.random() < garbleChance) {
|
|
return this.garbleWord(word);
|
|
}
|
|
return word;
|
|
}).join(' ');
|
|
}
|
|
|
|
garbleWord(word) {
|
|
const sounds = ['hgh', 'arr', 'ghh', '...', 'bra', 'in', 'zZz'];
|
|
return sounds[Math.floor(Math.random() * sounds.length)];
|
|
}
|
|
|
|
toJSON() {
|
|
return {
|
|
level: this.level,
|
|
xp: this.xp,
|
|
maxXp: this.maxXp,
|
|
skills: this.skills,
|
|
points: this.points
|
|
};
|
|
}
|
|
|
|
load(data) {
|
|
if (!data) return;
|
|
this.level = data.level;
|
|
this.xp = data.xp;
|
|
this.maxXp = data.maxXp;
|
|
this.points = data.points;
|
|
// Merge skills to keep structure if definition changed
|
|
for (const k in data.skills) {
|
|
if (this.skills[k]) {
|
|
this.skills[k].level = data.skills[k].level;
|
|
}
|
|
}
|
|
}
|
|
}
|