Полный гайд по инстансам (Kamaloka и что угодно)

1. Нам необходимо создать XML файл в которой будет описан наш инстанц (Для наглядного примера берем Kamaloka)

Путь: gameserver\data\instances\[72] Kamaloka, Hall of the Abyss.xml
Сама схема:
XML:
<!DOCTYPE list SYSTEM "instances.dtd">
<list>
    <instance id="72" name="Kamaloka, Hall of the Abyss" maxChannels="10" collapseIfEmpty="5" timelimit="30" dispelBuffs="true">
        <collapse on-party-dismiss="true" timer="60"/>
        <level min="70" max="80"/>
        <party min="2" max="6"/>
        <return loc="43928 -49144 -792"/>
        <teleport loc="180056 -88968 -7216"/>
        <geodata map="25_15"/>
        <remove itemId="0" count="0" necessary="false"/>
        <give itemId="0" count="0"/>
        <quest id="0"/>
        <reuse resetReuse="30 6 * * *" setUponEntry="true" sharedReuseGroup="1"/> <!-- Instance reuse at 6:30 every day -->
        <spawns>
            <spawn mobId="25657" type="point" respawn="0>
                <coords loc="180375 -88984 -7216"/>
            </spawn>
            <spawn mobId="25658" type="point" respawn="0>
                <coords loc="182168 -88968 -7216"/>
            </spawn>
            <spawn mobId="25659" type="point" respawn="0>
                <coords loc="183911 -88969 -7216 "/>
            </spawn>
        </spawns>
        <doors>
            <door id="25150001" opened="false"/>
            <door id="25150002" opened="false"/>
            <door id="25150003" opened="false"/>
            <door id="25150004" opened="false"/>
        </doors>
    </instance>
</list>

Где:
  • name - название инста
  • maxChannels - сколько может быть создано реплик этого инстанса
  • collapseIfEmpty -время через которое игроков при успешном проходе или истечении времени инстанса будет автоматически закрыт и игроки перемещены в <return loc="43928 -49144 -792"/>
  • timelimit - время жизни инстанса
  • dispelBuffs - удалять баффы при входе в инстанс или нет
  • <collapse on-party-dismiss="true" timer="60"/> - закрывать инстанс и возвращать игроков назад через timer="60" если пати была разорвана
  • <level min="70" max="80"/> - минимальный и максимальный уровень для входа в инстанс
  • <party min="2" max="6"/> - минимальное количество и максимальное количество игроков в пати
  • <teleport loc="180056 -88968 -7216"/> - точка телепорта при входе в инстанс
  • <return loc="43928 -49144 -792"/> - координата в которую будет возвращать игроков при закрытии инстанса
  • <geodata map="25_15"/> - квадрат геодаты текущего инстанса (нужно ставить если у вас есть там двери, нет - можете забить)
  • <remove itemId="0" count="0" necessary="false"/> какой итем нужен для входа в инстанс. По умолчанию ничего не забираем
  • <give itemId="0" count="0"/> - предмет который будет выдан после входа в инстанс
  • <quest id="0"/> - необходимый квест для входа в инстанса.
  • <reuse resetReuse="30 6 * * *" setUponEntry="true" sharedReuseGroup="1"/> - когда произойдёт сброс отката инста. setUponEntry ture -откат ставится сразу после входа, а не по завершению. sharedReuseGroup - шарить его во всю группу инстансов
  • <spawns></spawns> - блок для спауна НПЦ или мобов которые вы хотите или описываете своим скриптом.
  • <doors></doors> - двери которые есть в инсте, обязательно указывать или игроки будут через них пробегать якобы нет геодаты внутри.
  • <add_parameters><param name="hwidLimit" value="true"/></add_parameters> - если активировать этот параметр, откат будет записываться на HWID и не пускать в инст если HWID тот же.
  • <zones></zones> - блок с массивом зон (необязательный). Как пример: <zones><zone name="[my_zone_1]" active="true"/><zone name="[my_zone_1]" active="true"/></zones>


2. Делаем своего НПЦ или берем стандартного id 40031
Пример:
По факту у вас должен быть тип НПЦ <set name="type" value="EventReflectionManager" />
Но так же выкладываю полного

