Desertir 202 Опубликовано 2 Ноября 2011 (изменено) Задался вопросом, как убрать значение из пстора. Делал так local key = "key_1" local vol = nil xr_logic.pstor_store(db.actor,key,vol) При этом общеизвестная ругань: Arguments : LUA error: e:\stalker\gamedata\scripts\_g.script:20: bad argument #2 to 'format' Как нормально удалить значение из пстора? PS: понял, почему вылетает, но вопрос еще открыт. Изменено 2 Ноября 2011 пользователем Desertir ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 2 Ноября 2011 KD87, ну это напрямую, а если в xr_logic.pstor_is_registered_type(tv) добавить еще одну проверку tv ~= "nil"? Думаю он и nil запишет без выпендрежа ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 3 Ноября 2011 alife():create(spawn_item, db.actor:position()... Не spawn_item, а item... ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 3 Ноября 2011 Говори, что и где правил в бинд_сталкер и выкладывай все новые скрипты, под спойлер конечно. Вылет (если я прав) указывает на то, что в скрипте inventory есть синтаксическая ошибка. ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 5 Ноября 2011 Почитай раздел Синтаксис строки форматирования. Мне очень помогло. На счет "не работает". В основном числовые значения в Сталкере имеют тип float или integer. Так что попробуй заменить "%.02d" на "%.02f". По крайней мере у меня при записи в пстор нормально оставалось 2 знака после запятой. ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 16 Ноября 2011 _Призрак_, так же как вариант: создать статик и к нему приаттачивать статики с установленным текстом, причем увеличивать Y-координату приаттаченных статиков на N (высота шрифта + отступ). PS: вопрос то для темы Худа. ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 6 Декабря 2011 (изменено) AndreySol, а не проще, чем писать на форум, проверить самому? void Init(float x, float y, float w, float h) --активирует ранее созданное окно, которое будет иметь координаты x,y и ширину,высоту w,h соответственно. void Init(string texture, float x, float y, float w, float h) --плюс к вышенаписанному присваивает окну текстуру. void InitTexture(string texture) --просто присваивает окну текстуру. Так же интересны еще 3 метода void SetTextureOffset(float x, float y) --устанавливает смещение текстуры относительно координат окна. void SetStretchTexture(bool) --устанавливает "растягивание" текстуры: допустим у нас текстура размером 100х100, а окно 100х50, в этом случае если установить флаг true, то текстура растянется до размеров окна. bool GetStretchTexture() --установлено ли "растягивание" текстуры? Изменено 6 Декабря 2011 пользователем Desertir ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 16 Декабря 2011 (изменено) Tris, Старлей, начикать бы вам обоим по одному месту, что за глупые ошибки. for i=1 to 15 do Неверно, здесь Tris прав, однако тут return alife():create(items[math.random(#items)], npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()) нет. Оператор return хоть и возвращает значение выражения, стоящего после него, он также и вызывает мгновенное завершение функции, поэтому в циклах его нельзя ставить, разве что после какого-нибудь условия. Следует либо убрать его совсем, либо, если нужны все 15 серверных объектов, заспавненных в рюкзак к npc, можно заполнять таблицу и возвращать уже ее. function spawn_item(spawn_item, npc) local obj_tbl = {} for i=1, 15 do if npc == nil then npc=db.actor end obj_tbl[i] = alife():create(items[math.random(#items)], npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()) end return obj_tbl end Shadows, items[math.random(#items)] Получение случайного значения из таблицы items. Напомню, оператор #tbl возвращает целочисленное N, причем выполняется 2 условия: что tbl[N] ~= nil и что tbl[N+1] == nil. Видимо выше в скрипте есть таблица items с именами секций нужных предметов. Вроде все правильно написал, если нет - Artos поправит. Все верно, только: 1. СтОит предупредить, что на выходе цикла уже будет не серверный объект, а таблица заспавненных ... , что может быть важно для задумки Tris'а. 2. Не прокомментировано то, что первый аргумент вызова функции (spawn_item) по сути баласт или ошибка. Вероято Tris подразумевал именно таблицу 'items'. 3. Из цикла вытащить однотипные операции по проверке отсутствия 'npc' и получение параметров для спавна, т.е. типа: function spawn_item(items, npc) --/< на входе список секций для спавна if not npc then npc = db.actor end local vPos, idLv, idGv, id = npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id() local obj_tbl = {} for i=1, 15 do obj_tbl[i] = alife():create( items[math.random(#items)], vPos, idLv, idGv, id ) end return obj_tbl --/> таблица заспавненных объектов end --/Artos Изменено 16 Декабря 2011 пользователем Artos ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 2 Февраля 2012 Нужно перепаковывать нет-пакет, но, на сколько мне подсказали, там нет того, что есть в конфигах (возможно малая часть и есть). Так что только подменой. *Shoker*, не обязательно дублировать, если имя будет меняться 2-3 раза, думаю, не так уж и затратно написать еще несколько наследуемых секций, где будет изменяться только имя и описание. Хотя если у тебя пара сот стволов... ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 18 Февраля 2012 День добрый. Первое. Недавно для себя открыл, что ключом таблицы может быть... таблица. Отсюда вопрос, какие критерии достаточны для равенства таких (в виде таблицы) ключей? Никогда не задавался вопросом равенства таблиц, а вот тут всплыло. Второе. Как известно, пстор это таблица, стандартными средствами в которую можно записать только число\строку\булево значение, при этом ключом может быть только строка (это следует из функции xr_logic.pstor_save_all). В последствии она записывает в нет пакет, значит, по аналогии, можно записать и таблицу как значение пстора, более того, можно ключом пстора сделать не только строку, но и число или ту же таблицу. Вопрос, кто-нибудь уже это сделал и я тут велосипед изобретаю? Если да, то прошу ссылку к этому делу, сравнить, учесть ошибки. Если нет, то я пошел допиливать эту писалку\читалку. На ТЧ. Арбитр, в АМК при использовании спальника идет проверка на здоровье ГГ, и если оно ниже какого то значения, то кнопка "Спать до выздоровления" создается, если ты об этом. Другое дело сделать это в активном окне. Посмотри тут и тут. PS: И еще, заглянул в Справочник, увидел класс reader. Зачем он нужен? Обычного нет пакета не хватило? Там же только методы на чтение (запись я так понимаю идет в движке или из сохранения, а само чтение в методе биндера load). ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 18 Февраля 2012 Я не задавался целью узнать, какие типы данных могут быть ключами таблицы. На счет равенства таблиц, если спрашиваю, значит для меня это все таки имеет смысл. в нет-пакет такое все одно не запишешь и по любому придется сериализировать. Хм, я что, совершил невозможное? Не смешите. Я же написал, что пстор (по факту - таблица), когда вызывается метод биндера актора save, записывается в нет пакет. Повторю, таблица записывается в нет пакет, однако с большим НО - значением может быть только число\строка\булево, а ключом - исключительно строка. Что сделал я, я немного подкорректировал запись пстора в нет пакет, при этом значением и ключом может быть число\строка\булево\таблица, в свою очередь у этой внутренней таблицы ключи\значения так же могут быть числами\строками\булевыми\таблицами, однако вышеперечисленное НО никуда не делось. В конце концов самая последняя таблица может иметь только числа\строки\булевы. НЕ таблиц в pstor, а сериализированных в строку таблиц. Такой метод убирает это НО? Т.е. можно ли например в пстор записать таблицу, где есть ссылки на функции, потом сделать сейв\лоад и ссылки будут вполне рабочие? ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 17 Июля 2012 ins33, смешно уже смотреть на твои попытки что то сделать. У нас нету твоего кода и мы не экстрасенсы. Этот вылет связан с тем. что в скрипте есть ошибка синтаксиса, так что либо выкладывай весь код, который там написан, либо иди учи луа, хотя это как раз и надо было сделать с самого начала. ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 18 Июля 2012 (изменено) Callisto, сначала подумал про функцию AddCustomStatic С AddDialogToRender немножко меньше мороки - не надо прописывать в ui_custom_msgs.xml. Если верить справочнику, лучше поступить так, в биндере актора за функциями написать новую переменную local wnd = nil, и прописать следущий код в нет_спавн актора if wnd == nil then wnd = CUIStatic() wnd:Init("путь_до_текстуры",x,y,ширина,высота) wnd:Show(true) --не уверен в надобности get_hud():AddDialogToRender(wnd) end В нет_дестрой if wnd ~= nil then get_hud():RemoveDialogToRender(wnd) wnd = nil end Коды не проверял, но должно работать Изменено 18 Июля 2012 пользователем Desertir ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 21 Июля 2012 (изменено) Занялся логикой, схемами поведения и т.п. Возник вопрос про условия экшена. Например есть строки action:add_precondition (world_property(stalker_ids.property_alive, true)) action:add_precondition (world_property(stalker_ids.property_enemy, false)) action:add_precondition (world_property(stalker_ids.property_danger,false)) action:add_precondition (world_property(stalker_ids.property_anomaly,false)) Сами условия более менее понятны, но как они проверяются? Но даже если это списать на проверку в движке - константы из класса stalker_ids, то встает вопрос про "самодельные" константы: function addCommonPrecondition(action) --action:add_precondition (world_property(xr_evaluators_id.reaction,false)) action:add_precondition (world_property(xr_evaluators_id.stohe_meet_base + 1,false)) action:add_precondition (world_property(xr_evaluators_id.sidor_wounded_base + 0, false)) action:add_precondition (world_property(xr_evaluators_id.chugai_heli_hunter_base, false)) action:add_precondition (world_property(xr_evaluators_id.abuse_base, false)) end Откуда такие смещения в 1, 0(?), в других скриптах бывает 2 и т.д. Я нигде не нашел проверки на эти константы, только использование в конструкторе world_property. Так как это все работает? Что за класс такой world_property? PS: а кто нибудь описывал, какие условия проверяются для каждой константы из класса stalker_ids? PPS: ТЧ 1.0004 если это важно. Изменено 21 Июля 2012 пользователем Desertir ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 22 Июля 2012 Напишу тут. Пара уточнений. Под объектом в целом я буду иметь ввиду клиентский объект NPC. Менеджер - объект, получаемый методом motivation_action_manager() объекта: local manager = object:motivation_action_manager() Экшн - объект класса унаследованного от action_base. Прописать условие в менджер: manager:add_evaluator(id, property_evaluator(npc, name)) Установить условие экшену: action:add_precondition(world_property(id, true/false)) Итак, есть функция из xr_logic - enable_generic_schemes, которая косвенно через пару функций вызывается из апдейтов биндеров, так же она вызывается из метода класса gulag, но я пока не о гулагах. В этой функции прописаны схемы которые по идее активны всегда, так ведь? Ну если условия все пройдут. В конечном итоге еще через пару функций вызывается функция add_to_binder для каждой схемы, прописанной в enable_generic_schemes. В add_to_binder прописываются различные условия, например: manager:add_evaluator (properties["abuse"], evaluator_abuse("evaluator_abuse", st)) где properties["abuse"] = xr_evaluators_id.abuse_base. Если эта схема всегда активна, в своей новой, которая прописывается как например walker или kamp, т.е. которая активна не всегда, я могу опять получить менеджер объекта, в котором уже есть это условие, и установить это условие в каком нибудь экшене. В итоге работает это все так: -Есть несколько схем, которые активны всегда. -В этих схемах в менеджер каждого объекта прописываются разные условия с идом. -Позже к любому экшену в любой другой схемы можно добавить это условие по иду с помощью класса world_property. Так ли это, ну хотя бы образно? Если да, тогда имеет смысл порядок включения схем в enable_generic_schemes? Допустим в одной схеме есть установка условия на что-либо, а прописывается само условие на что-либо в менеджер только в следующей схеме. Или условие в экшн устанавливается только как ид, и не важно, прописано это условие в менеджер? И что если установить эшену несуществующее условие, если движок не найдет по иду условие - вылет? ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 30 Июля 2012 _Призрак_, хм, стандартных функций нету, я не нашел, может кто получше знает? Но пришла идея. Пост получился в стиле догадок, так что попрошу не смеяться\плакать. Прим.: лв - левел вертекс. Как можно вообще получить лв? 1. Через граф игры, но там нигде не используется позиция. В общем, не то, хотя кто его знает. 2. Методы game_object. 2.1. accessible_nearest(const vector&, vector&) Первый вектор это наша позиция, второй - направление(?). Предположительно, возвращает ближайший вертекс к позиции в направлении второго вектора, куда может пойти непись, к которому был применен этот метод. У меня вызывал вылет без лога, может у тебя, _Призрак_, получиться. Пример использования в xr_kamp, при этом, как условие, используется и метод accessible(number), аргумент - ид лв. Общий смысл наверное этот, но почему у меня не работает, не знаю. Это было первое, что мне пришло в голову. 2.2. level_vertex_id() Более чем знакомый метод. Поясню смысл, по заданной позиции мы спавним предмет, который не требует лв (антирад например). Дальше я хотел узнать сразу лв через свойство серверного объекта m_level_vertex_id, но ни черта не вышло - вернуло nil, почему? Класс не тот? Использовал другую секцию, соответственно другой класс, где это свойство точно должно быть, и опять nil. Решил довести до конца, т.е. до клиентского объекта. if se_obj then local cl_obj = level.object_by_id(se_obj.id) if cl_obj then local text = string.format("diff time %s; c_lv: %s; s_lv %s; s_gv %s", time - begin,c_obj:level_vertex_id(),tostring(se_obj.m_level_vertex_id),tostring(se_obj.m_game_vertex_id)) dprint(text) alife():release(se_obj,true) se_obj = nil end else se_obj = alife():create("antirad",vector():set(42.7,6.1,-23.67),0,2791) begin = time_global() end Все это дело конечно же в апдейте, вне функций объявлены se_obj и begin. В лог посыпалась такая инфа ! Cannot find saved game ~~~ diff time 239; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 249; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 296; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 252; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 258; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 280; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 286; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 250; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 224; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 258; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 271; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 269; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 269; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 264; c_lv: 17459; s_lv nil; s_gv nil ! Cannot find saved game ~~~ diff time 287; c_lv: 17459; s_lv nil; s_gv nil Лв тот, это с моей локации, но способ убивает своей дорогой в Москву через Китай, при этом нужно знать хотябы один гейм вертекс с локации. В общем кривое и сумасшедшее решение. 2.3. set_actor_position(vector&) И тут мне пришла еще одна дурацкая идея, разновидность 2.2. Можно переместить ГГ в заданную позицию, на следущем апдейте снять его лв и вернуть обратно. Минусы значительнее: все это только в пределах активной локации, невозможность обработать сразу несколько точек. Точнее можно и несколько точек, но если их будет слишком много, то играющий успеет увидеть мерцание экрана сразу после загрузки игры (если вообще планируется снимать лв в самом начале, иначе тоже ф топку). if begin == true then old_pos = db.actor:position() db.actor:set_actor_position(vector():set(42.7,6.1,-23.67)) begin = false elseif begin == false then dprint(db.actor:level_vertex_id()) db.actor:set_actor_position(old_pos ) begin = nil end Снова в апдейте, а begin и old_pos так же объявлены как глобальные для модуля. Единственный плюс, меньше нагрузки и скорость побольше, за один апдейт все свершиться. Но о лучше\хуже вообще не стОит говорить, все как видно и так плачевно 3. level.vertex_in_direction(number, vector&, number) И вот вроде бы эврика, но черта с два. Тесты показали несостоятельность этой задумки, точнее только на половину. Итак, эта функция возвращает лв в направлении единичного вектора (2 аргумент) от другого лв (ид - 1 аргумент) на расстоянии (число - 3 аргумент). Например level.vertex_in_direction(0,vector():set(0,0,1),5) - по хорошему это дело вернет лв от нулевого лв на расстоянии 5 метров строго на север, НО если на пути не будет ноды (аи сетка пошла вокруг камня, а направление проходит как раз через камень), то возвратится граничный лв. Решил немножко порисовать. Я думаю все наглядно, в итоге мы получим не зеленый лв, а синий. Но могу сказать, что способ вполне рабочий на целой аи сетке. function get_vl_by_pos(pos_lv) local n = 16661 pos_lv = vector():set(42.7,6.1,-23.67) local pos_n = level.vertex_position(n) local dir = vector():sub(pos_lv,pos_n) local radius = dir:magnitude() dir:normalize() local lv = level.vertex_in_direction(n,dir,radius) dprint(lv) end Сначала я взял n = 0 но не вышло изза описаной выше проблемы, взял который не так далеко, все заработало. Тут я переопределил входной аргумент, это исходная позиция. В итоге тоже присоединяюсь к вопросу, покажите мне, извращенцу, как можно получить лв по позиции? И задам еще более обширный вопрос, как получить все лв, которые находятся в какой либо зоне, в рестрикторе например? ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 5 Августа 2012 Итак, во-первых, _Призрак_, спасибо тебе за мотивацию Это я о получении левел вертекса по позиции. Хоть мне это и не нужно как то, но идет развитие идеи о получении таблицы лв из зоны, что мне нужно. Ну а во-вторых, да, я смог получить лв по позиции без полного перебора на ТЧ. Перебор идет частичный. Расскажу о фактах про аи-сетку. 0. При проекции на плоскость XZ представляет собой ноды 0.7х0.7 1. Ноды (или лв) нумеруются с юга на север, с запада на восток. 2. Нулевой вертекс самый западный, однако не всегда самый южный. 3. Вертекс имеет координаты X и Z кратные 0.7 (размеру ноды). 4. Если лв различаются только координатой У (на разной высоте), то нумерация чередуется (что нумеруется первым, верхний или нижний, мне пока не известно). Повторюсь, это факты, так сделали GSC. Т.е. некая упорядоченность есть, и она никуда не девается при перекомпиляции карты, если аи-сетка не менялась. Вот сама функция local edir = vector():set(1,0,0) function get_lv_by_pos(need_pos) local lv,tmp_lv = 0,0 local pos = level.vertex_position(lv) local offset = ((need_pos.z > pos.z) and 1) or -1 local dist = need_pos.x - pos.x while dist > 0.35 do lv = level.vertex_in_direction(lv,edir,dist) if lv == tmp_lv then lv = lv + offset else pos = level.vertex_position(lv) dist = need_pos.x - pos.x end tmp_lv = lv end offset = ((need_pos.z > pos.z) and 1) or -1 dist = math.abs(need_pos.z - pos.z) local hight = math.abs(need_pos.y - pos.y) while dist > 0.35 or hight > 1 do lv = lv + offset pos = level.vertex_position(lv) dist = math.abs(need_pos.z - pos.z) hight = math.abs(need_pos.y - pos.y) end return lv end need_pos - позиция, по которой будет считаться вертекс Исходя из фактов, задача сводилась к получению столбца, где содержится нужный нам лв. Точнее любого лв из одного столбца с нужным нам лв. Это делается в первом цикле. Во втором идет уже полный перебор до нужных нам значений. Некий брутфорс присутствует, но все же не пол миллиона вертексов сравнивать. На счет скорости выполнения, она дико разная, т.к. невозможно предсказать, сколько будет перебрано лв. Мои тесты ! Cannot find saved game ~~~ time 906.521301 lv 16215 ! Cannot find saved game ~~~ time 30504.269531 lv 46570 ! Cannot find saved game ~~~ time 675.549866 lv 246010 ! Cannot find saved game ~~~ time 675.374878 lv 246010 ! Cannot find saved game ~~~ time 2139.680420 lv 595088 ! Cannot find saved game ~~~ time 2091.987061 lv 595088 ! Cannot find saved game ~~~ time 2460.593506 lv 397579 Думаю, на худ даже выводить можно, хотя так лучше не экспериментировать Брался лв актора, получался всегда правильный. Если есть время и желание, можете протестировать у себя, результаты в ЛС. Метод хорош тем, что должен работать и в подземных уровнях, однако есть один изъян, если высота между реальным лв и позицией будет отличаться больше чем на метр, то игра зависнет, так что аккуратнее, хотя это не должно стать проблемой. 1 ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 12 Сентября 2012 (изменено) У тебя просто инициализация этого чекера, а регистрировать на каллбеки кто будет? Замени xml:InitCheck("check_svu", self) на self:Register(xml:InitCheck("check_svu", self), "check_svu") PS: разобрался бы сначала в оконных классах, чем просто копировать с примера. Изменено 12 Сентября 2012 пользователем ColR_iT ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 12 Сентября 2012 ПЫСы их знают, какие каллбеки нужны. Сейчас порылся, для чекера в ui_mp_main.script стоит BUTTON_CLICKED, а не CHECK_BUTTON_SET. Используй поиск по файлам в Notepad++ например, лучший друг в изучении скриптов и конфигов. ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение
Desertir 202 Опубликовано 30 Декабря 2012 Столкнулся с такой проблемой. При создании окна со списком не всегда доступны элементы списка, которые я туда добавляю. Точнее не "не всегда", а при определенном условии, если игра на паузе или не загружен уровень, то все в порядке. Если создать окно непосредственно во время игры, то никакие элементы списка я не могу получить. Я так понимаю, то ли это сборщик мусора, то ли я не правильно делаю. Пока решил проблему сохранением элемента списка непосредственно в списке (а ля таблица). Упрощенный пример кода, который демонстрирует эту проблему под спойлером. class "bug" (CUIScriptWnd)function bug:__init(owner) super()self:Init(0,0,1024,768)self.bg = CUIFrameWindow()self.bg:Init("ui_tablist_textbox",128,128,256,320)self.list = CUIListWnd()self.list:Init(138,138,172,172)self.list:EnableScrollBar(true)self.list:ShowSelectedItem(true)self:AttachChild(self.bg)self:AttachChild(self.list)self:Register(self.list,"list")self:AddCallback("list",ui_events.LIST_ITEM_CLICKED,self.start,self)self:reset_list()if owner thenself.owner = ownerself.owner:GetHolder():start_stop_menu(self,true)self.owner:GetHolder():start_stop_menu(self.owner,true)elselevel.start_stop_menu(self,true)endendfunction bug:start()local sel_item = self:get_sel_item()if not sel_item then pcon("item not exist") return endlocal name = sel_item:GetText()pcon(name)endfunction bug:reset_list()local t = {"Kardon","Svalka","Agroprom","Bar","Yantar","Military","Pripyat","Chernobyl"}self.list:RemoveAll()for _,value in pairs(t) doself.list[value] = CUIListItemEx()self.list[value]:SetText(value)self.list:AddItem(self.list[value])--local a = CUIListItem()--a:SetText(value)--self.list:AddItem(a)endendfunction bug:get_sel_item()local sel_index = self.list:GetSelectedItem()local sel_item = self.list:GetItem(sel_index)return sel_itemendfunction bug:OnKeyboard(dik,keyboard_action)CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)if dik == DIK_keys.DIK_ESCAPE thenif self.owner thenself:GetHolder():start_stop_menu(self.owner,true)self:GetHolder():start_stop_menu(self,true)elselevel.start_stop_menu(self,true)endendreturn trueend В таком виде работает всегда. Т.е. объект элемента списка сохраняется и никуда не вышвыривается. Если закомментить строки self.list[value] = CUIListItemEx() self.list[value]:SetText(value) self.list:AddItem(self.list[value]) и раскомментить 3 строки ниже них, то работает только в главном меню. Очевидно и понятно, что переменная a существует только в своем блоке, но почему элемент не сохраняется методом AddItem? Или список в принципе рассчитан на работу только в главном меню и его составляющих? Как обойтись без такого шаманства self.list[value] = CUIListItemEx() если мне нужно создавать окно в игре, а не в главном меню? PS: pcon - вывод в лог, в качестве owner выступает объект главного меню, если запущено в нем. Если окно запущено в игре, owner = nil. ТЧ 1.0004. SAP и Trans mod github Поделиться этим сообщением Ссылка на сообщение