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

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


Svoboда

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

Окей, начнём с того, что сохраняешь ты в сейв переменную delay, которая ВСЕГДА равна 300 вместо своего таймера timer.

Притом там где ты её сохраняешь она скорее всего вообще не доступна и равна nil, т.к находится внутри функции my_timer()

А закончим тем что этот таймер вообще бессмысленно сохранять потому что time_global() после перезагрузки начинает отчёт с нуля. Тебе тогда вместо time_global() нужно использовать game.time(), он ведёт отсчёт от начала новой игры. С ним возможно есть косяк с переполнением но тебе пока не стоит заботится об этой проблеме. 

local time = 0
 local delay = 300
 function my_timer()
  if time == 0 then
   --\\ Первый вызов этой функции
   time = game.time()
  else
   if game.time() > time+delay*1000 then
    time = game.time()
    return true
   end
  end
 end

packet:w_u32(time)
time = reader:r_u32()
Этот таймер начнёт свой отсчёт после первого вызова.

 

Опиши лучше подробней для чего тебе нужен таймер.

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

http://www.amk-team.ru/forum/index.php?showtopic=12753

В таком случаи найди здесь "Универсальные таймеры" и лучше используй их. 

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Или я чего то не понял в работе этих функций в ЗП, или я чего то сломал, но:

применяя на сталкере best_enemy(), best_danger() и get_enemy() они практически всегда возвращают nil даже если я стою перед ним и он сажает очередь за очередью из автомата. Кто нибудь сталкивался с подобным? Есть ли универсальный и точный способ определить что сталкер сейчас находится в состоянии опасности? 

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Ты должен указать вертолёту его анимацию, параметр motion_name

По умолчанию он прописан как $editor, поэтому происходит вылет. 
Тебе нужно тут:
-- свойства cse_motion
packet
:w_stringZ(motion_name)

Указать название анимации, кажется idle чтобы просто висел.

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

@Старлей, я немного перепутал, motion_name можно вернуть как было, из за того что ты используешь какой то старый скрипт (видимо прямиком из ТЧ) и там параметр startup_animation назван как cse_alife_helicopter__unk1_sz поэтому я его и не увидел.

 

Тебе советую сделать вот что:
Попросить у Artos-а свежий скрипт для работы с нэт-пакетами (т.к его ссылка мертва): Либо взять тут прошлую версию, но я не гарантирую что там нету косяков. И спавнить вертолёт через него.

 

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

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

@Карлан, 

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

local bStarted = false
function my_update() --/ update
 if not bStarted then
  start_multi_timer(2, "my_file.my_func3", nil, true)
  bStarted = true
 end
end

И дальше таймер уже сам будет вызывать функцию my_file.my_func3 каждые 2 секунды\минуты или что там.

Это мульти-таймер. 

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

 

UPD: Поправил код.

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Толи в этой теме, то ли в "Общих вопросах по Lua" этот вопрос когда то обсуждался кажется Artos-ом, да что то поиском ничего не смог найти.

Вопрос насчёт хранения ссылок в Lua или даже в Lua-Bind-е, приведу пример из игры.

 

Допустим в игре я получил lua-биндовский объект (сталкера, оружие, да что угодно) и занёс ссылку на этот объект в таблицу.

local tbl = {}

local obj = level.object_by_id(,,,) - получили онлайновый объект

tbl.cur_obj = obj - занесли ссылку на него в таблицу

Далее в процессе игры мой объект удаляется (как серверный) или переходит в оффлайн и его клиентский объект (на который ссылается obj) где то там в движке уничтожается (?). Тогда по идее по tbl.cur_obj у меня тоже должен хранится, и обычно вроде как и будет, nil.

 

Но всегда ли это верно? Может ли быть так, что после удаления объекта где то в движке, ссылка на него всё ещё может быть активной в течении одного\двух циклов?

 

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

 

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

Да и вообще вопрос о безопасности хранения прямых ссылок на движковые объекты. 

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

@Artos, спасибо за ответ. По наводке как раз нашёл нужный пост. 

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

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

 

Вообщем если вдруг кому интересно, то конкретно в моём случае проблема была в том, что в апдейте НПС я не сделал проверку на то, что он живой\мёртвый, и поэтому когда для мёртвого НПС вызывал его движковый метод:

 

if best_enemy ~= nil then

  npc:enable_memory_object(best_enemy, false)

end

 

Биндер объекта на этом месте ломался, и следовательно при срабатывании какого нибудь колбека на этом НПС (например колбек на осмотр трупа) игра вылетала с руганью что self.object = nil.

 

Как вариант, отловить "зависшего" НПС можно тем, что у него в биндере перестаёт вызываться метод :update() соответственно если НПС долго не обновлялся, можно считать что он скорее всего завис, а это может привести как к простому сбою при обыске, так и к порче сохранений, если очень повезёт. 

  • Нравится 1
  • Не нравится 1

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

@Карлан, в функции save() получай размер всей твоей таблицы (либо table.size\table.count (забыл что именно) - это если на модулях Artos-а сидишь, либо вручную считай его через перебор всех элементов - pairs(). 

 

Сохраняй этот размер в пакет.

Дальше через тот же pairs() перебирай всю твою таблицу и сохраняй каждый из её четырёх элементов.

Примерно будет так:

local t = {
{key1=string, key2=number, key3=boolean, key4=boolean},
{key1=string, key2=number, key3=boolean, key4=boolean}
...
}
save()
local size = table.size(t) 
packet:w_u16(size)

for _,v in pairs(t) do
 packet:w_stringZ(v.key1)
 packet:w_s32(v.key2)
 packet:w_bool(v.key3)
 packet:w_bool(v.key4)
end

Соответственно в:

load()
local size = packet:r_u16() 

for i=1, size do
 local temp_tbl = {}
 temp_tbl.key1 = packet:r_stringZ()
 temp_tbl.key2 = packet:r_s32()
 temp_tbl.key3 = packet:r_bool()
 temp_tbl.key4 = packet:r_bool() 

 table.insert(t, temp_tbl)
end

Где t это твоя таблица, которую тебе нужно было сохранить.

Вариант для гурманов - запаковать всю таблицу в одну огромную строку (в тех скриптах от Artos-а кажется table.compres) и попытаться впихнуть её в stringZ, но скорее всего игра подавится при большой таблице. 

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Понаставь в свой код вывод в лог\консоль через printf (или что там у тебя выводило в лог)
И посмотри, тут два варианта как мне кажется:
1) Либо функция сохранения\записи не работает так как ты от неё ожидаешь.

2) Либо она работает, но значения потом перезаписываются в связи с неправильной работой скрипта.
Например после load() ты загрузил из сейва сохранённые значения, а потом прочёл их из конфига и перезатёр. 

 

По крайнем мере как и сохранение ключей так и сохранение строк должно работать правильно.
Поставь дополнительные printf-ы в разных местах кода и проследи в правильном ли порядке они срабатывают. 

 

Ну или на худой конец выложи текущий вариант trade_manager в личку или лучше сюда, тогда мож увидим где косяк. 

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Давно с UI не работал, но если нет нормального способа через какой нибудь статик, то например в ОГСМе это делали через ListBox, то-есть просто разбивали текст на строки и построчно добавляли их в "список". Можешь глянуть в ОГСМ ЧН энциклопедию. Тока на ЗП код нужно будет переделывать. 

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Как по мне вопрос вполне ясный. Текст со скроллером. 

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

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

 

Dennis_Chikin, ну очевидно же, что вот так:

 

 

Не, если в particle_object передать не существующий путь, то игра вылетит. 

 

Насчёт функции чтения всех параметров - она действительно удобная, но есть один недочёт - при необходимости получить всего 1 параметр из конфига ты скопом считываешь сразу 30-40, причём каждый раз. На глаз это не заметно, но с точки зрения оптимизации это ужасно.

 

Тут есть несколько вариантов:

1) Почему бы тебе просто не написать свою функцию-обёртку над system_ini()

Я например использую такую:

local cost = _u.ltx(секция, "cost", "num")

 

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

 

Пример можно глянуть здесь: http://pastebin.com/iT9ztQik

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

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Попробуй что нибудь придумать с dik_to_bind()

local bind = dik_to_bind(dik)

if bind == key_bindings.kQUIT then
    self:OnButton_close_clicked()
end

В Lua_help смотри C++ class key_bindings.

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

 

И да, в строке у loadstring скобки писать не нужно

 

 

На самом деле это "фича" Lua, любую функцию можно вызывать как со скобками так и без, правда вроде как если без скобок, то передать можно лишь один аргумент (а если без аргументов или больше чем один, то по моему вообще не вызовется). В тонкости не вдавался. Например можно abort("text"), а можно abort "text"

Если просто написать abort без скобок то ничего не будет. (точнее мы просто получим ссылку на функцию)

 

assert же просто если первым аргументом идёт false (или nil), то крэшает игру и пишет какую то фразу в лог.

Например assert(false, "yes") крэшнет игру и напишет в логе "yes", если вызывать с одним аргументом, то будет писать "assertion failed!"

Так что это не более чем узкоспециализированный аналог abort()-а в сталкере.

 

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

 

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

 

Ну а что мешает проверить. :)

Скорее всего сработает, на крайняк если юзаешь предмет скриптово, то в этот момент можешь запоминать ID использованного предмета, и в колбеке на использование проверять этот момент. 

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

@Stalkersof, попробуй вместо 0 указать 1500 или любое положительно число. (5000)

relation_registry.set_community_goodwill ("military", db.actor:id (), 1500) по идее работает прямо на Кордоне.

Скорее всего при 0 у тебя просто не изменяется никак отношение,  и нужно брать число побольше.

Если по умолчанию у тебя отношение со сталкерами -2000, то соответственно и пиши 2000, но это теория.

 

Я не помню точно что там творится с отношением группировок в ТЧ, 

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

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

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Если сам скрипт у тебя без ошибок (синтаксических) то на лицо не правильный вызов функции necrolog(victim)

Покажи кусок из xr_motivator где ты её вызываешь.

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Хм, покажи пож-ста всю эту функцию под спойлером, мож где то в ней стоит return из за чего твой код просто не вызывается. 

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

Да не, это просто подсветка синтаксиса от другого языка видимо, либо просто глючит.

Из того что могу посоветовать:

1) Все таблицы из necrolog(victim) вынеси за пределы функции (перед ней например, или в начале скрипта), т.к содержимое таблиц у тебя

определенно зарание, а так получается что при каждом вызове функции эти таблицы как бы заново создаются, что вообще плохо в плане производительности (хотя в твоём случае это совершенно не заметно) 

 

2)  

["agroprom"] = "Окрестности НИИ Агропром",
}

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

-- Некролог (На основе работы тов. Weanchester)
function necrolog(victim)
 get_console():execute("kill_msg")
 get_console():execute(victim:name())
 ...

При смерти сталкеров у тебя в консоли должна появляться строка kill_msg и имя погибшего сталкера.

Если этого не происходит, значит функция всё таки не вызывается, если функция вызывается, то аналогично через вывод в консоль проверяй доходит ли функция до отправки сообщения:

if victim and IsStalker(victim) and shans>27 then
     get_console():execute("send_msg")
     db.actor:give_game_news(necrolog_text, "ui_inGame2_Necrolog", math.random(1000,3000), 3000)
  • Нравится 1

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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


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

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