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

Народная 2010 разработка


n6260

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

(изменено)

Monnoroch, нельзя - игра не запустится с файлом большим 2 ГБ!

Да я ведь уже поддерживаю Солянку с упакованной геймдатой. :)

 

Monnoroch, посмотри моё сообщение в теме ссылок. Там есть ссылка как на саму Солянку упакованную так и на "идеологию" упаковки.

 

Monnoroch, тут проблема в инете, я так понимаю. :(

 

Ray, любые правки или дополнения можно бросать по-старому - в виде папки "геймдата".

 

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

 

Ray, тоже почитай "Как паковалась геймдата" в моём сообщении в теме ссылок. Там всё расписано (и то, что умные, если им нужно, распакуют легко).

 

Ray, так и я - ЗА. Но у Архары слабый интернет для экспериментов :(

 

Самый свежий винрар наконец научился распаковывать то, на что исходный код был доступен уже больше чем пол года. :(

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

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

1) Сделать инсталлер, который будет устанавливать только упакованную геймдату от Архары + от него же адаптации и респавн. Это нужно для того, чтобы следующие дополнения или патчи не конфликтовали с ранее установленными "приправами" как это было в последнем инсталлере (инсталлер удался, но установить по верх его геймдаты полуфинал уже нельзя было :().

2) Всякие другие "приправы" к Солянке выпускать отдельными упакованными геймдатами или даже инсталлерами этих упакованных геймдат. И то - только проверенные временем. Например, музыкальные флешки, фотозона и т.п. Те же флешки не меняются со дня их создания и в этом их сила :)

3) А кто сам из игроков чего захочет добавить - пускай бросают по-старому в папку "gamedata".

 

Если пункты 1) и 2) захочет делать один человек, то он сможет всё (геймдату Солянки, дополнения Солянки, патчи Солянки, флешки, фотозону...) упаковать в отдельные *.db файлы и упаковать их тем же 7zip-м (жмётся так же хорошо как и папка gamedata) в разные архивы как части инсталлера (как было с музыкальными флешками в последнем инсталлере).

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

'gamedata.dbc' 1.9 ГБ, 'gamedata.dbd' 1.7 ГБ - Солянка от 08.08

'gamedata.dbe' 0.6 ГБ - все дополнение вместе по 13.12 (это чтобы первые два файла игрокам не перекачивать! )

'gamedata.dbf' - все патчи в одном файле

'gamedata.dbm' - адаптации для мониторов - каждая адаптация в своём отдельном файле (попросту любые худы, сюда можно добавить ещё худов - от n6260, Серафима...)

'gamedata.dbr' - респавн (частый и редкий) - каждый в своём отдельном файле

На раздаче в торренте:

- Солянка ('gamedata.dbc' и 'gamedata.dbd' вместе со старыми адаптациями 'gamedata.dbm' и респавном 'gamedata.dbr') - в одтельном архиве;

- дополнения ('gamedata.dbf' с новыми адаптациями 'gamedata.dbm' и респавном 'gamedata.dbr') - в отдельном;

- патчи ('gamedata.dbf') - в отдельном.

Теперь бы я адаптации и респавн выкладывал вместе с патчами :rolleyes:

По аналогии можно добавить что угодно. Нужно лишь соблюдать последовательность (последний перекрывает файлы предыдущего).

 

P.S. Почему есть отдельный файл для дополнений - если перепаковать всю Солянку в три *.db файла c,d,e и выпустить потом следующее крупное дополнение, то файл "e" уже нельзя будет заменять (разве что точно знать что раньше паковалось в него, только к этому добавить новое дополнение и упаковать опять в "е"-файл - появляется вероятность промахнуться, так как основная геймдата смешивается с дополнением не полностью с заменой файлов, а лишь как бы с боку :) В общем появится дублирование в исходных ингридиентах для упакованной геймдаты).

P.P.S. В теме ссылок давать ссылки только на инсталлер и файлы для этого инсталлера "от Архары". При этом файлы с флешками, фотозоной и т.д., которые также будут упакованы в файлы *.db и пожаты, давать отдельно от основного соляночного инсталлера, который сможет подключать их динамически. Хотя можно и отдельными инсталлерами. Все остальные ссылки - в теме Народного творчества.

 

Это лишь моё мнение :)

 

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

Изменено пользователем sapsan
  • Нравится 1

Поделиться этим сообщением


Ссылка на сообщение

Arhara, нужно закомментировать в gamedata/config/ui/ui_custom_msgs.xml строку 184:

<texture>ui_hud_frame_clock_vergas</texture>

Она осталась в полуфинале.

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Shadowman, Monnoroch, решил тут взглянуть на переодевание неписей. Понял не много, но нашел несколько странностей:

1. куски кода по выбору секции по визуалу сдублированны в xrs_armor.script (со строки 1648) и death_manager.script (со строки 206), но при этом по-разному достаётся переменная vis (похоже, что в xrs_armor.script более совершенный вариант) и есть ещё небольшое отличие по нейтралам;

