Показать: 15|Ответить: 0

[Монстры] [Elmorion BD] Вождь Карул Оруто

[Скопировать ссылку]
Опубликовано вчера 11:56 | Показать все этажи |Режим чтения

Вождь Карул Оруто ID: 27164

Уровень: 40 · Агрессия: · Пол: MALE· Раса: HUMANOID· HP: ·
Вождь Карул Оруто

Spawn

Диалоги

Тип

Monster

AI

Дроп:

🩸 1. Линия фракции Тьмы — «Эхо Утраты»
Роль: хранитель древнего проклятия, связанного с Осколками Тьмы.
Описание:
Когда-то Карул Оруто был вождём гордых горных орков, охранявших врата мира стихий. После «Разлома Первого Света» он пал под воздействием Тьмы и стал бессмертным стражем древнего кристалла. Его тело изъедено временем, но сила не угасла.
Квест:
Игроку предстоит сразиться с ним, чтобы добыть Осколок Тлена — один из ключевых фрагментов для формирования Кристалла Тьмы.
В бою он произносит реплики, напоминающие о былой гордости орков и их предательстве богами.

⚔️ 2. История Эпохи Разломов — «Падшие Вожди»
Роль: один из «Семи павших», вождей, что пытались закрыть разлом, но были превращены в чудовищ.
Описание:
Карул Оруто был братом Вождя Тарука, но предал клан, заключив договор с сущностями Астрала. Он стал первым, кто получил «Печать Осквернённого Тела» — магическую метку, превращающую его плоть в орудие разрушения.
Использование:
Можно внедрить его как рейдового босса уровня 55–65 с уникальной механикой —
он периодически вызывает эхо своих павших воинов (призраки, усиливающие его атаку).

🔥 3. Ветка Света — «Очищение Разлома»
Роль: страж древней кузницы, осквернённый Тьмой.
Описание:
Светлые силы видят в Каруле не просто врага, а потерянную душу. Герой может выбрать — убить его или очистить, пожертвовав своей частью Света.
В зависимости от выбора изменяется баланс мира в счётчике Астры (BB).

🧩 4. Клановая миссия — «Трофеи Вождя»
Роль: объект охоты для группового ивента.
Описание:
Карул может быть добавлен как еженедельный босс, дающий клановые ресурсы (например, «Кровавый Тотем Оруто» и «Клык Вождя»).
Эти предметы можно использовать для улучшения клановых умений или для обмена у шаманов в Эльморе.

💀 Возможное расположение:
  • Локация: Долина Орков или Руины Кузницы Огня
  • Тип: Рейд-босс или Квестовый монстр (в зависимости от выбранной линии)
  • Фракция: Тьма / Хаос
  • Уровень: 60–65
  • Награды:

    • Осколок Тьмы
    • Фрагмент Тотема Оруто
    • Редкие материалы для Кузницы Астры



🩸 КВЕСТ: Наследие Оруто
(Q10031_OrutoLegacy.java)
Тип: Сюжетный / Фракционный (Тьма)
Уровень: 55+
Начало: Город Гиран — NPC «Шаман Друккар»
Финал: Битва с Вождём Карулом Оруто (ID: 27164)

📜 I. Пролог — «Шёпот из Разлома»
NPC: Шаман Друккар (ID: 30977)
HTML: 30977-1.htm
<html><body>Шаман Друккар:<br>Ты слышишь это? Земля стонет. В глубинах Разлома просыпается древний дух — <font color="LEVEL">Карул Оруто</font>.<br>Когда-то он был вождём орков, но принял силу Тьмы, чтобы спасти свой клан… и обрёк его.<br><br>Если хочешь понять, что ждёт Эльморион, иди туда, где камни плачут кровью.<br><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Q10031_OrutoLegacy acceptQuest">Отправиться к Разлому</Button></body></html>
Цель: Принять задание и отправиться к «Разлому Оруто» (локация — северная часть Долины Орков).

⚔️ II. Этап — «Падший Вождь»
Описание:
Игрок находит лагерь павших орков. В центре стоит идол с выбитым именем Оруто. При взаимодействии запускается сцена появления вождя.
NPC: Вождь Карул Оруто (ID: 27164)
HTML: 27164-1.htm
<html><body>Вождь Карул Оруто:<br><font color="LEVEL">Ты… живой?</font> Я помню свет… и боль. Моё тело — это тюрьма, созданная богами.  Ты пришёл забрать моё наследие? Или освободить?<br><br><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Q10031_OrutoLegacy killBoss">Сразиться с ним</Button><br><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Q10031_OrutoLegacy purifySoul">Очищение души</Button></body></html>

