Jump to content
Sign in to follow this  
n6260

Народная 2010 разработка

Recommended Posts

Dennis_Chikin    3,597

"Что у нее внутри, и как это сделать лучше". Для тех, кто уже разбирается в скриптах, конфигах, текстурах и "других страшных словах" ©, и имеет желание и время действительно делать их лучше.
См. подробности в первом посте.

Тема НЕ является ни столом заказов, ни службой техподдержки, ни справочным бюро.

Edited by Dennis_Chikin
  • Like 2
  • Полезно 1

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

Ответ на оффтопик в "разговорах":

Если нам надо найти "Костюм Тирекса", то запускаем поиск по конфигам, и ищем, внезапно, "Костюм Тирекса".

Он, внезапно, находится в string_table_outfit.xml:

<string id="strelok_outfit_name">

<text>Костюм Тирекса</text>

</string>

 

Зеленый, оранжевый и прочие серобуромалиновые кружки, которые иногда высвечиваются при загрузке и тут же исчезают - ну, это такие кружки, которые иногда высвечиваются при загрузке. ;)

Надо копать, где конкретно вся эта иллюминация на голод/холод/радиацию проверяется, но на практике ни кому не интересно.

  • Like 2

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

И сюда тоже положу, дабы не потерялось. Лечение вылета Гавра + одного из случаев обкрадывания тайников с замками в них. На базе НОРМАЛЬНОГО Сапсаноскрипта (а где люди берут то, что берут, которое потом всячески глючит и вылетает - ну, это уж я не знаю).

 

https://dl.dropboxusercontent.com/u/27871782/zamok.script

Проверять не на чем, и некогда, так что добровольцы - вперед.

Чистая-сапсанопатчи-ОП со всеми буквами - без разницы.

Edited by Dennis_Chikin

Share this post


Link to post
Share on other sites
romale    476

На базе НОРМАЛЬНОГО Сапсаноскрипта

Это какого, если не секрет?

добровольцы - вперед.

В ОП, патч 1.0004 - при отравлении вылета нет с наличием в инвентаре замка.

А вот при установке замка на рюкзак и попытке его (замок) снять - имеем такой вылет:

 

FATAL ERROR

 

[error]Expression : fatal error

[error]Function : CScriptEngine::lua_error

[error]File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp

[error]Line : 73

[error]Description : <no expression>

[error]Arguments : LUA error: d:\s.t.a.l.k.e.r_op\gamedata\scripts\zamok.script:37: attempt to index global 'sim' (a nil value)

 

--------------------------

 

Перезалил под тем же именем.

Пока без вылетов при тех же манипуляциях.. Edited by romale

Вы ленивы, следовательно - вы изобретательны. © граф Де Гиш

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

Добавил этот самый sim общим для всего скрипта.

Заодно подумал, и выписал ему таблеток от жадности.

 

Перезалил под тем же именем.

 

 

"Пока без вылетов при тех же манипуляциях.. " - ну, ура ?

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

Все глюки оффлайн-алайфа, конечно же, не лечит.

Edited by Dennis_Chikin
  • Like 1

Share this post


Link to post
Share on other sites
romale    476

- ну, ура ?

Денис, ну, наверное ура :)

Все сообщения выводятся.

Только я ж писал, что вылетов не было и все так же работало со скриптом из тестового набора Сапсана :)

 

Кстати, ты так и не сказал, что такое "НОРМАЛЬНЫЙ Сапсаноскрипт"


Вы ленивы, следовательно - вы изобретательны. © граф Де Гиш

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

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

 

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

Edited by Dennis_Chikin

Share this post


Link to post
Share on other sites
romale    476

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

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

Когда забираю - сообщение только при изъятии последнего замка.

 

Угум. Вот это - признак правильной работы. dc

 

Раньше были сообщения на каждый устанавливаемый/снимаемый.

Edited by Dennis_Chikin

Вы ленивы, следовательно - вы изобретательны. © граф Де Гиш

Share this post


Link to post
Share on other sites
romale    476

@Dennis_Chikin,

Денис, возник вопрос в связи с участившимися жалобами подобными этой:

При подборе гранаты у Калмыка идет вылет:

Помнится подобное уже обсуждалось: http://www.amk-team.ru/forum/index.php?showtopic=8830&p=718724 и ниже.

Ты там выкладывал правку:

Несколько критичных правок: xr_danger, разблокировал переключение состояний после ТД, ну и гранату переделал

http://www.amk-team.ru/forum/index.php?showtopic=8830&p=721024

Собственно, что там (какие правки) относится именно к гранате и моменту ее взятия, кроме \gamedata\config\scripts\new\nebo\marsh_havan_restr.ltx ?

Или замена только этого файла достаточна?

Сам раньше проверить не мог, поскольку с тех пор ниразу с 6-м патчем не играл, а вылет имеет место только в игре с 6-м.. А сейчас еще не дошел до Калмыка.

Edited by romale

Вы ленивы, следовательно - вы изобретательны. © граф Де Гиш

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

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

 

Соответственно, переделана вся сценка с гранатой, и вынесена в storyline.script:

 

function take_from_box( box, item )
	-- log( "info", "take_from_box, item: %s, box: %s", ( item and item:name() ) or "nil", ( box and box:name() ) or "nil" )
	if box and string_sub( box:name(), 1, 8 ) == "prov_ruk" then
		marsh_kalmyk_start( box, item )
	end
end


function marsh_kalmyk_start( box, item )
	log( "info", "marsh_kalmyk, entry" )
	level["add_pp_effector"]( "agr_u_fade.ppe", 8120802, false )
	level["hide_indicators"]()
	bind_stalker["hide_weapon"]()
	local apos = actor:position()
	local obj = sim:object( box:id() )
	if obj then
		amk_particle["amk_particle"]( {
			["particle"] = "explosions\\explosion_fuelcan",
			["pos"] = box:position(),
			["sound"] = "weapons\\t_rgd5_explosion" } )
		local dist = apos:distance_to_sqr( box:position() )
		if dist < 100 then
			local h = hit()
			h["draftsman"] = actor
			h["direction"] = vector():set( 0, 1, 0 )
			h:bone( "bip01_spine" )
			h["type"] = hit["explosion"]
			h["power"] = ( dist < 1 and 0.8 ) or 0.8 / dist
			h["impulse"] = 500
			actor:hit( h )
		end
		sim:release( obj, true )
	end
	level["add_cam_effector"]( "camera_effects\\fusker.anm", 999, false, "" )
	timer_add( "marsh_kalmyk", marsh_kalmyk )
	timer_start( "marsh_kalmyk", 2, item:id() )
end

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

 

function marsh_kalmyk( obj_id )
	if actor:has_info( "kalmyak_vstreca_start" ) then
		actor:give_info_portion( "kalmyak_vstreca_grab" )
		return
	end
	level["add_pp_effector"]( "deadcity_wake.ppe", 8120803, false )
	actor:give_info_portion( "kalmyak_vstreca_start" )
	actor:set_actor_position( patrol( "kalmyak_tele_walk" ):point( 0 ) )
	timer_start( "marsh_kalmyk", 5 )
	local obj = sim:object( obj_id )
	if obj then sim:release( obj, true ) end
	level["show_indicators"]()
	bind_stalker["restore_weapon"]()
end

Обе функции - под "обезжиренную". actor должен быть в глобальном пространстве, доработку таймеров смотрим в amk_timers.script

 

Да, гранату теперь в рюкзак можно класть обычную (еще -1 ни зачем не нужная секция из развесистой клюквы конфигов), или вообще не гранату. Тогда можно еще удаление убрать вообще.

 

\gamedata\config\scripts\new\nebo\marsh_havan_restr.ltx - это на взятие какого предмета что вызываем.

В принципе, можно и нужно снести вообще весь рестриктор, и провешивать при инициализации вызов на открытие рюкзака, если находимся на болотах.

Share this post


Link to post
Share on other sites
xuyc    79

@Dennis_Chikin,

А тебе не приходила в голову мысль сделать фиксы самых грубых известных ошибок и ляпов в скриптах соли? Не перелопачивая все, а только самое вопиющее? Например в level_weathers.script есть такое:

if self.cycle_idx[self.dyn_weather] == nil then
                self.dyn_wather = tmp_dyn_weather
            end
        end

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

 

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

Вот это конкретное я выкладывал 3 года назад. Или 4.

Последний раз - пару месяцев назад.

 

Кроме того, сейчас здесь лежит "плоский" погодный скрипт под любую соль.

 

Ну и еще так по мелочи.

 

Фиксить все под старую - бессмысленно уже. Тем более, что от переписывания большими кусками не уйти.

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

https://dl.dropboxusercontent.com/u/27871782/sounds.7z

Текущий полный набор скриптов озвучки. Конфиг перенесен в скрипт, дабы не тормозило.

 

Подробности смотрите в теме.

 

Для адаптации куда либо надо понимать, что db.actor продублирован в глобальном пространстве. Там же, в _g.script - постоянно обновляется время ( game_time_sec, game_time_ms, global_time_ms и т.д.)

То есть, либо вернуть старые переменные и вызовы (и огрести все положенные тормоза), либо сделать так же.

 

 

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

Edited by Dennis_Chikin
  • Like 2

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

История одной пессимизации:

код:
local ini = system_ini()
local test
local pt = profile_timer(); pt:start()
for i = 1,10000 do ini = system_ini(); test = ini:r_bool( "test1", "bool_t" ) end
pt:stop()

И вывод времени.
варианты:
ini = system_ini(); test = ini:r_bool( "test1", "bool_t" ) -- 13.623 ms
test = system_ini():r_bool( "test1", "bool_t" ) -- 12.740 ms
и просто test = ini:r_bool( "test1", "bool_t" ) -- 7.463 ms
Мелочь, а приятно. Но, то есть, я здесь был не прав, считая, что конфиги читаются при каждом system_ini(). Как указал KD87, читаются они при старте игры, а system_ini() - это всего-лишь возврат указателя CInifile *pSettings.

Однако, если мы попытаемся читать не system_ini():, а test.ltx, всего из 4-х строк, картина становится вот такой:
ini = ini_file( test.ltx ); test = ini:r_bool( "test1", "bool_t" ) -- 517.023 ms
test = ini:r_bool( "test1", "bool_t" ) -- 4.947 ms

То есть, движок сталкера и сам по себе файлы кэширует довольно неплохо, но "иногда" и "внезапно" подвержен склерозу, если речь идет не об system.ltx

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

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

Не хочу сегодня ни чей флуд читать, сам флудить буду !

Тем более, что понаписал стресс-тестов, погонял, ни какого криминала не нашел, у кого-там чего все разваливается - в упор не понимаю.

 

Итак, краткое содержание предыдущей серии:

 

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

Вызовы функций - жрут.

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

system.ltx - особый случай, и открыт при запуске игры. Впрочем, если использовать конструкцию ini_file("system.ltx") - эффект даже проверять не хочу.

 

Итого, идея навесить сверху еще какое-то специальное скриптовое кэширование - это довольно плохая идея.

Особенно, если это самое скриптовое постоянно занимается переоткрыванием файлов.

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

 

В общем, для чистой соли и всех солянкоклонов, наиболее правильным будет вернуться везде именно к прямому чтению из файлов. А заодно поубирать и вызовы util.что-то-там.

 

Но некоторое улучшение ситуации мы можем получить, дописав в _g.script следующие строчки:

 

sys_ini = system_ini() -- выигрыш не очень большой, но лишний вызов функции все-таки не нужен. Особенно, для каждого из тех 1500 костюмов и прочих радостей.

А далее мы заменяем все одноименные переменные и функции вот на такие:

 

local t_ini = { ["system_ini"] = sys_ini }

iniLines = {
	["float"]	= {},
	["u32"]		= {},
	["string"]	= {},
	["string_wq"]	= {},
	["boolean"]	= {},
	["line"]	= {},
	["count"]	= {},
	["exist"]	= {} }

iniOtherLines = {}

local iniSections = {}	-- что кэшируем; если пустая - то уже ничего не кэшируем. И вообще не кэшируем.

iniStat = {}
iniCaching = true
iniStatistic = false

iniSectionsCount = 0


function getIniValuePrepare( vtype, sect, file )	-- тип, секция, имя файла
	local t2, t3
	if file then	-- файл, не system.ltx
		local ini = t_ini[file]	-- уже открыт ?
		if not ini then		-- или открываем и сохраняем ссылку
			ini = ini_file( file ) or abort( "getIniValuePrepare, invalid file: %s", file )
			t_ini[file] = ini
		end

		local t1 = iniOtherLines[file]	-- зачем-то отдельная таблица
		if not t1 then
			t3 = {}
			t1 = { [vtype] = { [sect] = t3 } }; iniOtherLines[file] = t1; return ini, t3
		end
		local t2 = t1[vtype]
		if t2 then	-- по типам есть кэш, пытаемся проверить таблицу для секции
			t3 = t2[sect]
			if not t3 then t3 = {}; t2[sect] = t3 end	-- или создать
		else t3 = {}; t2 = { [sect] = t3 }; t1[vtype] = t2	-- нет типа, содаем его и секцию
		end
		return ini, t3
	end

	t2 = iniLines[vtype]	-- или таблица для system.ltx
	if t2 then
		t3 = t2[sect]
		if not t3 then t3 = {}; t2[sect] = t3 end	-- или создать
	else t3 = {}; t2 = { [sect] = t3 }; iniLines[vtype] = t2	-- нет типа, содаем его и секцию
	end
	return sys_ini, t3
end


function iniLineSectionExist( sect, file )
	if sect then
		if file then
			local ini = t_ini[file]	-- уже открыт ?
			if not ini then		-- или открываем и сохраняем ссылку
				ini = ini_file( file ) or abort( "iniLineSectionExist, invalid file: %s", file )
				t_ini[file] = ini
			end
			return ini:section_exist( sect )
		end
		return sys_ini:section_exist( sect )
	end
	return false
end


function iniLinesCount( sect, file )
	if sect then
		if file then
			local ini = t_ini[file]	-- уже открыт ?
			if not ini then		-- или открываем и сохраняем ссылку
				ini = ini_file( file ) or abort( "iniLinesCount, invalid file: %s", file )
				t_ini[file] = ini
			end
			if ini:section_exist( sect ) then return ini:line_count( sect ) end
		elseif sys_ini:section_exist( sect ) then return sys_ini:line_count( sect )
	end	end
	return 0
end


function getIniLine( sect, num, defKey, defVal, file )
	if sect and num then
		if file then
			local ini = t_ini[file]	-- уже открыт ?
			if not ini then		-- или открываем и сохраняем ссылку
				ini = ini_file( file ) or abort( "getIniLine, invalid file: %s", file )
				t_ini[file] = ini
			end
			if ini:section_exist( sect ) then
				return ini:r_line( sect, num, defKey, defVal )
			end
		elseif sys_ini:section_exist( sect ) then
			return sys_ini:r_line( sect, num, defKey, defVal )
	end	end
	return false, defKey, defVal
end


function getIniValueFloat( sect, line, def, file )
	if sect and line then
		if file then
			local ini = t_ini[file]	-- уже открыт ?
			if not ini then		-- или открываем и сохраняем ссылку
				ini = ini_file( file ) or abort( "getIniValueFloat, invalid file: %s", file )
				t_ini[file] = ini
			end
			return ( ini:section_exist( sect ) and ini:line_exist( sect, line )
				and ini:r_float( sect, line ) ) or def
		end
		return ( sys_ini:section_exist( sect ) and sys_ini:line_exist( sect, line )
			and sys_ini:r_float( sect, line ) ) or def
	end
	return def
end


function getIniValueU32( sect, line, def, file )
	if sect and line then
		if file then
			local ini = t_ini[file]	-- уже открыт ?
			if not ini then		-- или открываем и сохраняем ссылку
				ini = ini_file( file ) or abort( "getIniValueU32, invalid file: %s", file )
				t_ini[file] = ini
			end
			return ( ini:section_exist( sect ) and ini:line_exist( sect, line )
				and ini:r_u32( sect, line ) ) or def
		end
		return ( sys_ini:section_exist( sect ) and sys_ini:line_exist( sect, line )
			and sys_ini:r_u32( sect, line ) ) or def
	end
	return def
