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

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

Тема для обсуждения скриптов всего и всех в серии игр STALKER.


Задавая вопрос (!):
1. Внимательно изучите суть вопроса. Вопрос должен соответствовать выбранной Вами темы. Это поможет сохранить порядок и читабельность темы, а также облегчит поиск и понимание сего;
2. Изучите то, что уже есть в теме (пролистайте "руками", воспользуйтесь поиском на форуме);
3. Изучите информацию которая может вам помочь:

 
 

Stalkerin. Там есть много хороших статей касательно данной темы.
Уроки по модостроению. Есть рабочие примеры готовых скриптов различного назначения.

 

Справочное руководство по языку Lua 5.1
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/ru
Справочник по функциям и классам. Собрано много информации по функциям и классам, не всем, но по основные сведения предоставлены.

4. Дабы не превращать обсуждение в "кашу" разной информативной направленности, задавайте несколько вопросов по порядку (в разных постах) после того, как получите ответ на предыдущий вопрос;
5. "Спасибо" и тому подобное - будьте так любезны в ПМ. Если не любите писать в ПМ, в конце вопроса напишите фразу: "Заранее спасибо!" - или что-то в этом духе;
6. ПОЖАЛУЙСТА! Указывайте, для какой игры Вам необходима информация (ТЧ, ЧН, ЗП), если стоит мод - укажите название мода;
7. Если Вы что-то сделали и результат не такой, какой Вами задумывался, то, пожалуйста, приводите коды которые Вы изменяли/писали целиком! Это поможет другим правильно ответить на Ваш вопрос, а также оградит Вас от лишней писанины.
8. Оформляйте сообщение. Пользуйтесь тегами для того, чтобы отделить код от текста. Пишите грамотно - ПОЛЬЗУЙТЕСЬ ЗНАКАМИ ПРЕПИНАНИЯ.
9. И помните: «Правильно заданный вопрос – половина ответа».

 

Какие вопросы следует задавать, а какие нет...

 

Задавайте вопросы, которые касаются непосредственно скриптов и их работы, т.е. Вы что-то делаете, а у Вас что-то не получается, при этом у Вас на руках должен быть хотя бы какой-то код, свидетельствующий о Вашей причастности к вопросу.

 

Вопросы которые будут удалятся, следовательно их задавать не нужно:
-- Где находится та или иная функция?
Для ответа используем поиск по словам среди файлов оригинальной игры или мода, если объект поиска относится к нему, при помощью программы, которая Вам наиболее симпатизирует;
-- Как сделать что-то/то-то?
С подобными вопросами, либо в "ковырялки", где Вам вероятнее всего так же не ответят, либо выдвигаем мысли, подкреплённые теорией, практикой (идеальный вариант) и здравым рассудком;
-- Вопросы со смыслом: "сделайте", "совместите" и подобными глаголами повелительного наклонения.
-- К тому же удалению будут подвергаться вопросы, в которых масштабно не используются теги, для отделения кода и цитат от основного текста, а также не вписан в спойлер код размером превышающие семь строк.
Ответ на возможно возникший вопрос: В какую тему можно обратиться по поводу логики и спавна объектов?
В тему "ковырялок" соответствующей версии игры, для которой Вы задаёте вопрос.

И последнее: очень рекомендовано к прочтению Правила форума
 


  • Спасибо 1
  • Полезно 2
Ссылка на комментарий

Ребята, прошу помощи, уже неделю ковыряю - неосилю...

Проблема следующая:

 

Что нужно?

ГГ подходит к ящику (тайнику) и нажимает на него, срабатывает инфо  ui_car_body, как узнать какой ящик открыл ГГ?

Т.е. надо userdata этого конкретного ящика.

Пробовал через bind_physic_object.script -> function generic_physics_binder:use_callback( item, who )

это работает частично, т.к. например на Свалке, ящик возле Беса = gar_simulation_box_2 - не срабатывает (не идёт колбек).

Например для трупов сталков прекрасно работает treasure_manager.script -> function CTreasure:use( npc ) , как только нажимаешь на труп, сразу идёт колбек что это за userdata, надо тоже самое но на ящики.

