The complete guide of instances (Kamaloka and whatever)

Deazer

Разработчик
Staff member
#1
1. We need to create an XML file in which our instance will be described (For an illustrative example, we take Kamaloka)

Path: gameserver\data\instances\[72] Kamaloka, Hall of the Abyss.xml
The xml itself:

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>
Where:
  • name - instance name
  • maxChannels - how many replicas of this instance can be created
  • collapseIfEmpty - the time after which the players will be automatically closed and the players will be moved to <return loc="43928 -49144 -792" /> upon successful passage or expiration of the instance time
  • timelimit - instance lifetime
  • dispelBuffs - remove buffs when entering an instance or not
  • <collapse on-party-dismiss="true" timer="60"/> - close the instance and return players back through timer="60" if the party was broken (time in seconds)
  • <level min="70" max="80"/> - minimum and maximum level to enter the instance
  • <party min="2" max="6"/> - minimum number and maximum number of players in a party
  • <teleport loc="180056 -88968 -7216"/> - teleport point at the entrance to the instance
  • <return loc="43928 -49144 -792"/> - the coordinate to which the players will return when the instance is closed
  • <geodata map="25_15"/> - the square of the geodata of the current instance (you need to put it if you have doors there, no - you can forget)
  • <remove itemId="0" count="0" necessary="false"/> what item is needed to enter the instance. We do not take anything by default
  • <give itemId="0" count="0"/> - an item that will be issued after entering the instance
  • <quest id="0"/> - required quest to enter the instance.
  • <reuse resetReuse="30 6 * * *" setUponEntry="true" sharedReuseGroup="1"/> - when the instance reuse will be reset. setUponEntry ture - reuse is set immediately after entry, not upon completion. sharedReuseGroup - share it with the entire group of instances
  • <spawns></spawns> - block for spawning NPCs or mobs that you want or describe with your script.
  • <doors></doors> - the doors that are in the insta must be indicated or the players will run through them supposedly there is no geodata inside.
  • <add_parameters><param name="hwidLimit" value="true"/></add_parameters> - if you enable this parameter, the reuse will be written to the HWID and not allowed to the player if the HWID is the same.
  • <zones></zones> - block with an array of zones (optional). As an example: <zones><zone name="[my_zone_1]" active="true"/><zone name="[my_zone_1]" active="true"/></zones>
2. We make our own NPC or take a standard one id 40031
Example:
In fact, you must have an NPC type <set name="type" value="EventReflectionManager" />
But I also post full

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>

Now we look at its dialogue and visually hook the entrance to the instance we need to it:
The path must be gameserver\data\html\events\instances\40031.htm
Now the dialogue itself:
and immediately look at the line [npc_%objectId%_Chat 1|Enter Kamaloka.] which will transfer us to enter the instance 40031-1.htm

HTML:
Pathfinder Worker:

What! You want to enter Kamaloka?

[npc_%objectId%_event_instance 72|Enter Kamaloka, Hall of the Abyss (level 70-80).]
Where npc_%objectId%_event_instance 72 is the id of our instance! Which we have already pre-created in gameserver\data\instances\[72] Kamaloka, Hall of the Abyss.xml

3. How to open doors or do whatever you want to do when killing Raids or mobs inside the instance. We will deal specifically with door openings and you need to know at least a little of reality.
Let's move on to an example:
Where, when you kill mob id 25657, the door id 25150002 will open and when you kill 25658, the door id 25150003 will open.
These mobs themselves, id 25657 and id 25658 in data/npc have the type <set name="type" value="EventReflectionMob" />
You can create any scenario you want or open doors when you kill a mob you need inside an instance.
I am attaching the source code how to compile your scripts and load them >>> Guide of compile <<<

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;
      }
    }
  }
}
The whole system is limited only by your imagination, and with minimal knowledge you can create any instances with any scenarios and events. All in your hands!
 
Last edited:

BerserkdGG

Пользователь
#2
What's the best way of handling reflection variables?.
I want to check if the 5 mobs where killed. Right now I'm using player.setVar() but i'd like to use something in memory, like player.getReflection.setVar("mobsKilled")

In this example I can handle reflection mobs, but not the reflection itself.
 

Deazer

Разработчик
Staff member
#3
set any INT flag at method on kill, that all. That is most easy way.
And you can set it like activeChar.setVar("some_param", String.valueOf(val), -1); and on next enter at Refglection flush that param, like activeChar.setVar("some_param", String.valueOf(0), -1);
 

BerserkdGG

Пользователь
#4
set any INT flag at method on kill, that all. That is most easy way.
And you can set it like activeChar.setVar("some_param", String.valueOf(val), -1); and on next enter at Refglection flush that param, like activeChar.setVar("some_param", String.valueOf(0), -1);
This solution has a concurrency problem when you kill 3 or more mobs at the same time.
Is it there any way to add semaphores/mutex/whatever lock to that variable?.

Thanks!

Edit:
Solved by using synchronized keyword on a singleton class method.
 
Last edited:
Top