Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Скрипты
GAMEINATOR forums > S.T.A.L.K.E.R. > Мастерская: создание модов для S.T.A.L.K.E.R.
Страницы: 1, 2, 3, 4, 5, 6
RayTwitty
Цитата(Pavel_Blend @ 07.09.2020, 16:02) *
При изучении нужно знать две вещи: сам луа и собственно функции движка (в блендере это называется API, наверное в X-Ray это тоже API в виде lua функций).

Луа в сталкере это по сути интерфейс, осуществляющий доступ к внутридвижковым объектам. Этакая надстройка на логикой внутри движка.

Цитата(Pavel_Blend @ 07.09.2020, 16:02) *
как вообще можно встроить свои собственные скрипты в сталкер? Я пока знаю, что можно в диалогах прописать вызов скрипта и функции. А какие ещё способы есть?

Можно просто вызвать любую функцию в скрипте, тогда он инициализируется. Поскольку, почти все начинают работать с конкретными объектами и чаще всего с актором, свои скрипты инициализируют из bind_stalker.script.

Цитата(Pavel_Blend @ 07.09.2020, 16:02) *
И как сделать редактор погоды в игре?

В ТЧ без правок движка никак. Исходя из первой моей цитаты, тебе потребуется написать экспорт движковых функций в Lua, после чего написать на основе оконной системы сталкера весь интерфейс. Задача весьма нетривиальная и не на пару часов.
Pavel_Blend
Цитата(RayTwitty @ 07.09.2020, 21:20) *
Можно просто вызвать любую функцию в скрипте, тогда он инициализируется. Поскольку, почти все начинают работать с конкретными объектами и чаще всего с актором, свои скрипты инициализируют из bind_stalker.script.

а вообще, какой принцип работы скриптов в сталкере? Вот в blender game engine есть такое понятие, как такт, который длится 1/60 секунд. Во время этого такта выполняются действия. А в сталкере как всё работает? Например, как работает bind_stalker? В этом скрипте каждый кадр выполняется определённая функция? Или данный скрипт выполняется один раз за весь сеанс игры? И вообще где выполняется основная работа скриптовой системы? Вот к примеру скрипт из диалога выполнится только один раз. А какие скрипты непрерывно работают в игре и обрабатывают события?
Diesel
Pavel_Blend, движок заранее заготовленные внедряет свои щупальца в скрипты. И ждёт их изменений, согласно обновлений в движке.
В движке создаются скрипты, как основа, для луа. Каждая функция луа, заранее прописана в движок. Если и не прописана, то предок этой функции всё равно в движке есть.

В поиск визуалки забей .def и увидишь сколько их там.
RayTwitty
Цитата(Pavel_Blend @ 08.09.2020, 17:44) *
В этом скрипте каждый кадр выполняется определённая функция?

Нет, в движке есть глобальный шедулер (апдейтер), из которого уже апдейтятся все онлайновые объекты (он в свою очередь вроде бы как раз из рендера должен вызываться, но я уже не помню). Покадрового апдейта в скриптах нет, у актора вроде бы интервал каждые 20-40 мс, он динамичен, для этого есть переменная delta в аргументе. У других объектов интервал в целях оптимизации может быть больше.

Цитата(Pavel_Blend @ 08.09.2020, 17:44) *
Или данный скрипт выполняется один раз за весь сеанс игры?

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

Плюс те же функции в биндерах, вызываются при определенных события. Например net_spawn при появлении актора на уровне, update - периодический апдейт (см. выше) и т.д.

Цитата(Pavel_Blend @ 08.09.2020, 17:44) *
А какие скрипты непрерывно работают в игре и обрабатывают события?

Ну кроме апдейта объектов и некоторых апдейтов в UI-интерфейсах таких нет.
Pavel_Blend
А с помощью скриптов возможно сделать такую вещь:

добавить отметки в пда на все динамические объекты. На сталкеров, на мутантов, тайники, физические объекты, лампочки, бочки, аномалии, еду, патроны, оружие. В общем на всё. И сделать так, чтобы при убийстве сталкера, в пда была метка его трупа. Только метка меняла цвет на серый. Была метка бандита, к примеру, красной, а при убийстве стала серой. И чтобы можно было скрывать метки по типу: аномалии, тайники, трупы, физ. объекты и т. д.

