ColR_iT 171 Опубликовано 4 Января 2012 Арбитр, плохо искал. В LW есть целый файл посвященный таймерам и называется он lwc_timer.script, принцип действия можно посмотреть в их же скриптах. Также можно посмотреть, как в АМК сделана варка артов по рецептам, там как-раз используется таймеры. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 3 Февраля 2012 Driv3r, а что это за объект у тебя npc? Его ведь как-то определить нужно, либо уже в функцию передать... И совет на будущее - не занимайся бестолковым копи-пастом. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 5 Февраля 2012 (изменено) Возник вопрос. В файле treasure_manager.ltx есть условия на выдачу тайника найденных на убиенных. Условие это задаётся в строке condlist, сами условия ясны как белый день, но вот что означает цифра после, я недоумеваю. Пример такой строки: condlist = {=npc_rank(veteran)} 2 Цифра означает сколько необходимо выполнить условие или же это некая вероятность, если так, то в каком отношенни она задаётся, поскольку значения больше 10 в оригинале нет. Изменено 5 Февраля 2012 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 7 Февраля 2012 Немного усидчивости и шевеления извилинами и вот он - алгоритм выдачи тайника в ТЧ. Начну с лирики... Лично мне не понятен смысл такой реализации, но в конечном итоге я хоть понял как эта реализация работает и надеюсь, что и вам как-то поможет... Цифра в конце стоки condlist, в файле treasure_manager.ltx, задающая условие на выдачу тайника, не какая не вероятность и не колличество выполненых условий, как думал я, а это просто цифра, да-да именно цифра и ничего иначе. По сути, в секциях самих тайников, описанных в файле указанном выше, заданно условие на выдачу, а именно строками condlist и community. Community задаёт группировки с которых можно снять тайник, а в condlist, задаётся условие: сначало следует... ну, назовём это - блок (фигурные скобки {}), затем эта злосчастная цифра, далее возможен ещё один или несколько блоков задающих уже другие условия, идущих через запятую. Пример: condlist = {=npc_rank(novice) =actor_on_level(l01_escape)} 2, {=npc_rank(novice) =actor_on_level(l02_garbage)} 2 Всё что внутри блока расматривается как "and", т.е. должны выполниться все условия: и НПС должен быть новичок, и локация должна быть "Кордон", это что касается первого блока. Сами же блоки расцениваются как "or": либо этот блок, либо тот. Теперь собственно, сам алгоритм выдачи... Алгорит описан в файле treasure_manager.script, но вот до принципа его работы ещё нужно догадаться. Для большей наглядности картины, рекомендую открыть файлы treasure_manager.ltx и treasure_manager.script , дабы воочию наблюдать ход событий. Неже в скобках будут указаны строки, для быстрой навигации по файлу treasure_manager.script При обыске трупа вызывается метод use класса CTreasure (93). Метод считывает все параметры убиенного и сравнивает их с параметрами community и condlist, которые уже инициализированы в конструкторе класса (66 и 77 соответственно). В методе есть оператор for (98), который обрабатывает таблицу treasure_info (54), по элементам которой и происходит сравнение. При переборе этих элементов, загадочная цифра в конце блока condlist, присваивается переменной treasure_prob (100), при условии, что НПС подходит по заданным условиям, если же условия не выполнились, то присваивается 0. Затем идёт сравнение - равно ли её значение стам: if tonumber(treasure_prob) == 100 then Отсюда, вытекает два вывода: 1. Данная проверка всегда в оригинале вернёт false, т.к. значения цифры больше 10 просто нет. 2. Если в condlist поставить число 100 после блока, то такой тайник будет выдан в обязательном порядке, с тем требованием, что условие в блоке выполнились и группировка НПС совпала с community и дальнейшего вычисления не произойдёт. Как я написал выше, значение переменной treasure_prob, в оригинале, всегда будет меньше 100 и даже меньше 11, поэтому мы переходим дальше. А дальше и начинается то самае шаманство, которое определяет выдавать нам тайник или нет. В таблицу avail (113) заносятся данные для каждого тайника подходящего под условия нашего обыскиваемого НПС. Т.е. если condlist вернул true и группировка, та что нужно. Данные заносятся не все, а только имя секции тайника (k) указывается в квадратных скобках в файле treasure_manager.ltx и treasure_prob для этого тайника, т.е. наша непонятная цифра, в таблицу она заносится как prob. По большому счёту, эта таблица хранит в себе имена тех тайников, из которых будет производится выбор, какой именно тайник выдавать. Далее переменной tr_sum присваивается значение treasure_prob (114) и поскольку всё это происходит в цикле, то данная переменная хранит в себе сумму всех значений treasure_prob для тайников подходящих под условия (нужный НПС, нужное место). Если вы не поняли последнее предложение прочтите его ещё раз и так до тех пор пока не поймёте, потому как это ключевой момент! Дальше, проверка на равенство (120) переменной tr_sum и ноля (такое произойдёт, если за блоком condilst будет стоять значение 100), а также проверяется вернула ли функция math.random значение меньше 65 или нет... вчитайтесь внимательно - функция math.random. Если что-то одно вернёт true, то тайник выдан не будет. Затем определяется какой именно тайник будет выдан. Переменной tr_w присваивается случайной число (126) в диапазоне от 1 до значения переменной tr_sum, которая в свою очередь хранит сумму цифр в condlist, тех тайников, которые прошли отбор по community и condlist. Потом происходит перебор элементов таблицы avail (127), где: Переменная tr_w уменьшается на значение prob каждого элемента массива. Так происходит до тех пор пока данная переменная не станет отрицательной, как только это произошло, выдаётся тайник, чей prob был вычтен последним. Всё. Выводы... Цифра в строке condlist не какая на хрен не вероятность, а просто цифра, и каково её значение особой роли не играет. Вообще GSC вероятно немного не правильно распределили эти цифры, в алгоритме просматривается процентные соотношения, но высчитать их, зная что работает функция random физически не реально. Можно заметить, что в алгоритме две вероятности: первая определяет будет ли выдан нам тайник вообще (121), вторая определят какай именно тайник будет выдан (126), но опять же таки, просчитать какой именно - крайне трудно, а то и вообще невозможно. Так что, если хотите, чтобы тайники выдавались чаще, измените число 65 в строке 121 на меньшее. Надеюсь, что эта писанина внесёт хоть кому-нибудь, какую-то ясность в работе данного алгоритма. Спасибо за внимание. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 7 Февраля 2012 Artos Моя первостепенная задача была выяснить, что за число в condlist и на кой ляд оно вообще нужно. И я выяснил... По ходу итерации по таблице treasure_info, где проверялись условия condlist и community, переменная tr_sum хранит в себе сумму treasure_prob всех тайников прошедших валидность по условиям, а treasure_prob это и есть "наша" цифра. А также в таблицу avail заносятся все тайник у которых подошёл community. Если подошёл и condlist, то prob равняется treasure_prob, иначе 0. Зачем было так без смысленно забивать таблицу, мне не понятно, но ... В конце-концов таблица avail, при обыске трупа с которого я получил тайник, выглядит следующим образом: avail = { {k=esc_secret_anomaly_dead, prob=2}, {k=esc_secret_bandit_cross, prob=5}, {k=esc_secret_nice_place, prob=3}, {k=esc_secret_safe_farm, prob=2}, {k=gar_secret_box_blockpost, prob=3}, {k=esc_secret_village_rucksack, prob=3}, {k=val_secret_0008, prob=1}, {k=gar_secret_bandit_hiding, prob=3}, {k=esc_secret_kpp_tower, prob=2} } Все тайники с prob равным 0, я отсёк условием: if treasure_prob ~= 0 then ещё на этапе создания этой таблицы, поскольку таковые значения абсолютно ни на что не влияют. Без такового условия, данная таблица имела бы следующий вид, т.е. по сути то, как она выглядет в оригинале: avail = { {k=esc_secret_anomaly_dead, prob=2}, {k=bar_secret_0010, prob=0}, {k=gar_secret_concrete_blocks, prob=0}, {k=val_secret_0026, prob=0}, {k=ros_secret_0011, prob=0}, {k=ros_secret_0006, prob=0}, {k=bar_secret_0002, prob=0}, {k=mil_secret_0028, prob=0}, {k=mil_secret_0012, prob=0}, {k=rad_secret_0004, prob=0}, {k=val_secret_0023, prob=0}, {k=val_secret_0022, prob=0}, {k=bar_secret_0006, prob=0}, {k=agr_secret_inventory_schlosser, prob=0}, {k=agr_secret_box_institute, prob=0}, {k=esc_secret_bandit_cross, prob=5}, {k=esc_secret_nice_place, prob=3}, {k=bar_secret_0005, prob=0}, {k=rad_secret_0002, prob=0}, {k=mil_secret_0000, prob=0}, {k=rad_secret_0000, prob=0}, {k=yan_secret_0000, prob=0}, {k=bar_secret_0007, prob=0}, {k=agr_secret_sewers, prob=0}, {k=ros_secret_0022, prob=0}, {k=agr_secret_rotted_log, prob=0}, {k=ros_secret_0020, prob=0}, {k=val_secret_0004, prob=0}, {k=val_secret_0017, prob=0}, {k=ros_secret_0015, prob=0}, {k=ros_secret_0021, prob=0}, {k=esc_secret_safe_farm, prob=2}, {k=gar_secret_metal_hiding, prob=0}, {k=mil_secret_0009, prob=0}, {k=agru_secret_mole_cave, prob=0}, {k=agr_secret_safe_bush, prob=0}, {k=val_secret_0005, prob=0}, {k=mil_secret_0004, prob=0}, {k=agr_secret_box_radiation, prob=0}, {k=yan_secret_0010, prob=0}, {k=val_secret_0003, prob=0}, {k=mil_secret_0003, prob=0}, {k=gar_secret_bus_rucksack, prob=0}, {k=yan_secret_0013, prob=0}, {k=mil_secret_0016, prob=0}, {k=gar_secret_bus_tube, prob=0}, {k=yan_secret_0012, prob=0}, {k=yan_secret_0011, prob=0}, {k=yan_secret_0009, prob=0}, {k=yan_secret_0008, prob=0}, {k=gar_secret_rucksack_noones, prob=0}, {k=yan_secret_0007, prob=0}, {k=bar_secret_0001, prob=0}, {k=yan_secret_0006, prob=0}, {k=bar_secret_0014, prob=0}, {k=gar_secret_south_safe, prob=0}, {k=yan_secret_0005, prob=0}, {k=esc_secret_refuge, prob=0}, {k=yan_secret_0004, prob=0}, {k=yan_secret_0003, prob=0}, {k=gar_secret_box_blockpost, prob=3}, {k=esc_secret_village_rucksack, prob=3}, {k=yan_secret_0002, prob=0}, {k=gar_secret_escavator, prob=0}, {k=yan_secret_0001, prob=0}, {k=rad_secret_0005, prob=0}, {k=agr_secret_agrosafe, prob=0}, {k=val_secret_0032, prob=0}, {k=gar_secret_north_tube, prob=0}, {k=pri_secret_0002, prob=0}, {k=gar_secret_east_tube, prob=0}, {k=bar_secret_0018, prob=0}, {k=agr_secret_cross, prob=0}, {k=bar_secret_0004, prob=0}, {k=val_secret_0025, prob=0}, {k=rad_secret_0003, prob=0}, {k=val_secret_0021, prob=0}, {k=val_secret_0015, prob=0}, {k=agru_secret_box_bloodsucker, prob=0}, {k=agr_secret_rucksack_window, prob=0}, {k=val_secret_0010, prob=0}, {k=agr_secret_safe_wall, prob=0}, {k=ros_secret_0016, prob=0}, {k=val_secret_0008, prob=1}, {k=x16_secret_0001, prob=0}, {k=val_secret_0006, prob=0}, {k=val_secret_0002, prob=0}, {k=pri_secret_0000, prob=0}, {k=agru_secret_bandit_obschak, prob=0}, {k=val_secret_0000, prob=0}, {k=bar_secret_0017, prob=0}, {k=gar_secret_bandit_hiding, prob=3}, {k=gar_secret_cistern_pipe, prob=0}, {k=ros_secret_0000, prob=0}, {k=bar_secret_0012, prob=0}, {k=mil_secret_0014, prob=0}, {k=gar_secret_forest_log, prob=0}, {k=mil_secret_0002, prob=0}, {k=mil_secret_0015, prob=0}, {k=ros_secret_0002, prob=0}, {k=ros_secret_0013, prob=0}, {k=agr_secret_roof_box, prob=0}, {k=bar_secret_0015, prob=0}, {k=ros_secret_0012, prob=0}, {k=x16_secret_0000, prob=0}, {k=ros_secret_0008, prob=0}, {k=agr_secret_safe_tree, prob=0}, {k=ros_secret_0007, prob=0}, {k=ros_secret_0009, prob=0}, {k=esc_secret_kpp_tower, prob=2}, {k=ros_secret_0001, prob=0}, {k=val_secret_0024, prob=0}, {k=bar_secret_0011, prob=0}, {k=rad_secret_0001, prob=0}, {k=agr_secret_gray, prob=0}, {k=mil_secret_0013, prob=0}, {k=agr_secret_box_stairs, prob=0}, {k=val_secret_0027, prob=0}, {k=pri_secret_0001, prob=0}, {k=val_secret_0001, prob=0}, {k=mil_secret_0005, prob=0}, {k=val_secret_0011, prob=0}, {k=pri_secret_0003, prob=0}, {k=bar_secret_0016, prob=0}, {k=mil_secret_0018, prob=0}, {k=bar_secret_0009, prob=0}, {k=ros_secret_0003, prob=0}, {k=gar_secret_car_hiding, prob=0}, {k=ros_secret_0017, prob=0}, {k=esc_secret_thief, prob=0}, {k=mil_secret_0017, prob=0}, {k=pri_secret_0004, prob=0}, {k=mil_secret_0007, prob=0}, {k=bar_secret_0000, prob=0}, {k=gar_secret_rotted_stump, prob=0}, {k=mil_secret_0011, prob=0}, {k=agr_secret_rucksack_laketube, prob=0}, {k=agr_secret_pipe_rucksack, prob=0}, {k=agr_secret_tree_rucksack, prob=0}, {k=mil_secret_0008, prob=0}, {k=mil_secret_0010, prob=0}, {k=gar_secret_avoska, prob=0}, {k=bar_secret_0008, prob=0}, {k=mil_secret_0001, prob=0}, {k=mil_secret_0006, prob=0}, {k=agr_secret_truck, prob=0}, {k=bar_secret_0003, prob=0}, {k=bar_secret_0019, prob=0}, {k=gar_secret_rucksack_ruins, prob=0}, {k=val_secret_0007, prob=0}, {k=agr_secret_box_zavhoz, prob=0}, {k=agr_secret_rucksack_blue, prob=0}, {k=ros_secret_0023, prob=0} } Как можно заметить она существенно больше... Причем таковая таблица, для одинаковых по рангу и группировке НПС, формируется идеинтичная, причем в непонятном для меня порядке, почему перебор идёт не в том порядке, в котором тайники прописаны в treasure_manager.ltx? Дальше, у нас идёт условие выдачи тайника впринципе: if tr_sum == 0 or math.random(100) < 65 then return end Как видно, тайник действительно выдастся с вероятностью 35%. А вот далее идёт выбор самого тайника: 1:local tr_w = math.random(tr_sum) 2:for k,v in pairs(avail) do 3: tr_w = tr_w - v.prob 4: if tr_w <= 0 then 5: --' Выдать тайник 6: self:give_treasure(v.k) 7: break 8: end 9:end Первая строчка данного кусочка кода, записывает в переменную tr_w случайное число от 1 до значения переменной tr_sum, которая, в свою очередь, хранит в себе сумму treasure_prob всех тайников прошедших валидность, или можно сказать, что tr_sum равна сумме всех prob, из таблице avail, это одно и тоже. Затем ещё один цикл, в котором переменная tr_w уменьшается на значение prob, каждого тайника из таблицы. Как только эта переменная становиться отрицательной, то выдаём тайнкци с именем k, чей prob оказался последним (строки 4,6 приведённого "кусочка"). "Весовой эквивалент" - да, возможно так и есть. Поскольку таблица avail формируется одинаковая для одной и той же группировки, то впринципе, можно вычислить и процентное соотношение данного числа, естественно, что в разных случаях (ранг НПС, локация на которой мы сейчас) это соотношение будет разным, поэтому задать одинаковую вероятность для нескольких, вроде как, подходящих НПС, заранее неполучится... Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 10 Февраля 2012 Wookie, в теме "Справочник по функциям и классам" есть подробное описание скриптовой составляющей диалогов, в том числе в третьей части рассказывается и о расстоянии на котором можно открыть диалоговое окно: "Диалоги. Часть 3" Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 12 Февраля 2012 (изменено) Касательно первого пункта из вопросов MIDERY. Ребята, всё намного проще. Инфопоршень который стоит в качестве проверки: <dont_has_info>escape_volk_ак74u_done</dont_has_info> и инфопоршень который выдаётся: <give_info>escape_volk_ak74u_done</give_info> просто напросто разные. В первом случае буквосочетание "ак" написано кириллицей и только. Artos Чтобы диалог не появлялся нужно чтобы стояла общая проверка (прекондишен) для диалога, а не в самм диалоге. Это или в скриптах или в логике НПС делается.Вовсе не обязательно. Тег <precondition> используется для проверки функции, MIDERY же в своём диалоге использовал наличие одного инфопоршня и отсутствие другого, в качестве условия появления диалога в целом. gruber, а о каком собственно лимите идёт речь? Изменено 12 Февраля 2012 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 12 Февраля 2012 (изменено) gruber, а можно по подробнее об этом, поскольку мне казалось, что ограничения как такового нет, а инфопоршни читаются при каждой загрузке игры. Изменено 12 Февраля 2012 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 13 Февраля 2012 CON, для ГГ что ли? Ответ прост, как и сам вопрос: в all.spawn убрать из секции спавна актора строку device_torch. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 13 Февраля 2012 CON, конечно можно - скриптом. Приблизительно вот так: local obj_torch = db.actor:object("device_torch") if obj_torch then db.actor:drop_item(obj_torch) end Я выбросил предмет, можешь его удалить в последствии. SWoBoDoWeTH, загляни в шапку этой темы:"The new weapon and its addition in S.T.A.L.K.E.R", там есть ответ на твой вопрос. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 13 Февраля 2012 MIDERY. Найди отдельно для себя: проверка на поднятие предмета и вывод сообщения (собственно это у тебя есть), и посмотри как это сделано в принципе. P.S. Извини, если обидно прозвучит, но по моему ты пытаешься прыгать выше головы... Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 14 Февраля 2012 Boofer, спавн происходит далее через скрипт, т.е. с использованием переменных lvid, gvid и pos или руками вписываешь? Если руками и уверен в правильности скрипта, то делай выводы... Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 15 Февраля 2012 Artos, почему именно нет пакеты? Ведь есть методыfunction turn_on(); function turn_off(); для класса hanging_lamp. Это рудимент? Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 17 Февраля 2012 (изменено) Nic101 Давай начнём с того, что всё же нужно соблюдать элементарные знания правописания, а также будем использовать теги для отделения кода от текста. А теперь по твоему посту: Файла release_body_manager.script в игре просто не существует, не по тому, что ты неправильно написал расширение файла, а потому, что разработчики просто такового не создавали. Поэтому и комментировать в файле xr_motivator.script, будет нечего, и открывать собственно также нечего. Всё бы ничего, но ты не ошибся, т.е. решение действительно рабочее. Но вот есть одна большая проблема: ты не в изначальном вопросе, не в посте выше не указал версию игры, хотя пишешь ты в тему по ковырянию ТЧ (Тень Чернобыля), а не в тему по Зову Припяти, где твой ответ будет актуальным и то с некоторыми оговорками. Итого: 1. Правильно выбирай тему; 2. Правильно задавай вопрос; 3. Нашёл решение - поделись, а не бросайся полученными знаниями; 4. И пиши, пожалуйста, грамотнее. Спасибо за понимание. Изменено 17 Февраля 2012 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 17 Февраля 2012 MIDERY Во-первых, из рестриктора можно вызывать и функцию напрямую, но она должна быть в файле xr_effects.script, вот так: on_actor_inside = %=tester% И функцию измени, чтобы не принимала никаких аргументов, вот так: function tester() news_manager.send_tip(db.actor, "%c[255,255,128,128]Блаблабла:\n%c[default]Проверка", nil, nil, 30000) end Во-вторых, ты темой ошибся. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 19 Февраля 2012 Сообщение от модератора ColR_iT Ребята, перемещаемся с вопросами о косяках моделей, костях, конвертации из одного формата в другой, в соответствующие темы. Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 22 Февраля 2012 Вольт В файле esc_trader_door.ltx замени вторую строчку на вот эту: active = ph_door@closed Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 24 Февраля 2012 fzz Ох, ну и следопыт же ты. Десять раз говоришь искал!? А что именно ты искал? Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 28 Февраля 2012 (изменено) FANAT Универсальные гулаги (general_lager). По своей сути это вид гулага, который задаёт все значения для схем по умолчанию. А работы распределяет исходя из наличия путей на уровне, где находится таковой гулаг. Т.е. он автоматически соберет все точки путей на уровне начинающиеся на имя смарта и "парсит" их названия следующим образом: (имя смарта)_(схема)_(номер схемы)_(поднастройка схемы)_(состояние гулага). И компонует всё это дело в работы. Работой будет по сути путь вида esc_gen_lager_walker_1_walk_1 и esc_gen_lager_walker_1_look_1, здесь: esc_gen_lager - имя смарта; walker - схема; 1 - номер схемы. Если нужно например, несколько однотипных схем, то просто задаём несколько номеров; walk - поднастройка схемы, т.е. что именно это за точка; 1 - состояние гулага. 1 - день, 0 - ночь. С одной стороны всё это упрощает создание гулага, с другой же ИМХО наоборот. Но тут уже кому как. ------------- tonloon Как раз таки дело в "параметрах этих ogg файликов". Комментариям для звуковых файлов в игре отведена отдельная роль, при помощи них, НПС адекватно будут реагировать на звуки. Звуки нужно прогонять через СДК, только тогда из консоли исчезнут надписи Missing ogg-comment. Собственно эта надпись сама за себя говорит, что не правильные комментарии в файле. Изменено 28 Февраля 2012 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
ColR_iT 171 Опубликовано 28 Февраля 2012 wikreznowНа самом деле всё гораздо проще. ... fixed_bones = link - где link имя кости, которую фиксируешь. Для оружия это может быть wpn_body ...Вместо link нужно вписывать любую кость, которая есть у объекта, который ты спавнишь, именно за эту кость будет зафиксирован предмет. Для оружия это wpn_body, например, для ведра это может быть bone01 и т.д. Посмотреть наличие и название костей можно в SDK в Actor Editore. Как нанести предмету хит можно посмотреть вот в этом посте: Наносим хит предмету (третий спойлер снизу). Почитать о классе hit можно вот здесь: hit (спойлер с именем "Далее"). Поделиться этим сообщением Ссылка на сообщение