Dota 2 Workshop Tools (Глоссарий, общие обсуждения, вопросы)
121975
1534
lomal сказал(а):↑Ребят, повторю вопрос: как сделать чтобы на герое чужой спел кастовался нормально? у меня анимации нет, где её подключить?Нажмите, чтобы раскрыть...
Если ты делал полностью новый скилл то там есть строка
TheAnyKey сказал(а):↑
юзал кто?Нажмите, чтобы раскрыть...
Он ещё не вышел, он недоработан до ужаса.
FractalTree сказал(а):↑Пока что в поездке и нет возможности потрогать редактор самому. Поэтому назрел вопрос, на который я ещё не нашёл ответа: можно ли делать карту на 6/7/8/9 игроков в одной команде против одного игрока под контролем AI (мод не дотаподобный)?Нажмите, чтобы раскрыть...
Где то читал разрабы говорили 100х100 человек максимум в dota2 workshop tools можно замутить.
Dahz сказал(а):↑А можно ли добавлять свои модели?Нажмите, чтобы раскрыть...
Ну что за глупые вопросы... конечно можно.
С этим инструментом можно на изи новых героев штамповать которые еще в разработке. Можно переписать скрипт камеры и сделать как в World of Warcraft, можно на движке доты2 свою собвстенную игрулю написать и Гейб не узнает.
Kozhin2012 сказал(а):↑Ну что за глупые вопросы... конечно можно.
С этим инструментом можно на изи новых героев штамповать которые еще в разработке. Можно переписать скрипт камеры и сделать как в World of Warcraft, можно на движке доты2 свою собвстенную игрулю написать и Гейб не узнает.Нажмите, чтобы раскрыть...
ответь в лс, пожалуйста.
E]
FrostJkeee сказал(а):↑Народ, дайте наводку как сделать что бы при убийстве крипа он тут же спавнился в лагере (нейтральные крипы)Нажмите, чтобы раскрыть...
Где-то в доках наверняка есть событие смерть entity .
Так же в api есть метод https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting/API/CDOTA_BaseNPC.RespawnUnit
Но как это все собрать в работающий код - хз. В эту степь я еще не лазил.
UPDATE OnEntityKilled() вот что-то похожее на искомое событие. (с англ. entity - сущность. т.е. кто-угодно)
нашел в коде от мода InvokerWars, кто-то выкладывал недавно.
Спойлер: "Кусок исходника"function InvokerWars:OnEntityKilled( keys )
local killedUnit = EntIndexToHScript( keys.entindex_killed )
local killerEntity = nil
if keys.entindex_attacker == nil then
return
end
killerEntity = EntIndexToHScript( keys.entindex_attacker )
local killedTeam = killedUnit:GetTeam()
local killerTeam = killerEntity:GetTeam()
if killedUnit:IsRealHero() == true then
local death_count_down = 5
killedUnit:SetTimeUntilRespawn(death_count_down)
InvokerWars:CreateTimer(DoUniqueString("respawn"), {
endTime = GameRules:GetGameTime() + 1,
useGameTime = true,
callback = function(reflex, args)
death_count_down = death_count_down - 1
if death_count_down == 0 then
--Respawn hero after 5 seconds
killedUnit:RespawnHero(false,false,false)
return
else
killedUnit:SetTimeUntilRespawn(death_count_down)
return GameRules:GetGameTime() + 1
end
end
})
Там у чувака на вход передается некий keys с помощью которого он узнает ID умершего entity, только вот когда я тестил похожий метод, который тоже получал keys, этот keys у меня всегда был nil в языке lua это означает пустой, то есть никакого ID получить я не смог.
Может автор этих Инвокеров появится и прояснит ситуацию, а пока ...
Killerbl сказал(а):↑Допустим я добавил хук, изменил его, что нужно изменить чтобы на другом герое была его анимация.Нажмите, чтобы раскрыть...
Присоединяюсь к вопросу. Мне хотябы чтобы не измененный хук работал на другом герое.
А то получается что герои имеют только анимации родных скилов, а чужие юзают но без анимации.
d1amon сказал(а):↑
8 гб озу
i5 7 x64Нажмите, чтобы раскрыть...
Спойлер: "Почти такая же проблема!((((("
Объём двигателя, л. 1.1
Мощность двигателя, л.с. 53
Максимальная скорость, км/ч 145
Разгон до 100 км/ч, сек 16.2
Расход топлива по трассе при скорости 90 км/ч, л/100 км4.6
Расход топлива в городском цикле, л/100 км6.9
НЕ ЗАВОДИТСЯ!! ЧТО ДЕЛАТЬ!??????
fobas213 сказал(а):↑ты в нее поиграть хочешь или на ее основе что то сделать?Нажмите, чтобы раскрыть...
Если не секрет, о чем карту делаешь?
doter.ua сказал(а):↑
Спойлер:Копаясь в различных доках и исходниках приобрел немного знаний про Scripting, которые изложу в этом посте. (Вся работа в файле addon_game_mode.lua) Вкратце о чем пойдет речь:
- Обработка событий
- Как получить доступ к герою
- Что дает этот доступ? например можно изменить:
- Текущее ХП,
- Золото,
- Увеличить Макс. запас ХП и т.д.
Итак, в этой теме уже было пару сообщений про события, но объяснять другие пункты не рассказав про события будет неправильно.
1) Под событием подразумевается блок кода, который будет выполнен, когда это событие произойдет.
2) К сожалению список таких событий я не нашел. (Подсмотрел пару штук в Исходниках) например когда погибает юнит, когда герой кастует заклинание, когда герой респавнится и т.д.
3) Пример события это простая функция:
function ИмяМода:Имя_События() // имя мода например DotaPvP (задается вначале)
Какие-нибудь действия
end
4) Событию нужно написать слушателя listener. Делается это в блоке
function ИмяМода:InitGameMode()
бла бла
ListenToGameEvent('любое_имя', Dynamic_Wrap(ИмяМода, 'Имя_события'), self)
бла бла
end
5) В примере будем работать с событием AbilityUsed - когда используется заклинание.
ИмяМетода - DotaPvP.
В самом низу документа вставим нашу функцию:
function DotaPvP:AbilityUsed()
print('[DotaPvP] AbilityUsed')
end
Для начала просто выведем сообщение в консоль методом print('текст')
6) API методы из доков вольво
https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting/API
В разделе (по ссылке выше) список доступных методов.
- Часть из них можно вызвать просто скопировав название и передав параметры
Название_Метода( параметр_1, параметр_2 )
- Другая часть вызывается с помощью классов, методами которых они являются
чудо_класс:Название_Метода( параметр_1, параметр_2 )
Все методы делятся по разделам, у раздела Global стоит описание "Global functions. These can be called without any class" - могут вызываться без класса, то есть это та самая "первая часть", о которой я упоминал выше.
Однако есть разделы, в описании которых это не указано, тем не менее методы от туда так же вызываются без классов. Впрочем, с опытом, можно легко определить: вызывается ли тот или иной метод без класса.
Итак возьмем метод GameRules:SetGoldPerTick(5) где 5 - (число) кол-во золота, которое дается игроку за тик (просто капает со временем), GameRules - название раздела, SetGoldPerTick собственно сам метод. Между ними двоеточие - обязательный элемент.
Куда вставлять этот метод? туда же, где и слушатели listener (см. пункт 4)
7) Теперь перейдем к самому интересному - доступ к герою.
Да да речь пойдет про методы, которые нуждаются в классе.
Официального описания я не нашел (Но раздел scripting постоянно пополняется новыми разделами, надеюсь разрабы добавят инфы про нашу тему)
Скитаясь по разным исходникам.lua набрел на класс PlayerResource он позволяет получить доступ к герою.
Прелесть в том, что сам класс PlayerResource уже создан (наверно где-то в исходниках c++, да какая разница где, главное он есть) нужно всего лишь написать PlayerResource традиционное двоеточие и добавить метод из Раздела
CDOTA_PlayerResource
Возможно есть классы похожие на PlayerResource которые обеспечат доступ ко всем "нуждающимся в классах методам" Но я только 3 дня назад поставил Workshop tools на закачку и сам еще толком не разобрался.
8) Итак в разделе CDOTA_PlayerResource есть методы:
HasSelectedHero( число) - возвращает true\false если есть пикнутый герой (судя из названия)
GetSelectedHeroEntity( число) - возвращает класс, способный работать с методами из раздела CBaseEntity - собственно в нем и находятся методы, которые позволяют манипулировать над героем.
Объявим переменную local hero = PlayerResource:GetSelectedHeroEntity( номер )
- local - модификатор области видимости (сейчас это не важно)
- hero - просто название (Герой интуитивно понятно, что для работы с героем)
Что касается HasSelectedHero этот метод используется для проверки, вдруг ни одного героя не пикнули, а мы попробуем вызвать метод, который использует пикнутых героев.
Эта проверка была в блоке кода, в котором я и нашел класс PlayerResource.
9) Итак мы получили переменную (класс) hero с ее помощью сделаем следущее:
Все как раньше: ищем нужные методы в соответствующем разделе. (в случае с hero в разделе CBaseEntity)
- local maxHp = hero:GetMaxHealth() // текущий макс запас ХП.
- hero:SetMaxHealth( maxHp + 500 )
// ставим новый запас на 500 больше.- hero:SetHealth( maxHp + 500 )
// текущее хп = макс запасу (фулл).
Все это дело в цикле (блок повторяющийся заданное кол-во раз) по итерации (один обход цикла) на каждого героя.
Так же будем добавлять золото
PlayerResource:ModifyGold(nPlayerID, 500, false, 1)
- nPlayerID - id номер игрока (игроки нумеруются от 0) мы передаем переменную из цикла (это номер обхода цикла, т.е. если 10 игроков, то тело цикла сработает 10 раз и nPlayerID номер конкретного обхода.)
- 500 - кол-во голды
- false - boolean значение (надежное ли золото, которое не теряется при смерти)
- последний параметр - хз, просто принимает число(в описании нет ничего)
Стоит отметить, что цикл срабатывает для всех героев, независимо от того кто кастанул, чтобы делать для каждого героя отдельно нужно знать ID player который кастанул. и для этого ID уже делать манипуляции, я же не задумывался над тем где взять Конкретный ID, а просто для примера взял цикл со всеми героями (тем более тестил все сам, у меня то был всего один герой.)
итак ФУЛЛ КОД
Спойлер: "КОД"print( "Dota PvP game mode loaded." )
if DotaPvP == nil then
DotaPvP = class({})
end
-- ACTIVATE
function Activate()
GameRules.DotaPvP = DotaPvP()
GameRules.DotaPvP:InitGameMode()
end
-- INIT
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 )
-- Register Game Events
GameRules:SetGoldPerTick(5)
--listeners
ListenToGameEvent('dota_player_used_ability', Dynamic_Wrap(DotaPvP, 'AbilityUsed'), self)
end
--------------------------------------------------------------------------------
function DotaPvP:GameThink()
return 0.25
end
function DotaPvP:AbilityUsed()
print('[DotaPvP] AbilityUsed')
-- Цикл от 0 до системной константы DOTA_MAX_TEAM_PLAYERS
for nPlayerID = 0, DOTA_MAX_TEAM_PLAYERS-1 do
if PlayerResource:HasSelectedHero( nPlayerID ) then
local hero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
local maxHp = hero:GetMaxHealth()
hero:SetMaxHealth( maxHp + 500 )
hero:SetHealth( maxHp + 500 )
PlayerResource:ModifyGold(nPlayerID, 500, false, 1)
end
end
end
Спойлер: "КОД"
Если пост будет полезный можно закрепить в шапку :blush:
Нажмите, чтобы раскрыть...
Хорошая статья, в шапку обязательно. Ответил чтобы не потерять)
doter.ua сказал(а):↑Копаясь в различных доках и исходниках приобрел немного знаний про Scripting, которые изложу в этом посте. (Вся работа в файле addon_game_mode.lua)
Вкратце о чем пойдет речь:
- Обработка событий
- Как получить доступ к герою
- Что дает этот доступ? например можно изменить:
- Текущее ХП,
- Золото,
- Увеличить Макс. запас ХП и т.д.
Итак, в этой теме уже было пару сообщений про события, но объяснять другие пункты не рассказав про события будет неправильно.
1) Под событием подразумевается блок кода, который будет выполнен, когда это событие произойдет.
2) К сожалению список таких событий я не нашел. (Подсмотрел пару штук в Исходниках) например когда погибает юнит, когда герой кастует заклинание, когда герой респавнится и т.д.
3) Пример события это простая функция:
function ИмяМода:Имя_События() // имя мода например DotaPvP (задается вначале)
Какие-нибудь действия
end
4) Событию нужно написать слушателя listener. Делается это в блоке
function ИмяМода:InitGameMode()
бла бла
ListenToGameEvent('любое_имя', Dynamic_Wrap(ИмяМода, 'Имя_события'), self)
бла бла
end
5) В примере будем работать с событием AbilityUsed - когда используется заклинание.
ИмяМетода - DotaPvP.
В самом низу документа вставим нашу функцию:
function DotaPvP:AbilityUsed()
print('[DotaPvP] AbilityUsed')
end
Для начала просто выведем сообщение в консоль методом print('текст')
![]()
6) API методы из доков вольво
https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting/API
В разделе (по ссылке выше) список доступных методов.
- Часть из них можно вызвать просто скопировав название и передав параметры
Название_Метода( параметр_1, параметр_2 )
- Другая часть вызывается с помощью классов, методами которых они являются
чудо_класс:Название_Метода( параметр_1, параметр_2 )
Все методы делятся по разделам, у раздела Global стоит описание "Global functions. These can be called without any class" - могут вызываться без класса, то есть это та самая "первая часть", о которой я упоминал выше.
Однако есть разделы, в описании которых это не указано, тем не менее методы от туда так же вызываются без классов. Впрочем, с опытом, можно легко определить: вызывается ли тот или иной метод без класса.
Итак возьмем метод GameRules:SetGoldPerTick(5) где 5 - (число) кол-во золота, которое дается игроку за тик (просто капает со временем), GameRules - название раздела, SetGoldPerTick собственно сам метод. Между ними двоеточие - обязательный элемент.
Куда вставлять этот метод? туда же, где и слушатели listener (см. пункт 4)
7) Теперь перейдем к самому интересному - доступ к герою.
Да да речь пойдет про методы, которые нуждаются в классе.
Официального описания я не нашел (Но раздел scripting постоянно пополняется новыми разделами, надеюсь разрабы добавят инфы про нашу тему)
Скитаясь по разным исходникам.lua набрел на класс PlayerResource он позволяет получить доступ к герою.
Прелесть в том, что сам класс PlayerResource уже создан (наверно где-то в исходниках c++, да какая разница где, главное он есть) нужно всего лишь написать PlayerResource традиционное двоеточие и добавить метод из Раздела
CDOTA_PlayerResource
Возможно есть классы похожие на PlayerResource которые обеспечат доступ ко всем "нуждающимся в классах методам" Но я только 3 дня назад поставил Workshop tools на закачку и сам еще толком не разобрался.
8) Итак в разделе CDOTA_PlayerResource есть методы:
HasSelectedHero( число) - возвращает true\false если есть пикнутый герой (судя из названия)
GetSelectedHeroEntity( число) - возвращает класс, способный работать с методами из раздела CBaseEntity - собственно в нем и находятся методы, которые позволяют манипулировать над героем.
Объявим переменную local hero = PlayerResource:GetSelectedHeroEntity( номер )
- local - модификатор области видимости (сейчас это не важно)
- hero - просто название (Герой интуитивно понятно, что для работы с героем)
Что касается HasSelectedHero этот метод используется для проверки, вдруг ни одного героя не пикнули, а мы попробуем вызвать метод, который использует пикнутых героев.
Эта проверка была в блоке кода, в котором я и нашел класс PlayerResource.
9) Итак мы получили переменную (класс) hero с ее помощью сделаем следущее:
Все как раньше: ищем нужные методы в соответствующем разделе. (в случае с hero в разделе CBaseEntity)
- local maxHp = hero:GetMaxHealth() // текущий макс запас ХП.
- hero:SetMaxHealth( maxHp + 500 )
// ставим новый запас на 500 больше.- hero:SetHealth( maxHp + 500 )
// текущее хп = макс запасу (фулл).
Все это дело в цикле (блок повторяющийся заданное кол-во раз) по итерации (один обход цикла) на каждого героя.
Так же будем добавлять золото
PlayerResource:ModifyGold(nPlayerID, 500, false, 1)
- nPlayerID - id номер игрока (игроки нумеруются от 0) мы передаем переменную из цикла (это номер обхода цикла, т.е. если 10 игроков, то тело цикла сработает 10 раз и nPlayerID номер конкретного обхода.)
- 500 - кол-во голды
- false - boolean значение (надежное ли золото, которое не теряется при смерти)
- последний параметр - хз, просто принимает число(в описании нет ничего)
Стоит отметить, что цикл срабатывает для всех героев, независимо от того кто кастанул, чтобы делать для каждого героя отдельно нужно знать ID player который кастанул. и для этого ID уже делать манипуляции, я же не задумывался над тем где взять Конкретный ID, а просто для примера взял цикл со всеми героями (тем более тестил все сам, у меня то был всего один герой.)
итак ФУЛЛ КОД
Спойлер: "КОД"print( "Dota PvP game mode loaded." )
if DotaPvP == nil then
DotaPvP = class({})
end
-- ACTIVATE
function Activate()
GameRules.DotaPvP = DotaPvP()
GameRules.DotaPvP:InitGameMode()
end
-- INIT
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 )
-- Register Game Events
GameRules:SetGoldPerTick(5)
--listeners
ListenToGameEvent('dota_player_used_ability', Dynamic_Wrap(DotaPvP, 'AbilityUsed'), self)
end
--------------------------------------------------------------------------------
function DotaPvP:GameThink()
return 0.25
end
function DotaPvP:AbilityUsed()
print('[DotaPvP] AbilityUsed')
-- Цикл от 0 до системной константы DOTA_MAX_TEAM_PLAYERS
for nPlayerID = 0, DOTA_MAX_TEAM_PLAYERS-1 do
if PlayerResource:HasSelectedHero( nPlayerID ) then
local hero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
local maxHp = hero:GetMaxHealth()
hero:SetMaxHealth( maxHp + 500 )
hero:SetHealth( maxHp + 500 )
PlayerResource:ModifyGold(nPlayerID, 500, false, 1)
end
end
end
Спойлер: "КОД"
Если пост будет полезный можно закрепить в шапку :blush:
Нажмите, чтобы раскрыть...
Надо отдельную тему создать и туда полезные статьи подобные кидать.)
doter.ua сказал(а):↑Где-то в доках наверняка есть событие смерть entity .
Так же в api есть метод https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Scripting/API/CDOTA_BaseNPC.RespawnUnit
Но как это все собрать в работающий код - хз. В эту степь я еще не лазил.
UPDATE OnEntityKilled() вот что-то похожее на искомое событие. (с англ. entity - сущность. т.е. кто-угодно)
нашел в коде от мода InvokerWars, кто-то выкладывал недавно.
Спойлер: "Кусок исходника"function InvokerWars:OnEntityKilled( keys )
local killedUnit = EntIndexToHScript( keys.entindex_killed )
local killerEntity = nil
if keys.entindex_attacker == nil then
return
end
killerEntity = EntIndexToHScript( keys.entindex_attacker )
local killedTeam = killedUnit:GetTeam()
local killerTeam = killerEntity:GetTeam()
if killedUnit:IsRealHero() == true then
local death_count_down = 5
killedUnit:SetTimeUntilRespawn(death_count_down)
InvokerWars:CreateTimer(DoUniqueString("respawn"), {
endTime = GameRules:GetGameTime() + 1,
useGameTime = true,
callback = function(reflex, args)
death_count_down = death_count_down - 1
if death_count_down == 0 then
--Respawn hero after 5 seconds
killedUnit:RespawnHero(false,false,false)
return
else
killedUnit:SetTimeUntilRespawn(death_count_down)
return GameRules:GetGameTime() + 1
end
end
})
Там у чувака на вход передается некий keys с помощью которого он узнает ID умершего entity, только вот когда я тестил похожий метод, который тоже получал keys, этот keys у меня всегда был nil в языке lua это означает пустой, то есть никакого ID получить я не смог.
Может автор этих Инвокеров появится и прояснит ситуацию, а пока ...Нажмите, чтобы раскрыть...
Автор инвокеров Сайбермэт.
Тема закрыта
-
ЗаголовокОтветов ПросмотровПоследнее сообщение
-
Skiffersan 21 Dec 2024 в 15:27Сообщений: 1 21 Dec 2024 в 15:27
Сообщений:1
Просмотров:5
-
Сообщений:6
Просмотров:23
-
Сообщений:15
Просмотров:41
-
Сообщений:8
Просмотров:26
-
внук берии 21 Dec 2024 в 14:31Сообщений: 5 21 Dec 2024 в 14:31
Сообщений:5
Просмотров:34


