Делаем мод на спавн врагов скриптами в Fallout 4 - часть 4 - настраиваем спавн по типу локации

В этом уроке научимся скриптами определять, какой тип врагов обитает на текущей локации и подгоним спавн под них. Также выведем его в МСМ меню дроп-списком.

Делаем мод на спавн врагов скриптами в Fallout 4 - часть 4 - настраиваем спавн по типу локации

Предыдущая статья:

Добавим необходимые переменные

В позапрошлом уроке мы узнали, что в редакторе Creation Kit у каждой локации есть набор ярлыков/ключевых слов/кейвордов. Среди них есть и такие, что говорят о типе населяющих локацию противников.

Начинается с LocEnc
Начинается с LocEnc

Добавим этот и другие аналогичные кейворды в скрипт:

Scriptname KP_DES:MainQuestScript extends Quest ... Keyword Property LocEncGhouls Auto Const Keyword Property LocEncGunners Auto Const Keyword Property LocEncSuperMutants Auto Const Keyword Property LocEncSynths Auto Const Keyword Property LocEncMirelurks Auto Const Keyword Property LocEncMolerats Auto Const ...

Соответственно, добавим и ссылки на акторов для спавна, но под конец докинем переменные для транзита типа актора между функциями ActorType , для транзита ссылки на локацию CurrentLocation и переменную uiLocationEnemyType для МСМ меню. Ее используем для дроп-списка:

Scriptname KP_DES:MainQuestScript extends Quest ... ActorBase Property LvlRaider Auto Const Mandatory ActorBase Property LvlFeralGhoul Auto Const Mandatory ActorBase Property LvlGunnerMixed Auto Const Mandatory ActorBase Property LvlMirelurkAll Auto Const Mandatory ActorBase Property LvlMolerat Auto Const Mandatory ActorBase Property LvlSupermutantMixed Auto Const Mandatory ActorBase Property LvlSynth Auto Const Mandatory ActorBase ActorType = none Location Property CurrentLocation Auto Int Property uiLocationEnemyType Auto Conditional ...

После добавления новых переменных не забывайте компилировать скрипт и заполнять ссылки в Properties через кнопку Auto-Fill.

Больше заострять на этом внимания не буду.

Внесем переменные в скрипты

Поправим событие перехода между локациями. Занесем место, куда игрок переходит, в транзитную переменную и вызовем новую функцию, которую распишем ниже:

... Event Actor.OnLocationChange(Actor akSender, Location akOldLoc, Location akNewLoc) CurrentLocation = akNewLoc ;!!!!запоминаем локацию, куда перешли CheckLocEnemyType() ;!!!!добавляем новую функцию if ( akNewLoc.HasKeyword(LocTypeClearable) && !akNewLoc.IsCleared() ) int chance = Utility.RandomInt() if (setSpawnerChanceToSpawn > chance) SpawnerEligibleLoc = true else SpawnerEligibleLoc = false endif else SpawnerEligibleLoc = false endIf SpawnerAlreadySpawn = false uiSpawnerAlreadySpawn = SpawnerAlreadySpawn uiSpawnerEligibleLoc = SpawnerEligibleLoc EndEvent ...

Теперь создадим функцию CheckLocEnemyType, которая будет проверять кейворды локации, определять тип врагов на ней и заносить подходящего врага в транзитную переменную ActorType:

... Function CheckLocEnemyType() ActorType = LvlRaider uiLocationEnemyType = 0 if (CurrentLocation.HasKeyword(LocEncGhouls)) ActorType = LvlFeralGhoul uiLocationEnemyType = 1 elseif (CurrentLocation.HasKeyword(LocEncGunners)) ActorType = LvlGunnerMixed uiLocationEnemyType = 2 elseif (CurrentLocation.HasKeyword(LocEncSuperMutants)) ActorType = LvlSupermutantMixed uiLocationEnemyType = 3 elseif (CurrentLocation.HasKeyword(LocEncSynths)) ActorType = LvlSynth uiLocationEnemyType = 4 elseif (CurrentLocation.HasKeyword(LocEncMirelurks)) ActorType = LvlMirelurkAll uiLocationEnemyType = 5 elseif (CurrentLocation.HasKeyword(LocEncMolerats)) ActorType = LvlMolerat uiLocationEnemyType = 6 endif EndFunction ...

Добавим дроп-список в МСМ меню

Цифра в переменной uiLocationEnemyType нужна для дроп-списка в меню МСМ. Собственно, я сразу покажу как его оформлять. Запись дроп-листа выглядит так:

... {"text": "Тип врагов на локации", "type": "dropdown", "help": "Какой тип врагов будет спавниться в соответствии с принадлежностью локации", "valueOptions": {"sourceType": "PropertyValueInt", "sourceForm": "KP-DynamicEnemySpawner.esp|1000F99", "propertyName": "uiLocationEnemyType", "options": ["Рейдеры (или иной)", "Гули", "Стрелки", "Супермутанты", "Синты", "Болотники", "Кротокрысы"] } }, ...

Как можно догадаться, в списке options написаны по порядку тексты, соответствующие разным значениям переменной uiLocationEnemyType, начиная с 0.

Выглядеть это будет так (в синей рамке)
Выглядеть это будет так (в синей рамке)

Подобным образом можно настраивать различные переключатели параметров. Выглядит красивее, чем банальное переключение циферок.

Поправим спавнер

Напоследок, заменим в скрипте непосредственно спавна актора на транзитную переменную:

... Function SpawnActors() ... if (SpawnMarker != none) i = 1 int actorsNum = Utility.RandomInt(setSpawnerMinActors, setSpawnerMaxActors) While (i <= actorsNum) Actor a0 = SpawnMarker.PlaceActorAtMe(ActorType) as actor ;!!!! ВОТ ЗДЕСЬ Utility.Wait(0.1) a0.Moveto(SpawnMarker, Utility.RandomInt(-10, 10), Utility.RandomInt(-10, 10), abMatchRotation = true) a0.MoveToNearestNavmeshLocation() i += 1 EndWhile if (ShowDebug) debug.notification("[DES] "+ actorsNum +" actors spawned!") endif SpawnerAlreadySpawn = true uiSpawnerAlreadySpawn = SpawnerAlreadySpawn endif endif EndFunction ...

Вот и все, теперь спавниться будут не рейдеры, а подходящие по типу локации противники.

Также я снизила расстояние разброса акторов в команде a0.Moveto(SpawnMarker, Utility.RandomInt(-10, 10), Utility.RandomInt(-10, 10), abMatchRotation = true) со 100 до 10.

А то враги могли смещаться за пределы стен в некоторых локациях.

Теперь враги спавнятся, но все еще стоят на месте. Следующий шаг - заставить их куда-нибудь идти, к игроку или центру локации. Я уже затестила и внедрила это в мод, так что скоро распишу, как это делается.

4
3
1
1
1