Эта тема может быть неактуальна по причине того, что вышел новый движок Source 2.Спойлер: "Первая часть"https://dota2.ru/forum/threads/dota-2-workshop-tools.599240/page-40 пост под номером #800Спойлер: "Третья"*** Вторая часть ***1) Первым делом пару слов про "Динамический лагерь". Олдскулы, игравшие в разные мапы третьего Варика должны помнить о лагерях бесконечного фарма. В таких лагерях после смерти крипов появляются новые, как правило, более мощные. По-моему даже в Петрах такие есть, там панды фармят ночью (или днем:)) 2) Сразу вставлю конечный результат: 3) Начнем с самого простого: создание юнита.
- Создаем юнитов.
- Создаем лагерь юнитов.
- Создаем динамический лагерь (название сам придумал)
Описание методаhandle CreateUnitByName(string a, Vector b, bool c, handle d, handle e, int f) Creates a DOTA unit by its dota_npc_units.txt name ( szUnitName, vLocation, bFindClearSpace, hNPCOwner, hUnitOwner, iTeamNumber ) Требует на вход 6 аргументов, подсмотрев исходник кибермэта, пришел к выводу, что нам понадобятся только зеленые аргументы, а вместо красных передадим заглушки ( один false, и два nil) Наш метод примет вид: CreateUnitByName(Название_из_dota_npc_units.txt, Vector(x, y, z), false, nil, nil, DOTA_TEAM_NEUTRALS)Подробнее про аргументы (рассмотрим только зеленые)Первый аргумент это название юнита, из тхт файла http://rghost.ru/57412109 например "npc_dota_neutral_kobold" в этом файле описываются юниты, вначале каждого описания есть такое название (начинается на npc_dota_) Второй аргумент это координаты "высадки" юнита. задаются вектором: Vector(число, число, число)Следующие три аргумента пропускаем... Последний аргумент это константа из доков. https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting/Constants На скрине раздел Teams. Наш юнит будет нейтралом 4) Создание лагеря? просто создаем в цикле несколько юнитов. 5) Динамический лагерь. необходимо учесть пару моментов:Спойлер: "Как определить нужные координаты?"Разместите любой объект, например дерево, в редакторе и выделите егов свойствах объекта будут его координаты (потом объект можно удалить:)) Свойство origin - то что нам нужно6) Сразу отмечу, что в конце будет весь код целиком (а здесь лишь фрагменты + пояснение)
- массив для хранения живых крипов. units = {nil, nil, nil}
- Заготовить массив с разными крипами (пару названий из тхт файла)
- Создать отдельную функцию создания лагеря (для удобства)
- Создать массив с id номерами юнитов, нам придется обрабатывать гибель определенных юнитов (именно из нашего лагеря)
- Создать событие "гибель юнита" onEntityKilled
- Спавнить юнитов в разные точки (Vector) крипы могут застрять друг в друге.
Массив с крипами:local spawnType= {"npc_dota_neutral_kobold", "npc_dota_neutral_polar_furbolg_champion", "npc_dota_neutral_centaur_khan"} - зверухи, которые в видео.Отдельная функция + цикл:function имя()for count = 1, 3 do units<count] = CreateUnitByName(массив_названий<count], Vector(x + массив_чисел<count], y, z), false, nil, nil, DOTA_TEAM_NEUTRALS ) endend Где массив_названий - массив с разными зверухами. массив_чисел - числа для суммирования с координатой (чтобы крипы спавнились в разные точки) отличаются немного - крипы будут рядом.Массив id номеровРанее мы создали массив units из трех элементов(3 живых крипа) такой же массив будет хранить числа - id номера. метод юнит:GetEntityIndex() массив_id[count] = массив_юнитов[count]:GetEntityIndex() Чтобы узнать длину массива в Lua нужно перед именем масива написать # переменная = #массивОсталось только создать событие гибель крипа, и в нем проверять id.Т.к создавать события мы научились в первой части, то сразу приступим к проверке: Есть массив из трех юнитов. кто-то на карте сдох - нужно сверить id жмурика с каждым из наших трех крипов (напомню у нас есть массив с id) for 3 раза do if массив_индексов<count] == keys.entindex_killed then У нас будет счетчик живых крипов (вначале он = 3), если ид совпал тогда уменьшаем его на 1. end Проверяем наш счетчик, если он равен 0, значит последний крип сдох и пора заспавнить новых.(вызвать функцию спавна) Еще есть переменная spawnLevel - номер(в массиве) крипов которые будут спавнится. эта переменная увеличивается на 1 перед вызовом Если достигнут макс левел(spawnLevel > 2) то всегда спавним самых кртых крипов (последних) На самом деле код простой как тапочек: вот фуллUPDATE: можно использовать функцию [COLOR=#ffff4d]RandomVector[/COLOR](максимальное значение) вместо того велосипеда с массивом. т.е. спавнить крипа в Vector(x, y, z) + RandomVector(100)Спойлер: "КОД"print( "Dota PvP game mode loaded." ) if DotaPvP == nil then DotaPvP = class({}) end function Activate() GameRules.DotaPvP = DotaPvP() GameRules.DotaPvP:InitGameMode() end function DotaPvP:InitGameMode() local GameMode = GameRules:GetGameModeEntity() -- Enable the standard Dota PvP game rules GameRules:GetGameModeEntity():SetTowerBackdoorProtectionEnabled( true ) -- Register Think GameMode:SetContextThink( "DotaPvP:GameThink", function() return self:GameThink() end, 0.25 ) -- Spawn creeps MAX_SPAWN_COUNT = 3 spawnCount = 3; spawnLevel = 1; offset = { 0, 50, -50} makeSpawn() --listeners ListenToGameEvent('entity_killed', Dynamic_Wrap(DotaPvP, 'onEntityKilled'), self) end function DotaPvP:GameThink() return 0.25 end function DotaPvP:onEntityKilled(keys) for i = 1, #units do if spawnIndex ~= nil then --print(tostring(spawnIndex) .. ' ' .. tostring(keys.entindex_killed)) if spawnIndex == keys.entindex_killed then spawnCount = spawnCount - 1 print('##### EQUALS #####') end end end if spawnCount == 0 then if spawnLevel < MAX_SPAWN_COUNT then spawnLevel = spawnLevel + 1 else spawnLevel = MAX_SPAWN_COUNT end makeSpawn() end end function makeSpawn() local spawnType= {"npc_dota_neutral_kobold", "npc_dota_neutral_polar_furbolg_champion", "npc_dota_neutral_centaur_khan"} units = {nil, nil, nil} spawnIndex = {nil, nil, nil} for count = 1, MAX_SPAWN_COUNT do units[count] = CreateUnitByName(spawnType[spawnLevel], Vector(1980 + offset[count] , 1024, 128), false, nil, nil, DOTA_TEAM_NEUTRALS) spawnIndex[count] = units[count]:GetEntityIndex() print('---------NEW SPAWN CREATED-------------------') end spawnCount = MAX_SPAWN_COUNT end
Хорошdoter.ua сказал(а):↑Спойлер: "Первая часть"https://dota2.ru/forum/threads/dota-2-workshop-tools.599240/page-51 пост под номером #1019*** Вторая часть ***1) Первым делом пару слов про "Динамический лагерь". Олдскулы, игравшие в разные мапы третьего Варика должны помнить о лагерях бесконечного фарма. В таких лагерях после смерти крипов появляются новые, как правило, более мощные. По-моему даже в Петрах такие есть, там панды фармят ночью (или днем:)) 2) Сразу вставлю конечный результат: 3) Начнем с самого простого: создание юнита.
- Создаем юнитов.
- Создаем лагерь юнитов.
- Создаем динамический лагерь (название сам придумал)
Описание методаhandle CreateUnitByName(string a, Vector b, bool c, handle d, handle e, int f) Creates a DOTA unit by its dota_npc_units.txt name ( szUnitName, vLocation, bFindClearSpace, hNPCOwner, hUnitOwner, iTeamNumber ) Требует на вход 6 аргументов, подсмотрев исходник кибермэта, пришел к выводу, что нам понадобятся только зеленые аргументы, а вместо красных передадим заглушки ( один false, и два nil) Наш метод примет вид: CreateUnitByName(Название_из_dota_npc_units.txt, Vector(x, y, z), false, nil, nil, DOTA_TEAM_NEUTRALS)Подробнее про аргументы (рассмотрим только зеленые)Первый аргумент это название юнита, из тхт файла http://rghost.ru/57412109 например "npc_dota_neutral_kobold" в этом файле описываются юниты, вначале каждого описания есть такое название (начинается на npc_dota_) Второй аргумент это координаты "высадки" юнита. задаются вектором: Vector(число, число, число)Следующие три аргумента пропускаем... Последний аргумент это константа из доков. https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting/Constants На скрине раздел Teams. Наш юнит будет нейтралом 4) Создание лагеря? просто создаем в цикле несколько юнитов. 5) Динамический лагерь. необходимо учесть пару моментов:Спойлер: "Как определить нужные координаты?"Разместите любой объект, например дерево, в редакторе и выделите егов свойствах объекта будут его координаты (потом объект можно удалить:)) Свойство origin - то что нам нужно6) Сразу отмечу, что в конце будет весь код целиком (а здесь лишь фрагменты + пояснение)
- массив для хранения живых крипов. units = {nil, nil, nil}
- Заготовить массив с разными крипами (пару названий из тхт файла)
- Создать отдельную функцию создания лагеря (для удобства)
- Создать массив с id номерами юнитов, нам придется обрабатывать гибель определенных юнитов (именно из нашего лагеря)
- Создать событие "гибель юнита" onEntityKilled
- Спавнить юнитов в разные точки (Vector) крипы могут застрять друг в друге.
Массив с крипами:local spawnType= {"npc_dota_neutral_kobold", "npc_dota_neutral_polar_furbolg_champion", "npc_dota_neutral_centaur_khan"} - зверухи, которые в видео.Отдельная функция + цикл:function имя()for count = 1, 3 do units<count] = CreateUnitByName(массив_названий<count], Vector(x + массив_чисел<count], y, z), false, nil, nil, DOTA_TEAM_NEUTRALS ) endend Где массив_названий - массив с разными зверухами. массив_чисел - числа для суммирования с координатой (чтобы крипы спавнились в разные точки) отличаются немного - крипы будут рядом.Массив id номеровРанее мы создали массив units из трех элементов(3 живых крипа) такой же массив будет хранить числа - id номера. метод юнит:GetEntityIndex() массив_id[count] = массив_юнитов[count]:GetEntityIndex() Чтобы узнать длину массива в Lua нужно перед именем масива написать # переменная = #массивОсталось только создать событие гибель крипа, и в нем проверять id.Т.к создавать события мы научились в первой части, то сразу приступим к проверке: Есть массив из трех юнитов. кто-то на карте сдох - нужно сверить id жмурика с каждым из наших трех крипов (напомню у нас есть массив с id) for 3 раза do if массив_индексов<count] == keys.entindex_killed then У нас будет счетчик живых крипов (вначале он = 3), если ид совпал тогда уменьшаем его на 1. end Проверяем наш счетчик, если он равен 0, значит последний крип сдох и пора заспавнить новых.(вызвать функцию спавна) Еще есть переменная spawnLevel - номер(в массиве) крипов которые будут спавнится. эта переменная увеличивается на 1 перед вызовом Если достигнут макс левел(spawnLevel > 2) то всегда спавним самых кртых крипов (последних) На самом деле код простой как тапочек: вот фуллСпойлер: "КОД"print( "Dota PvP game mode loaded." ) if DotaPvP == nil then DotaPvP = class({}) end function Activate() GameRules.DotaPvP = DotaPvP() GameRules.DotaPvP:InitGameMode() end function DotaPvP:InitGameMode() local GameMode = GameRules:GetGameModeEntity() -- Enable the standard Dota PvP game rules GameRules:GetGameModeEntity():SetTowerBackdoorProtectionEnabled( true ) -- Register Think GameMode:SetContextThink( "DotaPvP:GameThink", function() return self:GameThink() end, 0.25 ) -- Spawn creeps MAX_SPAWN_COUNT = 3 spawnCount = 3; spawnLevel = 1; offset = { 0, 50, -50} makeSpawn() --listeners ListenToGameEvent('entity_killed', Dynamic_Wrap(DotaPvP, 'onEntityKilled'), self) end function DotaPvP:GameThink() return 0.25 end function DotaPvP:onEntityKilled(keys) for i = 1, #units do if spawnIndex ~= nil then --print(tostring(spawnIndex) .. ' ' .. tostring(keys.entindex_killed)) if spawnIndex == keys.entindex_killed then spawnCount = spawnCount - 1 print('##### EQUALS #####') end end end if spawnCount == 0 then if spawnLevel < MAX_SPAWN_COUNT then spawnLevel = spawnLevel + 1 else spawnLevel = MAX_SPAWN_COUNT end makeSpawn() end end function makeSpawn() local spawnType= {"npc_dota_neutral_kobold", "npc_dota_neutral_polar_furbolg_champion", "npc_dota_neutral_centaur_khan"} units = {nil, nil, nil} spawnIndex = {nil, nil, nil} for count = 1, MAX_SPAWN_COUNT do units[count] = CreateUnitByName(spawnType[spawnLevel], Vector(1980 + offset[count] , 1024, 128), false, nil, nil, DOTA_TEAM_NEUTRALS) spawnIndex[count] = units[count]:GetEntityIndex() print('---------NEW SPAWN CREATED-------------------') end spawnCount = MAX_SPAWN_COUNT endНажмите, чтобы раскрыть...
Кастомные в смысле самодельные 3Д модели? с такими я не работал. Не знаю нужно ли кешировать стандартные модели, я не делал. Список крипов: https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting/Built-In_Unit_Names Лесные нейтралы начинаются с npc_dota_neutral_имя Как ввести? Нужно передать первым аргументом в CreateUnitByName( "имя крипа" ... другие аргументы) У меня используется массив из трех таких имен local spawnType= {"npc_dota_neutral_kobold", "npc_dota_neutral_polar_furbolg_champion", "npc_dota_neutral_centaur_khan"} Я создавал переменную spawnLevel которая была равна 1, 2, 3 (и потом все время 3) В цикле передавал массив<spawnLevel] в итоге использовались: 1-й 2-й 3-й элементы массива ( названия скрипов)Ambassador601 сказал(а):↑Все отлично написано, автору спасибо, Только после некоторого тестирования спавнов крипов у меня возникает вопрос - кастомные юниты появляются без моделек и т.п. Значком ERROR. Как в данный скрипт ввести юнитов из списка npc_units_custom?Нажмите, чтобы раскрыть...
имеется в виду не модели кастомные, а крипы с измененными статами, скиллами и т.д. из списка npc_units_custom, я ведь правильно понимаю, что именно в нем скриптить юнитов надо? Разобрался, просто та моделька, что была в примере у вольво по какой-то причине не прогружалась. Остальные работают и так. В любом случае спасибо)
Если так делать, то все равно крипы порою спавнятся друг на друге. Можно ли сделать так, чтобы у этого вектора устанавливалось не только максимальное значение, но и минимальное?doter.ua сказал(а):↑UPDATE: можно использовать функцию [COLOR=#ffff4d]RandomVector[/COLOR](максимальное значение) вместо того велосипеда с массивом. т.е. спавнить крипа в Vector(x, y, z) + RandomVector(100)Нажмите, чтобы раскрыть...
https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting/API/Global.FindClearSpaceForUnit используй на крипа сразу после спавнаMooMooKhan сказал(а):↑Если так делать, то все равно крипы порою спавнятся друг на друге. Можно ли сделать так, чтобы у этого вектора устанавливалось не только максимальное значение, но и минимальное?Нажмите, чтобы раскрыть...
Надо создать кастомное событие отслеживающее смерть крипа, по его срабатыванию запустить таймер (библиотека от БМД). По окончанию таймера заспавнить крипа. Есть еше вариант, создать невидимый спел, запускающий скрипт, который вызывает код на LUA, который запускает таймер от БМД. По окончанию спавнить крипа. Мне больше нравиться, метод номер 2, так как универсален для всех типов крипов + в качестве селектора вы, тоесть кому дали спел тот и воскреснет.Lw_Player сказал(а):↑Как сделать задержку например в 30 секунд для каждого крипа в отдельности. Т.е мы убиваем одного крипа из 3х и через 30 секунд этот крип появится и в лагере их снова будет 3? И как добавить второй лагерь?Нажмите, чтобы раскрыть...
А кто знает где можно посмотреть про библиотеки, классы и функции? Просто занялся скриптингом, в прошлом кодил на яве и пыхе. Думаю посмотрев мануал по дота-луа, я смогу что либо написать. Кстати как бы это не звучало странно, меня интересует документация на английском, но не помешает посмотреть и на русском. Так же огромное спасибо Дотер.юа за четыре прекрасных статьи. Пиши ещё, твои статьи актуальны и интересны читателю, ну а я надеюсь что кто либо даст ссылку на доки. Спасибо за внимание. С уважением Владимир.
Тема закрыта
-
ЗаголовокОтветов ПросмотровПоследнее сообщение
-
Сообщений:3
Просмотров:4
-
Сообщений:5
Просмотров:6
-
Сообщений:8
Просмотров:10
-
TheDangerGames 24 Apr 2024 в 02:47Сообщений: 10 24 Apr 2024 в 02:47
Сообщений:10
Просмотров:14
-
Сообщений:6
Просмотров:10