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

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

_Призрак_, я, как бы, прежде чем писать перепробовал кучу вариантов <_<, и этот приводит к...

 

attempt to index local 'inventory_wnd' (a nil value)

 

Ибо, как я понял, он(main_input_receiver) отлавливает открытое окно, а не закрытое :) .

Изменено пользователем Struck
Ссылка на комментарий

Но у остальных же все работает. И у меня работало, хотя и с ПДА. Почему тебе не запомнить класс окна и не получать его каждый раз?

Freedom

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

Не класс, а объект всё-таки...

local inventory_wnd = nil

function on_inv_open()
if not wnd then
inventory_wnd = level.main_input_receiver()
wnd = CUIStatic()
wnd:SetAutoDelete(true)
wnd:SetWndRect(190, 730, 108, 33)
wnd:SetText("Кол-во: ")
wnd:SetFont(GetFontGraffiti22Russian())
wnd:SetTextColor(ca,cr,cg,cb)
end
inventory_wnd:AttachChild(wnd)
end

function on_inv_close()
inventory_wnd:DetachChild(wnd)
end

 

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

Charsi, Чет я тугой походу...вылетаю с пустым логом при повторном открытии инвентаря.

 


local wnd = nil
local inventory_wnd = nil
local ca, cr, cg, cb = 255, 231, 153, 22

function show(cnt)
if wnd == nil then return end
wnd:SetText("Кол-во: "..cnt)
end

function de_init()
inventory_wnd:DetachChild(wnd)
end

function init()
if not wnd then
inventory_wnd = level.main_input_receiver()
wnd = CUIStatic()
wnd:SetAutoDelete(true)
wnd:SetWndRect(190, 730, 108, 33)
wnd:SetText("Кол-во: ")
wnd:SetFont(GetFontGraffiti22Russian())
wnd:SetTextColor(ca,cr,cg,cb)
end
inventory_wnd:AttachChild(wnd)
end

 

Изменено пользователем Struck
Ссылка на комментарий

Ну это то дураку понятно, так и делаю.

Вот как бы..

 

if info_id == "ui_inventory" then
init()
elseif info_id == "ui_inventory_hide" then
de_init()
end

Изменено пользователем Struck
Ссылка на комментарий

Struck, чтобы получить выигрыш в производительности и не генерить каждый раз объекты, в m_backpack.script один раз (при первом обращении) генерятся и запоминаются как wnd = CUIStatic(), так и hud = level.main_input_receiver(), смотри табличку tHuds.

При закрытии окна инвентаря, в ТЧ происходит выдача соответствующего инфопоршня ("ui_trade###") - окно вообще закрывается или меняется на окно "торговли" - именно по этому событию от объекта hud (это общее окно инвентаря) отсоединяется (:DetachChild) информационное окно (wnd), тем самым очищая прежнюю информацию.

Т.о. тебе или генерить каждый раз соответствующие окна и пристыковывать их или запоминать основное (hud) и каждый раз при открытии инвентарного окна пристыковывать к нему свое информационное и по закрытию - отстыковывать и удалять.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos,

каждый раз при открытии инвентарного окна пристыковывать к нему свое информационное и по закрытию - отстыковывать и удалять.

 

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

 

Пытался делать через табличку на мотив tHuds - вылетал.(код уже удалил, поэтому "как делал" показать не могу)

 

P.S. как доделать мой вариант?

Изменено пользователем Struck
Ссылка на комментарий

_Призрак_, Charsi, окна (объекты) полученные через level.main_input_receiver() все же различны как для КПК (PDA) так и для разных ситуаций инвентарных окон.

На закрытие инвентаря...
- а что в твоем Charsi,понимании это за событие? ;-) Можно заглянуть к себе в инвентарь (<I>) и закрыть его, можно начать диалог с НПС (<F>) и видеть свой инвентарь ... А можно и из диалога открыть окно торговли ... Все это сопровождается открытием и закрытием "инвентаря"...

 

Struck, "как доделывать" - ответ прост: головой и руками. ;-) Перед тобою все есть и в последних постах и в собственно в упомянутом тобою скрипте. Доделывать "твой вариант" за тебя - считаю ненужным занятием.

 

P.S. Копаясь с данным функционалом ... для корректной начальной работы пришлось даже на старте игры вводить симуляцию принудительного закрытия "инвентарного" диалога (см. give_info("ui_talk_hide") ), чтобы алгоритм был предсказуем и корректен.

Объяснять не имею времени, да и не помню всех подробностей ... сам посмотри когда какие "оконные" инфопоршни появляются и присутствуют и особенно на старте игры, когда есть "нестандартность".

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos, если бы я мог, я бы сюда не писал...сегодня уже часа три пыхтел ковыряясь в этом коде, перепробовал кучу разных вариантов, ничего не помогло...так как что здесь нужно - я точно не знаю(точнее знаю, но реализовать не могу)...а "тыкать пальцем в небо" можно бесконечно.

 

Доделывать "твой вариант" за тебя - считаю ненужным занятием.

 

Полностью согласен, но...:)

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

Struck, прекращаем оффтопик о трудностях модмейкерства и потраченном времени... Для сравнения: мною, на эксперименты с именно этим модулем и в частности по выводу информации в свое окошечко приаттаченное к инвентарному было потрачено не один день. Тебе, по сути, всего-то осталось убрать невостребованное и добавить своего...

Так что не "тыкать пальцем в небо" нужно, теряя понапрасну время, не ждать готового кода, а думать, экспериментировать, получать информацию, анализировать и делать то, что захотелось. Самому(!), без всяких "но".

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos,

Ну хоть пинка дай куда идти, что смотреть...так как по твоему скрипту я мало что понял, вылетаю с пустым логом при повторном открытии инвентаря => второй раз хреново аттачится мой статик как я понимаю. Конечно же мне интересней докопаться самому, но вот у меня есть код вышеуказанный мною в 4709 посте, и безлоговый вылет...и что мне с этим делать я собственно говоря не знаю, но твое "всего-то осталось" немного подбадривает :)

 

 

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

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

Твой вылет обусловлен тем, что закрыв окно инвентаря, ты не удосужился деаттачить прикрепленное к нему свое информационное окошко. При попытке доступа к этому же инвентарному окну (повтороном открытии) объект окна пытается отобразить и ранее приаттаченное и(!), т.к. это окошко (wnd) уже не существует - происходит движковый вылет.

Поэтому, если ты что-то приаттачиваешь к окнам - озаботься вовремя это деаттачить. Когда это "вовремя" - тебе также дана информация да и в скрипте-примере это достаточно ясно (см. вызов UI_Clear).

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

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

 

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

 

Можно попытаться создать добавляемое окно один раз и до конца игры. Вопрос, когда именно делать то и другое. Вопрос с созданием в сущности не так и важен, это можно попросту сделать при первом использовании, используя функцию в таком стиле:

local added_wnd
local function get_my_wnd()
added_wnd = added_wnd or create_my_wnd()
end

потом надо везде получать это окно только с помощью этой функции, и проблем не будет. Однако вопрос с удалением уже не так тривиален. К какому из событий игры привязаться, чтобы оно произошло с гарантией? На самом деле, есть куча сценариев, когда ни один из вариантов не является в полной мере надёжным. На мой взгляд метод биндера актора ~finalaze - самый подходящий, поскольку срабатывает при любом штатном сценарии завершения игры. Одна только проблема, иногда удалением в нём по невыясненным причинам даёт сбой.

 

Другой вариант, если присоединяемое окно - не банальный статик, а окно на основе скриптового класса, то можно попытаться отсоединить его в его же собственном методе ~finalize. Надо только убедиться, что он вызывается, а для этого надо ненароком не сохранить ссылку на себя в этом окне, чтобы сработал уборщик мусора.

 

Другой вариант - создавать добавляемое окно всякий раз при присоединении и удалять при отсоединении. Этот вариант ничем не хуже остальных. Никакой нагрузки на ресурсы здесь нет, поскольку создание в данном случае - разовая и с точки зрения игры весьма редкая операция. Может даже оказаться, что это более надёжный и менее запутанный вариант, поскольку все начальные и завершающие действия с окном делаются в одном месте (т.е. создали и присоединили, а потом отсоединили и там же удалили).

 

Если окно создаётся один раз, то в этом случае вопрос с моментом присоединения тоже на самом деле неоднозначный. Как и в случае с физическим созданием я могу решить присоединить один раз и до конца игры. Всегда ли это срабатывает, уже не помню. А можно присоединять при открытии диалога и отсоединять при закрытии. В этом случае, как и для создания, важно, чтобы открытие/закрытие всегда срабатывало парой. Вот с этим тоже есть проблема. Опять же не помню подробностей, но для какого-то из движковых диалогов извещение об открытии/закрытии срабатывает нестабильно, поэтому насколько это подходящий вариант надо решать по ситуации.

  • Нравится 1
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий
... метод биндера актора ~finalaze - самый подходящий, поскольку срабатывает при любом штатном сценарии завершения игры. Одна только проблема, иногда удалением в нём по невыясненным причинам даёт сбой.

Выскажу пару-тройку мыслей-дополнений:

1. Вероятно (ИМХО на 99%) невыясненные сбои при "неудалении" - следствие зависаний самого биндера актора, на котором висят кучи коллбэков, которые зачастую не отключаются по завершению игры... Например, различные "on_drop" в сторонних скриптах, пытающиеся "криво" обработать событие "потеря предмета" для уже деактивированного объекта актра и т.п.

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

2. Есть менее "нагруженный", а значит и более надежный вариант - класс "actor_proxy", причем, объект этого класса возникает в игре одним из первых (до запуска сэйва) и уничтожается после "забинденого актора", что дает возможность и делать различные предустановки и чистить по окончанию.

3. Для ЧН и ЗП можно воспользоваться классом "se_actor"... уж на нем врядли могут возникать невысненные причины, т.е. игра или рухнет или будет работать.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos,

в том-то и дело, что сам ~finalize срабатывал, однако вылетало при удалении окна, вызванном из него. При этом, удаление из иного места в том случае работало нормально. Впрочем, тогда системы так и не выяснил, посему достоверность информации неполная. Я могу предположить, что проблема с ~finalizeв том, что это метод, вызываемый при работе сборщика мусора, а для глобальных объектов типа актора сборщик срабатывает не во время игры, а где-то между завершением и загрузкой. Насколько в этот момент можно заниматься оконными операциями и вообще чем-то, сказать сложно.

С этой точки зрения никакой иной объект не имеет особенных преимуществ перед ~finalize биндера актора, поскольку все они окончательно удаляются в одно и тоже время.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

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

malandrinus,

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

Тот же actor_proxy:deinit() вызывается не абы когда сработает чистильщик класса, а достаточно предсказуемо и вполне контролируемо из скриптов. Это событие (точнее события: se_smart_terrain:on_unregister() ) как раз происходит именно "в игре", имеется при любой ситуации выхода из игры (с перезагрузкой иль без нее) и по-сути независимо от зависаний потоков (не сработает один-два раза, сработает на третий...).

Хотя конечно же, и это не панацея для операций с оконными объектами, все же деаттачить прицепленные окна-объекты следует не в "темную и скопом", а "под контролем" локальных скриптов/классов или же вести централизованный алгоритм подобных оконных объектов. Но для общей зачистки "всего и вся" по выходу из игры, остановки работы различных скриптов/коллбэков и прочего - вполне удобная точка (событие)

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

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

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

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

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

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

Войти

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

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

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