Если у вас появились вопросы по модостроению в игре S.T.A.L.K.E.R. Задавайте их в этой теме - умные головы, модосторители и просто разбирающиеся в программировании люди вам ответят.
Сборник модостроения ЗП v10.10.11 (автор: XOBAH): *.CHM, *.HTML [cut noguest=Если у вас не открывается файл CHM]Если у вас не открывается файл: 1. Запустите [Пуск]=>[Выполнить] (либо хот-кей [WIN]+[R]) 2. Введите команду (без кавычек) "regsvr32 %windir%\system32\hhctrl.ocx" 3. Если вылезло окно об успешном завершении вы все сделали правильно и можете перезагружать компьютер (а может и не надо) Также: файлы МОГУТ не открываться если в пути к файлу есть: символы кириллицы, "_", "#" Также: есть не стандартные программы-просмоторщики CHM файлов. Например: FBReader[/cut] [cut=Где найти лог игры после вылета]Что такое LOG ошибки, и как мне его найти? Это система отладки происходивших вылетов, которая подается игрой в форме текста, хотя не всегда. Для того чтоб найти LOG необходимо зайти вот сюда:
В Win хр лог находится:
C:\Documents and Settings\All Users\Документы\S.T.A.L.K.E.R. - Зов Припяти\logs
Затем открываете первый файл в формате TXT, и в нем отбираете с низу 25 строчек. После кидаете эти 25 строчек в сообщение на форум.
В Win7 лог находится C:\Users\Public\Documents\S.T.A.L.K.E.R. - Зов Припяти\logs
Путь к папке с логом можно найти открыв файл fsgame.ltx который находится в корневой директории ЗП, за это отвечает строка: ... $app_data_root$ = true | false| $fs_root$| users\(тут мы указываем что папка пользователя, будет хранится рядом с Fsgame.ltx) ... $logs$ = true| false| $app_data_root$| logs\(а тут мы указываем что в папке пользователя, в подпапке Logs будут храниться наши логи) ... [/cut][cut=Получение более подробной информации о вылете (ХОВАН)] Открываем файл _g.script и ищем такую функцию: function abort(fmt, ...) Там есть заккомментированная строчка "--error_log(reason)", ее и надо расскомментировать, должно получиться вот так:
Код
function abort(fmt, ...) local reason = string.format(fmt, ...) error_log(reason) end
Вот для примера два одинаковых вылета, первый с функцией по умолчанию, второй - с поправленной функцией
Первый:
Код
Expression : !m_error_code Function : raii_guard::~raii_guard File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp Line : 748 Description : ....a.l.k.e.r. - Зов Припяти\gamedata\scripts\_g.script:478: bad argument #2 to 'format' (string expected, got nil)
Второй:
Код
Expression : 0 Function : ErrorLog File : D:\prog_repository\sources\trunk\xrServerEntities\script_engine_script.cpp Line : 49 Description : 'Attempt to read a non-existant string field 'path_walk' in section 'walker@mechanic'
[/cut]
Перед тем, как задать вопрос в этой теме, прочтите все предыдущие страницы, статьи в wiki по ссылке из шапки и соседнюю тему "Курс молодого бойца", возможно Ваш вопрос уже рассматривался.
Если произошел вылет - выкладываем лог! Вопрос ставим четко, не забываем указывать версию игры, установленные моды их версии, установленные фиксы модов и подробно ваши правки. Помните чем подробнее вопрос, тем точнее ответ.
Посты, для которых есть свои категории, из этой темы будут удаляться или перемещаться в соответсвующую тему. Персональных извещений в ЛС о переносе\удалении поста не будет, ищите сами. Учитывайте, что в системах Ucoz тема не обновляется в статистике при переносе поста. Посты, написанные здесь-же после переноса, будут расцениваться как кросспостинг, со всеми вытекающими
[cut noguest=Первый юбилей нашей темы]
Здравствуйте господа модостроители, и все так или иначе причастные к этому. Нашей теме исполнился 1 год. От души поздравляю Всех Вас дорогие друзья, творческих успехов. Хочу так же выразить отдельную благодарность denis2000 и ХОВАН.
tracker 23.06.11
[/cut]
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение:
Можно как-то в ЗП сделать чтобы аномалии реагировали на нпс?
Это реализовано во многих модах, в частности в "Припять. Точка отсчета". Если не дружите со скриптами, то даже не пытайтесь. "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение:
Это реализовано во многих модах, в частности в "Припять. Точка отсчета". Если не дружите со скриптами, то даже не пытайтесь.
Жаль, надеялся, что дело затронет лишь конфигурации. Не подскажите ещё один момент? Пытаюсь добавить в солянку "Мясник-мод". Мод содержит части собак, псевдособак, снорков, кабанов, кровососов и плотей, вот только там нет руки бюрера, которую-бы очень хотелось видеть в игре. В некоторых файлах мода она прописана. Файловая структура такова:
Код
*configs\creatures\m_*имя мутанта*; Конфиг для каждого мутанта на снятие части *configs\misc\monster_items; Прописанные части мутантов *configs\text\rus\string_table_enc_mutants; Названия и описания частей *configs\localization; Скрипт-ссылка на вышеуказанный файл *configs\system; Инклуд (включение) в файл "misc\monster_items.ltx" *meshes\dynamics\equipments\item_*имя части*; Игровая модель выброшенного предмета *scripts\bind_monster; Скрипт коллбека убитого монстра на спавн и снятие части *textures\ui\ui_icon_equipment; Иконки в рюкзаке
Я постарался добавить руку бюрера её во все необходимые файлы:
Код
*configs\creatures\m_burer; Прописал снятие на основе других мутантов, всё готово. *configs\misc\monster_items; Итем руки бюрера был прописан создателем мода. *configs\text\rus\string_table_enc_mutants; Добавил описание предмета и название. *configs\localization; Изменения не нужны *configs\system; Тоже не нужны *meshes\dynamics\equipments\item_burer_hand; Добавил 3D модель. *scripts\bind_monster; Изменения не требуются, коллбек универсален для всех мутантов. *textures\ui\ui_icon_equipment; Иконка добавлена создателем мясника
После всех попыток добавления руки при нажатии на убитого бюрера ничего не происходит, хотя во всех недостающих файлах я её добавил. С других матантов части снимаются. Итем руки mutant_burer_hand прописан без ошибок. В чём может быть проблема?
Эти 0 пользователя(ей) поблагодарили =Stalker123= за это полезное сообщение:
=Stalker123=, Приведите файлы configs\creatures\m_burer и scripts\bind_monster. "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение:
;---------------------------------------------------------------------------- ph_skeleton_airr_lin_factor = 2.0 ;550.0 (изменно из-за того, что убрано домножение коэффициент 0.002 из кода) ph_skeleton_airr_ang_factor = 0.0 ;0.0 (изменно из-за того, что убрано домножение на коэффициент 0.3 из кода (0.0*0.3=0.0)) ph_skeleton_hinger_factor1 = 1.0 ;1.0 (изменно из-за того, что убрано домножение на коэффициент 5.0 из кода) ph_skeleton_ddelay = 15.0 ;Время изменения значения трения в суставе с момента создания шелла, сек
satiety_v = 0.0001 ;скорость уменьшения сытости со временем radiation_v = 0.00001 ;скорость уменьшения радиации satiety_power_v = 0.001 ;увеличение силы при уменьшении сытости satiety_health_v = 0.00007 ;увеличение здоровья при уменьшении сытости satiety_critical = -1.0 ;критическое значения сытости (в процентах от 0..1) когда здоровье начианает уменьшаться radiation_health_v = 0.01 ;уменьшение здоровья при воздействии радиации morale_v = 0.01 ;скорость восстановления морали health_hit_part = 0.5 ;процент хита, уходящий на отнимание здоровья power_hit_part = 1.0 ;процент хита, уходящий на отнимание силы psy_health_v = 0.1 ;скорость восстановления psy-здоровья
;открытые раны bleeding_v = 0.05 ;потеря крови при номинальной ране в секунду wound_incarnation_v = 0.04 ;крутизна кривой заживления (какой процент раны останется после заживления в игровую секунду) min_wound_size = 0.01
sleep_health = 1.0 ;1.5 ;коэффициенты скоростей изменения параметров во время сна sleep_power = 1.0 ;1.5 sleep_satiety = 1.0 ;0.8 sleep_radiation = 1.0 ;1.1 sleep_psy_health = 1.0
eat_freq = 5.0 ; частота укусов в сек eat_slice = 0.01 ; увеличение сытости при 1 укусе eat_slice_weight = 10.0 ; уменьшение еды у трупа
bone_head = head ; bone name
DayTime_Begin = 20 ; начала дня для монстра DayTime_End = 6 ; конец дня для монстра Min_Satiety = 0.6 ; мин. норма сытости (меньше - уже голодный) Max_Satiety = 0.9 ; макс. норма сытости (больше - очень сытый)
satiety_threshold = 0.5 ; below this value monster fill hunger ;--------------------------------------------------------- ; Sounds and sound parameters ;---------------------------------------------------------
cform = skeleton ; collision class class = SM_BURER ; AI class
script_binding = bind_monster.bind
bone_torso = chest ; bone name bone_head = head ; bone name bone_fire = head ; bone name weapon_usage = 0 ; boolean actor_restrictor = medium_monster ;medium_monster,stalker,none
distance_to_corpse = 1.2 ; дист. до трупа, при которой он переходит в состояние еды
[burer_vision_free] min_view_distance = 0.6 ; коэффициент, который множится на eye_range, в зависимости от угла max_view_distance = 1.0 ; коэффициент, который множится на eye_range, в зависимости от угла visibility_threshold = 100.0 ; значение, при достижении суммой которого объект считается видимым always_visible_distance = 0.3 time_quant = 0.001 decrease_value = 0.01 ; значение, на которое уменьшается вес, если объект попал в фрустум, но отсёкся по каким-то причинам velocity_factor = 0.5 luminocity_factor = 0.5 ; фактор освещения (только для Актёра) transparency_threshold = 0.25
[burer_vision_danger] min_view_distance = 0.6 ; коэффициент, который множится на eye_range, в зависимости от угла max_view_distance = 1.0 ; коэффициент, который множится на eye_range, в зависимости от угла visibility_threshold = 100.0 ; значение, при достижении суммой которого объект считается видимым always_visible_distance = 0.3 time_quant = 0.001 decrease_value = 0.01 ; значение, на которое уменьшается вес, если объект попал в фрустум, но отсёкся по каким-то причинам velocity_factor = 0.5 luminocity_factor = 0.5 ; фактор освещения (только для Актёра) transparency_threshold = 0.25
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 ------ use -------- self.use = 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)
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 then self.use = true end end
function generic_object_binder:on_use(obj, who) --// спавним в инвентарь юзающего, части монстра 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)
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") --------- use ----------- packet:w_bool(self.use) ------------------------- end
function generic_object_binder:load(reader) self.loaded = true set_save_marker(reader, "load", false, "generic_object_binder") object_binder.load(self, reader) xr_logic.load_obj(self.object, reader) set_save_marker(reader, "load", true, "generic_object_binder") ---------- use ----------- self.use = reader:r_bool() if self.use then self:exist_use() end ------------------------- end
Эти 0 пользователя(ей) поблагодарили =Stalker123= за это полезное сообщение:
=Stalker123=, Надпись на монстре перед использованием есть? Spawn_Inventory_Item_Probability отличное от 0 ставили? "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение:
Сделайте в конфиге строку в таком виде: Spawn_Inventory_Item_Section = mutant_burer_hand Или пробуйте пробел перед цифрой: Spawn_Inventory_Item_Section = mutant_burer_hand, 2 "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение:
=Stalker123=, Могу сказать одно, условие из скрипта:
Код
if self.item and system_ini():section_exist(self.item) then
не выполняется. Или в таблицу в принципе ничего не попадает или секции с именем которое содержит переменная self.item нет в конфиге. Поэтому нет текстовой подсказки на Бюрере нет колбека на объект при юзанье. "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение:
В Зове Припяти бандиты не водят игрока по локации. Это проверяет функция uni_traveler_precond в travel_manager.
Код проверки.
if npc:character_community() == "bandit" then return false end
В СГМ много несквадовых НПС. Базы бандитов, наемников, Рассвета и т.д. Если подойти к такому НПС и спросить "Чем занимаешься" - инициируем травел-диалог, то получим вылет из-за того, что непись несквадовый.
Вопрос такой. Как проверить, сквадовый НПС или нет?
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение:
Здравствуйте. Не подскажите, реально ли сделать цену продажи предмета торговцем более 1.000.000? В конфиге предмета ставлю цену (costs) допустим 3.000.000, но торговец всё равно дороже 1.000.000 не продаёт. Я один, но это не значит, что я одинок... _________________________________ В.Цой
Эти 0 пользователя(ей) поблагодарили ZmeеY за это полезное сообщение:
ZmeеY, Вероятнее всего - нет, уткнулись в ограничения переменных движка. Кстати даже если у НПС бесконечные деньги то более 1000000 он тоже не заплатит (не хватит "бесконечных" денег). "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение:
=Stalker123=, Могу сказать одно, условие из скрипта: Код if self.item and system_ini():section_exist(self.item) then
не выполняется. Или в таблицу в принципе ничего не попадает или секции с именем которое содержит переменная self.item нет в конфиге. Поэтому нет текстовой подсказки на Бюрере нет колбека на объект при юзанье.
Хорошо, спасибо за помощь в этом деле. Буду пытаться сделать что-то толковое.
Эти 0 пользователя(ей) поблагодарили =Stalker123= за это полезное сообщение:
[error]Expression : !m_error_code [error]Function : raii_guard::~raii_guard [error]File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp [error]Line : 748 [error]Description : ...g\Зов Припяти\gamedata\scripts\travel_manager.script:88: attempt to index local 'squad' (a nil value)
stack trace:[/cut]
Вылет получаю при любой попытке разговора с несквадовым сталкером с дефолтными диалогами.
[cut=Глючная функция]function uni_traveler_precond(actor, npc) local squad = get_object_squad(npc) local new_target = xr_logic.pick_section_from_condlist(db.actor, squad, squad.action_condlist) --88строка if new_target ~= nil and new_target ~= "nil" then return false end if squad ~= nil and squad:commander_id() ~= npc:id() then return false end if npc:character_community() == "bandit" then return false end if level.name() == "jupiter_underground" then return false end if npc:character_community() == "army" then return false end local smart = xr_gulag.get_npc_smart(npc) if (smart) then if smart:name() == "jup_b41" then return false end end return true end[/cut]
Фрагмент кода
local new_target = xr_logic.pick_section_from_condlist(db.actor, squad, squad.action_condlist) if new_target ~= nil and new_target ~= "nil" then return false end
был добавлен по совету Дмитрия (makdm). Подробности тут. Для сквадовых сталкеров он работает отлично.
Если этот код убрать (закоментировать), то диалоги становятся доступными. Но при инициации травел-диалога (Чем сейчас занимаешься?) получаю другой вылет.
[cut=Лог]FATAL ERROR
[error]Expression : !m_error_code [error]Function : raii_guard::~raii_guard [error]File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp [error]Line : 748 [error]Description : ...g\Зов Припяти\gamedata\scripts\travel_manager.script:184: attempt to index local 'npc_squad' (a nil value)
stack trace:[/cut]
[cut=Функция]function squad_action_description(actor, npc, dialog_id, phrase_id) local npc_squad = get_object_squad(npc) if npc_squad.current_action == nil or npc_squad.current_action.name == "stay_point" then --184 строка return "dm_" .. "stalker" .."_doing_nothing_"..tostring(math.random(1,3)) --npc:character_community() end local target_id = npc_squad.assigned_target_id -- if target_id == nil then -- return "dm_" .. npc:character_community() .."_doing_nothing" -- end local target_obj = alife():object(target_id) if target_obj == nil then abort("SIM TARGET NOT EXIST %s, action_name %s", tostring(target_id), tostring(npc_squad.current_action.name)) end local target_clsid = target_obj:clsid() if target_clsid == clsid.script_actor then abort("Actor talking with squad, which chasing actor") elseif target_clsid == clsid.online_offline_group_s then return "dm_" .. "stalker" .."_chasing_squad_"..alife_character_community(target_obj) --npc:character_community() elseif target_clsid == clsid.smart_terrain then local smart_name = target_obj:name() local travel_class = get_travel_class() local desc = travel_class.smart_to_stringtables[smart_name] if desc == nil then abort("wrong smart name [%s] in travel_manager.ltx", tostring(smart_name)) end return desc end abort("wrong target clsid [%s]", tostring(target_clsid)) end[/cut]
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: