Dennis_Chikin 3663 Опубликовано 22 Июля 2014 Да. Единственно, следует учитывать, что некоторые предметы торговцы резервируют "под себя", так что в предложении может быть на 1 предмет меньше, чем задано. То есть, поставлено количество 1, вероятность 1 - в торговле предмета не будет. Поставлено 2, 1 - в торговле будет 1. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 22 Июля 2014 На сколько помню, это флагами задается, или что-то типа того. Но точно не скажу - надо искать по разделу. Еще вроде резервируют аптечки. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 28 Июля 2014 (изменено) Проверяет условия для выдачи и завершения квестов. task_manager на самом деле управляет скорее диалогами, а этот оперирует собственно поршнями. Изменено 28 Июля 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 28 Июля 2014 bind_stalker же. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 2 Августа 2014 (изменено) К вопросу об апдейте из bind_stalkker: привычное всем if time_global() < next_update_time then простыня из вызовов 100500 функций в 100500 скриптах - это, конечно, ужасно. Особенно, если вызываемое должно срабатывать 1 раз за всю игру. Но плодить 100500 рестрикторов - тоже не вариант (на самом деле даже и 65000 не получится по понятной причине). Что делать ? А подключать динамически. Точно по тому же принципу, что и известные всем "таймеры" из amk-мода и различные их вариации. Примерно вот так: local tasks_list = {} -- имя, группа( 50, 200, 1000, 5000 ), функция -- local t50, t200, t1000, t5000 = {}, {}, {}, {} -- группы { строка для wathdog, функция } local t50n, t200n, t1000n, t5000n = 0, 0, 0, 0 -- функций в группе local t50i, t200i, t1000i, t5000i = 1, 1, 1, 1 -- текущая функция в группе local t50t, t200t, t1000t, t5000t = 0, 0, 0, 0 -- время следующего обновления local t50q, t200q, t1000q, t5000q = 50, 200, 1000, 5000 -- через сколько обновлять function task_add( tname, tgroup, f ) if ( tgroup or 200 ) == 200 then t200n = t200n + 1; table_insert( t200, { f, tname } ) elseif tgroup == 1000 then t1000n = t1000n + 1; table_insert( t1000, { f, tname } ) elseif tgroup == 5000 then t5000n = t5000n + 1; table_insert( t5000, { f, tname } ) elseif tgroup == 50 then t50n = t50n + 1; table_insert( t50, { f, tname } ) end end function task_del( tname, tgroup ) -- log( "info", "task_delete, task: [%s], gp: %s", tname, ( tgroup or "any" ) ) if tgroup or 200 == 200 then for i = 1, t200n do if t200[i][2] == tname then t200n = t200n - 1; table_remove( t200, i ); return end end end if tgroup or 1000 == 1000 then for i = 1, t1000n do if t1000[i][2] == tname then t1000n = t1000n - 1; table_remove( t1000, i ); return end end end if tgroup or 5000 == 5000 then for i = 1, t5000n do if t5000[i][2] == tname then t5000n = t5000n - 1; table_remove( t5000, i ); return end end end for i = 1, t50n do if t50[i][2] == tname then t50n = t50n - 1; table_remove( t50, i ) end end end здесь 4 таблицы по группам, в зависимости от желаемой частоты вызова: 50, 200, 1000, и 5000ms. По нужному условию вызываем task_add(), и на вход передаем ссылку на свою функцию, имя функции (для отладки и чтобы можно было удалить, когда станет не нужна, группу апдейта (50, 200, 1000, 5000). Когда становится не нужна - task_del( имя, группа). В собственно апдейте bind_stalker делаем так: function actor_binder:update( delta ) ... if t1000i == 0 then -- ни чем не заняты ? if global_time_ms >= t1000t then t1000t, t1000i = global_time_ms + t1000q, 1 -- используем этот цикл под что-нибудь полезное end else gp_fn = t1000[t1000i] -- выполняем последовательно что там еще есть if gp_fn then t1000i, amk.oau_watchdog = t1000i + 1, gp_fn[2]; gp_fn[1]() else t1000i = 0 -- и используем остаток end end Здесь еще кроме динамического подключения сделано выполнение по одной подключенной функции за апдейт - чтобы не было эффекта "прихрамывания". P.S. код можно было бы организовать и "по-академичнее", но целью ставился минимальный overhead - поэтому столь монструозная функция удаления ненужного. Изменено 2 Августа 2014 пользователем Dennis_Chikin 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 2 Августа 2014 (изменено) FantomICW, Это что-то под Artos'овские скрипты или типа того ? my_spawn.script не скомпилился. Изменено 2 Августа 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 2 Августа 2014 (изменено) ну тогда вот это - local upd:num_items = packet:r_u8() - явно что-то странное. Как и packet:w_u8(upd:num_items). И вообще: https://dl.dropboxusercontent.com/u/27871782/amk_netpk.script Заточено под скорость, а то в amk/xrs оно все из себя весьма неторопливое. Изменено 2 Августа 2014 пользователем Dennis_Chikin 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 6 Августа 2014 http://www.amk-team.ru/forum/index.php?showtopic=8830&p=763618 отсюда и далее. Скрипты брать с последней страницы. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 9 Августа 2014 "Могу конечно ошибаться, но вопрос интересный и похоже не решённый" Ну так вот замеры: xr_motivator (esc_factory_bandit4):net_spawn, alive xr_motivator 1: 218.31875610352 xr_motivator 2: 10.894275665283 xr_motivator 3: 1025343.3125 xr_motivator 4: 4695.3569335938 xr_motivator total: 1030485.3125 ну и т.д. для каждого непися. где 3 - xr_sound.load_sound() ну и далее по тексту: sound_theme.load_sound() Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 9 Августа 2014 Микросекунды. Ага, до полутора секунд на отдельных неписях. Измерялось в "солянке", где в звуки дополнительно всяких окуджав понапихали, плюс, зачем-то, ко всем неписям еше и озвучку для уникальных. Методика стандартная - profile_timer(). Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 10 Августа 2014 На предыдущей странице ссылка на полную историю вопроса. Принудительное кэширование не работает, зато, похоже, звуки кэшируются самим движком при загрузке. Осталось только полностью переделать звуковой конфиг и правильно переложить сами звуки. Субъективно все эффекты вполне соответствуют замерам. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 10 Августа 2014 Ну так использовать полноформатное game_time. Хотя для себя я предпочел при сохранении вычитать текущее, и писать остаток, а в игре каждый раз отсчитывать от 0. function time_check() ... global_time_ms = time_global() game_time_time = game.get_game_time() -- полное игровое время game_time_sec = game_time_time:diffSec( game_time_base ) -- секунд от загрузки local _, _, _, _, _, _, ms = game_time_time:get() -- y, m, d, hh, mm, ss, ms game_time_ms = game_time_sec * 1000 + ms -- ms от загрузки end function init_time_check() game_time_time = game.get_game_time() game_time_base = game_time_time -- local y, m, d, hh, mm, ss, ms = game_time_time:get() -- game_time_sec = game_time_time:diffSec( game_time_start ) -- game_time_ms = game_time_sec * 1000 + ms -- время теперь считается от загрузки game_time_sec = game_time_time:diffSec( game_time_base ) _, _, _, _, _, _, game_time_ms = game_time_time:get() level.add_call( time_check, dummy_action ) end Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 17 Августа 2014 (изменено) Ну, так уж "непрост"... Листнуть 4 страницы назад - не такое уж и непосильное дело. Да и на сталкер-вики сходить - не велик подвиг. Изменено 17 Августа 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 27 Августа 2014 что actor_binder:net_spawn вызывается сразу после actor_binder:load Да. Всегда, кроме начала игры. И не только актор, а вообще все. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 9 Сентября 2014 Если нужен актор - для сингла его id всегда 0, а game object - db.actor Если нужен непись, то ( ( ( n1:id() ~= 0 ) and n1 ) or n2 ) Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 25 Октября 2014 (изменено) По п1 - не надо ни какого апдейта. Кстати, кто там просил примеров с info и окном диалога - тоже см. сюда. local t_info, t_info_any, t_info_n = {}, {}, 0 function add_on_info( f, nfo ) -- ( функция, инфо ), либо f для любых инфо if nfo then local t = t_info[nfo] if t then table_insert( t, f ) else t_info[nfo] = { f } end else t_info_n = t_info_n + 1; t_info_any[t_info_n] = f end end function actor_binder:info_callback( npc, nfo ) for i = 1, t_info_n do t_info_any[i]( nfo, npc ) end local t = t_info[nfo] if t then for i = 1, #t do t[i]( nfo, npc ) end end ltasks_proceed() -- Сюжет ltasks_process_info( nfo ) -- Отметки на карте end function init()... local add_on_info = bind_stalker.add_on_info add_on_info( inv_open, "ui_inventory" ) add_on_info( inv_open, "ui_trade" ) add_on_info( inv_open, "ui_car_body" ) add_on_info( inv_closed, "ui_inventory_hide" ) add_on_info( inv_closed, "ui_trade_hide" ) add_on_info( inv_closed, "ui_car_body_hide" ) ... return true end function inv_open() actor_data.inv_open = true end local on_closed_t = {} local on_closed_n = #on_closed_t function add_inv_closed( f ) on_closed_n = on_closed_n + 1 on_closed_t[on_closed_n] = f end function inv_closed() actor_data.inv_open = false chk_belt_add() for i = 1, on_closed_n do -- коллбэки всех, кому интересны изменения if on_closed_t[i] then on_closed_t[i]() end end end -- actor_data и chk_belt_add - ваши данные и проверки. Вместо 100500 модификаций костюмов актор элементарно с самого начала загружается невидимым балластом, например. А потом балласт убирается. 2. пока объект, полученный через level.object_by_id() существует - он существует. А вот если ушел в оффлайн или уничтожен (что, в принципе, одно и тоже), результаты будут забавные, да. Изменено 25 Октября 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 25 Октября 2014 (изменено) Юзердаты, на него ссылающиеся, после этого показывают на что попало. Да, пользоваться ими нельзя, следовательно, и хранить тоже бессмысленно. Есть, кстати, замечательный глюк в xr_conditions, где происходит обращение к сохраненной неизвестно когда, кем, и зачем юзердате. Изменено 25 Октября 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 26 Октября 2014 (изменено) Ну а что вы хотите от студенческих курсовых ? По поводу идеи с рефакторингом - ну вот я занимаюсь. Но на базе соли. По тому что там проблемы очевидно повылазили раньше, чем где-то еще, по тому что в общем приличный набор карт, хотя и глючных, и по тому что туда уже добавлено много сторонних поделий, которые тоже надо перелопачивать сразу. Начинать в очередной раз все с нуля - не хочу. Да, модули Артоса на мой взгляд чрезмерно академичны. Этим и не нравятся. Вот допилю новый формат сохранений в гулагах - выложу очередную демосборку. А если кто хочет помочь - то, кстати, посмотрите смысл job.fill_idle на предмет смысла значений, отличных от -1 и -2 в xr_gulag - где, зачем и для чего в принципе это может использоваться. function rad_pass_time(actor, npc) return true end Это запчасть от убиения актора, если он сунулся на радар без записки или в неподходящее время. Изменено 26 Октября 2014 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 26 Октября 2014 Вообще согласен, но на изучение и нормальную сборку из исходников тоже некоторое время нужно. Так что сразу - не получится. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение
Dennis_Chikin 3663 Опубликовано 27 Октября 2014 Мдя, пример выбран... Ну вот только случайно и можно. Скрипты подключаются "на лету". Вот есть, допустим, my_kew1.script, а в нем функция my_kew1_function(), то если где-то написать my_kew1.my_kew1_function() - как до нее дойдет, так сразу и подключится. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Поделиться этим сообщением Ссылка на сообщение