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

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


Svoboда

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

Неужели каждое вложение перебирать и переписывать?

Именно. С автоматической рекурсией по вложенным таблицам. :)

  • Полезно 1

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


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

FonSwong, извиняюсь, но это тихий ужас. К сожалению, пишу с телефона; если раньше никто не напишет, расширю своё сообщение завтра.

  • Согласен 3

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


Ссылка на сообщение
(изменено)

Тогда уж for i=1,#t - если, конечно, массив заполнен правильно и кол-во элементов в нём достаточно для того, чтобы заморачиваться скоростью.

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

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


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

@Nazgool, я ж не особо и спорю, и полностью согласен с тем, что все зависит от того, чем и как именно массив заполнен.

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

Всё зависит от целей и методов/качества реализации. Я тоже предпочитаю использовать ipairs, но бывают случаи, когда лучше отступить от канонов. Потому и упомянул. :)

Собственно, только автор вопроса может окончательно решить, что ему больше подходит.

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


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

@advisor890

if math.abs(distance - 10) < 0.1 then
Число справа меньше - граница более чёткая, но больше вероятности её пропустить, число больше - граница более размытая, но вероятность определения повышается.

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

  • Согласен 1

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


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

@CRAZY_STALKER666, если в my_sid хранятся story_id, тогда так (для одного НПС):

local se_obj = alife():story_object(sid)
if se_obj then
  local obj = level.object_by_id(se_obj.id)
  obj:kill(obj)
end
где sid - story_id убиваемого НПС.

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


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

Практически так и есть, но дополню.

Вызывается при любом сохранении (это ответ на выделенный жирным вопрос). Если в функциях self:save_old() и ogsm_debug.clean_pstor() содержится то, что можно предположить (OGSM для ТЧ нет под рукой), служит в качестве своеобразного контроля переполнения pstor актора во избежание появления битых сейвов. А именно: производится запись pstor (или что там делает save_old()) в чистый net-пакет, проверяется его размер, если всё в порядке, тогда pstor пишется в net-пакет сейва как есть, если же превышен допустимый для ТЧ максимум - предварительно очищается.

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

  • Спасибо 1

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


Ссылка на сообщение
(изменено)

@CRAZY_STALKER666, например se_stor от , который сохраняет данные как раз в таких объектах. Подробную информацию можно найти в постах автора модуля.

Если не ошибаюсь, @Malandrinus тоже делал подобный модуль.

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

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


Ссылка на сообщение
(изменено)

Включая и автосейв?

При любом сохранении.

 

Разумеется, хранилище может переполняться от того, что туда пишется слишком много данных. Максимальный размер net-пакета (в том числе актора) в ТЧ равен 8192 байта, в ЧН/ЗП вдвое больше. Обрати внимание на содержимое скопированной тобой функции save_old(): в net-пакет актора что-то пишут менеджеры погоды, тайников и заданий, радара и детектора. Много? Без детального изучения неизвестно. Плюс запись текущих настроек. Плюс pstor, то есть хранилище, в которое пихали данные все, кому не лень. Посмотри в твоей же clean_pstor(): из pstor вычищаются аномалии, таймеры, прочие служебные переменные - на всё это нужно место в net-пакете актора. А сколько в твоём моде других, неучтённых здесь мест использования штатных функций записи/чтения xr_logic.pstor_store() и xr_logic.pstor_retrieve()? То-то и оно. Увлёкся, записал лишнее - опаньки, вышли за 8 килобайт.

 

Потому и начали придумывать альтернативные варианты. Подробнее о разных скриптовых способах записи данных можно прочитать здесь: http://www.amk-team.ru/forum/topic/6185-skriptovanie/page-209#entry694323

Изменено пользователем Kirgudu
  • Спасибо 3

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


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

@CRAZY_STALKER666, нет там у тебя трёх «end». Есть это:

return true AND db.actor:give_info_portion("bar_bandit_death_all")
то есть на возврат идёт результат логического умножения true и результата выполнения функции. Не путай «and» и «end».

Почему синтакс-чекер ругается при замене функции? Возможно, ты просто делаешь опечатку, например, ошибочно ожидая третий «end», его и ставишь.

  • Спасибо 1

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


Ссылка на сообщение
(изменено)

@Kober(BRUC),

packet:w_bool(self.inventory)

self.inventory = reader:r_bool()
От слов write (w_) и read (r_). Непонятно, откуда ты i_bool взял, разве что опечатка.

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

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

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


Ссылка на сообщение
(изменено)

@Kober(BRUC), не уверен, что попытка записи в нетпакет значения nil, когда ожидается bool, не даст немедленную ошибку или отложенный сбой при загрузке. Пусть лучше кто-нибудь ещё уточнит, у меня нет сейчас возможности проверить.

Если ты сохранил в нетпакет 2 переменных друг за другом, то там теперь лежат оба значения. При чём тут очередь? Смысл в том, что в каком порядке ты пишешь значения в нетпакет при сохранении, точно в таком же порядке ты их должен читать при загрузке. В таком же порядке и составе, без пропусков. Грубо говоря, если ты пишешь что-нибудь типа такого (обрати внимание на разные типы и, соответственно, длину значений в байтах):

packet:w_bool(self.var1)
packet:w_stringZ(self.var2)
packet:w_float(self.var3)
а потом пытаешься читать так:

self.var1 = reader:r_bool()
self.var3 = reader:r_float()
то получишь ерунду. Изменено пользователем Kirgudu
  • Спасибо 1

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


Ссылка на сообщение
(изменено)

@Kober(BRUC), разницы может не быть, но я бы сделал так:

ini_file("gamedata\\config\\file.ltx")

ИМХО, движок просто не находит файл.

 

@Charsi, точно, я даже не обратил внимания.

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

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


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

@pc-2, ты б внимательно прочёл, что именно написано в логе вылета.

"attempt to index global 'sobj' (a nil value)" - скрипт не может получить свойство id переменной sobj, так как sobj ничего не содержит. Эта переменная просто не присвоена.

Надо делать так:

local sobj = alife():create("kurevo", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
level.client_spawn_manager():add(sobj.id, -1, function(id, obj) db.actor:eat(obj) end)
  • Согласен 1

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


Ссылка на сообщение
(изменено)

@Kober(BRUC)

В твоём варианте number_after_decimal_point(45.54050001) = 1

 

@Kondr48, примерно так:

function count_decimal_places(n)
  local r = string.match(n, "%.[0-9]*[1-9]")
  return r and r:len() - 1 or 0
end

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

Завершающие нули (если есть в строке) не учитываются.

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

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


Ссылка на сообщение
(изменено)

@Kober(BRUC), ЕМНИП, 12. Но это для аргумента-числа.

Поправка: всего 14 знаков, из которых следует вычесть число периодов (именно периодов, а не знаков, то есть единственный нуль не играет роли) до десятичной точки.
А для строки ограничения нет:

count_decimal_places("45.54050657156521651751257251721571257125721512521567215215454654654001") = 68
Изменено пользователем Kirgudu
  • Полезно 2

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


Ссылка на сообщение
(изменено)
n < 1, c = 16;

Думаю, всё-таки

n < 1, c = 14;

Что как раз соотносится с тем, что я написал выше. Остальное тоже не противоречит.

 

Интересно, что если передать напрямую слишком большое число (не важно, с десятичной частью или без), где-то в недрах обработчика от фонаря добавляется точка после первого же знака:

count_decimal_places(2421212105221221) = 13
а следует это отсюда:
string.match(2421212105221278, "%.[0-9]*[1-9]") = ".4212121052212"

Забавно.

Update.

 

А вообще, как выясняется, там не всё так просто и для моего варианта. Например:

function count_decimal_places(n)
  local r = string.match(n, "%.[0-9]*[1-9]")
  return r and r:len() - 1 or 0
end
count_decimal_places(.0000000045)

Результаты промежуточных вычислений такие.
n внутри функции: 4.5e-009
r: ".5"
На выходе: 1

То есть всё портит внутреннее представление дробных чисел.

 

Как вариант, можно самостоятельно переводить число в строку:

function count_decimal_places(n)
  local r = string.match(string.format("%.20f", n), "%.[0-9]*[1-9]")
  return r and r:len() - 1 or 0
end

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

string.format("%.15f", 11.00045) --> "11.000450000000001"

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

 

Возможно, кто-нибудь сможет предложить правильное решение.

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

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


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

@pc-2, попробуй так:

local sobj = alife():create("kurevo", vector(), 0, 0, db.actor:id())
level.client_spawn_manager():add(sobj.id, 0, function(id, obj) db.actor:eat(db.actor:object("kurevo")) end)

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

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


Ссылка на сообщение
(изменено)

@Kondr48,

function gui_mechanic_wnd:play_repair_sound()
  math.randomseed(device():time_global())
  local snd_obj = sound_object("scripts\\remkit\\ui_repairweapon_0"..math.random(1, 7))
  gz_utils.s_play_no_feedback(snd_obj)
end
Изменено пользователем Kirgudu
  • Спасибо 1

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


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

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

AMK-Team.ru

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