Цель гайда - создать и добавить в магазин итем со своей иконкой, имеющий следующие свойства:
• При ударе руками владельца включенного итема юнит получает урон и в него бьёт молния.
• Итем имеет свойство "Toggle" - например, как армлет в доте.
• Юнит, который активирует данный итем приобретает визуальный эффект.
Итак. Начнем понемногу.• При ударе руками владельца включенного итема юнит получает урон и в него бьёт молния.
• Итем имеет свойство "Toggle" - например, как армлет в доте.
• Юнит, который активирует данный итем приобретает визуальный эффект.
Шаг 1. Создание итема, присваивание базовых свойств.
Следующий код пишем в npc_items_custom.txt:
Код:
"item_moon_shield"// после "item_" указываем желаемое имя итема
{
"ID" "2104" //Уникальный id итема. Не должен совпадать с id других итемов.
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_ITEM | DOTA_ABILITY_BEHAVIOR_NO_TARGET | DOTA_ABILITY_BEHAVIOR_TOGGLE" //Способность определяется как предмет, не требует выбора цели и применяется на владельца, "зажимается", как, к примеру, армлет в доте.
"BaseClass" "item_datadriven" // Базовый класс. Он заточен глубоко в ядре доты, его не трогаем.
"Model" "models/props_gameplay/red_box.vmdl" // Модель итема, когда он дропнут на землю
"AbilityTextureName" "item_moon_shield" // Иконка предмета. О ней позже.
"ItemCost" "5" // Стоимость в магазине.
"ItemDroppable" "1" // 1 - можно выбросить. 0 - выбросить нельзя.
"ItemSellable" "1" // Можно ли продать.
"ItemKillable" "0" // Можно ли сломать, когда лежит на земле
"ItemShareability" "ITEM_NOT_SHAREABLE" // Можно ли передавать
"ItemDeclarations" "DECLARE_PURCHASES_TO_TEAMMATES | DECLARE_PURCHASES_TO_SPECTATORS | DECLARE_PURCHASES_IN_SPEECH" // Не трогаем.
"AbilityCooldown" "1" //
"AbilityManaCost" "15"
}
Шаг 2. База есть. Теперь модифаер, который будет присваиваться владельцу предмета.
Продолжаем тот же код.
Код:
"Modifiers"// В этом блоке описываются все модифаеры, которые будут использоваться
{
"modifier_moon_shield" // Создаем модифаер
{
"IsBuff" "1" // Определяется как бафф. Будет отображаться над скиллами
"Hidden" "0" // 1 - бафф будет работать, но не будет отображаться
"EffectName" "particles/econ/courier/courier_golden_roshan/golden_roshan_ambient.vpcf" // Визуальный эффект, который получит владелец итема.
"EffectAttachType" "follow_origin" // Определяет, где будет находиться эффект. В данном случае - под персонажем.
}
Шаг 3. Теперь мы указываем, что будет происходить, когда нас ударят. Продолжаем код в том же модифаере.
Код:
"OnAttacked"// Код снизу будет происходить, когда владельца предмета ударят. Данное событие выдает атакующего(ATTACKER), атакуемого(TARGET) и количество нанесенного атакуемому урона(DAMAGE).
{
"AttachEffect" // Создаем эффект
{
"Target" "ATTACKER" // Цель эффекта - атакуемый
"EffectName" "particles/units/heroes/hero_leshrac/leshrac_lightning_bolt.vpcf" // Сам эффект.
"EffectAttachType" "follow_overhead" // Точка удара молнии будет над головой цели
"ControlPoints" // Контрол поинты разбирать нужно отдельно. Скажу лишь, что у каждого эффекта есть поинты, которые пронумерованы. С помощью этой команды можно изменять положение xyz поинтов.
{
"01" "0 0 2000" [font=courier][size=4]// Поднимаем точку, из которой бьет молния на 2000 вверх. Без этого молния будет бить из центра карты.
}
}
}
Шаг 4. Добавляем возможность включения и выключения итема. Теперь модифаер "modifier_moon_shield" будет действовать на владельца лишь тогда, когда итем включен. Следующий код пишется уже после блока модифаеров.
Код:
"OnToggleOn"// "Когда включен". Использовать можно только если итем имеет тип поведения "DOTA_ABILITY_BEHAVIOR_TOGGLE"
{
"ApplyModifier"// Присваиваем модифаер цели
{
"ModifierName" "modifier_moon_shield"
"Target" "CASTER"
}
}
"OnToggleOff" // "Когда выключен"
{
"RemoveModifier" // Отбираем модифаер у цели
{
"ModifierName" "modifier_moon_shield"
"Target" "CASTER"
}
}
Шаг 5. Производим предварительное кеширование эффектов, которые использовали в модифаере. Без этого эффекты воспроизводиться не будут. Следующий код производится в addon_game_mode.lua
Код:
function Precache( context )
PrecacheResource("particle", "particles/units/heroes/hero_leshrac/leshrac_lightning_bolt.vpcf" , context)
PrecacheResource("particle", "particles/econ/courier/courier_golden_roshan/golden_roshan_ambient.vpcf" , context)
end
Шаг 6.1. Добавляем возвращение урона атакующему путем вызова скрипта lua. Сначала добавим вызов скрипта во все тот же npc_items_custom.txt:, к тому же "OnAttacked".
Код:
"RunScript" // Вызываем скрипт, который находится в scripts/vscripts нашего проекта
{
"ScriptFile" "abilities.lua"// Имя скрипта
"Function" "attack_func" // Функция, которую мы вызываем в скрипте. Менять можно по желанию.
"Target" "ATTACKER" // Передаем в скрипт атакующего
"Damage" "%attack_damage" // Передаем в скрипт кол-во нанесенного нам урона.
}
Шаг 6.2. Создаем в scripts/vscripts файл abilities.lua. описываем функцию.
Код:
function attack_func(event) -- Описываем функцию. Все, что мы передавали в скрипт записано в кейсе event
for key, unit in pairs(event.target_entities) do -- Взял из чужого кода. По идее - перебирает все цели и производит над ними действия, описанные ниже. Точно пока не разобрался, но работает все только так, поэтому не трогаем.
local damage_taken = event.Damage -- Достаем и присваиваем переменной полученный дамаг
local return_damage = damage_taken * 1.25 -- Увеличиваем полученный дамаг на 25%
ApplyDamage({ victim = event.attacker, attacker = event.target, damage = return_damage, damage_type = DAMAGE_TYPE_MAGICAL }) -- Наносит магический урон атакующему от атакуемого в размере "return_damage". Об этой команде советую почитать отдельно.
print(damage_taken,return_damage, event.attacker, event.target) -- Использовал для отладки. Выдает значения переменных в консоль. Мало ли, может пригодится.
end
end
Фулл код npc_items_custom.txt:
"item_moon_shield"
{
"ID" "2104"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_ITEM | DOTA_ABILITY_BEHAVIOR_NO_TARGET | DOTA_ABILITY_BEHAVIOR_TOGGLE"
"BaseClass" "item_datadriven"
"Model" "models/props_gameplay/red_box.vmdl"
"AbilityTextureName" "item_moon_shield"
"ItemCost" "5"
"ItemDroppable" "1"
"ItemSellable" "1"
"ItemStackable" "1"
"ItemKillable" "0"
"ItemShareability" "ITEM_NOT_SHAREABLE"
"ItemDeclarations" "DECLARE_PURCHASES_TO_TEAMMATES | DECLARE_PURCHASES_TO_SPECTATORS | DECLARE_PURCHASES_IN_SPEECH"
"AbilityCooldown" "1"
"AbilityManaCost" "15"
"Modifiers"
{
"modifier_moon_shield"
{
"IsBuff" "1"
"Hidden" "0"
"EffectName" "particles/econ/courier/courier_golden_roshan/golden_roshan_ambient.vpcf"
"EffectAttachType" "follow_origin"
"OnAttacked"
{
"RunScript"
{
"ScriptFile" "abilities.lua"
"Function" "attack_func"
"Target" "ATTACKER"
"Damage" "%attack_damage"
}
"AttachEffect"
{
"Target" "ATTACKER"
"EffectName" "particles/units/heroes/hero_leshrac/leshrac_lightning_bolt.vpcf"
"EffectAttachType" "follow_overhead"
"ControlPoints"
{
"01" "0 0 3000"
}
}
}
}
}
"OnToggleOn"
{
"ApplyModifier"
{
"ModifierName" "modifier_moon_shield"
"Target" "CASTER"
}
}
"OnToggleOff"
{
"RemoveModifier"
{
"ModifierName" "modifier_moon_shield"
"Target" "CASTER"
}
}
}
}
{
"ID" "2104"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_ITEM | DOTA_ABILITY_BEHAVIOR_NO_TARGET | DOTA_ABILITY_BEHAVIOR_TOGGLE"
"BaseClass" "item_datadriven"
"Model" "models/props_gameplay/red_box.vmdl"
"AbilityTextureName" "item_moon_shield"
"ItemCost" "5"
"ItemDroppable" "1"
"ItemSellable" "1"
"ItemStackable" "1"
"ItemKillable" "0"
"ItemShareability" "ITEM_NOT_SHAREABLE"
"ItemDeclarations" "DECLARE_PURCHASES_TO_TEAMMATES | DECLARE_PURCHASES_TO_SPECTATORS | DECLARE_PURCHASES_IN_SPEECH"
"AbilityCooldown" "1"
"AbilityManaCost" "15"
"Modifiers"
{
"modifier_moon_shield"
{
"IsBuff" "1"
"Hidden" "0"
"EffectName" "particles/econ/courier/courier_golden_roshan/golden_roshan_ambient.vpcf"
"EffectAttachType" "follow_origin"
"OnAttacked"
{
"RunScript"
{
"ScriptFile" "abilities.lua"
"Function" "attack_func"
"Target" "ATTACKER"
"Damage" "%attack_damage"
}
"AttachEffect"
{
"Target" "ATTACKER"
"EffectName" "particles/units/heroes/hero_leshrac/leshrac_lightning_bolt.vpcf"
"EffectAttachType" "follow_overhead"
"ControlPoints"
{
"01" "0 0 3000"
}
}
}
}
}
"OnToggleOn"
{
"ApplyModifier"
{
"ModifierName" "modifier_moon_shield"
"Target" "CASTER"
}
}
"OnToggleOff"
{
"RemoveModifier"
{
"ModifierName" "modifier_moon_shield"
"Target" "CASTER"
}
}
}
}
Результат:
Советы:
• Советую для ознакомления два открытых на гитхабе популярных проекта:
Warchasers: https://github.com/MNoya/Warchasers
Жизнь на Арене: https://github.com/ZLOY5/LiA
Скачайте их, распакуйте и установите программу Far 3. И когда становится тяжело понять, как описать ту или иную команду или функцию - заходите через Far в корень скачанных проектов, жмите alt + F7. В первом поле вводите "*.*", во втором - то, что нужно найти, например "OnAttacked".
• На ГитХабе в поиске так же всегда можно поискать интересующие команды и функции. Также для поиска и вообще "почитать" советую https://moddota.com
• На сайте https://moddota.com создатель Warchasers - Noya, оформляет качественные гайды, несколько из них:
http://moddota.com/forums/discussion/14/datadriven-ability-breakdown-documentation
https://moddota.com/forums/discussion/4/datadriven-items
http://moddota.com/forums/discussion/93/point-channeling-aoe-ability-example
https://moddota.com/forums/discussion/69/particle-attachment
• Репозиторий, где показаны базовые вещи и есть стартовый набор скриптов: https://github.com/bmddota/barebones
• Ну и конечно же - по возможности старайтесь создавать свои или переводить чужие гайды, так как то, что Вам кажется очевидным, кому-то придется понимать на забугорских сайтах 2 а то и больше дней, так как российское сообщество D2WT ушло не очень далеко от нулевого уровня.
Автор - Slavko.
Последнее редактирование модератором: