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

[SoC] Ковыряемся в файлах


Halford

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

Могу только телепатически...

Не news_main.script -ли, часом, чего-то хочет ?

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


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

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

И это - файлы конфигов ?

Ну так не надо ничего запаковывать. Есть каталог игры, где лежат gamedata.db0, db1 и т.д., там же лежит каталог bin... Вот в нем, рядом с bin, создаем каталог же, gamedata. В нем - уже config. В нем, если надо, misc и т.д.

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

 

А вот если речь идет про файл gamedata/spawns/all.spawn  - вот здесь надо уже acdc применять, и все изменения в основном будут уже после старта новой игры.

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


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

У меня на самом деле такой вопрос: у mods/* приоритет перед gamedata/* ?

 

Ага, забавненько... То есть, получается, таки очередная "борьба с читерами" по принципу "все равно толку не будет, но маленькую гадость я таки сделаю" ?

 

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

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

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


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

На сколько мне склероз не изменяет, основная часть этого самого списка находится где-то в районе gamemtl.xr, прочее - в конфигах в секциях [immunity]. За исключением исключений.

  • Спасибо 1

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


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

Либо добавлять свое в se_monster.script (отслеживает всех существующих монстров), и проверять их живость/нахождение на нужной локации, либо что-то типа

 

function init()
    lname = level.name()
    cur_map = lids[lname]
    sim = alife()
    gg = game_graph()

    local obj, cls_id, obj_name, obj_t, sect, gvid, lvid, map, pid, parent, ini, t, tt
    for k, v in pairs( xl_types ) do obj_by_type[k] = {} end

    log( "log", "init, lv: %s (%s)", lname, tostring( cur_map ) )

    for i = 1, 65534 do
        obj = sim:object( i )
        if obj then
            cls_id = obj:clsid()
            sect = obj:section_name()
            if bad_clsid[cls_id] or bad_sect[sect] then
                log( "warning", "bad item: %s", obj:name() )
                cls_id = false    -- пометка глючных объектов на удаление
            else                -- продолжаем чистить глючные объекты
                pid = obj.parent_id    -- заодно узнаем владельца...
                if pid == 65535 then    -- и локу, если ничейный
                    gvid = obj.m_game_vertex_id
                    if gg:valid_vertex_id( gvid ) then
                        map = gg:vertex( gvid ):level_id()
                        lvid = obj.m_level_vertex_id
                        if lvid < 4294967296 and vids[map][3] < lvid then
                            log( "error", "invalid level vertex, level %s, obj: %s",
                                sim:level_name( map ) or "none", obj:name() )
                            ini = obj:spawn_ini()
                            if ini then
                                if ini:section_exist( "logic" ) then
                                    log( "info", "logic present, keep" )
                                else cls_id = false
                                end
                            else log( "info", "no spawn_ini, keep" )
                        end    end
                    else
                        log( "error", "invalid game vertex, obj: %s, delete", obj:name() )
                        cls_id = false
                    end
                    parent = false
                else
                    map = false    -- если есть владелец, то пофиг на карту
                    parent = pid and sim:object( pid )
                    if parent and parent.name then parent = parent:name()
                    else parent = false
            end    end    end

            if cls_id then            -- если валидный
                obj_t = cls_xl[cls_id]    -- и нужный, то раскладываем по таблицам
                obj_name = obj:name()
                if obj_t == "anoms" and obj_by_name[obj_name] then
                    t = obj_by_name[obj_name]
                    log( "error", "duplicate object: %s (type: %s), id: %s, level: %s, parent: %s (vs. id: %s (type: %s), level: %s, parent: %s )", obj_name, obj_t or "?", i, map or "?", parent or "none", t.id, t.type, t.map or "?", t.parent or "none" )
                    sim:release( obj, true )
                elseif obj_t and obj_by_type[obj_t] then
                    t = { ["map"] = map, ["id"] = i, ["type"] = obj_t, ["sect"] = sect,
                        ["obj"] = obj, ["name"] = obj_name, ["parent"] = parent }

                    obj_by_name[obj_name] = t
                    obj_by_id[i] = t

                    if parent then
                        tt = obj_by_parent[pid]
                        if tt then tt[i] = t
                        else obj_by_parent[pid] = { [i] = t }
                        end
                    else obj_by_type[obj_t][i] = t
                    end
                else    -- ищем амк-респавнеры
                    ini = obj:spawn_ini()
                    s = ini and ini:section_exist( "respawn" )
                        and ini:line_exist( "respawn", "amk_name" )
                        and ini:r_string( "respawn", "amk_name" )
                    if s then respawners[s] = obj end
                end
            else log( "info", "delete" ); sim:release( obj, true )    -- удаляем глючные объекты
    end    end    end

    for k, v in pairs( vids ) do
        wpn_by_map[k] = {}
        t = { ["npc_dead"] = {}, ["mob_dead"] = {} }
        for k, v in pairs( xl_types ) do t[k] = {} end
        obj_by_map[k] = t
    end

    local p
    t = obj_by_type.wpn_prot
    for k, v in pairs( obj_by_type.firearm ) do    -- бесхозные стволы проверяем на близость к неписям
        p = ( t_wprm or get_wprm() ).prot or prot_name[ v.name ] or
            v.obj.m_story_id ~= 4294967296
        if p then v.prot = p; t[k] = v    -- защищенные стволы храним отдельно
            -- log( "info", "init, wpn: %s, prot: %s", v.name, tostring( p ) )
        elseif v.map ~= curr_map then    -- остальные раскладываем по картам
            wpn_by_map[ v.map ][k] = v
        end
    end

    clr_dead_mob()
    clr_dead_npc()    -- при уборке хлама удаляются сначала трупы, потом стволы

    t = {}
    local n, c = 0, 0
    local prm
    for k, v in pairs( wpn_by_map ) do    -- готовим стволы на удаление
        for kk, vv in pairs( v ) do
            if vv.keep then    -- стволы рядом с кем-то считаем
                c = c + 1
                obj_by_map[ vv.map ].firearm = vv
            else            -- лежащие далеко от неписей - на удаление
                prm = t_wprm[ vv.sect ] or get_wprm( vv.sect )
                vv.r = prm.cost * get_wpn_cond( vv.obj )
                n = n + 1; t[n] = vv
    end    end    end

    if lim_wpn < c then lim_wpn = 0
    else lim_wpn = lim_wpn - c
    end

    if lim_wpn < n then    -- оставляем для подбирания неписями или ГГ
        table_sort( t, function( a, b ) return a.r < b.r end )
        for i = 1, lim_wpn do tt = t[i]; obj_by_map[ tt.map ].firearm = tt end
    end
    for i = lim_wpn + 1, n do    -- удаляем свыше лимита
        obj = t[i].obj
        sim:release( obj, true )
        obj_by_id[ obj.id ] = nil
    end

    for k, v in pairs( obj_by_type.npc ) do obj_by_map[ v.map ].npc[k] = v end
    for k, v in pairs( obj_by_type.npc_dead ) do obj_by_map[ v.map ].npc_dead[k] = v end
    for k, v in pairs( obj_by_type.mob ) do obj_by_map[ v.map ].mob[k] = v end
    for k, v in pairs( obj_by_type.mob_dead ) do obj_by_map[ v.map ].mob_dead[k] = v end
    fake_trade( obj_by_type.npc )
    amk_spawners()
    return true
end

- это из уборщика кусок.

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


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

local t = read_monster_params( obj )

t.custom = "[logic]\ncfg = scripts\\что-попало.ltx

write_monster_params( t, obj )

 

функции взять из amk

  • Полезно 1

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


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

Гм, с учетом того, что в ОП движок ни кто не правил, мне удивительно слышать, что там что-то не так, как в другом месте.

Но, кстати, да - что-то этакое, странное, замечалось. Не в ОП отнюдь.

 

Ни заглянуть в собственно движок, ни поиграться с порядком k в system руки не дошли пока. 8(

 

P.S. А давайте мы все-таки будем писать больше по делу, и меньше - про отвлеченные материи ? Это так - пожелание, обращенное к неопределенному кругу лиц. Только вот в четверг тему чистил...

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

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


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

И это ОПЯТЬ оригинал ?

 

См. в шапке про телепатов.

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

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


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

Он тоже в отпуске. 8(

 

Тайники не могут перестать работать просто так сами по себе. Очевидно, что-то изменялось. Что именно и как именно - вот кто здесь должен это знать ?

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


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

Ну правильно разбредаются. Группировка не подходит для смарта. Теперь смотреть все файлы gulag*.script и везде заменять бандитов на сталкеров. А потом еще курить smart_terrain_presets.

  • Спасибо 1

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


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

Можно и оттуда, и оттуда. Простейший вариант - под ноги актора:

local obj = alife():create( "m_inventory_box", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id() )

if obj then

local t = amk.get_invbox_data( obj )

t.custom = "[logic]\ncfg = scripts\\treasure_inventory_box.ltx"

amk.set_invbox_data( t, obj )

end

 

где m_inventory_box - секция тайника, прописанная в конфиге,

amk.script - см. в соответствующем моде, логика:

[logic]
active = ph_idle@enable
[ph_idle@enable]
nonscript_usable = true
tips = "какой-то текст"
P.S. Да, еще бы, конечно, не помешала проверка на валидость этого самого db.actor:game_vertex_id() Изменено пользователем Dennis_Chikin

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


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

Гм, "чтобы ни куда не уходил" - это, наверное, все же не логика, а прежде всего custom_data с чем-то типа

[smart_terrains]
none = true

Ну а дальше - уже действительно в логике все равно walker и путь, с одной точкой. Или camper. В общем, та самая схема, которая отвечает за нужные анимации и прочее поведение.

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


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

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

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

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


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

В онлайне ? В оригинале не обыскивают вообще. В солянке - wather_act.script.

 

Проблема решена давно, но... В общем, одной строчкой не обойтись. А чтоб еще единая "для большинства" - тем более. Проще закрасить, и переписать заново. Что и сделано, но для одного конкретного.

 

Ну, можешь поискать что-нибудь типа

max_dist=5+math_sqrt(value), и как-нибудь покрутить. Типа там max_dist=5+math_sqrt(value)/10

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

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


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

Да, и где-то уже про это писал: сразу снести строчки

for o in npc:memory_sound_objects() do

check_item(o)

end

 

Ибо пользы от них нет, а тормоза - есть.

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


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

Недавно ж где-то расписывал: в офлайне логика не работает. Она только для онлайновых объектов.

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

 

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

Ну или принудительно освобождать его от работы с какой-то частотой.

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


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

Волка просто выгоняют из одного смарта, и записывают в другой.

[smart_terrains]
esc_lager = {-agroprom_military_case_have -esc_fanat_spawn}
mil_lager = {+agroprom_military_case_have -escape_lager_volk_resiver_done}, {+esc_fanat_spawn -escape_lager_volk_resiver_done}
sak_lager = {+escape_lager_volk_resiver_done}
Пока не дошел - работает вот это самое выгнали/назначили.

 

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

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


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

2 UnLoaded: Ну, по идее, это самое smart_terrains - тоже логика, да. Но выполняется в другом месте.

 

То есть, грубо говоря, такая последовательность (оригинал чуток переписан, но смысл должен быть примерно понятен, а то исходный лень искать):

 

function read_smart_terrain_conditions( obj )	-- вызывается объектами, которые могут ходить под smart terrain
	local ini = obj.ini

	if ini and ini:section_exist( smart_section ) then
		local n = ini:line_count( smart_section )
		if n == 0 then return end
		local t = {}
		local r, k, v
		for i = 0, n - 1 do
			r, k, v = ini:r_line( smart_section, i, "", "" )
			-- if dbg then log( "info", "[%s]:[%s]", k, string_sub( v, 1, 180 ) ) end
			if k == "none" then
				if v == nil or v == "" or v == "true" then
					if n == 1 then obj.strn_none = true; return end
					abort( "read_smart_terrain_conditions, invalid section [%s] (%s), ( n: %s, none )", smart_section, obj:name(), n  )
				-- else log( "info", "read_smart_terrain_conditions, [%s] (%s)", string.sub( v, 1, 150), obj:name() )
				end
			elseif v == "true" then
				if ( n == 1 ) or ( n == 2 and ini:line_exist( smart_section,
					"respawn_check" ) ) then obj.strn_e = k; return
				end
				abort( "read_smart_terrain_conditions, invalid section [%s] (%s), ( n: %s = true )", smart_section, obj:name(), n )
			end
			t[k] = xr_logic.parse_condlist1( --[[ obj, smart_section, k,]] v )

		end
		return t
	end
end

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

 

	if obj.strn_e == self.nm then	-- если смарт заведомо эксклюзивный, ни каких условий не проверяем
		npc_info.exclusive = true
	else
		n = obj.smart_terrain_conditions and obj.smart_terrain_conditions[ self.nm ]
		npc_info.cond = n	-- копируем условие для апдейта/анрега (экономим там одно извлечение из таблицы)
		if n then npc_info.exclusive = true
		else npc_info.exclusive = false
	end	end

 

 

Далее, в апдейте, происходит проверка:

 

-- Обновление. В онлайне вызывается через binder. Также может вызваться принудительно из xr_effects
-- Если в гулаге ни кого не осталось или условия существования гулага не выполняются - убрать гулаг.
-- В npc_info.cond только условия непися в ЭТОМ смарте, они и проверяются.
-- Если условие было просто true - в npc_info.cond оно не пишется, и никогда не проверяется.

function se_smart_terrain:update()
	cse_alife_smart_zone.update( self )
	if not self.gulag_working then return end
	if self:is_gulag_available() then
		if self.check_time < game_time_time then
			self.check_time = game_time_time + check_period
			for id, npc_info in pairs( self.npc_info ) do	-- не собрался ли кто-то уходить
				if npc_info.cond and not xr_logic.pick_section_from_condlist(
				  db.actor_proxy, npc_info.se_obj, npc_info.cond ) then
					--log( "info", "(%s):update, remove: %s", self.nm, npc_info.se_obj:name() )
					self:unregister_npc( npc_info.se_obj )
			end	end

- если непись проверку не прошел - выгнали.

 

Если непись все еще под смартом - работает уже xr_gulag. Там примерно то же, только для конкретных работ. Если непись на работу годится - назначили. И начинаем смотреть собственно логику. Если есть active_section - ее читаем, находим путь, находим координаты первой точки, и запоминаем.

 

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

Так и перемещается.

 

А вот хождение по точкам пути - это уже всякие xr_walker, xr_patrol, и так далее. Которые запускаются только в онлайне. Они там путь путь разбирают на части, получают нужный вертекс, и пинками гонят непися в этот вертекс, попутно дергая state_manager на предмет анимаций.

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

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


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

1. Похоже таки карточка. В железный раздел.

2. А не геометрия ли конкретных модов ? Ждем тех, кому будет не лень сравнить.

 

2 qwertynosik: "помощь" засчитывается, когда убит тот, кто нанес ранение. Причем нужно успеть в промежуток, пока ранившего "помнят".

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


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

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