И как можно полностью отключить респавн? Чтобы новые мутанты и сталкеры не появлялись?
Yara
Цитата(Pavel_Blend @ 10.09.2020, 15:23) *
И как можно полностью отключить респавн? Чтобы новые мутанты и сталкеры не появлялись?

Попробуй в se_respawn.script заремить строку self:spawn(), а для отметок всего использую такое:
...

CODE

По клавише в главном меню: ui_main_menu.script,
-----------------------------
function main_menu:OnKeyboard(dik, keyboard_action) --virtual function
...
if keyboard_action == ui_events.WINDOW_KEY_PRESSED then
...
if dik == DIK_keys.DIK_NUMPAD0 then
if (level.present() and db.actor ~= nil and db.actor:alive()) then
this.mark_all_objects()
end
end



В самый конец файла добавить:

function mark_all_objects()
for i=1,65535,1 do
local obj = alife():object(i)
if (obj and obj.parent_id and obj.parent_id == 65535) then
local obj_name = obj:name()

-- from _g.script

if (IsStalker(obj)) then
level.map_add_object_spot(obj.id, "obj_location", tostring(obj_name))
end
if (IsMonster(obj)) then
--if (IsMonster(obj) and obj:alive()) then -- только живых
level.map_add_object_spot(obj.id, "obj_location", tostring(obj_name))
end

if (
isWeapon(obj) or -- оружие

-- from lua_help.script

get_clsid(obj)==clsid.wpn_ammo or -- патроны
get_clsid(obj)==clsid.wpn_ammo_og7b or -- выстрелы рг/пг
get_clsid(obj)==clsid.wpn_ammo_vog25 or
get_clsid(obj)==clsid.wpn_ammo_m209 or

get_clsid(obj)==clsid.obj_explosive or -- взрывные бочки и прочее

get_clsid(obj)==clsid.obj_food or -- еда и медицина
get_clsid(obj)==clsid.obj_antirad or
get_clsid(obj)==clsid.obj_bandage or
get_clsid(obj)==clsid.obj_bottle or
get_clsid(obj)==clsid.obj_medkit or

get_clsid(obj)==clsid.equ_stalker_s or -- костюмы

get_clsid(obj)==clsid.artefact_s or -- арты
get_clsid(obj)==clsid.artefact or

get_clsid(obj)==clsid.inventory_box or -- тайники
get_clsid(obj)==clsid.obj_phskeleton or -- физ.объекты
get_clsid(obj)==clsid.obj_phys_destroyable or
get_clsid(obj)==clsid.obj_physic or
get_clsid(obj)==clsid.obj_breakable or
get_clsid(obj)==clsid.script_phys or
get_clsid(obj)==clsid.obj_climable or -- лестницы
get_clsid(obj)==clsid.projector or -- прожектор
get_clsid(obj)==clsid.hanging_lamp or -- лампочки

get_clsid(obj)==clsid.ameba_zone or -- аномалии
get_clsid(obj)==clsid.torrid_zone or
get_clsid(obj)==clsid.zone or
get_clsid(obj)==clsid.zone_acid_fog or
get_clsid(obj)==clsid.zone_bfuzz_s or
get_clsid(obj)==clsid.zone_dead or
get_clsid(obj)==clsid.zone_galant_s or
get_clsid(obj)==clsid.zone_galantine or
get_clsid(obj)==clsid.zone_mbald_s or
get_clsid(obj)==clsid.zone_mincer_s or
get_clsid(obj)==clsid.zone_mosquito_bald or
get_clsid(obj)==clsid.zone_radioactive or
get_clsid(obj)==clsid.zone_rusty_hair or
get_clsid(obj)==clsid.nogravity_zone or

get_clsid(obj)==clsid.level_changer or -- переходы
get_clsid(obj)==clsid.respawn or -- респавнеры
get_clsid(obj)==clsid.smart_terrain or -- смарты
get_clsid(obj)==clsid.script_restr or -- рестрикторы
get_clsid(obj)==clsid.script_zone or
get_clsid(obj)==clsid.car_s or -- машины
get_clsid(obj)==clsid.script_heli or -- вертолёты
get_clsid(obj)==clsid.helicopter
)
then
level.map_add_object_spot(obj.id, "obj_location", tostring(obj_name))
end

end
end
end



Добавить в map_spots.xml,
-----------------------------
<!-- debug icon -->
<obj_location>
<level_map spot="obj_location_spot"/>
<mini_map spot="obj_location_spot"/>
</obj_location>
<obj_location_spot x="0" y="0" width="4" height="4" alignment="c" stretch="1">
<texture r="0" g="255" b="255">ui_minimap_point</texture>
</obj_location_spot>

RayTwitty
Цитата(Pavel_Blend @ 10.09.2020, 12:23) *
А с помощью скриптов возможно сделать такую вещь:

добавить отметки в пда на все динамические объекты. На сталкеров, на мутантов, тайники, физические объекты, лампочки, бочки, аномалии, еду, патроны, оружие. В общем на всё.

Можно. Перебираешь все айдишники (1..65536, 0 - актор, его пропускаем) объектов в игре через alife():object(id), или если нужно только онлайновых то level.object_by_id(id). Добавляем метку через level.map_add_object_spot.

Цитата(Pavel_Blend @ 10.09.2020, 12:23) *
И сделать так, чтобы при убийстве сталкера, в пда была метка его трупа. Только метка меняла цвет на серый. Была метка бандита, к примеру, красной, а при убийстве стала серой.

Так это штатный механизм ПДА. Надо только тег level_spot/mini_spot в xml конфиге проверить/сделать.

Цитата(Pavel_Blend @ 10.09.2020, 12:23) *
И чтобы можно было скрывать метки по типу: аномалии, тайники, трупы, физ. объекты и т. д.

Для этого нужно написать UI, в котором добавлять/удалять метки по типу объекта. Скрывать нельзя, только если экспортировать из движка получение CUIStatic метки.

Цитата(RayTwitty @ 07.09.2020, 21:20) *
В ТЧ без правок движка никак. Исходя из первой моей цитаты, тебе потребуется написать экспорт движковых функций в Lua, после чего написать на основе оконной системы сталкера весь интерфейс. Задача весьма нетривиальная и не на пару часов.

Вот кстати чувак сделал консольные команды, к которым можно привязаться в интерфейсе biggrin.gif
https://www.gameru.net/forum/index.php?s=&a...t&p=1680713
Правда команд мало, и вообще это нужно было бы сделать через экспорт методов, но уж как есть.
Pavel_Blend
RayTwitty, попробовал редактор погоды. Трудновато редактировать. Хотелось бы иметь ползунки, чтобы плавно менять цвета. Ну или чтобы были горячие клавиши. Например, стрелки (вниз-вверх - листать параметры, влево-вправо - менять значения параметров). И ещё трудно угадать цвет солнца. Всё таки без игрового редактора удобнее тем, что можно загрузить в фотошоп текстуру неба и пипеткой скопировать цвет солнца. А потом пропорционально его увеличить или уменьшить.

А что ещё интересного можно сделать с помощью скриптов, кроме проставления меток?

И вопрос: я проставил метки на всех сталкеров и удалил респавн. Зачистил локации от врагов, но не от всех. Остались монолитовцы, к примеру. Они видны на карте, но их там нет. И монстры. Монолитовцы в припяти возле гаражей у костра. Они не спавнятся. Не выполнено определённое условие для их спавна. В userdata у них прописано это:

CODE
[smart_terrains]
none = true

[logic]
active = kamp1
combat_ignore = combat_ignore

;on_signal = arrived | camper2 %+pri_wave1_side_start%

[kamp1]
center_point = pri_sideway_left_kamp

[combat_ignore]


Как заспавнить с помощью скриптов объекты, которые уже есть, но не заспавнены (как монолитовцы).

AndreySol
Цитата
А что ещё интересного можно сделать с помощью скриптов, кроме проставления меток?

Ну так весь сюжет в общем-то скриптами строится. Вся логика объектов в конечном счете разворачивается в скрипты(xr_logic.script и все схемы поведения), все гулаги и их работы(xr_gulag.script). Спавн объектов, всякие UI-окна с различным функционалом.
RayTwitty
Наткнулся на интересный прикол с вещественным типом в Lua. Есть два листинга:

1) Здесь к одному числу прибавляется другое и в результате получается 0.75. После чего я выполняю сравнение с константой 0.75, которое разумеется проходит (YES).
Код
local value = 0.25

value = value + 0.5

print(value) --> 0.75

if value <= 0.75 then
    print("YES")
else
    print("NO")
end

2) По сути тоже самое, только довожу число до 0.75 за несколько шагов. Весь цимес заключается в том, что сравнение с константой 0.75 не проходит (NO)!
Код
local value = 0.25

for i = 1, 10 do
    value = value + 0.05
end

print(value) --> 0.75

if value <= 0.75 then
    print("YES")
else
    print("NO")
end

Если в Си у меня бы вопросов не возникло, то тут получается довольно неожиданно (всегда думал, что Lua пытается автоматом привести точность, что видно в первом листинге). В игре из-за этого не проходит сравнение по достижению числа верхней границы (меняю прозрачность и она не может дойти до 100%). Я так понимаю, это особенности внутренних расчетов Lua и на каком-то этапе там все-таки записывается в конец числа некий мусор? Получается, сравнивать надо с эпсилоном (+0.001 например) или вручную обрезать число до сотых?

P.S. опытным путем выяснил, что сравнение перестает работать уже на втором шаге:

Код
local value = 0.7
value = value + 0.05
print(value) --> 0.75
if value <= 0.75 then print("YES") else print("NO") end --> YES


Код
local value = 0.65
value = value + 0.05
value = value + 0.05
print(value) --> 0.75
if value <= 0.75 then print("YES") else print("NO") end --> NO


P.S2. соорудил такую дичь z_lol1.gif
Код
tonumber(tostring(value)) <= 0.75

работает отлично в обоих случаях.

P.S3. оказывается в Питоне есть целый класс для таких нужд:
https://www.bestprog.net/ru/2019/10/18/pyth...decimal-ru/#q03
поэтому функция
Код
function normalize_decimal(n)
    return tonumber(tostring(n))
end

уже не так сильно похожа на дичь... Возможно в питонском классе внутри происходит тоже самое.
1001v
RayTwitty, https://0.30000000000000004.com/
RayTwitty
Цитата(RayTwitty @ 11.12.2020, 02:18) *
работает отлично в обоих случаях.

А вот в стулкере в отличии от консольной Луа почему-то не сработало.

Поэтому пришлось расчехлить функцию округления с заданной точностью и вручную указывать количество знаков:
Код
function math.round(n, exactness)
    return tonumber(string.format("%."..(exactness or 0).."f", n))
end

local value = 0.65
value = value + 0.05
value = value + 0.05
print(value) --> 0.75
if math.round(value, 2) <= 0.75 then print("YES") else print("NO") end --> YES

pardon.gif
abramcumner
Цитата(RayTwitty @ 11.12.2020, 05:33) *
А вот в стулкере в отличии от консольной Луа почему-то не сработало.

Потому что это дичь и не должно работать. Попробуй свою функцию не на 0.75, а 0.8, например.
Почитай ссылку, которую дали.

Цитата
math.round(value, 2) <= 0.75

Можно нормально же записать в виде value < 0.75 + eps, где eps ты выбрал 0.01.

Зачем тебе вообще проверять на равенство?

Цитата
Возможно в питонском классе внутри происходит тоже самое.

Питоновский класс реализует арифметику на числах с фиксированной точкой. Основан на сишной библиотеке. Можно затащить в луа и будет, как в питоне smile.gif
RayTwitty
Цитата(abramcumner @ 11.12.2020, 13:14) *
Можно нормально же записать в виде value < 0.75 + eps, где eps ты выбрал 0.01.

В реальном коде условие сложнее, есть еще нижняя граница, где нужно уже отнимать eps. В целом, fsimilar из движка ровно это и делает, только нужно изменить функцию на предмет сравнения <= или >=.

Цитата
value < 0.75

У меня шаг 0.05, с таким условием застопорится на 0.7. Можно в константе указать заранее больше, но эта константа может меняться в дальнейшем и не хотелось бы подразумевать в ней некоторые условия и подводные камни.

Цитата(abramcumner @ 11.12.2020, 13:14) *
Потому что это дичь и не должно работать.

Да, я об этом сразу и написал) Просто меня навело на мысль, что стандартный print выводит число с правильной точностью и возможно дело в банальном переводе в строку. Исходники не смотрел, быстрее было в консоли проверить на практике. Выходит, что нет и там скорее всего какой-нибудь format как у меня в round-функции.

Цитата(abramcumner @ 11.12.2020, 13:14) *
Почитай ссылку, которую дали.

Я на основе этой ссылки и других, которые сам нашел, последний пост и написал. Ранее я уже писал про eps, это первое что я и сделал - прибавил и отнял 0.00001.
Вопрос был даже не в этом скорее, а почему в Луа только со второй операции начинает портиться точность.
abramcumner
Цитата(RayTwitty @ 11.12.2020, 23:18) *
Ранее я уже писал про eps, это первое что я и сделал - прибавил и отнял 0.00001.
Вопрос был даже не в этом скорее, а почему в Луа только со второй операции начинает портиться точность.

Ни число 0.7, ни число 0.05 не могут быть представлены в формате ieee754. Вместо них берутся ближайшие значения. Условно 0.70000000001 и 0.04999999999. Так получается, что в сумме они дают 0.75. А если к 0.650000000001 прибавить два раза по 0.04999999999, то 0.75 не получится.
Точность вычислений никуда не девается, она ровно такая же точная

Цитата
У меня шаг 0.05, с таким условием застопорится на 0.7.

Если работает через преобразование в строку, то и с эпсилоном в условиях должен работать.
RayTwitty
Цитата(abramcumner @ 12.12.2020, 02:12) *
Если работает через преобразование в строку, то и с эпсилоном в условиях должен работать.

А не прокатит с эпсилоном в моем случае. Но по другой причине: при изменении прозрачности, у меня вот эта погрешность с каждым шагом увеличивается и если погонять туда-сюда получается лютое смещение - не тысячные, а уже десятые. Я правда не совсем уверен, что это вина чисто Луа, возможно арифметика в сталкерском методе. У меня новый метод для оконных классов, который меняет прозрачность - по сути тот же стандартный SetColor, только устанавливает альфу 0..1 (умножается на 255). При получении соответственно делится. Сама прозрачность устанавливается v:SetOpacity(v:GetOpacity() + step), видимо здесь накапливается погрешность.
Всё это удалось решить с помощью math.round на каждом шаге (заодно, оно же решило вопрос при сравнении с границами).

Если делать совсем по красоте, то надо тащить питоновский класс))
abramcumner
Цитата(RayTwitty @ 12.12.2020, 03:42) *
Сама прозрачность устанавливается v:SetOpacity(v:GetOpacity() + step), видимо здесь накапливается погрешность.

Ну пусть здесь "копится погрешность", но по-прежнему непонятно в чем проблема. Похоже ты делаешь какое-то анимирование(типа проявляешь окно). Пусть у тебя на каком-то шаге(хотя по расчетам должно было сработать) не сработало условие value >= 0.75, потому что value = 0.7499999, ну так сработает на следующем. Будет 0.799999999. Это так принципиально?

Или можно делать по шагам. Посчитал, что прозрачность нужно изменить за 5 итераций, ну и сделал 5 итераций. В конце можно установить прозрачность на то значение, которое требуется.
RayTwitty
Цитата(abramcumner @ 12.12.2020, 15:27) *
Ну пусть здесь "копится погрешность", но по-прежнему непонятно в чем проблема.

Было две разных проблемы:
1) Сравнение с пределом (константой 0.75). Лечится эпсилоном к константе или math.round к value.
2) Проблема с прозрачностью, выше пост. Скорее всего внутридвижковая проблема сталкера, лечится math.round на каждом шаге.

Цитата(abramcumner @ 12.12.2020, 15:27) *
Или можно делать по шагам.

По шагам, по сути, я тоже делал но там именно накапливается погрешность. К примеру первые 10 раз получается от 0.25 до 0.74, потом вернулись на 10 назад, получили не 0.25, а уже 0.24 и т.д. Так нижний предел я легко сместил до 0.1 вообще biggrin.gif Видимо где-то, что-то округляется, в Луа или в движке при делении/умножении хз. math.round корректировка на каждом шаге помогла.

А могут быть потери при переводе float -> u32? У меня прозрачность float от 0 до 1, а альфа текстуры задается целым числом от 0 до 255:
alpha = u32(opacity*255.f)
соответственно геттер обратно преобразует u32 -> float.
opacity = float(alpha)/255.f
abramcumner
Цитата(RayTwitty @ 12.12.2020, 16:41) *
А могут быть потери при переводе float -> u32? У меня прозрачность float от 0 до 1, а альфа текстуры задается целым числом от 0 до 255:
alpha = u32(opacity*255.f)
соответственно геттер обратно преобразует u32 -> float.
opacity = float(alpha)/255.f

