Dennis_Chikin 3 662 Опубликовано 10 Ноября 2015 Просто, 32 непися в онлайне - это уже слегка перебор по-любому. Ну и как выяснили, столько и не надо, чтоб эффекты УЖЕ получить. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 11 Ноября 2015 (изменено) (для поиска: se_respawn, респавн)Итак, наконец, мы добрались до собственно потрохов: почему попытки что-то "подкручивать" лишь усугубляют. Вот не думал, что это кому-то надо объяснять, однако ж, на дворе шел 2015 год...)Возьмем для наглядности скрипт из amk. Ибо, как уже замечено, на дворе - 2015-й.Ну, одна строчка в update(), который, собственно, и вызывается в онлайне, самоочевидна. А вот далее (ну, вы поняли): function se_respawn:execute() if self.already_once_spawned == true then return end if self.idle_spawn_min == -1 then return end if self.respawn_time < game.get_game_time() then local idle_time = game.CTime() idle_time:setHMSms( math.random( 24, 32 ), 0, 0, math.random( self.idle_spawn_min, self.idle_spawn_max ) * 1000 ) self.respawn_time = game.get_game_time() + idle_time self:spawn() end end Первые 2 здесь - это для прости-господи респавнеров, которые срабатывают либо один раз в жизни, либо, кому-то показалось проще вместо alife():create() городить огород с прибиванием гвоздями в олспавне. Ну, да, борьба с читерами - это - святое. То, что такой "респавнер" замечательно грохается, либо, все что нужно, спавнится 100500 разными способами в куда угодно в любых количествах - ну а кого это волнует ? Зато виртуальные читеры в очередной раз виртуально посрамлены.Но вот дальше... А дальше, проверяется, не настало ли время очередного респавна, каким-то образом вычисленное и сохраненное. И ежели настало - тадам... Нет, мы ЕЩЕ ничего не спавним. Мы вычисляем время СЛЕДУЮЩЕГО респавна !Все все поняли ? Нет ? Время следующего, Карл !То есть, не важно, надо спавнить, не надо спавнить... Оно будет вычислено, и будет дожидаться следующей проверки. В том числе, если спавнить ничего не надо.Теперь, внимание, вопрос: если надо заспавнить через секунду после вычисления ? Ответ: ПРАВИЛЬНО. Вот когда настанет это самое вычисленное, тогда и...А если, нет, ну совершенно случайно, игрок в прошелся по всем нашим 100 лагерям по 300 неписей (все, разумеется, с одинаковыми тимами, сквадами и группами, хотя к данному вопросу это отношения уже не имеет), и все зачистил, а через секунду наступило время спавна ? И еще раз - ПРАВИЛЬНО. Игрок получает на голову все свои 300 монстров для всех 100 лагерей.Ура, товарищи !Ну, то, что некий рэндом этого самого времени теоретически должен вычисляться из 2-х цифр, а если взять первый попавшийся олспавн, мы скорее всего увидим там ОДНУ цифру в типа 10 игровых минут (то есть, одну реальную минуту), из которой и предполагается вычислять рэндом, это уже так - мелочи жизни.Собственно в idle_time:setHMSms( math.random( 24, 32 )... мы уже видим попытку бороться с авторами олспавнов, вводя принудительно задержку от 24 до 32 в данном случае часов, к его 10 минутам), но, см. пункт 1-й, про то, как это время вычисляется и используется.Теперь, надо ли кому-либо объяснять, как используются значения min_count, max_count и max_spawn, или все понятно, так сказать, по аналогии ?Замечу лишь, что даже правильно прописав вот эти самые min_count и max_count в силу опять же описанного выше, все будет заполнено под завязку, а разница лишь в том, за один заход, или за несколько.Вопрос: что с этим можно сделать ?Очевидно что, во-первых, вычислять время следующего спавна только после того, как спавн ДЕЙСТВИТЕЛЬНО случился тьфу, не случился, а ПОНАДОБИЛСЯ. Или не случился, но по уважительной причине. Иначе следует проверять, не пора ли, но вот спавн начинать вот как раз через вычисленное время. Заодно, хе-хе, и рандомизируется, как надо.Во вторых, заранее вычислять количество, ДО какого надо спавнить. И запоминать. Если вдруг к нужному моменту понадобилось больше - опять же, переносим на следующий раз.Да, еще неплохо бы спавн не сразу по 100 штук всего и по-больше, а по 1 штук за апдейт. Тогда и табунами не будут ходить, во-первых, а во-вторых, прекратятся эти безобразные рывки, которые проиходят при спавне запланированного табуна в 300 (нет, лучше - в 500 электропсикислотноогнеметных химер залпового огня), а потом удаления 499 лишних).Впрочем, это у нас русский форум , а на дворе кончается всего-лишь 2015 год ...P.S. Да, собственно, это и есть причина, по которой с респавнерами, как чем-то, подлежащим апдейту через движок, надо кончать. 8 лет назад еще.Переносить на опрос, скажем, по одному СМАРТУ в 5 секунд в моменты, когда движок не загружен, а там уже проводить обслуживание, вычисление количеств/времени, и проверять уже это самое вычисленное.Для чего же на самом деле хорош респавнер, как он есть - это реализовать через него, скажем, спавн артов, привязанных к аномалиям. (Случайный/спавн при сработке, "варка" и т.д).Вот здесь - да, определили, что аномалия должна чего-то там родить через какое-то время, создали спавнер, он отработал - удалили. Сам он к аномалии больше не привязан - то есть, все вот эти динамические аномалии, выбросы, и т.д. - великолепно переживет, и сохранит что надо, до нужного момента. А не хранить всякую ересь в нетпакете актора. Изменено 11 Ноября 2015 пользователем Dennis_Chikin 1 1 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 12 Ноября 2015 Разовый спавн 10 объектов, особенно, в цикле - спавн-попытка регистрации-удаление - вполне заметный рывок. На первом проходе всех апдейтов (10-20 минут после НИ), актор движется вот этими самыми рывками. Попытка выдать их за "эффект слабого здоровья" - довольно наивна. По поводу разборок о плагиатах - их традиционно начинают именно сами плагиаторы. Иного еще не видел. И, да, единственная защита - публиковать, до того, как такой вот умник подсуетился. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 18 Ноября 2015 (изменено) В общем, по последним издевательствам и по медитации над исходниками (индусский и китайский код, а также их комбинации, предназначены не для изучения, а именно для медитации), team - общая память. Сквад - "союзнические отношения" между соседними смартами. То есть, уникальные для каждого непися - не надо, а вот для двух смартов, где неписи с одинаковым тимом, и оба - в онлайне - желательно, чтобы увидев актора у моста, блокпост его не шел убивать в, если игрок сохранился/загрузился в бункере сидоровича. А вот если надо, чтобы тот блокпост по тревоге занимал места, как написано в работах для 2-го стейта, а не вылезал всей толпой бегать по всей локации за оным актором (ну и тем более - агропром) - у того патруля, и у капитана с охранниками и снайперами должен быть разный тим. Ну и его смену надо дорабатывать - "штатных" средств нет. По аномальками и респавнерам - не, реально удобно. Вот аномальке заказали арт родить, а аномалии у нас динамические. Создаем респавнер, прописываем в него арт, и благополучно забываем. Если хотим, чтобы с исчезновением аномалии больше ничего не рождалось - можно ж в том респавнере проверку на существование аномалии добавить. Или еще что. Именно смысл в том, что вообще-то - полная свобода. Он же и за судьбой рожденных артов может следить. По крайней мере, это ЕДИНСТВЕННАЯ польза, которую я лично от них обнаружил. 2 Nazgool: чтобы применить какой-то метод, сначала надо знать, что есть необходимость в его применении. И даже через coroutine, вызывая цикл на 100 созданий, запихиваний в смарты (с перебором всех существующих) и удалений - все равно получим цикл на 100 этих самых. Вот от том, собственно, и пост. Изменено 18 Ноября 2015 пользователем Dennis_Chikin 1 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 18 Ноября 2015 (изменено) По сквадам - не нужно. Переопределяется а ослпавне для смарта, или принудительно в работах. По тимам - в общем, тоже не особенно надо, поскольку все равно ручная работа. А вот средства задать его, так же, как и сквад - да, надо. Этой проблемы нет при изначальном спавне, и, в принципе, при тщательном ручном прописывании связок работы-принимаемые профили, но вот когда спавниться что угодно, где угодно, и захватывается чем угодно - ой таки вэй. "Попытки кстати были, и кстати удачные." а потом идем в соседнюю тему, и читаем вопросы, задаваемые в 2015 году. Про dunin_ammo.script, например. И там же читаем совет прописать новые патроны в сами-знаете-куда. Причем в общем-то другого ни кто и не даст, ибо эту рухлядь править... Хе, вчера в очередной раз делал "совместимость" по сэйвам для скрипта, который "почему-то перестал работать", чтобы заменить его на человеческий. Выдирал цепочку c self.weather_manager = level_weather.get_weather_manager() self.weather_manager:on_save() и вставлял считывание по флажку stringZ и какого-то int'а. В тот же самый нетпакет того же самого актора, Карл. Через 5 скриптов ! В 2015ом году. Вместо, банального, db.storage[0].pstor, если уж так хочется это уродливое каждый раз руками набивать. Кстати, выложи уже сюда xr_spawner и тот вертолет. А то тебе же потом и предъявят, что ты типа "код спер". А то мне вот опять же не далее как вчера уже в очередной раз успели моим файлом 2009го года в нос потыкать. Как плагиатору. Изменено 18 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 18 Ноября 2015 Детектор просто снесен давно. По поводу перепаковок - тоже существует уже лет, этак, 7 - куча альтернативных. Не говоря об "умных тайниках" и "умных рюкзаках", куда кладется сколько надо, и достается тоже сколько надо, а таскающие по локациям 10000 пачек по одному патрону - ну, если задаться целью вызвать крах игры - эта цель будет достигнута так или иначе. И даже гораздо более простыми средствами. Собственно, с первого момента введения первой "разгрузки", первого магазина и прочего первого подгузника вся "перепаковка" лишилась смысла чуть более, чем полностью. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 18 Ноября 2015 (изменено) Весь детектор - 2 строки в непосредственно биндсталкере, или в любом удобном месте. Динамически подключаемые. И то - не используется, по тому как есть только одна локация, где нечто подобное в принципе предусмотрено. А подгузники, и иже с ними - они просто фактом появления сделали то старье ненужным. Сами-то подгузники можно и не включать. И, да, лично мне умные тайники больше нравятся. Изменено 18 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 18 Ноября 2015 (изменено) Сохранение не нужно. Хиты великолепно сохраняются в акторе. Сколько получил - все его. Интенсивность новых великолепно считается по дистанции до выбранной точки. И, кстати, "рестрикторов" там тоже не надо. Рестриктор делает то же самое, но через 10 петель кишечника. Надо, на уровне, по инфе, добавить рассчет расстояния и выдачу хита. Если не уровень, и не инфа, не добавлять ничего. Изменено 18 Ноября 2015 пользователем Dennis_Chikin 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 18 Ноября 2015 (изменено) Он как бы позволяет. Но, в отличии от групп и сквадов, нет способа задать его при выдаче работ. В смысле, прописав в свойства смарта или в работы. Если только извратом в предикат. Изменено 18 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 19 Ноября 2015 (изменено) В смысле, метод есть, и регулярно вызывается. Вот тем самым xr_gulag при распределении работ. Но именно тим - оставляет родной, неписевый. То есть, надо допиливать напильником. Я вот об чем. Делать просто "рандомизацию" - а зачем ? У нас 3-4 смарта с неписями одного вида на локе. Из них в онлайне одновременно - ну вот 3 на Кордоне, 4 на агре. И то не понятно - на кой, собственно, их в онлайне принудительно держать. Сначала героически создаем себе проблемы, затем - героически их преодолеваем. Или еще лучше - устраиваем очередную "охоту на читеров", из-за которых у модододела колбаса в холодильнике плесенью покрылась, и жена с соседом изменила. Аж тьфу. Изменено 19 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 20 Ноября 2015 <<И собственно почему бы не допилить и причем тут "охота на читеров" я не знаю.>> Ну просто я пока не вижу чего-то такого, требующего радикального вмешательства. В данном случае. Ради 5-ти смартов, сделанных и расставленных неподумавши. Поправить вот эти конкретные 5 штук, да и все. Как и заворачивания работ каждую в отдельный псевдообъект. Мороки много, толк - сомнителен. Как бы, другой конец шкалы радикализма, противоположный объявлению виновниками собственной лажи (или лажи своего Гуру) вот тех самых неведомых читеров. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 20 Ноября 2015 (изменено) Меня смущает то, что как минимум в двух местах при выборе работ явно требуется сортировка. - объектам, + плоским таблицам. А хранение информации о неписях - вот это - точно надо переделывать все. Ну и, да, если уж переделывать - так мы, помнится, бурно обсуждали в более соседних темах преимущества и недостатки, и я все-таки склоняюсь вообще к убежищам. Вообще чисто движковым. То есть, плясать от оценки движком укромности рельефа в окрестностях некоторой заданной точки (а также -собственно, поиск таких точек), и там все и организовывать. Покойникам же (то есть, всей системе смартов, гулагов и респавнеров) - устроить торжественное погребение. Изменено 20 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 20 Ноября 2015 Если делать глубокую переработку, движок трогая, то игрок движку здесь ни как вообще. Модмейкер смотрит на локу, и ставит точки, где он примерно хотел бы что-то видеть. Дальше движково ищем вот эти вот самые "укрытия", да хоть бы стандартные, только, естественно, без того, от кого укрываемся, со всех сторон, и формируем там позиции стояния-сидения-брожения. Но, это мы уже ушли в мечтания, похоже. Имея же то, что имеем - то есть, некрофилическую вполне систему этих самых смартов, не кидаться в глубокую переделку синтаксиса, а вот просто руководствоваться правилами достаточно не сложными, и у кого где проблемы - аккуратно поправить теми средствами, какие есть. Правка заведомо кривых конфигов скриптами - занятие почтенное, традициями освященное, но не сильно благодарное, да. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 21 Ноября 2015 (изменено) То есть, все-таки вернуть несколько гулагов под одним смартом ? Да, по сравнению со стэйтами - явно лучше. И можно заодно сбрасывать всякое странное, чего неписи успели неведомым путем нахвататься в предыдущем. Также упрощается контроль за валидностью работ/занятых, и все эти приоритеты {здесь текст удален по причине п2.0 правил} - тоже таки да - проще становится. P.S. А вот по злопамятности неписей, похоже, грядут новые шокирующие подробности... enable_memory_object( ..., false ) - внезапно, похоже, очень даже при чем. Изменено 21 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 24 Ноября 2015 (изменено) модераторское: дискуссия слегка переместилась в эмоциональную сферу, а предложения оппонентов, на сколько я вижу, читаются невнимательно. Ну и сами предложения эти несколько неконкретны. По крайней мере лично я понял предлагаемое совершенно иначе, чем остальные. Предлагаю внимательно перечитать хотя бы СОБСТВЕННЫЕ тексты, и попробовать сформулировать более четко и доходчиво. Я через некоторое время напишу, как именно понял. 2 Murarius: не совсем так. В некоторых случаях код не нужен. Или его еще нет. А вот описание в этих случаях желательно бы как можно более однозначное. Изменено 24 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 24 Ноября 2015 (изменено) Вроде, 20 минут выкроил, выполняю обещанное. Итак, мне вот тоже не нравятся работы с состояниями. Не нравятся тем, что получается слишком много букв, и очень трудно контролировать все это глазами. Буквально пару дней назад описка с 0 вместо 1 - и пол дня на то, чтоб ее найти. Простыни получаются преразвесейшистые. Накладные расходы по получению/сортировке/переключению работ со стейтами - тоже не маленькие. Но в данном случае как раз имеем повод отбросить хакерские замашки в пользу читаемости, и даже не задумываться особо про то, какой же из вариантов будет быстрее на сотую микросекунды . Из собственно же методов борьбы с развесистыми простынями вижу два простых (в смысле, скриптовых, не дожидаясь, пока с неба свалится экзешник, чтоб сам кофе варил, и за пивом бегал): 1. Развернуть часть текущего ужаса и кошмара в плоские таблицы (все равно xr_gulag в итоге именно их хочет, и формирует). То есть, не вот вставка в переданную таблицу, и не проверка на каждый чих "подходящести", а отдать готовые. При некотором усилии можно эти работы со стейтами записывать так, что просто скользя глазом замечаешь отличия. И руками можно посчитать. А потом валидатор напустить, в сомнительных моментах. Этот код я вкладывал в более специализированной теме, ссылку давал, примеры давал, повторять смысла не вижу. Кому надо - найдет/посмотрит. 2. Перейти, вот как я понял прозвучавшие здесь предложения, к системе один смарт - несколько гулагов в нем. Преимущество - простыни становятся гораздо менее обширными, общие параметры из работ выносятся в параметры гулага, можно даже банально эти работы наследовать, подставляя отличия. То есть, для каждого стейта - один гулаг, в смарте - по гулагу для каждого стэйта. С точки зрения кода, навскидку, переключение между гулагами - будет проще-изящнее-быстрее. На самом деле даже "освобождать/переназначать/и т.д." ни кого не надо. Переключили гулаг, переинициализировали логику, и все. При покидании смарта - запустили "сборку мусора". В обоих случаях, заметим, НЕ требуется срочно переделывать все готовое. Оба варианта вполне дополняют стандартный. Собственно, в моем варианте с плоскими таблицами есть вариант такого вот одностейтового гулага, и осталось только "когда-нибудь" дополнить до "более одного гулага в смарте". Работа вот с этим одностейтовым - по факту проще и по факту, оно быстрее. Проверено. То есть, если коротко, то оно вот как-то так в итоге выглядит: local g_comms = { ["atp_brigada"] = "stalker", -- 14.08, Калинин ["atp_fabrika_bandit"] = "bandit", -- ["atp_stalk"] = "stalker", -- допа 2011 ... local g_jobs = { ["atp_fabrika_bandit"] = { -- Бандиты на АТП { section = "logic@atp_fabrika_bandit_walker1", idle = 0, prior = 10, state = {0}, in_rest = "", out_rest = "" }, { section = "logic@atp_fabrika_bandit_walker2", idle = 0, prior = 10, state = {0}, in_rest = "", out_rest = "" }, ... local t_states = { ["esc_blokpost"] = esc_blokpost, ["esc_lager"] = esc_lager, ["esc_bridge"] = esc_bridge, ["esc_fabrika_bandit"] = esc_fabrika_bandit, ["esc_dogs_to_fox"] = esc_dogs_to_fox, ["esc_specnaz"] = esc_specnaz, ["esc_boars_dogs"] = esc_boars_dogs, ["esc_killers"] = esc_killers, ["esc_dogs_swarm"] = esc_dogs_swarm, ["esc_stalker_camp"] = esc_stalker_camp, ["esc_corps"] = esc_corps, ["esc_assault"] = esc_assault } function load_states( gname, type ) -- стэйта нет - значит, всегда 0 return t_states[type] end function checkStalker( npc_community, gulag_type, npc_rank, obj ) local c = g_comms[gulag_type] if c then return c == npc_community end return ( obj["profile_name"] and obj:profile_name() == g_names[gulag_type] ) or false end function checkMonster( npc_community, gulag_type ) local c = g_comms[gulag_type] if c then return c == npc_community end if gulag_type == "esc_boars_dogs" then return npc_community == "dog" or npc_community == "boar" end return false end Ну вот как-то так, да. Это "дополнительный", альтернативный формат записи. Но все еще один смарт - один гулаг. С несколькими - в 2 раза сокращается количество строк, и сами строки упрощаются (от них в основном только секции логики и нужны) Вот что я не понял в звучавших предложениях - это заворачивать КАЖДУЮ работу в "псевдообъект". Подозреваю, что имелось в виду нечто иное. Изменено 24 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 24 Ноября 2015 prior = 5 - это нужно, когда есть работы, на которых должен быть кто-то конкретный, или когда нужно, чтобы из всех возможных заняты были именно эти. У меня работы с условиями всегда проверяются первыми, так что здесь уже задумываться слишком сильно не надо. Вообще, опять же, в мультигулаговый смарт такие отдельным гулагом имеет смысл оформлять. Избавились. сквады - имеет смысл менять динамически, раз пошла такая пьянка. группы - как выяснили, нужны там, где задействованы в путях с сигналами. position_threshold - это интересная такая штука... Смысл - надо ли в офлайне бежать к начальной точке пути. capacity - нужно для текущего формата, если используешь условия в работах. И для генералов. Плюс, если они у тебя прописаны для всех - можешь исправить разные косяки, дописав "запасные работы" (классика жанра - волк/фанат/шустрый, и наймы на кордоне, где при неудачном стечении обстоятельств получаещь сбежавшего непися или висяк.) Кондлисты - мне не нравятся. Медленные, и читаются плохо. Лучше иметь возможность задавать явно. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 24 Ноября 2015 Этот "миф" дан вполне в ощущениях. Вот так оно блин там сделано: да, когда дошел - считается заступившим, назначается логика и т.д. А вот пока НЕ дошел - регулярно вызывается self:free_obj_and_reinit(), и вот только тогда моб каким-то загадочным образом может сдвинуться с места. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 25 Ноября 2015 (изменено) Закомментите освобождение с работы для недошедших, и посмотрите на результат. В оффлайне. Изменено 25 Ноября 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3 662 Опубликовано 28 Декабря 2015 (изменено) Продолжаем разговор про xr_logic: try_sw_time1, try_sw_time2 = 0, 0 function try_switch_to_another_section( npc, st, actor ) if _G.watchdog then return false end _G.watchdog = "try_switch" if not actor then abort( "try_switch_to_another_section, scheme: %s, no actor", st.scheme or "n/a" ) end local l = st.logic or abort( "try_switch_to_another_section, invalid logic, scheme: [%s] (%s)", st.active_scheme or "none", ( npc and npc:name() ) or "script" ) local npc_id = npc:id() local sw, sw1, f local chk = { ["on_actor_dist_le"] = function ( c ) if npc.alive and npc:alive() and npc:see( actor ) and c.v1 >= distance_between( actor, npc ) then return true end end, ["on_actor_dist_le_nvis"] = function ( c ) if c.v1 >= distance_between( actor, npc ) then return true end end, ["on_actor_dist_ge"] = function ( c ) -- составляет пару с on_actor_dist_le, где >= if npc.alive and npc:alive() and npc:see( actor ) and c.v1 < distance_between( actor, npc ) then return true end end, ["on_actor_dist_ge_nvis"] = function ( c ) -- составляет пару с on_actor_dist_le_nvis, где >= if c.v1 < distance_between( actor, npc ) then return true end end, ["on_signal"] = function ( c ) if st.signals and st.signals[c.v1] then return true end end, -- FIXME: не дублировать тут имена, оставить один on_info, -- но добавлять несколько его экземпляров в список ["on_info"] = function ( c ) return true end, ["on_timer"] = function ( c ) if global_time_ms >= db.storage[npc:id()].activation_time + c.v1 then return true end end, ["on_game_timer"] = function ( c ) -- GAMETIME added by Stohe. if game_time_time:diffSec( db.storage[npc:id()].activation_game_time ) >= c.v1 then return true end end, ["on_actor_in_zone"] = function ( c ) if utils.npc_in_zone(actor, db.zone_by_name[c.v1]) then return true end end, ["on_actor_not_in_zone"] = function ( c ) if not utils.npc_in_zone( actor, db.zone_by_name[c.v1] ) then return true end end, ["on_npc_in_zone"] = function ( c ) if utils.npc_in_zone( level.object_by_id( c.npc_id ), db.zone_by_name[c.v2] ) then return true end end, ["on_npc_not_in_zone"] = function ( c ) if not utils.npc_in_zone( level.object_by_id( c.npc_id ), db.zone_by_name[c.v2] ) then return true end end, ["on_actor_inside"] = function ( c ) if utils.npc_in_zone( actor, npc ) then return true end end, ["on_actor_outside"] = function ( c ) if not utils.npc_in_zone( actor, npc ) then return true end end } for n, c in pairs( l ) do local p = profile_timer() p:start() for i = 1, 100 do if cond_name( c.name, "on_actor_dist_le" ) then if npc.alive and npc:alive() and npc:see( actor ) and c.v1 >= distance_between( actor, npc ) then sw = true end elseif cond_name( c.name, "on_actor_dist_le_nvis" ) then if c.v1 >= distance_between( actor, npc ) then sw = true end elseif cond_name( c.name, "on_actor_dist_ge") then -- составляет пару с on_actor_dist_le, где >= if npc.alive and npc:alive() and npc:see( actor ) and c.v1 < distance_between( actor, npc ) then sw = true end elseif cond_name( c.name, "on_actor_dist_ge_nvis" ) then -- составляет пару с on_actor_dist_le_nvis, где >= if c.v1 < distance_between( actor, npc ) then sw = true end elseif cond_name( c.name, "on_signal" ) then if st.signals and st.signals[c.v1] then sw = true end -- FIXME: не дублировать тут имена, оставить один on_info, -- но добавлять несколько его экземпляров в список elseif cond_name( c.name, "on_info" ) then sw = true elseif cond_name( c.name, "on_timer" ) then if global_time_ms >= db.storage[npc_id].activation_time + c.v1 then sw = true end elseif cond_name( c.name, "on_game_timer" ) then -- GAMETIME added by Stohe. if game_time_time:diffSec( db.storage[npc_id].activation_game_time ) >= c.v1 then sw = true end elseif cond_name( c.name, "on_actor_in_zone" ) then if utils.npc_in_zone(actor, db.zone_by_name[c.v1]) then sw = true end elseif cond_name( c.name, "on_actor_not_in_zone" ) then if not utils.npc_in_zone( actor, db.zone_by_name[c.v1] ) then sw = true end elseif cond_name( c.name, "on_npc_in_zone" ) then if utils.npc_in_zone( level.object_by_id( c.npc_id ), db.zone_by_name[c.v2] ) then sw = true end elseif cond_name( c.name, "on_npc_not_in_zone" ) then if not utils.npc_in_zone( level.object_by_id( c.npc_id ), db.zone_by_name[c.v2] ) then sw = true end elseif cond_name( c.name, "on_actor_inside" ) then if utils.npc_in_zone( actor, npc ) then sw = true end elseif cond_name( c.name, "on_actor_outside" ) then if not utils.npc_in_zone( actor, npc ) then sw = true end else abort( "try_switch_to_another_section: invalid condition: [%s] (%s)", c.name, npc:name() ) end end p:stop() try_sw_time2 = try_sw_time2 + p:time() local p = profile_timer() p:start() for i = 1, 100 do f = chk[string_match( c.name, "^([%D]+)" )] if f then sw1 = f( c ) end end p:stop() try_sw_time1 = try_sw_time1 + p:time() if sw ~= sw1 then log( "error", "%s ~= %s (%s, %s, %s)", tostring( sw ), tostring( sw1 ), tostring( n ), tostring( c.name ), to_str( npc ) ) end if sw then sw = switch_to_section( npc, st, pick_section_from_condlist( actor, npc, c.condlist ) ) if sw then _G.watchdog = false; return sw end end sw, sw1 = nil, nil end _G.watchdog = false return false end Сорри за неряшливый вид. Однако: sw1: 2691772.75 sw2: 7585235 Есть в этом нечто удивительное, правда ? И, кстати, оно таки ЖРЕТ. Реально жрет. Пара десятков рестрикторов и десяток неписей - очень даже ой. И, кстати, здесь можно этот самый аппетит еще поурезать вполне. Изменено 3 Января 2016 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение