// /server_modules/data.js const GAME_CONFIG = require('./config'); // Подключаем конфиг для ID способностей и других значений // --- Базовые Статы Персонажей --- const playerBaseStats = { id: GAME_CONFIG.PLAYER_ID, // Технический ID слота characterKey: 'elena', // Уникальный ключ персонажа name: "Елена", maxHp: 120, maxResource: 150, attackPower: 15, resourceName: "Мана", avatarPath: 'images/elena_avatar.webp' // Пример пути к аватару }; const opponentBaseStats = { // Балард (для AI) id: GAME_CONFIG.OPPONENT_ID, // Технический ID слота characterKey: 'balard', // Уникальный ключ персонажа name: "Балард", maxHp: 140, maxResource: 100, attackPower: 20, resourceName: "Ярость", avatarPath: 'images/balard_avatar.jpg' // Пример пути к аватару }; const almagestBaseStats = { // Альмагест (для PvP) id: GAME_CONFIG.OPPONENT_ID, // Технический ID слота (занимает слот оппонента) characterKey: 'almagest', // Уникальный ключ персонажа name: "Альмагест", maxHp: 120, // Статы как у Елены для зеркальности maxResource: 150, attackPower: 15, resourceName: "Темная Энергия", avatarPath: 'images/almagest_avatar.webp' // Пример пути к аватару (нужно создать изображение) }; // --- Способности Персонажей --- // Способности Игрока (Елена) const playerAbilities = [ { id: GAME_CONFIG.ABILITY_ID_HEAL, name: 'Малое Исцеление', cost: 20, type: GAME_CONFIG.ACTION_TYPE_HEAL, power: 30, description: 'Восстанавливает ~30 HP' }, { id: GAME_CONFIG.ABILITY_ID_FIREBALL, name: 'Огненный Шар', cost: 30, type: GAME_CONFIG.ACTION_TYPE_DAMAGE, power: 25, description: 'Наносит ~25 урона врагу' }, { id: GAME_CONFIG.ABILITY_ID_NATURE_STRENGTH, name: 'Сила Природы', cost: 15, type: GAME_CONFIG.ACTION_TYPE_BUFF, duration: 4, descriptionFunction: (config) => `Восст. ${config.NATURE_STRENGTH_MANA_REGEN} маны при след. атаке (${4 - 1} хода)`, isDelayed: true // Этот эффект применяется ПОСЛЕ следующей атаки, а не сразу }, { id: GAME_CONFIG.ABILITY_ID_DEFENSE_AURA, name: 'Аура Защиты', cost: 15, type: GAME_CONFIG.ACTION_TYPE_BUFF, duration: 3, grantsBlock: true, // Дает эффект блока на время действия descriptionFunction: (config) => `Снижает урон на ${config.BLOCK_DAMAGE_REDUCTION * 100}% (${3} хода)` }, { id: GAME_CONFIG.ABILITY_ID_HYPNOTIC_GAZE, name: 'Гипнотический взгляд', cost: 30, type: GAME_CONFIG.ACTION_TYPE_DISABLE, effectDuration: 2, // Длительность безмолвия в ходах противника cooldown: 6, power: 5, // Урон в ход от взгляда description: 'Накладывает на противника полное безмолвие на 2 хода и наносит 5 урона каждый его ход. КД: 6 х.' }, { id: GAME_CONFIG.ABILITY_ID_SEAL_OF_WEAKNESS, name: 'Печать Слабости', cost: 30, type: GAME_CONFIG.ACTION_TYPE_DEBUFF, effectDuration: 3, // Длительность дебаффа power: 10, // Количество ресурса противника, сжигаемое каждый ход cooldown: 5, // Описание теперь может адаптироваться к ресурсу оппонента descriptionFunction: (config, oppStats) => `Накладывает печать, сжигающую 10 ${oppStats.resourceName} противника каждый его ход в течение 3 ходов. КД: 5 х.'` } ]; // Способности Противника (Балард - AI) const opponentAbilities = [ { id: GAME_CONFIG.ABILITY_ID_BALARD_HEAL, name: 'Покровительство Тьмы', cost: 20, type: GAME_CONFIG.ACTION_TYPE_HEAL, power: 25, successRate: 0.60, // Шанс успеха description: 'Исцеляет ~25 HP с 60% шансом', // Условие для AI: HP ниже порога condition: (opSt, plSt, currentGameState, config) => { return (opSt.currentHp / opSt.maxHp) * 100 < config.OPPONENT_HEAL_THRESHOLD_PERCENT; } }, { id: GAME_CONFIG.ABILITY_ID_BALARD_SILENCE, name: 'Эхо Безмолвия', cost: GAME_CONFIG.BALARD_SILENCE_ABILITY_COST, type: GAME_CONFIG.ACTION_TYPE_DISABLE, // Описание с адаптацией descriptionFunction: (config) => `Шанс ${config.SILENCE_SUCCESS_RATE * 100}% заглушить случайное заклинание Елены на ${config.SILENCE_DURATION} х.`, // Условие для AI: HP выше порога лечения, Елена не заглушена, не на спец. КД condition: (opSt, plSt, currentGameState, config) => { const hpPercent = (opSt.currentHp / opSt.maxHp) * 100; const isElenaAlreadySilenced = currentGameState?.player.disabledAbilities?.length > 0 || currentGameState?.player.activeEffects?.some(eff => eff.id.startsWith('playerSilencedOn_')); return hpPercent >= config.OPPONENT_HEAL_THRESHOLD_PERCENT && !isElenaAlreadySilenced && opSt.silenceCooldownTurns <= 0; }, successRateFromConfig: 'SILENCE_SUCCESS_RATE', // Шанс берется из конфига durationFromConfig: 'SILENCE_DURATION', // Длительность берется из конфига internalCooldownFromConfig: 'BALARD_SILENCE_INTERNAL_COOLDOWN' // Спец. КД берется из конфига }, { id: GAME_CONFIG.ABILITY_ID_BALARD_MANA_DRAIN, name: 'Похищение Света', cost: 10, type: GAME_CONFIG.ACTION_TYPE_DRAIN, powerManaDrain: 5, // Сколько маны вытягивает powerDamage: 5, // Сколько урона наносит дополнительно powerHealthGainFactor: 1.0, // Множитель для расчета лечения от вытянутой маны description: `Вытягивает 5 Маны у Елены, наносит 5 урона и восстанавливает себе здоровье (100% от украденного).`, // Условие для AI: У Елены достаточно маны, не на спец. КД condition: (opSt, plSt, currentGameState, config) => { const playerManaPercent = (plSt.currentResource / plSt.maxResource) * 100; const playerHasHighMana = playerManaPercent > (config.BALARD_MANA_DRAIN_HIGH_MANA_THRESHOLD || 60); return playerHasHighMana && opSt.manaDrainCooldownTurns <= 0; }, internalCooldownValue: 3 // Спец. КД задается здесь } ]; // Способности Альмагест (PvP - зеркало Елены) const almagestAbilities = [ { id: GAME_CONFIG.ABILITY_ID_ALMAGEST_HEAL, name: 'Темное Восстановление', cost: 20, type: GAME_CONFIG.ACTION_TYPE_HEAL, power: 30, description: 'Поглощает жизненные тени, восстанавливая ~30 HP' }, { id: GAME_CONFIG.ABILITY_ID_ALMAGEST_DAMAGE, name: 'Теневой Сгусток', cost: 30, type: GAME_CONFIG.ACTION_TYPE_DAMAGE, power: 25, description: 'Запускает сгусток чистой тьмы, нанося ~25 урона врагу' }, { id: GAME_CONFIG.ABILITY_ID_ALMAGEST_BUFF_ATTACK, name: 'Усиление Тьмой', cost: 15, type: GAME_CONFIG.ACTION_TYPE_BUFF, duration: 4, // Аналогично Силе Природы, но использует Темную Энергию descriptionFunction: (config) => `Восст. ${config.NATURE_STRENGTH_MANA_REGEN} Темной Энергии при след. атаке (${4 - 1} хода)`, isDelayed: true // Этот эффект применяется ПОСЛЕ следующей атаки }, { id: GAME_CONFIG.ABILITY_ID_ALMAGEST_BUFF_DEFENSE, name: 'Щит Пустоты', cost: 15, type: GAME_CONFIG.ACTION_TYPE_BUFF, duration: 3, grantsBlock: true, // Дает эффект блока на время действия descriptionFunction: (config) => `Создает щит, снижающий урон на ${config.BLOCK_DAMAGE_REDUCTION * 100}% (${3} хода)` }, { id: GAME_CONFIG.ABILITY_ID_ALMAGEST_DISABLE, name: 'Раскол Разума', cost: 30, type: GAME_CONFIG.ACTION_TYPE_DISABLE, effectDuration: 2, cooldown: 6, power: 5, // Урон от ментального воздействия description: 'Вторгается в разум противника, накладывая полное безмолвие на 2 хода и нанося 5 урона каждый его ход. КД: 6 х.' }, { id: GAME_CONFIG.ABILITY_ID_ALMAGEST_DEBUFF, name: 'Проклятие Увядания', cost: 30, type: GAME_CONFIG.ACTION_TYPE_DEBUFF, effectDuration: 3, power: 10, // Количество ресурса противника, сжигаемое/истощаемое cooldown: 5, descriptionFunction: (config, oppStats) => `Накладывает проклятие, истощающее 10 ${oppStats.resourceName} противника каждый его ход в течение 3 ходов. КД: 5 х.` } ]; // --- Система Насмешек --- // Ключи верхнего уровня: characterKey того, кто произносит насмешку ('elena', 'almagest') // Внутри каждого characterKey: ключи characterKey противника ('balard', 'almagest', 'elena') // Внутри каждого противника: секции по триггерам (battleStart, selfCastAbility, onOpponentAction, etc.) const tauntSystem = { elena: { // Насмешки Елены balard: { // Против Баларда (AI) // Триггер: Елена использует СВОЮ способность selfCastAbility: { [GAME_CONFIG.ABILITY_ID_HEAL]: [ "Свет лечит, Балард. Но не искаженную завистью искру.", "Я черпаю силы в Истине." ], [GAME_CONFIG.ABILITY_ID_FIREBALL]: [ "Прими очищающее пламя Света!", "Пусть твой мрак сгорит!" ], [GAME_CONFIG.ABILITY_ID_NATURE_STRENGTH]: [ "Сама земля отвергает тебя, я черпаю её силу!", "Гармония природы со мной." ], [GAME_CONFIG.ABILITY_ID_DEFENSE_AURA]: [ "Порядок восторжествует над твоим хаосом.", "Моя вера - моя защита." ], [GAME_CONFIG.ABILITY_ID_HYPNOTIC_GAZE]: [ "Смотри мне в глаза, Балард. И слушай тишину.", "Твой разум - в моей власти." ], [GAME_CONFIG.ABILITY_ID_SEAL_OF_WEAKNESS]: [ "Твоя ярость иссякнет, как вода в песке, Балард!", "Твоя сила угасает." ] }, // Триггер: Противник (Балард) совершает действие onOpponentAction: { [GAME_CONFIG.ABILITY_ID_BALARD_HEAL]: [ "Пытаешься отсрочить неизбежное жалкой темной силой?" ], [GAME_CONFIG.ABILITY_ID_BALARD_SILENCE]: { success: [ "(Сдавленный вздох)... Ничтожная попытка заглушить Слово!" ], fail: [ "Твой шепот Тьмы слаб против Света Истины!" ] }, [GAME_CONFIG.ABILITY_ID_BALARD_MANA_DRAIN]: [ "Ты питаешься Светом, как паразит?!" ], attackBlocked: [ "Твои удары тщетны перед щитом Порядка." ], // При блоке атаки Баларда attackHits: [ "(Шипение боли)... Боль – лишь напоминание о твоем предательстве." ] // При попадании атаки Баларда }, // Триггер: Базовая атака Елены basicAttack: { merciful: [ "Балард, прошу, остановись. Еще не поздно.", "Подумай о том, что потерял." ], dominating: [ // Когда HP Баларда ниже порога PLAYER_MERCY_TAUNT_THRESHOLD_PERCENT "Глина не спорит с гончаром, Балард!", "Ты ИЗБРАЛ эту гниль! Получай возмездие!", "Самый страшный грех - грех неблагодарности!", "Я сотру тебя с лика этой земли!" ] }, // Триггер: Изменение состояния боя (например, начало, оппонент почти побежден) onBattleState: { start: [ "Балард, есть ли еще путь назад?" ], // Начало AI боя с Балардом opponentNearDefeat: [ "Конец близок, Балард. Прими свою судьбу." ] // Балард почти побежден } }, almagest: { // Против Альмагест (PvP) // Триггер: Елена использует СВОЮ способность selfCastAbility: { [GAME_CONFIG.ABILITY_ID_HEAL]: [ "Я исцеляюсь Светом, который ты отвергла.", "Жизнь восторжествует над твоей некромантией!", "Мое сияние не померкнет." ], [GAME_CONFIG.ABILITY_ID_FIREBALL]: [ "Очищающий огонь для твоей тьмы!", "Почувствуй гнев праведного Света!", "Это пламя ярче твоих теней!" ], [GAME_CONFIG.ABILITY_ID_NATURE_STRENGTH]: [ "Природа дает мне силу, а тебе - лишь презрение.", "Я черпаю из источника жизни, ты - из могилы." ], [GAME_CONFIG.ABILITY_ID_DEFENSE_AURA]: [ "Мой щит отразит твою злобу.", "Свет - лучшая защита.", "Твои темные чары не пройдут!" ], [GAME_CONFIG.ABILITY_ID_HYPNOTIC_GAZE]: [ "Смотри в глаза Истине, колдунья!", "Твои лживые речи умолкнут!", "Хватит прятаться за иллюзиями!" ], [GAME_CONFIG.ABILITY_ID_SEAL_OF_WEAKNESS]: [ "Твоя темная сила иссякнет!", "Я ослабляю твою связь с бездной!", "Почувствуй, как тает твоя энергия!" ] }, // Триггер: Противник (Альмагест) совершает действие onOpponentAction: { [GAME_CONFIG.ABILITY_ID_ALMAGEST_HEAL]: [ "Лечишь раны тьмой? Она лишь глубже проникнет в тебя.", "Твоя магия несет лишь порчу, даже исцеляя." ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_DAMAGE]: [ "Твоя тень лишь царапает, не ранит.", "Слабый удар! Тьма делает тебя немощной." ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_BUFF_ATTACK]: [ "Черпаешь силы из бездны? Она поглотит и тебя.", "Твое усиление - лишь агония искаженной энергии." ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_BUFF_DEFENSE]: [ "Щит из теней? Он рассыпется прахом!", "Твоя защита иллюзорна, как и твоя сила." ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_DISABLE]: [ "(Сдавленно) Твои ментальные атаки отвратительны!", "Тьма в моей голове... я вырвусь!" ], // Если Елена попадает под Раскол Разума Альмагест [GAME_CONFIG.ABILITY_ID_ALMAGEST_DEBUFF]: [ "Истощаешь мою силу? Я восстановлю ее Светом!", "Твое проклятие слабо." ], // Если Елена попадает под Проклятие Увядания Альмагест attackBlocked: [ "Твоя атака разбилась о мой щит Света!", "Предсказуемо и слабо, Альмагест." ], // При блоке атаки Альмагест attackHits: [ "(Резкий вздох) Коснулась... Но Свет исцелит рану.", "Эта царапина - ничто!", "Ты заплатишь за это!" ] // При попадании атаки Альмагест }, // Триггер: Базовая атака Елены (PvP) basicAttack: { general: [ "Тьма не победит, Альмагест!", "Твои иллюзии рассеются перед Светом!", "Пока я стою, порядок будет восстановлен!" ] }, // Триггер: Изменение состояния боя onBattleState: { start: [ "Альмагест! Твоим темным делам пришел конец!", "Во имя Света, я остановлю тебя!", "Приготовься к битве, служительница тьмы!" ], // Начало PvP боя с Альмагест opponentNearDefeat: [ "Твоя тьма иссякает, колдунья!", "Сдавайся, пока Свет не испепелил тебя!", "Конец твоим злодеяниям близок!" ] // Альмагест почти побеждена } } }, almagest: { // Насмешки Альмагест elena: { // Против Елены (PvP) // Триггер: Альмагест использует СВОЮ способность selfCastAbility: { [GAME_CONFIG.ABILITY_ID_ALMAGEST_HEAL]: [ "Я питаюсь слабостью, Елена!", "Тьма дает мне силу!" ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_DAMAGE]: [ "Почувствуй холод бездны!", "Твой Свет померкнет перед моей тенью!" ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_BUFF_ATTACK]: [ "Силы Бездны со мной!", "Моя тень становится гуще!" ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_BUFF_DEFENSE]: [ "Мой щит выкован из самой тьмы!", "Попробуй пробить это, служительница Света!" ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_DISABLE]: [ "Твой разум сломлен!", "Умолкни, Светлая!", "Я владею твоими мыслями!" ], [GAME_CONFIG.ABILITY_ID_ALMAGEST_DEBUFF]: [ "Твоя сила тает!", "Почувствуй гниль!", "Я истощаю твой Свет!" ] }, // Триггер: Противник (Елена) совершает действие onOpponentAction: { [GAME_CONFIG.ABILITY_ID_HEAL]: [ "Исцеляешься? Твои раны слишком глубоки!" ], [GAME_CONFIG.ABILITY_ID_FIREBALL]: [ "Жалкое пламя! Мои тени поглотят его!" ], [GAME_CONFIG.ABILITY_ID_NATURE_STRENGTH]: [ "Сила земли? Смешно! Бездну ничто не остановит." ], [GAME_CONFIG.ABILITY_ID_DEFENSE_AURA]: [ "Твой щит из Света не спасет тебя от Тьмы!" ], [GAME_CONFIG.ABILITY_ID_HYPNOTIC_GAZE]: [ "(Сдавленно, затем смех) Попытка управлять моим разумом? Жалко!", "Ты пытаешься заглянуть в Бездну?!" ], // Если Альмагест попадает под Гипнотический взгляд Елены [GAME_CONFIG.ABILITY_ID_SEAL_OF_WEAKNESS]: [ "Моя энергия вечна, дура!", "Это лишь раздражение!" ], // Если Альмагест попадает под Печать Слабости Елены attackBlocked: [ "Твой блок не спасет тебя вечно, Елена!", "Это лишь задержка." ], // При блоке атаки Елены attackHits: [ "Ха! Чувствуешь силу Тьмы?", "Это только начало!", "Слабость!" ] // При попадании атаки Елены }, // Триггер: Базовая атака Альмагест basicAttack: { general: [ "Почувствуй мою силу!", "Тени атакуют!", "Я наношу удар!" ] }, // Триггер: Изменение состояния боя onBattleState: { start: [ "Тысяча лет в заточении лишь усилили меня, Елена!", "Твой Свет скоро погаснет!", "Пора положить конец твоему господству!" ], // Начало PvP боя с Еленой opponentNearDefeat: [ "Твой Свет гаснет!", "Ты побеждена!", "Бездне нужен твой дух!" ] // Елена почти побеждена } } } }; // --- Экспорт Данных --- const gameData = { // Базовые статы playerBaseStats, opponentBaseStats, // Балард almagestBaseStats, // Альмагест // Способности playerAbilities, // Елена opponentAbilities, // Балард almagestAbilities, // Альмагест // Система насмешек (с разделением по персонажам и противникам) tauntSystem // Переименовали для лучшей структуры }; // --- Вспомогательные функции для использования ВНУТРИ data.js или модулей, которые его используют --- // Эти функции НЕ являются частью экспортируемого объекта gameData, // но могут быть вызваны внутри этого файла, например, в descriptionFunction // Или их можно было бы экспортировать отдельно, если они нужны другим модулям, не имеющим gameData в аргументах. // Но в текущей структуре gameLogic они не нужны, так как gameLogic получает gameData и имеет свои локальные хелперы. // function _getCharacterData(key) { // if (!key) return null; // switch (key) { // case 'elena': return { baseStats: playerBaseStats, abilities: playerAbilities }; // case 'balard': return { baseStats: opponentBaseStats, abilities: opponentAbilities }; // case 'almagest': return { baseStats: almagestBaseStats, abilities: almagestAbilities }; // default: console.error(`data.js::_getCharacterData: Unknown character key "${key}"`); return null; // } // } // function _getCharacterBaseData(key) { // const charData = _getCharacterData(key); // return charData ? charData.baseStats : null; // } // function _getCharacterAbilities(key) { // const charData = _getCharacterData(key); // return charData ? charData.abilities : null; // } if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { module.exports = gameData; } // console.log("data.js загружен и gameData объект создан/экспортирован.");