Доброго времени суток, господа мододелы, решил тут поделиться фишечкой, может кто-то это не знал, а кто-то знал и умалчивал, так вот:
Сегодня я покажу в примере, как создать свой простой/универсальный предмет сделать ему модельку когда он лежит на земле (аля рапира, ботинки и прочее), поменять предмету текстуру и как ему накинуть иконку в панели предметов, чтож начнем.
Система дропов предметов / спавна предметов позаимствована у "vulkantsk"
Возвращаемся в Hammer пробуем компилить и радуемся
Спасибо за внимание :з
Сегодня я покажу в примере, как создать свой простой/универсальный предмет сделать ему модельку когда он лежит на земле (аля рапира, ботинки и прочее), поменять предмету текстуру и как ему накинуть иконку в панели предметов, чтож начнем.
Система дропов предметов / спавна предметов позаимствована у "vulkantsk"
Идем по пути: ********\steam\steamapps\common\dota 2 beta\game\dota_addons\********\scripts\vscripts\ (вместо * ваш путь), создаем тут файлик "item_drop.lua"
В этой же папке откройте ваш "addon_game_mode.lua" и добавьте строчку: require ("item_drop") - она подключит созданный вами ранее LUA скрипт
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) Скачиваем Box.fbx <- (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) Как только подогнали хитбокс - для более точной настройки используйте значения Bounds в правой колонке
20) Сохраняем нашу готовую модель в контекстном меню нажимаем: File -> Save (ctrl+s)
20.1) Работа с моделью закончена - это то что будет выпадать на землю
20.2) Не спешите закрывать окно, оно щас пригодится чтобы сделать иконку и получить быстро материал для модели (чтоб не бегать по 100 раз в Asset Browser)
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) Скачиваем Box.fbx <- (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) Как только подогнали хитбокс - для более точной настройки используйте значения Bounds в правой колонке
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:
если не отображается просто нажми на него
- пришлось уже вставлять ссылками картинки, лимит 10 файлов (картинок)
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.2) Вставляю туда текстуру, перекрашиваю её 4.3) Сохранив новую текстуру в формате PNG | TGA | PSD | TIF
4.4) Идем обратно в окно материалов в контекстном меню нажимаем: File -> New -> Он не даст редактировать пока не сохраним! -> File -> Save As.. -> любое название для материала
4.5) Если все сделано верно, то будут доступны функции для материалов и добавление материала, нажимаем на папку для выбора Color:
4.6) В появившемся окне выбора текстуры вместо параметра: Images выбираем All Images и выбираем Вашу готовую текстуру
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"
}
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) Покажу лайфхак как замутить со своей наложенной готовой текстурой иконку для предмета:
Вот картинка без фона в более менее хорошем качестве Вот картинка как иконка с фоном - мелкие недочеты ретуши уже не видны, да и в падлу было красиво делать
ПУТЬ ДЛЯ СОХРАНЕНИЯ ИКОНОК:
ДИСК:\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"
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" "+к урону"
}
}
Спасибо за внимание :з
Последнее редактирование: