Kirgudu 1 217 Опубликовано 29 Сентября Поделиться Опубликовано 29 Сентября @ted.80 так подставь то, что ты взял из полной функции, в своё условие. local actor = db.actor + actor:object=="gen_document_1354" and actor:object=="gen_document_1355" = db.actor:object=="gen_document_1354" and db.actor:object=="gen_document_1355" db.actor:object - это функция. Мало того, что ты сравниваешь её (не результат выполнения функции, а саму функцию) со строкой, так ещё и применяешь синтаксис, характерный для вызова метода (указание функции после двоеточия), без собственно вызова (забыл про круглые скобки). Это приведёт к немедленному отказу в загрузке такого скрипта движком, потому что его синтаксис некорректен. И даже такое написание, хоть синтаксически и правильное, будет неверным: db.actor:object()=="gen_document_1354" and db.actor:object()=="gen_document_1355" поскольку вызов этой функции требует передачи аргумента: db.actor:object("строка"), см. пример парой сообщений выше. Так-то по смыслу твоё предложение верно. Правильная же реализация будет такая: elseif ln=="l15_generators" and actor:object("gen_document_1354") and actor:object("gen_document_1355") then 3 1 Инструмент Ссылка на комментарий
Juk_Bers0vik 1 Опубликовано 14 Октября Поделиться Опубликовано 14 Октября А что нужно дописать, чтобы при выпадении с мутантов было больше частей тел? И чтоб с того же кабана можно было всегда по разному выбить 4, 3, 2, 1 Ссылка на комментарий
Купер 2 908 Опубликовано 14 Октября Поделиться Опубликовано 14 Октября @Juk_Bers0vik , что используется в качестве базы для правок? Если не изменяет память, в ЧН оригинальной версии выпадение, вообще, изначально не предусмотрено. Просто чтобы было понятно, от чего отталкиваться. Простой правкой конфигов не обойтись, придётся добавлять скриптовый спаун в тело мутанта. Примеры релизации пожно подсмотреть в FS моде, старых версиях OGSM, например, или поискать отдельно smart_monser_part мод. И доработать под собственные нужды . 2 Ссылка на комментарий
Norman Eisenherz 316 Опубликовано 15 Октября Поделиться Опубликовано 15 Октября @Juk_Bers0vik Спавн имеет то же описание в движке и те же конфиги, только вероятность везде указана 0. Для нескольких предметов надо делать обработчик в [bind_monster.script] update. 1 Мини-моды: ТЧ ЧН ЗП Шпаргалка Ссылка на комментарий
Купер 2 908 Опубликовано 15 Октября Поделиться Опубликовано 15 Октября А зачем update коллбек у мутанта дёргать? "Одноразовый" on_death, по-моему, более чем достаточно. Или net_spawn, например. 1 Ссылка на комментарий
Norman Eisenherz 316 Опубликовано 15 Октября Поделиться Опубликовано 15 Октября Да, это лишнее – апдейт нужен для обновления подсказки. 1 Мини-моды: ТЧ ЧН ЗП Шпаргалка Ссылка на комментарий
imcrazyhoudini 209 Опубликовано 2 Ноября Поделиться Опубликовано 2 Ноября Спавню НПС в скваде в смарт террейн. Сквад: Спойлер [yan_ryaboy] faction = stalker npc = yan_ryaboy Собственно, а как этому скваду/НПС назначить story id? ищу человека, который смог бы заняться разработкой погоды на OGSR. кто может помочь - пишите в ЛС. Ссылка на комментарий
Kirgudu 1 217 Опубликовано 2 Ноября Поделиться Опубликовано 2 Ноября 11 часов назад, imcrazyhoudini сказал: как этому скваду/НПС назначить story id Отряду никак, story_id может быть присвоен только объекту, но не группе объектов. Одному НПС из отряда, если этот отряд симуляционный (то есть один из многих отрядов с идентичным профилем, создающийся для целей войны группировок), тоже никак. Симуляционные скрипты не смогут решить самостоятельно НПС из какого отряда должен иметь уникальный story_id. А вот если такой отряд один на всю игру и спавнится по какому-то событию из логики или вручную, тогда есть лазейка. Для этого можно модифицировать следующую цепочку функций (см. места с комментариями, оформленными --<< ... >>): Скрытый текст function create_squad(actor, obj, p) if obj ~= nil then printf("pl:creating_squad from obj [%s] in section [%s]", tostring(obj:name()), tostring(db.storage[obj:id()].active_section)) end local squad_id = p[1] if squad_id == nil then abort("Wrong squad identificator [NIL] in create_squad function") end local smart_name = p[2] if smart_name == nil then abort("Wrong smart name [NIL] in create_squad function") end --<< добавляем чтение третьего параметра, в котором опционально может быть передан story_id >> local first_npc_story_id = p[3] local ltx = sim_board.squad_ltx if not ltx:section_exist(squad_id) then abort("Wrong squad identificator [%s]. Squad descr doesnt exist.", tostring(squad_id)) end local player_name = utils.cfg_get_string(ltx, squad_id, "faction", self, true, "") local board = sim_board.get_sim_board() local player = board.players[player_name] if player == nil then abort("Wrong player_name [%s] for squad [%s]", tostring(player_name), tostring(squad_id)) end local smart = board.smarts_by_names[smart_name] if smart == nil then abort("Wrong smart_name [%s] for [%s] faction in create_squad function", tostring(smart_name), tostring(player_name)) end --!!!!!!!!!!! Зыс из затычка против вылета, если кто-то пытается спаунить отряд с комьюнити отличным от того которым занят смарт!!!!!! if smart.player_name ~= player_name and smart.player_name ~= "none" then return end local squad local is_autogenerated_id = utils.cfg_get_bool(ltx, squad_id, "auto_id", self, false, false) --<< передаём параметр со story_id дальше, в симуляционный скрипт >> if is_autogenerated_id then squad = board:create_squad(player.player_name, sim_squad_scripted.sim_squad_scripted, smart, nil, squad_id, first_npc_story_id) else squad = board:create_squad(player.player_name, sim_squad_scripted.sim_squad_scripted, smart, squad_id, nil, first_npc_story_id) end board:enter_smart(squad, smart.id) for k,v in pairs(squad.squad_npc) do local obj = alife():object(k) board:setup_squad_and_group(obj) end squad:update() end Скрытый текст --<< добавляем в параметры функции ещё один для передачи story_id >> function sim_board:create_squad(player_id, squad_class, spawn_smart, sq_id, settings_id, first_npc_story_id) printf("create squad called") local squad_id = tostring(sq_id or self.id_generator:get_id()) if self.squads[squad_id] ~= nil then printf("---------------------------") print_table(self.squads) printf("------------------------last_id %s", self.id_generator.m_last_id) print_table(self.id_generator.m_given) printf("---------------------------") print_table(self.id_generator.m_free) printf("---------------------------") abort("Two or more squad with id[%s] found!!!", squad_id) end local squad = squad_class(self, player_id, squad_id, settings_id) squad:init_squad(spawn_smart) printf("Creating squad[%s] in smart[%s]", squad_id, spawn_smart:name()) self.squads[squad_id] = squad --' Определяем в каком смарте создать новый отряд --<< передаём добавленный параметр далее в функцию создания НПС >> squad:create_npc(spawn_smart, first_npc_story_id) squad:set_squad_sympathy() squad:set_squad_relation() self:assign_squad_to_smart(squad, spawn_smart.id) --' Пересчитываем Team, Squad, Group for k,v in pairs(squad.squad_npc) do local obj = alife():object(k) squad.board:setup_squad_and_group(obj) end --' Регистрануть новый отряд в его группировке. self.players[player_id]:register_squad(squad) self.players[player_id]:faction_brain_update() return squad end Скрытый текст --<< добавляем в параметры функции ещё один для передачи story_id >> function sim_squad_generic:create_npc(spawn_smart, first_npc_story_id) self.squad_power = 0 --' Высчитываем базовую позицию спауна local base_spawn_position = spawn_smart.position local base_lvi = spawn_smart.m_level_vertex_id local base_gvi = spawn_smart.m_game_vertex_id if spawn_smart.spawn_point ~= nil then base_spawn_position = patrol(spawn_smart.spawn_point):point(0) base_lvi = patrol(spawn_smart.spawn_point):level_vertex_id(0) base_gvi = patrol(spawn_smart.spawn_point):game_vertex_id(0) end local custom_resource = nil local min_npc, max_npc = 3,5 if self.player_id == "monster" then local level_name = alife():level_name(game_graph():vertex(spawn_smart.m_game_vertex_id):level_id()) local min, max = 0,5 if monster_resource_by_level[level_name] ~= nil then min = monster_resource_by_level[level_name][1] max = monster_resource_by_level[level_name][2] end custom_resource = math.random(min,max) min_npc = monster_num_by_resource[custom_resource][1] max_npc = monster_num_by_resource[custom_resource][2] end local player = self.board.players[self.player_id] local npc_in_squad = math.random(min_npc,max_npc) --<< определяем необходимость присвоения story_id (параметр передан или нет) >> local need_story_id = (type(first_npc_story_id) == "number") for i=1,npc_in_squad do local position = base_spawn_position position.x = position.x + math.random(-2,2) position.z = position.z + math.random(-2,2) local spawn_section = player:get_spawn_section(spawn_smart, custom_resource) local obj = alife():create(spawn_section, position, base_lvi, base_gvi) --<< если необходимо присвоить story_id, делаем это посредством редактирования net-пакета >> if need_story_id and obj then local pk = get_netpk(obj, 1) if pk:isOk() then local data = pk:get() data.story_id = first_npc_story_id pk:set(data) end --<< сбрасываем признак необходимости story_id, так как присвоить можно только один раз первому НПС из отряда >> need_story_id = false --<< добавляем id НПС и story_id в онлайн таблицу объектов, получивших связку со story_id уже после загрузки >> if not db.id_by_story_id then db.id_by_story_id = {} end db.id_by_story_id[first_npc_story_id] = obj.id end obj.squad_id = self.squad_id self.squad_npc[obj.id] = obj.id self.sound_manager:register_npc(obj.id) if self.commander_id == nil then self.commander_id = obj.id end self.npc_count = self.npc_count + 1 --printf("sim_squad_generic: npc_count is [%s], obj:rank is [%s], obj:name is [%s], self.squad_power is [%s]", tostring(self.npc_count), tostring(obj:rank()), obj:name(), tostring(self.squad_power)) self.squad_power = self.squad_power + 5*obj:rank()/1000 end self.smart_id = spawn_smart.id self:refresh() if self.squad_power > 25 then abort("Squad power couldnt be over 25!!!") end end Скрытый текст --<< добавляем в параметры функции ещё один для передачи story_id >> function sim_squad_scripted:create_npc(spawn_smart, first_npc_story_id) local spawn_sections = utils.parse_names(utils.cfg_get_string(sim_board.squad_ltx, self.settings_id, "npc", self, true, "")) self.squad_power = 0 local spawn_point = utils.cfg_get_string(sim_board.squad_ltx, self.settings_id, "spawn_point", self, false, "") --print_table(debug.getinfo(1)) printf("SPAWN SMART %s", spawn_smart:name()) --' Высчитываем базовую позицию спауна local base_spawn_position = spawn_smart.position local base_lvi = spawn_smart.m_level_vertex_id local base_gvi = spawn_smart.m_game_vertex_id if spawn_point ~= nil then base_spawn_position = patrol(spawn_point):point(0) base_lvi = patrol(spawn_point):level_vertex_id(0) base_gvi = patrol(spawn_point):game_vertex_id(0) elseif spawn_smart.spawn_point ~= nil then base_spawn_position = patrol(spawn_smart.spawn_point):point(0) base_lvi = patrol(spawn_smart.spawn_point):level_vertex_id(0) base_gvi = patrol(spawn_smart.spawn_point):game_vertex_id(0) end local player = self.board.players[self.player_id] local spawn_sections_ltx = system_ini() --<< определяем необходимость присвоения story_id (параметр передан или нет) >> local need_story_id = (type(first_npc_story_id) == "number") for k,v in pairs(spawn_sections) do local custom_data = utils.cfg_get_string(spawn_sections_ltx, v, "custom_data", self, false, "", "stalker_custom_data.ltx") if custom_data ~= "stalker_custom_data.ltx" then abort("INCORRECT npc_spawn_section USED [%s]. You cannot use npc with custom_data in squads", v) end local position = base_spawn_position position.x = position.x + math.random(-2,2) position.z = position.z + math.random(-2,2) local obj = alife():create(v, position, base_lvi, base_gvi) --<< если необходимо присвоить story_id, делаем это посредством редактирования net-пакета >> if need_story_id and obj then local pk = get_netpk(obj, 1) if pk:isOk() then local data = pk:get() data.story_id = first_npc_story_id pk:set(data) end --<< сбрасываем признак необходимости story_id, так как присвоить можно только один раз первому НПС из отряда >> need_story_id = false --<< добавляем id НПС и story_id в онлайн таблицу объектов, получивших связку со story_id уже после загрузки >> if not db.id_by_story_id then db.id_by_story_id = {} end db.id_by_story_id[first_npc_story_id] = obj.id end obj.squad_id = self.squad_id self.squad_npc[obj.id] = obj.id self.sound_manager:register_npc(obj.id) if self.commander_id == nil then self.commander_id = obj.id end self.npc_count = self.npc_count + 1 self.squad_power = self.squad_power + 5*obj:rank()/1000 end self.smart_id = spawn_smart.id self:refresh() end Скрытый текст --<< модифицируем оригинальную функцию поиска объекта по story_id, чтобы она учитывала свежесозданные (на этом же апдейте) объекты >> function level_object_by_sid( sid ) local sim = alife() if sim then local se_obj = sim:story_object( sid ) if se_obj then return level.object_by_id( se_obj.id ) end --<< серверный объект не найден, ищем среди добавленных после загрузки >> local se_obj_id = db.id_by_story_id and db.id_by_story_id[sid] if se_obj_id then return level.object_by_id( se_obj_id ) end end return nil end Тогда, например, создание из логики уникального отряда, первому (либо единственному) НПС из состава которого будет присвоен story_id, будет выглядеть так (показано на примере Васяна со Свалки): [sr_idle@story_messenger] on_info = {+gar_story_searched_digger_body} sr_idle@story_messenger_dogs_spawn %=create_squad(gar_digger_messenger_man:gar_smart_terrain_8_5:731)% где 731 - добавленный в том числе в game_story_ids.ltx персональный story_id. Примечание: для модификации net-пакета и присвоения story_id в данном примере использован модуль m_netpk от Артоса: https://www.amk-team.ru/forum/topic/13216-sborochnyj-ceh/?do=findComment&comment=971137 3 Инструмент Ссылка на комментарий
imcrazyhoudini 209 Опубликовано 2 Ноября Поделиться Опубликовано 2 Ноября @Kirgudu https://dropmefiles.net/ru/UH7Gzws9V Не работает почему-то, проверил пару раз, можешь взглянуть, авось прозевал чего? ищу человека, который смог бы заняться разработкой погоды на OGSR. кто может помочь - пишите в ЛС. Ссылка на комментарий
Kirgudu 1 217 Опубликовано 2 Ноября Поделиться Опубликовано 2 Ноября @imcrazyhoudini придется подождать, я за компом буду уже не скоро, в лучшем случае дня через 3. Может кто быстрее подскажет. 1 Инструмент Ссылка на комментарий
Kirgudu 1 217 Опубликовано 4 Ноября Поделиться Опубликовано 4 Ноября 02.11.2024 в 22:59, imcrazyhoudini сказал: Не работает почему-то, проверил пару раз, можешь взглянуть, авось прозевал чего? 1. Я функцию create_npc в sim_squad_scripted.script выше сначала показал с ошибкой, затем поправил почти сразу после публикации поста, но в примере выше она осталась с ошибкой. Не исключено, что по каким-то причинам эта ошибка к вылету не ведёт, но при этом и не работать не даёт правильно, такое бывает. Рекомендую снова взять себе эту функцию из моего поста, теперь она там исправлена. 2. Не показано, где и как происходит создание нужного отряда. 3. Не показано, добавлен ли новый story_id в реестр. В остальном модификация оригинальных функций произведена правильно, кроме вышеупомянутой других ошибок не вижу. Опять же, по такой схеме story_id добавляется Васяну и потом используется в моде Final Stroke, там это проверено не раз и успешно работает. 1 Инструмент Ссылка на комментарий
imcrazyhoudini 209 Опубликовано 4 Ноября Поделиться Опубликовано 4 Ноября @Kirgudu 5 часов назад, Kirgudu сказал: Не показано, добавлен ли новый story_id в реестр. Скрытый текст game_story_ids.ltx [story_ids] 1 = "yan_saharov" 2 = "yan_pribor" 3 = "yan_ryaboy" ; нужный 5 часов назад, Kirgudu сказал: 2. Не показано, где и как происходит создание нужного отряда. Скрытый текст [logic] active = sr_idle [sr_idle] on_info = {+yan_ryaboy_start} sr_idle@2 %=create_squad(yan_ryaboy:yan_ryaboy:3)% 5 часов назад, Kirgudu сказал: теперь она там исправлена. Поправил, не помогло. ищу человека, который смог бы заняться разработкой погоды на OGSR. кто может помочь - пишите в ЛС. Ссылка на комментарий
Kirgudu 1 217 Опубликовано 4 Ноября Поделиться Опубликовано 4 Ноября (изменено) @imcrazyhoudini, что такое второй параметр yan_ryaboy из твоего вызова спавна отряда? Вот этот: 1 час назад, imcrazyhoudini сказал: %=create_squad(yan_ryaboy:yan_ryaboy:3)% И ещё вопрос: что именно не работает-то? Спавн отряда? Или назначение НПС из этого отряда story_id? Если второе - как проверял? Изменено 4 Ноября пользователем Kirgudu Инструмент Ссылка на комментарий
imcrazyhoudini 209 Опубликовано 4 Ноября Поделиться Опубликовано 4 Ноября 1 час назад, Kirgudu сказал: Вот этот: Название смарта + название сквада. Не работает назначение стори айди. Проверял двумя способами - одновременно со спавном НПС выдаётся квест в котором цель указана как сей НПС. И пытался такой функцией проверить: Скрытый текст function spot_ryaboy() local obj = alife():story_object(story_ids.yan_ryaboy) level_tasks.add_location_by_id(obj.id, "blue_location", game.translate_string("set_spot_ban")) end На что получаю: Скрытый текст FATAL ERROR [error]Expression : !m_error_code [error]Function : raii_guard::~raii_guard [error]File : E:\GitHub\Advanced-X-Ray-Public\SourcesAXR\xrServerEntitiesCS\script_storage.cpp [error]Line : 748 [error]Description : ....k.e.r. clear sky\gamedata\scripts\dialogs_yantar.script:755: attempt to index local 'obj' (a nil value) stack trace: 0x00000000400CC800 AdvancedXRay.exe, Device + 544 byte(s) FATAL ERROR [error]Expression : fatal error [error]Function : CScriptEngine::lua_error [error]File : E:\GitHub\Advanced-X-Ray-Public\SourcesAXR\xrServerEntitiesCS\script_engine.cpp [error]Line : 180 [error]Description : <no expression> [error]Arguments : LUA error: ....k.e.r. clear sky\gamedata\scripts\dialogs_yantar.script:755: attempt to index local 'obj' (a nil value) ищу человека, который смог бы заняться разработкой погоды на OGSR. кто может помочь - пишите в ЛС. Ссылка на комментарий
Kirgudu 1 217 Опубликовано 5 Ноября Поделиться Опубликовано 5 Ноября (изменено) @imcrazyhoudini и не заработает таким образом. Ты пытаешься найти серверный объект по его story_id, но сервер ничего об этом номере не знает, поскольку ты вот только что его присвоил.. Обрати внимание на последний спойлер в моём примере, а именно _g.script и функцию level_object_by_sid, специально модифицированную для таких случаев. Используй её или, если нужен только id, можно вытащить кусочек функционала из функции с поиском в db таблице, куда мы положили нужную информацию при назначении story_id. Либо производи нужные действия не на том апдейте, когда story_id присваивался, а позже. 10 часов назад, imcrazyhoudini сказал: Название смарта + название сквада Самодобавленный смарт, значит. Ясно. А то одно из предположений было, что отряд не спавнится из-за указания невалидного смарта. Изменено 5 Ноября пользователем Kirgudu 1 Инструмент Ссылка на комментарий
imcrazyhoudini 209 Опубликовано 5 Ноября Поделиться Опубликовано 5 Ноября Извиняюсь, если не понял, но я квест позже начал инициализировать, но всё равно не помогло: Скрытый текст [logic] active = sr_idle [sr_idle] on_info = {+yan_ryaboy_start} sr_idle@2 %=create_squad(yan_ryaboy:yan_ryaboy:3)% [sr_idle@2] on_info = sr_idle@3 %=give_inited_task(storyline:yan_ryaboy_start:stalker)% [sr_idle@3] on_info = {+yan_contr_start} sr_idle@4 %=create_squad(yan_gorbun:yan_gorbun)% [sr_idle@4] on_info = nil Плюс, если я устанавливаю стори_ид Рябому, то он больше не является членом смарт террейна и гуляет где захочет. ищу человека, который смог бы заняться разработкой погоды на OGSR. кто может помочь - пишите в ЛС. Ссылка на комментарий
Kirgudu 1 217 Опубликовано 5 Ноября Поделиться Опубликовано 5 Ноября @imcrazyhoudini как связана инициализация квеста с использованием только что присвоенного story_id, непонятно: опять сделано что-то, что осталось за кулисами. Когда будет время (скорее всего, в предстоящие выходные), постараюсь сам воспроизвести ситуацию на файлах чистой игры и предоставлю результат для изучения. А пока дальше сам, мои советы на какое-то время иссякли. Не исключено, что успеешь сам найти решение проблемы раньше, метод-то вполне рабочий - подтверждается реальными опытами в существующем моде. Инструмент Ссылка на комментарий
imcrazyhoudini 209 Опубликовано 5 Ноября Поделиться Опубликовано 5 Ноября @Kirgudu имеешь в виду под "за кулисами" - квест показать? Я то могу: Скрытый текст [yan_ryaboy_start] prior = 1 type = storyline task_type = additional icon = ui_icontask_help_icon target_story_ids = 3 name = yan_ryaboy_name text = yan_ryaboy_text condlist_0 = {+yan_ryaboy_life} complete condlist_1 = {+yan_ryaboy_dead} fail Но вот дело в том, что ломается смарт террейн когда пытаешься назначить стори айди. И на следующую часть логики (sr_idle@3 вроде уже) не переходит. Ещё из интересного - при сейв-лоаде до бесконечности спавнится по одному НПС (Рябой опять-таки), что даёт основание полагать, что логика рестриктора зацикливается. Но это всё догадки. ищу человека, который смог бы заняться разработкой погоды на OGSR. кто может помочь - пишите в ЛС. Ссылка на комментарий
Kirgudu 1 217 Опубликовано 5 Ноября Поделиться Опубликовано 5 Ноября @imcrazyhoudini всё, я понял, что у тебя за последовательность событий, раньше как-то туманно было. Ты спавнишь отряд, и из этой же логики в следующей секции запускаешь квест, целью которого является искомый story_id. Честно говоря, я не уверен, что между двумя частями логики проходит достаточное для получения сервером информации о story_id количество апдейтов. Если это так, рекомендую попробовать сделать запуск квеста во второй секции логики не на on_info, а, например, на on_timer с таймаутом в пару секунд. Однако если с промежутком между секциями логики всё в порядке, предлагаю посмотреть на содержимое функции task_objects.get_inited_task, где обрабатывается параметр квеста target_story_ids. Первые несколько строчек выглядят так (остальные нам не интересны): local sid = tonumber(self.target_story_ids) -- считываем из параметра квеста story_id if(sid) then self.target = id_by_sid(sid) -- находим серверный объект по story_id и берём у него id (функция в _g.script) if not(self.target) then -- проверяем, что полученный id не пустой abort("Target for storyline task doesnt exist. Story id [%s]", tostring(self.target_story_ids)) end ... Получается, что если бы story_id не был присвоен нашему объекту, мы неминуемо дошли бы до вызова функции abort. Вот и думай. Может стоит обложиться выводом в лог во всех ключевых точках и попытаться понять, что конкретно происходит. 1 Инструмент Ссылка на комментарий
imcrazyhoudini 209 Опубликовано 6 Ноября Поделиться Опубликовано 6 Ноября @Kirgudu должен признать, что когда назначаю стори айди логика рестриктора дальше не читается, Рябой в смарт не заселяется. Куда покопать в таком случае? Могу даже мод в личку скинуть с нужным сейвом если так сказать дистанционно решить не получится. ищу человека, который смог бы заняться разработкой погоды на OGSR. кто может помочь - пишите в ЛС. Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти