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

Dennis_Chikin

Жители
  • Число публикаций

    6 272
  • Регистрация

  • Последнее посещение

  • Дней в топе

    33
  • AMKoin

    513 [Подарить AMKoin]

Весь контент пользователя Dennis_Chikin

  1. "Ставлю min_snd = 7, max_snd = 10 Вроде нормальные паузы, но иногда вторая фраза идёт сразу после первой. Ну и хотелось-бы пореже." Оно для группы в основном. Для одиночек я, кажется, дополнительно прикручивал правильную паузу. Плюс, это именно когда задали тему, и дальше они тупо ее повторяют - выбирая случайные звуки из загруженных. Для одиночных обычно используется сингл или рэндом, но в ремарке, с переходом по окончанию звука к следующей секции. Тут, естественно, будет именно сразу и однократно, пока опять на эту же секцию не вернется ("Проходи, не задерживайся!" - ага). Вообще, вся система крайне запутанная, половина звуков используется не по назначению, для второй половины что-то где-то неправильно сконфигурировано. Правильно - это все оторвать, и вызывать всю нужную озвучку через %=mysounds.soundXXXX%, либо вообще дописать для xr_logic поддержку select = myscript.myfunc, где и проверяться все что надо будет, с возвратом секции, на которую переходить, и выполняться сразу все, что нужно, если нужно.
  2. Dennis_Chikin

    У Костра XVII

    Угу, у нас в школе о подрастающем поколении заботились: кто в школьной столовой не ест - трудный подросток из неблагополучной семьи, со всеми вытекающими. Только к самому концу полегчало. По поводу баранины - вообще, там, где она доступна, больных/пораненных именно бараньим бульоном всегда выпаивали. С курицы же нынешней гастрит сразу. А с каждой второй еще и сальмонеллёз.
  3. Файл битый. И не факт, что только он. Проверил архив на гуглодиске - там целый. https://drive.google.com/open?id=1cxcZ9jSgbhcwII2sn-7HNQ2Pr-ed0uvx Вот так должно быть. Ниже конфиг текущий рабочий. https://drive.google.com/open?id=1OoJ61RBDqWpz6hC6n-InX749DsHdbtnS
  4. 2018-11-18 должно быть достаточно. Закиньте куда нибудь файл gamedata\config\weapons\w_ak74.ltx и дайте мне ссылку.
  5. Не, это на скринах вообще что-то странное... Должен быть в правой четверти экрана.
  6. Dennis_Chikin

    У Костра XVII

    Есть, но сервировку придется поменять. А к вопросу об что останется - так в нормальных питательных заведениях обычно и соль, и перец, и горчица и уксус на столе стоят. Кому сколько надо - то и добавляют. Опять же, даже в "блинных" на раздаче можно и соус выбрать. И только в школьных столовых система "жри, что дают".
  7. Оно самое. 100 - полностью блокирует оный рэндом.
  8. Dennis_Chikin

    У Костра XVII

    @Индифферентный Маргинал, Пожалуй, так и сделаю.
  9. И добавлю еще, что "не езда" БТРа - проблема комбинированная, движково/скриптовое. Если БТР по какой-то причине не может разогнаться, скриптик вырубает ему движение совсем. Но "неразгон" без видимых причин - это именно где-то глубоко в потрохах. По звукам - ну я и спрашиваю: что именно непонятно ? min_snd, max_snd - пауза между звуками, чтоб не было аццкого винегрета. rnd - на сколько я знаю, рудимент звуковых рестрикторов, который лучше не трогать вообще, prior - еще более древняя древность, которая вроде как не используется. Касательно юмора - ну вон по отношениям неписей со смартами разжевал уж куда подробнее, результат - вполне ожидаемый, чуть выше по теме наблюдаемый. 2Okichi: так я про прозекторскую и говорю. Собственно, после этого и понял, что смысла нет.
  10. team - ну, например, xr_walker.script self.move_mgr:reset( st.path_walk, t_walk, st.path_look, t_look, st.team, st.suggested_state )
  11. по звукам: function play_sound( npc, t_themes, timeout ) local t, n = {}, 0 -- список тем local tt for k, v in pairs( t_themes ) do -- проверяем существование и перекладываем в i-таблицу tt = t_list[v] if tt then n = n + 1; t[n] = v else log( "error", "play_sound, ivalid theme %s [%s]", to_str( v ), to_str( npc ) ) return false end end -- log( "info", "play_sound, themes: %s (%s)", n, to_str( npc ) ) if n == 0 then return false end n = t[math.random(n)] -- из списка тем выбираем одну t = { ["theme"] = n } get_sound( t_list[n], t, npc ) -- получаем настройки n = t.max_snd -- проверяем корректность, t - настройки if n then tt = t_grps[ get_key(npc) ] -- tt - теперь группа для непися tt.idle = math.random( t.min_snd, n ) * 1000 else -- если, например, воюют, то таблица пустая, играть ничего не надо -- log( "info", "play_sound, busy ( theme: %s )", t.theme, to_str( npc ) ) return false end n = t.into_max -- последовательный список из настроек if n and n ~= 0 then local into = t.into_id tt = db.sound[npc:id()].last_snd -- что играли до этого момента local id = tt[into] -- log( "info", "play_sound, check into: %s:%s, last id: %s (%s)", t.theme, into, tostring( id ), to_str( npc ) ) if id then if id < n - 1 then id = id + 1 else -- вышли за пределы ( при n == 1 максимальный id == 0 ) if t.into_cycled then id = 0 else -- log( "info", "play_sound, not cycled, already played (%s)", id ) return false -- для xr_kamp ! end end else id = 0 end tt[into] = id -- process_tutor_on_sound( t.theme ) npc:play_sound( into, 1, 0, 1, 0, id ) -- log( "info", "play_sound, into: %s:%s, id: %s (%s)", t.theme, into, id, to_str( npc ) ) return true end n = t.rnd_max -- выбираем 1 случайный звук if n and n ~= 0 then local rnd = t.rnd_id local id = 0 if tt.last_snd then -- а здесь мы проверяем id не непися, а группы tt = tt.last_snd if n >= 2 then -- больше одного варианта, исключаем повторы if id == tt[rnd] then id = math_random( n - 1 ) -- 0, если уже что-то было if id == tt[rnd] then id = 0 end -- криво, кстати else id = math_random( 0, n - 1 ) -- если новый, то сразу от 0 end -- elseif tt[rnd] then tt[rnd] = false; return -- нефиг попугайствовать -- пока закомментировано из-за того, что одноразовые определены как рэндом, -- взрывы вертолетов, например end tt[rnd] = id -- сохраняем в группу играемый звук else -- таблица last_snd почему-то не создана if n >= 2 then id = math_random( 0, n - 1 ) end tt.last_snd = { [rnd] = id } end -- log( "info", "play_sound, rnd: %s:%s, id: %s (%s), timeout: %s", t.theme, rnd, id, to_str( npc ), timeout or 0 ) if timeout then npc:play_sound( rnd, timeout + 1, timeout, 1, 0, id ) else npc:play_sound( rnd, 1, 0, 1, 0, id ) end return true end return false end Ну и что именно здесь непонятно?
  12. Dennis_Chikin

    У Костра XVII

    Пройдемте, гражданин! (С) Впрочем, азот и кислород - тоже вполне себе и взрывчатка, и наркотики.
  13. Dennis_Chikin

    У Костра XVII

    @W.A.S.P., эфирные масла, масло какао, фосфолипиды, белки, целлюлоза, крахмал, таннин, сахара, меланин, соли, кофеин. Правда, тут не только перегонка нужна, ну и это верно для собственно какао, ибо до нас от него в основном доезжает одна целлюлоза и немножко красителя.
  14. Dennis_Chikin

    У Костра XVII

    Мда, начало трэда тоже явно кому-то с кем-то изменило, раз его это самое... Что до британцев - ну, они вообще известные затейники. Вспомнить те же крестовые походы, и чем там занимались двое глав враждебных государств, если когда один приболел, второй присылал ему корзины с фруктами, а когда войнушка формально закончилась, и начали разъезжаться по домам - первого немедленно захватил "в плен" глава третьего государства...
  15. Dennis_Chikin

    У Костра XVII

    В британиях за high treason (то есть, измену против Короля) в числе прочего полагалась кастрация.
  16. Огср - это как раз почти ТЧ. Ну, в теории должно работать все, кроме мультплэера, который все равно не работал. Если не работает что-то еще - или внимательно читать про изменения, которые надо внести, или сообщать разработчикам о проблеме.
  17. Следующая проверка: if self.accepted_communities and not self.accepted_communities[community] then return false end здесь, вроде, все очевидно - берется из custom data смарта, строчка communities = чего-то-там, через запятые, если не совпало ни с одним - не пускаем, если строчки нет вообще - проверяем дальше. Понятно, что никакие назначения не конкретного непися или конкретного монстра в конкретный смарт ничем не помогут. if obj_agreement ~= agreed_exclusive and not self:check_preset( community, obj:rank(), self.gparams.preset_name ) then return false end А вот здесь назначение уже учитывается, и непись с принудительно назначенным смартом проверку пройдет. Если кто-то скрипт не "доработал" так, чтобы не проходили. В чем смысл самой проверки? function se_smart_terrain:check_preset( npc_community, npc_rank, preset_name ) local preset = smart_terrain_params.get_preset( preset_name ) if preset == false then return true else local t = preset[npc_community] if t and ( npc_rank >= t[1] and npc_rank <= t[2] ) then return true else return false end end end preset_name - это у нас опять же custom data, строка вида preset = l01_escape или типа того. smart_terrain_params.sctipt ищет это в misc\\smart_terrain_presets.ltx, и вставляет в табличку, по которой опять же проверяются допустимое коммунити и ранги для всей локации. И если мы пишем, чтобы капитана с уникальным пистолетом и рангом мастер на Кордон не пускать - его на Кордоне и не будет. Далее, если и эту проверку благополучно прошли, то if not xr_gulag.checkNpc( community, is_stalker, self.gparams.type, obj:rank(), obj ) then return false end - через 100500 скриптов перебирается список level_gulags = {} в xr_gulag.script, и в каждом из скриптов списка дергаются checkStalker()/checkMonster() на предмет опять же проверки коммунити, ранга, имени и т.д. в надежде, что они вернут нам true. Ну и, наконец, return self.gulag:is_there_any_suitable_job( self:fill_npc_info( obj ), obj_agreement == agreed_exclusive ) - ищутся свободные работы, чтобы запихнуть на них претендента. Впрочем, редкая птица долетит до середины Днепра, и если тот, кого мы хотим видеть в каком-то смарте, туда почему-то не идет - обвешиваем логами предыдущие проверки, и смотрим, как он их проходит (или не проходит). Не забывая, при этом, что чтение данных, повторюсь, случается при появлении монстра/непися в игре, а вот как, когда и куда мы их записали - это уже знает только тот, кто их записывает. Да, кстати, философский вопрос о первичности курицы и яйца - в данном случае отнюдь не филосовский, и условия на, скажем, спавн непися, и на разрешение ему идти в тот или иной смарт - могут срабатывать в разное время. Если же кто думает, что список граблей, а также прочих борон, сеялок и молотилок исчерпан - он думает неправильно. То есть, если нашелся единственный смарт, который только и подходит нашему монстру или неписю - в какой-то момент монстронепись пойдет в него. Если же таких несколько, то: function se_smart_terrain:suitable( obj ) local v = 0 if self:obj_accepts_smart_terrain(obj) == agreed_exclusive then v = 100000 end for id, strn in pairs( smart_terrains[self:get_level_name()] ) do if strn:is_gulag_available() then v = v + strn.gulag.capacity - strn.gulag:get_population() end end return v end Мы видим некое очень сильное колдунство: перебор всех смартов на локации, в которые претендента в принципе могут пустить, с вычислением некоего приоритета в зависимости от их заполненности. Даже думать не хочу, каким может получиться результат, но именно сюда очень любят лазить разные шаловливые ручки, и править так, чтобы все живое пыталось лезть туда, где максимальная емкость, но в смарты с емкостью на 1-2 объекта шли только тогда, когда совсем уж податься некуда. Еще очень популярное исправление - проверка на то, можно ли объекту ходить в онлайн. Суть здесь вот в чем: есть у нас, допустим, в олспавне на генераторах некий кровосос, которому в онлайн можно только после некоего события. Если этот кровосос окажется, допустим, в смарте в кровососовке на Складах, а мы взяли задание на острел кровососов - мы его не сможем выполнить, пока не произойдет искомое событие на генераторах. Логичное решение - не пускать таких в смарты вообще, пока им не разрешили онлайн. Но, это, опять же, кто как правит, и как проверяет это самое разрешение на онлайн. см., например, вариант амк: function se_smart_terrain:obj_accepts_smart_terrain( obj ) if obj.smart_terrain_conditions then local any_exclusive = false local s for name, condlist in pairs(obj.smart_terrain_conditions) do s = xr_logic.pick_section_from_condlist( db.actor_proxy, obj, condlist ) if s ~= nil then if name == "none" then return disagreed elseif name == self:name() then return agreed_exclusive end else if name == self:name() then return disagreed end end end -- Если объекту запрещено переходить в online и эксклюзивные смарты недоступны, то не пускаем его никуда. if obj:can_switch_online() == false then return disagreed end end return agreed end Как подобные правки работают - в каждом конкретном случае надо разбираться отдельно. Вопрос о максимальной вместимости смартов - это отдельная тема, пока лишь скажу, что лучше бы задавать в самих смартах такую, чтобы не превышала максимальное количество имеющихся работ для ВООБЩЕ любого возможного случая, и для невозможного - тоже. Иначе - вылеты, и советы "знатотов" "снизить настройки графики и добавить памяти". Вот теперь, вроде, все.
  18. Dennis_Chikin

    У Костра XVII

    Идентичный заменителю натурального.
  19. Dennis_Chikin

    [SoC] Вопросы по SDK

    Мда, ирония осталась непонятой. Дело не в "адаптации СДК", а в том, что оно "само знает", как где что менять. А без него - там, как бы по времени - неведомому герою можно смело обещать тот памятик из платины. Когда надо будет выполнять обещанное - помрет уже и ишак, и султан, и обещавший, и сам герой.
  20. Dennis_Chikin

    [SoC] Вопросы по SDK

    Не только можно - но и нужно. Hex-editor в руки, и вперед. Благодарное человечество изваяет памятник герою. А то помню, как Петрович выражался, что по поводу болот, что того же радара. Опять же, переходик между Лощиной и Кордоном поправить - надо всего-лишь найти 3 неправильные вершинки, побайтным просмотром, и опять же в bin поправить. Куча мест, где сетка в стенах... Тоже побайтные исправления требуются. Просто народ нонеча ленивый пошел... Все бы им, чтобы как нибудь само, а они - только чтобы кнопку нажать.
  21. Неукоснительно исполняйте взаимоисключающие параграфы! (C)

  22. А сейчас - даже не сельхозинвентарь, а, не побоюсь этого слова, посевная и уборочная техника для крупнотоннажного, так сказать, производства. Что, впрочем, не мешает исполнять на ней те же действия с теми же результатами, что и для граблей обыкновенных. local a = self:smart_terrain_accepts_obj( obj, b ) где второй аргумент у нас, напоминаю - можно ли непися запускать в смарт. Уже замечательно для случая с disagreed. Впрочем, если даже неписю предписано идти в конкретный смарт - счастья это особо не прибавляет, ибо: function se_smart_terrain:smart_terrain_accepts_obj( obj, obj_agreement ) if obj_agreement == disagreed then return false end if obj_agreement == agreed_exclusive or self.gulag:get_non_exclusive_population() < self.gulag.capacity_non_exclusive then local community, is_stalker = self:get_obj_community( obj ) local smart_level_group = self:get_level_name() local npc_level_group = alife():level_name(game_graph():vertex(obj.m_game_vertex_id):level_id()) if level_groups[smart_level_group] ~= level_groups[npc_level_group] then return false end if self.accepted_communities and not self.accepted_communities[community] then return false end if obj_agreement ~= agreed_exclusive and not self:check_preset( community, obj:rank(), self.gparams.preset_name ) then return false end if not xr_gulag.checkNpc( community, is_stalker, self.gparams.type, obj:rank(), obj ) then return false end return self.gulag:is_there_any_suitable_job( self:fill_npc_info( obj ), obj_agreement == agreed_exclusive ) else return false end end Первая строка - прекрасна сама по себе. Следующая проверка - если неписю подходит любой смарт - проверяем ограничение на численность неписей, для которых подходит любой смарт. Если непись явно назначен именно в этот смарт, ЛИБО получил, наконец, разрешение идти в него - ограничение на численность неписей, которым подходит любой смарт, не проверяется. С точки зрения банальной эрудиции следует предположить, что все остальные проверки - действуют. Не помню, был ли в оригинальном ТЧ квест на принести уникальный пистолет от командира блокпоста, или он остался от билдов, но именно по этой причине выполнить его крайне проблематично как минимум уже в АМК. Ибо командир блокпоста может быть где угодно, но только не на блокпосту. Ибо банально не проходит все остальные проверки. А вот это - к вопросу о бандитах/наемниках/армейцев/монстрах в баре. local smart_level_group = self:get_level_name() local npc_level_group = alife():level_name(game_graph():vertex(obj.m_game_vertex_id):level_id()) if level_groups[smart_level_group] ~= level_groups[npc_level_group] then return false end В начале скриптика присутствует такая табличка: local level_groups = { l01_escape = "group1", l02_garbage = "group1", l03_agroprom = "group1", l03u_agr_underground = "group1", l04_darkvalley = "group1", l04u_labx18 = "group1", l05_bar = "group1", l06_rostok = "group1", l07_military = "group1", l08_yantar = "group1", l08u_brainlab = "group1", l10_radar = "group1", l10u_bunker = "group1", l11_pripyat = "group1", l12_stancia = "group3", l12u_sarcofag = "group3", l12u_control_monolith = "group3", l12_stancia_2 = "group3" } В модах у нее появился комментарий "чтобы не ходили через бар", впрочем, являющийся, как правило, единственным изменением. Всякое разное же продолжило шастать через бар, материализуясь, как правило, либо у Арни, либо в бункере у Воронина, с результатом слегка предсказуемым. Как это работает, и что с этим делать? В предшествующих текстах, которые все равно никто не прочитал, и читать не будет, уже говорилось, что с момента появления непися/монстра, и далее - периодически, происходит перебор всех, то есть, абсолютно всех смартов на предмет согласия его принять. Какой согласился, и выдал максимальный приоритет - под тот и пойдет. То есть, появился, к примеру, в ТД, а приняли, к примеру, на Янтаре - пойдет на Янтарь. Передвигаются они по вершинкам, из одной в другую, и если такая, которая по пути, окажется, к примеру, в бункере Воронина - монстр/непись появится в бункере Воронина, если мы в этот момент в радиусе онлайна. А если прикрутить еще "оффлайн-боевку" или "офлайн-шмон" - эта "офлайн-боевка" того Воронина (или еще какого Арни) грохнет и без входа того тушканчика в онлайн. Аналогично, если путь будет через базу Свободы - снорки с кровососами будут сыпаться на головы свободовцам. Вот чтобы подобного казуса не произошло - либо надо убрать подобные пути, либо не пускать живность с ТД, кордонов и прочих болот ни на Янтарь, ни на Склады ни в прочие места, куда они пойдут через бар. То есть, Кордон-x18 должны иметь один ключ, а вот Росток и Янтарь - уже другой. Примерно так: local level_groups = { l01_escape = "1", l02_garbage = "1", l03_agroprom = "1", l03u_agr_underground = "1", l04_darkvalley = "1", l04u_labx18 = "1", l05_bar = "1", l06_rostok = "2", l07_military = "2", l08_yantar = "2", l08u_brainlab = "3", l10_radar = "2", l10u_bunker = "2", l11_pripyat = "2", l12_stancia = "2", l12u_sarcofag = "2", l12u_control_monolith = "2", l12_stancia_2 = "2" } Росток-Янтарь оставляем в одной группе с радаром и прочими припятями, потому что тот уголок, где у них остается путь, нам не мешает. Ну и не забыть всякие перещеры с лощинами добавить. Если мы не хотим, чтобы с конкретной локации кто-то уходил, и не пускать в не чужих - ставим отдельный, уникальный ключ. Кстати, на счет "убрать пути" (или их не прописать, или запретить монстрам/неписям ходить по вершинкам с определенным флагом, но разрешить захватываться в смарт на локации, куда пути нет - будет как раз знаменитый вылет по плотям в x16
  23. Без доработки - непись так и будет вечно в этой анимации. Добить из схемы - почему б нет?
  24. Да, в on_hit() проверяем, говорим state_manager отыгрыть анимацию, и вызываем kill(), если анимаций не осталось. Или сами наносим еще один хит по кости, чтобы анимация игралась автомагчески, потом, опять же - kill() вариант - в xr_wound реакцию на ранения допилить по тому же принципу.
×
×
  • Создать...