2. в этих же кусках кода либо перевести всё на elseif, либо на таблицы по сравнению в лоб и сравнению как части (чисто для оптимизации);

3. там же есть вероятность неинициализации переменной sect (мне не известно нормально ли отработает "read_if_exist_str()") - может лучше вместо "local sect" сделать "local sect = nil" ?

4. закомментирован stalker_soldier и stalker_suit, который встречается в одной из проверок в xrs_armor.script в строке 1727, а также soldier_outfit (у него визуал soldier_suit) присутствует в all.spawn (может это и ничего, но выглядит пропущенным);

5. xrs_armor.script в строке 1613 присутствует проверка на имена неписей - ведь в начале есть список игнорируемых неписей, кроме того как-то странно проверка на имена связана с экзоскелетом... или просто скобку забыли закрыть где нужно;

6. xrs_armor.script в строках 1832 и 1834 проход по всему и проверка на здорового сталкера - разве нету в АМК таблицы сталкеров? Вопрос актуален и для уборщика, если он запускается после создания такой таблицы.

7. xrs_armor.script в строке 1852 лишние проверки - вся таблица заполнена (мелочь);

8. xrs_armor.script в строке 34 в таблице upgrade_top_lvl не все локации.

 

Shadowman,

Проверка на outfit и exoskelet
здесь суть не в самой проверке, а в её связке (and, or) с проверкой имён.

 

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

По п.1 - сделать дублирующийся код функцией и вызывать её из death_manager.script.

 

Shadowman, ну я выдал всё что увидел :)

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Shadowman, Monnoroch,

Может таблицу исключений по переодеванию перенести в "протектед_итемс", а в xrs_armor.script комментарием указать, где они находятся?

Это чтобы Архара всех VIP-персонажей в одном месте добавлял :)

А может вообще их уравнять с теми, чьи трупы нельзя убирать уборщику?

Или вообще ввести в конфиг непися какой-то особый атрибут protected или vip равный true или 1, и уже в коде уборщика и переодевания просто проверять наличие/значение этого артрибута? Тогда Архаре не нужно будет после добавления квестового непися помнить, что нужно его ещё и внести в два файла, да ещё и не ошибится при этом (любое движение несёт в себе вероятность ошибки )

 

P.S. Итерации по оптимизации закончились :crazy:

 

Arhara, даже если так - как ты относишься к тому, чтобы держать все списки исключений в одном файле "протектед_итемс" или введению в конфиг непися спецатрибутов "неубираемый" (protected_remove=1), "непереодевающийся" (protected_unchanged_clothes=1) ?

 

Monnoroch, о тормозах я подумал, но всё же переодевания не так часты, как и уборка трупов.

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

Поделиться этим сообщением


Ссылка на сообщение

Shadowman, Monnoroch, табличка так табличка. Моё дело - предложить. :)

А по стволам - может уровень считается уровнем только в определённых границах координат и те неписи появились как бы вне уровня (вне "закона" скриптов)?

Поделиться этим сообщением


Ссылка на сообщение
(изменено)
sapsan, гы,красиво ты с табличкой :)

но все таки в данном случае оно того не стоит ..

Это я больше для примера ввёл. Ведь вы оба много кода пишите или ещё будете писать для сталкера и не только. А этот способ вызова функций является очень оптимальным. Да и переделать существующий код можно под эту "технику".

 

инфопорции - это куча методов выполнять.

опять же - не стоит оно того.

Ну я так и написал - можно и не использовать. Хотя куча методов будет выполняться не чаще 1 раза в секунду да ещё и при нужном условии (слабом здоровьи, высокой радиации или истощении).

 

Согласен, тут Monnoroch вроде немного недосмотрел, но на первый взгляд это можно исправить так

В моём файле это уже исправлено. А что не досмотрел, то я сам конечный вариант не сразу написал - часа два над ним посидел :)

 

По вызову функций - это, кажись, есть и в Делфи, и в С++. Лишь бы мог переменной присвоить функцию или ссылку на неё.

 

Shadowman, есть в скриптах - ищи по "](". Но не подсмотрел в сталке, а где-то вычитал.

 

[spoiler=За счёт чего появляется выигрыш при использовании массива функций или других значений]Это быстрее только в случае замены if-в или switch-й этим массивом. В случае if-в или switch-й идёт сравнение по всей их цепочке if ... else до момента пока не выполнится одно из условий-сравнений, а в случае массива сразу находится нужная функция. Вот на отсутствии этой цепочки проверок и осуществляется экономия.

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

 

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

 

В том скрипте всего две проверки, а если их десятки... В критических участках кода эти мизерные выиграши дадут существенный выигрыш.

 

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

 

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Всё, что ниже - только мои догадки :)

Залез я в xrs_armor.script и вот что заметил:

- В функции add_to_binder() есть привязка неписю "способа мышления" (evaluator_see_useful_armor()) и там (add_to_binder()) в исключениях отсутствуют какие-то одиночки (stranger), для которых также отсутствует запись в таблице armors_by_community и остальных таблицах. Таким образом им привязывается мышление, но данных по ним нет. И по ходу выполнения должен быть завис или вылет в функции check_armor() в проверке if suits_to_visuals[com][vis] then так как и в таблице suits_to_visuals их нет.

 

- В таблице armors_by_community запись для экологов пустая, хотя их нет в исключениях в том же add_to_binder(), а при выполнении функции select_next_visual() они отсекаются проверкой table.getn(armors_by_community[com])>0.

 

Таким образом как минимум нужно ввести дополнительную проверку так:

        if suits_to_visuals[com] and suits_to_visuals[com][vis] then

Кроме того, если уж экологи должны иметь только свой визуал, тогда можно добавить ещё визуалов эколога в таблицу suits_to_visuals["ecolog"], если имеются новые, и сам разрешенный визуал в таблицу armors_by_community["ecolog"].

 

Если нужно, чтобы те одиночки переодевались, нужно убрать их из исключения в add_to_binder() и заполнить для них все таблицы.

 

Кроме того есть ещё такая мысль - можно ведь исключать неписей по имени не во время npc_update(binder) и evaluator_see_useful_armor:evaluate() (если я правильно понимаю - эти функции вызывается только у тех неписей, к которым было прикручено мышление в add_to_binder()), а ещё во время того самого прикручивания мышления в add_to_binder(), что там так и делается для двух товарищей (object:name()=="mil_stalker0012" or object:name()=="yantar_ecolog_general"). В то же время в функции update() эту проверку нужно оставить.

 

Самый кардинальный и простой метод - отрезать :crazy: В этом случае нужно просто и экологов, и тех одиночек (stranger) поместить в исключения в функции add_to_binder() как целые сообщества (community). Но это самый нежелательный вариант.

 

Ну и на последок - нужно провести ревизию таблицы suits_to_visuals на наличие визуалов, которые там прописаны.

 

Вот вариант файла с дополнительной защитой на будущее, исключёнными одиночками (stranger) и разрешением переодеваться экологам в косюмы экологов.

 

 

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

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

Вот исправленный файл.

Ray, добавь его в архив.

Arhara, если ты уже заполнял этот файл, то просто вместо

local random_news_number

пропиши

local random_news_number = 1

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Wlad777, подозреваю, что всё же есть такие неписи и кроме ГГ.

arhara_dialog.script:

--' ГГ друг снайперов
function friend_community(actor, npc)
db.actor:set_character_community("stranger", 0, 0)
end

dialog_manager.ltx:

[dm_action_info_18]
wounded = false
level = l05_bar
npc_community = stranger
category = cool_info

[dm_action_info_19]
wounded = false
level = l05_bar
npc_community = stranger
category = cool_info

stable_dialog_manager.xml:

- <string id="dm_action_info_18">
  <text>Эта территория теперь контролируется "Долгом", и закон здесь - правила "Долга". Мы контролируем границы зоны и остужаем горячие головы: подорванные сюда целыми составами приезжают, любители романтики... а потом гибнут пачками в первый же день.</text> 
  </string>
- <string id="dm_action_info_19">
  <text>Ты на нашей перевалочной базе бывал? Она, правда, не только наша - тут много кого встретить можно. Главное, место хорошее, без дряни всякой, и все новости о Зоне сюда стекаются. Почти всегда чего-нибудь полезное услышать можно или просто с народом за жизнь потрепаться. Жаль только, Лысый с группой позавчера ушёл - так я с ним в этот раз и не свиделся.</text> 
  </string>

 

 

Monnoroch, а так не проще будет:

function actor_binder:on_info(info)
if fncs_by_info[info] then
fncs_by_info[info]()
end
end

?

 

И по колбеку на инфопорцию как избавление от апдейта ты прав.

 

Я там в лоб скопировал. Теперь выполнится только один раз.

Аргументы - не нужно иметь и синхронизировать две таблицы.

 

fncs_by_info[info] - это как-бы переменная, которая имеет в себе или ссылается на функцию

fncs_by_info[info]() - это уже вызов самой функции

 

Monnoroch, проверил - точно один раз.

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

Поделиться этим сообщением


Ссылка на сообщение

Arhara, так моё дело было сами скрипты поправить, чтобы всё было быстро, читабельно и ты мог легко править всякие настройки. А сами настройки, а особенно координаты, я не трогал.

Всё в твоих руках. ;)

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

С замками ситуация была такая:

- Все рюкзаки Сидоровича были на одно лицо для замков (у всех стори ИД = 4294967296, тоесть отсутствует). Поэтому закрыв такой рюкзак замком, автоматически закрывались все рюкзаки Сидоровича.

