В данной теме вы можете задавать любые вопросы касательно S.T.A.L.K.E.R. моддинга
• Не флудить • Предварительно просматривайте раздел, ведь ответ на ваш вопрос может быть там • В своем вопросе указывайте платформу моддинга — Тень Чернобыля, Чистое небо или Зов Припяти
1. Какая стоит игра, с каким патчем? 2. Какой мод, версия мода? 3. Что правили своими ручками? 4. Лог вылета и последние 25 строк (помещать под спойлер).
Структура папок и файлов в корневом каталоге игры:
...\S.T.A.L.K.E.R\gamedata\anims – папка содержит исполнительные файлы эффектов (например от ПНВ).
...\S.T.A.L.K.E.R\gamedata\config – папка содержит основные конфигурационные файлы (т. е. большинство настроек игры)
...\S.T.A.L.K.E.R\gamedata\meshes – содержит модели игровых предметов и персонажей...
...\S.T.A.L.K.E.R\gamedata\scripts – папка со скриптами (рабочими файлами содержащими в себе наборы функций) – основная папка, отвечающая за ответные действия игры и действия производимых игроком в игре.
...\S.T.A.L.K.E.R\gamedata\shaders – папка содержит в себе конфигурационные файлы шейдеров.
...\S.T.A.L.K.E.R\gamedata\sounds – здесь находятся все звуки игры (разложены по своим каталогам и папкам)
...\S.T.A.L.K.E.R\gamedata\spawns – содержит файл спавна – очень важный файл – не трогать без нужды!!!
...\S.T.A.L.K.E.R\gamedata\textures – содержит разложенные по каталогам и папкам текстуры используемые в игре.
Теперь разберем папки в каталоге «config»
...\S.T.A.L.K.E.R\gamedata\config\creatures - содержит массу конфигурационных файлов, в основном отвечающих за взаимодействие Главного героя игры (в дальнейшем ГГ) и прочего окружения в игре и ТТХ самого ГГ.
...\S.T.A.L.K.E.R\gamedata\config\gameplay – содержит конфиг. файлы персонажей игры (НПС) отвечающие за внешний вид, статус, снаряжение. Файлы: character_desc_ххх (где ххх – название локации) и character_desc_general (отвечает за зомбированного персонажа). Также содержит файлы диалогов и профилей НПС.
…\S.T.A.L.K.E.R\gamedata\config\misc – конфиг.файлы торговцев (папки с именами торговцев), артефактов, брони, квестовых предметов, уникальных предметов, файл отвечающий за награды за автозадания, файл эффектов (алкоголизма, ранения, ПНВ и прочих)...
…\S.T.A.L.K.E.R\gamedata\config\mp – среди прочих содержит важный файл mp_ranks – отвечающий за выпадение оружия и патронов из рук ГГ и НПС – без прописывания добавляемого в игру оружия в этот файл при выпадении нового оружия из рук ГГ\НПС будут следовать вылеты.
…\S.T.A.L.K.E.R\gamedata\config\text\rus – содержит файлы описаний всего и вся находящегося в игре (брони, артефактов, оружия, предметов и прочего).
…\S.T.A.L.K.E.R\gamedata\config\weapons – содержит конфиг.файлы оружия и боеприпасов используемых в игре.
…\S.T.A.L.K.E.R\gamedata\config\weathers – содержит конфиг.файлы настройки погоды на локациях.
Теперь немного подробнее о файлах.
...\S.T.A.L.K.E.R\gamedata\config\misc:
Папка shop_ххх (ххх – имя торговца) – содержит конфиг.файлы ассортимента торговца.
outfits – содержит секции конфигов костюмов.
artefacts - содержит секции конфигов артефактов.
items - содержит секции конфигов предметов.
monster_items - содержит секции конфигов частей монстров
postprocess - содержит секции конфигов пост. процессов (например: ПНВ).
quest_items - содержит секции конфигов квестовых предметов.
task_manager - содержит секции наград за автоквесты.
unique_items - содержит секции конфигов уникального оружия и костюмов.
Ну я же ответил, что мол в логике прописывать можно sit_normal.
То что вас за такое криворучие не настиг злобный жук - это вам просто повезло! Запомните, а лучще запишите на всех заборах, что animpoint_sit_normal и sit_normal - это РАЗНЫЕ анимстейты для РАЗНЫХ задач!
То что вас за такое криворучие не настиг злобный жук - это вам просто повезло! Запомните, а лучще запишите на всех заборах, что animpoint_sit_normal и sit_normal - это РАЗНЫЕ анимстейты для РАЗНЫХ задач!
Извиняюсь все отлично работает, НПС сел куда надо и как надо. Впредь буду внимательней.
Вообще эта фраза лишена изрядной доли смысла, поскольку данная секция читается скриптом, которому плевать где эта секция прописана в castom_data спавн секции или в castom_data секции из all.spawn. И как на эту секцию реагировать тоже решает скрипт, который легко и просто при необходимости переписать. В каком состоянии скрипты у спрашивающего я не знаю, но насколько помню если у НПС есть кастом дата и в ней прописана логика, то скрипт будет игнорировать попытки назначить НПС гулаг. _S_k_i_F_, 1. Перед записью в пакет нужно для начала убедиться, что self.use ~= nil, иначе что вы запишете? 2. Переменная self.use бинарная, значит никак не package:w_u8(self.use), а package:w_bool(self.use) 3. Если self.use == true, то записать еще потребуется self.item (строка), self.item_count (беззнаковое число) 4. Если при чтении выясниться, что self.use == true, то читаете дополнительно self.item и self.item_count 5. При чтении self.use == true, значит требуется регистрация колбека на юзанье трупа монстра: self.object:set_callback(callback.use_object, self.on_use, self)
Сообщение отредактировал denis2000 - Четверг, 24.03.2016, 15:46
Перезагрузился, что бы заработала логика, и он ушёл по своим делам. Заспавнил егшо через all.spawn для проверки, и всё сработало! И на сколько я помню, не только smart_terrains читается только из all.spawn.
riper, >>cleack<< или так level.set_time_factor(number) Установку по умолчанию смотри в alaiftime_factor =
Добавлено (24.03.2016, 19:28) --------------------------------------------- Mopa, Зачем ты пытаешься это сделать? Тебе всё равно надо писать логику, если конечно ты хочешь отправить его в kamp и указать path_walk = *_task то тут нужен гулаг. В остальном же, проще создать уника. Или all.spawn тебе в помощь. Ну а если хочешь заселить пустой гулаг, то это сделает за тебя респавнер. Плюс надо будет убедится, что работа не отменена условиями.
Сообщение отредактировал ins33 - Четверг, 24.03.2016, 19:31
И на сколько я помню, не только smart_terrains читается только из all.spawn.
ins33, вы не внимательно прочитали то, что написал вам denis2000
Секция smart_terrains вычитывается скриптом se_stalker.script в методе fill_exclusives() при помощи функции read_smart_terrain_conditions из скрипта smart_terrain.script В данном методе для считывания настроек читается spawn_ini () Например, что мешает в скриптах исправить это на system_ini() ? Тогда настройки можно считывать не из all.spawn, а из секции НПС, проспавненного скриптом!!! Так что, как написАл denis2000 - что пропишите в скриптах, то и будет делать движок. ПропИшите читать из custom_data, то так и будет. ПропИшите читать из секции - будет читать из секции.
Сообщение отредактировал makdm - Четверг, 24.03.2016, 20:55
_S_k_i_F_, в секции звука указан рандом, т.е. поигрывание одного из нескольких звуковых файлов. При работе скрипта обнаружилось, что нескольких файлов - просто нет. Отсюда и вылет.
Если передать всё содержимое инвентаря ГГ НПС, то при смерти, там будет только то что прописано в death_*.ltx Возможно ли, не правя конфиги получит весь хабар обратно, как из inventory_box.
Какой ф-ей можно получить визуал нпс? И какой назначить?
denis2000, что-то я совсем запутался. Привел биндер к этому виду. Все сохраняется, но при перезагрузке опять же нельзя юзать труп. И насчет self.item и self.item_count не понял. Куда именно их писать?
function bind(obj) printf("_bp: monster.bind: name='%s', id='%d'", obj:name(), obj:id())
-- Для спауна --xr_spawner.spawn_client(obj)
local new_binder = generic_object_binder(obj) obj:bind_object(new_binder) end
local last_update = 0 -- combat ------------------------------------------------------------------------------------ class "generic_object_binder" (object_binder)
function generic_object_binder:__init(obj) super(obj) self.loaded = false end
function generic_object_binder:reload(section) object_binder.reload(self, section) end
function generic_object_binder:reinit() object_binder.reinit(self)
function generic_object_binder:update(delta) object_binder.update(self, delta)
local npc = self.object local npc_st = db.storage[npc:id()] local invulnerability = utils.cfg_get_string(npc_st.ini, npc_st.active_section, "invulnerable", npc, false, "", nil) if invulnerability ~= nil then local condlist = xr_logic.parse_condlist(npc, npc_st.active_section, "invulnerable", invulnerability) local invulner = xr_logic.pick_section_from_condlist(db.actor, npc, condlist) == "true" if npc:invulnerable() ~= invulner then npc:invulnerable(invulner) end end
if xr_combat_ignore.fighting_with_actor_npcs[self.object:id()] and self.object:best_enemy() == nil then xr_combat_ignore.fighting_with_actor_npcs[self.object:id()] = nil end
local squad = get_object_squad(self.object) local object_alive = self.object:alive() --' printf("_bp: generic_object_binder: UPDATE [name='%s' time=%d]", --' self.object:name(), time_global())
if not object_alive then return end
self.object:set_tip_text("") local st = db.storage[self.object:id()] if st ~= nil and st.active_scheme ~= nil then xr_logic.try_switch_to_another_section(self.object, st[st.active_scheme], db.actor) end -- Апдейт отряда if squad ~= nil then if squad:commander_id() == self.object:id() then squad:update() end end
self.object:info_clear()
local active_section = db.storage[self.object:id()] and db.storage[self.object:id()].active_section if active_section then self.object:info_add("section: " .. active_section) end local best_enemy = self.object:best_enemy() if best_enemy then self.object:info_add("enemy: " .. best_enemy:name()) end self.object:info_add(self.object:name().." ["..self.object:team().."]["..self.object:squad().."]["..self.object:group().."]")
if alife():object(self.object:id()) == nil then return end
if squad ~= nil then self.object:info_add("squad_id: " .. squad:section_name()) if squad.current_action ~= nil then local target = squad.assigned_target_id and alife():object(squad.assigned_target_id) and alife():object(squad.assigned_target_id):name() self.object:info_add("current_action: " .. squad.current_action.name .."["..tostring(target).."]") end end
-- Если есть враг , то идем в комбат !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if self.object:get_enemy() then if xr_logic.mob_captured(self.object) then xr_logic.mob_release(self.object) end return end
if squad and squad.current_action and squad.current_action.name == "reach_target" then local squad_target = simulation_objects.get_sim_obj_registry().objects[squad.assigned_target_id] if squad_target == nil then return end -- printf("_bp: mob_reach_task:reset_scheme: %s", self.object:name())
local target_pos, target_lv_id, target_gv_id = squad_target:get_location() -- if not xr_logic.mob_captured(self.object) then xr_logic.mob_capture(self.object, true) -- end if squad:commander_id() == self.object:id() then action(self.object, move(move.walk_with_leader, target_pos), cond(cond.move_end)) else local commander_pos = alife():object(squad:commander_id()).position if commander_pos:distance_to(self.object:position()) > 10 then action(self.object, move(move.run_with_leader, target_pos), cond(cond.move_end)) else action(self.object, move(move.walk_with_leader, target_pos), cond(cond.move_end)) end end return end
if self.st.active_section ~= nil then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "update", delta) end end
function generic_object_binder:extrapolate_callback() -- Проверяем, что объект еще в онлайне if db.storage[self.object:id()] == nil or db.storage[self.object:id()].object == nil then return end
local cur_pt = self.object:get_current_point_index() if self.object:get_script() == false then return false end
local patrol_path = self.object:patrol() if not level.patrol_path_exists(patrol_path) then return false --abort("bind_monster:extrapolate_callback(). There is no patrol path [%s]", tostring(patrol_path)) end if patrol(patrol_path):flags(cur_pt):get() == 0 then --printf("_bp: generic_object_binder: extrapolate_callback: cur_pt = %d: true", cur_pt) return true end --printf("_bp: generic_object_binder: extrapolate_callback: cur_pt = %d: false", cur_pt) return false end
function generic_object_binder:waypoint_callback(obj, action_type, index) if self.st.active_section ~= nil then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "waypoint_callback", obj, action_type, index) end end
function generic_object_binder:death_callback(victim, who) printf("stop_dead_id"..self.object:id())
self:hit_callback(victim, 1, vector():set(0,0,0), who, "from_death_callback") if who:id() == db.actor:id() then xr_statistic.inc_killed_monsters_counter() xr_statistic.set_best_monster(self.object) end
if self.st.mob_death then xr_logic.issue_event(self.object, self.st.mob_death, "death_callback", victim, who) end
if self.st.active_section then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "death_callback", victim, who) end --' Наносим небольшой импульс вперед. local h = hit() h.draftsman = self.object h.type = hit.fire_wound h.direction = db.actor:position():sub(self.object:position()) h:bone("pelvis") h.power = 1 h.impulse = 10 self.object:hit(h)
local obj_clsid = self.object:clsid() if obj_clsid == clsid.poltergeist_s then printf("releasing object ["..self.object:name().."]") if alife():object(self.object:id()) ~= nil then alife():release(alife():object(self.object:id()), true) end end self:exist_use() end
function generic_object_binder:exist_use() local ini = system_ini() if ini:line_exist(self.object:section(), "Spawn_Inventory_Item_Section") then local conf = ini:r_string(self.object:section(), "Spawn_Inventory_Item_Section") local items = {} for s in string.gfind(conf, "%s*([^,]+)%s*") do table.insert(items, s) end self.item = items[1] if self.item and system_ini():section_exist(self.item) then self.item_count = tonumber(items[2]) or 1 self:set_use(ini) end end end
function generic_object_binder:set_use(ini) local character_use = (ini:r_string(self.object:section(), "character_use")) or "monstr_character_use" self.object:set_tip_text(character_use) self.object:set_callback(callback.use_object, self.on_use, self) self.sound_use = sound_object("material\\dead-body\\collide\\hithard0"..tostring(math.random(1, 6)).."hl") if not self.use and self.use ~= nil then self.use = true end if self.use == true then self.object:set_tip_text(character_use) self.object:set_callback(callback.use_object, self.on_use, self) self.sound_use = sound_object("material\\dead-body\\collide\\hithard0"..tostring(math.random(1, 6)).."hl") end end
function generic_object_binder:on_use(obj, who) local active_slot = db.actor:active_slot() and db.actor:active_slot() == 1 if not active_slot then return end for i=1, self.item_count do alife():create(self.item, who:position(), who:level_vertex_id(), who:game_vertex_id(), who:id()) end self.object:set_callback(callback.use_object, nil) self.object:set_tip_text("") self.use = false local ini = system_ini() local h = hit() h.draftsman = self.object h.type = hit.fire_wound h.direction = vector():set(0,1,0) h:bone( (ini:r_string(self.object:section(), "bone_impuls_abscission")) or "bip01_spine" ) h.power = 1 h.impulse = ( (ini:r_u32(self.object:section(), "impuls_abscission")) or 100 ) self.object:hit(h) self.sound_use:play_at_pos(self.object, self.object:position(), sound_object.s3d) end
if(who:id()==db.actor:id()) then xr_statistic.set_best_weapon(amount) end
if self.st.hit then xr_logic.issue_event(self.object, self.st.hit, "hit_callback", obj, amount, local_direction, who, bone_index) end
if amount > 0 then printf("HIT_CALLBACK: %s amount=%s bone=%s who:id() = [%s] actor:id() = [%s]", obj:name(), amount, tostring(bone_index), who:id(), db.actor:id()) end end
function generic_object_binder:hear_callback(self, who_id, sound_type, sound_position, sound_power) if who_id == self:id() then return end xr_hear.hear_callback(self, who_id, sound_type, sound_position, sound_power) end
function generic_object_binder:net_spawn(sobject) if not object_binder.net_spawn(self, sobject) then return false end
local on_offline_condlist = db.storage[self.object:id()] and db.storage[self.object:id()].overrides and db.storage[self.object:id()].overrides.on_offline_condlist if on_offline_condlist ~= nil then xr_logic.pick_section_from_condlist(db.actor, self.object, on_offline_condlist) end
if not self.object:alive() then return true end if alife():object(self.object:id()) == nil then return false end
--******************************* Телепорт на первую точку пути работы смарттеррейна...***************************** local se_obj = alife():object(self.object:id()) if db.spawned_vertex_by_id[se_obj.id] ~= nil then self.object:set_npc_position(level.vertex_position(db.spawned_vertex_by_id[se_obj.id])) db.spawned_vertex_by_id[se_obj.id] = nil elseif db.offline_objects[se_obj.id] ~= nil and db.offline_objects[se_obj.id].level_vertex_id ~= nil then printf("changing position for object[%s] from %s to %s : level vertex [%s] to [%s]", se_obj:name(), vec_to_str(se_obj.position), vec_to_str(level.vertex_position(db.offline_objects[se_obj.id].level_vertex_id)), tostring(se_obj.m_level_vertex_id), tostring(db.offline_objects[se_obj.id].level_vertex_id)) self.object:set_npc_position(level.vertex_position(db.offline_objects[se_obj.id].level_vertex_id)) elseif se_obj.m_smart_terrain_id ~= 65535 then local smart_terrain = alife():object(se_obj.m_smart_terrain_id) if smart_terrain.arriving_npc[se_obj.id] == nil then local smart_task = smart_terrain.job_data[smart_terrain.npc_info[se_obj.id].job_id].alife_task self.object:set_npc_position(smart_task:position()) end end --******************************************************************************************************************
local st = db.storage[self.object:id()] if st and st.active_scheme then xr_logic.issue_event(self.object, st[st.active_scheme], "net_destroy") end
-- Запоминаем позицию и активную секцию -------- if db.offline_objects[self.object:id()] then db.offline_objects[self.object:id()].level_vertex_id = self.object:level_vertex_id() db.offline_objects[self.object:id()].active_section = db.storage[self.object:id()].active_section end ------------------------------------------------n
db.del_obj(self.object) db.storage[self.object:id()] = nil object_binder.net_destroy(self) end
function generic_object_binder:reload(section) object_binder.reload(self, section) --printf("generic_object_binder:reload(): self.object:name()='%s'", self.object:name()) end
function generic_object_binder:net_save_relevant() --printf("generic_object_binder:net_save_relevant(): self.object:name()='%s'", self.object:name()) return true end
function generic_object_binder:save(packet) packet:w_bool(self.use) set_save_marker(packet, "save", false, "generic_object_binder") object_binder.save(self, packet) xr_logic.save_obj(self.object, packet) set_save_marker(packet, "save", true, "generic_object_binder") end
Добро. ЗП. Можно ли игроку запретить использовать КПК скриптом? А спустя необходимое время снова разрешить использование КПК? И тольк не функцией disable_ui
Разве? Тогда почему конструкция типа:Код[smart_terrains]none = trueприспокойно читается из кастом даты?
Если скриптово - не читается, пробовал не раз, и по-всякому. если есть способ, о котором я не знаю, был бы рад примеру. На АМк мне другой способ подсказали: прописать в секции моба/НПС ссылку на файл кастом_даты, где указать секцию [smart_terrains], и все заработало.