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

Скриптование


Svoboда

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

Здрасьте.

 

Можно ли без правок движка изменить формат счетчика оставшегося времени для заданий? Единственный подходящий файл – [scripts\ask_manager.script], но сообщения в явном виде или его фрагментов (ui_st_time_remains, ui_st_days и ui_st_hours) в нем нет, как и ссылки на блок rem_time из файла [config\ui\job_item.xml].

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Здрасьте.

 

Делаю счетчик хилок на HUD: создал группу скриптовых статиков, вывел через get_hud():AddDialogToRender(…) и записал в таблицу, чтобы статики не потерялись при уборке.

Проблема: если добавлять статики в таблицу через table.insert, то индексы получаются просто числами, и найти среди них нужный статик (для привязки текста или для удаления статика, если каких-то предметов 0) невозможно. Если добавлять статики в таблицу по секции предмета list[sect] = static, то случается безлоговый вылет через секунду после загрузки – так же, как при отсутствии хранения ссылок на статики. Что я упускаю?

 

Мой мод и оригинал счетчика: https://drive.google.com/open?id=16gX0BYqim6zB6aZnGLqSV-kMPMB3QjQC

 

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Тот же вопрос по счетчику хилок…

Потестил оригинальный мод – после 3-й или 4-й загрузки (не важно, один сейв или разные) случается безлоговый вылет. Судя по результатам частичного исключения кода, ошибка все-таки не в таблице, а в выводе статиков.

Знаю, что мод написан еще под ТЧ 1.0004 – может, с тех пор что-то поменялось в способе вывода? В текущей версии (Steam 1.0006) повыключал все скриптовые моды, и все равно вылет после нескольких загрузок.

Кто-нибудь, попробуйте повесить у себя на апдейт оригинальный мод (hud_med) – случается ли вылет?

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Здрасьте.

 

Можно ли проверить наличие открытых диалоговых окон без перебора инфо-поршней ui_…? Видел упоминания о функции level.main_input_receiver, но где бы найти пример ее использования (кроме закрытия текущего окна через GetHolder():start_stop_menu)?

 

Может, просто есть какая-то проверка на отображение HUD?

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

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Здрасьте.

 

Существует ли в явном виде переменная, в которой хранится текущий вес предметов в инвентаре?

Есть ли способ чтения текущего веса, кроме прямого перебора или специальной функции в X-Ray Extensions?

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Здрасьте.

 

ТЧ 1.0006, счетчик лечебных предметов на HUD: статики не скрываются при использовании оптического прицела.

Пробовал добавлять проверку на текущее значение точности – без эффекта.

            if ui_on() or db.actor:accuracy()*1000 < 1 then
                st:Show(false)

 

Как правильно проверить активный оптический прицел?

https://drive.google.com/open?id=1F4OSvmH9l2UBxYgTOAgi0rfUMvQz3yi4

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Комсомол не ищет легких путей (а еще ленится разбирать нетпакеты): вместо чтения флага съемного прицела из нетпакета пошел через fov. Метод не самый оптимальный в плане того, что оптику низкой кратности приходится исключать вручную, но общий размер кода меньше.

 

Spoiler

 

67,5    обычный режим
45        MP5
41,25    пистолеты и дробовики / РГ-6
37,5    автоматы / LR мод (1,5x)
37,12    бинокль мин

25        G36 / FN2K (3,6x)
22,5    SUSAT / ПСО-1 / РПГ-7 (4x)
15        SUSAT мод / ПСО-1 мод (5x)
11,25    ПСО-1 мод / гаусс (5,5х)
5,625    бинокль макс

 

 

Скрипт вывода состояния прицела:

Spoiler

[scripts\bind_stalker.script]

t_upd = 0

function actor_binder:update(delta)
	object_binder.update(self, delta)

	if t_upd < time_global() then
		t_upd = time_global() + 500

		local item = db.actor:active_item()
		if item and not string.find( "wpn_knife, bolt", item:section() ) then
			if device().fov < 67 then	-- режим прицеливания (базовый fov = 67.5)
				if string.find( "wpn_binoc, wpn_lr300_m1", item:section() ) then	-- бинокль (fov = 37.1 … 5.6)
					news_manager.send_tip(db.actor, "binoc or lr-300_mod")			-- или мод LR-300 (fov = 37.5)
				elseif device().fov <= 25 then		-- любая оптика кратностью 3.6x (G36/FN2K) и выше
					news_manager.send_tip(db.actor, "optical scope")
				else
					news_manager.send_tip(db.actor, "%c[ui_clr_2]iron sights")
				end
			else
				news_manager.send_tip(db.actor, "%c[gray]no zoom")
			end
		else
			news_manager.send_tip(db.actor, "%c[red]no weapon")
		end
	end
  
  …

 

 

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Здрасьте.

 

Есть ли способ перебора только онлайн-объектов без перебора всех объектов на карте? Скажем, надо обнаружить противника в заданном радиусе, меньшем радиуса A-life.

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

@AndreySol Нет-спавн, скорее всего, не годится, тк проверку требуется выполнять не в момент загрузки, а несколько раз между загрузками. Перебор только db.storage – похоже, то, что нужно. Единственная непонятка: в заголовке [db.script] сказано "база данных живых онлайновых объектов …", но без проверки obj:alive() трупы тоже считаются активными противниками и приведенная ниже проверка выдает "true". Может, в проверке что-то не учтено?

 

Spoiler

function enemy()
	for id, v in pairs(db.storage) do
		local obj = level.object_by_id(id)
		if obj then
			if obj:alive() and ( obj:relation(act) == game_object.enemy or IsMonster(obj) )
			and obj:position():distance_to( act:position() ) < 40 then
				return true
			end
		end
	end

	return false
end

 

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Здрасьте.

 

Укорачивание строки, если она хотя бы на 2 символа больше заданной длины:

        local q_name = string.len(text)
        if q_name > 35 and q_name ~= 36 then
            text = string.sub(text, 1, 35) .. "…"
        end

 

Вариант "and q_name ~= 36" работает, а вариант "and not q_name == 36" – нет (вылета нет, но строка остается без изменений). Почему?

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

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

@Kirgudu Не догоняю… Было выражение "and not q_name == 36", которое прочиталось до имени переменной с логическим результатом "q_name == nil". Осталась часть "== 36" – с ней что происходит? Пустое место равно числу и никаких действий по этому поводу?

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

@Kirgudu "Сравнение false с числом" – вот эта часть отсутствовала в моих знаниях. Это такие азы, которые неизвестно, в каком разделе учебника искать.

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Здрасьте.

 

ТЧ 1.0006.

Есть мод с выводом статиков на HUD. Требуется поймать начало/конец катсцены и нажатие клавиш [Num +/-], чтобы временно скрыть статики. Как отследить указанные события? Может, есть проверка вроде hud_off() == true/false или отслеживание действия level.hide_indicators?

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

Здрасьте.

 

Делаю перебор пустующих, но все еще отмеченных тайников. Запуск после прогрузки (скажем, при использовании бинта) проходит успешно – с выводом списка. Запуск из actor_binder:net_spawn(data) проходит без какого-либо результата – видимо, тайники/метки еще не успевают прогрузиться. Как правильно отложить запуск скрипта, чтобы получать список сразу после загрузки? Пробовал условия if alife(), if level.present(), if device().precache_frame <= 1 – без эффекта.

 

На всякий случай, код:

Spoiler

function search()
	for sid = 5000, 5480 do
		local stash = level_object_by_sid(sid)
		if stash then
			if level_tasks.is_map_spot_present(sid, "treasure") and stash:is_inv_box_empty() then
				local ini = ini_file("misc\\treasure_manager.ltx")
				local n = ini:line_count("list")
				for i = 1, n do
					local useless, sect, empty = ini:r_line("list", i, "", "")
					if string.len(sect) > 0 and ini:r_u32(sect, "target") == sid then
						local name = game.translate_string( ini:r_string(sect, "name") )
						news_manager.send_tip(db.actor, sid .. ": " .. sect .. " = " .. name)
					end
				end
			end
		end
	end
end

 

 

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

1. Если под проверкой серверных объектов имеется в виду проверка меток напрямую через story_id тайников, то такая проверка выдает все известные тайники на локации, включая те, что давно облутаны и уже не имеют видимых меток.

2. Вот я и спрашиваю, как научить скрипт ждать. Мне известен только костыль через level.client_spawn_manager с ожиданием регистрации лишнего объекта и последующим его удалением, но это занимает не больше 0,5 с.

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

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

Ответ: Наличие лута и метки тоже можно проверять.

Какова содержательная этого ответа, если в скрипте я как раз проверяю метку и лут?

 

2. Можно пример с разовым действием на апдейте? С таким, условие запуска которого не проверяется на каждом кадре или каждые несколько секунд.

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

1. Старый баг ТЧ: если перезагрузиться на текущей локации, некоторые известные, но еще не облутанные тайники станут пустыми при сохранении видимости меток.

2. Тут можно поспорить: перебор все равно начинается с полного списка тайников, только по имени вместо sid, и активных тайников в целом больше, чем меток на текущей локации. Однако, при ссылке на готовую таблицу и ключ "active" код действительно получается проще:

Spoiler

[stash_fix.script]

function search()
	local t = treasure_manager.get_treasure_manager()
	local empty = {}

	for id, v in pairs(t.treasure_info) do
		if v.active == true then
			local sid = v.target
			local stash = level_object_by_sid(sid)
			if stash and stash:is_inv_box_empty() then
				empty[id] = sid
--				news_manager.send_tip(db.actor, id .. ": " .. sid)
			end
		end
	end

	return empty
end

 

3. Остается вопрос с отложенным разовым запуском. Допустим, я применяю вот такую конструкцию с двумя флагами:

Spoiler

[bind_stalker.script]

local stash_upd = false
local t_start = 0
local timeout = true
…
function actor_binder:net_spawn()
	t_start = time_global()
	stash_upd = true
end
…
function actor_binder:update(delta)
	if timeout then
		if time_global() > t_start + 5000 then
			timeout = false
		end
	end

	if stash_upd and not timeout then
		stash_fix.search()
		stash_upd = false
	end
end

 

Как эту конструкцию упростить?

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

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

@naxac Задействовал второй подход: добавил в конец функции give_treasure указанную ниже конструкцию с временной проверкой, и на тестовом тайнике результат стабильно положительный – предметы при многократной перезагрузке не теряются. Первый раз применил level.add_call; насколько оптимальна такая конструкция, и нет ли излишней нагрузки на actor_binder:update? Иконка дискеты вроде отображается с обычной частотой…

 

Spoiler

function switch(obj)
	if obj.online then
		local stash = obj.id
		alife():set_switch_online(stash, false)
		alife():set_switch_offline(stash, true)

		local t_start = time_global()

		local function delay()
			if time_global() > t_start + 2000 then
				return true
			end

			return false
		end

		local function back_online()
			alife():set_switch_offline(stash, false)
			alife():set_switch_online(stash, true)
			level.remove_call(delay, back_online)
		end

		level.add_call(delay, back_online)
	end
end

 

 

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

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение

@naxac Да, так даже проще. Со временем только странность: при прямой проверке переключение тайника проходит почти незаметно, а с таймером на 1 секунду тайник только уходит в оффлайн и не возвращается. Вроде и ПК не такой старый, и индикатор подгрузки не отображается постоянно.

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

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