Мы, вчера, соседям сказали, что материализация - состоялась, чтобы ваш авторитет не уронить. Вот, мол, было изваяние, а теперь - стала Марья Ивановна. Многие верят ... ©

Ссылка на комментарий

Продолжу:

Скрытый текст

Ребята, прошу помощи, уже неделю ковыряю - неосилю...

Проблема следующая:

 

Что нужно?

ГГ подходит к ящику (тайнику) и нажимает на него, срабатывает инфо  ui_car_body, как узнать какой ящик открыл ГГ?

Т.е. надо userdata этого конкретного ящика.

Пробовал через bind_physic_object.script -> function generic_physics_binder:use_callback( item, who )

это работает частично, т.к. например на Свалке, ящик возле Беса = gar_simulation_box_2 - не срабатывает (не идёт колбек).

Например для трупов сталков прекрасно работает treasure_manager.script -> function CTreasure:use( npc ) , как только нажимаешь на труп, сразу идёт колбек что это за userdata, надо тоже самое но на ящики.

 

Что выяснил: 

[bind_physic_object](use_callback): срабатывает только тогда, если ID ящика есть в db.storage, если нету - то нет реакции, вообще никакой. Для примера тестирую на Свалке. Всего 36 рюкзаков, из них в storage только 24, более того, рюкзак который спавнится по заданию Кости на Свалке тоже в storage не добавляется, рюкзак из инвентаря если спавнить - то добавляется.

Вопрос актуален:

как сделать колбек на открытие любого ящика? Т.е. подошёл, нажал на любой ящик, сработала какя-то функция.

 

Написал свой биндер (по аналогии 

[inventory_box]

[m_inventory_box]:inventory_box

[rx_inventory_box]:inventory_box

[kostya_box]

в items_devices.ltx и devices.ltx

 

теперь не работает script_binding = bind_physic_object.init

сделал так:

script_binding = my_binder.init
script_binding = bind_physic_object.init

работает только bind_physic_object.init но он не видит все ящики

 

сделал так:

script_binding = bind_physic_object.init

script_binding = my_binder.init

работает только my_binder.init , он видит все ящики, всё как мне надо, НО, теперь не работает bind_physic_object.init ...

 

Вопрос: как повесить на, например, [inventory_box] и bind_physic_object.init и my_binder.init чтобы оба работали, мой биндер нужен только для определения ящика который юзает ГГ, получается что в конструкции вида:

[inventory_box]

...

script_binding = bind_physic_object.init

script_binding = my_binder.init

 

работает тот что написан последним? Выходит два биндера нельзя вешать?

 

П.С. Получается, если мой биндер видит все ящики, значит ошибка в оригинальном биндере bind_physic_object.script?

Изменено пользователем Баба ЯГА

Мы, вчера, соседям сказали, что материализация - состоялась, чтобы ваш авторитет не уронить. Вот, мол, было изваяние, а теперь - стала Марья Ивановна. Многие верят ... ©

Ссылка на комментарий

А есть ли какая то возможность отследить момент появления ГГ после телепортации на другую локацию. Делаю проводников на движке ОГСР. Хочется прикрутить эффект после перехода на другую локацию.

Ссылка на комментарий

@Stalkersof Как вариант при переходе проводником выдавать поршен "использован проводник", и при спавне актора на локации проверять, включен ли он.

  • Полезно 1

А где зима?

img.php?nick=Balavnik&sert=2&text=t6

Ссылка на комментарий

@Stalkersof bind_actor.script -> net_spawn. Но этот колбек также вызывается при загрузке сохранения(т.к. по факту происходит спавн актора на уровень, выход в онлайн). Поэтому если хочется заморочиться, то желательно другое решение искать.

  • Спасибо 1

А где зима?

img.php?nick=Balavnik&sert=2&text=t6

Ссылка на комментарий
3 часа назад, Balavnik сказал:

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

Ну так правильно - на предыдущей локации выдаешь инфо, на новой локации проверяешь и удаляешь. Можно еще по идее и в pstor актора сохранить флажок, чтобы с поршенами не возиться.

Ссылка на комментарий

Здравствуйте! Появился такой вопрос. Можно ли как-нибудь отследить сколько времени висит артефакт на поясе? платформа ЗП

«Если долго мучиться, что-нибудь получится»
Охотник за артефактами|Crow Game Killer
img.php?nick=Pavel2000&sert=2&text=t0

Ссылка на комментарий

@RayTwitty того что ты написал, у меня нет в файле... Вот код файла bind_physic_object.script, где что изменить?

Скрытый текст

-- Physic objects binding; Разработчик: Evgeniy Negrobov (Jon) jon@gsc-game.kiev.ua
-- Доработки: Andrey Fidrya (Zmey) af@svitonline.com; completed

local watchdog = false

function log( ... ) _util.log( "bind_physic_object", ...) end
function abort( ... ) _util.abort( "bind_physic_object", ...) end

local gg = game_graph()

local path_exists = level.patrol_path_exists

local load_obj, save_obj = xr_logic.load_obj, xr_logic.save_obj
local issue_event = xr_logic.issue_event

local c_projector = clsid.projector
local c_car = clsid.car_s

local mtype_itm = modules.stype_item

local dbst = db.storage

local t_online = xl_data.get_t_online()
local t_npc_alive = t_online.npc_alive


class "generic_physics_binder" ( object_binder )


function generic_physics_binder:__init( item ) super( item )
    self.initialized = false
    self.loaded = false
    self.item_id = item:id()
    self.item_name = item:name()
end


function generic_physics_binder:reload( sect )
    object_binder.reload( self, sect )
end


function generic_physics_binder:reinit()
    if _G.watchdog then abort( "(%s):reinit, _G.watchdog: %s", self.item_name, _G.watchdog ) end
    _G.watchdog = "generic_physics_binder:reinit " .. self.item_name

    -- if string.find( self.item_name, "door" ) then
    --    log( "info", "(%s):reinit ...", self.item_name )
    -- end

    object_binder.reinit( self )
    local item = self.object
    local id = self.item_id

    local st = dbst[id]
    if st then
        self.st = st
        if st.pstor then self.pstor = st.pstor
        else st.pstor = {}; self.pstor = st.pstor
        end
    else
        local pstor = {}
        self.pstor = pstor
        st = { ["pstor"] = pstor }
        self.st = st
        dbst[id] = st
    end
    local c = item:get_car()
    if c then self.health = c:GetfHealth() end

    -- if string.find( self.item_name, "door" ) then
    --    log( "info", "(%s):reinit, ok", self.item_name )
    -- end
    _G.watchdog = false
end


function generic_physics_binder:net_save_relevant() return true end


function generic_physics_binder:save( pk )
    if _G.watchdog then abort( "(%s):save, _G.watchdog: %s", self.item_name, _G.watchdog ) end
    _G.watchdog = "generic_physics_binder:save " .. self.item_name

    object_binder.save( self, pk )
    save_obj( self.object, pk )

    if ( dbst[self.item_id].ini_filename or "" ) == "" then
        log( "error", "(%s):save, object not inited, (i: %s, a: %s)", self.item_name,
            tostring( self.initialized ), tostring( dbst[self.item_id].active_section ) )
        _G.sv_err = true
    end

    _G.watchdog = false
end


function generic_physics_binder:load( pk )
    if _G.watchdog then abort( "(%s):load, _G.watchdog: %s", self.item_name, _G.watchdog ) end
    _G.watchdog = "generic_physics_binder:load " .. self.item_name

    object_binder.load( self, pk )
    load_obj( self.object, pk )
    self.loaded = true

    _G.watchdog = false
end


function generic_physics_binder:use_callback( item, who )
    -- log( "info", "(%s):use ...", self.item_name )
    local st = self.st
    if st.active_section then
        issue_event( self.object, st[st.active_scheme], "use_callback", item, who )
    end
    if self.ph_snd then
        -- log( "info", "(%s):use, %s", tostring( self.item_name ), tostring( self.pstor.ph_snd ) )
        if self.pstor.ph_snd == 0 then
            self.pstor.ph_snd = 1
            self.object:set_tip_text( "Выключить" )
        elseif not self.pstor ~= 2 then
            self.pstor.ph_snd = 0
            self.object:set_tip_text( "Включить" )
    end    end
end

function generic_physics_binder:update( delta )
    if watchdog then
        _G.watchdog = watchdog
        abort( "(%s):update, watchdog: %s", self.item_name, watchdog )
    end
    watchdog = "generic_physics_binder:update " .. self.item_name

    local item = self.object
    local st = self.st

    object_binder.update( self, delta )
    if not self.initialized then

        if self.loaded and ( st.loaded_ini_filename or "" ) == "" then
            log( "error", "(%s):update, init, save file corrupted", self.item_name )
        end

        self.initialized = true    -- закомментить при отладке
        xr_logic.initialize_obj( item, st, self.loaded, actor, modules.stype_item )

        -- Запускаем ассоциированный с объектом партикл.
        local s = utils.cfg_get_string( st.ini, st.section_logic, "particle", item, false, "", nil )
        if s then
            self.particle = particles_object( s )
            self.particle:play_at_pos( item:position() )
        end

        -- Дизаблим ассоциированный с объектом граф
        local graph_point_marker = utils.cfg_get_string( st.ini, st.section_logic, "graph_point_marker", self.object,false, "", nil )
        if graph_point_marker then
            self.disable_graph_point = patrol( graph_point_marker ):game_vertex_id( 0 )
            game_graph():accessible( self.disable_graph_point, false )
        end

        local ini = st.ini
        if ini and ini:section_exist( "logic" ) and ini:line_exist( "logic", "active" ) then
            local s = ini:r_string( "logic", "active" )
            if s and string.match( s, "ph_sound" ) then
                self.ph_snd = true
                -- log( "info", "(%s):update, init, ph_sound present", self.item_name )
                if self.pstor.ph_snd ~= 2 then
                    if self.pstor.ph_snd == 0 then item:set_tip_text( "Включить" )
                    else
                        self.pstor.ph_snd = 1
                        item:set_tip_text( "Выключить" )
                end    end
            end
        end
    end
    if st.active_section or ( item:spawn_ini()
      and item:spawn_ini():section_exist( "drop_box" ) ) then
        watchdog = false
        xr_logic.issue_event( item, st[st.active_scheme], "update", delta )
            item:set_callback( callback.hit, generic_physics_binder.hit_callback, self )
            item:set_callback( callback.death, generic_physics_binder.death_callback, self )
            item:set_callback( callback.use_object, generic_physics_binder.use_callback, self )

        -- для бтра hit_callback не вызывается. заткнём эту дырку.
        if self.health and ( not self.nofixonhit ) then
            local health = item:get_car() and item:get_car():GetfHealth()
            if health then
                if self.health - health > 0.00001 then
                    self.health = health
                    self:hit_callback( item, self.health - health, vector():set( 1, 0, 0 ), actor, 0 )
                    self.nofixonhit = false
                end
            end
        end
    end
    -- if not self.initialized then    -- отладка !
    --    self.initialized = true
    --    log( "info", "(%s):update, init, ok", self.item_name )
    -- end
    watchdog = false
end


function generic_physics_binder:net_spawn( data )
    if not object_binder.net_spawn( self, data ) then
        return false
    end
    local item = self.object
    local cls = item:clsid()
    if cls == c_projector then
        db.add_sl( item )
    elseif cls == c_car then
        local h = hit()
        h.power = 0
        h.impulse = 0.0001
        h.draftsman = item
        h.direction = vector():set( 0, 0, 0 )
        h.type = hit.strike
        item:hit(h)
    end
    return true
end


function generic_physics_binder:net_destroy()
    local item = self.object
    local st = self.st
    if st.active_scheme then
        xr_logic.issue_event( item, st[st.active_scheme], "net_destroy" )
    end
    if self.particle then self.particle:stop() end
    if item:clsid() == clsid.projector then db.del_sl( item )
    end
    db.storage[item:id()] = nil
    object_binder.net_destroy( self )
end


function generic_physics_binder:hit_callback( victim, amount, dir, who, bone_idx )
    self.nofixonhit = true
    local st = self.st
    local item = self.object
    if self.ph_snd and ( amount >= 0.2 ) then
        -- log( "info", "(%s):hit_callback, %s (%s)", tostring( self.item_name ), tostring( amount ), tostring( self.pstor.ph_snd ) )
        self.pstor.ph_snd = 2
        item:set_tip_text( "" )
    end

    if st.ph_on_hit then
        xr_logic.issue_event( item, st.ph_on_hit, "hit_callback", victim, amount, dir, who, bone_idx )
    end
    if st.active_section then
        xr_logic.issue_event( item, st[st.active_scheme], "hit_callback", victim, amount, dir, who, bone_idx )
    end
end


function generic_physics_binder:death_callback( victim, who )
    local st = self.st
    local item = self.object
    local ini = item:spawn_ini()
    if st.active_section then
        xr_logic.issue_event( item, st[st.active_scheme], "death_callback", victim, who )
    end
    if self.particle then
        self.particle:stop()
    end
    if self.disable_graph_point then
        game_graph():accessible( self.disable_graph_point, true )
    end
    if ini and ini:section_exist( "drop_box" ) then xr_box.spawn_items( item ) end
end


function init( item )
    -- log( "info", "init, %s ...", item:name() )

    local ini = item:spawn_ini()
    if ( ini and ( ini:section_exist( "drop_box" ) or ini:section_exist( "logic" ) ) )
      or item:clsid() == c_projector then
        db.storage[item:id()] = {}
        local new_binder = generic_physics_binder( item )
        item:bind_object( new_binder )
    end

    -- log( "info", "init, %s: ok (no bind)", item:name() )
end


log( "module", "ok" )
 

 

Мы, вчера, соседям сказали, что материализация - состоялась, чтобы ваш авторитет не уронить. Вот, мол, было изваяние, а теперь - стала Марья Ивановна. Многие верят ... ©

Ссылка на комментарий
13.02.2025 в 12:00, Pavel_2000 сказал:

Можно ли как-нибудь отследить сколько времени висит артефакт на поясе? платформа ЗП

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

Способ простой, но ресурсоёмкий. В модуле bind_artefact в методе artefact_binder:update() проверять, есть ли родитель у клиентского объекта артефакта (функция obj:parent()) и равен ли он id актора. Если да, запускается скрипт, определяющий наличие предметов на поясе с помощью спавна невидимого объекта-разделителя (легко ищется поиском по форуму). Если id одного из предметов совпадает с id артефакта, update которого сейчас работает - прибавляем счётчик времени на поясе и сохраняем значение в свойствах артефакта (net-пакет или pstor объекта).

Способ посложнее, но с на порядок меньшей нагрузкой на движок. Когда артефакт может у нас появиться на поясе или быть удалённым из него, точнее, какие сопутствующие события мы можем отследить? Первое, что приходит в голову - это on_item_take и on_item_drop. Второе - это когда предмет уже в инвентаре, но мы перемещаем его между собственно рюкзаком и поясом. Это отследить без модификаций движка сложно, но у нас есть событие закрытия инвентаря, а для надёжности можно добавить проверку и при открытии. Так вот, при этих четырёх событиях мы запускаем функцию проверки предметов на поясе, упомянутую в способе первом, и для всех найденных на нём артефактов активируем счётчик времени, а для тех, что были на поясе ранее, но теперь убраны - деактивируем. Данные об активации счётчика времени и значение самого счётчика можно сохранять в свойствах самих артефактов по факту их перемещения в/из пояса, а прибавлять счётчик - всё в том же методе artefact_binder:update() конкретных артефактов.

  • Нравится 2
  • Полезно 2
Ссылка на комментарий
23 часа назад, Баба ЯГА сказал:

or item:clsid() == c_projector then

 

or item:clsid() == c_projector or item:clsid() == clsid.inventory_box then

У тебя какие-то правленные скрипты судя по всему.

13.02.2025 в 12:00, Pavel_2000 сказал:

Здравствуйте! Появился такой вопрос. Можно ли как-нибудь отследить сколько времени висит артефакт на поясе? платформа ЗП

Все зависит от того, есть ли методы проверки артефакта на поясе или колбек на перемещение на пояс\в рюкзак с пояса. В ЗП не помню, что есть, а чего нет. Если этого всего нет, то придется реализовывать руками, примерно как выше сказали. Есть готовые реализации определения предметов на поясе, им уже лет 15. Я бы их немного изменил, добавив запись информации о появлении артефакта на поясе в серверный объект (там же, где реализовано "проявление" артефактов Лунный свет ночью). Проще говоря - если сейчас артефакт на поясе и не заполнено поле в серверном объекте, то это будет маркер появления артефакта на поясе и оно же время. Для всех остальных артефактов поле обнуляем. А уже потом, в нужных местах просто берем текущее время и отнимаем записанное - получаем искомую разницу.

  • Нравится 1
  • Полезно 1
Ссылка на комментарий

Привет!
Задача - прочитать текстовый файл. Файл физически есть. 
 

local filename = getFS():update_path("$fs_root$", "tmp_del_me\\config\\weapons\\w_toz34.ltx")
log(filename) --> z:\op-2.2\tmp_del_me\config\weapons\w_toz34.ltx
local file = getFS():r_open(filename)

 

После этого имеем сообщение:


WARNING: CLocatorAPI::check_for_file file not found file z:\op-2.2\userdata\settings\z:\op-2.2\tmp_del_me\config\weapons\w_toz34.ltx in files list (size = 157817) 

 

Какого лешего оно добавляет в начало пути вот это?! "z:\op-2.2\userdata\settings"

Естественно, переменная file не создаётся...

Изменено пользователем phalcor
Ссылка на комментарий
38 минут назад, Norman Eisenherz сказал:

Какая ссылка указана в [fsgame.ltx] под именем $fs_root$?

Никакая: (где-то читал, что и не указывается она явно, ибо игра берёт её из реестра, хотя...)

Скрытый текст

$app_data_root$        = true|        false|    $fs_root$|            userdata\
$game_data$           = true|        true|    $fs_root$|            gamedata\
$game_ai$            = true|        false|    $game_data$|        ai\
$game_spawn$        = true|        false|    $game_data$|        spawns\
$game_anims$           = true|        true|    $game_data$|        anims\
$game_levels$       = true|        false|    $game_data$|        levels\
$game_meshes$        = true|        true|    $game_data$|        meshes\
$game_dm$            = true|        true|    $game_data$|        meshes\
$game_shaders$        = true|        true|    $game_data$|        shaders\
$game_sounds$        = true|        true|    $game_data$|        sounds\
$game_textures$        = true|        true|    $game_data$|        textures\
$game_scripts$        = true|        false|    $game_data$|        scripts\
$game_config$        = true|        false|    $game_data$|        config\
$game_huds$             = true|     false|     $game_data$|        skins_ui\huds\
$game_ui_inventory$       = true|     false|     $game_data$|        skins_ui\inventory
$level$              = false|    false|    $game_levels$
$game_saves$        = true|        false|    $app_data_root$|    savedgames\
$logs$              = true|        false|    $app_data_root$|    logs\
$crash$                = true|        false|    $app_data_root$|    crashes\
$screenshots$        = true|        false|    $app_data_root$|    screenshots\
$game_settings$        = true|        false|    $app_data_root$|    settings\
$mod_dir$             = false|    false|    $fs_root$|            mods\

 

Ссылка на комментарий
2 часа назад, abramcumner сказал:

а если вызвать r_open вот так?

Тогда так: 

WARNING: CLocatorAPI::check_for_file file not found file z:\op-2.2\userdata\settings\$fs_root$ in files list (size = 157893)

Вот скрипт:

local fs = getFS()

local fn ="w_toz34.ltx"
local ex = fs:exist( "$game_config$", "weapons\\"..fn)
if ex and ex.modif == 0 then --запакован, распакуем-скопируем 
    local from, to 
    from = fs:update_path("$game_config$", "weapons\\"..fn)
    to = fs:update_path("$fs_root$", "tmp_del_me\\"..fn)  
    fs:file_copy(from, to) --файл успешно копируется в корневая папка игры\tmp_del_me\w_toz34.ltx
    local file = getFS():r_open("$fs_root$","tmp_del_me\\"..fn)  --ВОТ ЭТО НЕ РАБОТАЕТ, выдаётся warning:
	--WARNING: CLocatorAPI::check_for_file file not found file z:\op-2.2\userdata\settings\$fs_root$ in files list (size = 157893)
end

Т.е. тут мало того, что припысывается в начало пути непонятно откуда берущийся z:\op-2.2\userdata\settings\,

но и не воспринимается $fs_root$. Мистика...

Ссылка на комментарий

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

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

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