☯️ III. Развилка:🩸 Вариант 1 — «Путь Тьмы»
Игрок выбирает битву. После победы он получает предмет:
[Осколок Тлена] (ID: 200014)
и увеличивает счётчик фракции Тьмы в системе АСТРЫ.
🌅 Вариант 2 — «Путь Света»
Игрок очищает дух Оруто, теряя 1 очко Света, но получая предмет:
[Память Оруто] (ID: 200040) — используется позже для создания Скрижали.

🏆 IV. Завершение — «Наследие Принято»
Возврат к: Шаман Друккар
HTML: 30977-2.htm
<html><body>Шаман Друккар:<br>Судьба Оруто решена...<br>Я чувствую, как Астра записала это в летопись мира.<br>Каждый выбор изменяет равновесие, путник. Даже твой.<br><br><font color="LEVEL">Ты завершил квест "Наследие Оруто".</font></body></html>

💰 Награды:
    • Осколок Тлена (для пути Тьмы)

    • Память Оруто (для пути Света)

    • EXP: 2,500,000

    • Adena: 500,000

    • BB-событие: AstraBalanceManager.updateFaction("DARK" or "LIGHT")



⚙️ Техническая интеграция
Файл: Q10031_OrutoLegacy.java
Путь: \data\scripts\quests\Q10031_OrutoLegacy
Связанные HTML:
  • 30977-1.htm
  • 27164-1.htm
  • 30977-2.htm





