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

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


Svoboда

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

17 минут назад, Norman Eisenherz сказал:

Почему без "запасного" маркера случается вылет?

Так у тебя проблема не с "костылем-перебором", а с отображением ячеек инвентаря, раз вылет туда ссылается. Насколько я понял, отработал R_ASSERT, потому что функция не нашла предмет по указанной позиции. Нужно смотреть метод GetCellAt, возможно там предметы 0х0 не обрабатываются. Обратить также внимание на сравнение вещественных чисел с нулем, менялось это или нет. Или, может быть при удалении предмета из онлайна его уже нет в CUICellContainer, это вполне могло поменяться в ЧН, тогда как в ТЧ прокатывало.

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

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
11.07.2023 в 19:39, Norman Eisenherz сказал:

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

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

 

В общем случае, по идее в одной ячейке может быть только один предмет. А когда у нас предмет 0х0, то их может быть бесконечно много, что уже выглядит как косяк с точки зрения системы. Почему тогда в ТЧ это работает?.. Нужно смотреть все цепочки вызовов, что откуда вызывается, в том числе GetItemPos.

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

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
4 часа назад, phalcor сказал:

Подскажите, как можно определить опьянение актора? Скриптовой функции, я так понял, нет. 

Может, как-то через нет-пакет это число добывается? 

Просто факт опьянения или степень опьянения? Если первое - можно попробовать отследить наличие эффектора. Если второе, то тут сложнее и костыли.

 

Вроде в АМК моде была алкогольная зависимость, можно посмотреть как там сделали.

 

P.S. А, на чистом движке эффектор тоже не получить никак, так что только костыли выдумывать.

 

@666Ian значение надо сохранить в серверном объекте в se_item.script, найдя нужный тебе класс оружия. После чего загрузить и выставить это значение при входе оружия в онлайн (на net_spawn или на первом апдейте).

Изменено пользователем RayTwitty
  • Нравится 1
  • Полезно 1

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
2 часа назад, Опричник сказал:

огсе 0693

В нем есть свойство alcohol, там все проще.

 

В АМК скорее всего считали сколько раз выпили водку (использовали предмет) и параллельно рассчитывали опьянение на апдейте, повторяя то, что делает движок внутри. Ну я бы так наверно сделал, если нет возможности движок поправить.

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
6 часов назад, 666Ian сказал:

А можно какой-нибудь простой пример, вот цену предмета конкретного выставить в 10 рублей?

Нужно создать биндер для оружия (по аналогии с физ. объектами например), подключить его в базовой секции в конфигах (если есть, иначе во всех секциях по отдельности), получать на net_spawn серверный объект и смотреть, сохранена ли там стоимость. Если да, то менять (восстанавливать) ее твоим способом через свойство cost для клиентского объекта.

Соответственно при первом изменении свойства, менять также значение и в серверном объекте по аналогии. Серверный объект это "слепок" клиентского/онлайного, в котором сохраняются данные. Тебе надо следить за тем, чтобы данные были одинаковы.

 

Проще по-моему двиг поправить, добавив там в общую кучу сохранение cost))

  • Нравится 1
  • Сочувствую 1

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
1 час назад, 666Ian сказал:

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

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

 

1 час назад, 666Ian сказал:

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

Нет, экземпляр биндера создается для каждого объекта отдельно, в том и смысл))) Биндер физ. объектов я привел в пример как тот, который можно взять за основу. По-нормальному конечно, для артов нужен свой биндер, для оружия свой и т.д. У всех объектов же разные параметры.

Изменено пользователем RayTwitty
  • Нравится 2

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
22 часа назад, 666Ian сказал:

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

Пример тут в двух словах не получится привести. Могу как вариант посоветовать посмотреть Shadows Addon, там есть биндер автомобилей (sa_cars.script) и сохранение/загрузка топлива (se_car.script).

 

Но если у тебя кастомный движок типа OGSR, то нафиг это все надо - сделай себе форк и добавь необходимые параметры прямо в движок.

  • Нравится 1
  • Согласен 1

Telegram-канал RayTwitty Space

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


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

@wdfgosdgf https://xray-engine.org/index.php?title=Класс_sound_object

 

Автоматическое изменение позиции звука не реализовано, нужно делать ручками. В твоем случае надо подвязаться на апдейт биндера вороны и обновлять позицию звука через метод set_position. Разумеется, для каждой вороны свой экземпляр звукового объекта, ссылка на который сохраняется в биндере.

Изменено пользователем RayTwitty
  • Нравится 3

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
21.10.2023 в 14:54, Капрал Хикс сказал:

Подскажите, в оригинале ТЧ можно влиять на голод ГГ скриптами? Скажем, повесить на апдейт увеличение сытости при наличии в инвентаре определённой брони?

Разве что спавнить с каким-то интервалом по времени невидимый батон и съедать его по-тихому.

 

P.S. Только сейчас заметил пост выше))

Изменено пользователем RayTwitty
  • Нравится 2

Telegram-канал RayTwitty Space

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


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