- Некоторые нычки от ПЫС также со стори ИД = 4294967296 (отсутствует). Кроме того их имена (level_prefix_inventory_box_0012) явно недоделаны самими ПЫС-ми. Они должны были называться как новые стационарные нычки от мододелов (atp_arhara_secret_1), тоеть вместо level_prefix должен быть идентификатор уровня. Из-за этого в игре есть нычки с одинаковыми именами и некоторые из них без стори ИД.

 

Внёс я изменения в работу замков. Изменения не кардинальные и не до конца корректные потому, что пришлось бы менять и amk_offline_alife.script (переводить работу замков и защиты на ИД нычек).

Изменения - если у нычки стори ИД = 4294967296, то под защиту берётся её имя.

Таким образом рюкзаки Сидоровича теперь будут охраняться индивидуально. У нычек от ПЫС-в со стори ИД = 4294967296 уменьшится защита "на шару", а с установленным стори ИД (таких - большенство) защита будет нормальная - по их стори ИД.

 

Вот результат. Можно раскомментировать отладочный вывод в консоль и понаблюдать за именами и стори ИД нычек.

 

P.S. Не нашел код защищающий рюкзаки Сидоровича.

 

Arhara, что скажешь - переделывать amk_offline_alife.script чтобы совсем было правильно (там не много) ?

Вот вариант "совсем правильно" :)

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

solvador, наши наработки потихоньку перетекают в Солянку ;)

 

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

solvador, если ты об включении именно в Солянку, то да - все наработки этой темы - для Солянки.

 

Arhara, Вот вариант замка "совсем правильно" :)

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Arhara, в моём новом варианте amk_offline_alife.script из "правильных замков" в строке 540 есть такой кусок проверки:

(alife():object(artefact.parent_id):clsid()>172 and alife():object(artefact.parent_id):clsid()<180)

Я так понимаю, что это аномалии. Нужно добавить новые сюда приблизительно так:

(alife():object(artefact.parent_id):clsid()>172 and alife():object(artefact.parent_id):clsid()<180 or alife():object(artefact.parent_id):clsid() == НОМЕР КЛАССА АНОМАЛИИ)

Или скажи мне номера новых аномалий - я добавлю.

 

P.S. Нашел в такую проверку:

(sobj:clsid()>172 and sobj:clsid()<180) or
sobj:clsid()==clsid.zone_electra_s or
(sobj:clsid()>18019 and sobj:clsid()<18024) or
sobj:clsid()==clsid.nogravity_zone

 

Если она есть полной, то нужно сделать общую функцию проверки и вызывать её всюду (таких файло-мест есть 3).

 

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

Только вот я не понял зачем идёт сравнение с clsid.nogravity_zone, который равен 179 и автоматом попадает в диапазон проверки

(sobj:clsid()>172 and sobj:clsid()<180)

?

Описка по незнанию?

 

    const zone_bfuzz_s = 168;
    const zone_galant_s = 169;
    const zone_mbald_s = 170;
    const zone_mincer_s = 171;
    const zone_rusty_hair = 181;
    const zone_buzz_s = 185;
    const zone_zharka_s = 188;
    const zone_electra_s = 189; 
    const zone_ice = 190; 
    const zone_ice_s = 191;

 

Или я чего не понимаю ?

 

Shadowman, я нашел все файлы, в которых проверяется объект на то, что он есть аномалией, и уже поправил их все, но наткнулся на ещё большее количество "неучтённых" аномалий. :rolleyes:

 

Инетересно - а какой класс у стационарной радиации? А то ещё неписи перестанут там ходить или ещё чего делать...

Похоже это

const zone_radioactive = 180;

и её стоит исключить из проверки...

 

Arhara, вот результат. Включены отсутствующие аномалии, кроме стационарной радиации (zone_radioactive = 180), всюду используется унифицированная функция проверки. Также в архиве присутствует изменённый замок, так как в файле amk_offline_alife.script пересеклись правки по замку и аномалиям.

 

function is_anomaly(class_id)
    return 
    (
        class_id and 
        (
            (class_id >= 168 and class_id <= 179) or
            class_id == 181 or
            class_id == 185 or
            (class_id >= 188 and class_id <= 191) or
            (class_id >= 18020 and class_id <= 18024)
        )
    )
end

 

if is_anomaly(sobj:clsid()) then

amk_anoms.is_anomaly(alife():object(artefact.parent_id):clsid())

 

 

P.S. Нужно протестировать.

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Arhara, по нычкам - да, там есть таблица исключений стори ИД:

    5008,
    5013,
    5014,
    5041,
    5065,
    5084,
    5104,
    5205,
    5222,
    5226,
    5237,
    5238,
    5243,
    5244,
    5245,
    5246,
    5247,
    5248,
    5249,
    5250,
    5254,
    5255,
    5408,
    5413,
    5428,
    5433,
    5434,
    5444,
    5446,
    5470,
    5471,
    5472,
    5473,
    5474,
    573

Я её не трогал.

Arhara, список аномалий, как я понял, "одобрили" неотрицанием Shadowman, malandrinus, Monnoroch :rolleyes:

Если что - редактируется только таблица anomaly_classes в файле amk_anoms.script.

 

Arhara, Monnoroch, по death_manager.script - я его исправил и адаптировал назад под Солянку. Исправил порядок проверки на поиск части в имени секции и вернул поиск по части имени непися вместо прямого сравнения.

Вот результат.

 

P.S. Ревизия кода приветствуется.

 

Arhara, извини - урвал время на покодировать. Играть - давно уже не играю...

 

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

Всем скриптёрам, нашел одну "аномалию" в скрипте amk_anoms.script - таблица on_anoms_per_level заполняется по проверке на то, что объект - это аномалия, но нигде не используется! :huh:

Смотрел даже в Солянке от 2009.08.08.

Качаю оригинальный АМК 1.4.1 с патчами для изучения....

Скачал, посмотрел - то же самое - таблица on_anoms_per_level нигде не используется :(

 

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

Arhara, по аномалиям - я сам спавн их не трогал, только их определие в скриптах поправил. Это не должно повлиять на сами аномалии.

Места изменений:

- отключение аномалий при начале выброса (теперь должны отключатся все аномалии);

- включение аномалий после выброса (включатся все аномалии обратно);

- проверка неписем в оффлайне не пренадлежит ли артефакт аномалии (теперь непись не должен влезть ни в какую аномалию);

- выявление причины смерти непися для новостей (теперь имена аномалий должны отображатся нормально, а не как указал Shadowman ("причина смерти неизвестна").

 

По таблице on_anoms_per_level - видать была задумка где-то её использовать, но потом обошлись без неё. Вот и вся история :)

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Arhara, не понял. Убрать из таблицы ещё и "zone_smallrain_s", "zone_zavesa_s", "zone_fountain_s", "zone_sphere_s", "zone_ogon_s", "zone_monolith_s"? Так я видел сферу точно, фонтан видел и "огонёк" тоже видел :)

 

P.S. Тестировал аномалии на Баре и услышал окружающие звуки как в подземках... Баг однако. Услышал после выброса. До выброса были обычные для Бара звуки.

 

Arhara, так просто закомментируй ненужные аномалии в таблице anomaly_classes и всё - больше нигде править не нужно.

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Arhara, вот исправление ЧУ для случая переходов ГГ между локациями на которых есть или нету ЧУ (например над землёй и под землёй).

 

Или, если ты вносил правки в таблицы файла, то замени этот кусок:

    -- неписи становятся в стойку с выставленным стволом
    if timeh == horror_begin_time.h and timem >= horror_begin_time.m and timem <= 59 then
        if panic_minute ~= timem then
            panic_minute = timem

            local npc, npc_position, position
            for k, v in pairs (db.storage) do
                npc = level.object_by_id(k)
                if npc and npc:alive() and IsStalker(npc) and tabl_npc_ignore[npc:name()] ~= true then
                    npc_position = npc:position()
                    position = vector():set(npc_position.x + math.random(-5,5), npc_position.y, npc_position.z + math.random(-5,5))
                    state_mgr.set_state(npc, "hide_s_right", nil, nil, {look_position = position})
                end
            end

            --[[for k, v in pairs (db.storage) do
                npc = level.object_by_id(k)
                if npc and npc:alive() and IsStalker(npc) and tabl_npc_ignore[npc:name()] ~= true then
                    state_mgr.set_state(npc, "hide_s_right")
                end
            end]]
        end
    end

    --сообщение о старте
    if timeh == horror_begin_time.h and timem == (horror_begin_time.m + 1) then
        if db.actor:dont_has_info("random_pre_news") then
            db.actor:give_info_portion("random_pre_news")
            random_news_number = math.random(table.getn(tabl_mess_begin))
            presoobj()
        end
    end
    
    --включение установки или её сбой
    if (timeh == horror_time.h and timem == horror_time.m)  then
        if db.actor:dont_has_info("horror") then
            game_reloaded = false
            db.actor:give_info_portion("horror")
            if math.random(2) == 2 then --удача запуска 50/50
                local level_name = level.name()
                local level_info = tabl_horror_by_level[level_name]
                if level_info then
                    level.add_cam_effector("camera_effects\\earthquake.anm", 77777775, true, "")
                    level.add_pp_effector("dead_zone.ppe", 77777774, false)
                    level.add_pp_effector("nano.ppe", 77777773, false)
                    level.add_pp_effector("nightvision.ppe", 77777772, false) 
                    level.add_pp_effector("psy_antenna.ppe", 77777771, true, "")
                    effects()
                    news()
                    horrorspawn(level_name)
                    hit_actor(level_name)
                    spawn_phantom()
                    horror_sound()
                    
                    local npc, npc_position
                    for k, v in pairs (db.storage) do
                        npc = level.object_by_id(k)
                        if npc and npc:alive() and IsStalker(npc) and tabl_npc_ignore[npc:name()] ~= true then
                            state_mgr.set_state(npc, "idle", nil, nil, nil, {animation = true})
                        end
                    end
                    
                    random_reaction()
                end
            else -- неудачный запуск
                db.actor:give_info_portion("horror_fail")
                presoobjFAIL()
            end
            --meceniy_dinrad.disable() -- может это делать перед выбросом ?
            --meceniy_dinrad.level_spawn() -- может это делать после выброса ?
        end
    end

    -- перезапуск спецэффектов в случае перезапуска игры
    if timeh == horror_time.h and timem >= horror_time.m and timem < horror_end_time.m and game_reloaded and db.actor:dont_has_info("horror_fail") then
        game_reloaded = false
        level.add_cam_effector("camera_effects\\earthquake.anm", 77777775, true, "")
        level.add_pp_effector("psy_antenna.ppe", 77777771, true, "")
        horror_sound()
    end
    
    --окончание ЧУ
    if (timeh == horror_end_time.h and timem == horror_end_time.m) then
        if db.actor:dont_has_info("horror_time_end") then
            db.actor:give_info_portion("horror_time_end")
            
            if db.actor:dont_has_info("horror_fail") then
                level.add_pp_effector ("teleport.ppe", 77777777, false)
                level.remove_pp_effector(77777774)
                level.remove_pp_effector(77777773)
                level.remove_pp_effector(77777772)
                level.remove_pp_effector(77777771)
                level.remove_pp_effector(77777776)
                level.remove_cam_effector(77777775)
                remove_horror_mutant()
            end
        end
    end