end


function getIniValueString( sect, line, def, file )
	if sect and line then
		if file then
			local ini = t_ini[file]	-- уже открыт ?
			if not ini then		-- или открываем и сохраняем ссылку
				ini = ini_file( file ) or abort( "getIniValueString, invalid file: %s", file )
				t_ini[file] = ini
			end
			return ( ini:section_exist( sect ) and ini:line_exist( sect, line )
				and ini:r_string( sect, line ) ) or def
		end
		return ( sys_ini:section_exist( sect ) and sys_ini:line_exist( sect, line )
			and sys_ini:r_string( sect, line ) ) or def
	end
	return def
end


function getIniValueStringWQ( sect, line, def, file )
	if sect and line then
		if file then
			local ini = t_ini[file]	-- уже открыт ?
			if not ini then		-- или открываем и сохраняем ссылку
				ini = ini_file( file ) or abort( "getIniValueStringWQ, invalid file: %s", file )
				t_ini[file] = ini
			end
			return ( ini:section_exist( sect ) and ini:line_exist( sect, line )
				and ini:r_string_wq( sect, line ) ) or def
		end
		return ( sys_ini:section_exist( sect ) and sys_ini:line_exist( sect, line )
			and sys_ini:r_string_wq( sect, line ) ) or def
	end
	return def
end


function getIniValueBool( sect, line, def, file )
	if sect and line then
		if file then
			local ini = t_ini[file]	-- уже открыт ?
			if not ini then		-- или открываем и сохраняем ссылку
				ini = ini_file( file ) or abort( "getIniValueBool, invalid file: %s", file )
				t_ini[file] = ini
			end
			if ini:section_exist( sect ) and ini:line_exist( sect, line ) then
				return ini:r_bool( sect, line )
			end
		elseif sys_ini:section_exist( sect ) and sys_ini:line_exist( sect, line ) then
			return sys_ini:r_bool( sect, line )
		end
	end
	return def
end

 

- фактически, весь кусок между

-------======= ini reading functions by sapsan =======------

и -------======= / ini reading functions by sapsan =======------

 

В принципе, можно еще и дальше заменить одноименное на

function printf() end

function mylog() end

function dbglog() end

и совсем где-то в середине - function print_table() end

 

По тому как не нужны.

 

Отличия от того, что я давал - косметические, ну и поправлена ставшая жертвой копипасты function getIniValuePrepare(), которая, впрочем, все равно не используется.

 

В общем, не все оптимизации одинаково полезны.

Edited by Dennis_Chikin
  • Thanks 1
  • Полезно 2

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,597

В порядке ликбеза, про ТД.

 

Почему неписи не ходят как надо - расписано страницу назад. Ну и недели три назад в ШМ.

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

 

Впрочем, совет - не ходить повторно куда не нужно (то есть, кргда Сидорович сказал на Кордон  идти - имеет смысл идти именно туда).

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

 

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

Там вам будет вполне такой фриплэй: можно спокойно перестрелять красных бандюков, вывести пленных о бандитского лагеря, затем встретиться с Пулей, и вывести Любера, затем взять в любом порядке квесты на Фраера и на Угрюмого, Потом пообщаться с нейтральным Боровом, который скажет вам спасибо за дохлого Фраера. При этом и Монгол, и Жила - вполне себе нормально себя чувствуют, все время всей этой опупеи.

 

В общем, не так все и сложно с переносом в куда угодно. Но, повторяю, лишнее.

 

Так, что у нас там еще осталось из вечных тем ? Юрик ? Так вот вы таки тоже будете удивлены, но тоже две недели назад выкладывалось очередной раз в ШМ. И тоже, кстати, можно и без правок - просто бандюков дымовухой разогнали, и ушли спокойно на Кордон. И ВСЕ. Нормально все перемещалки сработают, не смотря даже и на баги оригинала.

 

Единственный проблемный персонаж - Лис - влетающий в аномалии на свалке. И то по тому как руки не дошли. Вообще можно и битхаком, кстати, любой олспавн поправить. Букву f на b заменить.

Edited by Dennis_Chikin
  • Like 1

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

AMK-Team.ru

×
×
  • Create New...