Перейти к контенту

Рекомендуемые сообщения

Кстати, в сдк при установки шейпа по умолчанию стоит сфера, а не бокс. А рестрикторы разрабы ведь именно в СДК делали, не так-ли? Сорри, что влез в беседу, просто тоже интересно стало, почему на ТЧ-уровнях черз кострища проходят ноды АИ-сетки. Ведь самый простой способ ограничить нпс от попаданий в костер - убрать оттуда аи-сетку, на ЗП и ЧН локациях именно так и сделано. Но это уже оффтоп...

Ссылка на комментарий

Clayman

Говоря о чем-то следует уточнять, если возможны разночтения. Если в SDK сферой ставится "пламя" - то нет ничего удивительного. Если спейс-рестриктор, ограничивающий кострище - то в all.spawn'е мы видим сплошные кубы ... что расходится с твоим утверждением.

Оганичивать же отсутствием AI-сетки, ИМХО, неразумно. Во-первых, костры бывают и без "бочек", т.е. просто угольки на земле и вполне можно по ним пробежаться в сапогах в пылу боя ... Во-вторых, мы тут собственно не только об оригинале говорим, и костры вполне спокойно спавнятся модмейкерами там, где им удобно. Предлагаешь ради этого перекомпилировать карты, чтобы под кострами были "дырки"?

ИМХО, т.к. костры все же не "бетонные" заглушки, следует не вырезать их из карт, а теми же скриптами, в которых имеются недоработки, избавляться от ситуаций, когда неписи лезут в костры.

 

Цель изначального поста, как раз в том, чтобы дать по-возможности информацию для применения, дабы избегать советов по удалению ограничивающих рестрикторов или подобных "вырезаний" из карт. Имея всю информацию и голову, можно найти решения/алгоритмы чтобы и избавиться от поджаривания заживо и других коллизий ...

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Artos,

Но, учитывая, что это все же не аномалия, которых немало в зоне и которым специально в модах ставится тип 0, дабы неписи в них попадались, а именно костер, который заведомо виден неписям, то значение 2 просто бы продублировало внешний ограничитель. И, учитывая эмпирические наблюдения, НПС "видит" границу рестрикторов несколько ранее, чем касается их, т.к. видно, как при своих похождениях они именно обходят зоны, а не "коснувшись" границы - начинают обход. Вот это и подразумевал под "может поменьше бы жарились", т.к. возможно "видели" бы не одно, а целых два ограничения.

Да не будут они "видеть" два, поскольку внутреннее не сработает никогда. Они вообще ничего здесь не видят, поскольку касание относится к другому типу сенсоров, тактильному, вдобавок рестриктор - вообще не сенсор, а просто тупой запрет на вход. Видеть аномалию неписи не могут хотя бы потому, что у неё нет визуала и сенсор зрения на неё не сработает.

Ну а если внутренний шейп, принадлежащий самой аномалии, никогда не сработает, то и нет смысла нагружать движок ненужными проверками. Это же не бесплатно всё, эти проверки вешаются на внутренний апдейт и подразумевают проверку попадания в данный шейп каждого непися на уровне. Не так уж мало вычислений.

 

Что касается неписей, обходящих аномалии. Лично я наблюдал картину противоположную описанной тобой: непись идёт строго по краю аномалии, а та непрерывно на него срабатывает. Непись не дохнет сразу только потому, что степень удара вроде как зависит от расстояния до центра и на краю существенно меньше.

 

Почему неписи жарятся/жарились в кострах - это отдельный разговор. Там кажется были проблемы с оффлайновым перемещением, когда они выходили в онлайн в костре, застревали в бочке и соответственно там благополучно дожаривались. Как-то так вроде, хотя на 100% не уверен.

 

А халтура (это о форме куба) - обычно делается с целью облегчения ... Но задать сферу, с ее двумя параметрами радиуса и offset'а, гораздо проще, чем четыре для куба ... тем более для пламени все одно сфера применена ... Вот это и смущает, а может есть какой-то скрытый смысл в "халтуре" разрабов? ;-)

Не боги горшки обжигают =) Сказали кому-то расставить костров на уровне и накрыть рестрикторами. Этот кто-то не заморачиваясь натыкал их за полчаса, после чего все об этом забыли. А мы тут скрытый смысл ищем.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

malandrinus

Наверное про тип 0/2 стОит прекращать, т.к. собственно информации не прибавляется.

Мною слово "видят" взято именно в кавычки и даже никак не подразумевает чего то связанного с визуалами.

А вот мои слова об эмпирическом опыте тобою проигнорированы. Приведенный тобою пример хождения по краю вполне может и быть, но и то, что поставив ограничивающий рестриктор на пути неписю, можно наблюдать как он ДО подхода к зоне начинает коректировать свой путь - это тоже имеет место быть.

Собственно мой вопрос был просто, почему там, где все одно ставится некая цифра, ставится именно 0, а не 2, что более соответствовало бы логике кодов/игры, хотя может и быть нерезультативным в итоге.

Мною было во всем моде изменено для костровых аномалий именно на 2 и давненько не видел, чтобы кто-либо загорал в кострах (хотя работает еще и схема их обхода). Только для схем с логикой kamp и walker остались огрехи ... см. ниже.

 

Ну расхожее мнение, о том, что неписи в оффлайне приходят на точку пути в центр костра и там из-за этого жарятся, не выдерживает критики (подробно со схемой кампа разбирался). Как только НПС переходит в онлайн логика схемы заставляет его выбрать точку у костра и соответственно выйти из кострища. И "бочки" в этом не помеха, т.к. НПС не замечаю бочек и походят сквозь них.

Если же логика неверна/дала сбой или модмейкер дал команду в схеме walker иль camper стоять именно в этой точке - то удивляться и плеваться игрокам стоит именно на кривые коды, а не огрехи движка/игры. Т.о. виновата именно некорректная логика, которая "замораживает" неписей в кострах. ИМХО.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Artos,

Ну расхожее мнение, о том, что неписи в оффлайне приходят на точку пути в центр костра и там из-за этого жарятся, не выдерживает критики

Я это наблюдал своими глазами, когда настроил телепорт на выход рядом с костром. Было отлично видно, как неписи разбегаются из центра костра и попутно жарятся.

 

Добавлено через 13 мин.:

Artos,

Мною слово "видят" взято именно в кавычки и даже никак не подразумевает чего то связанного с визуалами.

Это не просто слова, всё имеет значение. Настоящее "видит" может срабатывать на расстоянии. Если же не видит, а "видит", то это не понять что и не понять как работает.

Если шейп аномалии находится внутри шейпа рестриктора, то "увидеть" его невозможно никак, потому что единственный способ, чтобы непись о нём узнал - это коснуться его. Но он же внутри рестриктора, как непись его коснётся? Ну и зачем его включать тогда? Потому и выключен. Это отвечает на твой вопрос "почему не 2, а 0".

Если есть внешний рестриктор, то попасть в него снаружи непись не может никак. Эта часть сетки попросту исключена из навигации. Значит единственным способом для непися попасть внутрь - это оказаться уже внутри, что, логически рассуждая, может произойти только в момент выхода в онлайн. Почему конкретно это происходит (непись стоит в точке костра при выходе в онлайн), я на самом деле не знаю.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Ну, наверное все же разговор и сетования не о том, что "разбегаясь", неписи успевают получить некий хит от костра, а о том, что именно не разбегаются, а тупо стоят в кострах и жарятся ...

 

И, выскажу все же свою предполагалку о форме рестриктора - "куб".

Все же это похоже не халтура, а ... подстраховка. Рассуждения:

Диагональ основания рестриктора костров равна почти везде ~2.5 метра и высота ~ 1.9 метра.

Вероятно, разработчики хотели ограничивать цилиндрическую область в ~2 метра вокруг костра.

Высота же им потребовалась, чтобы неписи корректно замеряли расстояние от высоты центра своих моделей (~1.7м) до запретной границы.

Учитывая, что разница в высоте у неписей/монстров может быть от минимума (крысы/тушканы/лежачие раненые) и до ... в полный рост, то при использовании формы "сфера" с центром "у поверхности земли" для высоких возникает погрешность, т.е. граница сферы на высоте их роста отодвигается по сравнению "у ног".

Если же приподнять сферу - низкорослые объекты получат погрешность в расстоянии и могут "подползать" под сферу.

Вот за неимением цилиндра и применили куб, как более близкий к требуемым ограничениям.

В общем-то это уже из области "мелочевки", но может кому-то и будут полезным подобные частности/предположения.

 

Добавлено через 11 мин.:

malandrinus, Если шейп аномалии находится внутри шейпа рестриктора, то "увидеть" его невозможно никак, потому что единственный способ, чтобы непись о нём узнал - это коснуться его.
Не соглашусь с такой категоричностью. Конечно мы не знаем всех алгоритмов движка и вполне может быть так, как ты предполагаешь, но также может быть и то, что при движении или даже покое для неписей просчитываются некие упреждающие значения тех же вертексов и их координаты проверяются на "вхождение в запредные зоны" и, т.о. и происходит "видимость" неписями закрырых зон заранее.

Повторю все же, что не замечал чтобы неписи постоянно в игре, бежали и уперевшись в границу запретной зоны, приостанавлявались и начинали бы ее обходить ... Все гораздо плавнее и уже третий раз обращаю внимание на то, что неписями заранее (при движении по точкам) просчитывается некий маршрут и доступность пути (nearest_waypoint, nearest_accessible_vertex), а это значит что неписи могут "видеть" внутри кострового куба с диагональю в 2,4м дополнительную аномальную сферу радиусом ~0,7м. Упреждение менее чем в метр вполне даже возможно.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Есть предположение по поводу рестрикторов и как они работают. Неписи же по сетке ходят, пространство как таковое для них весьма вторично. Думаю, что рестриктор для ограничения движения скорее всего просто исключает из навигации узлы сетки, попавшие в рестриктор. Т.е. он буквально делает в AI сетке временную дыру. Это косвенно подтверждается тем, что путь сглаживается при подходе к зоне рестриктора. Тем не менее, это ничуть не мешает неписю пройти вдоль аномалии, как только он таки до неё дошёл, что может приводить к тому эффекту, который я описывал выше.

 

Это предположение можно проверить, у меня есть идея как именно. Надо будет заняться на досуге.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий
malandrinus: Если есть внешний рестриктор, то попасть в него снаружи непись не может никак. Эта часть сетки попросту исключена из навигации. Значит единственным способом для непися попасть внутрь - это оказаться уже внутри, что, логически рассуждая, может произойти только в момент выхода в онлайн. Почему конкретно это происходит (непись стоит в точке костра при выходе в онлайн), я на самом деле не знаю.
Если теория говорит об одном, а на практике имеем иное - значит или теория имеет "дырки" или практика манипулирует исключениями ...

Как раз сейчас имею сценку, когда для НПС в гулаге прописана схема kamp с центром center_point = camp_point и, при некоторых внешних раздражителях (нападение монстров, например) этот НПС порой (едко) залезает в костер и так оттуда и не вылезает. Это означает, что точки сетки внутри ограниченной зоны кострища для него все же доступны. и он в них попадает.

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

Примечательно то, что все остальные, кто может подключаться к этому же кампу, ни разу не попадали в костер. Секция "странного" НПС на базе stalker_sakharov.

 

Так же замечено, что если неписям переключить тип движения с точечного на "по путям", то через костры они вполне даже неплохо проходят и в онлайне, т.е. по узлам, которые и к кострищам/бочкам относятся и вроде как должны бы быть отключены. Хотя конечно и опалиться успевают ...

 

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

Уже пробовал реализовывать подобное и получался вполне действенный вариант, хотя с реализацией различных анимаций еще нужно бы повозиться, т.к. или начинали бешенно забрасывать куда-то в точку болты или паниковать и носиться как безумные.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

У меня есть вопрос о LW группы мод АМК.

В этом пространстве, как я могу появляться NPC мод?

Respwnen, но не раз?

У этого, но это уже verscuht программное обеспечение устанавливается только не всегда аварии и ничего в журнале

vPos = vector():set(-172.94567871094,1.1770851612091,403.09545898438)

oNpc = alife():create("mar_clear_sky_first_stalker_2", vPos,55978,3361)

local tData = net_packet_read.GetStalker(oNpc)

tData.iUpdHealth = 0

net_packet_write.SetStalker(tData, oNpc)

 

и даже здесь

 

local oIni = ini_file("spawn\\spwaner.ltx")

function spwan()

if not has_alife_info("spwan_only_one_npc") then

 

if oIni:section_exist("spawns") then

for iKey = 0, oIni:line_count("spawns") - 1 do

local bResult, sRespawn, sValue = oIni:r_line("spawns", iKey, "", "false")

if bResult and sValue == "true" and oIni:section_exist(sRespawn) then

 

local tData = {}

 

tData["RespawnSections"] = ReadLine(oIni, "String", sRespawn, "sections")

tData["MaxSpawn"] = ReadLine(oIni, "Number", sRespawn, "max_spawn", 1)

tData["MaxCount"] = ReadLine(oIni, "Number", sRespawn, "max_count", tData["MaxSpawn"])

tData["MinCount"] = ReadLine(oIni, "Number", sRespawn, "min_count", tData["MaxCount"])

tData["Conditions"] = ReadLine(oIni, "String", sRespawn, "conditions", 100)

tData["iIdleSpawn"] = ReadLine(oIni, "String", sRespawn, "idle_spawn", "medium")

tData["sLogic"] = ReadLine(oIni, "String", sRespawn, "logic", "nil")