Да, конечно. К тому же здесь ты переводишь не в u32, а в u8 по сути.
RayTwitty
abramcumner, исправить никак нельзя? Или только переписывать весь код цвета на один формат?
abramcumner
Вот так в цикле не писать "v:SetOpacity(v:GetOpacity() + step)" и все. В начале сделать
local opacity = v:GetOpacity()
и работать уже с переменной opacity.
RayTwitty
abramcumner, идею понял, только в моем случае все несколько сложнее - окон (статиков) куда больше чем один, у базового окна куча дочерних, для которых я пропорционально тоже меняю прозрачность. В этом случае, придется в таблице хранить текущую прозрачность для каждого из них. В целом, пока выглядит более хлопотнее чем:
Код
local normalize_opacity = function(opacity)
    return math.round(opacity, 2)
end

for k, v in pairs(windows_collection) do
    v:SetOpacity(normalize_opacity(v:GetOpacity() + step))
end

Но если с типами в движке ничего замутить нельзя (и без переписывания целиком управления цветом), тогда ладно.
abramcumner
Цитата(RayTwitty @ 14.12.2020, 23:55) *
Но если с типами в движке ничего замутить нельзя (и без переписывания целиком управления цветом), тогда ладно.

Можно перевести SetOpacity/GetOpacity на работу с диапазоном 0-255, а не 0..1. Тогда вообще все должно круто работать.
RayTwitty
Есть функция clamp, которая держит число в рамках диапазона. Стандартная функция и много где используется, в движке сталкера, в вебе (особенно в css) и т.д.
Код
function clamp(n, min, max)
    return n < min and min or n > max and max or n
end


Есть еще такая функция - по сути тоже самое, что и предыдущее, только если n больше максимального, то возвращается минимальное и наоборот. Для простоты обозвал ее iclamp (inverted clamp). У меня часто используется в разных списках, прокрутках значений, переключении полей TABом и т.д.
Код
function iclamp(n, min, max)
    return min + (n - min) % (max - min + 1)
end

Вопрос - может быть у последней функции есть какое-то общепринятое название? Не сильно важно конечно, но мб кто-то в курсе. Пока оставлю как есть.
abramcumner
Modulo with ofset biggrin.gif

Цитата
The modulo with offset a modd n is implemented in Mathematica as[16] Mod[a, n, d].

Думаю и для луа сойдет math.fmod с тремя аргументами.
RayTwitty
abramcumner, а там разве не со смещением? Например, когда то, насколько превысили max, прибавляется к min? В моем случае, при превышении max всегда будет на выходе min, то есть по смыслу (применения) функция как раз ближе к clamp-у.

Вот кстати wrap, переписанный с википедии под луа, с включением мин/макса:
Код
function wrap(x, min, max)
    x = x - math.floor((x - min) / (max - min + 1)) * (max - min + 1)
    --[[if x < 0 then
        x = x + max - min
    end]]
    return x
end

PS условие с проверкой на ноль можно выпилить по идее.
abramcumner
RayTwitty, со смещением. В твоем iclamp по идее тоже превышение прибавляется к min.
На мой взгляд все три функции делают одно и то же. Название wrap лучше и привычнее.
RayTwitty
Цитата(abramcumner @ 11.01.2021, 02:14) *
В твоем iclamp по идее тоже превышение прибавляется к min.

Нет, при превышении max результат будет равен min, при принижении(? biggrin.gif ) min результат будет равен max. wrap тоже самое, только учитывает смещение.

В общем я понял, что в принципе, можно называть как угодно biggrin.gif Видимо мой случай часто делают просто условиями по месту и не парятся с отдельными функциями.
RayTwitty
Следующий код проигрывает звук в голове актора:
Код
sound_object("zvuk"):play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(0,0,0), 1.0)

меня глючит или если указать вектор vector():set(0,0,1)
Код
sound_object("zvuk"):play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(0,0,1), 1.0)

то звук будет играть как бы чуть на расстоянии?
Может у кого есть хорошие наушники чтобы проверить? Я на колонках разницы вообще не слышу.

На всякий случай: https://xray-engine.org/index.php?title=Класс_sound_object
abramcumner
Цитата(RayTwitty @ 12.01.2021, 22:54) *
Код
sound_object("zvuk"):play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(0,0,1), 1.0)

то звук будет играть как бы чуть на расстоянии?

sound_object.s2d должен игнорировать настройки расстояния и просто играть, как будто ты звук в медиаплеере слушаешь.
RayTwitty
Что-то я не выкупаю. Есть строка
Код
"hud_fov 0.55"