на этот:

    -- неписи становятся в стойку с выставленным стволом
    if timeh == horror_begin_time.h and timem >= horror_begin_time.m and timem <= 59 then
        if panic_minute ~= timem then
            panic_minute = timem
            
            -- тревожим неписей только на локациях, где есть ЧУ
            if tabl_horror_by_level[level.name()] then
                local npc, npc_position, position
                for k, v in pairs (db.storage) do
                    npc = level.object_by_id(k)
                    if npc and npc:alive() and IsStalker(npc) and tabl_npc_ignore[npc:name()] ~= true then
                        npc_position = npc:position()
                        position = vector():set(npc_position.x + math.random(-5,5), npc_position.y, npc_position.z + math.random(-5,5))
                        state_mgr.set_state(npc, "hide_s_right", nil, nil, {look_position = position})
                    end
                end
            end
        end
    end

    --сообщение о старте
    if timeh == horror_begin_time.h and timem == (horror_begin_time.m + 1) then
        if db.actor:dont_has_info("random_pre_news") then
            db.actor:give_info_portion("random_pre_news")
            random_news_number = math.random(table.getn(tabl_mess_begin))
            presoobj()
        end
    end
    
    --включение установки или её сбой
    if (timeh == horror_time.h and timem == horror_time.m)  then
        if db.actor:dont_has_info("horror") then
            game_reloaded = false
            db.actor:give_info_portion("horror")

            -- расслабляем неписей только на локациях, где есть ЧУ
            if tabl_horror_by_level[level.name()] then
                local npc, npc_position
                for k, v in pairs (db.storage) do
                    npc = level.object_by_id(k)
                    if npc and npc:alive() and IsStalker(npc) and tabl_npc_ignore[npc:name()] ~= true then
                        state_mgr.set_state(npc, "idle", nil, nil, nil, {animation = true})
                    end
                end
            end

            if math.random(2) == 2 then --удача запуска 50/50
                local level_name = level.name()
                local level_info = tabl_horror_by_level[level_name]
                if level_info then
                    level.add_cam_effector("camera_effects\\earthquake.anm", 77777775, true, "")
                    level.add_pp_effector("dead_zone.ppe", 77777774, false)
                    level.add_pp_effector("nano.ppe", 77777773, false)
                    level.add_pp_effector("nightvision.ppe", 77777772, false) 
                    level.add_pp_effector("psy_antenna.ppe", 77777771, true, "")
                    effects()
                    news()
                    horrorspawn(level_name)
                    hit_actor(level_name)
                    spawn_phantom()
                    horror_sound()
                    random_reaction()
                end
            else -- неудачный запуск
                db.actor:give_info_portion("horror_fail")
                presoobjFAIL()
            end
            --meceniy_dinrad.disable() -- может это делать перед выбросом ?
            --meceniy_dinrad.level_spawn() -- может это делать после выброса ?
        end
    end

    -- перезапуск спецэффектов в случае перезапуска игры
    if timeh == horror_time.h and timem >= horror_time.m and timem < horror_end_time.m and game_reloaded and db.actor:dont_has_info("horror_fail") then
        game_reloaded = false
        -- возвращаем спецэффекты только на локациях, где есть ЧУ
        if tabl_horror_by_level[level.name()] then
            level.add_cam_effector("camera_effects\\earthquake.anm", 77777775, true, "")
            level.add_pp_effector("psy_antenna.ppe", 77777771, true, "")
            horror_sound()
        end
    end
    
    --окончание ЧУ
    if (timeh == horror_end_time.h and timem == horror_end_time.m) then
        if db.actor:dont_has_info("horror_time_end") then
            db.actor:give_info_portion("horror_time_end")
            
            if db.actor:dont_has_info("horror_fail") then
                -- вспышка окончания ЧУ только на локациях, где есть ЧУ
                if tabl_horror_by_level[level.name()] then
                    level.add_pp_effector ("teleport.ppe", 77777777, false)
                end
                level.remove_pp_effector(77777774)
                level.remove_pp_effector(77777773)
                level.remove_pp_effector(77777772)
                level.remove_pp_effector(77777771)
                level.remove_pp_effector(77777776)
                level.remove_cam_effector(77777775)
                remove_horror_mutant()
            end
        end
    end

 

Изменения:

- неписи тревожатся только на локациях, где возможен ЧУ;

- неписи расслабляются после тревоги только на локациях, где возможен ЧУ;

- спецэффекты ЧУ восстанавливаются только на локациях, где возможен ЧУ;

- вспышка окончания ЧУ появляется только на локациях, где возможен ЧУ;

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

Поделиться этим сообщением


Ссылка на сообщение

Shadowman, malandrinus, табличка работает нормально. Она у меня не работала только потому, что я её не проверял - написал и выложил. Методом научного втыка вычислил и закомментировал две аномалии (--[clsid.zone_buzz_s] = true, --[clsid.zone_ice] = true,), после чего всё заработало и выброс пережил нормально на Баре... Под правки Архары по аномалиям нужно подрезать таблицу. Будет время - сделаю. Но введение таблицы и единую функцию проверки можно отложить до "после выхода следующего дополнения" так как у нас с Архарой возникли разногласия по этому поводу. Вот наша переписка:

sapsan:

По аномалиям:

Может я не всё понял, но мне показалось что ты не совсем понял суть последней правки.

Она отвечает за:

- распознавание неписями аномалий при поиске артефактов (они в них теперь не полезут);

- отключение/включение аномалий после начала/окончания выброса (раньше новые аномалии не убирались и, как следствие, не меняли своё мместо положения);

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

Если я ошибся в твоём непонимании правки - хорошо :)

 

Arhara:

Не заметил - потому как у меня на баре всё ок. :ny_ph34r_1: Меня более мало интересуют дин. аномалии - в моём понятии и неоднократных пробах - им не нужны не прописи, ни СИДы, ни прочее. Всё и так работает без лишних заморочек. Интересен только момент обхождения неписями аномалий - не смотрел, но думаю, это достаточно лишь прописать в неписях по группировкам - по подобию монстров....

П.С - а нужна ли табла по классам аномалий вообще????

 

sapsan:

Смотри. Раньше проверка на то, что объект - это аномалия, делался так:

if (sobj:clsid()>172 and sobj:clsid()<180) or
sobj:clsid()==clsid.zone_electra_s or
(sobj:clsid()>18019 and sobj:clsid()<18024) or
sobj:clsid()==clsid.nogravity_zone then

Теперь это делается так:

if is_anomaly(sobj:clsid()) then

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

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

Ведь добавлял ты новые аномалии в таблицы спавна. Ну перенёс ты их в олл.спавн, но ведь из игры они никуда не делись и класс_ид у них тоже остался. Просто регистрировать их уже не нужно (если я правильно понял), но вот сама игра должна и дальше с ними "работать", а для этого нужна эта проверка.

 

Arhara:

У новых дин. аномалий нет класс_ид. Нет вообще ничего, кроме конфига, а у части - нет даже и этого. Зачем их вносить куда-то ещё, если и так всё работает?

 

sapsan:

Ты хочешь сказать, что убрал их и в lua_help.script из C++ class clsid {? Если да - ты проверял, что они меняют место после выброса ?

На основе проверки на sobj:clsid() осуществлялась перестановка аномалий и запрет на обращение внимание неписями на арты в аномалиях...

 

Arhara:

Конечно, проверял. Более того - уже давно вышла правка - а в ней - я убрал им СИДы, регистрацию, луа_хелп и прочую хренотень. Это только провацировало вылеты. :ny_ph34r_1: :ny_ph34r_1:

 

sapsan:

Посмотрел правку - там ты убрал класс_ид только у новых аномалий... Они пропадают сразу после начала выброса ? А то я не тестировал с убранными класс_ид у аномалий. Как по мне, то с моей правкой или без неё, но с удалёнными класс_ид из луа_хелп новые аномалии не будут отключатся с началом выброса и перемещатся после него. Если удаляются и перемещаются - то я чего-то не понимаю... Может тогда нужно начать НИ, чтобы они не удалялись и не перемещались ? Так как у уже заспавненных аномалий сохранились класс_ид...

 

Arhara:

В том то всё и дело, что они работают и не вызывают багов. А при прописке - наоборот...

 

Arhara:

Нет, я оставил проверку на аномалии от АМК - так как было, убрав только свои, новые и оставил их в табле и по локам, изменив конфиги самих аномалий. Более - ничего не менял.

 

sapsan:

И в новой игре твои новые аномали при начале выброса пропадают ?

Без проверок, которые ты убрал, код удаления аномалий в начале выброса их не распознает и не удалит... Также и с неписями...

P.S. Будешь выкладывать следующее обновление или патч - выложи его как тестовый... Не хорошие у меня мысли по поводу новых аномалий без проверок в коде :) Помнишь как игроки жаловались, что после выброса новые аномалии не пропадали и не перемещались? Это как раз из-за отсутствия тогда проверок...

 

Arhara:

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

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

 

sapsan:

В народ ты выложил правку, в которой отключены в луа_хелп и амк_аномс только новые аномалии, а не все. Да и проверки остались по старым аномалиям. Вот когда все аномалии отключишь и проверки уберёшь... :rolleyes:

 

Arhara:

Я говорил только о новых. Старые - остались как были.

 

sapsan:

Поживём - увидим. По-моему, сейчас (без моей, но с твоей правкой) новые аномалии не будут менять место положения после выброса.

 

Arhara:

Я протестил - ничего просто так не выкладываю :ny_ph34r_1:

 

 function turn_off_all() for i=0,65534 do
local sobj = alife():object(i)
if sobj then
if (sobj:clsid()>172 and sobj:clsid()<180) or sobj:clsid()==clsid.zone_electra_s then
local map = alife():level_name(game_graph():vertex(sobj.m_game_vertex_id):level_id())
if not check_exclusion(sobj,map) then
local status=get_anomaly_status(sobj)
if status=="on" then set_anomaly_status(sobj,"del")
end end
end end
end end

 

Именно она заставила меня так долго припираться с Архарой :)

Знающие, что скажите на отсутствие проверки новых аномалий в ней ? Если Архара прав, то каким образом новые аномалии отключаются в начале выброса и меняют место после него ? :russian_ru:

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

lsclon, мне тоже эта мысль пришла, но как тогда с детекторами ?

За уборку аномалий во время выброса отвечает функция turn_off_all(), которую я указал выше. И, как я теперь понял, она будет работать для новых аномалий, так как класс_ид у них равен класс_ид каких-то старых.

Но в чём смысл делать близнецов? Если смысл в оптимизации - тогда почему бы и старые аномалии не свести в одну ? Опять же - по какому признаку детекторы различают аномалии ?

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

lsclon, это объекты со статусом "on" и с класс_ид, который прошел проверку выше (172...180).

 

lsclon,

берутся из функции get_anomaly_status
Нет они берутся с помощью local sobj = alife():object(i), потом проходят проверку на класс_ид, а только потом уже и на статус...

 

malandrinus, благодарю. Ну теперь то всё ясно :). Если что - ковырять детекторы...

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

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Просматривал тут код на предмет послепроверки object_by_id и нашел вот такой кусок кода:

        local enemy=false
        for a=0,65534 do
            local obj=level.object_by_id(a)
            if obj then
                if (( IsStalker(obj) and amk.get_npc_relation(obj,db.actor)=="enemy" ) or 
                    IsMonster(obj)) and obj:position():distance_to(db.actor:position())<40 
                    and obj:see(db.actor) then
                    enemy=true
                    break
                end
            end
        end

Он мне не понравился этим:

local obj=level.object_by_id(a)

Полез в документацию по Луа и нашел вот это:

Обработка каждого объявления local ведет к созданию новой локальной переменной. Рассмотрим следующий пример:

     a = {}
     local x = 20
     for i=1,10 do
       local y = 0
       a[i] = function () y=y+1; return x+y end
     end

Цикл создает 10 экземпляров функции, в которых используются различные переменные y и один и тот же x.

Как я понимаю, в результате до срабатывания убощика памяти (о нём ещё не читал :)) такой код наплодит в памяти 10 переменный y. В случае же кода из скриптов Солянки таких переменных obj будет 65535. :russian_ru:

 

P.S. Почитал о сборщике мусора в Луа. Он действительно запускается через промежутки времени или по достижению определённого объёма занимаемой памяти. Выходит, что циклы с такими объявлениями будут кратковременно засорять память.

А чтобы всё было красиво нужно сделать так:

        local enemy=false
        local obj
        for a=0,65534 do
            obj=level.object_by_id(a)
            if obj then
                if (( IsStalker(obj) and amk.get_npc_relation(obj,db.actor)=="enemy" ) or 
                    IsMonster(obj)) and obj:position():distance_to(db.actor:position())<40 
                    and obj:see(db.actor) then
                    enemy=true
                    break
                end
            end
        end

P.P.S. А такого в скриптах - валом...

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

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    Ни один зарегистрированный пользователь не просматривает эту страницу.

AMK-Team.ru

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