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

Справочник по функциям и классам


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

malandrinus, я попробовал по 10 раз по 10 через некоторый промежуток времени, привязал к таймеру, все отлично, Просто делал динам.аномалии, принцип примитивный. Скрипт ищет нужные секции, и удаляет их (перебор каждого из 65565 айди и сравнения его с секциями, которые задал) и вторая чать просто спавнит их.Когда пробовал по 100 за раз , рано или поздно, происходили вылеты(лог есть, но только стак трэк и все), а сейчас через таймер амк сделал примитивный цикл, по 10 шт, пока все отлично, уже 125 раз на данный момент переспавним, оббегал всю локацию. Норм, и во время спавна (я туда посыл новости приписал) даже не подвисает нисколько.

 

Единственно хотел спросить. Вергас как-то мне сказал, что если один скрипт (сам файл ил другое что-то) будет содержать очень много всяких функций, которые будут вызываться из разных мест, то будет переполнение стэков. Так вот у меня вопрос. Если я разделю один скрипт( 92 кб, там много чего) на несколько частей, то как это повлияет на работу скрипта\игры, будут ли тормоза? или лучше все в одном крипте хранить?

Что-то кончается, что-то начинается...

Ссылка на комментарий

Vano_Santuri,

По-моему никак это ни на что не повлияет. Дели или объединяй скрипты как тебе удобно. На мой взгляд, реально вызвать переполнение стека только если зациклить рекурсивный вызов. Типа такого:

function fun()
   fun() -- сама себя вызывает до бесконечности
end

fun() -- здесь получишь вылет с сообщением "stack overflow"

Для вылета в данном случае потребовалось 16 тыс. итераций. Я думаю, можно попытаться вызвать переполнение стека, если распаковать длинную таблицу и сунуть её как список аргументов. Но это всё нетривиальные случаи, как правило такой ситуации быть не должно.

  Полезный утиль (Показать)
Ссылка на комментарий

У меня возник такой очень интересный вопрос. Он не по функциям или классам, а скорее по структуре и архитектуре.

 

Допустим у меня есть пачка функций. Нужно написать такую функцию, что когда я её вызываю , она рандомно выбирает любую функцию из той пачки и вызывает её.

 

Можно примерчик? А то у меня фантазии не хватило, получилось сделать через

 

if math.random(0,1)>0.5 then

........

 

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

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

Что-то кончается, что-то начинается...

Ссылка на комментарий

local funcs = {
[1] = function()....end,
[2] = function()....end,
[3] = function()....end,
[4] = function()....end,
[5] = function()....end
}

function call()
funcs[math.random(#funcs)]
end

math.random(0,1) = math.random() - и вернет 0 или 1.

нету смысла писать > 0.5 - это дольше обрабатывается чем == 1

====

и все-таки вопрос-то не сюда,а в ковырялку.

====

нет,Ray, ну вот зачем ты это написал и дал человеку код,который гораздо сложнее того,что он просит,если я уже дал внятный ответ? ;)

===

Ты преподом чтоли работаешь?

Изменено пользователем Monnoroch
Ссылка на комментарий
  Monnoroch писал(а):
local funcs = {
[1] = function()....end,
...
}

В данном случае индексы указывать не надо. Автонумерация от единицы и так получится. Т.е. достаточно как-то так:

local funcs = {
fun1,
fun2,
fun3,
...
}

 

Зато конструкция вида:

local funcs = {
[<ключ1>] = function1,
[<ключ2>] = function2,
[<ключ3>] = function3,
...
}

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

 

Что касается неподходящей темы, то я с этим не согласен. Не помню, говорил или нет, но желание было замутить здесь статейку другую по "advanced Lua", где в том числе обсуждались бы и такие вопросы. Потому что смотреть на код порой просто больно. Теми же таблицами похоже что сами разработчики научились пользоваться только в ЗП =)

 

Добавлено через 13 мин.:

Раз пошла такая пьянка. Комрады, не пишите плиз соединение нескольких строк так:

res = a..b..c..d..e

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

Вместо этого используйте string.format:

res = string.format("%s%s%s%s%s",a,b,c,d,e)

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

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

 

Так можно соединять и заранее неизвестное число строк. Если надо, напишу как именно.

  • Нравится 1
  Полезный утиль (Показать)
Ссылка на комментарий

Ясно, только один момент :

 

[<ключ1>] = function1,

 

<ключ1> - что подрузумевается под этим? произвольное слово? Или что-то другое.

 

И еще вопрос, допустим идет вызов функции на какое-то условие :

 

