- 25 Сен 2015
- 2,348
- 41
Мне известно три способа создания своей руны.
Первый - это через создание вещицы-руны.
Однако у такого способа есть огромный недостаток: необходимо иметь пустой слот в инвентаре, чтобы поднять руну, да и к тому же в этом пустом слоте на миг будет мелькать иконка руны. В следствие этого недостатка я не буду приводить пример реализации этого метода, так как есть более красивые.
Второй - в момент активации руны заменять ее модификатор на свой. Весьма элегантный метод, но обладает своими минусами:не можем изменить модельку руны; руны бывают разные и работать надо будет с каждой; на миг вы будете видеть модификатор оригинальной руны (я не знаю, можно ли его как-то перехватить). Этот способ я так же не буду рассматривать, ибо я хочу "чистый" продукт.
И вот тут появляется третий способ - создание монстра-руны.
Единственный его минус заключается в том, что мы будем атаковать руну, что весьма непривычно.
Итак, для начала подготовим свой модификатор:
Создаем в папочке "vscripts" папочку "modifiers", а в ней создаем файл с расширением "lua" и иминем вашего будущего модификатора. Я придумал такое: modifier_one_punch_speed.
Далее прописываем в него все необходимое.
Советую удалить все мои комментарии из него, дабы глаза не мозолили и снизить вероятность возможных ошибок (комментарии начинаются с --).
Далее нам надо подумать о респавне руны и коде, функции, что будет активировать наш модификатор на убийце будущего юнита-руны.
Поэтому идем в папочку "scripts", там создаем файлик lua. В нем будет логика респавна да и активации модификатора. Я такой обычно называю ai.
Теперь идем в папочку "scripts", там в папочку "npc", а там в npc_abilities_custom.txt
Создаем две абилки:
В абилке активации модификатора у нас что есть: есть два модификатора, что висят на самом юните-руне, это
"modifier_rune"
Который запустит скрипт "ai.lua", а в нем функцию "AddModifier" тогда, когда юнит умрет.
и "modifier_no_health_bar"
Который скрывает хп бар юнита, дабы было красиво и он больше походил на рунку.
Теперь мы создаем саму руну-юнита.
Идем в папочку "scripts", там в папочку "npc", а там в файлик npc_units_custom.txt
В нем создаем нашего крипа-руну, который не должен уметь ходить или бить и иметь мизерное хп.
Заметьте:
"Model" "models/props_gameplay/rune_regeneration01.vmdl"
Я использовал модель руны регенерации, но можно и любую другую задать. Это плюс этого метода.
Кроме того не забываем указать ему:
// Abilities
//----------------------------------------------------------------
"Ability1" "ability_rune"
"Ability2" "ability_rune_respawn"
Наши, созданные выше, абилки.
Итак, теперь шагаем в тот файл, в котором вы спавните юнита. У меня это main.lua, у вас может быть addon_game_mode.lua.
Далее не забываем в папке "resource" в файле "addon_english.txt" указать описание монстра и модификатора.
Первый - это через создание вещицы-руны.
Однако у такого способа есть огромный недостаток: необходимо иметь пустой слот в инвентаре, чтобы поднять руну, да и к тому же в этом пустом слоте на миг будет мелькать иконка руны. В следствие этого недостатка я не буду приводить пример реализации этого метода, так как есть более красивые.
Второй - в момент активации руны заменять ее модификатор на свой. Весьма элегантный метод, но обладает своими минусами:не можем изменить модельку руны; руны бывают разные и работать надо будет с каждой; на миг вы будете видеть модификатор оригинальной руны (я не знаю, можно ли его как-то перехватить). Этот способ я так же не буду рассматривать, ибо я хочу "чистый" продукт.
И вот тут появляется третий способ - создание монстра-руны.
Единственный его минус заключается в том, что мы будем атаковать руну, что весьма непривычно.
Итак, для начала подготовим свой модификатор:
Создаем в папочке "vscripts" папочку "modifiers", а в ней создаем файл с расширением "lua" и иминем вашего будущего модификатора. Я придумал такое: modifier_one_punch_speed.
Далее прописываем в него все необходимое.
Код:
--объявляем наш модификатор как объект-класс
modifier_one_punch_man_speed = class({})
--возвращаем false (лож) на вопросы о скрывании модификатора с глаз
--мы ведь хотим видеть красивую иконочку над показателями здоровья
function modifier_one_punch_man_speed:IsHidden()
return false
end
--эта штука будет на любые распросы о типе нашего модификатора
--говорить, что он на скорость атаки
--все типы можете в офф документации глянуть
function modifier_one_punch_man_speed:DeclareFunctions()
return { MODIFIER_PROPERTY_ATTACKSPEED_BONUS_CONSTANT }
end
--тут возвращаем имя иконочки
--не буду рассказывать, как делать иконочку
--можете использовать тут имена стандартных абилок
--например вместо моего "one_punch_man" взять "brewmaster_drunken_haze"
function modifier_one_punch_man_speed:GetTexture()
return "one_punch_man"
end
--когда нас спросят, а сколько скорости то плюсануть
--мы ответим 99999
function modifier_one_punch_man_speed:GetModifierAttackSpeedBonus_Constant()
return 99999
end
--возвращаем true на любые вопросы о том
--удалять ли модификатор, если носитель умрет
--можете и false поставить, чтобы он не пропадал после смерти
--как хотите
function modifier_one_punch_man_speed:RemoveOnDeath()
return true
end
Советую удалить все мои комментарии из него, дабы глаза не мозолили и снизить вероятность возможных ошибок (комментарии начинаются с --).
Далее нам надо подумать о респавне руны и коде, функции, что будет активировать наш модификатор на убийце будущего юнита-руны.
Поэтому идем в папочку "scripts", там создаем файлик lua. В нем будет логика респавна да и активации модификатора. Я такой обычно называю ai.
--во первых подключаем наш модификатор сюда
LinkLuaModifier("modifier_one_punch_man_speed", "modifiers/modifier_one_punch_man_speed.lua", LUA_MODIFIER_MOTION_NONE )
--дале делаем функцию респавна руны
function RuneRespawn(data)
--копируем ссылку на юнита
local moob = data.caster
--копируем его имя
local name = moob:GetUnitName()
--копируем точку его спавна на карте в виде координат вектора
local SpawnLoc = moob.vSpawnLoc
--в случае, если точка спавна пустая была
--бацаем ту, в которой умер юнит
if (SpawnLoc == nil) then
SpawnLoc = moob:GetOrigin()
end
--запусаем таймер, про таймеры можете найти видос неплохой на ютюбе и форуме
--я поставил таймер на 15 сек
--то есть через 15 сек после смерти руна возрадится снова
GameRules:GetGameModeEntity():SetContextThink(string.format("CreatureThink_%d",moob:GetEntityIndex()),
function()
local unit = CreateUnitByName(name, SpawnLoc, true, nil, nil, DOTA_TEAM_NEUTRALS )
unit.vSpawnLoc = SpawnLoc
end,
15)
end
--функция активации модификатора
function AddModifier(data)
--копируем ссылку на атакующего
local Attacker = data.attacker
--вешаем на него наш модификатор на 15 секунд
Attacker:AddNewModifier( data.caster, nil, "modifier_one_punch_man_speed", {duration = 15} )
end
LinkLuaModifier("modifier_one_punch_man_speed", "modifiers/modifier_one_punch_man_speed.lua", LUA_MODIFIER_MOTION_NONE )
--дале делаем функцию респавна руны
function RuneRespawn(data)
--копируем ссылку на юнита
local moob = data.caster
--копируем его имя
local name = moob:GetUnitName()
--копируем точку его спавна на карте в виде координат вектора
local SpawnLoc = moob.vSpawnLoc
--в случае, если точка спавна пустая была
--бацаем ту, в которой умер юнит
if (SpawnLoc == nil) then
SpawnLoc = moob:GetOrigin()
end
--запусаем таймер, про таймеры можете найти видос неплохой на ютюбе и форуме
--я поставил таймер на 15 сек
--то есть через 15 сек после смерти руна возрадится снова
GameRules:GetGameModeEntity():SetContextThink(string.format("CreatureThink_%d",moob:GetEntityIndex()),
function()
local unit = CreateUnitByName(name, SpawnLoc, true, nil, nil, DOTA_TEAM_NEUTRALS )
unit.vSpawnLoc = SpawnLoc
end,
15)
end
--функция активации модификатора
function AddModifier(data)
--копируем ссылку на атакующего
local Attacker = data.attacker
--вешаем на него наш модификатор на 15 секунд
Attacker:AddNewModifier( data.caster, nil, "modifier_one_punch_man_speed", {duration = 15} )
end
Теперь идем в папочку "scripts", там в папочку "npc", а там в npc_abilities_custom.txt
Создаем две абилки:
Код:
"ability_rune_respawn"
{
"BaseClass" "ability_datadriven"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_HIDDEN"
"OnOwnerDied"
{
"RunScript"
{
"ScriptFile" "ai.lua"
"Function" "RuneRespawn"
}
}
}
Код:
"ability_rune"
{
"BaseClass" "ability_datadriven"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_HIDDEN"
"OnCreated"
{
"ApplyModifier"
{
"Target" "CASTER"
"ModifierName" "modifier_rune"
}
"ApplyModifier"
{
"Target" "CASTER"
"ModifierName" "modifier_no_health_bar"
}
}
"Modifiers"
{
"modifier_rune"
{
"IsHidden" "1"
"OnAttacked"
{
"RunScript"
{
"ScriptFile" "ai.lua"
"Function" "AddModifier"
}
}
}
"modifier_no_health_bar"
{
"Passive" "1"
"IsHidden" "1"
"States"
{
"MODIFIER_STATE_NO_HEALTH_BAR" "MODIFIER_STATE_VALUE_ENABLED"
}
}
}
}
В абилке активации модификатора у нас что есть: есть два модификатора, что висят на самом юните-руне, это
"modifier_rune"
Который запустит скрипт "ai.lua", а в нем функцию "AddModifier" тогда, когда юнит умрет.
и "modifier_no_health_bar"
Который скрывает хп бар юнита, дабы было красиво и он больше походил на рунку.
Теперь мы создаем саму руну-юнита.
Идем в папочку "scripts", там в папочку "npc", а там в файлик npc_units_custom.txt
В нем создаем нашего крипа-руну, который не должен уметь ходить или бить и иметь мизерное хп.
Код:
"npc_rune"
{
// General
//----------------------------------------------------------------
"BaseClass" "npc_dota_creature"
"Model" "models/props_gameplay/rune_regeneration01.vmdl"
"ModelScale" "0.9"
"Level" "1"
"HealthBarOffset" "140"
"HasInventory" "0"
"ConsideredHero" "0"
"IsNeutralUnitType" "1"
"UnitLabel" "rune"
// Abilities
//----------------------------------------------------------------
"Ability1" "ability_rune"
"Ability2" "ability_rune_respawn"
// Armor
//----------------------------------------------------------------
"ArmorPhysical" "0"
"MagicalResistance" "0"
// Attack
//----------------------------------------------------------------
"AttackCapabilities" "DOTA_UNIT_CAP_NO_ATTACK"
"AttackDamageType" "DAMAGE_TYPE_ArmorPhysical"
"AttackDamageMin" "0"
"AttackDamageMax" "0"
// Bounty
//----------------------------------------------------------------
"BountyGoldMin" "0.0"
"BountyGoldMax" "0.0"
// Bounds
//----------------------------------------------------------------
"BoundsHullName" "DOTA_HULL_SIZE_HERO"
"RingRadius" "70"
"CollisionSize" "1"
// Movement
//----------------------------------------------------------------
"MovementCapabilities" "DOTA_UNIT_CAP_MOVE_NONE"
"MovementSpeed" "0"
// Status
//----------------------------------------------------------------
"StatusHealth" "1"
"StatusHealthRegen" "0"
"StatusMana" "0"
"StatusManaRegen" "0"
// Vision
//----------------------------------------------------------------
"VisionDaytimeRange" "900"
"VisionNighttimeRange" "600"
// Team
//----------------------------------------------------------------
"TeamName" "DOTA_TEAM_NEUTRALS"
"CombatClassAttack" "DOTA_COMBAT_CLASS_ATTACK_BASIC"
"CombatClassDefend" "DOTA_COMBAT_CLASS_DEFEND_STRUCTURE"
"UnitRelationShipClass" "DOTA_NPC_UNIT_RELATIONSHIP_TYPE_BUILDING"
}
Заметьте:
"Model" "models/props_gameplay/rune_regeneration01.vmdl"
Я использовал модель руны регенерации, но можно и любую другую задать. Это плюс этого метода.
Кроме того не забываем указать ему:
// Abilities
//----------------------------------------------------------------
"Ability1" "ability_rune"
"Ability2" "ability_rune_respawn"
Наши, созданные выше, абилки.
Итак, теперь шагаем в тот файл, в котором вы спавните юнита. У меня это main.lua, у вас может быть addon_game_mode.lua.
Код:
function main:SpawnRune()
--не забываем в хамере, на карте, создать объект с именем, к примеру, spawn_rune
--то есть ту точку, куда будем спавнить руну
--это может быть как и блок типа path_corner
--так и объект spawner_info, смотрите сами
--вот здесь я ищу и копирую координаты созданного мною spawn_rune в хаммере
local point = Entities:FindByName( nil, "spawn_rune"):GetAbsOrigin()
--создаю юнита-руну, делаю его нейтралом
local unit = CreateUnitByName("npc_rune", point, true, nil, nil, DOTA_TEAM_NEUTRALS )
--указываю ему точку спавна для будущего респавна
unit.vSpawnLoc = unit:GetOrigin()
end
Далее не забываем в папке "resource" в файле "addon_english.txt" указать описание монстра и модификатора.
Код:
"lang"
{
"Language" "English"
"Tokens"
{
"addon_game_name" "my addon"
// ******************** moobs ********************
"npc_rune" "Rune of attack speed"
// ******************** MODIFIERS ********************
"DOTA_Tooltip_modifier_one_punch_man_speed" "Speed of One Punch Man"
"DOTA_Tooltip_modifier_one_punch_man_speed_Description" "Three-year training bearing fruit: attack speed increase by 99999"
}
}
Последнее редактирование модератором: