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

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

@AndreySol, попробую, потом напишу результат.

Все зовут меня Пришедший из Ниоткуда...Почему?Потому что я пришел из ниоткуда и иду в никуда...

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

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

 

А можно по-человечески объяснить, что значит "вешаем на правую мышь" и как собственно проверять? Я же сказал, что в скриптах ничего не шарю, потому и прошу помощи.

Изменено пользователем MegaStalker
Добавлено Dennis_Chikin,

100500 раз говорили:

Сначала идем сюда: https://www.amk-team.ru/forum/topic/11584-yazyk-lua-obschie-voprosy-programmirovaniya/?page=1

Потом идем на lua.org и качаем там luac5.1.exe с причиндалами. luac5.1.cmd с содержимым вида

c:\куда_положили\luac5.1.exe %1
pause

вешаем на правую мышь, и им проверяем то, что понаделали.

Добавлено Dennis_Chikin,

ПКМ, "открыть с помощью", далее выбрать созданный cmd. Дальше все будет написано фонтом по бэкграунду:

в частности, если написано, что после строки 668 в news_main.script не хватает end - идем в тему по ссылке, внимательно читаем, и разбираемся, почему не хватает.

  • Не нравится 1

Все зовут меня Пришедший из Ниоткуда...Почему?Потому что я пришел из ниоткуда и иду в никуда...

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

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

    local reason=dead_reason[math.random(table.getn(dead_reason))]
    local dead=where_dead[math.random(table.getn(where_dead))]

 

  • Спасибо 1
Ссылка на комментарий
1 минуту назад, Dennis_Chikin сказал:

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

    local reason=dead_reason[math.random(table.getn(dead_reason))]
    local dead=where_dead[math.random(table.getn(where_dead))]

 

АМК знают, я же из их файла выдрал этот код. Просто в скачанном мною моде все было не разбито на кучу файлов, как у АМК, а соединено в один.

  • Смешно 3

Все зовут меня Пришедший из Ниоткуда...Почему?Потому что я пришел из ниоткуда и иду в никуда...

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

А напомните мне кто-нибудь, как вызвать my_subdir\my_script.my_function() ?

Где-то такое видел, но не помню, как правильно делается.

 

То есть, файлы лежат не в gamedata\scripts, а в gamedata\scripts\my_subdir

Можно, конечно, и все в sripts, но там возможна куча файлов  на одну тему, и получается как-то "неаккуратненько" (tm).

 

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

@Dennis_Chikin, ты про это? Проверял не в сталкаче.

C:\Programs\lua\test\src\test_folder\test_dofile.lua:


function test_func()
	print("print from test_dofile.lua")
end

C:\Programs\lua\test\src\test_prog.lua:

dofile("C:/Programs/lua/test/src/test_folder/test_dofile.lua")

test_func()

 

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

Например, путь я пытался узнать. Все перебранные варианты - либо nil, либо "ушла и не вернулась".

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

@Dennis_Chikin, в целом @buffy дал правильный совет, емнип.

my_script.script:

_G['my_script'] = {
	my_function = function() end
	my_function_2 = function() end
}

В любом нужном месте, например в _g.script:

local my_scripts_loaded = false
if not my_scripts_loaded then
	dofile(getFS():update_path("$game_scripts$","my_subdir\\my_script.script"))
	my_scripts_loaded = true
end

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

Как потом вызывать, думаю, понятно.

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

getFS():update_path("$game_scripts$","my_subdir\\my_script.script")

 

Вот это надо было. Спасибо.

  • Согласен 1
  • Полезно 1
Ссылка на комментарий
local esc_b2_give_random_table = {}
esc_b2_give_random_table[1] = {		[1] = {item = {"af_medusa"}},
									[2] = {item = {"af_blood"}},
									[3] = {item = {"af_vyvert"}}
	}
	
	
function esc_b2_give_random(first_speaker, second_speaker)
	for i = 1,1 do
		if has_alife_info("test_function") then
			for j = 1,#esc_b2_give_random_table[i] do
				if has_alife_info("test_function") then
					for k,v in pairs(esc_b2_give_random_table[i][j].item) do
						dialogs.relocate_item_section_to_actor(first_speaker, second_speaker,v)
					end			
					give_info("esc_b2_done_item_"..tostring(i).."_"..tostring(j))
					break
				end
			end	
	    end
	end
end

 

Пытаюсь создать функцию на выдачу рандомных предметов

НПС, которому в экшене диалога прописана эта функция(esc_b2_give_random), всегда выдает только первый предмет из esc_b2_give_random_table, т.е. af_medusa

А нужно, чтобы он выдавал случайно 1 из 3, прописанных в esc_b2_give_random_table, предметов

"Люди — животные, не имеющие ни страха, ни уважения, ни сочувствия. Лишь только блеск выгоды в глазах" © Алексей Шевцов

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

OC: Windows 10 Home, Видеокарта: NVIDIA GeForce GTX 1050 TI 4ГБ, Процессор: Intel Core i3 7100 3900 МГц 2 ядра, RAM(ОЗУ): 8ГБ DDR4, ROM(ПЗУ): 1ТБ

 

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

всегда выдает только первый предмет

Break прерывает цикл j.

 

1 час назад, Metro_Rus сказал:

нужно, чтобы он выдавал случайно

local rnd = math.random(1, #esc_b2_give_random_table[i])
dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, esc_b2_give_random_table[i][rnd].item[1])
Изменено пользователем WinCap
  • Спасибо 1

S.T.A.L.K.E.R. CoP Objects (upd 11.03.24)

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

@WinCap, Спасибо

function esc_b2_give_random(first_speaker, second_speaker)
    local random = math.random(1,3)
	if random == 1 then
		dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "af_medusa")
	end
	if random == 2 then
		dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "af_blood")
	end
	if random == 3 then
		dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "af_vyvert")
	end
end

можно вроде и так:puffy:

задаем рандомное число от "a" до "z"

Если "функция" равна "b", то делаем это..

Если "функция" равна "q", то делаем другое..

"Люди — животные, не имеющие ни страха, ни уважения, ни сочувствия. Лишь только блеск выгоды в глазах" © Алексей Шевцов

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

OC: Windows 10 Home, Видеокарта: NVIDIA GeForce GTX 1050 TI 4ГБ, Процессор: Intel Core i3 7100 3900 МГц 2 ядра, RAM(ОЗУ): 8ГБ DDR4, ROM(ПЗУ): 1ТБ

 

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

Всем привет. Кто-то проверял, этот метод предотвращения утечки памяти после закрытия окна действительно работает?

 

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

function autohiding_msg(txt, delay)
	local dlg = MonologueMsg(txt)
	level.start_stop_menu(dlg, true)
	autohide_dlg_timer(delay, dlg):start()
end

class "MonologueMsg" (CUIScriptWnd)

function MonologueMsg:__init(txt) super()
	local xml = CScriptXmlInit()
	local dev = device()
	
	if dev.aspect_ratio > 0.7 then
		xml:ParseFile("ui_ogse_monologue_msg.xml") -- 4^3
	else
		xml:ParseFile("ui_ogse_monologue_msg_16.xml") -- 16^9
	end	
	xml:InitWindow("main", 0, self)
	self.msg = xml:InitStatic("main:msg", self)
	self.msg:SetTextST(txt)
	self.dlg = self                                         
end 

function MonologueMsg:OnKeyboard(dik, key_act) CUIScriptWnd.OnKeyboard(self,dik,key_act)
	if key_act == ui_events.WINDOW_KEY_PRESSED and dik == DIK_keys.DIK_ESCAPE then
		self:GetHolder():start_stop_menu(self,true)
		self.dlg = nil -- отпускаем объект для сборщика мусора
	end
	return true
end

  

Также интересует, есть ли смысл использовать collectgarbage("collect") после закрытия окна?

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

@TIGER_VLAD, а где тут борьба с утечкой памяти? Вот это

self.dlg = self
self.dlg = nil

Сомнительная конструкция. Кстати, зачем ты делаешь

	if dev.aspect_ratio > 0.7 then
		xml:ParseFile("ui_ogse_monologue_msg.xml") -- 4^3
	else
		xml:ParseFile("ui_ogse_monologue_msg_16.xml") -- 16^9
	end	

Движок самостоятельно нужный файл будет использовать. Используй просто без постфикса.

 

Ты уверен что из-за этого окна течет память? Или тут не весь код приведен?

 

Я знаю только одну причину утечки памяти, связанную с окнами. Это когда в окнах используется AddCallback(), куда self передается. В этом случае окно уборщиком удалено не будет. Его этот self будет держать, т.к. оно там сохраняется в списке коллбэков. Я для этого делал вот такой костыль

class "ui_simple_craft" ( dsh_ui.dshCUIScriptWnd )
  self:dshAddCallback( "btn_4", ui_events.BUTTON_CLICKED, self.rep_btn, self )
function ui_simple_craft:on_quit()
  self:GetHolder():start_stop_menu( self, true )
  self:dsh_unregister_self()
end

dshCUIScriptWnd вот тут можешь посмотреть

https://github.com/dsh2dsh/op2ogse/blob/master/gamedata/scripts/dsh/dsh_ui.script

Там еще используется метод ClearCallbacks(), просто закомментируй, если у тебя такого нет. Это я в OGSR добавлял, что бы список коллбэков окна в движке очищать. Смысл в том, что бы self в коллбэках окна не хранился, а хранился некий идентификатор, с помощью которого этот self в нужный момент извлекается из другой структуры, не связанной с этим окном.

 

1 hour ago, TIGER_VLAD said:

Также интересует, есть ли смысл использовать collectgarbage("collect") после закрытия окна?

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

 

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

@dsh, Это код из ОГСЕ 0693 (ogse.script)

 

47 минут назад, dsh сказал:

Я для этого делал вот такой костыль... dshCUIScriptWnd вот тут можешь посмотреть...

Спасибо, буду разбираться. 

47 минут назад, dsh сказал:

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

Сложно конечно)

 

47 минут назад, dsh сказал:

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

Понял. Кстати этих collectgarbage("collect") в скриптах ОГСЕ (ui_handradio.script, jekan_devices.script, jekan_devices2.script, ui_remkit.script) - полно. От этого и немного фризит после нажатия на кнопки.

Изменено пользователем TIGER_VLAD
Ссылка на комментарий
12 minutes ago, TIGER_VLAD said:

От этого и немного фризит после нажатия на кнопки.

Можешь спокойно убирать, они там не нужны. И вот эти вот self.dlg = nil тоже не нужны. Это, как мертвому припарки. В скриптах OGSE полно мусора.

 

13 minutes ago, TIGER_VLAD said:

Сложно конечно

Да там в принципе можешь не разбираться. Просто добавь себе этот скрипт, закомментируй там ClearCallbacks() и везде поменяй

где наследуется от CUIScriptWnd пусть наследуется от dsh_ui.dshCUIScriptWnd

везде, где встретишь self:AddCallback(), поменяй на self:dshAddCallback()

в функциях выхода, там, где осуществляется закрытие окна, как правило, в OGSE это on_quit(), в конец добавь self:dsh_unregister_self(). Вот и все.

 

Ссылка на комментарий
17 минут назад, dsh сказал:

Можешь спокойно убирать, они там не нужны

Да уже пробовал, без collectgarbage фризов таких нет. 

 

14 минут назад, dsh сказал:

Просто добавь себе этот скрипт, закомментируй там ClearCallbacks() и везде поменяй

где наследуется от CUIScriptWnd пусть наследуется от dsh_ui.dshCUIScriptWnd

Да это я понимаю. Я имел ввиду код сложноват, до конца не пойму как оно работает)

 

 

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

@TIGER_VLAD, ну вот смотри. В стандартный AddCallback() передается функция и один параметр. Когда движок вызывает этот коллбэк, он вызывает эту функцию и передает ей этот параметр. Если функция - это метод класса, то первый параметр предполагается быть self. Таким образом регистрируются оконные коллбэки для классов, которые представляют из себя скриптовые окна. И вот этот самый self, который хранится, и не дает потом уборщику убрать это окно. Когда ты создаешь наследника dshCUIScriptWnd, то родитель в __init() назначает этому экземпляру порядковый номер и сохраняет, что этому номеру соответствует этот self. Сохраняет в отдельной табличке, которая ни имеет прямого отношения ко всем этим окнам. dshAddCallback() вызывает стандартный AddCallback(), но вместо той функции, которую ты туда передал, подставляет свою, при выполнении которой берется тот самый порядковый номер и достается по нему self, который затем и передается уже в твою функцию. Т.е. в коллбэке хранится уже не self, а какой-то порядковый номер и все, что сдерживает уборщик - это то, что окно сейчас используется и его self хранится в той табличке под тем порядковым номером. И вот dsh_unregister_self(), который ты вызовешь из on_quit(), удаляет из таблички тот self и порядковый номер. Все, уборщика больше ничто не держит. В списке коллбэков в движке до сих пор хранится переданный параметр, но теперь он не self и не ссылается ни на что. Это просто число и оно никому не мешает и никого не обязывает. Ну, как смог объяснил.

 

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

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

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

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

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

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

Войти

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

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

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

AMK-Team.ru

×
×
  • Создать...