• Новые темы в этом разделе публикуются автоматически при добавлении файла в менеджер ресурсов.
    Ручное создание новых тем невозможно.
Иконка ресурса

Мануал Skilldata.txt - формат и описание параметров

kick

Предвестник
Administrator
Сообщения
6 961
Розыгрыши
21
Решения
1
Репутация
6 039
Реакции
6 790
Баллы
2 688
Описание параметров:
  • skill_begin - начало скилла
  • skill_name = [s_wyvern_breath] - название скилла (на которое ссылаются извне, например из itemdata)
  • /* [와이번 브레스] */ - Комментарий на корейском языке
  • skill_id = 4289 - ID Скилла
  • level = 1 - Уровень скилла
  • operate_type = P - пассивный, А1 или А2 - активный скилл.
SKILL_INSTANT=A1
SKILL_DURATION=A2
SKILL_DURATION_LEVEL_UP=A4
SKILL_SELFDURATION=A3
SKILL_PASSIVE=p
SKILL_TOGGLE=T
SKILL_CHANNELLING_INSTANCE=CA1
SKILL_CHANNELLING_DURATION=CA2
SKILL_CHANNELLING_DURATION_LEVEL_UP=CA5
SKILL_CHARGE_INSTANT=DA1
SKILL_CHARGE_DURATION=DA2
SKILL_AURA=AU
SKILL_AURA_ACTIVITY=A5
SKILL_GROUP_TOGGLE=TG
SKILL_BACK_STEP_INSTANT=DA3
SKILL_BACK_STEP_DURATION=DA4
SKILL_AURA_ACTIVITY2=A6
SKILL_PARTY_INSTANT=AP
SKILL_DUAL_PUMP1=DP1
SKILL_RACE_SPECIAL_PASSIVE=RP
SKILL_BLINK_INSTANT=DA5
SKILL_BACK_STEP_DURATION_WITH_TARGET_KNOCKBACK=DA6
  • magic_level = 60 - Уровень с которого персонаж может использовать данный скил
  • effect = - Что умеет скилл. Список эффектов.
  • operate_cond = {{op_wyvern}} - условия использования скилла
  • is_magic = 0 - скорость каста скилла и откат зависят от каст спида
  • is_magic = 1 - скорость каста скилла и откат зависят от атак спида
  • is_magic = 2 - фиксированые скорость каста скилла и откат ни от чего не зависят aka SOE, свиток воскрешения etc.
  • mp_consume2 = 400 - Сколько требует MP
  • cast_range = 700 - Дальность выстрела данным скиллом
  • effective_range = 1200 - Эффективная "дальность" атаки
  • skill_hit_time = 3.6 - Время каста скилла
  • skill_cool_time = 0 - фриз после каста, если поставить параметр "3" это будет значить что после каста скилла чар будет 3 секунды стоять как бы заморожен, нельзя будет двигаться, кастовать
  • skill_hit_cancel_time = 3.6 - в течении которого времени можно отменить каст скилла кнопкой Esc
  • reuse_delay = 6 - Откат скила
  • attribute = attr_fire - тип скилла (водяной, ветряной, темная атака например..)
  • effect_point = -1500 - используется для повышения эффективности аггра у мобов
  • target_type = wyvern_target - тип цели, на которую кастуется скилл. В данном случае только на другую виверну
  • affect_scope = wyvern_scope - как выбирается цель (одиночная, на себя, диапазон, аура)
  • affect_range = 200 - как выбирается цель (одиночная, на себя, диапазон, аура)
  • affect_object = wyvern_object - как выбирается цель (одиночная, на себя, диапазон, аура)
  • affect_limit = {0;0} - минимальное и максимальное количество обрабатываемых целей, если 0;0 то нет ограничения.
  • next_action = none - Выполнение команды после использовании скила
  • ride_state = {@ride_wyvern} - описывает, можно ли юзать скилл сидя на страйдере/виверне и так далее
  • skill_end - окончание скила
 
Последнее редактирование:
У него интерлуде ваганта.
Да, всё верно. Он самый. Так как полагать(или предполагать) его работу при таком сочетании? Дважды хейтит с разными шансами на себя или всё же один раз?
Есть еще Vengeance(id368) с двумя одинаковыми показателями шанса
Effect: [ [ "p_resist_dispel_by_category", "slot_buff", "-60", "per" ], [ "i_target_me_chance", "60" ], [ "i_target_me_chance", "60" ], [ "p_physical_defence", [ "all" ], "5400", "diff" ], [ "p_magical_defence", [ "all" ], "4050", "diff" ], [ "p_block_move" ] ]
 
Ну за ИЛ не скажу, особенно за многократно обкостыленный, но в ХФ и ГФ эффекта i_target_me_chance нет в ДП(и я сильно подозреваю, что в ядре тоже)
Есть третий вариант: Взаимопроникновение идей, методом копипаста.
 
Это самопал или чёто такое. Возможно наследие от с1-с4, углубляться не стал и не хочу.

{i_target_me;%value%} - так +- везде.
 
Подскажите, как расшифровать условие скила или как описать в яве.
Спасибо
Код:
effect={{p_trigger_skill_by_dmg;{enemy_all;1;131};{100;50;diff}

Не совсем понимаю, что из этого урон, а что шанс.
Если по аналогии с умением: Мираж, то тригер при 100 урона с 50% шансом активации?
Но тогда, что значит: {enemy_all;1;131}

Часть нашел..
а - {enemy_all;1;131}, это:
nEnemyType; int nEnemyLevelFrom; int nEnemyLevelTo;
 
Для p_trigger_skill_by_dmg
Пример параметров {enemy_all;1;100};{1;90;diff};[s_npc_trigger_target_cancel1];self;{all}
{{ТИП_ФУНКЦИИ_ТРИГГЕРА;{Условие*;уровень_мин;уровень_макс};{мин_урон;шанс;тип_ордера};{скилл_триггер};цель_триггера;{допкондишен}
Условие* в контексте ХФ может быть одним из трех enemy_all, pk, mob

В яве можно просто создать общую функцию на триггеры, которая будет обрабатывать дефолтные для всех видов триггеров параметры, а также наследовать от нее персонифицированные функции триггеры.
Также, на каждый тип триггера можно сделать функцию, калькулятор которой будет дергаться в момент когда происходит нужное событие. Например получение урона. Это наиболее простая реализация.
 
Реакции: kick
Реализация есть, интересует условие.
Что есть урон, а что шанс.
Код:
effect={{p_trigger_skill_by_dmg;{enemy_all;1;131};{100;50;diff}
50% активация при 100 урона
или
100% активация при 50 урона

JavaScript:
        <triggers>
            <trigger id="0000" level="1" type="RECEIVE_DAMAGE" chance="50" increasing="true">
                <player damage="100;0"/>
            </trigger>
        </triggers>
 
Может кому пригодится - от нечего делать расколупал и сохранил простеньким скриптом разные скиллдаты на тему того, какие в них существуют параметры и все такое.
Проанализировал таким образом все варианты скиллдат из недавней утечки и шары птс 287 протокола + скиллдату от хф.

В архивах названия файлов = названиям параметров, а их содержимое - все возможные значения этих параметров.
PHP:
require_once "../../common.php";

$sd = $l2s::loadData("skilldata.txt");

$a = [];

for ($x = 0; $x < count($sd); $x++)
{
    if ($sd[$x][0] != "skill_begin")
        continue;

    foreach ($sd[$x] as $t)
    {
        $t = trim($t);

        if (strpos($t, "=") === false || strpos($t, "/*") !== false)
            continue;

        $t = explode("=", $t, 2);
        $k = trim($t[0]);
        $v = trim($t[1]);

        if (!isset($a[$k]) || !in_array($v, $a[$k]))
            $a[$k][] = $v;
    }
}

if (!file_exists("skilldata"))
    mkdir("skilldata");

foreach ($a as $k => $v)
{
    sort($v);
    file_put_contents("skilldata/{$k}.txt", implode("\n", $v)."\n");
}
 

Вложения

  • skilldata_287_classic.zip
    274,1 КБ · Просмотры: 13
  • skilldata_287_classic_aden.zip
    252,8 КБ · Просмотры: 5
  • skilldata_287_essence.zip
    302,7 КБ · Просмотры: 9
  • skilldata_287_homunculus.zip
    1 МБ · Просмотры: 15
  • skilldata_hf.zip
    366,7 КБ · Просмотры: 22
Дополню немного своим разбором skilldata, которую делал, когда переписывал скилл движок. Тут разобрано по типам данных и эффектам.
 

Вложения

  • skilldata_separate_287_ess.zip
    16 КБ · Просмотры: 21
  • skilldata_separate_hf.zip
    10,4 КБ · Просмотры: 21
  • skilldata_separate_287_hom.zip
    19,2 КБ · Просмотры: 14
PHYSICAL_SKILL = 0
MAGIC_SKILL = 1
ETC_SKILL = 2
SONGDANCE_SKILL = 3
TRIGGER_SKILL = 4
SUMMON_SKILL = 5
PHYSICAL_SKILL_NOCANCEL = 6
MAGIC_SKILL_NOCANCEL = 7
MAGIC_SKILL_MAX = 8
PHYSICAL_ATTACK_SKILL = 10
PHYSICAL_DEFENSE_SKILL = 11
PHYSICAL_SHOOT_SKILL = 12
PHYSICAL_ENCHANT_SKILL = 13
MAGIC_ELEMENT_SKILL = 20
MAGIC_DIMENSION_SKILL = 21
MAGIC_ENCHANT_SKILL = 22
MAGIC_HOLY_SKILL = 23
MAGIC_DARKNESS_SKILL = 24
MAGIC_VOODOO_SKILL = 25
MAX = 26
 
  • operate_type = P - пассивный, А1 или А2 - активный скилл.
SKILL_INSTANT=A1
SKILL_DURATION=A2
SKILL_DURATION_LEVEL_UP=A4
SKILL_SELFDURATION=A3
SKILL_PASSIVE=p
SKILL_TOGGLE=T
SKILL_CHANNELLING_INSTANCE=CA1
SKILL_CHANNELLING_DURATION=CA2
SKILL_CHANNELLING_DURATION_LEVEL_UP=CA5
SKILL_CHARGE_INSTANT=DA1
SKILL_CHARGE_DURATION=DA2
SKILL_AURA=AU
SKILL_AURA_ACTIVITY=A5
SKILL_GROUP_TOGGLE=TG
SKILL_BACK_STEP_INSTANT=DA3
SKILL_BACK_STEP_DURATION=DA4
SKILL_AURA_ACTIVITY2=A6
SKILL_PARTY_INSTANT=AP
SKILL_DUAL_PUMP1=DP1
SKILL_RACE_SPECIAL_PASSIVE=RP
SKILL_BLINK_INSTANT=DA5
SKILL_BACK_STEP_DURATION_WITH_TARGET_KNOCKBACK=DA6
 
Вот я их в сервере в enum видел тоже, но в скилл дате не нашел ничего похожего. Это для каких хроник актуально?
 
Из этого списка в Glory Days есть до A6 (включительно). Выше хроник нету чтобы глянуть
 
Последнее редактирование:
Ааа, действительно. В 287 из шары тоже есть.
Спасибо)
 
Подскажите пожалуйста по параметру operate_type на протокол 418. У меня другие значения в skillgrp (0, 5, 15, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 277, 280, 281, 284, 285, 287, 292) Но информацию по соответствии значений не нашел.
 
reuse_delay_type = S
на хфе вроде как глобальное кд на скиллы, спс Aristo
 
Нет, это именно Super. Если скилл имеет reuse_delay_type = S, то он получает откат для всех сабов и мейна, а если нет, только на активный саб или мейн.

Код:
enum SkillReuseDelayType : __int32
{
  SRDT_NORMAL = 0x0,
  SRDT_SUPER = 0x1,
};

Код:
__int64 __fastcall CCreature::SetSkillReuseDelay(CCreature *this, CSkillInfo *skill)
{
  double v4; // xmm6_8
  int m_nReuseDelayGroup; // r8d
  std::_Tree_node<std::pair<int const ,CSkillInfo const *>,void *> *v6; // rcx
  std::_Tree_node<std::pair<int const ,CSkillInfo const *>,void *> *v7; // rax
  const CSkillInfo *v8; // rdx
  std::_Tree_node<std::pair<int const ,CSkillInfo const *>,void *> *v9; // rdx
  std::_Tree_node<std::pair<int const ,CSkillInfo const *>,void *> *j; // rdx
  int m_nSubJobId; // r8d
  int v12; // edx
  std::_Tree_node<std::pair<int const ,CSkillInfo const *>,void *> *Myhead; // rcx
  std::_Tree_node<std::pair<int const ,CSkillInfo const *>,void *> *Left; // rax
  const CSkillInfo *second; // rdx
  std::_Tree_node<std::pair<int const ,CSkillInfo const *>,void *> *Right; // rdx
  std::_Tree_node<std::pair<int const ,CSkillInfo const *>,void *> *i; // rdx
  int m_nSkillId; // edx

  v4 = (double)(int)CCreature::CalcReuseDelay(this, skill);
  if ( v4 > 0.0 )
  {
    m_nReuseDelayGroup = skill->m_nReuseDelayGroup;
    if ( skill->m_ReuseDelayType )
    {
      if ( m_nReuseDelayGroup > 0 )
      {
        Myhead = this->m_ActiveSkills._Mypair._Myval2._Myval2._Myhead;
        Left = Myhead->_Left;
        if ( Myhead->_Left == Myhead )
        {
LABEL_33:
          m_nSkillId = skill->m_nSkillId;
        }
        else
        {
          while ( 1 )
          {
            second = Left->_Myval.second;
            if ( skill->m_nSkillId != second->m_nSkillId && m_nReuseDelayGroup == second->m_nReuseDelayGroup )
              break;
            if ( !Left->_Isnil )
            {
              Right = Left->_Right;
              if ( Right->_Isnil )
              {
                for ( i = Left->_Parent; !i->_Isnil && Left == i->_Right; i = i->_Parent )
                  Left = i;
                Left = i;
              }
              else
              {
                do
                {
                  Left = Right;
                  Right = Right->_Left;
                }
                while ( !Right->_Isnil );
              }
            }
            if ( Left == Myhead )
              goto LABEL_33;
          }
          m_nSkillId = second->m_nSkillId;
        }
        CSkillReuseDelay::AddOrUpdateSkillReuseDelay(
          &this->m_SkillReuseDelay,
          m_nSkillId,
          this->m_data->m_nSubJobId,
          (int)v4,
          0);
      }
      m_nSubJobId = 4;
    }
    else
    {
      if ( m_nReuseDelayGroup > 0 )
      {
        v6 = this->m_ActiveSkills._Mypair._Myval2._Myval2._Myhead;
        v7 = v6->_Left;
        if ( v6->_Left != v6 )
        {
          while ( 1 )
          {
            v8 = v7->_Myval.second;
            if ( skill->m_nSkillId != v8->m_nSkillId && m_nReuseDelayGroup == v8->m_nReuseDelayGroup )
              break;
            if ( !v7->_Isnil )
            {
              v9 = v7->_Right;
              if ( v9->_Isnil )
              {
                for ( j = v7->_Parent; !j->_Isnil && v7 == j->_Right; j = j->_Parent )
                  v7 = j;
                v7 = j;
              }
              else
              {
                do
                {
                  v7 = v9;
                  v9 = v9->_Left;
                }
                while ( !v9->_Isnil );
              }
            }
            if ( v7 == v6 )
              goto LABEL_17;
          }
          v12 = v8->m_nSkillId;
          m_nSubJobId = this->m_data->m_nSubJobId;
          goto LABEL_37;
        }
      }
LABEL_17:
      m_nSubJobId = this->m_data->m_nSubJobId;
    }
    v12 = skill->m_nSkillId;
LABEL_37:
    CSkillReuseDelay::AddOrUpdateSkillReuseDelay(&this->m_SkillReuseDelay, v12, m_nSubJobId, (int)v4, 0);
  }
  if ( v4 > 300000.0 )
    _InterlockedExchange(&this->m_lSaveSkillReuseDelay, 1);
  return (unsigned int)(int)v4;
}