Need help?
Create a topic in the appropriate section
Don't write everything in the chat!Take a look at the marketplace
There you can buy
everything related to game serversDon't want a ban?
Please read our rules
Don't disturb the order!Sell or buy?
Use services of the guarantor
We will make your deal safe
- 0
-
Similar Content
-
By paranoyk
©(краткая ода как я выносил себе мозг с помощью лута)
Настроить лут на сервере постарались сразу после релиза ибо многое "не там и не тут"....
Первая фигура Марлезонского балета.
Файлов которые отвечают за лут прямым и коственным образом,судя по всему мнго,но настройки которые нам доступны сосредоточены в папке mpmissions\dayzOffline.chernarusplus и mpmissions\dayzOffline.chernarusplus\db
cfglimitsdefinition.xml -файл в котором обозначены категории лута, тэги спавна, классы объектов для спавна и зоны спавна.(если я правельно понял,в информатике это называеться "заданием классов" или как то так). Даллее с чем я экспериментировал.
<category name="......."/> Спавнящийся лут имеет (а может и не иметь) определенную категорию и только одну. Сюда можно вписать свою категорию и давать её предметам.(в файле тайпс)
Тэги... в ванили
<tag name="floor"/>
<tag name="shelves"/>
<tag name="ground"/>
Лут может иметь или не иметь, для более точного "определения" что и где должно спавнится. Можно вводить свои и потом в mapgroupproto.xml вставлять в нужном мест. Если нет-спавнятся везде, если для лута есть тэг, только в тех местах где тэг присутствует .("пол"," полка","земля"-всего лишь для удобства и понимания, можно назвать тэг хоть "мистер питкин", без кирилицы ебстестенно, вводится в другом файле о чём ниже)
Классы объектов для спавна
<usage name="......."/> Стационарные объекты имеют в своём обозначении один или несколько таких классов имён. Легко можно прописать свой и дать его категории стационарных объектов или объекту. (правда уникальных объектов на карте-раз,два и обчёлся). Опять таки используется в тайпс. Лут может иметь или нет. (насчёт нескольких-не проверял, но не советую).
Прописав свой к примеру "MyBox"....и потом в mapgroupproto.xml у военных контейнеров убрав все классы и оставив только этот, в нём будут спавниться только те предметы которым вы в "тайпс" пропишите данную категорию. Так же есть на карте СЕ в виде пятен, минус в том что нанесены они небрежно, результат-спавн к примеру медпредметов в машинах и киосках больницы Черногорска. Любой объект попавший в ореол получит спавн только обозначенного ореола. (после патча 1.20 стало проблематично сразу ввести новый класс, мгновенно ломается вся экономика. Приходится несколько раз пробовать с разными именами)
Зоны спавна
<value name="....."/> Тиры и иже с ними. Глобальные зоны на карте для определения спавна. Лут может иметь несколько или ни одного. Будет спавнится только там, если не оговорено особые условия. см опис. тайпс) И как они нанесены на карту-опять таки СЕ редактор... (картинка устаревшая).
Они могут накладыватся друг на друга. Так же их можно редактировать в редакторе СЕ.
mapgrouppos.xml - Файл в котором определяться координаты точки "карты" лута для каждого обьекта.(мдя,чего я счас сморозил то)
То есть указывает спавнеру "в этой точке будет спанится лут по "сетке" из файла mapgroupproto " и если там ЕСТЬ описание. Это не место спавна лута конкретно, а место спавна массива координат по которым спавнится лут. Проще всего это понять если у вас есть нормальный маппинг со спавном....и убрать маппинг-лут будет спавнится в старых местах и даже висеть в воздухе. (получить все точки для "спавна" можно с помощью команд в init )
Пример:
<group name="Land_Misc_FeedShack" pos="80.255409 113.792282 4422.158691" rpy="-0.000000 0.000000 -70.013718" a="160.013718" />
Land_Misc_FeedShack - название обьекта из файла mapgroupproto ,его ID...Можно написать хоть "Мой генимальный спавн". И спавнер если найдёт в mapgroupproto объект с таким названием-заспавнит лут по сетке. (вот ещё способ как модифицировать спавн лута).
pos="80.255409 113.792282 4422.158691" rpy="-0.000000 0.000000 -70.013718" - координаты центра "карты" лута для этого обьекта, совпадают с координатами обьекта
формат записи X-Y-Z завал,наклон,поворот.
a="........" Вектор поворота карты лута обьекта относительно самого обьекта.
Как он определяется - экспериментально выяснил в принципе....(угол поворота объекта - 90)х(-1)...как то там ещё можно возиться переводить с +360, но я просто пишу полученное значение и всё работает.
Да-да,именно тут прописывается что в вашей точке появляется лут и если он имеет прописанную сетку лута в mapgroupproto .(имееться ввиду в оффлайн редакторе поставив "француз"-тут вы пропишите в него лут,как прописать в он-лайн сам обьект-другая история под названием "возврат водяных колонок"). Сам объект НЕ НУЖЕН даже. Он всего лишь декорация карты и для спавна ка видите НЕ НУЖЕН.
mapgroupproto.xml - Файл в котором прописана "карта" лута для объекта. Вначале идёт описание для "дефолта" ,то есть деревьев и растений,а также камней! (тут я не понял,но ...это нам и не нужно,яблоки падают и хорошо..)
Пример:
<group name="Land_Tisy_Barracks"> - название обьекта, ID ИЛИ придуманный вами обьект.
<usage name="Military" /> - класс имени обьекта,может быть не один. (а если вы ввели свои-писать именно сюда)
<container name="lootFloor" lootmax="8"> - имя "контейнера" и максимальное количество лута которое может там появиться.(количество лута может быть и не обозначено,но если есть-никогда не будет больше чем количество точек спавна что ниже. НЕ РАБОТАЕТ- можно даже не мучатся, есть подозрения что количество лута ни как не изменить именно этой переменной для обьекта. )
<category name="tools" /> - класс лута который будет спавниться в данном "контейнере" ,может быть не один.
<tag name="ground" /> - тэг лута который будет спавнится.(может быть несколько). Спавн лута с этим тэгом. Если у лута нет тэга-спавн ТОЖЕ.
<point pos="-2.429444 -3.799637 3.698242" range="1.199951" height="2.000000" flags="32" /> - точка спавна лута, расстояние по X-Y-Z от центральной точки "карты лута" (где она,можно выяснить только эксперементально для каждого обьекта или в редакторе или...с помощью мода).
range="......." радиус спавна от заданной точки, то есть в этом "круге" будет спавниться лут.(не точно,если обьект имеет большие линейные размеры-не заспанится)
height="........."-высота объекта спавна,как я понял....(не точно,если обьект имеет большие линейные размеры-не заспавнится)
flags="32" - указание что спавн лута будет на уровне земли игнорируя координаты по высоте. Грубо говоря к примеру если спавн вокруг елки рождественской -весь лут будет лежать на земле. Вокруг ёлки. Или округ "воображаемой точки", если надо.
ниже всё тоже самое, но для своего "контейнера" данном здании.То есть обьект может иметь несколько контейнеров.
</container> <container name="lootshelves" lootmax="8"> <category name="tools" /> <category name="containers" /> <category name="clothes" /> <tag name="shelves" /> <point pos="0.968751 -3.434326 7.507324" range="0.581250" height="0.532341" /> .................................................. </container> <container name="lootweapons" lootmax="8"> <category name="weapons" /> <category name="explosives" /> <point pos="3.985354 -3.434326 6.267576" range="0.478125" height="0.533684" /> ................................................... </container> </group>
cfgrandompresets.xml - Файл в котором мы найдём так называемые "грузы"-группы предметов спавнящихся в предметах,зомби и тому подобное....(судя по всему сделано для удобства)
<cargo chance="0.35" name="foodVillage"> - шанс появления и его название.
Тут маленькое отступление. Поначалу я тоже думал что это какие то проценты, да так легче воспринимать. Но таки и немного не так. Просто опишу как спавнер "думает".
"Обьект имеет спавна внутри, получаем псевдослучайное число от 0 до 1. Сравниваем. Псевдочисло больше-нет спавна, иначе-спавн есть". Будем привычно называть его "шанс" и обозначим его как проценты, но ещё раз это НЕ ПРОЦЕНТЫ в прямом смысле.
<item name="SodaCan_Cola" chance="0.11" /> - название (ID) предмета и его шанс выпадения
.......................................................................
<item name="SpaghettiCan" chance="0.11" />
<item name="BakedBeansCan" chance="0.11" />
</cargo>
То есть "груз" foodVillage может выпасть в 35% случаев, если условее истинно,то может выпасть предмет из списка с вероятностью которая задана для предмета или ,если ни один предмет не прошёл-то опять таки ничего не выпадет. Выпадает только один предмет из списка, так и не выяснил,влияет ли очерёдность списка предметов или нет. То есть возможностей настройки тут-море,кто хорошо разбираеться в теорией вероятности поймёт данный раздел влёгкую.
Дополненно. Судя по всему спавнер не перебирает все предметы,а выбирает "случайно" какой тоодин и проверяет его.
Можно создавать свои собственные "миксы"....к примеру.
</cargo> <cargo chance="1.0" name="mixOptics"> <item name="PUScopeOptic" chance="0.33" /> <item name="PSO1Optic" chance="0.33" /> <item name="HuntingOptic" chance="0.3" /> </cargo> То есть "микс" появиться стопроцентно в объекте из него может выпасть....с вероятностью 33% ...перечисленные вещи.
Важно помнить,что если размер "контейнера" маленький (к примеру мишка),то в нём ни как не заспавниться ПСО-1. Размер имеет значение.
cfgspawnabletypes.xml - Список тех вещей, "контейнеры" в которых спавняться наборы из прошлого файла.
Так же можно прописать спавн в контейнер отдельной вещи.
И самое важное!
Именно тут можно указать степень износа заспавненых вещей по отдельности, если степень износа не указана-вещь будет иметь износ зданный в файле globals.xml, это строчки:
"LootDamageMax" и "LootDamageMin" .
Но это не относится что спавнится в них, то есть наборы грузов, аттачменты и сами грузы в контейнере всегда будут "идеальны".....(но контейнером может стать и обычная вещь!)
Тут же прописывается аттачменты если они есть и вы хотите заспавнитьвещь с прикреплёным аттачем.
<type name="ammobox"> - название (ID) вещи-контейнера.
<damage min="0.0" max="0.0" /> - этой строчки может и не быть, тогда износ будет взят из "глобалс". Означает что лут будет иметь при спавне не меньше едениц урона и не больше. То есть если выствите
min=0.2 то лут всегда будет всегда иметь при спвне 20% урона. Не меньше, максимальный урон это max, поставите к примеру 0,9 то вещи даже заруиненые будут спавнится.
Пороги когда вещь считается неповреждённой,а когда поношеной и тк.дл.-в другом файле и меняется уже сервер модом.
<cargo preset="optics" /> -название набора который может появиться внутри с шансом( как было описано выше)....
........................................
<cargo preset="ammoArmy" />
</type>
То есть можно прописать несколько наборов и если из каждого заспавниться вещь,то ограничение только "размер" контейнера и вещей.
Так же тут есть наборы аттачей для зомби, о них ниже, собраны примерно также.
Вторая фигура Марлезонского балета.
<type name="ZmbM_PatrolNormal_Autumn"> <cargo preset="foodArmy" /> <cargo preset="ammoArmy" /> </type> Вот вам и первый "ходячий" контейнер.....Увеличив к примеру в cfgrandompresets.xml шанс выпадения данных наборов-получите "доставщиков пиццы на дом".
Но не в каждом зомби такой набор и опять таки,вы можете их менять,добавлять,убирать....
А так же для зомби тут прописано что них может быть одето в виде аттачей. Не все зомби такое могут,смотреть нужно по ванильным файлам.
Пример:
<type name="ZmbM_HunterOld_Winter">-наш подопытный <cargo preset="foodHermit" />-набор лута в зомби <cargo preset="toolsHermit" />-набор лута в зомби <attachments preset="glassesVillage" />-какой набор может прирепится на местоаттача (очки в данном случае) <attachments preset="hatsFarm" />-какой набор может прирепится на местоаттача (кепка в данном случае) <attachments preset="bagsHunter" />-какой набор может прирепится на местоаттача (рюкзак в данном случае) <attachments preset="vestsHunter" />-какой набор может прирепится на местоаттача (разгрузка\броник в данном случае) </type> (очки ни когда не прописывайте-не работают)
А дальше-оружие...(так,дышите глубже)
<type name="CZ61"> - ID оружия
<attachments chance="0.10"> -Шанс что на нём будет прикреплён аттачмент 10%
<item name="AK_Suppressor" chance="1.00" /> - шанс появления самого аттачмента 100%
(не факт что так и надо,просто так проще высчитыывать процент появления аттачементов на оружии)
</attachments>
<attachments chance="0.30"> -то же самое и для другого аттачмента,обратите внимание,что мы не смешиваем в одну кучу "глушители и магазины"...
<item name="Mag_CZ61_20Rnd" chance="1.00" />
</attachments>
</type>
А если хочется "АКМ" что бы мог спавниться в полном обвесе?
А легко...
<type name="AKM"> <damage min="0.0" max="0.5" /> <attachments chance="1.00"> <item name="AK_WoodBttstck" chance="0.80" /> <item name="AK_PlasticBttstck" chance="0.30" /> <item name="AK_FoldingBttstck" chance="0.40" /> </attachments> <attachments chance="1.00"> <item name="AK_WoodHndgrd" chance="0.80" /> <item name="AK_PlasticHndgrd" chance="0.30" /> <item name="AK_RailHndgrd" chance="0.10" /> </attachments> <attachments chance="0.30"> <item name="Mag_AKM_30Rnd" chance="1.00" /> </attachments> <attachments chance="0.30"> <item name="AK_Suppressor" chance="0.50" /> </attachments> Видим что он может появляться с разными прикладами, цевьями, может с глушителем или без,с магазином или без....(хотите,можете и ПСО ему прописать).
Как видитев в этом файле нет многих вещей, тут нет ни ИЖ18,ни МП133....и они,гады спавняться всегда как прописано в globals.....Стоит добавить
<type name="Izh18">
<damage min="0.0" max="0.2" />
</type>
.....и ИЖ18 будет спавниться с дамагом который вы установили!
Думаете это всё?....Индейское жилище-фигвам!
Машины!....
<type name="OffroadHatchback"> <attachments chance="1.00"> <item name="HatchbackWheel" chance="0.60" /> </attachments> <attachments chance="1.00"> <item name="HatchbackWheel" chance="0.60" /> </attachments> <attachments chance="1.00"> <item name="HatchbackWheel" chance="0.40" /> </attachments> <attachments chance="1.00"> <item name="HatchbackWheel" chance="0.40" /> </attachments> <attachments chance="1.00"> <item name="HatchbackWheel" chance="0.20" /> </attachments> <attachments chance="1.00"> <item name="CarRadiator" chance="0.20" /> </attachments> <attachments chance="1.00"> <item name="CarBattery" chance="0.30" /> </attachments> <attachments chance="1.00"> <item name="HeadlightH7" chance="0.40" /> </attachments> <attachments chance="1.00"> <item name="HeadlightH7" chance="0.40" /> </attachments> <attachments chance="1.00"> <item name="HatchbackDoors_Driver" chance="0.30" /> </attachments> <attachments chance="1.00"> <item name="HatchbackDoors_CoDriver" chance="0.30" /> </attachments> <attachments chance="1.00"> <item name="HatchbackHood" chance="0.20" /> </attachments> <attachments chance="1.00"> <item name="HatchbackTrunk" chance="0.20" /> </attachments> </type> Это он так выглядит сейчас вроде...раньше было всё намного хуже...Машина стандартно спавнилась с ОДНИМ колесом.
Можете изменить аттачментам шансы хоть до "1.00" что бы машина спавнилась сразу собранная.(залить в неё жидкости-знает Боррзик,описывал на форуме,ищите).
Правда мы подло могЁм положить в машину.....бензин,масло...можно и ремкомплект.
<attachments chance="1.00">
<item name="SparkPlug" chance="0.6" />
</attachments>
<attachments chance="1.00">
<item name="EngineOil" chance="0.5" />
</attachments>
<attachments chance="1.00">
<item name="EngineOil" chance="0.5" />
</attachments>
<attachments chance="1.00">
<item name="EngineOil" chance="0.5" />
</attachments>
(в этом же файле,ПОЗЖЕ,появились и рождественские наборы...но было уже поздно-бегемоты должны быть повешаны!)
Дальше мы можем мелочь привесть к предметам,обычно это батарейка
Но можно и "предмет в предмете"! Поле для извращений-огромно.
Как пример:
<type name="PersonalRadio"> <attachments chance="0.30"> <item name="Battery9V" chance="1.00" /> </attachments> </type> <type name="GPSReceiver"> <attachments chance="0.30"> <item name="Battery9V" chance="1.00" /> </attachments> </type> Файлы с названием по типу mapgroupcluster.xml -это тот же mapgrouppos для камней, грибов,яблок и прочего.
Глыбжее,ширее,нижее. Преходим в папку db
events.xml - файл в котором описаны "случайные" события,такие как зомби,полицейская волга, хеликраш, адми...тоесть петух!, ну и прочие коровы и звери.
Например
<event name="AnimalCow"> -название ивента. Можно прописывать свои НО! Название ивента может начинатся ТОЛЬКО строго определенно.
аnimal - события с животными.
static - для спавна статичных ивентов типа Ми-8 или дома...
item - Для различных игровых предметов,как пример в ванили - блок досток.
Infected-зомби
Trajectory - спавн грибов,ягод и прочих камней
<nominal>10</nominal> - Колличество ивентов на карту единомоментно.То есть сразу. Именно ИВЕНТОВ. Десять машин, десять СТАЙ волков, десять ТОЧЕК спавна зомби....(может и меньше если невозможно заспавнить ивент из-за других условий, к примеру наличие игрока на спавне)
<min>6</min> - минимальное количество дочерних объектов указанных в <children> в ивенте
<max>15</max> - максимальноеколичество дочерних объектов указанных в <children> в ивенте
(обычно для стай волков и прочих живых организмов)
Причем от 6 до 15 ВСЕХ вписанных <children>. А вот сколько конкретно каждого,это уже в них настраивается
<lifetime>180</lifetime> - "время жизни" события Именно СОБЫТИЯ. То есть заспавнаня ивентом машина-пока стоит на точке спавна-это СОБЫТИЕ,как только вы отехали-это уже лут и время её жизни будет считыватся с (не кночи будет помянут сей файл) тайпса.
<restock>0</restock> - на сколько будет отложен спавн ивента до номинала, когда остальные условия для начала ивента выполнены.
Думате если два хеликраша они исчезнут и заспавнятся одновременно? Ага,счасЗъ. Тут зависит от много,даже от взаимодействия с ними игрока.
<saferadius>200</saferadius> - это расстояние от позиции игрока, на котором может возникнуть это событие.(поставте для интреса 50 для зомби:)))
<distanceradius>0</distanceradius> - минимальное расстояние от другого события.(очень актульно для машин, решать вам)
<cleanupradius>0</cleanupradius> - это расстояние от позиции игрока, на котором событие исчезнет после того, как время жизни закончится. (добвлено- для хеликрашей имхо лучше ставить ОЧЕНЬ большое,с хороший километр)
<secondary>InfectedArmy</secondary> - это имя другого события, которое вы хотите вызвать одновременно с этим событием, например, чтобы вызвать зомби вокруг здания или предмета. Настраивается в дочернем событии.(можно создать свой, но смешать зомбей с волками-не получится, генетика не та)
<flags deletable="0" init_random="0" remove_damaged="1" sec_spawner="0"/> -флаги настройки
deletable 1/0 - ивент удалятеся согласно параметрам самого события или по истечению времени в тайпс (не точно)...ИМХО
init_random 1/0 - ???
remove_damaged 1/0 - будет ли событие удаляться если достигла состояния "уничтожено" или останется лежать до истечения срока события.(актуально для машин...но ТОЛЬКО НА ТОЧКЕ СПАВНА!)
sec_spawner="0" - сорри не знаю, а чего не знаю-не меняю.
<position>fixed</position>
<position>player</position> - позиция будет выбираться из зафиксированых в файле cfgeventspawns.xml или событие срабатывает "на игрока".
<limit>.......</limit> - может быть следующии
custom - относится к внешнему файлу, например, для территорий животных.
child - событие будет обращатся к атрибутам min и max каждого дочернего элемента
parent - lотносятся к минимальным и максимальным атрибутам самого события
mixed - будет учитыватся и дочерние и собсвенное min-max события
<active>1/0</active> - включение и выключение события.(Вот она кнопка!)
<children>
<child lootmax="0" lootmin="0" max="3" min="0" type="Animal_BosTaurusF_Brown"/>
lootmax="0" lootmin="0" ....если предмет имеет сетку лута или контейнер -колличество лута при спавне (а теперь фокус, если в ивенте есть <secondary> с зомбями то их колличество будет равно.... мин + макс)
max="3" min="0" ......минимальное и максимальное колличество дочерних обьектов. (к примеру-коров данного типа в стаде)
types.xml-великий и ужасный.Содержит в себе данные о всём спавнещемся луте и контейнерах (хеликраши,машины,зомби-по сути-контейнеры).
Всякий лут должен быть в этом файле иначе-нет его спавна на карте. Также и синтаксическая ошибка в этом файле приводит к исчезновению всего лута с карты.
Если из него убрать что-то,(но этот предмет останеться лежать на земле до истечения срока)....и игрок его поднимет-краш.Так что файл требует трезвого ума и терпения.
<type name="Canteen"> - Название ID предмета
<nominal>30</nominal> -номинальное колличество спавна на карте к которому стремиться "спавнер".
<lifetime>7200</lifetime> - время "лежания" предмета после спавна ( а также судя,по всему-время после падения на землю с игрока).в сек. (на параметр не влияет ускорение времени на сервере, но влияет параметр из скриптс-"колличество тактов в секунду")
<restock>0</restock> - на сколько будет отложен спавн предмета до номинала, когда остальные условия для начала спавна выполнены. "задержка спавна".
<min>20</min>- минимальное колличество предмета на карте после которого начинаеться работа спавнера.
<quantmin>-1</quantmin> - если предмет "бутылка-магазин"-степень его наполнения минимальная - Для остальных значение -1
<quantmax>-1</quantmax> - если предмет "бутылка-магазин"-степень его наполнения минимальная - Для остальных значение -1
(теперь это значение работает и для оружия у котрого нет "сьёмного" магазина, типа СКС или 133 ружжа)
<cost>100</cost> - приоритет спавна грубо говоря. чем меньше-тем ниже будет вещь в очереди.
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/> -Флаги спавнера, они указывают в каких типах объектов считать nominal и min значения:
count_in_cargo - считает все предметы в контейнерах, ящики, рюкзаки, включая автомобили
count_in_hoarder - будет считаться в таких вещах как закопанные предметы, бочки, сундуки и всевозможные палатки
count_in_map - объекты, размещенные на карте (здания)
count_in_player - внутри инвентаря игроков, исключая руки (учёт для игроков онлайн, проверяется)
crafted - указывает на то, что данный предмет может быть закрафчен игроками
deloot - указывает что это объекты для спавна на динамических ивентах (событиях). (хеликрашыи, крушения поездов, дтп и прочее)
<category name="food"/> -категория лута ,может быть ТОЛЬКО одна.
<tag name="shelves"/> - тэги для настройки точек спавна
<usage name="Military"/> - класс лута может быть не один.
<value name="Tier2"/> - Зоны в каких будет спавниться лут
<value name="Tier3"/>
<value name="Tier4"/>
</type>
Если по простому,то "фляжка" будет спавниться в колличестве 30 штук постоянно в зонах 2-3-4 на военных обектах где возможно появление еды с использованием тэга shelves, то есть если в объекте совпадает в начале описания в mapgroupproto.xml,класс,категория,тэг -то предмет заспаниться в точке спавна,которые в этом же файле,для обьекта на карте из файла mapgrouppos.xml
<type name="ACOGOptic"> <nominal>20</nominal> <lifetime>7200</lifetime> <restock>1800</restock> <min>15</min> <quantmin>-1</quantmin> <quantmax>-1</quantmax> <cost>100</cost> <flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/> <category name="weapons"/> <usage name="Military"/> </type> <type name="AgaricusMushroom"> <lifetime>900</lifetime> <flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="1" deloot="0"/> </type> как видите,есть даже грибы,которые спавняться динамически.
И на закуску...
(если вещевые или другие моды перезаписывают эти файлы,то следите за тем что бы они сливались в экстазе,а не выпихивали друг друга)
По идее-ничего сложного,даже я разобрался.....почти.
Третья фигура Марлезонского балета....
Пара примеров....
<type name="StartKitIV"> <nominal>50</nominal> <lifetime>7200</lifetime> <restock>0</restock> <min>40</min> <quantmin>-1</quantmin> <quantmax>-1</quantmax> <cost>100</cost> <flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/> <category name="tools"/> <tag name="shelves"/> <value name="Tier1"/> <value name="Tier2"/> <value name="Tier3"/> <value name="Tier4"/> </type> Это "квадратик" или....гхм!. Что видим?Лут из категории "инструменты",спавниться постоянно в местах с тэгом,по всей карте....А какой он категории?А ни какой,вот и спавниться,хоть на лодках на берегу,хоть на вышке.
Добавляем категорию...
<type name="StartKitIV"> <nominal>50</nominal> <lifetime>7200</lifetime> <restock>0</restock> <min>20</min> <quantmin>-1</quantmin> <quantmax>-1</quantmax> <cost>100</cost> <flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/> <category name="tools"/> <tag name="shelves"/> <usage name="Medic"/> <value name="Tier1"/> <value name="Tier2"/> <value name="Tier3"/> <value name="Tier4"/> </type> Всё,теперь только на обьектах с классом "медик"-как и положено. (бегемоты должны быть повешаны!)....
Обьект радиовышка,кто лазил на неё,тот помнит что на ней спавнился полецейский лут. Почему?
А смотрим mapgroupproto.xml
<group name="Land_Tower_TC1"> <usage name="Village" /> <usage name="Industrial" /> <usage name="Police" /> <container name="lootFloor"> <category name="tools" /> <category name="containers" /> <category name="clothes" /> <category name="weapons" /> <category name="books" /> <category name="explosives" /> <point pos="-0.454809 14.404877 0.712779" range="0.314223" height="0.785558" /> <point pos="-0.582537 14.404785 0.034267" range="0.375000" height="0.913483" /> <point pos="0.773581 14.405716 0.067886" range="0.375000" height="0.915054" /> <point pos="-0.448550 14.404892 1.860424" range="0.432076" height="1.080190" /> <point pos="0.641068 14.405640 1.884647" range="0.512500" height="1.279480" /> <point pos="-1.132879 -1.965958 1.837671" range="0.581250" height="1.453125" /> <point pos="0.925214 -1.964554 -0.245559" range="0.821875" height="1.996796" /> <point pos="-0.880515 -1.965805 -0.105441" range="0.821875" height="2.000610" /> <point pos="0.998695 -1.964493 1.724339" range="0.890625" height="1.996490" /> </container> Лут категории "инструмент","контейнер"...."оружие" классов ...Да,"Полиция".....Удаляем нафинг полицию!
<group name="Land_Tower_TC1"> <usage name="Village" /> <usage name="Industrial" /> <container name="lootFloor"> <category name="tools" /> <category name="containers" /> <category name="clothes" /> <category name="weapons" /> <category name="explosives" /> <point pos="-0.454809 14.404877 0.712779" range="0.314223" height="0.785558" /> <point pos="-0.582537 14.404785 0.034267" range="0.375000" height="0.913483" /> <point pos="0.773581 14.405716 0.067886" range="0.375000" height="0.915054" /> <point pos="-0.448550 14.404892 1.860424" range="0.432076" height="1.080190" /> <point pos="0.641068 14.405640 1.884647" range="0.512500" height="1.279480" /> <point pos="-1.132879 -1.965958 1.837671" range="0.581250" height="1.453125" /> <point pos="0.925214 -1.964554 -0.245559" range="0.821875" height="1.996796" /> <point pos="-0.880515 -1.965805 -0.105441" range="0.821875" height="2.000610" /> <point pos="0.998695 -1.964493 1.724339" range="0.890625" height="1.996490" /> </container> </group> Теперь в лучшем случае дробаш там будет.
Ну,как то так....
Запрещено копирование данной статьи без соглосование с Администрацией и автором на другие ресурсы. All Rights Reserved
-
By BR0wi
Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
Подскажите как удалить точки спавна лута после удаления ванильных объектов через дейз эдитор. А то гадость какая-то получается, объектов нет, а лут спавнит.
Пытался найти точки по примерным коордмнатам в файле mapgrouppos.xml, но что-то как-то не получается, да и объектов слишком много удалено, вручную так искать несколько дней уйдет. Кто-нибудь владеет информацией на этот счет?
Заранее спасибо. -
By Plut
Доброго дня!
Ув. форумчане., такая проблема: берем лут и кладем в рюкзак(любой), рюкзак кладем в спец слот для рюкзаков машины, а после РР все что было в рюкзаке вываливается на землю под машину, а сам рюкзак(который в спец слоте маашины) оказывается пуст. При этом в бочках и ящиках/сундуках все отлично сохраняется.
Может быть связанно, но когда рюкзак в машине, то в него ничего не положить(в отличии от бочек и ящиков), приходится брать его в руки, наполнять хламом и класть в специальный для него слот.
Памагити, пасиба.
-
By 123new
И так, ребятки, вот вам небольшая 'полезняшка' от меня, и совершенно бесплатно!
Описание:
Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
или создать их самим со следующим содержанием:
Script.c
/* Описание: Скрипт выдачи индивидуального стартового лута, скина игрока и точек спавна Автор: 123new Установка: 1. По пути: {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\ создать папку 'CustomSpawnPlayerConfig' и поместить в нее 3 файла скрипта: Script.c Sets.c init_mod.c 2. В файле: {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\init.c в самом верху файла добавить: #include "$CurrentDir:mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\init_mod.c" 3. В папке, обозначенной параметром запуска сервера '-profile=', поместить файл с именем CustomSpawnPlayerConfig.txt и заполнить его данными по следующему формату: UID|Skin_player|sets_numbers|points_spawns где UID - это steam64id от профиля игрока в steam Skin_player - точный id скина игрока (можно указать 0 для отключения опции) sets_numbers - номер сета со стартовым лутом (можно указать несколько через ';', указать один всего, либо указать 0 для отключения опции) points_spawns - координаты спавна игрока на карте в формате 'x y z' (можно указать несколько через ';', указать всего одну точку, либо указать 0 для отключения опции) Пример: 76561198141889254|SurvivorM_Oliver|1|12955.091797 16.115206 7993.588379 76561198141889256|SurvivorM_Oliver|1;2|14791.965820 76.481781 14041.661133;12029.079102 196.356125 7274.689941 76561198141889253|SurvivorM_Oliver|0|0 4. В файле Sets.c в папке: {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\ настроить стартовый лут для ваших игроков и написать собственные сеты ВАЖНО: количество сетов можно делать любое, номера сетов брать от 1 и выше (не должно быть -1, либо 0, только от 1 и выше) Все что укажете в блоке default будет применено для всех игроков при респавне в случае, если им не выдан никакой сет! P.S. Прикрепить к соспавненному оружию магазин не получится, рабочего кода я не смог найти!! Если у вас папка активной миссии сервера отличается от dayzOffline.chernarusplus то переименуйте ее в строке, вписываемой в: {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\init.c {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\init_mod.c */ class CustomSpawnPlayerConfig { private string Location_Directory_config = "$profile:"; // Расположение папки с конфигом скрипта private string Location_filename_config = "CustomSpawnPlayerConfig.txt"; // имя файла с конфигом скрипта private string default_log_block_name = "[CustomSpawnPlayerConfig] "; // Стандартный блок скрипта для идентификации с script.log private string disable_read_parameter = "0"; // Стандартное значение (без кавычек) для обозначения в файле конфига скрипта неиспользование параметра private string block_split_parameters_config = "|"; // Символ, обозначающий разделение параметров при чтении файла конфига private string block_split_multi_parameters_config = ";"; // Символ, обозначающий перечисление в одной ячейке параметра нескольких параметров при чтении файла конфига private bool enabled_loading_custom_spawnpoints = true; // Параметр, включающий и отключающий возможность использования приватной точки спавна для каждого игрока. В случае отключения кастомная точка спавна будет отключена для всех поумолчанию, вне зависимости от данных в конфиге! private bool enabled_loading_custom_sets = true; // Параметр, включающий и отключающий возможность использования приватного сета для каждого игроков. В случае отключения выдача сетов будет отключена для всех поумолчанию, вне зависимости от данных в конфиге, будет выдаваться только сет для всех игроков! private bool enabled_loading_custom_skins = true; // Параметр, включающий и отключающий возможность использования индивидуального стартового скина игрока для каждого игрока. В случае отключения эта возможность будет отключена для всех поумолчанию, вне зависимости от данных в конфиге! // ------------------------------------------------------------ // ---------------- NEXT CODE DON'T EDIT ----------------- // ------------------------------------------------------------ ref map<string, ref array<vector>> players_spawnpoints = new map<string, ref array<vector> >; ref map<string, ref array<int>> players_sets = new map<string, ref array<int> >; ref map<string, string> players_skins = new map<string, string>; private bool enabled_loaded_successfull_config = false; string Log_CustomSpawnPlayerConfig_GetDateTime() { private int year, month, day, hour, minute, second; GetYearMonthDay(year, month, day); GetHourMinuteSecond(hour, minute, second); string returned_message = "[" + day.ToStringLen(2) + "." + month.ToStringLen(2) + "." + year.ToStringLen(2) + " - " + hour.ToStringLen(2) + "." + minute.ToStringLen(2) + "." + second.ToStringLen(2) + "] "; return returned_message; } bool Check_coords_disable(vector coord) { private bool ret_zn = false; private float pos_x = coord[0]; private float pos_y = coord[1]; private float pos_z = coord[2]; if ((pos_x == 0.0) & (pos_y == 0.0) & (pos_z == 0.0)) { ret_zn = true; } return ret_zn; } vector Set_Read_coords_disable() { return Vector(0.0, 0.0, 0.0); } void CustomSpawnPlayerConfig() { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + "CustomSpawnPlayerConfig initialize start!"); Read_Update_Config(); } void ~CustomSpawnPlayerConfig() { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + "CustomSpawnPlayerConfig work end, class closed!"); } void Read_Update_Config() { private string name_block_work = "[ReadAndUpdateSettings] "; Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + " Started Reading config!"); private array<string> readed_lines_config = ReadFileConfig(); private bool check_normal_read = AnaliseFileConfig(readed_lines_config); if (check_normal_read) { LoadFileConfig(readed_lines_config); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "config readed successfull!"); enabled_loaded_successfull_config = true; } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "config read failed, work script disabled for players!"); enabled_loaded_successfull_config = false; } } array<string> ReadFileConfig() { private string name_block_work = "[ReadFileConfig] "; private array<string> readed_lines_config = new array<string>; readed_lines_config.Clear(); if (FileExist ( (Location_Directory_config + Location_filename_config) ) ) { private string line_content; FileHandle file = OpenFile((Location_Directory_config + Location_filename_config), FileMode.READ); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Open file config: " + (Location_Directory_config + Location_filename_config)); if (file != 0) { while ( FGets( file, line_content ) > 0 ) { readed_lines_config.Insert( line_content); } CloseFile(file); } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! CAN'T OPEN FILE CONFIG : " + (Location_Directory_config + Location_filename_config)); } //readed_lines_config.Debug(); } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! CAN'T FOUND FILE CONFIG OR DIRECTORY: " + (Location_Directory_config + Location_filename_config)); } return readed_lines_config; } bool AnaliseFileConfig(array<string> readed_lines_config) { private bool return_zn = true; private string name_block_work = "[AnaliseFileConfig] "; if (readed_lines_config.Count() > 0) { foreach (string line : readed_lines_config) { if (line.Contains(block_split_parameters_config)) { private array<string> splited_line = new array<string>; line.Split( block_split_parameters_config, splited_line ); if (splited_line.Count() == 4) { private string UID_player = splited_line.Get(0); private string default_skin_player = splited_line.Get(1); private string sets_numbers_player = splited_line.Get(2); private string points_spawn_player = splited_line.Get(3); if ((UID_player == "") || (default_skin_player == "") || (sets_numbers_player == "") || (points_spawn_player == "")) { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! Lines in Readed file is not correct, please, fix your config script!"); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Line checking: " + line); return_zn = false; break; } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! Readed file is have incorrect count parameters with a tag '" + block_split_parameters_config + "', please, fix your config script!"); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Line checking: " + line); return_zn = false; break; } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! Readed file can't have a tag '" + block_split_parameters_config + "', please, fix your config script!"); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Line checking: " + line); return_zn = false; break; } } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! Config file is empty, fix your config script!"); return_zn = false; } return return_zn; } void LoadFileConfig(array<string> readed_lines_config) { private string name_block_work = "[LoadFileConfig] "; players_spawnpoints.Clear(); players_sets.Clear(); players_skins.Clear(); foreach (string line : readed_lines_config) { private array<string> splited_line = new array<string>; splited_line.Clear(); line.Split( block_split_parameters_config, splited_line ); private string UID_player = splited_line.Get(0); private string default_skin_player = splited_line.Get(1); private string sets_numbers_player = splited_line.Get(2); private string points_spawn_player = splited_line.Get(3); private array<vector> temp_players_spawnpoints = new array<vector>; temp_players_spawnpoints.Clear(); array<int> temp_players_sets = new array<int>; temp_players_sets.Clear(); array<string> temp_players_spawnpoints_string = new array<string>; temp_players_spawnpoints_string.Clear(); array<string> temp_players_sets_string = new array<string>; temp_players_sets_string.Clear(); if (points_spawn_player.Contains(block_split_multi_parameters_config)) { points_spawn_player.Split( block_split_multi_parameters_config, temp_players_spawnpoints_string ); } else { temp_players_spawnpoints_string.Insert(points_spawn_player); } foreach (string line_spawnpoint : temp_players_spawnpoints_string) { if (line_spawnpoint == disable_read_parameter) { temp_players_spawnpoints.Insert(Set_Read_coords_disable()); } else { temp_players_spawnpoints.Insert(line_spawnpoint.ToVector()); } } Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Generated massive for " + UID_player + " with " + temp_players_spawnpoints.Count().ToString() + " spawnpoints."); if (sets_numbers_player.Contains(block_split_multi_parameters_config)) { sets_numbers_player.Split( block_split_multi_parameters_config, temp_players_sets_string ); } else { temp_players_sets_string.Insert(sets_numbers_player); } foreach (string line_set : temp_players_sets_string) { if (line_set == disable_read_parameter) { temp_players_sets.Insert(0); } else { temp_players_sets.Insert(line_set.ToInt()); } } if (default_skin_player == disable_read_parameter) { default_skin_player = "0"; } Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Generated massive for " + UID_player + " with " + temp_players_sets.Count().ToString() + " sets."); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Detected for " + UID_player + " skin " + default_skin_player); players_spawnpoints.Insert(UID_player,temp_players_spawnpoints); players_sets.Insert(UID_player,temp_players_sets); players_skins.Insert(UID_player,default_skin_player); } } vector Load_And_Check_Spawnpoints(PlayerIdentity identity, vector pos_default) { private string name_block_work = "[Load_And_Check_Spawnpoints] "; private vector retun_pos = pos_default; if(identity) { private string Name_P = identity.GetName(); private string UID_P = identity.GetPlainId(); private string Game_UID_P = identity.GetId(); private string Game_ID_P = identity.GetPlayerId().ToString(); if (enabled_loading_custom_spawnpoints) { if ((players_spawnpoints.Count() > 0) && (enabled_loaded_successfull_config)) { if (players_spawnpoints.Contains(UID_P)) { private array<vector> readed_lines_config = new array<vector>; readed_lines_config = players_spawnpoints.Get(UID_P); private vector retun_pos_check = readed_lines_config.GetRandomElement(); if (Check_coords_disable(retun_pos_check)) { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") disabled loading private spawn point. Will be used default spawn point!"); } else { retun_pos = retun_pos_check; Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") setuped private spawn point: " + retun_pos.ToString()); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Can't founded private spawnpoint for player " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Config script is incorrect, checking private spawnpoints is disabled! Player: " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "disabled loading personal spawnpoints from config file script!"); } } Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") will be used spawn point: " + retun_pos.ToString()); return retun_pos; } string Load_And_Check_SpawnSkin_Player(PlayerIdentity identity, string characterName) { private string name_block_work = "[SelectStartSkinPlayer] "; private string retun_skin = characterName; if(identity) { private string Name_P = identity.GetName(); private string UID_P = identity.GetPlainId(); private string Game_UID_P = identity.GetId(); private string Game_ID_P = identity.GetPlayerId().ToString(); if (enabled_loading_custom_skins) { if (players_skins.Count() > 0) { if (players_skins.Contains(UID_P)) { private string readed_skin = players_skins.Get(UID_P); if (readed_skin == "0") { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") disabled loading private skin setting, will be used default setting game!"); } else { retun_skin = readed_skin; Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") setuped private skin setting: " + retun_skin); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Can't founded private skin setting for player " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Config script is incorrect, checking private skin setting is disabled! Player: " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "disabled loading personal skin player settings from config file script!"); } } Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") will be used skin: " + retun_skin); return retun_skin; } void Load_And_Check_StartLoadout(PlayerBase player) { private string name_block_work = "[SelectStartSetPlayer] "; private int use_set_id = -1; private PlayerIdentity identity = player.GetIdentity(); if(identity) { private string Name_P = identity.GetName(); private string UID_P = identity.GetPlainId(); private string Game_UID_P = identity.GetId(); private string Game_ID_P = identity.GetPlayerId().ToString(); if (enabled_loading_custom_sets) { if ((players_sets.Count() > 0) && (enabled_loaded_successfull_config)) { if (players_sets.Contains(UID_P)) { private array<int> readed_lines_config = new array<int>; readed_lines_config.Clear(); readed_lines_config = players_sets.Get(UID_P); private int chek_use_set_id = readed_lines_config.GetRandomElement(); if (chek_use_set_id == 0) { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") disabled loading private set numbers. Will be used default set player! "); } else { use_set_id = chek_use_set_id; Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") setuped private set number is: " + use_set_id.ToString()); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Can't founded private sets for player " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Config script is incorrect, checking private sets is disabled! Player: " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "disabled loading personal loadout sets player settings from config file script! Will be used default loadout!"); } if (use_set_id >= 0) { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") will be used spawn set with number is: " + use_set_id.ToString()); } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") will be used spawn default start set without number. "); } StartSetsPlayers.StartSetsPlayer(player, use_set_id); } } private array<EntityAI> GetItemListinobject(PlayerBase player,EntityAI item, bool check_player) { array<EntityAI> EntityAI_list_items = new array<EntityAI>; EntityAI_list_items.Clear(); int attIdx = 0; int attCount = 0; EntityAI item_in_object; if ((player) && (check_player)) { attCount = player.GetInventory().AttachmentCount(); for (attIdx = 0; attIdx < attCount; attIdx++) { item_in_object = player.GetInventory().GetAttachmentFromIndex(attIdx); if ( item_in_object.IsItemBase() ) { EntityAI_list_items.Insert(item_in_object); } } } if ((item) && !check_player) { attCount = item.GetInventory().AttachmentCount(); for (attIdx = 0; attIdx < attCount; attIdx++) { item_in_object = item.GetInventory().GetAttachmentFromIndex(attIdx); if ( item_in_object.IsItemBase() ) { EntityAI_list_items.Insert(item_in_object); } } } return EntityAI_list_items; } void RemoveAllItems (PlayerBase player) { private array<EntityAI> ItemListPlayer = new array<EntityAI>; private array<EntityAI> ItemsForDelete = new array<EntityAI>; private EntityAI itemInHands_player = player.GetHumanInventory().GetEntityInHands(); if (itemInHands_player != NULL) { if (player.CanDropEntity(itemInHands_player) && player.GetHumanInventory().CanRemoveEntityInHands()) { // Print("ItemForDelete: " + itemInHands_player.ToString()); ItemsForDelete.Insert(itemInHands_player); } } ItemListPlayer = GetItemListinobject(player,NULL,true); if (ItemListPlayer.Count() > 0) { foreach(EntityAI ItemPlayer: ItemListPlayer) { private array<EntityAI> ItemInItemInInventory = GetItemListinobject(NULL,ItemPlayer,false); private CargoBase cargo = ItemPlayer.GetInventory().GetCargo(); if(cargo) { if (cargo.GetItemCount() > 0) { for (int f = 0; f < cargo.GetItemCount(); f++) { if(cargo.GetItem(f)) { ItemsForDelete.Insert(cargo.GetItem(f)); } } } } if (ItemInItemInInventory.Count() > 0) { foreach(EntityAI items_temp: ItemInItemInInventory) { if(items_temp) { ItemsForDelete.Insert(items_temp); } } } if(ItemPlayer) { ItemsForDelete.Insert(ItemPlayer); } } } if (ItemsForDelete.Count() > 0) { foreach(EntityAI item_temp: ItemsForDelete) { if(item_temp) { GetGame().ObjectDelete(item_temp); } } } } }; Sets.c
class StartSetsPlayersConfig { void StartSetsPlayer(PlayerBase player,int use_set_id) { EntityAI itemCreated = NULL; EntityAI itemCreated1 = NULL; ItemBase itemCasted = NULL; switch( use_set_id ) //Раздаем лут (можно использовать значения от 1 и выше, только не 0 и не -1) { case 1: //Set with number 1 (Сет с номером 1) { My_Custom_Spawn_Parameters.RemoveAllItems(player); // Чтобы удалить с персонажа уже имеющиеся стандартные стартовые шмотки раскомментировать строку itemCreated = player.GetInventory().CreateInInventory("CoyoteBag_Green"); // Выдаем рюкзак и записываем в переменную itemCreated if (itemCreated) // Проверяем, создался ли рюкзак. Если он создался, переменная itemCreated будет не пуста и проверка пройдет { SetRandomHealthItem(itemCreated); // Выдаем рюкзаку рандомное качество itemCreated1 = itemCreated.GetInventory().CreateInInventory("Apple"); // Добавляем в инвентарь созданного рюкзака яблоко и записываем в переменную itemCreated1 if (itemCreated1) // Проверяем, создалось ли яблоко в рюкзаке, яблоко у нас с переменной itemCreated1 { SetRandomHealthItem(itemCreated1); // Выдаем яблоку рандомное качество } itemCreated1 = NULL; // Обнуляем значение переменной после работы с ней, чтобы следующая проверка прошла корректно itemCreated1 = itemCreated.GetInventory().CreateInInventory("Rag"); // Выдаем игроку бинты в рюкзак и записываем в переменную itemCreated1 if (itemCreated1) // Проверяем, создались ли бинты в рюкзаке, они у нас с переменной itemCreated1 { itemCasted = ItemBase.Cast(itemCreated1); // Выполняем преобразование в другой класс для работы с нужной нам функцией, поскольку в классе EntityAI нет нужной нам функции SetQuantity, а в подклассе ItemBase она есть. Предмет при этом так и остается один и тот же! itemCasted.SetQuantity(4); // Определяем количество для созданных бинтов как 4 штуки SetRandomHealthItem(itemCreated); // Выдаем бинтам рандомное качество, функция работает с классом EntityAI (см. в конфе файла) } } // переменную itemCreated не обнуляем далее, поскольку мы ее не используем в проверке ниже. itemCreated = player.GetInventory().CreateInInventory("TTSKOPants"); // Выдаем игроку штаны itemCreated = player.GetInventory().CreateInInventory("TTsKOJacket_Camo"); // Выдаем игроку куртку itemCreated = player.GetInventory().CreateInInventory("CombatBoots_Black"); // Выдаем игроку обувь //itemCasted = ItemBase.Cast(itemCreated); // Строка не нужна, закоментирована. используется для изменения класса EntityAI в ItemBase (чтобы нужные операции были доступны) itemCreated = player.GetInventory().CreateInInventory("CombatKnife"); // Выдаем игроку ножик в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("FNX45"); // Выдаем игроку FNX в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("Mag_FNX45_15Rnd"); // Выдаем игроку магазины к FNX в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("Mag_FNX45_15Rnd"); // Выдаем игроку магазины к FNX в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("Mag_AKM_30Rnd"); // Выдаем игроку магазины к AKM в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("Mag_AKM_30Rnd"); // Выдаем игроку магазины к AKM в любой свободный слот в инвентаре itemCreated = NULL; // Обнуляем значение переменной после работы с ней, нужно если мы будем использовать ее далее itemCreated = player.GetHumanInventory().CreateInHands("akm"); // Выдаем игроку AKM в руки if (itemCreated) // Проверяем, создался ли АКМ { itemCreated.GetInventory().CreateAttachment( "PSO11Optic" ); // Выдаем игроку на AKM оптику ПСО 11 и крепим itemCreated.GetInventory().CreateAttachment( "AK_WoodBttstck" ); // Выдаем игроку на AKM цевье, приклад и глушитель, и крепим itemCreated.GetInventory().CreateAttachment( "AK_WoodHndgrd" ); // Выдаем игроку на AKM цевье, приклад и глушитель, и крепим itemCreated.GetInventory().CreateAttachment( "AK_Suppressor" ); // Выдаем игроку на AKM цевье, приклад и глушитель, и крепим } break; } case 2: //Set with number 2 (Сет с номером 2) { break; } case 3: //Set with number 3 (Сет с номером 3) { break; } case 4: //Set with number 4 (Сет с номером 4) { break; } case 5: //Set with number 5 (Сет с номером 5) { break; } case 6: //Set with number 6 (Сет с номером 6) { break; } default: //Default starting spawn set (Сет поумолчанию для всех игроков, если хотите назначить - добавляйте здесь!) { //My_Custom_Spawn_Parameters.RemoveAllItems(player); // Чтобы удалить с персонажа уже имеющиеся стандартные стартовые шмотки раскомментировать строку DefaultSets(player); // Для выдачи своих сетов по рандому всем игрокам, не прописанным в скрипте, раскомментировать эту строку break; } } } void SetRandomHealthItem(EntityAI itemCreated) // Функция генерирует и применяет для предмета рандомное значение здоровья! { if ( itemCreated ) { private int rndHlt = Math.RandomInt(55,6); itemCreated.SetHealth("","",rndHlt); } } void DefaultSets(PlayerBase player) // Функция выдает сеты игрокам, не прописанным в конфигурации скрипта!!! { EntityAI itemCreated = NULL; EntityAI itemCreated1 = NULL; ItemBase itemCasted = NULL; // ниже пример, если вам нужно задать свои точки спавна для всех игроков. Этот код можно также использовать и для каждого сета индивидуально! // Код закомментирован, если это надо - раскомментируйте! // начало кода точек спавна игрока /* private array <vector> spawnpoints = {"7500 0 7500", "7500 0 7500","7500 0 7500", "7500 0 7500"}; private vector selected_spawnpoint = spawnpoints.GetRandomElement(); player.SetPosition(selected_spawnpoint); */ // конец кода точек спавна игрока private int random_set_number = Math.RandomIntInclusive(1,6); // генерируем рандом номер сета от 1 до 6 включительно (по значениям блоков case ниже) switch( random_set_number ) //Раздаем лут (можно использовать значения от 1 и выше, только не 0 и не -1) { case 1: //Set with number 1 (Сет с номером 1) { break; } case 2: //Set with number 2 (Сет с номером 2) { break; } case 3: //Set with number 3 (Сет с номером 3) { break; } case 4: //Set with number 4 (Сет с номером 4) { break; } case 5: //Set with number 5 (Сет с номером 5) { break; } case 6: //Set with number 6 (Сет с номером 6) { break; } default: //Default starting spawn set (Сет поумолчанию для всех игроков, в случае если ни один из сетов выше не выпал. { //My_Custom_Spawn_Parameters.RemoveAllItems(player); // Чтобы удалить с персонажа уже имеющиеся стандартные стартовые шмотки раскомментировать строку break; } } } } init_mod.c
#include "$CurrentDir:mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\Script.c" #include "$CurrentDir:mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\Sets.c" ref CustomSpawnPlayerConfig My_Custom_Spawn_Parameters = new CustomSpawnPlayerConfig(); ref StartSetsPlayersConfig StartSetsPlayers = new StartSetsPlayersConfig(); modded class CustomMission { override void OnInit () { super.OnInit(); GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(My_Custom_Spawn_Parameters.Read_Update_Config, 120000, true); // Обновление настроек скрипта кастомных спавнов, 1 минута = 60000 } override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName) { pos = My_Custom_Spawn_Parameters.Load_And_Check_Spawnpoints(identity, pos); characterName = My_Custom_Spawn_Parameters.Load_And_Check_SpawnSkin_Player(identity, characterName); super.CreateCharacter(identity, pos, ctx, characterName); return m_player; } override void StartingEquipSetup(PlayerBase player, bool clothesChosen) { super.StartingEquipSetup(player, clothesChosen); My_Custom_Spawn_Parameters.Load_And_Check_StartLoadout(player); } }
2. В файле:
{папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\init.c в самом верху файла добавить:
#include "$CurrentDir:mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\init_mod.c" Чтобы получилось примерно так
3. В папке, обозначенной параметром запуска сервера '-profile=', поместить файл с именем CustomSpawnPlayerConfig.txt
и заполнить его данными по следующему формату:
UID|Skin_player|sets_numbers|points_spawns где UID - это steam64id от профиля игрока в steam
Skin_player - точный id скина игрока (можно указать 0 для отключения опции)
sets_numbers - номер сета со стартовым лутом (можно указать несколько через ';', указать один всего, либо указать 0 для отключения опции)
points_spawns - координаты спавна игрока на карте в формате 'x y z' (можно указать несколько через ';', указать всего одну точку, либо указать 0 для отключения опции)
Пример:
Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
76561198141889254|SurvivorM_Oliver|1|12955.091797 16.115206 7993.588379 76561198141889256|SurvivorM_Oliver|1;2|14791.965820 76.481781 14041.661133;12029.079102 196.356125 7274.689941 76561198141889253|SurvivorM_Oliver|0|0
4. В файле Sets.c в папке:
{папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\ настроить стартовый лут для ваших игроков и написать собственные сеты
ВАЖНО: количество сетов можно делать любое, номера сетов брать от 1 и выше (не должно быть -1, либо 0, только от 1 и выше)
Все что укажете в блоке default будет применено для всех игроков при респавне в случае, если им не выдан никакой сет!
Поумолчанию в функции default вызывается функция DefaultSets, позволяющая рандомно выбирать любой из сетов для игроков, которым сет не задан в конфигурации скрипта. Принцип составления сетов такой же, как и выше. Если будете пользоваться этим, обратите вниманием на строку:
private int random_set_number = Math.RandomIntInclusive(1,6); Эта функция генерирует число от 1 до 6 включительно. Соответственно если сетов будет больше 6, то число надо корректировать и тут тоже!
P.S. Прикрепить к соспавненному оружию магазин не получится, рабочего кода я не смог найти!!
Если у вас папка активной миссии сервера отличается от dayzOffline.chernarusplus то переименуйте ее в строке, вписываемой в:
{папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\init.c
{папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\init_mod.c
Благодарности: Товарищу Mizev за его первоначальные гайды в группе VK при появлении в сети серверной части игры
-
-
Our picks
Смотрел все темы на сайте какие находил. Смотрел вариант от ультимы на rnrportal. Ничего не работает для 1.8.7 Да, я знаю про serverPlayerlogin.sqf, но меня также интересует настройка стартового лута по уидам. Есть какой-то рабочий вариант для 1.8.7?
ESS конечно есть, но он мне не подходит. Там идёт выбор классов, а мне нужно чтобы игрок сразу спавнился с тем лутом который я прописал в файле без выбора.
Share this post
Link to post
Share on other sites