Q10031_OrutoLegacy.java
  1. /*
  2. * Copyright (c) 2024 ASTRA Dynamics
  3. *
  4. * Licensed under the ASTRA License, Version 1.0 (the "License");
  5. * You may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. *     https://artace.ru/forum-78-1.html
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. * Author: SoulArchitect (ASTRA Dynamics)
  17. * Created Date: 2025-10-24
  18. *
  19. * Description (RU):
  20. *  Квестовая линия «Наследие Оруто».
  21. *  Игрок по выбору либо сражается с Вождём Карулом Оруто (ID 27164) и получает «Осколок Тлена»,
  22. *  усиливая фракцию Тьмы; либо очищает его дух и получает «Память Оруто», двигая счётчик Света.
  23. *
  24. *  Встроены безопасные вызовы в подсистему АСТРЫ (Balance Brain / Counters).
  25. *  Если классов АСТРЫ пока нет — блок try/catch заглушает вызов.
  26. */

  27. package quests.Q10031_OrutoLegacy;

  28. import org.l2jmobius.gameserver.enums.QuestSound;
  29. import org.l2jmobius.gameserver.enums.Race;
  30. import org.l2jmobius.gameserver.model.actor.Npc;
  31. import org.l2jmobius.gameserver.model.actor.Player;
  32. import org.l2jmobius.gameserver.model.quest.Quest;
  33. import org.l2jmobius.gameserver.model.quest.QuestState;
  34. import org.l2jmobius.gameserver.model.quest.State;
  35. import org.l2jmobius.gameserver.network.NpcStringId;
  36. import org.l2jmobius.gameserver.util.Util;

  37. public class Q10031_OrutoLegacy extends Quest
  38. {
  39.         // ====== Константы объекта мира / NPC / предметов ======
  40.         private static final int SHAMAN_DRUKKAR = 30977;   // Стартовый NPC (шаман в Гиране/Адене — можно поменять)
  41.         private static final int ORUTO_BOSS     = 27164;   // Вождь Карул Оруто (квестовый монстр/рейд)
  42.        
  43.         // Предметы по лору (создай при необходимости в базе/дат-файлах своими ID)
  44.         private static final int SHARD_DECAY    = 200014;  // Осколок Тлена (Тьма)
  45.         private static final int MEMORY_ORUTO   = 200040;  // Память Оруто (Свет)
  46.        
  47.         // Прочие настройки
  48.         private static final int MIN_LEVEL      = 55;
  49.        
  50.         // Состояния (cond) для наглядности
  51.         // 0 — ещё не брали; 1 — принято; 2 — выбрали бой; 3 — убит босс; 4 — выбрали очищение; 5 — очищено; 6 — завершение
  52.         private static final String VAR_PATH    = "path";  // "DARK" (бой) или "LIGHT" (очищение)
  53.        
  54.         public Q10031_OrutoLegacy()
  55.         {
  56.                 super(10031); // ID квеста
  57.                
  58.                 // Регистрация стартового NPC и обработчиков
  59.                 addStartNpc(SHAMAN_DRUKKAR);
  60.                 addTalkId(SHAMAN_DRUKKAR, ORUTO_BOSS);
  61.                
  62.                 // Если босс убивается — слушаем событие убийства
  63.                 addKillId(ORUTO_BOSS);
  64.                
  65.                 // Ограничения по уровню
  66.                 addCondMinLevel(MIN_LEVEL, "30977-minlevel.htm");
  67.         }
  68.        
  69.         @Override
  70.         public String onAdvEvent(String event, Npc npc, Player player)
  71.         {
  72.                 final QuestState qs = getQuestState(player, true);
  73.                 if (qs == null)
  74.                 {
  75.                         return null;
  76.                 }
  77.                
  78.                 String html = null;
  79.                
  80.                 switch (event)
  81.                 {
  82.                         // ===== Шаг 1: Принять задание у Друккара =====
  83.                         case "acceptQuest":
  84.                         {
  85.                                 if (qs.isCreated())
  86.                                 {
  87.                                         qs.startQuest();          // state: STARTED, cond=1
  88.                                         playSound(player, QuestSound.ITEMSOUND_QUEST_ACCEPT);
  89.                                         html = "30977-accepted.htm";
  90.                                 }
  91.                                 break;
  92.                         }
  93.                        
  94.                         // ===== Выбор: Бой с Оруто (Тьма) =====
  95.                         case "killBoss":
  96.                         {
  97.                                 if (qs.isStarted() && qs.getCond() == 1)
  98.                                 {
  99.                                         qs.setCond(2, true);      // Пошли в ветку боя
  100.                                         qs.set(VAR_PATH, "DARK");
  101.                                         html = "27164-fight.htm";
  102.                                 }
  103.                                 break;
  104.                         }
  105.                        
  106.                         // ===== Выбор: Очищение души (Свет) =====
  107.                         case "purifySoul":
  108.                         {
  109.                                 if (qs.isStarted() && qs.getCond() == 1)
  110.                                 {
  111.                                         qs.setCond(4, true);
  112.                                         qs.set(VAR_PATH, "LIGHT");
  113.                                        
  114.                                         // Здесь включаем «очищение»: даём предмет и фиксируем выбор
  115.                                         if (!hasQuestItems(player, MEMORY_ORUTO))
  116.                                         {
  117.                                                 giveItems(player, MEMORY_ORUTO, 1);
  118.                                         }
  119.                                        
  120.                                         // Сигналим в АСТРУ: -1 очко Света с игрока, +1 в глобальный «Очищение» (пример)
  121.                                         callAstraBalance(player, "LIGHT", +1, "OrutoPurified");
  122.                                        
  123.                                         html = "27164-purified.htm";
  124.                                 }
  125.                                 break;
  126.                         }
  127.                        
  128.                         // ===== Завершить квест у Друккара =====
  129.                         case "finishQuest":
  130.                         {
  131.                                 if (qs.isStarted())
  132.                                 {
  133.                                         // Путь Тьмы: предмет выдадим после убийства; Путь Света: предмет уже выдан
  134.                                         if (qs.getCond() >= 3 || qs.getCond() == 4 || qs.getCond() == 5)
  135.                                         {
  136.                                                 // Общая награда
  137.                                                 addExpAndSp(player, 2_500_000, 0);
  138.                                                 giveAdena(player, 500_000, true);
  139.                                                
  140.                                                 qs.exitQuest(false, true);
  141.                                                 html = "30977-finish.htm";
  142.                                         }
  143.                                 }
  144.                                 break;
  145.                         }
  146.                 }
  147.                 return html;
  148.         }
  149.        
  150.         @Override
  151.         public String onTalk(Npc npc, Player player)
  152.         {
  153.                 final QuestState qs = getQuestState(player, true);
  154.                 if (qs == null)
  155.                 {
  156.                         return getNoQuestMsg(player);
  157.                 }
  158.                
  159.                 String html = null;
  160.                
  161.                 switch (npc.getId())
  162.                 {
  163.                         case SHAMAN_DRUKKAR:
  164.                         {
  165.                                 if (qs.isCreated())
  166.                                 {
  167.                                         html = "30977-1.htm"; // Пролог и кнопка «acceptQuest»
  168.                                 }
  169.                                 else if (qs.isStarted())
  170.                                 {
  171.                                         if (qs.getCond() == 1)
  172.                                         {
  173.                                                 html = "30977-progress.htm"; // Подсказка: иди к Разлому/к Оруто
  174.                                         }
  175.                                         else if (qs.getCond() == 2)
  176.                                         {
  177.                                                 html = "30977-dark-wait.htm"; // Напоминание: победить Оруто
  178.                                         }
  179.                                         else if (qs.getCond() == 3 || qs.getCond() == 4 || qs.getCond() == 5)
  180.                                         {
  181.                                                 html = "30977-2.htm"; // Кнопка «finishQuest»
  182.                                         }
  183.                                 }
  184.                                 else
  185.                                 {
  186.                                         html = "30977-complete.htm"; // Уже завершали
  187.                                 }
  188.                                 break;
  189.                         }
  190.                        
  191.                         case ORUTO_BOSS:
  192.                         {
  193.                                 // Взаимодействуем с самим Вождём (диалог-развилка)
  194.                                 if (qs.isStarted() && qs.getCond() == 1)
  195.                                 {
  196.                                         html = "27164-1.htm"; // Кнопки: killBoss / purifySoul
  197.                                 }
  198.                                 else if (qs.isStarted() && qs.getCond() == 2)
  199.                                 {
  200.                                         html = "27164-fight.htm"; // Уже выбрали бой
  201.                                 }
  202.                                 else if (qs.isStarted() && (qs.getCond() == 4 || qs.getCond() == 5))
  203.                                 {
  204.                                         html = "27164-purified.htm"; // Уже выбрали очищение
  205.                                 }
  206.                                 break;
  207.                         }
  208.                 }
  209.                 return html;
  210.         }
  211.        
  212.         @Override
  213.         public String onKill(Npc npc, Player killer, boolean isSummon)
  214.         {
  215.                 final Player player = getRandomPartyMember(killer, 2); // cond=2 — выбрали бой
  216.                 if (player == null)
  217.                 {
  218.                         return super.onKill(npc, killer, isSummon);
  219.                 }
  220.                
  221.                 final QuestState qs = getQuestState(player, false);
  222.                 if ((qs != null) && qs.isStarted() && (qs.getCond() == 2))
  223.                 {
  224.                         // Выдаём «Осколок Тлена» за убийство и двигаем ветку
  225.                         if (!hasQuestItems(player, SHARD_DECAY))
  226.                         {
  227.                                 giveItems(player, SHARD_DECAY, 1);
  228.                         }
  229.                         qs.setCond(3, true); // Босс повержен
  230.                        
  231.                         // Сигналим в АСТРУ: рост Тьмы
  232.                         callAstraBalance(player, "DARK", +1, "OrutoSlain");
  233.                 }
  234.                 return super.onKill(npc, killer, isSummon);
  235.         }
  236.        
  237.         // ===== Безопасный вызов подсистемы АСТРЫ (если есть в твоём билде) =====
  238.         private void callAstraBalance(Player player, String faction, int delta, String reason)
  239.         {
  240.                 try
  241.                 {
  242.                         // Пример интеграции (адаптируй под свои классы):
  243.                         // org.elmorion.astra.AstraBalanceManager.updateFaction(faction, delta);
  244.                         // org.elmorion.astra.AstraMemory.log(player, "Q10031", reason, faction, delta);
  245.                        
  246.                         // Для Essence без АСТРЫ это просто заглушка:
  247.                         if (player != null && faction != null && reason != null)
  248.                         {
  249.                                 // no-op
  250.                         }
  251.                 }
  252.                 catch (Exception ignored)
  253.                 {
  254.                         // Никаких падений сервера из-за отсутствующей АСТРЫ.
  255.                 }
  256.         }
  257. }
