-
Автор темы
- #1
Доброго времени суток господа, решил я значится, дублировать на этот форум полезные материалы для мододелов, глядишь откроют ветку для таких как я и сюда подтянутся людишки
В общем то, чего томить, я буду добавлять в теме свои наработки
"Я учусь и вас научу, чо нам пацанам то, просто мало инфы для ру комьюнити"
В общем то, чего томить, я буду добавлять в теме свои наработки
"Я учусь и вас научу, чо нам пацанам то, просто мало инфы для ру комьюнити"
Сегодня я покажу в примере, как создать свой простой/универсальный предмет сделать ему модельку когда он лежит на земле (аля рапира, ботинки и прочее), поменять предмету текстуру и как ему накинуть иконку в панели предметов, чтож начнем.
Система дропов предметов / спавна предметов позаимствована у "
Возвращаемся в Hammer пробуем компилить и радуемся
если не отображается просто нажми на него
если не отображается просто нажми на него
если не отображается просто нажми на него
если не отображается просто нажми на него
Ссылка на первоисточник "
Спасибо за внимание :з
Система дропов предметов / спавна предметов позаимствована у "
Пожалуйста, авторизуйтесь для просмотра ссылки.
"Идем по пути: ********\steam\steamapps\common\dota 2 beta\game\dota_addons\********\scripts\vscripts\ (вместо * ваш путь), создаем тут файлик "item_drop.lua"
В этой же папке откройте ваш "addon_game_mode.lua" и добавьте строчку: require ("item_drop") - она подключит созданный вами ранее LUA скрипт
code_language.lua:
if ItemDrop == nil then
_G.ItemDrop = class({})
end
-- items - список предметов, которые могут выпасть
-- chance - шанс выпадения (если не определен, то равен 100%) список юнитов из которых могут выпасть предметы ( если не определен, то выпадает с любого юнита)
-- duration - длительность жизни предмета на полу( если не определен, то предмет лежит бесконечно)
-- limit - лимит предметов - количество предметов, которые могут выпасть( если не определен, то количество не ограничено)
-- units - список юнитов, из которых падает предмет
ItemDrop.item_drop = {
-- {items = {"item_branches"}, chance = 5, duration = 5, limit = 3, units = {"npc_name"} },
{items = {"item_swen_sword"}, units = {"Wooden_box1"}}, --100% шанс дропа из сундука
{items = {"item_flask"}, chance = 5, duration = 5},-- глобальный дроп в 5% фласки
{items = {"item_tango_single"}, chance = 15, duration = 3},-- глобальный дроп в 15% кусок тангуса
{items = {"item_enchanted_mango"}, chance = 8, duration = 5},-- глобальный дроп в 8% манго
}
-- point_name - название таргета
-- item_name - название предмета
ItemDrop.secret_items = {
-- ["point_name"] = "item_name",
["item_spawner_swen_sword"] = "item_swen_sword",
}
function ItemDrop:InitGameMode()
ListenToGameEvent('entity_killed', Dynamic_Wrap(self, 'OnEntityKilled'), self)
ListenToGameEvent('game_rules_state_change', Dynamic_Wrap(self, 'OnGameRulesStateChange'), self)
end
function ItemDrop:OnGameRulesStateChange()
local newState = GameRules:State_Get()
if newState == DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
ItemDrop:SpawnItems()
end
end
function ItemDrop:SpawnItems()
local items = self.secret_items
for point_name,item_name in pairs(items) do
local point = Entities:FindByName(nil, point_name)
if point then
point = point:GetAbsOrigin()
local newItem = CreateItem( item_name, nil, nil )
local drop = CreateItemOnPositionSync( point, newItem )
else
print("point with name "..point_name.." dont exist !")
end
end
end
function ItemDrop:OnEntityKilled( keys )
local killedUnit = EntIndexToHScript( keys.entindex_killed )
local name = killedUnit:GetUnitName()
local team = killedUnit:GetTeam()
if team ~= DOTA_TEAM_GOODGUYS and name ~= "npc_dota_thinker" then
ItemDrop:RollItemDrop(killedUnit)
end
end
function ItemDrop:RollItemDrop(unit)
local unit_name = unit:GetUnitName()
for _,drop in ipairs(self.item_drop) do
local items = drop.items or nil
local items_num = #items
local units = drop.units or nil -- если юниты не были определены, то срабатывает для любого
local chance = drop.chance or 100 -- если шанс не был определен, то он равен 100
local loot_duration = drop.duration or nil -- длительность жизни предмета на земле
local limit = drop.limit or nil -- лимит предметов
local item_name = items[1] -- название предмета
local roll_chance = RandomFloat(0, 100)
if units then
for _,current_name in pairs(units) do
if current_name == unit_name then
units = nil
break
end
end
end
if units == nil and (limit == nil or limit > 0) and roll_chance < chance then
if limit then
drop.limit = drop.limit - 1
end
if items_num > 1 then
item_name = items[RandomInt(1, #items)]
end
local spawnPoint = unit:GetAbsOrigin()
local newItem = CreateItem( item_name, nil, nil )
local drop = CreateItemOnPositionForLaunch( spawnPoint, newItem )
local dropRadius = RandomFloat( 50, 100 )
newItem:LaunchLootInitialHeight( false, 0, 150, 0.5, spawnPoint + RandomVector( dropRadius ) )
if loot_duration then
newItem:SetContextThink( "KillLoot",
function()
if drop:IsNull() then
return
end
local nFXIndex = ParticleManager:CreateParticle( "particles/items2_fx/veil_of_discord.vpcf", PATTACH_CUSTOMORIGIN, drop )
ParticleManager:SetParticleControl( nFXIndex, 0, drop:GetOrigin() )
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( 35, 35, 25 ) )
ParticleManager:ReleaseParticleIndex( nFXIndex )
-- EmitGlobalSound("Item.PickUpWorld")
UTIL_Remove( item )
UTIL_Remove( drop )
end, loot_duration )
end
end
end
end
function KillLoot( item, drop )
if drop:IsNull() then
return
end
local nFXIndex = ParticleManager:CreateParticle( "particles/items2_fx/veil_of_discord.vpcf", PATTACH_CUSTOMORIGIN, drop )
ParticleManager:SetParticleControl( nFXIndex, 0, drop:GetOrigin() )
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( 35, 35, 25 ) )
ParticleManager:ReleaseParticleIndex( nFXIndex )
-- EmitGlobalSound("Item.PickUpWorld")
UTIL_Remove( item )
UTIL_Remove( drop )
end
ItemDrop:InitGameMode()
В этой же папке откройте ваш "addon_game_mode.lua" и добавьте строчку: require ("item_drop") - она подключит созданный вами ранее LUA скрипт
Теперь приступим непосредственно к созданию модели и все что с ней связано вплоть до текстуры
1) Открываем любой Ваш проект через "Dota 2 tools"
2) Открываем в нём "Hammer"
3) Создаем новую пустую карту (можете её даже не сохранять, она нужна чтобы отцентрировать бедующую модель)
4) Переносите понравившуюся модель в центр сетки
если не отображается просто нажми на него
- Я добавил ландшафт, чтобы понимать, как будет смотреться предмет когда выпадет, как лут (это не обязательно - лишь наглядная демонстрация)
5) Выберите Вашу модель
если не отображается просто нажми на него
6) Нажмите в контекстном меню кнопку: File -> Export Selected
7) Введите название для Вашей модели и сохраните её по пути: \steam\steamapps\common\dota 2 beta\content\dota_addons\*\models (вместо * ваш путь)
8) Откройте в правом верхнем почти углу Tools -> Model editor
если не отображается просто нажми на него
9) В появившемся
если не отображается просто нажми на него
жмем: New VMDL From Mesh File или же сочетание клавиш "Ctrl+M" -> выбираем сохраненную ранее модель в формате "DMX" -> Появится диалоговое окно уточнения пути сохранения будущей модели -> Нажимаем OK
10) Нас встречает окно с Вашей моделью сохраненной ранее, положение модели в котором вы его экспортировали будучи на 6м шаге!
если не отображается просто нажми на него
11) Скачиваем
12) После скачивания помещаем её по пути :\steam\steamapps\common\dota 2 beta\content\dota_addons\***\models\ (Вместо * ваш путь)
13) Возвращаемся в наше окно с моделью, на строке контекстного меню находим кнопку: Animation -> Add Animation -> box.fbx (Выбираем наш ранее скачанный файлик с анимацией пустоты дающий нам косточку) (P.s. Управление такое же как и в Hammer: WASD + ПКМ для поворота камеры)
14) После предыдущего шага должна появиться строка Skeleton и Animations в древе файла слева
15) Нажимаем в контекстном меню кнопку: Model -> Hitboxes -> Add Hitbox -> соглашаемся с названиями либо переименовываем по желанию
16) Теперь настроим хитбокс у модели, выбираем в левом древе: Hitboxes -> HitboxSetList_X -> default -> X (X - название)
17) Для отображения хитбоксов необходимо включить визуалы на контекстном меню: Display -> Show all -> По желанию можно включить куб предмета (по нажатию на Show all они не отображаются, в дисплее оранжевый / фиолетовый / желтые кружки + физика зеленый)
18) После того как нажали на Show all у нас должен появиться зеленый квадратик - наш Хитбокс растягиваем его под модель: он нужен для того, что бы в игре модель можно было трогать как предметы, а не пустые модельки которые нельзя выбрать
19) Как только подогнали хитбокс
если не отображается просто нажми на него
- для более точной настройки используйте значения Bounds в правой колонке
20) Сохраняем нашу готовую модель в контекстном меню нажимаем: File -> Save (ctrl+s)
20.1) Работа с моделью закончена - это то что будет выпадать на землю
20.2) Не спешите закрывать окно, оно щас пригодится чтобы сделать иконку и получить быстро материал для модели (чтоб не бегать по 100 раз в Asset Browser)
1) Открываем любой Ваш проект через "Dota 2 tools"
2) Открываем в нём "Hammer"
3) Создаем новую пустую карту (можете её даже не сохранять, она нужна чтобы отцентрировать бедующую модель)
4) Переносите понравившуюся модель в центр сетки
5) Выберите Вашу модель
7) Введите название для Вашей модели и сохраните её по пути: \steam\steamapps\common\dota 2 beta\content\dota_addons\*\models (вместо * ваш путь)
8) Откройте в правом верхнем почти углу Tools -> Model editor
10) Нас встречает окно с Вашей моделью сохраненной ранее, положение модели в котором вы его экспортировали будучи на 6м шаге!
Пожалуйста, авторизуйтесь для просмотра ссылки.
<- (click) - простая анимация пустоты - с помощью неё мы добавим кость12) После скачивания помещаем её по пути :\steam\steamapps\common\dota 2 beta\content\dota_addons\***\models\ (Вместо * ваш путь)
13) Возвращаемся в наше окно с моделью, на строке контекстного меню находим кнопку: Animation -> Add Animation -> box.fbx (Выбираем наш ранее скачанный файлик с анимацией пустоты дающий нам косточку) (P.s. Управление такое же как и в Hammer: WASD + ПКМ для поворота камеры)
14) После предыдущего шага должна появиться строка Skeleton и Animations в древе файла слева
15) Нажимаем в контекстном меню кнопку: Model -> Hitboxes -> Add Hitbox -> соглашаемся с названиями либо переименовываем по желанию
16) Теперь настроим хитбокс у модели, выбираем в левом древе: Hitboxes -> HitboxSetList_X -> default -> X (X - название)
17) Для отображения хитбоксов необходимо включить визуалы на контекстном меню: Display -> Show all -> По желанию можно включить куб предмета (по нажатию на Show all они не отображаются, в дисплее оранжевый / фиолетовый / желтые кружки + физика зеленый)
18) После того как нажали на Show all у нас должен появиться зеленый квадратик - наш Хитбокс растягиваем его под модель: он нужен для того, что бы в игре модель можно было трогать как предметы, а не пустые модельки которые нельзя выбрать
19) Как только подогнали хитбокс
20) Сохраняем нашу готовую модель в контекстном меню нажимаем: File -> Save (ctrl+s)
20.1) Работа с моделью закончена - это то что будет выпадать на землю
20.2) Не спешите закрывать окно, оно щас пригодится чтобы сделать иконку и получить быстро материал для модели (чтоб не бегать по 100 раз в Asset Browser)
Переходим к созданию новой текстуры для предмета
По умолчанию, нельзя взять у готовой модели текстуру в формате TGA/PNG/PSD они все закомпилены, самый простой и быстрый способ это:
1) В том же окне нажимаем на контекстном меню кнопку: Asset -> Open related files -> *** Material Editor (* там много писать.. лень) -> .vmat ( - название материала по умолчанию в формате vmat)
2) Открылось
если не отображается просто нажми на него
, материал котого нельзя заменить, но я скажу хитрость, как оттуда взять эту самую текстуру
3) Жмем в правом окошке, где сфера, на полотно 3я кнопка и получаем нашу
если не отображается просто нажми на него
(она может быть статичной или динамичной)
3.1) Статичная - когда картинка не изменяется (показываю на этом примере)
3.2) Динамичная когда что-то переливается
4) Нехитрым способом WIN+SHIFT+S выделяем область нашей текстуры, открываем любой удобный нам редактор, я открою фотошоп
4.1) Создаю новый файл 1024х1024 - размер текстуры -
если не отображается просто нажми на него
4.2) Вставляю туда текстуру, перекрашиваю её
если не отображается просто нажми на него
4.3) Сохранив новую текстуру в формате PNG | TGA | PSD | TIF
4.4) Идем обратно в окно материалов в контекстном меню нажимаем: File -> New -> Он не даст редактировать пока не сохраним! -> File -> Save As.. -> любое название для материала
4.5) Если все сделано верно, то будут доступны функции для материалов и добавление материала, нажимаем на папку для выбора Color:
если не отображается просто нажми на него
4.6) В появившемся окне выбора текстуры вместо параметра: Images выбираем All Images и выбираем Вашу готовую текстуру
если не отображается просто нажми на него
4.7) Сохраняем Ваш материал в контекстном меню кнопка: File -> Save (ctrl+s)
4.8) Теперь нам доступен новый материал в "Asset Browser"
4.9) Идем в папку с Вашей моделью (куда Вы изначально сохранили МОДЕЛЬ.DMX)
4.10) Открываем Вашу модель.DMX редактором: Notepad ++ | Sublime text | Прочими редакторами
4.11) Ищем такую строку:
materials/models/items/sven/sven_ti7_immortal_sword/sven_ti7_immortal_sword.vmat - является материалом по умолчанию у предмета
Заменяем эту строчку путем к Вашему материалу, я его беру из "ASSET BROWSER" нажав: ПКМ на материал -> Copy Asset Name
a.vmat - путь к моему файлу (он не находится в папке models или material, а просто валяется в папке карты)
4.12) Готово, Вы молодцы и сделали теперь уже лежащий предмет в игре с Вашей текстуркой
По умолчанию, нельзя взять у готовой модели текстуру в формате TGA/PNG/PSD они все закомпилены, самый простой и быстрый способ это:
1) В том же окне нажимаем на контекстном меню кнопку: Asset -> Open related files -> *** Material Editor (* там много писать.. лень) -> .vmat ( - название материала по умолчанию в формате vmat)
2) Открылось
3) Жмем в правом окошке, где сфера, на полотно 3я кнопка и получаем нашу
3.1) Статичная - когда картинка не изменяется (показываю на этом примере)
3.2) Динамичная когда что-то переливается
4) Нехитрым способом WIN+SHIFT+S выделяем область нашей текстуры, открываем любой удобный нам редактор, я открою фотошоп
4.1) Создаю новый файл 1024х1024 - размер текстуры -
4.4) Идем обратно в окно материалов в контекстном меню нажимаем: File -> New -> Он не даст редактировать пока не сохраним! -> File -> Save As.. -> любое название для материала
4.5) Если все сделано верно, то будут доступны функции для материалов и добавление материала, нажимаем на папку для выбора Color:
4.8) Теперь нам доступен новый материал в "Asset Browser"
4.9) Идем в папку с Вашей моделью (куда Вы изначально сохранили МОДЕЛЬ.DMX)
4.10) Открываем Вашу модель.DMX редактором: Notepad ++ | Sublime text | Прочими редакторами
4.11) Ищем такую строку:
Код:
"material" "DmeMaterial"
{
"id" "elementid" "b96f1baf-98cf-4612-975d-0c8171d69a9a"
"name" "string" "material"
"mtlName" "string" "materials/models/items/sven/sven_ti7_immortal_sword/sven_ti7_immortal_sword.vmat"
}
Заменяем эту строчку путем к Вашему материалу, я его беру из "ASSET BROWSER" нажав: ПКМ на материал -> Copy Asset Name
a.vmat - путь к моему файлу (он не находится в папке models или material, а просто валяется в папке карты)
Переходим к созданию иконки
1) Открываем любой доступный фото/вектор редактор (желательно конечно же вектор - он не потеряет качество), но я по привычке открою фотошоп
2) Создаем размеры: 88х33 px dpi 300 (стандартно у меня всегда)
3) Заливаем туда картинку подготовленную заранее в хорошем разрешении для нашего предмета в фотошопе будет пиксельная война, для таких приколов лучше использовать CorelDraw
3.1) Покажу лайфхак как замутить со своей наложенной готовой текстурой иконку для предмета:
если не отображается просто нажми на него
Жмем все те же Win+Shift+S выделяем что надо заскринить, идем в редактор и вставляем это в нашу иконку - немного её редачим, фон там накидываем и так далее
Вот картинка без фона в более менее хорошем качестве Вот картинка как иконка с фоном
если не отображается просто нажми на него
- мелкие недочеты ретуши уже не видны, да и в падлу было красиво делать
ПУТЬ ДЛЯ СОХРАНЕНИЯ ИКОНОК:
ДИСК:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\resource\flash3\images\items\ (можно создавать подпапки)
1) Открываем любой доступный фото/вектор редактор (желательно конечно же вектор - он не потеряет качество), но я по привычке открою фотошоп
2) Создаем размеры: 88х33 px dpi 300 (стандартно у меня всегда)
3) Заливаем туда картинку подготовленную заранее в хорошем разрешении для нашего предмета в фотошопе будет пиксельная война, для таких приколов лучше использовать CorelDraw
3.1) Покажу лайфхак как замутить со своей наложенной готовой текстурой иконку для предмета:
Жмем все те же Win+Shift+S выделяем что надо заскринить, идем в редактор и вставляем это в нашу иконку - немного её редачим, фон там накидываем и так далее
Вот картинка без фона в более менее хорошем качестве Вот картинка как иконка с фоном
ПУТЬ ДЛЯ СОХРАНЕНИЯ ИКОНОК:
ДИСК:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\resource\flash3\images\items\ (можно создавать подпапки)
Перейдем теперь к добавлению нашего предмета / меча, в игру :
1) Открываем ДИСК:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\scripts\npc\ ФАЙЛ "npc_items_custom.txt"
Пример исходного кода с одним кастомным предметом - мечем который я рассматривал в этом уроке:
2) Возвращаемся в наш файл Item_drop.lua, начинаем добавлять предмет (в коде он уже добавлен как шанс дропа из ящика - но у вас не будет этого самого ящика по этому любой ваш юнит на карте) либо просто заспавните его на полу через "ItemDrop.secret_items", напишите название info_target и название предмета
1) Открываем ДИСК:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\scripts\npc\ ФАЙЛ "npc_items_custom.txt"
Пример исходного кода с одним кастомным предметом - мечем который я рассматривал в этом уроке:
Код:
"DOTAAbilities"
{
//=================================================================================================================
// SWEN SWORD - Меч Свена
//=================================================================================================================
"item_swen_sword" // название предмета
{
"ID" "2122" // уникальный ID предмета (не должны повторяться)
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE" // Что из себя представляет эффект от предмета (в данном случае пассивку)
"BaseClass" "item_datadriven" // База предмета
"Model" "models/swen_sword.vmdl"// Путь к модельке предмета
"AbilityTextureName" "Swen_sword" // Путь к текстурке иконки 88х33 в моём случае просто в папке items
// Item Info
//---------------------------------------------------------------------------------------------------------
"ItemCost" "9999999999" // цена покупки
"ItemSellable" "0" // возможность продать
"ItemKillable" "0" // возможность сломать шмотку
"ItemQuality" "epic" // где будет предмет в магазине
"ItemShopTags" "damage" // тэг в поиске магазина
"ItemAliases" "sword_life" // Алиас для магазина
"ItemShareability" "ITEM_NOT_SHAREABLE" // возможность стакать предмет - в этом случае уникальный (аля рапира)
"ItemDeclarations" "DECLARE_PURCHASES_TO_TEAMMATES | DECLARE_PURCHASES_TO_SPECTATORS | DECLARE_PURCHASES_IN_SPEECH" -- для шопа что-то
"Modifiers" // модификатор
{
"modifier_sword_life" // название модификатора
{
"Passive" "1" // тип модификатора
"IsHidden" "1" // видимость модификатора
"Properties" // действие модификатора
{
"MODIFIER_PROPERTY_BASEATTACK_BONUSDAMAGE" "%bonus_damage" // дать носителю дамаг от абилки bonus_damage
}
}
}
// Special // специальные вставки
//---------------------------------------------------------------------------------------------------------
"AbilitySpecial" // абика
{
"01" // нумирация
{
"var_type" "FIELD_INTEGER" // тип исчисления (целочисленное)
"bonus_damage" "150" // бонус от абилки дамаг +150
}
}
}
}
}
ДИСК:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\resource\ файл "addon_russian.txt"
code_language.lua:
"lang"
{
"Language" "russian"
"Tokens"
{
"addon_game_name" "Название вашей кастомки"
"DOTA_Tooltip_ability_item_swen_sword" "Легендарный меч Свена"
"DOTA_Tooltip_ability_item_swen_sword_Lore" "По легенде этот мечь способен прорубать толпы врагов"
"DOTA_Tooltip_ability_item_swen_sword_bonus_damage" "+к урону"
}
}
Ссылка на первоисточник "
Пожалуйста, авторизуйтесь для просмотра ссылки.
"Спасибо за внимание :з
Всех с новым 2022 годом, вот вам господа мододелы, исходничек Lua скрипта на ограничение подбора более одного уникального предмета
Благодарность за исходник: "
Нам понадобиться:
Ссылка на первоисточник "
Спасибо за внимание :3
Благодарность за исходник: "
Пожалуйста, авторизуйтесь для просмотра ссылки.
"Нам понадобиться:
Пример можно взять
Пожалуйста, авторизуйтесь для просмотра ссылки.
<- (click)Путь к файлу:
*:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\scripts\vscripts\
Название файла:
custom_sword.lua
*:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\scripts\vscripts\
Название файла:
custom_sword.lua
code_language.lua:
LinkLuaModifier("modifier_item_sword_life_lua", "custom_sword", LUA_MODIFIER_MOTION_NONE)
LinkLuaModifier("modifier_item_sword_water_lua", "custom_sword", LUA_MODIFIER_MOTION_NONE)
LinkLuaModifier("modifier_item_sword_death_lua", "custom_sword", LUA_MODIFIER_MOTION_NONE)
LinkLuaModifier("modifier_item_sword_insects_lua", "custom_sword", LUA_MODIFIER_MOTION_NONE)
item_sword_life_lua = class({})
function item_sword_life_lua:GetIntrinsicModifierName()
return "modifier_item_sword_life_lua"
end
modifier_item_sword_life_lua = class({
IsHidden = function(self) return true end,
IsPurgable = function(self) return false end,
IsDebuff = function(self) return false end,
IsBuff = function(self) return true end,
RemoveOnDeath = function(self) return false end,
DeclareFunctions = function(self) return
{
MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE,
} end,
})
function modifier_item_sword_life_lua:OnCreated()
local caster = self:GetCaster()
local vLocation = caster:GetAbsOrigin()
local item = self:GetAbility()
if caster.sword == nil then
caster.sword = self
else
Timers:CreateTimer(0, function()
caster:DropItemAtPositionImmediate(item, vLocation)
GameRules:SendCustomMessage("<font color='#FA8072'> Нельзя носить более одного уникального меча !</font>",0,0)
end)
end
self.bonus_dmg = self:GetAbility():GetSpecialValueFor("bonus_dmg")
end
function modifier_item_sword_life_lua:OnDestroy()
local caster = self:GetCaster()
if caster.sword == self then
caster.sword = nil
end
end
function modifier_item_sword_life_lua:GetAttributes()
return MODIFIER_ATTRIBUTE_MULTIPLE + MODIFIER_ATTRIBUTE_IGNORE_INVULNERABLE
end
function modifier_item_sword_life_lua:GetModifierPreAttack_BonusDamage()
return self.bonus_dmg
end
item_sword_water_lua = class({})
function item_sword_water_lua:GetIntrinsicModifierName()
return "modifier_item_sword_water_lua"
end
modifier_item_sword_water_lua = class({
IsHidden = function(self) return true end,
IsPurgable = function(self) return false end,
IsDebuff = function(self) return false end,
IsBuff = function(self) return true end,
RemoveOnDeath = function(self) return false end,
DeclareFunctions = function(self) return
{
MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE,
} end,
})
function modifier_item_sword_water_lua:OnCreated()
local caster = self:GetCaster()
local vLocation = caster:GetAbsOrigin()
local item = self:GetAbility()
if caster.sword == nil then
caster.sword = self
else
Timers:CreateTimer(0, function()
caster:DropItemAtPositionImmediate(item, vLocation)
GameRules:SendCustomMessage("<font color='#FA8072'> Нельзя носить более одного уникального меча !</font>",0,0)
end)
end
self.bonus_dmg = self:GetAbility():GetSpecialValueFor("bonus_dmg")
end
function modifier_item_sword_water_lua:OnDestroy()
local caster = self:GetCaster()
if caster.sword == self then
caster.sword = nil
end
end
function modifier_item_sword_water_lua:GetAttributes()
return MODIFIER_ATTRIBUTE_MULTIPLE + MODIFIER_ATTRIBUTE_IGNORE_INVULNERABLE
end
function modifier_item_sword_water_lua:GetModifierPreAttack_BonusDamage()
return self.bonus_dmg
end
item_sword_death_lua = class({})
function item_sword_death_lua:GetIntrinsicModifierName()
return "modifier_item_sword_death_lua"
end
modifier_item_sword_death_lua = class({
IsHidden = function(self) return true end,
IsPurgable = function(self) return false end,
IsDebuff = function(self) return false end,
IsBuff = function(self) return true end,
RemoveOnDeath = function(self) return false end,
DeclareFunctions = function(self) return
{
MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE,
} end,
})
function modifier_item_sword_death_lua:OnCreated()
local caster = self:GetCaster()
local vLocation = caster:GetAbsOrigin()
local item = self:GetAbility()
if caster.sword == nil then
caster.sword = self
else
Timers:CreateTimer(0, function()
caster:DropItemAtPositionImmediate(item, vLocation)
GameRules:SendCustomMessage("<font color='#FA8072'> Нельзя носить более одного уникального меча !</font>",0,0)
end)
end
self.bonus_dmg = self:GetAbility():GetSpecialValueFor("bonus_dmg")
end
function modifier_item_sword_death_lua:OnDestroy()
local caster = self:GetCaster()
if caster.sword == self then
caster.sword = nil
end
end
function modifier_item_sword_death_lua:GetAttributes()
return MODIFIER_ATTRIBUTE_MULTIPLE + MODIFIER_ATTRIBUTE_IGNORE_INVULNERABLE
end
function modifier_item_sword_death_lua:GetModifierPreAttack_BonusDamage()
return self.bonus_dmg
end
item_sword_insects_lua = class({})
function item_sword_insects_lua:GetIntrinsicModifierName()
return "modifier_item_sword_insects_lua"
end
modifier_item_sword_insects_lua = class({
IsHidden = function(self) return true end,
IsPurgable = function(self) return false end,
IsDebuff = function(self) return false end,
IsBuff = function(self) return true end,
RemoveOnDeath = function(self) return false end,
DeclareFunctions = function(self) return
{
MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE,
} end,
})
function modifier_item_sword_insects_lua:OnCreated()
local caster = self:GetCaster()
local vLocation = caster:GetAbsOrigin()
local item = self:GetAbility()
if caster.sword == nil then
caster.sword = self
else
Timers:CreateTimer(0, function()
caster:DropItemAtPositionImmediate(item, vLocation)
GameRules:SendCustomMessage("<font color='#FA8072'> Нельзя носить более одного уникального меча !</font>",0,0)
end)
end
self.bonus_dmg = self:GetAbility():GetSpecialValueFor("bonus_dmg")
end
function modifier_item_sword_insects_lua:OnDestroy()
local caster = self:GetCaster()
if caster.sword == self then
caster.sword = nil
end
end
function modifier_item_sword_insects_lua:GetAttributes()
return MODIFIER_ATTRIBUTE_MULTIPLE + MODIFIER_ATTRIBUTE_IGNORE_INVULNERABLE
end
function modifier_item_sword_insects_lua:GetModifierPreAttack_BonusDamage()
return self.bonus_dmg
end
Путь к файлу:
*:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\scripts\npc\
Название файла:
npc_items_custom.txt
*:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\scripts\npc\
Название файла:
npc_items_custom.txt
Код:
"DOTAAbilities"
{
"item_sword_insects_lua"
{
"BaseClass" "item_lua"
"ScriptFile" "custom_sword"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"Model" "models/sword_insects.vmdl"
"AbilityTextureName" "sword_insects"
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"bonus_dmg" "150"
}
}
}
"item_sword_death_lua"
{
"BaseClass" "item_lua"
"ScriptFile" "custom_sword"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"Model" "models/sword_death.vmdl"
"AbilityTextureName" "sword_death"
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"bonus_dmg" "150"
}
}
}
"item_sword_water_lua"
{
"BaseClass" "item_lua"
"ScriptFile" "custom_sword"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"Model" "models/sword_water.vmdl"
"AbilityTextureName" "sword_water"
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"bonus_dmg" "150"
}
}
}
"item_sword_life_lua"
{
"BaseClass" "item_lua"
"ScriptFile" "custom_sword"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"Model" "models/sword_life.vmdl"
"AbilityTextureName" "sword_life"
"RingRadius" "99"
"HealthBarOffset" "300"
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"bonus_dmg" "150"
}
}
}
}
Закиньте файл с любым названием - содержание:
Это таймеры, если у вас вдруг их нет
И подключите файл через:
require ("Ваше название") //без формата: require ("timers")
В файле addon_game_mode.lua
code_language.lua:
--[[
-- A timer running every second that starts immediately on the next frame, respects pauses
Timers:CreateTimer(function()
print ("Hello. I'm running immediately and then every second thereafter.")
return 1.0
end
)
-- A timer running every second that starts 5 seconds in the future, respects pauses
Timers:CreateTimer(5, function()
print ("Hello. I'm running 5 seconds after you called me and then every second thereafter.")
return 1.0
end
)
-- 10 second delayed, run once using gametime (respect pauses)
Timers:CreateTimer({
endTime = 10, -- when this timer should first execute, you can omit this if you want it to run first on the next frame
callback = function()
print ("Hello. I'm running 10 seconds after when I was started.")
end
})
-- 10 second delayed, run once regardless of pauses
Timers:CreateTimer({
useGameTime = false,
endTime = 10, -- when this timer should first execute, you can omit this if you want it to run first on the next frame
callback = function()
print ("Hello. I'm running 10 seconds after I was started even if someone paused the game.")
end
})
-- A timer running every second that starts after 2 minutes regardless of pauses
Timers:CreateTimer("uniqueTimerString3", {
useGameTime = false,
endTime = 120,
callback = function()
print ("Hello. I'm running after 2 minutes and then every second thereafter.")
return 1
end
})
-- A timer using the old style to repeat every second starting 5 seconds ahead
Timers:CreateTimer("uniqueTimerString3", {
useOldStyle = true,
endTime = GameRules:GetGameTime() + 5,
callback = function()
print ("Hello. I'm running after 5 seconds and then every second thereafter.")
return GameRules:GetGameTime() + 1
end
})
]]
TIMERS_THINK = 0.01
if Timers == nil then
print ( '[Timers] creating Timers' )
Timers = {}
Timers.__index = Timers
end
function Timers:new( o )
o = o or {}
setmetatable( o, Timers )
return o
end
function Timers:start()
Timers = self
self.timers = {}
local ent = Entities:CreateByClassname("info_target") -- Entities:FindByClassname(nil, 'CWorld')
ent:SetThink("Think", self, "timers", TIMERS_THINK)
end
function Timers:Think()
if GameRules:State_Get() >= DOTA_GAMERULES_STATE_POST_GAME then
return
end
-- Track game time, since the dt passed in to think is actually wall-clock time not simulation time.
local now = GameRules:GetGameTime()
-- Process timers
for k,v in pairs(Timers.timers) do
local bUseGameTime = true
if v.useGameTime ~= nil and v.useGameTime == false then
bUseGameTime = false
end
local bOldStyle = false
if v.useOldStyle ~= nil and v.useOldStyle == true then
bOldStyle = true
end
local now = GameRules:GetGameTime()
if not bUseGameTime then
now = Time()
end
if v.endTime == nil then
v.endTime = now
end
-- Check if the timer has finished
if now >= v.endTime then
-- Remove from timers list
Timers.timers[k] = nil
-- Run the callback
local status, nextCall = pcall(v.callback, GameRules:GetGameModeEntity(), v)
-- Make sure it worked
if status then
-- Check if it needs to loop
if nextCall then
-- Change its end time
if bOldStyle then
v.endTime = v.endTime + nextCall - now
else
v.endTime = v.endTime + nextCall
end
Timers.timers[k] = v
end
-- Update timer data
--self:UpdateTimerData()
else
-- Nope, handle the error
Timers:HandleEventError('Timer', k, nextCall)
end
end
end
return TIMERS_THINK
end
function Timers:HandleEventError(name, event, err)
print(err)
-- Ensure we have data
name = tostring(name or 'unknown')
event = tostring(event or 'unknown')
err = tostring(err or 'unknown')
-- Tell everyone there was an error
--Say(nil, name .. ' threw an error on event '..event, false)
--Say(nil, err, false)
-- Prevent loop arounds
if not self.errorHandled then
-- Store that we handled an error
self.errorHandled = true
end
end
function Timers:CreateTimer(name, args)
if type(name) == "function" then
args = {callback = name}
name = DoUniqueString("timer")
elseif type(name) == "table" then
args = name
name = DoUniqueString("timer")
elseif type(name) == "number" then
args = {endTime = name, callback = args}
name = DoUniqueString("timer")
end
if not args.callback then
print("Invalid timer created: "..name)
return
end
local now = GameRules:GetGameTime()
if args.useGameTime ~= nil and args.useGameTime == false then
now = Time()
end
if args.endTime == nil then
args.endTime = now
elseif args.useOldStyle == nil or args.useOldStyle == false then
args.endTime = now + args.endTime
end
Timers.timers[name] = args
return name
end
function Timers:RemoveTimer(name)
Timers.timers[name] = nil
end
function Timers:RemoveTimers(killAll)
local timers = {}
if not killAll then
for k,v in pairs(Timers.timers) do
if v.persist then
timers[k] = v
end
end
end
Timers.timers = timers
end
Timers:start()
И подключите файл через:
require ("Ваше название") //без формата: require ("timers")
В файле addon_game_mode.lua
Путь к файлу:
*:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\resource\
Файл:
addon_russian.txt
*:\steam\steamapps\common\dota 2 beta\game\dota_addons\КАРТА\resource\
Файл:
addon_russian.txt
Код:
"lang"
{
"Language" "russian"
"Tokens"
{
"DOTA_Tooltip_ability_item_sword_life_lua" "Меч повелителя теплокровных"
"DOTA_Tooltip_ability_item_sword_life_lua_Lore" "По легенде этот меч способен покарить теплокровных существ"
"DOTA_Tooltip_ability_item_sword_life_lua_bonus_dmg" "+к урону по живым"
"DOTA_Tooltip_ability_item_sword_water_lua" "Меч повелителя хладнокровных"
"DOTA_Tooltip_ability_item_sword_water_lua_Lore" "По легенде этот меч способен покарить хлоднокровных существ"
"DOTA_Tooltip_ability_item_sword_water_lua_bonus_dmg" "+к урону по амфибиям"
"DOTA_Tooltip_ability_item_sword_insects_lua" "Меч повелителя насекомых"
"DOTA_Tooltip_ability_item_sword_insects_lua_Lore" "По легенде этот меч способен покарить членистоногих"
"DOTA_Tooltip_ability_item_sword_insects_lua_bonus_dmg" "+к урону по насекомым"
"DOTA_Tooltip_ability_item_sword_death_lua" "Меч повелителя смерти"
"DOTA_Tooltip_ability_item_sword_death_lua_Lore" "По легенде этот меч способен покарить всю нечисть"
"DOTA_Tooltip_ability_item_sword_death_lua_bonus_dmg" "+к урону по мертвым"
}
}
Ссылка на первоисточник "
Пожалуйста, авторизуйтесь для просмотра ссылки.
"Спасибо за внимание :3
Последнее редактирование: