Перейти к содержанию

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

 
 

эхо44 меняй в defines.ltx, лежит прямо в configs. Оптимальное значение 50-55.


Дополнено 8 минуты спустя
В 05.09.2026 в 06:07, GunLagger_31r сказал:

Это так автором задумано или просто техническая невозможность заменить прицелы в тайниках?

Насколько я знаю, чтобы поменять содержимое тайника в ЗП, нужно ковырять all.spawn. В свою очередь это вызовет несовместимость с AN4 и тд, в общем не очень вариант. А ПСО заменён на ПО так же по техническим причинам - оригинальное тех. название ПСО (wpn_addon_scope) больно громоздкое, и у каждого ствола где он устанавливается вместо лаконичного названия wpn_ak74_pso было бы wpn_ak74_wpn_addon_scope. Мелочь, но неудобно. В итоге подобным названием награждается одна лишь Гроза - wpn_groza_wpn_addon_scope.

Ну, хотя бы в ТЧ и ЧН проблемы с наполнением тайников не будет.

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

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


Ссылка на сообщение
Поделиться на другие сайты
 
В 05.09.2026 в 16:02, эхо44 сказал:

@shunsuiа можешь подсказать, где и как именно его найти и изменить, если тебе не сложно? 

Но если речь идет просто о изменении конфига пользователя через блокнот то я уже пробывал

еще, конечно, можно запариться и через дебаг подбирать положение оружия и потом через доки их менять.

Зарание спасибо за помощь

Ставишь в configs/defines.ltx 

hud_fov = float (никаких чисел)

Вуаля, теперь можно менять это самое значение через консоль. 

PNA0j9fU8SZc6q0Gfoo1QEHQE8bzjIfYEVGHt-5y

  • Лайк 1
  • Сталкерский лайк 1

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


Ссылка на сообщение
Поделиться на другие сайты
 

@Ga2z @zovchernobyl спасибо большое 

  • Жму руку 2

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


Ссылка на сообщение
Поделиться на другие сайты
 

3.8.1.5 совместима с ixray 1.3.5 ? папку bin  оружейки кидать поверх bin ixray ?

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


Ссылка на сообщение
Поделиться на другие сайты
 
8 часов назад, Evgen89x сказал:

3.8.1.5 совместима с ixray 1.3.5 ? папку bin  оружейки кидать поверх bin ixray ?

Я поставил обновление движка, вроде не вылетело и ничего не взорвалось


Дополнено 51 минуты спустя

Из этого мода можно слямзить магазин на 60 5,45 аля Pufgun, если кому понадобится https://steamcommunity.com/sharedfiles/filedetails/?id=2980657900

1NOUVgigdd8.jpg

Изменено пользователем GunLagger_31r
  • Лайк 1

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


Ссылка на сообщение
Поделиться на другие сайты
 

Evgen89x да, судя по информации в обновлении 1.3.5, встанет без проблем. Нужно будет удалить gamedata и bin оружейки и накатить их от 1.3.5.

  • Лайк 1

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


Ссылка на сообщение
Поделиться на другие сайты
 

Ga2z ок, понял, спасибо

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


Ссылка на сообщение
Поделиться на другие сайты
 

Вопроса 2 первый а в спавнере все пушки? 2 можно ли и где найти тактические рукоятки для пушек? 

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


Ссылка на сообщение
Поделиться на другие сайты
 
10 часов назад, Маченый сказал:

Вопроса 2 первый а в спавнере все пушки? 2 можно ли и где найти тактические рукоятки для пушек? 

1. Да
2. Нет, они не идут как отдельный модуль, а как часть модели

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


Ссылка на сообщение
Поделиться на другие сайты
 

Плз проведи плотный рефакторинг. Убери всю новую броню из папки 3.8-cop, пусть лежит там где ей и место. Удали все эти правки на квесты, скрипты, тайники и прочее от Jurok, перебалансировку дамага (лучше балансить само оружие тогда, его урон), пусть будет только оружейный пак с торговлей, если тебе надо квестами и прочим но только если ты добавляешь туда оружие, а то адаптировать тяжко. У меня свои аддоны есть просто на ixr и та же новая броня тоже, вписана в сюжет, есть баланс её под оригинал, апгрейды у техников для каждой местами уникальные, а тут какой-то реликт копировать-вставить добавлен.

Ну это так просьба, твоё дело что с ней делать, адаптирую себе в любом случае.

_______________

Хотя я щас играю, с уроном у тебя всё в порядке, прям отлично. Короче если хочешь качай и забирай мою броню или мои апгрейды на броню. Если причешу тебе те моменты что меня смущают в твоих конфигах и скриптах, поменяешь их?


Дополнено 45 минуты спустя

Адаптация атмосфира 3 к сткопу

Качать отсюда https://www.moddb.com/mods/ix-ray-platform/addons/ix-ray-atmosfear-3, кидать в папку ixr_addons

https://disk.yandex.ru/d/5LWX3gj8C0v20g


Дополнено 50 минуты спустя

Кстати у них есть подключение файлов по маске, берёшь и делаешь так:

 

Спойлер

Screenshot_24.jpg.fc6150acf2834a18ddbebb6aa4fa2bf7.jpgScreenshot_25.jpg.7126ca88d711935098592e39b37665a3.jpg

 


Дополнено 55 минуты спустя
В 06.09.2026 в 08:37, Ga2z сказал:

Насколько я знаю, чтобы поменять содержимое тайника в ЗП, нужно ковырять all.spawn. В свою очередь это вызовет несовместимость с AN4 и тд, в общем не очень вариант.

SDK нужен, аи-сетку я тебе дам, а спаун они и не меняли там.

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

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


Ссылка на сообщение
Поделиться на другие сайты
 
В 10.09.2026 в 05:08, Sim_npc_default_01 сказал:

Плз проведи плотный рефакторинг. Убери всю новую броню из папки 3.8-cop, пусть лежит там где ей и место.

Согласен, это давно надо было сделать.

В 10.09.2026 в 05:08, Sim_npc_default_01 сказал:

Удали все эти правки на квесты, скрипты, тайники и прочее от Jurok

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

В 10.09.2026 в 05:08, Sim_npc_default_01 сказал:

перебалансировку дамага

Она ещё с древних времён с TrickSR, но всё же соглашусь что damages.ltx лишний.

В 10.09.2026 в 05:08, Sim_npc_default_01 сказал:

Кстати у них есть подключение файлов по маске, берёшь и делаешь так:

Всё это мне надо вынести отдельно, пока не разобрался как.

В 10.09.2026 в 05:08, Sim_npc_default_01 сказал:

SDK нужен, аи-сетку я тебе дам, а спаун они и не меняли там.

Спасибо, но честно говоря мне лень будет этим заниматься из-за парочки патронов и прицелов. :)


Дополнено 4 минуты спустя

И должен предупредить, что версия 3.8.2 с уже проведённым рефакторингом на подходе. Затронуты не только конфиги, но и всякая мелочь, что помешает при адаптации на свой проект. Тут уж выбор за тобой, брать как есть или ждать IX-Ray 1.4.

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


Ссылка на сообщение
Поделиться на другие сайты
 
3 часа назад, Ga2z сказал:

И должен предупредить, что версия 3.8.2 с уже проведённым рефакторингом на подходе. Затронуты не только конфиги, но и всякая мелочь, что помешает при адаптации на свой проект. Тут уж выбор за тобой, брать как есть или ждать IX-Ray 1.4.

Она на 1.4 будет? А я уже взял как есть, тестирую. 

 

3 часа назад, Ga2z сказал:

Честно говоря я и не помню что это вообще за правки

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

3 часа назад, Ga2z сказал:

Всё это мне надо вынести отдельно, пока не разобрался как.

Да можешь и без mod_название делать, просто оставить как есть, но переделать чтение по маске, всё равно потом упростит адаптацию и тебе тоже жизнь.

3 часа назад, Ga2z сказал:

Спасибо, но честно говоря мне лень будет этим заниматься из-за парочки патронов и прицелов. :)

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


Дополнено 5 минуты спустя

А вот это конечно ошибка что wpn_addon_scope_ прицел для тебя слишком длинное название, потом будет их парсить удобно. Кто знает, может разраб по маске запилит в торговле подключение всех этих предметов как в ogsr? А ты просто сделаешь wpn_addon_scope_ и париться потом не будешь. Со скриптами уже сейчас можно парсить, у тебя есть скрипты, требующие уникальное оружие Шустрого, а у тебя там обычные секции, хотя можно было бы выловить их по слову nimble и опять же забыть об этих скриптах, не ходить каждый апдейт туда вписывать новую пушку. Короче названия секций предметов надо по группам унифицировать на будущее.

И кстати ты оружие Шустрого не во все скрипты вписал, по состоянию на 3.8.1.5 по крайней мере, там же ещё квесты с обманом Коряги есть.

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

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


Ссылка на сообщение
Поделиться на другие сайты
 
2 минуты назад, Sim_npc_default_01 сказал:

Она на 1.4 будет?

Да.

2 минуты назад, Sim_npc_default_01 сказал:

А я уже взял как есть, тестирую. 

Ладно, не то чтобы изменения будут глобальными в 3.8.2.

5 минут назад, Sim_npc_default_01 сказал:

В BeyondCompare сравни просто эти файлы

Сравнил notepad'ом, оставил только tm_jupiter и скрипт xr_conditions.

8 минут назад, Sim_npc_default_01 сказал:

но переделать чтение по маске, всё равно потом упростит адаптацию и тебе тоже жизнь.

Переделал, ну и вынес всё что относится к новой броне в папку ixray-stcop-wp-3.8.2-outfits, как оно и должно было быть.

10 минут назад, Sim_npc_default_01 сказал:

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

Можно, но в целом эти предметы в тайниках не мешают.

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


Ссылка на сообщение
Поделиться на другие сайты
 
2 минуты назад, Ga2z сказал:

Ладно, не то чтобы изменения будут глобальными в 3.8.2.

Да ладно, перекачу потом в любом случае. Спасибо короче что прислушиваешься. 

  • Лайк 1

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


Ссылка на сообщение
Поделиться на другие сайты
 

Sim_npc_default_01 конечно, это всё давно пора было сделать по уму.

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


Ссылка на сообщение
Поделиться на другие сайты
 
Только что, Ga2z сказал:

конечно, это всё давно пора было сделать по уму.

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

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


Ссылка на сообщение
Поделиться на другие сайты
 

Sim_npc_default_01 сделают, а сейчас у них работы слишком много. :)

  • Лайк 1

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


Ссылка на сообщение
Поделиться на другие сайты
 
1 минуту назад, Ga2z сказал:

сделают, а сейчас у них работы слишком много. :)

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

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

Спойлер

; SOVIET SCOPES
;1p78,1pn93-1,ekp,okp,kobra = 5

; SOVIET SPECIAL SCOPES 9X39
;pso1m21,1p78,1pn93-1,ekp,okp,kobra = 6

; WESTERN SCOPES
;ac10632,acog,aimpoint,eot,pn23 = 5

; UK SCOPES 
;wpn_addon_scope_susat,ac10632,acog,aimpoint,eot,pn23 = 6

; HOW ADD ADDONS?
; wpn_ak74 = 1, scope = 2 (serial order from line 'scopes' in weapon config), silencer, launcher

;ASSAULT

wpn_abakan       /      less silencer   
wpn_ace52        /      less gl
wpn_aek971       /      have all
wpn_ak12         /      have all
wpn_ak74         /      have all
wpn_ak74m        /      have all
wpn_ak101        /      have all
wpn_ak103        /      have all
wpn_ak104        /      less gl
wpn_ak105        /      less gl
wpn_akm          /      less scopes
wpn_ak74u        /      less gl
wpn_aug_a3       /      less gl
wpn_fal          /      less gl
wpn_famas        /      less gl
wpn_famas_f1     /      less gl
wpn_fn2000       /      less scope and gl
wpn_g3           /      less gl
wpn_g36          /      less scope
wpn_galil        /      less gl - have 1 scope
wpn_groza        /      less silencer - have 1 scope
wpn_hk416        /      have all
wpn_l85          /      have all - six! uk scopes
wpn_lr300        /      less gl
wpn_m4           /      have all
wpn_m4_tac       /      less silencer and gl
wpn_m16          /      have all
wpn_scar         /      have all
wpn_sig550       /      less gl
wpn_sig552       /      less gl
wpn_type63       /      less silencer and gl - have 1 scope
wpn_val          /      less silencer and gl - six! soviet scopes
wpn_vihr         /      less gl - six! soviet scopes
wpn_vsk94        /      less gl - six! soviet scopes

; MACHINE GUNS

wpn_hk21         /      less gl
wpn_m60          /      less scope and gl
wpn_pkm          /      less all
wpn_pkp          /      less gl
wpn_rpd          /      less all
wpn_rpk          /      less gl
wpn_rpk74        /      less gl
wpn_rpk203       /      less gl

; PISTOLS

wpn_aps          /      have sil
wpn_beretta      /      have sil
wpn_colt1911     /      less all
wpn_cz75         /      have sil
wpn_desert_eagle /      less all
wpn_fn57         /      have sil
wpn_fnx45        /      have sil
wpn_fort         /      less all
wpn_glock        /      have sil
wpn_gsh18        /      less all
wpn_hpsa         /      less all
wpn_oc27         /      less all
wpn_oc33         /      have sil
wpn_pb           /      have sil
wpn_pm           /      less all    
wpn_sig220       /      have sil
wpn_tt33         /      less all 
wpn_usp          /      have sil
wpn_walther      /      have sil

; SHOTGUNS

wpn_fort500               /      have sil
wpn_m3super90             /      only 3 scopes ; ac10632,aimpoint,eot
wpn_mr153                 /      less all 
wpn_protecta              /      have scopes
wpn_saiga                 /      less gl
wpn_spas12                /      have sil
wpn_toz34                 /      less all 
wpn_bm16                  /      less all 
wpn_bm16_full              /      less all 
wpn_vepr                  /      have sil, only 3 scopes ; ac10632,aimpoint,eot
wpn_wincheaster1300      /      less all 

; SEMI-MG

wpn_bizon                 /      less gl
wpn_kedr                 /      have sil
wpn_kiparis              /      have sil
wpn_kriss_vector         /      less gl
wpn_mp5                  /      less gl 
wpn_p90                  /      have sil
wpn_pp2000               /      less gl
wpn_ppsh41                  /      less all 
wpn_ump45                 /      less gl
wpn_uzi_mini             /      have sil
wpn_uzi_micro            /      have sil
wpn_vityaz               /      less gl 

; SNIPER RIFLES

wpn_dvl10                /      less all 
wpn_gauss                /      less all 
wpn_l96                  /      less all 
wpn_m24                  /      have sil
wpn_m98b                 /      have sil
wpn_mk14                 /      less gl
wpn_mosin                /      have 1 scope
wpn_sks                  /      have scopes
wpn_sr25                 /      have sil
wpn_sv98                 /      have sil
wpn_svd                  /      less gl - have six! scopes ;pso1m2,1p78,1pn93-4,ekp,okp,kobra
wpn_svu                  /      have six! scopes ;pso1m2,1p78,1pn93-4,ekp,okp,kobra
wpn_vintorez             /      less silencer and gl - six! soviet scopes
wpn_vssk                 /      less all 

 

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


Ссылка на сообщение
Поделиться на другие сайты
 
43 минуты назад, Sim_npc_default_01 сказал:

И кстати ты оружие Шустрого не во все скрипты вписал, по состоянию на 3.8.1.5 по крайней мере

Хм, да вроде везде есть, по крайней мере на всё что Шустрый принёс Коряга реагировал (проверял конечно ещё на 3.8).


Дополнено 1 минуту спустя
43 минуты назад, Sim_npc_default_01 сказал:

Со скриптами уже сейчас можно парсить

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


Дополнено 2 минуты спустя
18 минут назад, Sim_npc_default_01 сказал:

И с узи сделай что-нибудь

Да всё забываю удалить её из конфигов, есть такое.


Дополнено 3 минуты спустя

По раздаче оружия, это всё куда-то в loadouts вписывается? Что-то не догоняю(

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

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


Ссылка на сообщение
Поделиться на другие сайты
 
10 минут назад, Ga2z сказал:

По раздаче оружия, это всё куда-то в loadouts вписывается? Что-то не догоняю(

Да, у тебе уже кто-то делал, ну может ему пригодится. Там же надо знать количество прицелов и аддонов на оружие есть он или нет. less gl например это значит НЕТ только подствола, have sil, значит ЕСТЬ только глушитель.


Дополнено 3 минуты спустя

Скрипты, тут старое jup_a10_proverka_wpn (это диалог с бандитом по Долгу Вано где ему можно пригрозить и со сталкерами на Затоне которые ищут артефакты у аномалии Цирк), actor_has_active_nimble_weapon тут новое есть, но старое бы удалить наверно 

Изменено пользователем Sim_npc_default_01
  • Мастер! 1

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


Ссылка на сообщение
Поделиться на другие сайты
 
13 минут назад, Sim_npc_default_01 сказал:

диалог с бандитом по Долгу Вано где ему можно пригрозить и со сталкерами на Затоне которые ищут артефакты

Про эти моменты забыл совсем, поправлю, спасибо.

Изменено пользователем Ga2z
  • Лайк 1

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


Ссылка на сообщение
Поделиться на другие сайты
 

У тебя ещё свой атлас иконок, но ты его для оружия онли используешь. Чтобы не париться, в mod_system_stcop понапрописывай в родительские секции айтемов как-то типа так. inv_scale = 1.0 на случай если у кого-то типа меня будет 2, хотя можешь не писать, пофиг. На HQ не хотел бы перевести свой атлас?
 

Спойлер

![device_flare]
inv_scale                 = 1.0
icons_texture = ui\ui_icon_equipment_stcopwp.dds

![detector_simple]
inv_scale                 = 1.0
icons_texture = ui\ui_icon_equipment_stcopwp.dds

![booster]
inv_scale                 = 1.0
icons_texture = ui\ui_icon_equipment_stcopwp.dd

![device_pda]
inv_scale                 = 1.0
icons_texture = ui\ui_icon_equipment_stcopwp.dds

итд

 

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

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


Ссылка на сообщение
Поделиться на другие сайты
 

ИИ-скрипт для тайников. Если кто-то балуется с ИИ, советую онли Gemini - Google Ai Studio, на худой конец DeepSeek, остальные в коде, особенно на сталкера вообще ничего не понимают. Ga2z 
 

Спойлер

В secrets.ltx

С трупов, в процентах. Можно не писать.
[settings]
global_drop_chance = 20

[zat_hiding_place_1]
name = st_zat_hiding_place_1_name - имя для тайника на глобал и не только карте
description = st_zat_hiding_place_1_desc - его описание, как в тч короче
Можно не вписывать их или оставить пустыми, будет просто тайник как в ЗП.

Как в ЧН для спауна у трупов. У трупа какого ранга и какой группировки может выпасть. Можно не писать.
community = stalker, bandit
rank = novice

Чтобы спаун с трупов работал, придётся прописать в хр мотиватор
 

function motivator_binder:use_callback(obj, who)
    printf("motivator_binder:use_callback(obj, who)")
    
    if self.object:alive() then
        inventory_upgrades.need_victim(obj)
        xr_meet.notify_on_use(obj, who)
        dialog_manager.disabled_phrases[obj:id()] = nil
        
        if self.st.active_section then
            xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who)
        end
    else
        if self.treasure_processed == false then
            local npc = self.object
            local success = treasure_manager.get_treasure_manager():give_random_from_deadbody(npc)
            
            if not success then
                treasure_manager_cs.use(npc)
            end

            self.treasure_processed = true            
        end        
    end
end



Replace заменяет предмет. Дефолтный wpn_mp5 заменяется wpn_p90:
wpn_mp5 = replace, wpn_p90

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

Например:

[zat_hiding_place_16]
name = st_zat_hiding_place_16_name
description = st_zat_hiding_place_16_desc
wpn_mp5 = replace, wpn_p90
ammo_9x19_fmj = 3, 1
community = bandit
rank = all


Подняв с него ammo_9x19_fmj = 3, 1, тайник засчитается, wpn_p90 роли уже не играет.

Неважно сколько было предметов. Например

medkit = 2, 1

Если поставить 

medkit = replace, medkit_army

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



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


drug_anabiotic = remove

 



Добавлена система удаления предмета если он ниже рестриктора на 5 метров (провалился под землю), предмет удаляется, в список тайника не заносится, метка теперь не будет висеть вечно как часто бывает, например тайник с ВОГами у ВНЗ.

 



Добавлена функция give_random(число), можно вызывать в квестах, при желании рестрикторах, диалогах например
    treasure_manager.get_treasure_manager():give_random() - выдаст 1 тайник
    treasure_manager.get_treasure_manager():give_random(2) - выдаст 2 тайника

Выдаёт тайник на той локации, на которой находится игрок.

Спойлер

local treasure_manager = nil

class "CTreasureManager"
function CTreasureManager:__init()
	self.items_spawned = false
	self.check_time = nil
	self.secrets = {}
	self.secret_restrs = {}
	self.items_from_secrets = {}
	
	-- Очередь для безопасного удаления и замены
	self.items_to_modify = {}
end

function CTreasureManager:initialize()
    local ini = ini_file("misc\\secrets.ltx")
	
    self.global_drop_chance = ini:section_exist("settings") and ini:line_exist("settings", "global_drop_chance") 
                              and ini:r_float("settings", "global_drop_chance") or 0	
	
    local n = ini:line_count("list")
    for i = 0, n - 1 do
        local result, id, value	= ini:r_line("list", i, "", "")
        if(ini:section_exist(id)) then
            self.secrets[id] = {
                items = {},
                modifiers = {}, -- ДОБАВЛЕНО ДЛЯ ЗАДАЧИ 2 (remove / replace)
                given = false, 
                empty = nil, 
                refreshing = false, 
                checked = false, 
                to_find = 0,

                name = ini:line_exist(id, "name") and ini:r_string(id, "name") or "",
                description = ini:line_exist(id, "description") and ini:r_string(id, "description") or "",
				
                rank = ini:line_exist(id, "rank") and ini:r_string(id, "rank") or "all",
                community = ini:line_exist(id, "community") and ini:r_string(id, "community") or "none"				
            }
            
            local items_count = ini:line_count(id)
            local item_section = ""
            for j = 0, items_count - 1 do
                result, item_section, str = ini:r_line(id, j, "", "")
                
                if(item_section == "empty") then
                    local parsed_condlist = xr_logic.parse_condlist(nil, "treasure_manager", "empty_cond", str)
                    self.secrets[id].empty = parsed_condlist
                elseif(item_section == "refreshing") then
                    local parsed_condlist = xr_logic.parse_condlist(nil, "treasure_manager", "refreshing_cond", str)
                    self.secrets[id].refreshing = parsed_condlist
                elseif(item_section ~= "name" and item_section ~= "description" and item_section ~= "rank" and item_section ~= "community") then
                    
                    -- ЗАДАЧА 2: Обработка remove и replace
                    local str_clean = str:match("^%s*(.-)%s*$")
                    if str_clean == "remove" then
                        self.secrets[id].modifiers[item_section] = { action = "remove" }
                    elseif string.find(str_clean, "^replace") then
                        -- Сделал поиск более надёжным, чтобы съедал любые пробелы
                        local target_sect = string.match(str_clean, "^replace%s*,%s*([^%s]+)")
                        if target_sect then
                            self.secrets[id].modifiers[item_section] = { action = "replace", target = target_sect }
                        end
                    else
                        -- Обычный парсинг
                        self.secrets[id].items[item_section] = {}
                        local tbl = utils.parse_spawns(str)
                        if(#tbl == 0) then
                            abort("There is no items count set for treasure [%s], item [%s]", id, item_section)
                        end
                        for k = 1, #tbl do
                            local item_data = {
                                count = tonumber(tbl[k].section) or 0,
                                prob = tonumber(tbl[k].prob or 1) or 1
                            }
                            table.insert(self.secrets[id].items[item_section], item_data)
                        end
                    end
                end
            end
        else
            abort("There is no section [%s] in secrets.ltx", tostring(id))
        end
    end
end

function CTreasureManager:fill(se_obj, treasure_id)
	if(self.secrets[treasure_id]) then
        local sect = se_obj:section_name()
        
        -- Перехват в очередь remove/replace
        if self.secrets[treasure_id].modifiers[sect] then
            local mod = self.secrets[treasure_id].modifiers[sect]
            table.insert(self.items_to_modify, {id = se_obj.id, mod = mod})
            return true 
        end

		local item = self.secrets[treasure_id].items[sect]
		if(item) then
			for i=1,#item do
				if not(item[i].item_ids) then
					item[i].item_ids = {}
				end
				local count = #item[i].item_ids
				if(count < item[i].count) then
					item[i].item_ids[count+1] = se_obj.id
					return true
				end
			end
		else
			abort("Attempt to register unknown item [%s] in secret [%s]", sect, treasure_id)
		end
	else
		abort("Attempt to register item [%s] in unexistent secret [%s]", se_obj:name(), treasure_id)
	end
end

function CTreasureManager:register_item(se_obj)
	local spawn_ini = se_obj:spawn_ini()
	if(spawn_ini:section_exist("secret")) then
		local result, id, value
		result, id, value = spawn_ini:r_line("secret",0,"","")
		if id ~= "name" then
			abort("There is no 'name' field in [secret] section for object [%s]", se_obj:name())
		end
		if value == "" then
			abort("Field 'name' in [secret] section got no value for object [%s]", se_obj:name())
		end
		return self:fill(se_obj, value)
	end
end

function CTreasureManager:register_restrictor(se_obj)
	local spawn_ini = se_obj:spawn_ini()
	if(spawn_ini:section_exist("secret")) then
		self.secret_restrs[se_obj:name()] = se_obj.id
	end
end

-- ЗАДАЧА 1: Функция очистки провалившихся вещей
function CTreasureManager:check_fallen_items()
    local to_remove = {}
    
    for obj_id, restr_id in pairs(self.items_from_secrets) do
        local obj = level.object_by_id(obj_id) -- Проверяем клиентский онлайн-объект!
        if obj then
            local se_restr = alife():object(restr_id)
            if se_restr then
                -- Сравниваем реальную физическую высоту
                if obj:position().y < (se_restr.position.y - 5.0) then
                    table.insert(to_remove, obj_id)
                end
            end
        else
            -- Подстраховка: если движок уже психанул и безвозвратно удалил улетевший в бездну предмет из игры
            if not alife():object(obj_id) then
                table.insert(to_remove, obj_id)
            end
        end
    end

    -- Удаляем и виртуально "поднимаем" провалившиеся предметы, чтобы счетчик тайника обновился
    for _, obj_id in ipairs(to_remove) do
        printf("TreasureManager: Item [%d] fell underground, auto-collecting to fix stash...", obj_id)
        
        local se_item = alife():object(obj_id)
        if se_item then
            alife():release(se_item, true)
        end
        
        -- Вызов on_item_take уберет его из списка items_from_secrets и уменьшит to_find
        self:on_item_take(obj_id) 
    end
end

function CTreasureManager:update()
	if not(self.items_spawned) then
		for k,v in pairs(self.secrets) do
			self:spawn_treasure(k)
		end
		self.items_spawned = true
	end
    
    -- БЕЗОПАСНАЯ обработка remove и replace
    if #self.items_to_modify > 0 then
        for i = 1, #self.items_to_modify do
            local data = self.items_to_modify[i]
            local se_obj = alife():object(data.id)
            
            if se_obj then
                if data.mod.action == "remove" then
                    alife():release(se_obj, true)
                elseif data.mod.action == "replace" and data.mod.target then
                    -- Вот тут был косяк: забыли скопировать AI-свойства старого предмета
                    local new_obj = alife():create(data.mod.target, se_obj.position, se_obj.m_level_vertex_id, se_obj.m_game_vertex_id)
                    new_obj.angle = se_obj.angle
                    new_obj:use_ai_locations(se_obj:used_ai_locations())
                    alife():release(se_obj, true)
                end
            end
        end
        self.items_to_modify = {}
    end
	
	local global_time = time_global()
	if(self.check_time and global_time - self.check_time <= 500) then
		return
	end
	self.check_time = global_time

    self:check_fallen_items()

	for k,v in pairs(self.secrets) do
		if(v.given) then
		 	if(v.empty) then
				local sect = xr_logic.pick_section_from_condlist(db.actor, nil, v.empty)
				if(sect == "true") and not v.checked then
					level.map_remove_object_spot(self.secret_restrs[k], "treasure")
					xr_statistic.inc_founded_secrets_counter()
					v.empty = nil
					v.checked = true
					printf("Empty secret [%s] remove map spot!", k)
				end
			elseif(v.refreshing and v.checked) then
				local sect = xr_logic.pick_section_from_condlist(db.actor, nil, v.refreshing)
				if(sect == "true") then
					v.given = false
					v.checked = false
					printf("Given secret [%s] now is avaliable!", k)
				end
			end
		end
	end
end

function CTreasureManager:spawn_treasure(treasure_id)
	if not(self.secrets[treasure_id]) then
		abort("There is no stored secret [%s]", tostring(treasure_id))
	end
	if(self.secrets[treasure_id].given) then
		printf("Secret [%s] already given!", treasure_id)
		return
	end
	for item_section, item_params in pairs(self.secrets[treasure_id].items) do
		for num = 1, #item_params do
            local item_count = item_params[num].count
            if type(item_count) ~= "number" then
                item_count = 0
            end
            
            for i = 1, item_count do
                local prob = math.random()
                if(prob < item_params[num].prob) then
                    if(item_params[num].item_ids and item_params[num].item_ids[i]) then
                        local se_obj = alife():object(item_params[num].item_ids[i])
                        local obj = alife():create( item_section,
                                                    se_obj.position,
                                                    se_obj.m_level_vertex_id,
                                                    se_obj.m_game_vertex_id)
                        obj.angle = se_obj.angle
                        obj:use_ai_locations(se_obj:used_ai_locations())
                        self.items_from_secrets[obj.id] = self.secret_restrs[treasure_id]
                        self.secrets[treasure_id].to_find = self.secrets[treasure_id].to_find + 1
                    end
                end
            end
		end
	end
end

function CTreasureManager:give_treasure(treasure_id, spawn)
	if not(self.secrets[treasure_id]) then
		abort("There is no stored secret [%s]", tostring(treasure_id))
	end
	if(self.secrets[treasure_id].given) then
		printf("Secret [%s] already given!", treasure_id)
		return
	end
	if(self.secrets[treasure_id].to_find == 0 and not(self.secrets[treasure_id].empty)) then
		if self.secrets[treasure_id].name ~= "" and news_manager.send_treasure_name then
			news_manager.send_treasure_name(2, self.secrets[treasure_id].name)
		elseif news_manager.send_treasure then
			news_manager.send_treasure(2) -- Заглушка, если функции send_treasure_name не существует
		end
		
		printf("Secret [%s] already empty", treasure_id)
		return
	end
	if(spawn) then
		self:spawn_treasure(treasure_id)
	end
	
	local spot_text = ""
	if self.secrets[treasure_id].name ~= "" then
		local name_text = game.translate_string(self.secrets[treasure_id].name)
		name_text = "%c[255,255,160,0]" .. name_text .. "%c[default]"
		
		if self.secrets[treasure_id].description ~= "" then
			local desc_text = game.translate_string(self.secrets[treasure_id].description)
			spot_text = name_text .. " \\n" .. desc_text
		else
			spot_text = name_text
		end
	end
	
	level.map_add_object_spot_ser(self.secret_restrs[treasure_id], "treasure", spot_text)
	self.secrets[treasure_id].given = true
	if self.secrets[treasure_id].name ~= "" and news_manager.send_treasure_name then
		news_manager.send_treasure_name(0, self.secrets[treasure_id].name)
	elseif news_manager.send_treasure then
		news_manager.send_treasure(0) -- Заглушка, если функции send_treasure_name не существует
	end
	printf("Give secret [%s]", treasure_id)
end

function CTreasureManager:give_random(count)
    count = count or 1 
    
    if type(count) ~= "number" then
        count = 1
    end
    
    local actor = db.actor
    if not actor then return end
    
    local level_name = level.name()
    local prefix = ""
    if level_name == "zaton" then
        prefix = "zat_hiding_place_"
    elseif level_name == "jupiter" then
        prefix = "jup_hiding_place_"
    elseif level_name == "pripyat" then
        prefix = "pri_hiding_place_"
    else return end
    
    local available_treasures = {}
    for k,v in pairs(self.secrets) do
        if not v.given and string.find(k, "^" .. prefix) then
            table.insert(available_treasures, k)
        end
    end
    
    if #available_treasures == 0 then return end
    
    local actual_count = math.min(count, #available_treasures)
    for i = 1, actual_count do
        if #available_treasures > 0 then
            local random_index = math.random(1, #available_treasures)
            local treasure_name = available_treasures[random_index]
            self:give_treasure(treasure_name)
            table.remove(available_treasures, random_index)
        else break end
    end
end

function CTreasureManager:on_item_take(obj_id)
	local restr_id = self.items_from_secrets[obj_id]
	local treasure_id = nil
	for k,v in pairs(self.secret_restrs) do
		if(restr_id == v) then
			treasure_id = k
		end
	end
	if(treasure_id) then
		self.secrets[treasure_id].to_find = self.secrets[treasure_id].to_find - 1
		
		if(self.secrets[treasure_id].to_find <= 0) then
			level.map_remove_object_spot(self.secret_restrs[treasure_id], "treasure")
			xr_statistic.inc_founded_secrets_counter()
			printf("Secret [%s] now is empty!", treasure_id)
			self.secrets[treasure_id].checked = true
			news_manager.send_treasure(1)
		end
		self.items_from_secrets[obj_id] = nil
	end
end

function CTreasureManager:save(package)
	set_save_marker(package, "save", false, "CTreasureManager")
	package:w_bool(self.items_spawned)
	local num = 0
	for k,v in pairs(self.items_from_secrets) do
		num = num + 1
	end
	package:w_u16(num)
	for k,v in pairs(self.items_from_secrets) do
		package:w_u16(k)
		package:w_u16(v)
	end

	num = 0
	for k,v in pairs(self.secrets) do
		num = num + 1
	end
	package:w_u16(num)
	for k,v in pairs(self.secrets) do
		if not(self.secret_restrs[k]) then
			package:w_u16(-1)
		else
			package:w_u16(self.secret_restrs[k])
		end
		package:w_bool(v.given)
		package:w_bool(v.checked)
		package:w_u8(v.to_find)
	end
	set_save_marker(package, "save", true, "CTreasureManager")
end

function CTreasureManager:load(package)
	set_save_marker(package, "load", false, "CTreasureManager")
	self.items_spawned = package:r_bool()
	self.items_from_secrets = {}
	local num = package:r_u16()
	for i = 1, num do
		local k = package:r_u16()
		local v = package:r_u16()
		self.items_from_secrets[k] = v
	end

	local num2 = package:r_u16()
	for i = 1, num2 do
		local id = package:r_u16()
		for k,v in pairs(self.secret_restrs) do
			if(v == id) then
				id = k
				break
			end
		end
		local given = package:r_bool()
		local checked = package:r_bool()
		local to_find = package:r_u8()
		if(id ~= 65535 and self.secrets[id]) then
			self.secrets[id].given = given
			self.secrets[id].checked = checked
			self.secrets[id].to_find = to_find
		end
	end
 	set_save_marker(package, "load", true, "CTreasureManager")
end
--------------------------------------------------------------------------------
function get_treasure_manager()
	if(treasure_manager == nil) then
		treasure_manager = CTreasureManager()
		treasure_manager:initialize()
	end
	return treasure_manager
end

function CTreasureManager:give_random_from_deadbody(npc)

    if math.random(100) > self.global_drop_chance then
        return false
    end

    local npc_rank = ranks.get_obj_rank_name(npc)
    local npc_comm = character_community(npc)
    local pool = {}

    for k, v in pairs(self.secrets) do
        if not v.given and v.community ~= "none" then
            
            local comm_match = (v.community == "all") or string.find(v.community, npc_comm)
            local rank_match = (v.rank == "all") or (v.rank == npc_rank)
            
            if comm_match and rank_match then
                table.insert(pool, k)
            end
        end
    end
    
    if #pool == 0 then return false end
    
    local selected_id = pool[math.random(#pool)]
    self:give_treasure(selected_id)
    return true 
end

 

Пример использования для сткопа:

[zat_hiding_place_30]
wpn_desert_eagle = 1, 1
ammo_11.43x23_fmj = 2, 1
ammo_11.43x23_fmj = 1, 1 - тут кстати ПЫС ошибка, две одинаковые секции, прочитает только последнюю. То есть одна пачка патрон в тайник не идёт по дефолту.

Делаем так

[zat_hiding_place_30]
wpn_desert_eagle = 1, 1
ammo_11.43x23_fmj = replace, ammo_50ae


В тайнике обе пачки будут 50го калибра. Но! Обе эти пачки без кастом даты, а потому в зачёт тайника они не войдут. Иконка на карте закроется только тогда когда ты подберёшь wpn_desert_eagle и только его. В тайнике они лежат на столе, смотри чтобы динамическая модель патрон ammo_50ae или её шейп с костью примерно соответствовали ammo_11.43x23_fmj, иначе они застрянут/вывалятся. Пистолет снайперской винтовкой не заменяем, аптечку или бинт комбинезоном не заменяем, короче ты понял суть.


Далее 

[zat_hiding_place_20]
ammo_5.45x39_fmj = 2, 1
wpn_ak74 = 1, 1
ammo_vog-25 = 2, 1
wpn_addon_grenade_launcher = 1, 1

Делаем так

[zat_hiding_place_20]
ammo_5.45x39_fmj = 2, 1
wpn_ak74 = 1, 1
ammo_vog-25 = 2, 1
wpn_addon_grenade_launcher = remove


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

Изменено пользователем Sim_npc_default_01
  • Лайк 1
  • Хабар 1

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


Ссылка на сообщение
Поделиться на другие сайты
 

В возможном предверии версии движка IX-Ray 1.4 хотелось бы предложить обновление для пулемёта Зулуса. Как я уже выяснил раньше, моделька была взята из COD Modern warfare Remastered. В первых скринах я собрал то, что имеется в игре на данный момент (только цвет чехла для короба не тот, но факт, что оба из КАЛибра). На вторых моё предложение. А так же хотелось бы увидеть прицел Ракурс на пикатини из Ганслингера Ссылки на модели прикладываю
https://sfmlab.com/project/f0f0e88b-4989-4493-8ed6-ca258f3379de/
https://sfmlab.com/project/008ea4db-af36-40a9-b7f6-09fa6430b92b/ (Отсюда взята передняя рукоятка)spacer.pngspacer.pngspacer.pngspacer.pngspacer.png

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


Ссылка на сообщение
Поделиться на другие сайты
 

Sim_npc_default_01 спасибо за все подробности, как дойдут руки, займусь ЗП. Пока бы выпустить ЧН версию.


Дополнено 0 минут спустя
В 20.09.2026 в 03:32, GunLagger_31r сказал:

хотелось бы увидеть прицел Ракурс на пикатини

Думаю будет, но не при текущей системе работы прицелов.

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


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Последние посетители   1 пользователь онлайн

Важная информация

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