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

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


Svoboда

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

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

 

То есть, поставлено количество 1, вероятность 1 - в торговле предмета не будет. Поставлено 2, 1 - в торговле будет 1.

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


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

На сколько помню, это флагами задается, или что-то типа того. Но точно не скажу - надо искать по разделу.

Еще вроде резервируют аптечки.

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


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

Проверяет условия для выдачи и завершения квестов.

 

task_manager на самом деле управляет скорее диалогами, а этот оперирует собственно поршнями.

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

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


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

К вопросу об апдейте из 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 - поэтому столь монструозная функция удаления ненужного.

Изменено пользователем Dennis_Chikin
  • Полезно 1

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


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

FantomICW, Это что-то под Artos'овские скрипты или типа того ?
 
my_spawn.script не скомпилился.

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

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


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

ну тогда вот это - local upd:num_items = packet:r_u8() - явно что-то странное. Как и packet:w_u8(upd:num_items).

 

И вообще: https://dl.dropboxusercontent.com/u/27871782/amk_netpk.script

 

Заточено под скорость, а то в amk/xrs оно все из себя весьма неторопливое.

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

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


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

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


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

"Могу конечно ошибаться, но вопрос интересный и похоже не решённый"

 

Ну так вот замеры:

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()

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


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

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

Методика стандартная - profile_timer().

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


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

На предыдущей странице ссылка на полную историю вопроса.

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

 

Субъективно все эффекты вполне соответствуют замерам.

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


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

Ну так использовать полноформатное 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

 

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


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

Ну, так уж "непрост"... Листнуть 4 страницы назад - не такое уж и непосильное дело. Да и на сталкер-вики сходить - не велик подвиг. ;)

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

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


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

что actor_binder:net_spawn вызывается сразу после actor_binder:load

 

Да. Всегда, кроме начала игры. И не только актор, а вообще все.

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


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

Если нужен актор - для сингла его id всегда 0, а game object - db.actor

Если нужен непись, то ( ( ( n1:id() ~= 0 ) and n1 ) or n2 )

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


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

По п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() существует - он существует. А вот если ушел в оффлайн или уничтожен (что, в принципе, одно и тоже), результаты будут забавные, да.

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

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


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

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

 

Есть, кстати, замечательный глюк в xr_conditions, где происходит обращение к сохраненной неизвестно когда, кем, и зачем юзердате.

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

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


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

Ну а что вы хотите от студенческих курсовых ?

 

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

 

Начинать в очередной раз все с нуля - не хочу.

 

Да, модули Артоса на мой взгляд чрезмерно академичны. Этим и не нравятся.

 

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

А если кто хочет помочь - то, кстати, посмотрите смысл job.fill_idle на предмет смысла значений, отличных от -1 и -2 в xr_gulag - где, зачем и для чего в принципе это может использоваться.

 

function rad_pass_time(actor, npc) return true end

Это запчасть от убиения актора, если он сунулся на радар без записки или в неподходящее время.

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

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


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

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

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


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

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

 

Скрипты подключаются "на лету".

Вот есть, допустим, my_kew1.script, а в нем функция my_kew1_function(), то если где-то написать my_kew1.my_kew1_function() - как до нее дойдет, так сразу и подключится.

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


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

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

AMK-Team.ru

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