function has_info()
if db.actor:has_info("info") then
.................
end
end

 

Вызов пошел, если поршень есть, то скрипт срабатывает, а вот если поршня еще нет, то скрипт не срабатывает? и возвращает false ? Или это ему надо еще дописать? И несет ли такая форма записи нагрузку на память?

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

Что-то кончается, что-то начинается...

Ссылка на комментарий
  Vano_Santuri писал(а):
<ключ1> - что подрузумевается под этим? произвольное слово?

Ключом может быть любая переменная, кроме значения nil: числа, строки, булевские, таблицы, функции и пользовательские объекты.

 

  Цитата
И несет ли такая форма записи нагрузку на память?
Вопрос некорректно поставлен. Какую-то нагрузку несёт любое шевеление. Другое дело, какую нагрузку несёт этот вариант по сравнению с каким-то другим. С чем ты его сравниваешь?

 

 

  Цитата
возвращает false ? Или это ему надо еще дописать?
  Ray писал(а):
пока ты не напишешь return true или return false (ну или что-то другое - все зависит от задачи) функция ничего возвращать не должна.

Если замутили таки функцию и надо вернуть true/false, то довольно часто можно обойтись без возврата false. Если ничего не возвращать, то это эквивалентно возврату nil. А nil в свою очередь в логических выражениях однозначно интерпретируется как false (согласно синтаксису языка). Впрочем, в данном случае это будет скорее трюкачеством.

  Полезный утиль (Показать)
Ссылка на комментарий

Ray,

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

if <лог. выр.> then
    return true
else
    return false
end

Посему я бы написал тот фрагмент так:

function has_info()
    local has_info = db.actor:has_info("info")
    if has_info then
      .................
    end
    return has_info
end

Что в вырожденном случае (при отсутствии действия по условию) приводит к более вразумительному коду.

  Полезный утиль (Показать)
Ссылка на комментарий

Ray,

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

 

ЗЫ: Это индикатор =) К концу недели способность рожать "длинные мнемоничные идентификаторы" сильно снижается.

 

  Полезный утиль (Показать)
Ссылка на комментарий

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

 

  Полезные функции для работы с графом игры (Показать)


Небольшое дополнение по методам:

  методы работы с файлом game.graph (Показать)

 

Изменено пользователем Kirgudu
Ссылка на комментарий

Сегодня опишу пару мелких, но полезных классов.

 

  profile_timer (Показать)

 

  client_spawn_manager (Показать)

 

Изменено пользователем Kirgudu
  Полезный утиль (Показать)
Ссылка на комментарий

Monnoroch,

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

--[[

...

]]

- это на самом деле тот-же короткий, просто два минуса комментируют "длинную строку", заключённую между [[...]]

 

В качестве открывающей и закрывающей скобок можно использовать также скобки вида [===[...]===], где количество знаков "равно" - это так называемый "уровень" строки. Нужно это с единственной целью включать в строки также и возможные последовательности ']]', ']=]' и т.д. Просто выбираете уровень, для которого закрывающая скобка уж точно в вашей строке не попадётся.

 

Добавлено:

Выше я не совсем понятно написал. Специальные символы игнорируются не в том смысле, что пропускаются, а в том смысле, что не разбивают длинную строку. Т.е. попросту попадают в строковый литерал без изменений. К примеру, здесь в приведённой строке:

[[начало строки
продолжение на новой строке
    продолжение на новой строке после символа табуляции]]

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

"начало строки\nпродолжение на новой строке\n\tпродолжение на новой строке после символа табуляции"

 

 

 

Изменено пользователем malandrinus
  Полезный утиль (Показать)
Ссылка на комментарий

Спасиюо.

Есть 2 ф-я чтения из конфига для строк:

 

function r_string_wq(string, string);--возвращает строку

function r_string(string, string);--возвращает строку

 

Видимо одна из них читает такую длинную строку?

Первая?

Ссылка на комментарий

Monnoroch,

я в своё время по использованию никакой разницы не нашёл, хотя думал, что "wq" означает что-то вроде "without quotes". Может просто терпения не хватило найти разницу. Однако обе функции совершенно точно убивают пробелы и табуляции, а в ltx файле не бывает многострочных параметров, так что прочитать с их помощью длинную строку не получится. Если нужна длинная строка надо использовать связку с xml и translate_string.

  Полезный утиль (Показать)
Ссылка на комментарий

malandrinus, Хмм,а как правильно читать actor_visual у броника,чтобы после его же записать в нетпакет НПСу?

 

local aTbl = amkII_rdpk.amkReadStalker(alife():object(oNpcId))

aTbl.sVisualName = system_ini():r_string_wq(sSect,"actor_visual")

amkII_wrpk.amkWriteStalker(aTbl, alife():object(oNpcId))

 

Вот просто чтение и сразу запись.

Я подозреваю,что надо както сконвертировать простую строку в эту.

какие вообще операции можно с ней производить?И как?

 

[[]]..[[]] - это можно?string.format() можно?

 

Вообще,что с ней можно вытворять,кроме коментирования?

Изменено пользователем Monnoroch
Ссылка на комментарий

ещё три точки может означать какой либо параметр.. Без ограничений и итп. и в виде [...] и передачи на функцию может послужить вызовом по имение данных из таблицы...

Строковые функции большой раздел.. Можно из одной строки и скобок сделать нечто невообразимое.

Формат и gsub посмотри.. по ману луа который malandrinus, давал тут, посмотри со второй по четвертую страницу ..

Ссылка на комментарий

malandrinus и всем кому интересно.

нашел на диске статью

 

Скрипты в игре «Сталкер»

Документация для гейм-дизайнеров и скриптописателей

 

В игре используется скриптовый язык Lua, поэтому необходимо воспользоваться его документацией для дальнейшего прочтения этого документа (S:\GameData\Scripts\manual.html)

Из игры в Lua вынесены следующие классы и глобальные функции:

a. Базовые функции на C++

i. log(<string_to_print>)

1. выводит в лог строку

ii. flush()

1. сохраняет лог на диск, работает очень медленно, в Release версии вообще отключена

iii. device()

1. получить экземпляр класса render_device (описание смотрите ниже)

iv. system_ini() – возвращает указатель ini_file на system.ltx

v. alife_simulator *alife() – возвращает указатель на симулятор

vi. game.time()

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

vii. level.object(<object_name>)

1. получить экземпляр класса game_object по имени объекта

viii. level.actor()

1. получить экземпляр класса game_object актёра

ix. level.get_weather()

1. возвращает строку – имя текущей погоды

x. level.set_weather(<weather_name>)

1. устанавливает погоду

xi. level.set_time_factor(<time_factor>)

1. устанавливает game time factor

xii. level.get_time_factor()

1. возвращает текущий game time factor

xiii. level.cover_in_direction(<vertex_id>,<direction>)

1. возвращает прикрытость в заданном узле в заданном направлении

xiv. level.vertex_in_direction(<vertex_id>,<direction>,<max_distance>)

1. возвращает ноду в заданном напрвалении

xv. level.rain_factor()

1. возвращает, насколько идёт дождь (0..1)

xvi. level.patrol_path_exists(<patrol_path_name>)

1. возвращает, существует ли патрульный путь.

xvii. level.vertex_position(<vertex_id>) – возвращает центр AI-ноды

b. Базовые функции на Lua

i. printf

1. форматированный вывод данных, аналог printf в C++ (с ограничениями)

ii. wait()

1. ждать до следующего обновления скрипта

iii. wait(<time_to_wait>)

1. ждать заданное в миллисекундах время до следующего обновления скрипта

iv. wait_game(<game_time_to_wait>)

1. ждать заданное в миллисекундах игровое время до следующего обновления скрипта

v. action(<object>,<action1>,…)

1. Добавить объекту object в очередь заданий новое с переданными под-action-ами (смотрите примеры)

c. Классы C++

i. vector

1. класс трёхмерный вектор, имеет следующие члены, методы:

x,y,z – компоненты вектора

set – установить значения компонент вектора по заданным значениям (три числа, вектор)

add – добавить вектор

sub – отнять вектор

mul – умножить покомпонентно на вектор

div – поделить покомпонентно на вектор

… - есть ещё штук 30 других, но вы вряд ли будете ими пользоваться........

 

Дмитрий Ясенев

12.10.2003

 

Надеюсь чем-то поможет

полная версия

http://ifolder.ru/16937470

Ссылка на комментарий

Информация для создателей скриптов

Составитель: Andrey Fidrya (Zmey), af@svitonline.com

  txt (Показать)
Изменено пользователем AKKK1
  • Нравится 1
Ссылка на комментарий

AKKK1,

всё это из билда 1935. К сожалению, бОльшая часть этой информации непосредственно не применима к последним билдам. Хотя несомненная польза есть - помогает хоть какие-то идеи получить.

  Полезный утиль (Показать)
Ссылка на комментарий

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

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

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

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