Изменение существующих юнитов в игре это промежуточный шаг между созданием собственных миссий в MissionEditor и созданием собственных моделей на пути освоения разработки комплексных модификаций игры.
Данный метод (туториал) можно использовать для многих целей, но, как показывает практика, зачастую область его применения сводится либо к простому получению новых необычных эмоций/созданию мемов/контента, либо для тестирования внутриигровых механик.
Например, выдать какому-нибудь ОБТ лучший ОБПС и КАЗ, проверить проходимость САУ с дополнительными 4 л.с. на тонну, либо вообще, используя только существующие модели, проверить теоретическую эффективность кумулятивных ПТАБов!
Пожалуй, нужно сразу оговориться об ограничениях:
- Игра позволяет использовать игрокам кастомные юниты только с теми моделями, которые находятся в категории
gameData\units
, туда относятся модели бронетехники и модели кораблей. Так как модели авиации находятся вgamedata\flightmodels
, при попытке использования их игроком игра просто откажется запускать миссию. Впрочем, данное ограничение не касается ИИ юнитов, но целесообразность их модификации без прямого контроля над юнитом очень сомнительна. Просто запомните, это возможно, но почти бесполезно. - Также у вас не получится добавить вторую башню на однобашенный танк. Игра крайне требовательна к соблюдению иерархии модели, а также наличии DM модулей для двигателей, турелей, пушек… В лучшем случае игра просто вылетит. Так что нужно знать меру.
- И нет, как-то деформировать, изменить или удалить часть модели нельзя. Для этого есть другой метод под названием
objectgroups
иinclude
, о котором мы поговорим в другой раз. - И последнее, любые модификации, кроме пользовательских камуфляжей, прицелов и озвучек, не работают в мультиплеере. Но даже если у вас каким-то чудом получилось из запустить — это называется читерство!
Для работы понадобится
- Notepad++ — универсальный текстовый редактор, главное преимущество которого по сравнению с обычным Блокнотом — более длительная память предыдущих действий. К нему очень желательно установить простенький плагин BracketsCheck, который поможет быстро обнаружить недостающую скобку и предотвратить вылет игры.
- WT Tools от @klensy — лучший друг датамайнера, в том числе и ваш источник исходных файлов вооружения, юнитов и сенсоров.
- War-Thunder-Datamine от @gszabi99 — несмотря на отличающуюся кодировку переменных, данный репозиторий выступает в качестве поисковика множества файлов игры.
Итак, приступим. Допустим, я хочу выдать R3 T20 ленту ОБПС, дополнительные 70 л.с. и двухплоскостной стабилизатор.
Шаг первый: Получение исходного .blk юнита
Для начала, вам нужно скопировать файл aces.vromfs.bin
из папки игры, и вставить в папку с вашими WT Tools.
После декомпилировать этот файл с помощью программы aces_unpack_blk
.
Процесс занимает какое-то время, по окончанию будет создана папка aces.vromfs.bin_u
, которую уже можно использовать.
Через поисковую строку находим файл r3_t20_fa.blkx
и открываем в Notepad++. Пока на этом всё.
Шаг второй: создание .blk юнита
Так как изменять содержимое файлов игры мы не можем, нам нужен новый файл юнита. Поэтому нужно создать новый .blk в папке WarThunder\content\pkg_local\gameData\units\tankModels\userVehicles
используя любой другой доступный файл, будь то миссии, конфига или файла созданного WT Tools. Названия у файла должно быть внутриигровым идентификатором одного из резервных танков любой страны. Например, ussr_bt_7.blk
или sw_strv_m31.blk
.
Открываем новый файл в редакторе и удаляем всё содержимое. Теперь нужно скопировать всё содержимое r3_t20_fa.blkx
в новый файл. У меня это sw_strv_m31.blk
.
Шаг третий: изменяем юнит
Структура блочных файлов, используемых в игре, отличается понятностью и логичностью. Даже без изучения специальных руководств или подсказок любой пользователь с базовым знанием английского языка сможет легко разобраться, какая переменная отвечает за ту или иную функцию.
Например, легко понять, что переменная model:t=""
отвечает за используемую 3D-модель, блок VehiclePhys{}
— за физические параметры юнита, а блок cockpit{}
— за положение и характеристики камеры игрока, управляющего юнитом. Именно поэтому я не вижу смысла писать подробный справочник о сотнях переменных и функций внутри файла — уверен, что пользователь сможет разобраться во всем самостоятельно.
Итак, открываем файл юнита и ищем блок commonWeapons
. Так как у изначального юнита всего одна автопушка, блок выглядит так:
commonWeapons{ Weapon{ trigger:t="gunner0" /* Триггер. Иначе говоря кнопка выстрела. */ blk:t="gameData/Weapons/groundModels_weapons/20mm_Oerlikon_KAD_B17_user_cannon.blk" /* путь к файлу используемой автопушки. */ emitter:t="bone_gun_barrel" flash:t="emtr_gun_flame" recoilMultiplier:r=0.5 /* Множитель отдачи ствола. */ useEmitter:b=yes shellCasingEmitter:t="emtr_shell" shellCasingMesh:t="auto_cannon_cartridge_case" openHatchTime:r=0.0 /* Время открытия люка для выброса гильз; В данном примере отстутсвует. */ shellCasingLifeTime:r=5.0 shellCasingImpulse:p3=1.0, 0.0, 0.0 linkShellCasingToGun:b=yes recoilOffset:r=0.1 /* дистанция отката ствола в метрах. */ jammedReloadTime:r=15.0 /* время перезярядки в случае клина пушки. */ barrelDP:t="gun_barrel_dm" /* DM модель повреждения ствола пушки. */ breechDP:t="cannon_breech_dm" /* DM модель повреждения казенной части пушки.*/ defaultYaw:r=0.0 /* Горизонтальное положение пушки по умолчанию. */ defaultPitch:r=0.0 /* Вертикальное положение пушки по умолчанию. */ speedYaw:r=45.0 /* Горизонтальная скорость наведения пушки. */ speedPitch:r=30.0 /* Вертикальная скорость наведения пушки. */ bullets:i=600 /* Количество боеприпасов. */ fireConeAngle:r=5.0 ChainfireTime:r=0.5 DelayAfterShoot:r=2.0 accuracyAir:r=1.5 accuracyGnd:r=0.0 errMeasureVel:r=0.0 errMeasureVelFast:r=0.0 errMeasureVelFwdShift:r=1.5 errMeasureVelDir:r=0.0 errTargettingOn100kmph:r=0.0 errTargetting:r=3.0 errExplTime:r=0.0 forestallTime:r=0.1 turret{ head:t="bone_turret" gun:t="bone_gun" barrel:t="bone_gun_barrel" gunnerDm:t="gunner_dm" loaderDm:t="loader_01_dm" } limits{ yaw:p2=-180.0, 180.0 /* Горизонтальное ограничение наведения пушки. В данном примере пушка может поворачиватся на все 360 градусов. */ pitch:p2=-10.0, 60.0 /* Вертикальное ограничение наведения пушки.*/ } gunStabilizer{ hasVerticalGunFreeMode:b=no hasHorizontal:b=yes /* Наличие горизонтального стабилизатора орудия. */ horizontalOmegaMult:r=1.0 horizontalSpeedLimitKPH:r=25.0 /* Максимальная скорость работы горизонтального стабилизатора орудия в км/ч. */ hasVertical:b=yes /* Наличие вертикального стабилизатора орудия. */ verticalOmegaMult:r=1.0 verticalSpeedLimitKPH:r=25.0 /* Максимальная скорость работы вертикального стабилизатора орудия в км/ч. */ speedFromVehicleVerticalMult:r=-1.0 errorKPHToDegrees{ row:p2=5.0, 0.0 row:p2=10.0, 0.015 row:p2=15.0, 0.02 row:p2=20.0, 0.1 row:p2=25.0, 0.3 } } } hideNodes{ node:t="ex_decor_l_01" node:t="ex_decor_r_01" } } weapon_presets{ preset{ name:t="it_oto_r3_t20_fa_default" blk:t="gameData/units/tankModels/weaponPresets/it_oto_r3_t20_fa_default.blk" /* Путь к пресету вооружения. Чесно говоря файл пустой и бесполезный, но без него не работает вооружение вообще. */ } }
Приступим.
Для начала, я увеличу максимальную скорость работы стабилизатора орудия, изменив параметры horizontalSpeedLimitKPH:r
и verticalSpeedLimitKPH:r
с 25 км/ч до 125 км/ч. Готово.
Теперь об ОБПС. Я бы мог просто скопировать путь к .blk автопушки Dardo, но так как я в заголовке обещал рассказать о пользовательском вооружении, мы просто добавим в боекомплект пушки ОБПС с вдвое большей бронепробиваемостью, чем стандартный бронебойный снаряд.
Для этого, я ищу в декомпилированных файлах 20mm_Oerlikon_KAD_B17_user_cannon.blkx
, копирую содержимое в новый файл в директории WarThunder\content\pkg_local\gameData\weapons\groundmodels_weapons
под названием better_20mm.blk
и сохраняю.
Теперь открываю файл и сразу вижу несколько переменных:
cannon:b=no /* Пушка ли это? */ weaponType:i=3 /* Тип вооружения. И его приоритет использования. */ bUseHookAsRel:b=yes emitColor:p3=1.0, 1.0, 0.0 emitI:r=10.0 emitR:r=3.0 emitTime:r=0.03 aimMinDist:r=0.1 aimMaxDist:r=2000.0 maxDeltaAngle:r=0.08 /* Горизонтальный разброс. */ maxDeltaAngleVertical:r=0.08 /* Вертикальный разброс. */ shotFreq:r=16.6 /* Скорострельность в выстрелах на минуту. */ shotFreqRndK:r=0.15 traceFreq:i=3 /* Частота использования трассерных снарядов в очереди. В данном примере каждый третий выстрел будет трассерным. */ bEnablePause:b=no bullets:i=600 /* Количество снарядов. */ bulletsCluster:i=1 /* Количество снарядов за выстрел. */ reloadTime:r=7.0 /* Время перезарядки. */ bulletsCartridge:i=120 /* Количество снарядов в очереди. */ fxType:t="muzzle_ground_20mm" fxMultipleSpawn:b=yes shouldCollideWithRendinsts:b=yes sound_path:t="tanks/weapon_tanks/cannons" sound_pathStudio:t="ground/weapon/cannons" sound:t="20mm_oerlikon_kad_b17" sound_inside:t="20mm_oerlikon_kad_b17_interior" soundLoop:b=yes sfxReloadBullet:t="grd_cannon_belt_reload" isBulletBelt:b=no overheat{ /* Настройки перегрева. 9 секунд стрельбы приведут к 50% заклинивания. */ overheat:p2=4.0, 0.0 overheat:p2=6.0, 0.1 overheat:p2=9.0, 0.5 } visualOverheat{ /* Настройки визуального отображения перегретого ствола). */ shotsToMax:i=120 cooldownTime:r=8.0 cooldownDelay:r=1.8 fxType:t="smoke_overheat_med" decalOffset:p3=0.0, 0.0, 0.0 decalSize:p3=1.8, 2.2, 2.2 }
Но менять здесь мне ничего не хочется. Пока спускаюсь, нахожу снаряд с настройками, похожими на бронебойный:
bullet{ bulletCount:i=10 /* Количество снарядов в ленте. Судя по всему заглушка. */ mass:r=0.111 /* Масса снаряда. */ caliber:r=0.02 /* Калибр в метрах. В данном случае 20 мм. */ speed:r=1100.0 /* Начальная скорость в м/с. */ maxDistance:r=5000.0 /* Максимальная дистанция стрельбы. */ damageMass:r=0.077 damageCaliber:r=0.012 normalizationPreset:t="apcr" ricochetPreset:t="apcr" groundRicochetPreset:t="apcr_ground" secondaryShattersPreset:t="ap_small_arms" stabilityThreshold:r=0.05 /* Множитель стабильности и, следовательно, точности снаряда в полёте. */ stabilityCaliberToArmorThreshold:r=5.0 stabilityReductionAfterRicochet:r=0.5 stabilityReductionAfterPenetration:r=0.15 bulletType:t="apcr_t" /* Тип снаряда. */ slopeEffectPreset:t="apcr" fresnel:p3=0.23, 0.1, 2.0 shellAnimation:t="video/shells_animations/apcr_t_shell.ivf" breakingArmorThicknessEffective:b=yes breakingArmorThickness:p2=2.0, 40.0 breakingCriticalSpeed:r=700.0 breakingDistance:r=0.02 relativeVelHitShift:p2=300.0, 1000.0 relativeVelArmorShift:p2=200.0, 1000.0 selfDestructionFx:t="explosion_air_selfexplosion_small" explosionEffect:t="hit_19_27mm_metal_ap" groundCollisionEffect:t="hit_19_27mm_dirt_ap" ricochetEffect:t="hit_19_27mm_metal_ap" waterCollisionEffect:t="hit_19_27mm_water" waterRicochetEffect:t="hit_19_27mm_water" groundRicochetEffect:t="hit_19_27mm_metal_ap" stabilityRicochetModifier{ /* Множители шанса рикошета под разными углами. */ mod1:p2=0.0, 0.05 mod2:p2=20.0, 0.1 mod3:p2=30.0, 0.2 mod3:p2=45.0, 0.3 } hitpower{ /* Множитель импульса который пуля передает цели на разных дистанциях. */ HitPower0m:p2=1.0, 300.0 HitPower1000m:p2=0.7, 1000.0 HitPower1500m:p2=0.6, 1500.0 HitPower2500m:p2=0.6, 2500.0 HitPower10000m:p2=0.5, 10000.0 } damage{ kinetic{ damageType:t="generic" demarrePenetrationK:r=0.65 /* Пробиваемость снаряда при идеальных условиях в мм. Изменяется в соответствии с множеством параметров и дистанцией. */ demarreSpeedPow:r=1.43 demarreMassPow:r=0.71 demarreCaliberPow:r=1.07 } breakingScaleByArmor{ mod0:p2=5.0, 1.0 mod1:p2=10.0, 0.8 mod2:p2=40.0, 0.5 } breakingScaleByAir{ mod0:p2=0.05, 1.0 mod1:p2=0.2, 0.7 mod2:p2=0.5, 0.5 } }
Я решил изменить следующие параметры:
- Увеличил значение начальной скорости
speed:r=
до 1300 м/с; - Заменил
bulletType:t="apcr_t"
наbulletType:t="apds_fs_long_tank"
, изменив внешний вид снаряда; - И удвоил значение пробиваемости снаряда
demarrePenetrationK:r=
с 65 мм, до 130 мм:demarrePenetrationK:r=1.3
; - Теперь возвращаемся к файлу юнита, и заменяем
20mm_Oerlikon_KAD_B17_user_cannon.blk
на нашbetter_20mm.blk
; - И последнее. Находим блок
engine{}
и строчкуhorsePowers:r=95.0
, и добавляем 70 лошадиных сил к двигателю. Должно получитсяhorsePowers:r=165.0
;
Сохраняем все файлы и переходим к тестированию
Для этого можно создать новую миссию, либо использовать существующую. Об их создании можно подробнее узнать тут.
Будет, пожалуй, нелишним упомянуть, что редактор миссий даже не подозревает о существовании любых юнитов кроме официальных, так что вам всё равно придётся редактировать файл миссии вручную. Вот пример настроек юнита:
tankModels{ name:t="ultra_R3_T20" tm:m=[[1, 0, 0] [0, 1, 0] [0, 0, 1] [308.818, 156.33, 549.329]] unit_class:t="userVehicles/sw_strv_m31" /* Путь к кастомному юниту. */ objLayer:i=1 closed_waypoints:b=no isShipSpline:b=no shipTurnRadius:r=100 weapons:t="it_oto_r3_t20_fa_default" /* Файл пресета вооружения. */ bullets0:t="" bullets1:t="" bullets2:t="" bullets3:t="" bulletsCount0:i=200 /* Количество бк. */ bulletsCount1:i=0 bulletsCount2:i=0 bulletsCount3:i=0 crewSkillK:r=0 applyAllMods:b=yes props{ army:i=1 count:i=1 formation_type:t="rows" formation_div:i=3 formation_step:p2=2.5, 2 formation_noise:p2=0.1, 0.1 } way{} }
Можно тестить, наслаждайтесь!