tData["sCount"] = ReadLine(oIni, "String", sRespawn, "count", "nil")

 

local sPosition = ReadLine(oIni, "String", sRespawn, "position")

local tPos = SplitString(sPosition, 1, ",")

 

local sCustomData = "[respawn]\n" ..

"name = "..sRespawn.."\n" ..

"respawn_section = "..tData["RespawnSections"].."\n" ..

"max_spawn = "..tData["MaxSpawn"].."\n" ..

"idle_spawn = "..tData["iIdleSpawn"].."\n" ..

"conditions = "..tData["Conditions"].."\n" ..

"logic = "..tData["sLogic"].."\n" ..

"count = "..tData["sCount"]

 

local vPos = vector():set(tonumber(tPos[1]), tonumber(tPos[2]), tonumber(tPos[3]) )

local oRespawn = alife():create("respawn", vPos, tonumber(tPos[4]), tonumber(tPos[5]) )

 

tData = net_packet_read.GetStalker(oRespawn)

 

tData.tShape = {}

tData.tShape[1] = {}

tData.tShape[1].iShapeType = 0

tData.tShape[1].iRadius = 1

tData.tShape[1].vCenter = vector():set(0, 0, 0)

 

tData.sCustomData = sCustomData

 

net_packet_write.SetStalker(tData, oRespawn)

 

 

end

end

end

end

db.actor:give_info_portion("spwan_only_one_npc")

end

 

 

Я надеюсь, что вы можете помочь мне, что.

Спасибо!

 

Строгое предупреждение от модератора ColR_iT
Ведь предлагал задавал вопросы на родном языке и дополнительно перевод на русский, оба варианта пряча под спойлер. Но нет ...

За отсутствие правописания в тексте 7 суток чтения, как регулярное нарушение.

Изменено пользователем ColR_iT
Ссылка на комментарий

Ох, опять наш иностранный гость задает нам ребусы как текстом, так и погадалками ... :shok:

 

1. Что подразумевает абревиатура LW - он оставляет нам для погадалок.

2. Что за скрипты net_packet_read и net_packet_write - он нам опять предоставляет гадать.

3. Что за параметр tData.iUpdHealth в получаемом им нет-пакете предполагается и изменяется - только гадать приходится.

В известных мне скриптах работы с нет-пакетами ничего подобного не встречалось, хотя семантика названия (iUpdHealth) сильно напоминает употребляемую и мною в скриптах.

Почему тут возникают ошибки, и даже без записи в лог - только кашпировские могут ответить. Хотя ... если, не понимая что-к-чему, пытаться манипулировать скриптами - результат как раз именно аховый.

 

Использование подобного: tData = net_packet_read.GetStalker(oRespawn) - говорит только о том, что наш гость даже не микроскопом пытается гвозь забить (что в общем-то можно, если постараться), а ... гвоздем молоток пытается к стенке приколотить. :crazy:

 

olaf1, как-то не получил от Вас ответа на свой вопрос (хотя это и оффтопик): "А сколько вам лет?"

Ну а работа с нет-пакетами объектов предполагает точное знание и понимание того, что хочет сделать модмейкер.

Любые ошибки и неточности тут чреваты вылетами и битыми сэйвами.

И, Ваши попытки манипулировать на свой вкус названиями параметров в считываемых данных из нет-пакета или попытка прочитать нет-пакет от рестриктора методами 'для сталкера' - ну ни в какие ворота не лезет. Это просто абсурд.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Здрасте, помогите пожалуйста, как будит выглядеть функция создания перехода через локацию в один конец? (вызовом диолога, основа ТЧ) Я покопался тут http://antreg.ucoz.ru/forum/5-10-1 но что то непонел, прошу помогите! Очень надо!

 

Прав *Shoker*, говоря о достаточно детальном примере по указанной тобою ссылке.

Если непонятно - то и спрашивай о непонятом, а не проси чтобы повторно таким же примером пытались втолковать. --/Artos

Изменено пользователем Artos
Ссылка на комментарий

По моему там и так всё достаточно хорошо расписано. Буквально по пунктам со всеми кодами.

(Сделано только грязновато, но такой вариант проще для понимания основ, так что для тебя он даже лучше)

Если есть конкретные вопросы - задавай, а так всё у тебя перед глазами. Дальше тока готовый скрипт давать.

 

Изменено пользователем *Shoker*

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

Ссылка на комментарий
function tropa_rostok()
    -- создается переход c РОСТОКА НА АРМЕЙСКИЕ СКЛАДЫ
    if (not has_alife_info( "info_tropa_rostok" )) then
        y_level.create_level_changer(
        20017,
        vector():set( -289.735,0.099,192.842 ),
        295,
        1340,
        13812,
        1847,
        vector():set( -408.979,-13.798,400.699 ),
        vector():set( 0.0,2.0,0.0 ),
        "l07_military",
        0)
        db.actor:give_info_portion("info_tropa_rostok")
    end
end

 

Я создаю скрипт, но со своими значениями. такой Прописываю его, но ничего не_работает, или я неправильно его вписываю. Я его прописываю в файл escape_dialog.scripts в строки на выдавание оружия

--------------------------------------------------------------------------------------------------------
-- Trader
--------------------------------------------------------------------------------------------------------


function transfer_deneg(first_speaker, second_speaker)
    dialogs.relocate_money(second_speaker, 300, "in")
    dialogs.relocate_item_section(second_speaker, "detector_simple", "in")
    dialogs.relocate_item_section(second_speaker, "amk_metka", "in")
    dialogs.relocate_item_section(second_speaker, "treasure_item", "in")
end
   

function give_weapon_from_trader(trader, actor)
    dialogs.relocate_item_section(trader, "wpn_bizon", "in")
    dialogs.relocate_item_section(trader, "ammo_9x18_fmj", "in")
dialogs.relocate_item_section(trader, "ammo_9x18_fmj", "in")
dialogs.relocate_item_section(trader, "ammo_9x18_fmj", "in")
dialogs.relocate_item_section(trader, "wpn_knife", "in")
moi_mod.spawn_patefon() 
moi_mod2.spawn_patefon()  
moi_mod3.spawn_patefon()  
moi_mod4.spawn_wpn_p90()  
moi_mod5.spawn_stalker_outfit()

tropa_marsh()

    --dialogs.relocate_item_section(trader, "ammo_9x18_fmj", "in")
end

 

Изменено пользователем Artos
Ссылка на комментарий

Daniar299

Учись задавать вопросы так, чтобы тебя понимали. Твои слова о "но ничего неработает" заставляют гадать ... ничего в игре не происходит, ничего ты не видишь или вообще происходит вылет.

Приходится только предполагать:

1. Указанные тобою функции вполне рабочие и при правильном их вызове переход спавнится и на экране ты должен видеть сообщение.

2. Вероятно у тебя происходит вылет из-за недопонятой тобою фразы из источника:

2) Далее, в самый конец этого файла вписываем собственно функцию спавна перехода, которую потом надо будет вызвать либо из диалога либо из инфопоршня либо по какому-нибудь условию.

...

--Обратите внимание, что название фашего скриптового файла необходимо ставить в функцию спавна. В представленном варианте - это y_level, у Вас может быть другое имя.

Если ты вписал свою функцию tropa_rostok именно по инструкции, т.е. в конец скрипта y_level, то в твоем escape_dialog.script вызов спавна должен быть так: y_level.tropa_marsh()

Старайся не просто копировать строки и подставлять свои параметры, а понимать что означают/делают эти строки ...

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Здравствуйте. Хотел бы прояснить вот какой момент - можно ли в лист вставлять объект не в конец, а в середину. Поясняю:

Есть объект типа CUIListBox (тот же CUIListWnd только в ЗП) и нужно в его середину вставить строку с текстом. На Qt есть отличная функция insert, которой можно указать куда вставлять обьект. Однако в сталкере я такого не нашел. Может я слепой? Больно уж не хочится очищать и заного добавлять все обьекты для того чтобы вставить пару строк текста в лист.

Изменено пользователем ColR_iT

Freedom

Ссылка на комментарий

 function create_level_changer( 
p_story_id, -- STORY_ID нового level_changer (понадобится нам позже) 
p_position, -- вектор, координаты точки, в которой будет располагаться центр нового level_changer 
p_lvertex_id, -- level_vertext_id - идентифицируют уровень, на котором будет создан level_changer 
p_gvertex_id, -- game_vertext_id 

p_dest_lv, -- level_vertex_id - идентифицируют уровень, на который level_changer будет перебрасывать игрока 
p_dest_gv, -- game_vertex_id 
p_dest_pos, -- координаты точки, в которой на новом уровне окажется игрок 
p_dest_dir, -- направрение взгляда игрока 
p_dest_level, -- название уровня, например "L11_Pripyat" 
p_silent -- следует задать 1, чтобы подавить вопрос о смене уровня (автоматический переход) 
) 
local obj = alife():create("level_changer", p_position, p_lvertex_id, p_gvertex_id) 

level.map_add_object_spot(obj.id, "level_changer", "") 

local packet = net_packet() 
obj:STATE_Write(packet) 

-- свойства cse_alife_object 
local game_vertex_id = packet:r_u16() 
local cse_alife_object__unk1_f32 = packet:r_float() 
local cse_alife_object__unk2_u32 = packet:r_u32() 
local level_vertex_id = packet:r_u32() 
local object_flags = packet:r_u32() 
local custom_data = packet:r_stringZ() 
local story_id = packet:r_u32() 
local spawn_story_id = packet:r_u32() 

-- свойства cse_shape 
local shape_count = packet:r_u8() 
for i=1,shape_count do 
local shape_type = packet:r_u8() 
if shape_type == 0 then 
-- sphere 
local center = packet:r_vec3() 
local radius = packet:r_float() 
else 
-- box 
local axis_x_x = packet:r_float() 
local axis_x_y = packet:r_float() 
local axis_x_z = packet:r_float() 
local axis_y_x = packet:r_float() 
local axis_y_y = packet:r_float() 
local axis_y_z = packet:r_float() 
local axis_z_x = packet:r_float() 
local axis_z_y = packet:r_float() 
local axis_z_z = packet:r_float() 
local offset_x = packet:r_float() 
local offset_y = packet:r_float() 
local offset_z = packet:r_float() 
end 
end 

-- свойства cse_alife_space_restrictor 
local restrictor_type = packet:r_u8() 

-- свойства cse_level_changer 
local dest_game_vertex_id = packet:r_u16() 
local dest_level_vertex_id = packet:r_u32() 
local dest_position = packet:r_vec3() 
local dest_direction = packet:r_vec3() 
local dest_level_name = packet:r_stringZ() 
local dest_graph_point = packet:r_stringZ() 
local silent_mode = packet:r_u8() 

packet:w_begin(game_vertex_id) -- game_vertex_id 
packet:w_float(cse_alife_object__unk1_f32) 
packet:w_u32(cse_alife_object__unk2_u32) 
packet:w_u32(level_vertex_id) -- level_vertex_id 
packet:w_u32( bit_not(193) ) -- object_flags = -193 = 0xFFFFFF3E 
packet:w_stringZ(custom_data) 
packet:w_u32(p_story_id) -- story_id 
packet:w_u32(spawn_story_id) 

packet:w_u8(1) -- количество фигур 
-- packet:w_u8(0) -- тип фигуры: сфера 
-- packet:w_vec3(vector():set(0, 0, 0)) -- sphere_center 
-- packet:w_float(3.0) 
packet:w_u8(1) -- тип фигуры: box 
packet:w_float(2) -- axis_x_x 
packet:w_float(0) -- axis_x_y 
packet:w_float(0) -- axis_x_z 
packet:w_float(0) -- axis_y_x 
packet:w_float(4) -- axis_y_y 
packet:w_float(0) -- axis_y_z 
packet:w_float(0) -- axis_z_x 
packet:w_float(0) -- axis_z_y 
packet:w_float(4) -- axis_z_z 
packet:w_float(0) -- offset_x 
packet:w_float(0) -- offset_y 
packet:w_float(0) -- offset_z 

packet:w_u8(3) -- restrictor_type 

packet:w_u16(p_dest_gv) -- destination game_vertex_id 
packet:w_s32(p_dest_lv) -- destination level_vertex_id 
packet:w_vec3(p_dest_pos) -- destination position 
packet:w_vec3(p_dest_dir) -- destination direction (направление взгляда) 
packet:w_stringZ(p_dest_level) -- destination level name 
packet:w_stringZ("start_actor_02") -- some string, always const 
packet:w_u8(p_silent) -- 1 for silent level changing 

packet:r_seek(0) 
obj:STATE_Read(packet, packet:w_tell()) 
news_manager.send_tip(db.actor, "Новый путь", nil, nil, 20000) 
end

 

Я не совсем понимаю что надо прописывать в первые 10 строк, и ещё в какой форме это написать! и как я понимаю это оставить как есть? news_manager.send_tip(db.actor, "Новый путь", nil, nil, 20000)

 

А что тебе не понятно? Там ведь есть отличные комментарии... яснее не куда.

Для send_tip, можешь вместо текста в кавычках написать свой, можешь оставить.

И, пожалуйста, пиши в конце концов грамотнее.

ColR_iT

Изменено пользователем ColR_iT
Ссылка на комментарий

Несколько комментариев по спавну переходов (level_changer) способом by antreg (см. в вопросах от Daniar299) :

 

1. Данный способ (коды спавна) применим только для ТЧ (SoC), т.к. в ЧН/ЗП (CS/CoP) класс и формат нет-пакетов для переходов чуть изменен (добавлены параметры), что требует доработки кодов спавна.

 