Понадобилось тут разобраться с поворотом объектов. Оказывается есть целых 3 ключевых понятия: direction, angle и rotation.
С последними двумя все просто, углы поворота над плоскостью, первый в радианах, второй в градусах (именно это значение мы видим в SDK).

А вот первое - это направление в диапазоне от -1 до 1.

Набросал функции получения direction имея angle/rotation, которые должны работать по идее даже в оригинале (где имеется полурабочий класс матрицы, но его достаточно):

function angle_to_direction(angle)
	local m = matrix()
	m:setXYZ(angle.x, angle.y, angle.z)
	return m.k
end

function rotation_to_direction(angle)
	local m = matrix()
	m:setXYZ(utils.deg2rad(angle.x), utils.deg2rad(angle.y), utils.deg2rad(angle.z))
	return m.k
end

А вот чтобы обратно получить angle/rotation имея direction, нужно, как я понял получить доступ к матрице трансформации объекта (XFORM), применив к нему getXYZ (ну или getHPB).

Прав ли я в рассуждениях и что такое на самом деле direction? Направление относительно чего?

 

P.S. Частично угол поворота можно восстановить при помощи методов вектора getH и getP, но только yaw и pitch.

  • Полезно 3

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
1 час назад, Zander_driver сказал:

У каждого 3д-объекта можно взять условно направление "вперед" - обычно это положительное направление по одной из осей локальных координат этого объекта

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

Telegram-канал RayTwitty Space

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


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

@Colder 

function read_list(section, ini)
	if not ini then
		ini = system_ini()
	end
	local t = {}
	for i = 0, ini:line_count(section) - 1 do
		local result, id, value = ini:r_line(section, i, "", "")
		if result then
			t[id] = value
		end
	end
	return t
end

local t = read_list("item", ini_file("items\\settings\\txr_list.ltx"))
ключи таблицы - твои предметы

 

  • Спасибо 1
  • Нравится 1
  • Полезно 1

Telegram-канал RayTwitty Space

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


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

@Капрал Хикс там просто выбор анимки в зависимости от условия, типа с надетым подстволом одно, у двустволки другое и т.д.

-- В той же ветке, после
elseif get_clsid(self.item) == clsid.wpn_bm16_s then
...
-- впилить
elseif self.item:is_artefact() then
...
end

Кстати, в актуальной версии скрипт посвежее :happy:

 

14 часов назад, Norman Eisenherz сказал:

Как на оригинальном движке создать циклическую проверку time_global вне загруженной игры, то есть без апдейта ГГ или другого объекта? Хочу сделать перемотку списка сейвов удерживанием клавиш.

В меню можно же подвязаться на апдейт UI-системы:

function Менюшка:Update()
	CUIScriptWnd.Update(self)
    ...
end

 

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

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
7 часов назад, Norman Eisenherz сказал:

один раз сработало, дальше молчит.

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

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
4 часа назад, Norman Eisenherz сказал:

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

Так сам апдейт работает нормально? Выясни, проблема в апдейте или в твоем коде счетчика. Потом уже дальше разбираться.

 

2 часа назад, Stalkersof сказал:

Скрипт не сработает если артефакт скинуть с пояса а не перемещать в рюкзак. Никто не знает как это отследить что арт был сброшен с пояса.

Ну так повесь вызов on_ruck на событие on_drop в том же биндере актора, будет при дропе еще уменьшаться вес. Впрочем, я не знаю зачем городить эти огороды, в ОГСР же по-любому должно в движке быть добавлено свойство арта на вес, неужели его там нет?

 

P.S.

https://github.com/OGSR/OGSR-Engine/wiki/Подробное-описание-изменений#new-properties-for-artifacts

:grin2:

 

10.12.2024 в 07:11, Stalkersof сказал:

Что это за set_int_arg0(24) и такого метода не существует obj:get_hud_shared_str()

ОГСР движок

Конечно такого метода нет, разные движки же. В SA xray-extensions. В ОГСР должны быть свои новые методы для этого всего, читай доку по движку. Имя худ секции можно просто из конфига прочитать как строковой параметр, разницы нет.

Изменено пользователем RayTwitty
  • Нравится 1

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
9 часов назад, Norman Eisenherz сказал:

Меню загрузки сейвов обновляется только один раз при создании окна.

Ну если load_dialog:Update() вызывается один раз, тогда никак:pardon:Хотя ЕМНИП в главном меню оно работало нормально, можно попробовать оттуда пробросить вызов.

 

9 часов назад, Stalkersof сказал:

Мне это надо для индикатора переносимого веса.

Это который на худе типа как в ЗП? Так для него просто нужно получить текущий вес инвентаря и сравнить с db.actor:get_actor_max_weight() или db.actor:get_actor_max_walk_weight(). Зачем второй раз считать всю эту заморочь, если движок уже посчитал?)

 

6 часов назад, Капрал Хикс сказал:

Убрали из рук - и вот здесь пытаемся играть анимку. Это как понимать?

