feat: Initial commit Plants vs Zombies Web Edition v2.4
- 5 Biomes: Day, Night, Pool, Fog, Roof (25 Campaign levels) - Minigames: Wall-nut Bowling, I Zombie, Roguelike, Boss Rush & Dr. Zomboss - Systems: Zen Garden, Workshop Crafting, Almanac, Tree of Wisdom, Achievements - Backend: REST API + SQLite Accounts & Save Synchronization - Infrastructure: Nginx HTTPS & Docker deployment
This commit is contained in:
commit
6457a8904e
50 files changed
+14486
No files matched your search
@@ -0,0 +1,168 @@
|
||||
// Tree of Wisdom System & Secret Cheats Engine
|
||||
window.TreeSystem = class TreeSystem {
|
||||
constructor(economySystem) {
|
||||
this.economy = economySystem;
|
||||
this.height = 0; // In feet
|
||||
this.fertilizerBags = 0;
|
||||
this.fertilizerCost = 150; // coins per bag
|
||||
|
||||
// Active visual / gameplay cheats
|
||||
this.cheats = {
|
||||
mustache: false,
|
||||
future: false,
|
||||
daisies: false,
|
||||
dance: false,
|
||||
pinata: false
|
||||
};
|
||||
|
||||
// Wisdom unlocked at various heights
|
||||
this.wisdomList = [
|
||||
{
|
||||
height: 1,
|
||||
title: 'Первый росток',
|
||||
text: '«Приветствую, садовник! Корми меня древесным удобрением, и я открою тебе сокровенные тайны газона и секретные коды игры!»'
|
||||
},
|
||||
{
|
||||
height: 5,
|
||||
title: 'Секрет Крыши',
|
||||
text: '«На крыше дома прямые выстрелы горохом врезаются в скат черепицы! Сажай Капустопульты и Арбузопульты в Цветочные Горшки для навесной стрельбы!»'
|
||||
},
|
||||
{
|
||||
height: 10,
|
||||
title: 'Секретный код: MUSTACHE',
|
||||
text: '«Хочешь придать врагам благородный вид? Введи код mustache на клавиатуре — и все зомби наденут великолепные усы!»',
|
||||
cheat: 'mustache'
|
||||
},
|
||||
{
|
||||
height: 20,
|
||||
title: 'Секрет Тумана',
|
||||
text: '«В ночном тумане зомби скрыты от взора, пока не подойдут вплотную. Но сплэш-атаки Арбузопульта и пробивающие споры Дымогриба бьют сквозь мглу!»'
|
||||
},
|
||||
{
|
||||
height: 30,
|
||||
title: 'Секретный код: FUTURE',
|
||||
text: '«Зомби из будущего уже здесь! Введи код future, чтобы зомби получили стильные неоновые кибер-очки!»',
|
||||
cheat: 'future'
|
||||
},
|
||||
{
|
||||
height: 50,
|
||||
title: 'Секретный код: DAISIES',
|
||||
text: '«Смерть нежити может приносить радость. Введи код daisies — при падении зомби на земле будут расцветать прекрасные маргаритки!»',
|
||||
cheat: 'daisies'
|
||||
},
|
||||
{
|
||||
height: 75,
|
||||
title: 'Секрет Доктора Зомбосса',
|
||||
text: '«Огромный робот Зомбот доктора Зомбосса выпускает ледяные и огненные шары! Ледяной шар можно уничтожить ТОЛЬКО огненным Халапеньо!»'
|
||||
},
|
||||
{
|
||||
height: 100,
|
||||
title: 'Секретный код: DANCE',
|
||||
text: '«Ты вырастил меня до небес (100 футов)! Вот финальная тайна: код dance заставит зомби ритмично танцевать прямо во время атаки!»',
|
||||
cheat: 'dance'
|
||||
}
|
||||
];
|
||||
|
||||
this.loadFromAuth();
|
||||
this.setupKeyboardListener();
|
||||
}
|
||||
|
||||
loadFromAuth() {
|
||||
this.height = 0;
|
||||
this.cheats = {};
|
||||
if (window.PvZAuth) {
|
||||
const uData = window.PvZAuth.getUserData();
|
||||
if (uData.treeOfWisdom) {
|
||||
this.height = uData.treeOfWisdom.height || 0;
|
||||
this.cheats = { ...(uData.treeOfWisdom.cheats || {}) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveToAuth() {
|
||||
if (window.PvZAuth && !window.PvZAuth.isGuest()) {
|
||||
window.PvZAuth.saveUserData({
|
||||
treeOfWisdom: {
|
||||
height: this.height,
|
||||
cheats: this.cheats
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
feedFertilizer() {
|
||||
if (!this.economy) return false;
|
||||
if (this.economy.totalCoins < this.fertilizerCost) return false;
|
||||
|
||||
this.economy.totalCoins -= this.fertilizerCost;
|
||||
this.economy.saveProfileData();
|
||||
this.height += 1;
|
||||
this.saveToAuth();
|
||||
|
||||
if (window.PvZAudio) window.PvZAudio.playWin();
|
||||
return true;
|
||||
}
|
||||
|
||||
toggleCheat(cheatId) {
|
||||
if (this.cheats.hasOwnProperty(cheatId)) {
|
||||
this.cheats[cheatId] = !this.cheats[cheatId];
|
||||
this.saveToAuth();
|
||||
if (window.PvZAudio) window.PvZAudio.playCoin();
|
||||
return this.cheats[cheatId];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
setupKeyboardListener() {
|
||||
let buffer = '';
|
||||
window.addEventListener('keydown', (e) => {
|
||||
// Avoid capturing input inside text boxes
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
||||
|
||||
const char = e.key.toLowerCase();
|
||||
if (/^[a-z]$/.test(char)) {
|
||||
buffer += char;
|
||||
if (buffer.length > 15) buffer = buffer.slice(-15);
|
||||
|
||||
for (const code of ['mustache', 'future', 'daisies', 'dance', 'pinata']) {
|
||||
if (buffer.endsWith(code)) {
|
||||
const state = this.toggleCheat(code);
|
||||
this.showCheatToast(code, state);
|
||||
buffer = '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
showCheatToast(code, active) {
|
||||
let toast = document.getElementById('achievement-toast');
|
||||
if (!toast) {
|
||||
toast = document.createElement('div');
|
||||
toast.id = 'achievement-toast';
|
||||
toast.className = 'achievement-toast';
|
||||
document.body.appendChild(toast);
|
||||
}
|
||||
|
||||
toast.innerHTML = `
|
||||
<div class="ach-toast-icon">✨</div>
|
||||
<div class="ach-toast-text">
|
||||
<div class="ach-toast-subtitle">ЧИТ-КОД АКТИВИРОВАН!</div>
|
||||
<div class="ach-toast-title">${code.toUpperCase()}: ${active ? 'ВКЛЮЧЕН ✅' : 'ВЫКЛЮЧЕН ❌'}</div>
|
||||
</div>
|
||||
`;
|
||||
toast.classList.add('visible');
|
||||
setTimeout(() => toast.classList.remove('visible'), 3000);
|
||||
}
|
||||
|
||||
// Get current tree level wisdom
|
||||
getCurrentWisdom() {
|
||||
const unlocked = this.wisdomList.filter(w => this.height >= w.height);
|
||||
return unlocked.length > 0 ? unlocked[unlocked.length - 1] : this.wisdomList[0];
|
||||
}
|
||||
|
||||
getAllUnlockedWisdom() {
|
||||
return this.wisdomList.filter(w => this.height >= w.height);
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user