Добавлен , опубликован
От хозяина блога: статья не моя, я лишь решил её перекопировать на хгм, что бы местные могли с ней ознакомиться.
Автор перевода: ExotiC
Англоязычная версия статьи

Строящиеся башни, отображение области строения и блокирование постройки друг на дружке

Автор предполагает, что перед чтением вы знаете о *.txt файлах, используемых для создания кастомных юнитов и способностей.
Итак, для создания башни нам нужно несколько вещей:
Измененный герой для создания у него способности "Постройка"
Измененная способность, которая будет у нашего героя
.lua скрипт, в которым мы опишем логику способности
Кастомное здание для постройки
Я буду детально разбирать код что для чего нужно, и на каждый строчке буду писать комментарий.

Кастомный герой

В npc_heroes_custom.txt:
"npc_dota_hero_storm_bro"
{
    "override_hero"     "npc_dota_hero_storm_spirit"
    "Ability1"      "place_tower"
}

Кастомная способность

В npc_abilities_custom.txt:
"place_tower"
    {
         // Все способности контроля требуют базовый класс, и так как это класс не просто изменяет старую абилку, он должен быть "data_driven"
        "BaseClass" "ability_datadriven"
        // Мы запрашиваем blah_POINT, для получение параметра "Target" для Lua функции, и blah_AOE для отображения AOE, когда размещаем башню
        "AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_POINT | DOTA_ABILITY_BEHAVIOR_AOE" 
        // Этот кусок не сильно важен, но делает тесты немного легче
        "AbilityTextureName" "axe_battle_hunger"
        "Ability Cast Range" "0"
        "Ability Cast Point" "0"

        // А вот этот важен. С его помощью задаем радиус AOE. Этот радиус будет отображаться в игре. Вы должны назвать так же, как PLACED_BUILDING_RADIUS в сценарии 
Lua для соответствия.

        "AOERadius" "45"

        // Когда мы начинаем заклинание (т.е. после того как мы нажали расположение где хотим построить)
        "OnSpellStart"
        {
            // Мы хотим запустить Lua скрипт
            "RunScript"
            {
                // Файл скрипта, который мы вызваем
                "ScriptFile"        "scripts/vscripts/custom_abilities.lua"
                // Специфичная функция, которая нам нужна
                "Function"          "placeBuilding"
                // Дополнительная информацию которую мы отправляем в файл Lua
                "Target" "POINT"
            }       
        }
    }
На этом способность сделана!

Скрипт Lua

    -- Константу пишем тут, чтобы была на виду
PLACED_BUILDING_RADIUS = 45.0;
function placeBuilding(keys)
    -- Нам потребуется несколько переменных, они должны быть понятны
    blocking_counter = 0
    attempt_place_location = keys.target_points[1]
    -- Как же сложно! В основном, эта строка находит все объекты внутри PLACED_BUILDING_RADIUS от того, где мы хотим поставить башню
    -- Цикл для подсчета
    for _,thing in pairs(Entities:FindAllInSphere(GetGroundPosition(attempt_place_location, nil), PLACED_BUILDING_RADIUS) )  do
        blocking_counter = blocking_counter + 1
    end
    print(blocking_counter .. " blockers")

    -- Если есть объекты, которые мешают размещению башни, тогда не строим здесь, иначе - размещаем
    if( blocking_counter < 1) then
        tower = CreateUnitByName("npc_dota_building_homebase", keys.target_points[1], false, nil, nil,keys.caster:GetPlayerOwner():GetTeam() ) 
    end
end

Кастомная башня

В npc_units_custom.txt
"npc_dota_building_homebase"
{
    // Что мы ходим видеть - моделька
    "Model" "models/buildings/building_plain_reference.vmdl"
    "BaseClass" "npc_dota_creature"
    // Насколько большой масштаб. Относится к PLACED_BUILDING_RADIUS
    "BoundsHullName" "DOTA_HULL_SIZE_HUGE"
}
Теперь вы разместили кастомную башню в абилке, и радиус способности покажет вам где разместить здание, будет ли мешать что-то, когда вы поместите его.
Печально то, что невозможно сделать больше, чем просто размещение башни, насколько я знаю. Мы не получаем доступ к курсору мыши в любой точке и когда мы изучаем абилку, поэтому мы не можем указать разрешенные позиции, или сетку, или все в таком духе.
`
ОЖИДАНИЕ РЕКЛАМЫ...