Возможно стейты (номера) другие, скрипт работает для оружия и гранат/болта. Никогда эту фичу с артом не ковырял, может там другие стейты идут...

 

В методе is_idle_state попробуй замени if self.item:is_weapon() then на if self.item:is_weapon() or self.item:is_artefact() then. У арта айдл вроде тоже нулевой стейт.

  • Нравится 1
  • Полезно 1

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
22 часа назад, Купер сказал:

а где это определяется/каким образом посмотреть можно?

В движке, обычно где-то есть перечисление с этими стейтами. У артов оно в заголовке Artifact.h - enum EAFHudStates

 

21 час назад, Stalkersof сказал:

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

В ОГСР в lua_help есть методы доп. веса - get_additional_max_weight/get_additional_max_walk_weight, но они вызываются вроде бы только для костюма. Я посмотрел, я эти методы добавлял еще в самом первом открытом репо по сталкеру :grin2: Оттуда их видимо и перетащили. Туда конечно потом надо было дописать и обработку артов.

Короче говоря, получить доп. вес костюма в слоте можно с помощью этих методов, а по артам - итерация по поясу и сложение параметра доп. веса из конфига. В сумме получится финальный прирост по весу, который уже можно добавлять к actor_max_weight/actor_max_walk_weight и сравнивать это все с get_total_weight. Или можно сразу в ЗП сырцах посмотреть, что нужно для того индикатора веса, чтобы не гадать. Я например не помню, который параметр ему нужен - max_weight или max_walk_weight))

Скрытый текст
local add_weight = 0

db.actor:iterate_belt(
	function(dummy, obj)
		if obj:is_artefact() then
      		-- подразумевается что у всех артов есть параметр additional_inventory_weight, который в базовой секции равен нулю
      		-- иначе нужно проверять наличие параметра
			add_weight = add_weight + system_ini():r_float(obj:section(), "additional_inventory_weight")
		end   
	end
)

log1("add_weight belt = "..add_weight)

local outfit = db.actor:current_outfit()
if outfit then
	add_weight = add_weight + outfit:get_additional_max_weight()
end

log1("add_weight belt + outfit = "..add_weight)

local max_weight = db.actor:get_actor_max_weight() + add_weight
if db.actor:get_total_weight() > max_weight then
...

 

 

12 часов назад, Norman Eisenherz сказал:

Нет, все равно одно обновление. Может, дело в движковом выводе окна – в простом скриптовом окне обновление постоянное.

То есть, следующий код выведет строку в лог только один раз?

function load_dialog:Update()
	CUIScriptWnd.Update(self)

	log("load_dialog:Update") -- функция вывода может отличаться в зависимости от платформы
end

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

Изменено пользователем RayTwitty
  • Спасибо 1
  • Нравится 1
  • Полезно 2

Telegram-канал RayTwitty Space

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


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

@Norman Eisenherz у меня следующий код работает без проблем в главном меню:

function main_menu:Update()
	CUIScriptWnd.Update(self)

	log("main_menu:Update")
end

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

 

16 часов назад, Norman Eisenherz сказал:

Такой код не дает вывода в консоль, хотя в [_g.script] применяется именно log(str).

Подразумевалось, что этот баян (16 летней давности) уже известен и у тебя есть функция на замену для вывода данных (там же комментарий написан). Выводи любым способом, да хоть тем же get_console():execute("load ~~~ ВАШ ТЕКСТ"), как это делали бородатые дядьки АМК)

Изменено пользователем RayTwitty
  • Спасибо 1
  • Полезно 1

Telegram-канал RayTwitty Space

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


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

@Norman Eisenherz 3 дня выясняли что не так с апдейтом, почему он не работает, даже в игру полез проверять, как оказалось, что все работало, а дело совсем в другом :facepalm:Я же об этом еще в этом посте спрашивал...

 

Значит кури класс CRenderDevice - https://www.amk-team.ru/forum/topic/7450-spravochnik-po-funkcijam-i-klassam/?do=findComment&comment=272244

 

time_global()\device().time_global() в меню использовать смысла нет, пробуй другие счетчики, например device().frame, а дельта между кадрами device().f_time_delta (у меня тоже нулевая, но я дальше главменю не загружал).

 

Работу всего этого можно тестить с включенным vsync, залочит на 60 кадров, без него будет улетать на сотни-тысячи, разницу в показаниях видно будет сразу, "другой ПК" не нужен.

 

P.S. Вопрос риторический - зачем считать время (его мы не получим), если можно считать скорость и расстояние (скролла)? Единственное, как учесть FPS, но это см. выше.

Изменено пользователем RayTwitty
  • Спасибо 1
  • Нравится 1

Telegram-канал RayTwitty Space

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


Ссылка на сообщение
14 часов назад, Norman Eisenherz сказал:

Их можно считать на уровне скриптов? Не просто править множителями до уровня "так пойдет"?

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

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

  • Спасибо 1
  • Нравится 1

Telegram-канал RayTwitty Space

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


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

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