2. Неудачный (ИМХО) способ задания аргументов для вызова функции спавна. Запутаться в 10-ти последовательных значениях немудрено новичкам. Да и применение комментование непосредственно в строках вызова функции - сбивает несколько с толку необычностью записи. Ниже приведен способ, который эквивалентен исходному, и хоть как-то повышает читаемость кода.

 

3. Излишние коды чтения несуществующих (cse_shape) и невостребованных (cse_level_changer) параметров свеже-заспвненного перехода.

вполне достаточно только считать начальную часть пакета (cse_alife_object).

 

4. Отсутствует возможность задать "точку возврата" (pt_move_if_reject), т.е. точку, в которую отбрасывается актор при отказе в диалоге перехода, что может приводить к зацикливаниию при отказах.

 

5. Для тех, кто использует коды записи в нет-пакет, следует учесть смысловую ошибку применения начального packet:w_begin(game_vertex_id). В данном случае для записи game_vertex_id следует использовать метод w_u16 (запись двух байт), а не метод записи заголовка пакета, который должен (хотя и не обязательно) идти в самом начале.

 

В итоге, подчищенная и немного подправленная аналогичная функция для y_level.script может выглядеть так:

function create_level_changer(...)
  local arg = {...}
  --[[
  arg[1] --/ story_id нового level_changer (понадобится нам позже)
  arg[2] --/ position (вектор), координаты точки, в которой будет располагаться центр нового level_changer
  arg[3] --/ level_vertext_id - идентифицируют уровень, на котором будет создан level_changer
  arg[4] --/ game_vertext_id
  
  arg[5] --/ destination level_vertex_id  - идентифицирует вертекс, на который level_changer будет перебрасывать игрока
  arg[6] --/ destination game_vertex_id - идентифицирует уровень, на который level_changer будет перебрасывать игрока
  arg[7] --/ destination_pos, координаты точки, в которой на новом уровне окажется игрок
  arg[8] --/ destination_dir, направление взгляда игрока
  arg[9] --/ destination_level, название уровня, например "L11_Pripyat"
  arg[10] --/ silent_mode, чтобы подавить вопрос о смене уровня следует задать 1 (автоматический переход)
  --]]
  
  local obj = alife():create("level_changer", arg[2], arg[3], arg[4]) --/ спавн перехода
  
  local pk = net_packet()
  obj:STATE_Write(pk) --/ чтение: запись в нет-пакет данных объекта
  --/ читаем из нет пакета свойства cse_alife_object
  local game_vertex_id  = pk:r_u16()
  local distance        = pk:r_float()
  local direct_control  = pk:r_u32()
  local level_vertex_id = pk:r_u32()
  local object_flags    = pk:r_u32()
  local custom_data     = pk:r_stringZ()
  local story_id        = pk:r_u32()
  local spawn_story_id  = pk:r_u32()
  --/ пишем 'заголовок' нет-пакета (2 байта)
  pk:w_begin(0) --/ installation in the package beginning
  --/ пишем в нет пакет cse_alife_object:
  pk:w_u16    (game_vertex_id)
  pk:w_float  (distance)
  pk:w_u32    (direct_control)
  pk:w_u32    (level_vertex_id)
  pk:w_u32    (object_flags)
  pk:w_stringZ(custom_data) --/ "[pt_move_if_reject]\npath = "..path
  pk:w_u32    (arg[1] or story_id) --/ заменяем!
  pk:w_u32    (spawn_story_id)
  --/ пишем свои данные:
  --/ свойства cse_shape
  pk:w_u8(1) --/ количество фигур
  --[[
  pk:w_u8(0) --/ тип фигуры: сфера (sphere)
  pk:w_vec3(vector():set(0,0,0)) --/ center
  pk:w_float(3.0) --/ radius
  --]]
  pk:w_u8(1) --/ тип фигуры: box
  pk:w_vec3(vector():set(3,0,0)) --/ axis_x (ширина)
  pk:w_vec3(vector():set(0,4,0)) --/ axis_y (высота)
  pk:w_vec3(vector():set(0,0,3)) --/ axis_z (глубина)
  pk:w_vec3(vector():set(0,0,0)) --/ offset (смещение)
  --/ свойства cse_alife_space_restrictor
  pk:w_u8(3) --/ restrictor_type (RestrictorTypeNone)
  --/ свойства cse_level_changer
  pk:w_u16(arg[6])               --/ destination game_vertex_id
  pk:w_s32(arg[5])               --/ destination level_vertex_id
  pk:w_vec3(arg[7])              --/ destination position
  pk:w_vec3(arg[8])              --/ destination direction (направление взгляда)
  pk:w_stringZ(arg[9])           --/ destination level name
  pk:w_stringZ("start_actor_02") --/ some string, always const
  pk:w_u8(arg[10] or 0)          --/ silent_mode, 1 for silent level changing
  if script_server_object_version() >= 8 then --/ for CS&CoP
    pk:w_bool(true) --/ enabled
    pk:w_stringZ("level_changer_invitation") --/ hint
  end
  pk:r_seek(2) --/ установка чтения нет-пакета в начало данных
  obj:STATE_Read(pk, pk:w_tell()-2) --/ запись: считываем в объект данные из нет-пакета
  --/ ставим метку и сообщаем о создании
  level.map_add_object_spot(obj.id, "level_changer", "")
  news_manager.send_tip(db.actor, "Новый путь", nil, nil, 20000)
end

- совместима и с прежним вариантом и с версиями для CS/CoP.

 

Ну а для более гибкого спавна, т.е. с заданием любого требуемого параметра, напомню о существовании универсальных читалок-писалок нет-пакетов объектов в игре.

Например, при использовании ранее тут упоминавшегося m_netpk.script спавн перехода для Daniar299 выглядел бы примено так:

function Tropa_Rostok()
  local story_id = 20017
  if not alife():story_object(story_id) then
    local position,lvid,gvid = vector():set(-289.735,0.099,192.842), 295, 1340 --/ координаты перехода
    local soLvChg = alife():create("level_changer", position, lvid, gvid) --/ спавн перехода
    local pk = get_netpk(soLvChg) --/ запрос нет-пакета
    if pk:isOk() then --/ получен доступ к нет-пакету объекта?
      local data = pk:get() --/ читаем данные из нет-пакета
      data.story_id             = story_id
      --data.shapes:addSphere(3) --/ задаем форму сферы радиусом в 3м
      data.shapes:addBox(vector():set(3,0,0),vector():set(0,5,0),vector():set(0,0,3),vector():set(0,0,0))
      data.restrictor_type      = 3 --/ RestrictorTypeNone
      data.dest_level_name      = "l07_military"
      data.dest_game_vertex_id  = 1847
      data.dest_level_vertex_id = 13812
      data.dest_position        = vector():set(-408.979,-13.798,400.699)
      data.dest_direction       = vector():set(0.0,2.0,0.0)
      data.dest_graph_point     = 'start_actor_02'
      data.silent_mode          = 0
      --data.custom_data:setString("[pt_move_if_reject]\npath = "..path) --/ "точка возврата"
      pk:set(data) --/< запись в нет-пакет
      level.map_add_object_spot(obj.id, "level_changer", "")
      news_manager.send_tip(db.actor, "На Склады", nil, nil, 20000)
    end
  end
end

 

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий
function Tropa_Rostok()
  local story_id = 20017
  if not alife():story_object(story_id) then
    local position,lvid,gvid = vector():set(-253.30751037598,-19.407945632935,-154.47235107422),8672,8 --/ координаты перехода
    local soLvChg = alife():create("level_changer", position, lvid, gvid) --/ спавн перехода
    local pk = get_netpk(soLvChg) --/ запрос нет-пакета
    if pk:isOk() then --/ получен доступ к нет-пакету объекта?
      local data = pk:get() --/ читаем данные из нет-пакета
      data.story_id             = story_id
      --data.shapes:addSphere(3) --/ задаем форму сферы радиусом в 3м
      data.shapes:addBox(vector():set(3,0,0),vector():set(0,5,0),vector():set(0,0,3),vector():set(0,0,0))
      data.restrictor_type      = 3 --/ RestrictorTypeNone
      data.dest_level_name      = "marsh"
      data.dest_game_vertex_id  = 9
      data.dest_level_vertex_id = 6344
      data.dest_position        = vector():set(-259.36654663086,-18.755743026733,-160.60395812988)
      data.dest_direction       = vector():set(0.0,2.0,0.0)
      data.dest_graph_point     = 'start_actor_02'
      data.silent_mode          = 0
      --data.custom_data:setString("[pt_move_if_reject]\npath = "..path) --/ "точка возврата"
      pk:set(data) --/< запись в нет-пакет
      level.map_add_object_spot(obj.id, "level_changer", "")
      news_manager.send_tip(db.actor, "На Болота", nil, nil, 20000)
    end
  end
end

 

Я изменил под себя, но последовал вылет

Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: .... - shadow of chernobyl2\gamedata\scripts\amk.script:832: attempt to index global 'escape_dialog' (a nil value)

 

Вот те строчки, не понимаю что тут не хватает?

function on_item_take(obj)
    [b]escape_dialog.have_a_art()[/b]
    flamethrower.have_a_fire_kolobok()
    flamethrower.have_a_trubki()
    flamethrower.have_a_manometr()
    flamethrower.have_a_vodko()
    flamethrower.have_a_gorelka()
    
    remove_spot_from_map(obj:id(),"red_location")
    mod_call("check_usable_item",obj)
end

 

Вылет был при начале новой игры!

Изменено пользователем ColR_iT
Ссылка на комментарий

Daniar299,

научись уже наконец юзать такую прогу как Script Syntax Checker на предмет нахождения ошибок в скриптах. ;)

Ссылка на комментарий

У меня есть вопрос

Почему только gespwant мой NPC, когда я рядом с его spawnpoints?

это мой сценарий, и у меня есть два сценария из другого упаковщик LW MOD

Я надеюсь, что рукоять далее

local oIni = ini_file("respawn\\respwaner.ltx")
function Init()
    if not has_alife_info("spwan_npc") then
        
    if oIni:section_exist("respawns") then
        for iKey = 0, oIni:line_count("respawns") - 1 do
            local bResult, sRespawn, sValue = oIni:r_line("respawns", iKey, "", "false")
            if bResult and sValue == "true" and oIni:section_exist(sRespawn) then
    
                local tData = {}
    
                tData["RespawnSections"] = ReadLine(oIni, "String", sRespawn, "sections")                
                tData["MaxSpawn"] = ReadLine(oIni, "Number", sRespawn, "max_spawn", 1)
                tData["MaxCount"] = ReadLine(oIni, "Number", sRespawn, "max_count", tData["MaxSpawn"])
                tData["MinCount"] = ReadLine(oIni, "Number", sRespawn, "min_count", tData["MaxCount"])
                tData["Conditions"] = ReadLine(oIni, "String", sRespawn, "conditions", 100)    
                tData["iIdleSpawn"] = ReadLine(oIni, "String", sRespawn, "idle_spawn", "medium")
                tData["sLogic"] = ReadLine(oIni, "String", sRespawn, "logic", "nil")
                tData["sCount"] = ReadLine(oIni, "String", sRespawn, "count", "nil")

                local sPosition = ReadLine(oIni, "String", sRespawn, "position")
                local tPos = SplitString(sPosition, 1, ",")
                
                local sCustomData = "[respawn]\n" ..
                    "name = "..sRespawn.."\n" ..
                    "respawn_section = "..tData["RespawnSections"].."\n" ..
                    "max_spawn = "..tData["MaxSpawn"].."\n" ..
                    "idle_spawn = "..tData["iIdleSpawn"].."\n" ..
                    "conditions    = "..tData["Conditions"].."\n" ..
                    "logic = "..tData["sLogic"].."\n" ..
                    "count = "..tData["sCount"]

                local vPos = vector():set(tonumber(tPos[1]), tonumber(tPos[2]), tonumber(tPos[3]) )
                local oRespawn = alife():create("respawn", vPos, tonumber(tPos[4]), tonumber(tPos[5]) ) 

                tData = net_packet_read.GetRespawn(oRespawn)    
                
                tData.tShape = {}
                tData.tShape[1] = {}
                tData.tShape[1].iShapeType = 0
                tData.tShape[1].iRadius = 1
                tData.tShape[1].vCenter = vector():set(0, 0, 0)
                
                tData.sCustomData = sCustomData        
            
                net_packet_write.SetRespawn(tData, oRespawn)    

                se_respawn.RegisterInit(oRespawn)
                se_respawn.spawnAction(oRespawn:name() )
                end
            end
        end
    end

db.actor:give_info_portion("spwan_npc")
end

 

local tIdlePreset = {
    ["seldom"]    = 900,
    ["medium"]    = 700,
    ["often"]     = 300
}

local i,k,v = 0,0,0

local tRespawners         = {}
local tRespawnersParent = {}


class "se_respawn" (cse_alife_smart_zone)
function se_respawn:__init(section) super(section)
    self.tSpawnObject     = {}    
    self.tSpawnProp     = {}
    self.oRespawnTime = game.CTime()
end


function se_respawn:STATE_Write( packet )
    cse_alife_smart_zone.STATE_Write( self, packet )
    utils.w_CTime(packet, self.oRespawnTime)
    
    local iTableSize = table.getn(self.tSpawnObject)
    packet:w_u8(iTableSize)    
    for i = 1, iTableSize do
        packet:w_u16(self.tSpawnObject[i])
    end
end


function se_respawn:STATE_Read( packet, size )
    cse_alife_smart_zone.STATE_Read( self, packet, size )    
    if editor() then
        return
    end
    
    self.oRespawnTime = utils.r_CTime(packet)
    local iTableSize = packet:r_u8()
    for i = 1, iTableSize do
        table.insert(self.tSpawnObject, packet:r_u16())
    end    
end

function se_respawn:on_register()
    cse_alife_smart_zone.on_register(self)
    RegisterInit(self)
end


function se_respawn:update()
    cse_alife_smart_zone.update(self)
    self:execute()
end


function se_respawn:execute()
    if self.iIdleSpawn == -1 then 
        return 
    end    

    if self.oRespawnTime > game.get_game_time() then
        return
    end
    
    local oIdleTime = game.CTime()
    oIdleTime:setHMSms(0,0,0, self.iIdleSpawn * math.random(1, 2) * 600)
    self.oRespawnTime = game.get_game_time() + oIdleTime        
    self:UpdateObject()

    local sProbability = xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.aConditions)
    if not sProbability or tonumber(sProbability) == 0 then 
        sim_statistic.respawn_enabled(self, false)
        return 
    end
    sim_statistic.respawn_enabled(self, true)

    if table.getn(self.tSpawnObject) < self.iMinCount then        
        while table.getn(self.tSpawnObject) < self.iMinCount do
            if self:CreateObject(100) == false then
                return
            end
        end    
        return
    end
        

    for i = 1, self.iMaxSpawn do        
        if self.iMaxCount ~= -1 and self.iMaxCount < #self.tSpawnObject then 
            return 
        end
        if self.tCount then
            for iKey, tRespawn in pairs(self.tSectionsToRespawn) do
                local iCount = self.tCount[iKey] or 1
                printf("Респавн: "..tostring(self.sName)..": "..tRespawn.section.." - "..iCount)
                
                for i = 1, iCount do
                    self:CreateObject(sProbability, tRespawn.section)
                end
            end    
        else
            if self:CreateObject(sProbability) == false then 
                return 
            end
        end
    end    
end


function se_respawn:UpdateObject()
    for k,v in pairs(self.tSpawnObject) do
        local obj = level.object_by_id(v)    
        if obj == nil then obj = alife():object(v) end    

        if obj == nil or ((IsStalker(obj) or IsMonster(obj)) and (obj:alive()~=true)) then
            table.remove(self.tSpawnObject, k)
        end
    end
end


function se_respawn:CreateObject(sProbability, sSpawnSection)
    if math.random(100) > tonumber(sProbability) then
        return
    end    
        
    local iSum = 0

    if not sSpawnSection then    
        for k,v in pairs(self.tSectionsToRespawn) do
            iSum = iSum + v.probability
        end
        
        iSum = math.random(0, iSum)
        for k,v in pairs(self.tSectionsToRespawn) do
            iSum = iSum - v.probability            
            if iSum <= 0 then
                sSpawnSection = v.section
                break
            end
        end
    end
    
    if sSpawnSection == nil then return false end        
    
    if self.iParent then
        local oParent = alife():story_object(self.iParent)
        if oParent == nil then
            abort("SPAWNING [%s], cant find parent with SID [%s]", self:name(), self.iParent)
            return
        end

        if oParent.id and self.bItemSpawn then
            local oItem = alife():create(sSpawnSection,    
                self.position,
                self.m_level_vertex_id,    
                self.m_game_vertex_id,
                oParent.id)                        
            table.insert(self.tSpawnObject, oItem.id)
            return true
        end
    else
        local oCreature = alife():create(sSpawnSection,    
            self.position,
            self.m_level_vertex_id,    
            self.m_game_vertex_id)    
        
        if self.sName==nil then
            if self.tSpawnProp[sSpawnSection].isCheck == true then
                oCreature:brain():update()
                local iSmartTerrainID = oCreature:smart_terrain_id()            
                if iSmartTerrainID ~= 65535 then        
                    table.insert(self.tSpawnObject, oCreature.id)
                    return true
                else
                    alife():release(oCreature, true)
                    return false
                end
            end                        
            table.insert(self.tSpawnObject, oCreature.id)
            return true
        else    
            if self.sLogic ~= "nil" then
                if IsMonster(oCreature) then
                    local tData = net_packet_read.GetMonster(oCreature)                    
                    tData.sCustomData = "[logic]\ncfg = scripts\\"..self.sLogic..".ltx" 
                    net_packet_write.SetMonster(tData, oCreature)
                elseif IsStalker(oCreature) then    
                    local tData = net_packet_read.GetStalker(oCreature)
                    tData.sCustomData = "[logic]\ncfg = scripts\\"..self.sLogic..".ltx" 
                    net_packet_write.SetStalker(tData, oCreature)
                end
            end
            table.insert(self.tSpawnObject, oCreature.id)
            return true
        end
    end
end


function RegisterInit(oRespawn)
    local ini = oRespawn:spawn_ini()
    if not ini:section_exist("respawn") then return    end

    oRespawn.tSectionsToRespawn  = readSpawns(ini, "respawn", "respawn_section", oRespawn.tSpawnProp)    
    if oRespawn.tSectionsToRespawn == nil then
        abort("RESPAWN: [%s] field 'respawn_section' doesn't exist.", tostring(oRespawn:name()))
    end    

    oRespawn.sLogic = ReadLine(ini, "String", "respawn", "logic")    
    oRespawn.sName = ReadLine(ini, "String", "respawn", "name")
    oRespawn.iMinCount =  ReadLine(ini, "Number", "respawn", "min_count",  0)
    oRespawn.iMaxCount =  ReadLine(ini, "Number", "respawn", "max_count", -1)
    oRespawn.iMaxSpawn =  ReadLine(ini, "Number", "respawn", "max_spawn",  1)
    oRespawn.iIdleSpawn = ReadLine(ini, "String", "respawn", "idle_spawn", "medium")
    oRespawn.sCond = ReadLine(ini, "String", "respawn", "conditions", 100)
    oRespawn.aConditions = xr_logic.parse_condlist(oRespawn, "respawn", "conditions", oRespawn.sCond)
    oRespawn.iParent =  ReadLine(ini, "Number", "respawn", "parent", nil)
    oRespawn.bItemSpawn = ReadLine(ini, "Boolean", "respawn", "item_spawn", false)

    local sCount = ReadLine(ini, "String", "respawn", "count", "nil")
    if sCount ~= "nil" then
        oRespawn.tCount = SplitString(sCount, 1, ",")
    end
    
    if oRespawn.iMinCount > oRespawn.iMaxCount and oRespawn.iMaxCount ~= -1 then
        abort("RESPAWN: [%s] min_count > max_count", oRespawn:name())
    end
    if tIdlePreset[oRespawn.iIdleSpawn] ~= nil then
        oRespawn.iIdleSpawn = tIdlePreset[oRespawn.iIdleSpawn]
    else
        oRespawn.iIdleSpawn = tonumber(oRespawn.iIdleSpawn)
        if oRespawn.iIdleSpawn == nil then
            abort("RESPAWN: [%s] 'idle_spawn' doesn't exist.", oRespawn:name())
        end
    end
    
    tRespawners[oRespawn:name()] = oRespawn
    if oRespawn.iParent ~= nil then
        tRespawnersParent[oRespawn.iParent] = oRespawn
    end

    sim_statistic.register_respawn(oRespawn)