Скопировать код
HTML-файлы (в папку data/scripts/quests/Q10031_OrutoLegacy/)
1) 30977-1.htm (пролог у шамана)



<html><body>Шаман Друккар:<br>Ты чувствуешь, как земля дрожит? Древний дух <font color="LEVEL">Карул Оруто</font> шевельнулся в Разломе.<br>Когда-то он был вождём орков, но принял силу Тьмы, пытаясь спасти свой клан — и пал.<br><br>Если хочешь понять, куда качнётся мир Эльмориона — иди. Астра запомнит твой выбор.<br><br><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Q10031_OrutoLegacy acceptQuest">Отправиться к Разлому</Button></body></html>

2) 30977-progress.htm (напоминание)



<html><body>Шаман Друккар:<br>Разлом шепчет имя Оруто. Иди туда, где камни пропитаны кровью. Выбор ждёт тебя.<br></body></html>

3) 30977-dark-wait.htm (выбрали бой, ещё не убили)



<html><body>Шаман Друккар:<br>Раз уж выбрал путь стали — доведи дело до конца. Победи <font color="LEVEL">Карула Оруто</font>!<br></body></html>

4) 30977-2.htm (финал — кнопка завершить)



<html><body>Шаман Друккар:<br>Судьба Оруто решена. Я слышу, как Астра заносит это в летопись мира...<br><br><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Q10031_OrutoLegacy finishQuest">Завершить «Наследие Оруто»</Button></body></html>

5) 30977-finish.htm (успешное завершение)



<html><body>Шаман Друккар:<br>Хорошая работа. Помни: каждый выбор изменяет равновесие.<br>Пусть Астра будет благосклонна к твоей дороге.<br></body></html>

6) 30977-minlevel.htm (если ниже уровня)



<html><body>Шаман Друккар:<br>Твоя сила ещё не готова к шёпоту Разлома. Возвращайся после <font color="LEVEL">55-го уровня</font>.<br></body></html>

7) 30977-complete.htm (уже проходили)



<html><body>Шаман Друккар:<br>Мы уже помним твой выбор. Иди своей дорогой, путник.<br></body></html>

8) 27164-1.htm (диалог-развилка с Оруто)



<html><body>Вождь Карул Оруто:<br>Ты… живой. А я — память, скованная плотью. Богам нужен был страж, и они сделали его из меня.<br><br>Чего ты ищешь — моего падения или моего освобождения?<br><br><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Q10031_OrutoLegacy killBoss">Сразиться с Вождём</Button><br><Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Q10031_OrutoLegacy purifySoul">Очищение души</Button></body></html>

9) 27164-fight.htm (ветка боя)



<html><body>Вождь Карул Оруто:<br>Пусть сталь говорит за нас. Покажи, чего стоит твой выбор!<br></body></html>

10) 27164-purified.htm (ветка очищения)



<html><body>Вождь Карул Оруто:<br>Твоё пламя… жжёт Тьму. Я помню свет — и благодарен. Возьми эту <font color="LEVEL">Память Оруто</font>...<br>И дай знать шаману: моя песня завершилась.<br></body></html>


Где положить файлы
  • Java:
    data/scripts/quests/Q10031_OrutoLegacy/Q10031_OrutoLegacy.java
  • HTML:
    data/scripts/quests/Q10031_OrutoLegacy/*.htm (все из списка выше)

Регистрация (если требуется в твоём билде): добавь Q10031_OrutoLegacy в scripts.cfg или убедись, что автозагрузка скриптов включена.

Быстрые примечания по интеграции
  • Спавн/локация Оруто: можешь оставить как «квестовый монстр» в существующей локации Долины Орков / Руинах Кузни. Если он уже есть в мире — всё ок.
  • Предметы 200014/200040: если их ещё нет в твоих itemname-ru.dat/itemdesc-ru.txt/EtcItemgrp*, просто добавь записи (у тебя уже есть шаблоны для осколков/памяти).
  • АСТРА (BB): замени внутри callAstraBalance(...) на свои реальные классы/методы. Сейчас это безопасная заглушка.
  • Баланс/награды: EXP/Adena подгони под экономику сборки.
  • Фракционные счётчики: если используешь глобальные переменные (SQL/Holder), добавь там обработку событий OrutoSlain и OrutoPurified.





Хроники Элмориона пишутся каждым шагом путника.
Расширенный режим
B Color Image Link Quote Code Smilies |Загрузить

Правила начисления баллов

Быстрый ответ Наверх Вернуться к списку