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

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


Svoboда

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

@Black_Raven_03 а если говорить непосредственно о коде, то

distance_between_safe(lobj, level.vertex_in_direction(nil,vector():set(-45,-2,-85),9)) < 900

где:

distance_between_safe вычисляет расстояние между двумя объектами,

lobj - клиентский объект аномалии,

level.vertex_in_direction(nil,vector():set(-45,-2,-85),9) возвращает номер (число, а не объект) вертекса в некоем направлении и на некоем расстоянии от номера другого вертекса, который в данном случае не передан (параметр nil).

 

В оригинале всё это в лучшем случае приведёт к значению 100000, которое точно больше 900, а значит внутрь условия ты не попадёшь.

В OGSR... не знаю, может какие-то функции и модифицированы, но всё равно код выглядит ошибочным.

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

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


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

@Black_Raven_03 и снова ты не понял, что именно я тебе пытался показать.
Посмотри на строку 5 своего кода, где длинное условие, не помещающееся на экране. Там в самом конце часть условия "and distance_between_safe(...) < 900", которое никогда не выполнится, а значит, ты не попадёшь внутрь к удалению аномалий.
Почему - расписал выше.

  • Спасибо 1

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


Ссылка на сообщение
19 часов назад, Labadal сказал:

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

Например, сняв искомый флаг в нет-пакете объекта с помощью модуля m_netpk от Артоса:

local sobj = alife():create(section, position, lvid, gvid)
if sobj then
	local pk = get_netpk(sobj)
	if pk:isOk() then
		local data = pk:get()
		data.object_flags = bit_and(data.object_flags, bit_not(object_flags.UsedAI_Locations)) -- сброс флага привязки к сетке (128)
		pk:set(data)
	end
end

 

Изменено пользователем Kirgudu
  • Полезно 3

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


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

@Norman Eisenherz я не знаток С++, но скорее всего break внутри выполняемой функции работает только в контексте этой функции, а поскольку никакого цикла в ней нет, такая команда приводит к исключению.

Более того, поскольку в нет и обработки и возвращаемого из functor значения (можно было бы вернуть true или false для остановки, как это сделано, например, в level.add_call для проверки выполнения условия), то и этот метод не пойдёт.
Отсюда ответ - никак.

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

local inv_item = nil
db.actor:inventory_for_each(function(item)
	if inv_item == nil and item:section() == section then inv_item = item end
end)
if inv_item then db.actor:transfer_item(inv_item, victim) end

 

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

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


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

@Norman Eisenherz я б сказал, что родительский объект не успевает получить информацию об этой привязке.

Сама привязка существует уже в момент спавна; достаточно после выхода нового объекта в онлайн проверить свойство parent_id (серверное) - оно будет равным id контейнера (актора). Но это единственное свойство, которое изменяется при помещении одного объекта внутрь другого.

Поскольку методы поиска дочернего объекта (:object(), :iterate_inventory() и :inventory_for_each()) работают не со всеми объектами игры - это было бы неоправданно долго, а с динамической коллекцией подчинённых объектов контейнера, требуется, чтобы эта коллекция также обновилась на клиенте. А это происходит, очевидно, на апдейте уже после выхода созданного дочернего объекта в онлайн.

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

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

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


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

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

Чтобы этого не происходило, значение переменной нужно не просто присваивать, но также сохранять в сейве (и читать оттуда при загрузке).
Примеров достаточно на любой вкус, даже в оригинале: см. xr_logic.pstor_store / xr_logic.pstor_retrieve (но это не лучший из вариантов, разве что для единичного использования).

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

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


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

@Norman Eisenherz скорее всего, дело в типе и размерности промежуточных переменных. 69 год - это (примерно) ёмкость int. Я бы предположил, что ограничение начинает работать где-то в строке "local ms = ...", поскольку diffSec сама по себе возвращает вполне вместимый float результат. Но это надо проверять.

Только зачем превращать сохраняемое значение в миллисекунды? Сохранять и восстанавливать можно непосредственно результат diffSec без промежуточных умножений и делений.

Ну а лично я сохранял бы в сейве все составляющие даты:

   local year, month, day, hour, min, sec, ms = ct:get()

и восстанавливал потом также из всех:

   local ct1 = game.CTime()
   ct1:set(year, month, day, hour, min, sec, ms)

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

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


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

@Алекс Мутный поищи Script Syntax Checker, возможно где-то рабочие ссылки остались. Или воспользуйся Lua плагином к Notepad++ от Charsi: https://disk.yandex.ru/d/UIMIb8_8vZtMD

У тебя явно ошибка синтаксиса в скрипте xr_motivator образовалась после слияния, раз он не загружается. Может скобку какую не закрыл или лишний end вставил.

Upd: нашёлся какой-то архив с чекером. https://disk.yandex.ru/d/TeUbiQ0sGjqW-w

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

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


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

@Pavel_2000 в том же скрипте, посредством которого ты отправляешь сообщение, есть функция получения идентификатора наименования предмета через его секцию: get_inv_name(section).

Пример:

local obj = db.actor:object("af_medusa")
if obj and not db.actor:has_info("medusa") then
    db.actor:give_info_portion("medusa")
    local news_text = game.translate_string("st_find_af")..": "..game.translate_string(news_manager.get_inv_name(obj:section()))
    db.actor:give_game_news(game.translate_string("st_tip"), news_text, "ui_inGame2_D_gonets_pravosudiya", 0, 3000, 0)
end

 

  • Спасибо 1

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


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

@Pavel_2000 зависит от версии игры.
В ЧН и ЗП есть вполне себе работающий итератор iterate_inventory_box, аналогичный по действию итератору iterate_inventory, но предназначенный, как можно догадаться, как раз для ящиков.
В ТЧ - см. совет выше по перебору серверных объектов.

  • Согласен 1
  • Полезно 1

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


Ссылка на сообщение
58 минут назад, Pavel_2000 сказал:

но мне бы пример живой увидеть хотя бы

Живой пример использования в ЗП (оригинал) можно увидеть здесь:
xr_effects.jup_b202_inventory_box_relocate(actor, npc)

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


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

как можно сделать задержку телепортации на две секунды?

function gaus_laz_v_gaus()
  if xr_conditions.actor_in_zone(actor, npc, {"gaus_laz_v_gaus_sr"}) then
    db.actor:give_info_portion("af_run_tutor")
    local timer = time_global() + 2000 -- установка маркера времени на 2 секунды вперёд
    level.add_call(
      function() return timer < time_global() end, -- проверка, что текущее время стало больше, чем установленный маркер
      function() teleport_actor(nil, nil, {"gaus_prolez_v_gaus_way","gaus_prolez_v_gaus_look"}) end -- действие, как только проверка вернула true
    )
  end
end

 

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

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


Ссылка на сообщение
36 минут назад, Balavnik сказал:

можно ли из функции менять глобальную переменную

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

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

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


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

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

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


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

@Balavnik, ничего не понял.

Если первая часть вопроса относится к моему ответу в "ковырялке", то переменная в примере была объявлена как локальная: local item_counts = enumerate_items(). Да, там, где выполняется эта строка, содержимое массива, конечно, изменится. Но при этом, поскольку переменная локальная, из других скриптовых модулей она будет недоступна.

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

Что же касается второй части, то - опять же, за отсутствием телепатов предположительно, - нужна некая система сохранения переменной в сейве, чтобы её значение можно было использовать в ранее запомненном виде хоть после перехода на другую локацию, хоть после сохранения-загрузки и вообще в любое время. Так? Современные версии движка, такие как OGSR, обладают подобными возможностями, вот буквально недавно на глаза попадался похожий вопрос и ответ на него. Если же модифицированные движки по тем или иным причинам не рассматриваются, рекомендую обратить своё внимание на модуль se_stor от Artos-а, который можно взять, например, здесь: 

 

  • Полезно 1

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


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

@Biblia В скриптовом плане ошибки нет (переменная только лишняя, вполне можно писать сразу db.actor.health =  0.5 - db.actor.health).

Выведи содержимое db.actor.satiety в лог и посмотри, чему оно равно и меняется ли вообще.

  • Нравится 1

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


Ссылка на сообщение
8 часов назад, WinCap сказал:

в заранее подготовленный ящик и обратно

Поддерживаю, незачем ради этого заморачиваться записью в сейв. В ЧН, например, именно так всё и происходит при ограблении в подвале Барахолки, можно посмотреть реализацию там - скриптовая база практически идентична.

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


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

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