Нужно из нее вытащить символы до пробела, то есть в данном случае hud_fov.
Пишу:
Код
print ( string.match("hud_fov 0.55", "^([A-Za-z0-9_]+)%s") )

всё работает. Пишу:
Код
print ( string.match("hud_fov 0.55", "^(%w+)%s") )

не работает. Опытным путем выяснил, что дело в символе нижнего подчеркивания.

Но ведь %w как раз должен соответствовать классу [A-Za-z0-9_] ?

https://duckduckgo.com/?q=regexp+cheat+shee...p;ia=cheatsheet
atanda
Ну, на сколько я знаю луа использует не регекспы, а паттерны, которые выглядят похожими, но соответствуют различным входным данным. http://lua-users.org/wiki/PatternsTutorial

Цитата(RayTwitty @ 14.01.2021, 00:54) *
Но ведь %w как раз должен соответствовать классу [A-Za-z0-9_] ?

нет. https://www.lua.org/manual/5.3/manual.html#6.4.1

Твой код следует написать так
Код
string.match("hud_fov 0.55", "^([%w_]+)")


Может быть можно сделать проще - не знаю, я не силён в паттернах, да и на луа давно не кодил.
RayTwitty
Цитата(atanda @ 14.01.2021, 10:45) *
Ну, на сколько я знаю луа использует не регекспы, а паттерны, которые выглядят похожими, но соответствуют различным входным данным

Да, в луа %w не содержит нижнее подчеркивание.
Цитата
For example, [%w_] (or [_%w]) represents all alphanumeric characters plus the underscore.

Подразумевается, мы сами как бы группу(класс) расширяем. По работе в основном сталкиваюсь с js и питоном, там по стандарту андескор в \w есть. Спасибо за наводку.
Пчел 3д
Добрый день, подскажите пожалуйста, как прописать скрипт на дверь в сталкер зов припяти, чтоб дверь открывалась нажатием клавиши "F" (использовать). Скрипт двери я прописал, но дверь открывается только в одну сторону и только тогда, когда актер в нее упирается. А хотелось бы как в игре, чтоб выскочило сообщение (открыть дверь - нажмите F)
Билдомассон
Цитата(Пчел 3д @ 24.01.2021, 14:01) *
Добрый день, подскажите пожалуйста, как прописать скрипт на дверь в сталкер зов припяти, чтоб дверь открывалась нажатием клавиши "F" (использовать). Скрипт двери я прописал, но дверь открывается только в одну сторону и только тогда, когда актер в нее упирается. А хотелось бы как в игре, чтоб выскочило сообщение (открыть дверь - нажмите F)

скопируй логику какой-нибудь из labx8.level, он по-моему идет вместе с сдк 0.7.
ну или вот взял логику от рандомной двери:
CODE
[collide]
ignore_static

[logic]
active = ph_door@close

[ph_door@close]
locked = false
closed = true
snd_open_start = trader_door_open_start
snd_close_start = trader_door_close_start
snd_close_stop = trader_door_close_stop
on_use = ph_door@open

[ph_door@open]
locked = false
closed = false
snd_open_start = trader_door_open_start
snd_close_start = trader_door_close_start
snd_close_stop = trader_door_close_stop
on_use = ph_door@close
Пчел 3д
Цитата(Билдомассон @ 24.01.2021, 15:29) *
Цитата(Пчел 3д @ 24.01.2021, 14:01) *
Добрый день, подскажите пожалуйста, как прописать скрипт на дверь в сталкер зов припяти, чтоб дверь открывалась нажатием клавиши "F" (использовать). Скрипт двери я прописал, но дверь открывается только в одну сторону и только тогда, когда актер в нее упирается. А хотелось бы как в игре, чтоб выскочило сообщение (открыть дверь - нажмите F)

скопируй логику какой-нибудь из labx8.level, он по-моему идет вместе с сдк 0.7.
ну или вот взял логику от рандомной двери:
CODE
[collide]
ignore_static

[logic]
active = ph_door@close

[ph_door@close]
locked = false
closed = true
snd_open_start = trader_door_open_start
snd_close_start = trader_door_close_start
snd_close_stop = trader_door_close_stop
on_use = ph_door@open

[ph_door@open]
locked = false
closed = false
snd_open_start = trader_door_open_start
snd_close_start = trader_door_close_start
snd_close_stop = trader_door_close_stop
on_use = ph_door@close



Спасибо, все получилось.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.