end


function spawnAction(name)
    local myRespawn = tRespawners[name]
    if myRespawn == nil then
        return
    end
        
    local sProbability = xr_logic.pick_section_from_condlist(db.actor_proxy, myRespawn, myRespawn.aConditions)
    for i = 1, myRespawn.iMaxSpawn do        
        if myRespawn.iMaxCount ~= -1 and table.getn(myRespawn.tSpawnObject) >= myRespawn.iMaxCount then
            return
        end
        if myRespawn.tCount then
            for iKey, tRespawn in pairs(myRespawn.tSectionsToRespawn) do
                local iCount = myRespawn.tCount[iKey] or 1
                printf(tostring(myRespawn.sName)..": "..tRespawn.section.." - "..iCount)
                
                for i = 1, iCount do
                    myRespawn:CreateObject(sProbability, tRespawn.section)
                end
            end                
            StartTime(myRespawn)
            
            return
        end
        
        if myRespawn:CreateObject(sProbability) == false then
            return
        else
            StartTime(myRespawn)
        end
    end    
end

function StartTime(myRespawn)
    local oIdleTime = game.CTime()
    oIdleTime:setHMSms(0,0,0, myRespawn.iIdleSpawn * math.random(1, 3) * 600)
    myRespawn.oRespawnTime = game.get_game_time() + oIdleTime
end

function parse_names(s)
    local t = {}
    for sName in string.gfind(s, "([%w_%-.\\]+)%p*") do
        table.insert(t, sName)
    end
    return t
end


function readSpawns(spawn_ini, section, line, tSpawnProp)
    if spawn_ini:line_exist(section, line) then            
        local tRetTable = {}
        local aTableSpawn = parse_names(spawn_ini:r_string(section, line))    
        local iCount = table.getn(aTableSpawn)            
        local k = 1        
        while k <= iCount do            
            local tSpawn = {}
            tSpawn.section = aTableSpawn[k]

            if aTableSpawn[k+1] ~= nil then
                local p = tonumber(aTableSpawn[k+1])
                if p then
                    tSpawn.probability = p
                    k = k + 2
                else
                    tSpawn.probability = 1
                    k = k + 1
                end
            else
                tSpawn.probability = 1
                k = k + 1
            end
            table.insert(tRetTable, tSpawn)    
            if tSpawnProp[tSpawn.section] == nil then        
                local respawn_ini = system_ini()
                local sCommunity     = ReadLine(respawn_ini, "String", tSpawn.section, "community", "nil")
                local sRank         = ReadLine(respawn_ini, "String", tSpawn.section, "spec_rank", "nil")
                local isCheck         = true
                local sCustomData     = ReadLine(respawn_ini, "String", tSpawn.section, "custom_data")        
                if sCustomData ~= nil then
                    local iniCustomData = ini_file(sCustomData)            
                    if iniCustomData:section_exist("smart_terrains") then                    
                        if iniCustomData:line_exist("smart_terrains", "none") then
                            if ReadLine(iniCustomData, "String", "smart_terrains", "none") == "true" then
                                isCheck = false
                            end    
                        end                    
                        if iniCustomData:line_exist("smart_terrains", "respawn_check") then
                            if ReadLine(iniCustomData, "String", "smart_terrains", "respawn_check") == "false" then
                                isCheck = false
                            end
                        end             
                    end
                end                
                tSpawnProp[tSpawn.section] = { sCommunity = sCommunity, sRank = sRank, isCheck = isCheck }
            end                    
        end    
        return tRetTable
    end    
    return nil
end


function create_ammo(section, position, lvi, gvi, pid, num)
    local ini = system_ini()
    local num_in_box = ini:r_u32(section, "box_size")
    while num > num_in_box do
        alife():create_ammo(section, position, lvi,    gvi, pid, num_in_box)
        num = num - num_in_box
    end
    return alife():create_ammo(section, position, lvi,    gvi, pid, num)
end



function spawn(name)
    local spawner = respawners[name]
    if spawner == nil then
        return
    end
    
    for i=1,spawner.max_spawn do
        if spawner.max_count ~= -1 and table.getn(spawner.spawned_obj) >= spawner.max_count then
--            printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(spawner:name()))
            return
        end        
        if spawner:create(xr_logic.pick_section_from_condlist(db.actor_proxy, spawner, spawner.conditions)) == false then
            return
        end
    end        
end

 

------------------------------------

А вот это уже зря ...

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

Ты так ничего и не понял о необходимости соблюдать правила форума. Более ответов для тебя не будет. --/Artos

 

Добавлено через 17 мин.:

что происходит?

кто olaf1?

 

Я просто скопировал его сценарий и улучшить его.

 

:rofl2:

ColR_iT

 

Если ты не olaf1 (действуешь по сути от его имени), то ... скопировал не только его сценарий, но и все то, за что им получен бан.

Т.е. и бессвязанное и безграмотное описание вопроса и недостаточную информативность в вопросе. --/Artos

 

Добавлено через 16 мин.:

Я не olaf1 и хорошо его знают не только видели его сценарий, и я думал, что я, возможно, выглядели лучше, и даже einwenig GSC форум, но koonnten не поможет мне

 

Я надеюсь, что они понимают, что я не olaf1 и я никогда не буду

 

Если ты не olaf1, то настоятельно рекомендую посмотреть не только его коды, которые он приводил тут на форуме, но и то, что ему рекомендовалось по поводу написания своих вопросов (на двух языках: рус и eng), дабы понять можно было бы. И писать ГРАМОТНО, т.е. понять вопрос:

Почему только gespwant мой NPC, когда я рядом с его spawnpoints?
- врядли кто сможет. Выделенных слов нет ни в русском ни в английском языках и вопрос бессмысленен.

В противном случае, правила форума, о необходимости грамотно писать в своих сообщениях, касаются всех, не взирая на национальные и языковые особенности. --/Artos

 

Добавлено через 14 мин.:

эх жаль

К сожалению, для моего языка, но я немецкий

и не может говорить на русском

 

и английском форуме я видел, никто не помогает: (

 

Попробуй писать auf dem Deutschen и на Русском (ориентируясь этой формой)... приложив усилия, чтобы тебя можно было бы понять. Слово gespwant и в немецком отсутствует.

Но если вопросы не будут понятны - лучше не мусорить в топике. --/Artos

 

olaf1, а вот я не верю, что это не ты - IP совпадает. :-) Правилами форума запрещено создавать несколько профилей... Этот профиль блокирую. Cyclone

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   1 пользователь

×
×
  • Создать...