XML:
<npc id="40031" name="Pathfinder Worker" title="Dimensional Manager">
   <set name="aggroRange" value="0" />
   <set name="ai_type" value="CharacterAI" />
   <set name="baseAtkRange" value="40" />
   <set name="baseCON" value="43" />
   <set name="baseCritRate" value="40" />
   <set name="baseDEX" value="30" />
   <set name="baseHpMax" value="2444.468" />
   <set name="baseHpRate" value="1" />
   <set name="baseHpReg" value="7.5" />
   <set name="baseINT" value="21" />
   <set name="baseMAtk" value="780" />
   <set name="baseMAtkSpd" value="500" />
   <set name="baseMDef" value="382" />
   <set name="baseMEN" value="20" />
   <set name="baseMpMax" value="1345.8" />
   <set name="baseMpReg" value="2.7" />
   <set name="basePAtk" value="1303" />
   <set name="basePAtkSpd" value="253" />
   <set name="basePDef" value="471" />
   <set name="baseRunSpd" value="120" />
   <set name="baseSTR" value="40" />
   <set name="baseShldDef" value="0" />
   <set name="baseShldRate" value="0" />
   <set name="baseWIT" value="20" />
   <set name="baseWalkSpd" value="30" />
   <set name="collision_height" value="23.0" />
   <set name="collision_radius" value="8.0" />
   <set name="level" value="70" />
   <set name="rewardExp" value="0" />
   <set name="rewardRp" value="0" />
   <set name="rewardSp" value="0" />
   <set name="shots" value="NONE" />
   <set name="texture" value="" />
   <set name="displayId" value="35579"/>
   <set name="type" value="EventReflectionManager" />
   <skills>
      <skill id="4416" level="14" /> <!--Humans-->
   </skills>
   <attributes>
      <defence attribute="fire" value="150" />
      <defence attribute="water" value="150" />
      <defence attribute="wind" value="150" />
      <defence attribute="earth" value="150" />
      <defence attribute="holy" value="150" />
      <defence attribute="unholy" value="150" />
   </attributes>
</npc>

Теперь смотрим его диалог и наглядно цепляем к нему вход в нужный нам инстанс:
Путь обязательно должен быть gameserver\data\html\events\instances\40031.htm
Теперь сам диалог:
и сразу смотрим на строку [npc_%objectId%_Chat 1|Войти в Камалоку.] которое перекинет нас для входа в инстанс 40031-1.htm

HTML:
Pathfinder Worker:

Да? Хотите войти в Камалоку?

[npc_%objectId%_event_instance 72|Войти в Камалоку, Зал Бездны (Уровень 70-80).]

Где npc_%objectId%_event_instance 72 id нашего инстанца! Который мы уже предварительно создали в gameserver\data\instances\[72] Kamaloka, Hall of the Abyss.xml

3. Как открывать двери или делать любые какие угодно вам действия при убийстве Рейдов или мобов внутри инстанса. Мы рассмотрим конкретно открытия дверей и вам необходимо знать хотя бы чуток яву.
Переходим к примеру:
Где при убийстве моба id 25657 будет открываться дверь id 25150002 и при убийстве 25658 будет открываться дверь id 25150003.
У самих же этих мобов id 25657 и id 25658 в data/npc стоит тип <set name="type" value="EventReflectionMob"/>
Вы можете создавать любой нужный себе сценарий или открывать двери при убийстве нужного вам моба внутри инстанса.
Исходный код прикладываю, как компилировать ваши скрипты и загружать их >>> Гайд <<<

Java:
package npc.model;

import l2.gameserver.instancemanager.ReflectionManager;
import l2.gameserver.model.Creature;
import l2.gameserver.model.instances.DoorInstance;
import l2.gameserver.model.instances.MonsterInstance;
import l2.gameserver.templates.npc.NpcTemplate;

public class EventReflectionMobInstance extends MonsterInstance
{
  public EventReflectionMobInstance(int objectId, NpcTemplate template)
  {
    super(objectId, template);
  }

  @Override
  protected void onDeath(Creature killer)
  {
    super.onDeath(killer);
    if(getReflection() == killer.getReflection() && getReflection() != ReflectionManager.DEFAULT)
    {
      switch(getNpcId())
      {
        case 25657:
        {
          DoorInstance door = getReflection().getDoor(25150002);
          if(door != null)
          {
            door.openMe();
          }
        }
        break;
        case 25658:
        {
          DoorInstance door = getReflection().getDoor(25150003);
          if(door != null)
          {
            door.openMe();
          }
        }
        break;
      }
    }
  }
}

Вся система ограничена лишь вашей фантазией и при минимальных знаниях вы можете создавать какие угодно инстансы с любыми сценариями и событиями. Все в ваших руках!
 
Last edited:
2-9 тоже поставил ?
Code:
<!DOCTYPE list SYSTEM "instances.dtd">
<list>
    <instance id="72" name="Kamaloka, Hall of the Abyss" maxChannels="30" collapseIfEmpty="1" timelimit="30" dispelBuffs="false">
        <collapse on-party-dismiss="true" timer="30"/> <!-- Time -->
        <level min="75" max="80"/>
        <party min="2" max="9"/>
        <return loc="147712 -55271 -2728"/> <!-- Goddard -->
        <teleport loc="180056 -88968 -7216"/>
        <geodata map="25_15"/>
        <remove itemId="9991" count="20" necessary="true"/> <!-- 20 Event Coin -->
        <give itemId="0" count="0"/> <!-- Token -->
        <quest id="0"/>
        <reuse resetReuse="30 6 * * *" setUponEntry="true" sharedReuseGroup="1"/> <!-- Instance reuse at 6:30 every day -->
        <spawns>
            <spawn mobId="25657" type="point">
                <coords loc="180375 -88984 -7216"/>
            </spawn>
            <spawn mobId="25658" type="point">
                <coords loc="182168 -88968 -7216"/>
            </spawn>
            <spawn mobId="25659" type="point">
                <coords loc="183911 -88969 -7216 "/>
            </spawn>
        </spawns>
        <doors>
            <door id="25150001" opened="false"/>
            <door id="25150002" opened="false"/>
            <door id="25150003" opened="false"/>
            <door id="25150004" opened="false"/>
        </doors>
        <add_parameters>
            <param name="hwidLimit" value="true"/>
        </add_parameters>
    </instance>
</list>
 
к сожалению
позже сам проверю. Что то ты делаешь не так. Вот тебе вариант проверки у самого НПЦ все проверки
Code:
package npc.model;

import l2.gameserver.data.htm.HtmCache;
import l2.gameserver.instancemanager.ReflectionManager;
import l2.gameserver.model.Party;
import l2.gameserver.model.Player;
import l2.gameserver.model.entity.Reflection;
import l2.gameserver.model.instances.NpcInstance;
import l2.gameserver.model.quest.QuestState;
import l2.gameserver.templates.npc.NpcTemplate;
import l2.gameserver.utils.ItemFunctions;
import l2.gameserver.utils.ReflectionUtils;
import quests._620_FourGoblets;

public final class EventReflectionManagerInstance extends NpcInstance
{
  public EventReflectionManagerInstance(int objectId, NpcTemplate template)
  {
    super(objectId, template);
  }

  @Override
  public void onBypassFeedback(Player player, String command)
  {
    if(!canBypassCheck(player, this))
      return;

    if(command.startsWith("event_instance"))
    {
      int val = Integer.parseInt(command.substring(15));
      Reflection r = player.getActiveReflection();
      Party playerParty = player.getParty();
      if(playerParty == null || !playerParty.isLeader(player))
      {
        showChatWindow(player, "not_party_leader.htm");
        return;
      }
      for(Player member : playerParty.getPartyMembers())
      {
        if(member.getInventory().getCountOf(4037) < 20)
        {
          showChatWindow(member, "not_enough_items.htm");
          return;
        }
        else
          ItemFunctions.removeItem(member, 4037, 20, true);
      }
      if(player.getParty() == null || !player.getParty().isLeader(player))
      {
        showChatWindow(player, "not_party_leader.htm");
        return;
      }

      if(r != null)
      {
        if(player.canReenterInstance(val))
          player.teleToLocation(r.getTeleportLoc(), r);
      }
      else if(player.canEnterInstance(val))
      {
        ReflectionUtils.enterReflection(player, val);
      }
    }
    else if(command.startsWith("escape_event_instance"))
    {
      if(player.getParty() == null || !player.getParty().isLeader(player))
      {
        showChatWindow(player, "not_party_leader.htm");
        return;
      }
      player.getReflection().collapse();
    }
    else if(command.startsWith("return"))
    {
      Reflection r = player.getReflection();
      if(r.getReturnLoc() != null)
        player.teleToLocation(r.getReturnLoc(), ReflectionManager.DEFAULT);
      else
        player.setReflection(ReflectionManager.DEFAULT);
    }
    else
      super.onBypassFeedback(player, command);
  }

  @Override
  public void showChatWindow(Player player, int val, Object... arg)
  {
    super.showChatWindow(player, val);
  }

  @Override
  public String getHtmlPath(int npcId, int val, Player player)
  {
    String pom;
    if(val == 0)
      pom = "" + npcId;
    else
      pom = npcId + "-" + val;

    return "events/instances/" + pom + ".htm";
  }
}
 
Guys, i have some questions.
1. its possible to make second boss respawn only when first boss was killed, and thirth boss when second was killed... etc.?
2. its possible to make at end of a dungeon appear a npc 'gk' who telepor back to real world all party and kill the instance like kamaloka on h5 chronicles.
 
Last edited:
Back
Top