#Speed Hunter :
у меня вопрос связанный с sound editor - я делаю все по правилам,как написано в инструкции здесь ,но вместо ogg файла у меня получается 2 файла - wav и thm. я пробовал вставить файл thm в игру вместе со звуком ogg(я его конвертером сделал). Вроде бы коммент работает,но как его не редактируй,звук не изменяет своих свойств.Подскажите,как сделать так,чтобы sound editor выдавал мне обычный ogg файл.
P.S.если кто-то ничего не понял из моего сумбурного рассказа,стукните плз в пм я объясню проблему в деталях.
C:\Program Files\X-Ray ___ sdK\editors\gamedata\sounds --- Там будет находиться твой готовый фийл.
У меня вопрос по Повелителю зоны.
Когда я открываю раздел мутантов и пытаюсь заспавнить химеру или зомби то следует стабильный вылет. Чего делать с ним?
Люди, не подскажите, можно как - нибудь отключить долбанный периодически повторяющийся квест на агропроме, когда нужно защитить задний выход базы сталкеров. Ну честно говоря уже достало это задание. Я бы его просто не выполнял, но бандиты торговца сталкеров умудряются грохнуть. Если его нельзя отключить, то хотя бы сделать так, чтоб он появлялся через очень-очень длительное время.
Также буду признателен, если подскажите, как торговца сталкеров на агропроме сделать неубиваемым, но это уже накрайняк, если скрипт не получится отрубить.
С точки зрения банальной эрудиции, не каждый локальный индивидуум вправе игнорировать тенденции своих парадоксальных эмоций.
HammerSledge если, уж так нужен агропромский торгаш у сталкеров(который хуже чем у чн) то регулярно убивай бандитов.(хотя долговского всегда должно хватать). и вообще странно как 5 бандитов умудряются снести сталкерскую базу(ведь в чн они плоховато сделаны).
добавлено спустя 1 час 30 минут
Super-Bandit Old Good Stalker Mod.
отредактировал(а) bandит: 17-08-2011 16:46 GMT3 час.
bandит в том то и дело, что бандюки у меня стабильно выносят сталкеров у заднего выхода, и перемещаются на площадь, где через окно умудряются вальнуть торгоша. Правда далеко не всегда, но обезопасить себя надо бы. Да и я хоть OGSM мод юзаю, но торгашей переделал так, чтобы у всех был бы в наличие весь их асоортимент, но по ценам, по которым хорошую вещь далеко не сразу купишь. Кроме того, асортимент у всех торговцев сделал свой, чтобы не повторялся. Ну как бы не хотеловь менять эту концепцию просто. Можно шмотки которые этот торговец продает распихать по другим, но уже имхо не так атмосферно, да и боюсь ошибки попрут в игре из-за убийства одного из ключевых неписей.
А в скриптах я как свинья в апельсинах разбираюсь. Интуитивно пробовал отключить, но вроде пока нужный скрипт не нашел.
С точки зрения банальной эрудиции, не каждый локальный индивидуум вправе игнорировать тенденции своих парадоксальных эмоций.
HammerSledge у меня тоже бандиты выносили задних. правда сталкерам я не помогал, т.к. у меня бандиты всегда оставались на задней точке, а их потом сталкеры мочили.
но если хочешь, переодень его в экзоскелет и всё. правда рано или поздно его всё равно грохнут.
а ошибки не попрут, не переживай.
пацаны такой вопрос с инета скачал мод для чн кровь и пуля и появилась проблемка на болотах на некоторых точках как рыбацкий,северный,южный хутор и 2 форпост просто всё белое и нечего не видно ни врагов ни друзей эт мод косячный или несовместимость с компом
Камрады !!! Остро нуждаюсь в помощи ! Мне необходимо перенести ствол с Теней Чернобыля в Чистое Небо. Кто может, и желает, мне помочь, хоть файлом, хоть ссылкой, хоть дельным советом - отзовитесь.
Люди прошу помогите, очень хочу нормальный АПС Стечкина, что бы был Авто. и качественный,
Было дело качал OGSM Mod искал искал АПС, в итоге нашел, и ** он не Авто был, да и текстуры фигня,
Дайте ссылочку на мод, не важно Глобальный мод или только на АПС, главное что бы хороший, и вообще был,
Заранее Спасибо
bandит Да не очень то я и странный. Просто я терпеть не могу МР 5 из Сталкеров всех частей, ну уроды просто, никакого обвеса поставить нельзя, хотя МР 5 в жизни - это прекраснейший грунт для всяких там коллиматоров, глушаков, ЛЦУ, складных прикладов и прочих подобных вкусностей.
Короче, нашёл модельку которая ну очень мне нра, но она под ТЧ, а мне прёт ЧН. Я начал изучать модостроительство, а тут такой облом, мол на ЧН другая метода установки новых стволов.Везде об этом упоминаеться, но конкретно по сути не сказано не слова.
Ну вот я и спрашиваю ... .
Есть секретная дверь на Лиманске...Там где много трупов долга и свободы.Там справа есть лестница и идёшь под неё среляешь в дверь и она открывается...и так доконца идёшь и там кирпичная дверь,как её открыть?Мне говорил друг что надо стрелять в тот генератор ,но он не открывает дверь!
порядок вызова методов биндера:
reload
reinit
load
net_spawn
--------------------------------------------------------------------------------------------------------------------]]
memtsg = {} --' временная таблица
lasthealth = 0
lastime = nil
local bloodsuckers_restr = {}
bloodsucker_zone_enter = {}
----------------------------------------------------------------------------------------------------------------------
class "motivator_binder" (object_binder)
function motivator_binder:extrapolate_callback(cur_pt)
if self.st.active_section then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "extrapolate_callback")
self.st.move_mgr:extrapolate_callback(self.object)
end
if patrol(self.object:patrol()):flags(cur_pt):get() == 0 then
return true
end
return false
end
function motivator_binder:reinit()
object_binder.reinit(self)
--memusage.collect_info(self.object, "reinit_start")
--printf("motivator_binder:reinit(): self.object:name()='%s'", self.object:name())
-- КОЛЛБЕКИ ЗДЕСЬ СТАВИТЬ НЕЛЬЗЯ! Здесь еще неизвестна активная схема.
-- Ставьте коллбеки в методе update в отмеченном комментарием месте.
local char_ini = self.object:spawn_ini() or ini_file("scripts\\dummy.ltx")
--' Создание менеджера контроля положений тела
--memusage.collect_info(self.object, "before_statemgr")
self.st.state_mgr = state_mgr.bind_manager(self.object)
--memusage.collect_info(self.object, "after_statemgr")
--memusage.collect_info(self.object, "reinit_end")
end
----------------------------------------------------------------------------------------------------------------------
function motivator_binder:net_spawn(sobject)
printf("motivator_binder:net_spawn(): self.object:name()='%s'", self.object:name())
local ppos = self.object:position()
--printf("position [%s][%s][%s]", ppos.x, ppos.y, ppos.z)
xrs_dyn_music.npc_table[self.object:id()] = self.object
--memusage.collect_info(self.object, "netspawn_start")
if not object_binder.net_spawn(self, sobject) then
return false
end
-- if self.object:spawn_ini():section_exist("dont_spawn_online") then
-- printf("!!!OFFLINE")
-- alife():object(self.object:id()).dont_spawn_online = true
-- end
--' Загрузка историй для лагеря.
if self.loaded == false then
local char_ini = ""
local spawn_ini = self.object:spawn_ini()
local filename = nil
if spawn_ini then
filename = utils.cfg_get_string(spawn_ini, "logic", "cfg", self.object, false, "")
printf("filename is [%s]", tostring(filename))
end
if filename ~= nil then
char_ini = ini_file(filename)
else
char_ini = self.object:spawn_ini() or ini_file("scripts\\dummy.ltx")
end
printf("xr_info loaded!!!")
xr_info.loadInfo(self.object, char_ini)
end
if not self.object:alive() then
return true
end
-- setting npc relation and sympathy from storage
local relation = db.goodwill.relations and db.goodwill.relations[self.object:id()]
if relation ~= nil and db.actor then
game_relations.set_npcs_relation(self.object, db.actor, relation)
end
local sympathy = db.goodwill.sympathy and db.goodwill.sympathy[self.object:id()]
if sympathy ~= nil then
game_relations.set_npc_sympathy(self.object, sympathy)
end
game_relations.set_level_faction_community(self.object)
db.add_enemy( self.object )
self.e_index = db.heli_enemy_count - 1
--' Для зомбированных чуваков говорим что аномалий не существует
-- if self.object:character_community() == "zombied" then
local manager = self.object:motivation_action_manager()
manager:remove_evaluator (stalker_ids.property_anomaly)
manager:add_evaluator (stalker_ids.property_anomaly, property_evaluator_const(false))
-- end
xr_smartcover.init_global_evaluators(self.object)
smart_terrain.setup_gulag_and_logic_on_spawn(self.object, self.st, sobject, modules.stype_stalker, self.loaded)
--' грузим универсальную реакцию на болотную тварь
bloodsucker_reaction.add_bloodsucker_reactions(self.object)
--' грузим универсальную реакцию на актёра вышедшего из левелчейнджера
actor_reaction.add_actor_reactions(self.object)
--' Универсальный тормоз на выход из комбата
if self.object:character_community() ~= "zombied" then
post_combat_idle.add_post_combat_idle(self.object)
end
self.object:group_throw_time_interval(2000)
if self.object:profile_name() == "stc_strelok" then
printf("strelok_health [true]")
stc_strelok_health_manager.cs_strelok_health(self.object)
end
return true
end
function motivator_binder:net_destroy()
if rx_ai then rx_ai.npc_switch_offline(self.object) end
--printf("motivator_binder:net_destroy(): self.object:name()='%s'", self.object:name())
xrs_dyn_music.npc_table[self.object:id()] = nil
xrs_dyn_music.stop_combat(self.object:id())
xr_sound.stop_sounds_by_id(self.object:id())
local st = db.storage[self.object:id()]
if st.active_scheme then
xr_logic.issue_event(self.object, st[st.active_scheme], "net_destroy", self.object)
end
db.del_obj(self.object)
db.storage[self.object:id()] = nil
self:clear_callbacks()
if self.e_index ~= nil then
db.delete_enemy( self.e_index )
end
if self.object:profile_name() == "stc_strelok" then
stc_strelok_health_manager.remove_health_bar()
end
object_binder.net_destroy(self)
end
function motivator_binder:clear_callbacks()
self.object:set_patrol_extrapolate_callback(nil)
self.object:set_callback(callback.hit, nil)
self.object:set_callback(callback.death, nil)
-- self.object:set_callback(callback.use_object, nil)
end
function motivator_binder:hit_callback(obj, amount, local_direction, who, bone_index)
callstack()
-- FIXME: коллбеки неплохо было бы регистрировать в общем storage, а не посхемно...
-- просто всегда ставить их при включении схемы и снимать при отключении.
if obj:profile_name() == "stc_strelok" then
stc_strelok_health_manager.hit_callback(obj, who, amount)
end
if self.st.active_section then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "hit_callback", obj, amount, local_direction, who, bone_index)
end
if self.st.combat_ignore then
xr_logic.issue_event(self.object, self.st.combat_ignore, "hit_callback", obj, amount, local_direction, who, bone_index)
end
if self.st.combat then
xr_logic.issue_event(self.object, self.st.combat, "hit_callback", obj, amount, local_direction, who, bone_index)
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", obj:name(), amount, tostring(bone_index))
sr_territory.issue_event(self.object, "hit_callback", obj, amount, local_direction, who, bone_index)
xr_wounded.hit_callback(self.object:id())
sim_combat.hit_callback(self.object:id(),who:id())
end
if rx_ai then rx_ai.npc_hit(obj,amount,local_direction,who,bone_index,self.object) end
end
function motivator_binder:death_callback(victim, who)
--' Distemper 03.2008 --
xrs_dyn_music.stop_combat(self.object:id())
--' Если игрок был с квестом от механика - фейлить его
local tm = task_manager.get_task_manager()
local inited_find_upgrade_tasks = tm.inited_find_upgrade_tasks
if inited_find_upgrade_tasks and inited_find_upgrade_tasks[self.object:id()] then
for k,v in pairs(inited_find_upgrade_tasks[self.object:id()]) do
printf("failing task %s status %s", tostring(v.id), tostring(v.status) )
if v.status == "selected" then
v.last_check_task = "fail"
end
end
end
local st = db.storage[self.object:id()]
local npc = self.object
stalker_generic.remove_level_spot(npc, st)
--' end --
if who:id() == db.actor:id() then
xr_statistic.addKillCount(self.object)
xr_statistic.inc_killed_stalkers_counter()
end
--' Загрузка историй для лагеря.
local known_info = utils.cfg_get_string(st.ini,st.section_logic , "known_info", self.object, false, "", nil)
printf("xr_info from death loaded!!!")
xr_info.loadInfo(self.object, st.ini, known_info)
if self.st.death then
xr_logic.issue_event(self.object, self.st.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
sr_territory.issue_event(self.object, "death_callback", victim, who)
self:clear_callbacks()
-- Отключаем реакцию на кровососа
bloodsucker_reaction.disable_bloodsucker_reaction(self.object)
--' Наносим небольшой импульс вперед.
if(actor_stats.remove_from_ranking~=nil)then
local community = self.object:character_community()
if community == "zombied" or
community == "monolith" or
community == "arena_enemy"
then
else
actor_stats.remove_from_ranking(self.object:id())
end
end
release_body_manager.get_release_body_manager():moving_dead_body(self.object) --' Distemper 11.02.2008
end
function motivator_binder:use_callback(obj, who)
printf("motivator_binder:use_callback(obj, who)")
if self.object:alive() then
inventory_upgrades.need_victim(obj) --' Distemper 03.2008
xr_use.notify_on_use(obj, who)
if self.st.active_section then
xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who)
end
else
if self.treasure_processed == false then
printf("treasure_manager.use(self.object)")
treasure_manager.use(self.object)
self.treasure_processed = true
end
end
end
function motivator_binder:update(delta)
object_binder.update(self, delta)
if bind_stalker.to_delayed_alife_release_objects[self.object:id()] == true then
printf("releasing object ["..self.object:name().."]")
alife():release(alife():object(self.object:id()),true)
return
end
local object_alive = self.object:alive()
local object = self.object
local actor = db.actor
local st = db.storage[object:id()]
local st_combat = st.combat
if not self.strelok_particles_added and object:profile_name() == "stc_strelok" then
object:start_particles("monsters\\polter_idle","bip01_head")
self.strelok_particles_added = true
end
if st ~= nil and st.active_scheme ~= nil and object_alive then
-- Обрабатываем Override on_combat
local switched = false
local manager = object:motivation_action_manager()
if manager:initialized() and manager:current_action_id() == stalker_ids.action_combat_planner then
local overrides = xr_logic.generic_scheme_overrides(object)
if overrides then
if overrides.on_combat then
xr_logic.pick_section_from_condlist(actor, object, overrides.on_combat.condlist)
end
if st_combat and st_combat.logic and not xr_logic.try_switch_to_another_section(object, st_combat, actor) then
if overrides.combat_type then
set_combat_type(object, actor, overrides)
end
else
switched = true
end
else
set_combat_type(object, actor, st_combat)
end
end
if not switched then
xr_logic.try_switch_to_another_section(object, st[st.active_scheme], actor)
end
else
-- если нет активной секции, то тип боя взять из секции on_combat
xr_combat.set_combat_type(object, actor, st_combat)
end
if self.first_update == false then
if object_alive == false then
death_manager.drop_manager(object):create_release_item()
end
self.first_update = true
end
if time_global() - self.last_update > 1000 then
sr_light.check_light(object)
self.last_update = time_global()
end
--' проверка, не находится ли сталкер в одном из sr_bloodsucker
for k,v in pairs(bloodsuckers_restr) do
if v:inside(object:position()) and object:alive() then
if bloodsucker_zone_enter[k] == nil then
-- printf("ZONE ENTERED")
bloodsucker_zone_enter[k] = object
end
else
if bloodsucker_zone_enter[k] ~= nil then
-- printf("ZONE ENTERED")
bloodsucker_zone_enter[k] = nil
end
end
end
--' Выбираем активный сектор для НПС
self.st.active_sector = sr_danger.select_active_sectors(object)
--' Апдейт менеджера состояний тела
if self.st.state_mgr then
if object_alive then
self.st.state_mgr:update()
-- Апдейт торговли
if self.st.state_mgr.combat == false and
self.st.state_mgr.alife == false
then
trade_manager.update(object)
end
else
self.st.state_mgr = nil
end
end
--' Апдейт саундменеджера
if object_alive then
xr_sound.update(object:id())
end
-- Апдейт отряда
local squad = db.storage[self.object:id()].squad_obj
if squad ~= nil then
if squad.commander_id == self.object:id() then
squad:update()
end
end
--[[
object:info_clear()
if object_alive then
--[[ local active_section = db.storage[object:id()].active_section
if active_section then
object:info_add("section: " .. active_section)
end
local best_enemy = object:best_enemy()
if best_enemy then
object:info_add("enemy: " .. best_enemy:name())
end
object:info_add(object:name().." ["..object:team().."]["..object:squad().."]["..object:group().."]")
if alife():object(object:id()) == nil then
return
end
local squad = db.storage[object:id()].squad_obj
if squad ~= nil then
object:info_add("squad_id: " .. squad.squad_id)
if squad.sim_combat_id ~= nil then
local smart = sim_board.get_sim_board().smarts[squad.sim_combat_id].smrt
local sim_combat = smart.combat_manager
object:info_add("sim_combat: stage[" .. sim_combat:get_squad_stage(squad).."]")
end
end
if object:is_talk_enabled() then
object:set_tip_text("character_use")
else
object:set_tip_text("")
end
else
object:set_tip_text_default()
end
if rx_ai then rx_ai.npc_update(self.object,self.st) end
end
function motivator_binder:reload(section)
--memusage.collect_info(self.object, "reload_start")
object_binder.reload(self, section)
--printf("motivator_binder:reload(): self.object:name()='%s'", self.object:name())
--self.object:set_pda_callback(pda_callback)
--memusage.collect_info(self.object, "reload_end")
end
function motivator_binder:net_save_relevant()
--printf("motivator_binder:net_save_relevant(): self.object:name()='%s'", self.object:name())
return true
end
function motivator_binder:save(packet)
set_save_marker(packet, "save", false, "motivator_binder")
object_binder.save(self, packet)
if self.object:profile_name() == "stc_strelok" then
stc_strelok_health_manager.save(packet)
end
packet:w_bool(self.treasure_processed)
function motivator_binder:hear_callback(self, who, sound_type, sound_position, sound_power)
if who:id() == self:id() then
return
end
local type = "NIL"
if bit_and(sound_type, snd_type.weapon) == snd_type.weapon then
type = "WPN"
if bit_and(sound_type, snd_type.weapon_shoot) == snd_type.weapon_shoot then
type = "WPN_shoot"
elseif bit_and(sound_type, snd_type.weapon_empty) == snd_type.weapon_empty then
type = "WPN_empty"
elseif bit_and(sound_type, snd_type.weapon_bullet_hit) == snd_type.weapon_bullet_hit then
type = "WPN_hit"
elseif bit_and(sound_type, snd_type.weapon_reload) == snd_type.weapon_reload then
type = "WPN_reload"
end
elseif bit_and(sound_type, snd_type.item) == snd_type.item then
type = "ITM"
if bit_and(sound_type, snd_type.item_pick_up) == snd_type.item_pick_up then
type = "ITM_pckup"
elseif bit_and(sound_type, snd_type.item_drop) == snd_type.item_drop then
type = "ITM_drop"
elseif bit_and(sound_type, snd_type.item_hide) == snd_type.item_hide then
type = "ITM_hide"
elseif bit_and(sound_type, snd_type.item_take) == snd_type.item_take then
type = "ITM_take"
elseif bit_and(sound_type, snd_type.item_use) == snd_type.item_use then
type = "ITM_use"
end
elseif bit_and(sound_type, snd_type.monster) == snd_type.monster then
type = "MST"
if bit_and(sound_type, snd_type.monster_die) == snd_type.monster_die then
type = "MST_die"
elseif bit_and(sound_type, snd_type.monster_injure) == snd_type.monster_injure then
type = "MST_damage"
elseif bit_and(sound_type, snd_type.monster_step) == snd_type.monster_step then
type = "MST_step"
elseif bit_and(sound_type, snd_type.monster_talk) == snd_type.monster_talk then
type = "MST_talk"
elseif bit_and(sound_type, snd_type.monster_attack) == snd_type.monster_attack then
type = "MST_attack"
elseif bit_and(sound_type, snd_type.monster_eat) == snd_type.monster_eat then
type = "MST_eat"
end
end
if type ~= "NIL" then
printf("SND *%s* dist: %d [%f], %s -> %s", type, self:position():distance_to(who:position()), sound_power, who:name(), self:name())
end
end
function AddToMotivator(npc)
if alife() then
npc:bind_object(this.motivator_binder(npc))
end
end
-- Эвалюаторы, которые имеют высший приоритет, и, соответственно, перебивают остальные скрипты собой
function addCommonPrecondition(action)
--action:add_precondition (world_property(xr_evaluators_id.reaction,false))
action:add_precondition (world_property(xr_evaluators_id.stohe_meet_base + 1,false))
action:add_precondition (world_property(xr_evaluators_id.sidor_wounded_base + 0, false))
--'action:add_precondition (world_property(xr_evaluators_id.chugai_heli_hunter_base, false))
action:add_precondition (world_property(xr_evaluators_id.abuse_base, false))
if rx_ai then rx_ai.addCommonPrecondition(action) end
if watcher_act then
action:add_precondition(world_property(watcher_act.evid_see_stuff, false))
end
end
function register_bloodsucker_restr(obj)
printf("registering blood restr!!!")
bloodsuckers_restr[obj:id()] = obj
end
--[[
----------------------------------------------------------------------------------------------------
-- ФУНКЦИИ, КОТОРЫЕ РАЗРЕШЕНО ВЫЗЫВАТЬ ИЗ ДРУГИХ СКРИПТОВ
----------------------------------------------------------------------------------------------------
Активация схем производится с помощью функций:
function gulag_activate(npc, ini, section, gulag_name, death, combat, actor_dialogs, trade, hit)
Предназначение:
активирует заданную схему, используется схемой гулаг. Тип скрипта определяется автоматически по имени секции.
Здесь:
npc - персонаж, для которого будет активирована схема
ini - его customdata
section - имя секции, которая должна быть активирована
gulag_name - имя гулага, которое будет добавлено спереди к именам путей
death, combat, actor_dialogs, trade, hit - имена секций, задающих поведение при смерти и в бою
function assign_storage_and_bind(npc, ini, scheme, section)
Предназначение:
Вызывает функцию add_to_binder схемы, а также создает (если его еще нет) и возвращает ссылку на storage
для схемы. Примечание: в storage при этом могут оставаться старые данные, схема должна очистить его
самостоятельно.
function subscribe_action_for_events(npc, storage, new_action)
Предназначение:
Регистрирует класс для получения нотификаций о таких событиях как сброс схемы, сохранение и т.д.
Класс реализует соответствующие функции (reset_scheme() и т.д.), которые будут вызываться из xr_logic
в нужные моменты.
function pick_section_from_condlist(actor, npc, condlist)
Предназначение:
Проверяет условия condlist, и если они успешны - ставит указанные infoportions и возвращает текст.
Если условия не выполняются - возвращает nil.
function try_switch_to_another_section(npc, st, actor)
Предназчанение:
Используя настройки xr_logic из storage персонажа, пытается переключить его на другую схему, если
хоть одно из условий переключения сработало. Обычно вызывается из метода update класса персонажа.
function is_active(npc, st)
Предназначение:
Вызывается из evaluator-а (или в самом начале update у предметов и монстров) для проверки, что данная
схема сейчас активна (схема определяется по данным в storage).
function cfg_get_switch_conditions(ini, section, npc)
Предназначение:
Считывает все возможные условия переключения схем.
function parse_condlist(npc, section, field, src)
Предназначение:
Распарсивает условия вида: {+infop1} section1 %-infop2%, {+infop3 -infop4} section2 ... в таблицу.
Параметры section и field используются только в сообщениях об ошибках. Если строка src считана не из файла,
а передается в эту функцию гулагом, то нужно задать следующие параметры:
--]]
-- section = "[[[gulag_tasks.script]]]"
-- field = "[[[gulag_name=имя_гулага]]]"
--[[
----------------------------------------------------------------------------------------------------
-- ПРИВАТНЫЕ ФУНКЦИИ
----------------------------------------------------------------------------------------------------
function activate_by_section(npc, ini, section, loading)
Предназначение:
Активирует указанную секцию. Если в данный момент какая-либо секция уже активирована, сообщает об ошибке.
function switch_to_section(npc, st, section)
Предназначение:
Выполняет переключение с одной секции на другую, если новая секция не nil. Если же она nil, остается
активной старая секция.
function abort_syntax_error_in_cond(npc, section, field)
Предназначение:
Сообщает о синтаксической ошибке в условиях переключения схем секции section и поля field, и останавливает
игру.
function parse_infop(rslt, str)
Предназначение:
Распарсивает условия вида " +infop1 =func -infop2 " и т.д. (все не перечислены) в таблицу.
function cfg_get_number_and_condlist(ini, section, field, npc)
function cfg_get_string_and_condlist(ini, section, field, npc)
function cfg_get_condlist(ini, section, field, npc)
Предназначение:
Считывает из customdata различные условия переключения схем.
function add_condition(lst, at, cond)
Предназначение:
Добавляет условие в список условий переключения схем.
function cfg_get_overrides(ini, section, npc)
Предназначение:
Считывает настройки для схем общего поведения.
function generic_scheme_overrides(npc)
Предназначение:
Возвращает ссылку на настройки схем общего поведения, актуальные для работающей в данный момент схемы,
либо nil, если ни одна из секций не активна, либо настройки не заданы.
--]]
--[[
-- Предназначение:
-- вызывается при включении набора скриптов через секцию logic у персонажа. Если в секции logic присутствует только
-- поле cfg, использует конфигурационный файл, заданный в этом поле, и возвращает новый ini file.
-- Здесь:
-- npc - персонаж, для которого будет активирована схема
-- ini - его customdata
-- stype - тип скрипта. Поскольку имя секции все еще неизвестно, его нужно задавать явно. Допустимые значения
-- перечислены в файле modules.script.
-- section - имя секции logic
-- gulag_name - имя гулага, если скрипт включается гулагом, а не биндером
--]]--
function configure_schemes(npc, ini, ini_filename, stype, section_logic, gulag_name)
--printf("DEBUG: enable_scripts: npc:name()=%s", npc:name())
local npc_id = npc:id()
local st = db.storage[npc_id]
-- если какая-то схема была до этого активна, деактивировать её
if st.active_section then
issue_event(npc, st[st.active_scheme], "deactivate", npc)
end
local actual_ini
local actual_ini_filename
if not ini:section_exist(section_logic) then
if gulag_name == "" then
-- Общие схемы должны работать и без logic:
actual_ini_filename = ini_filename
actual_ini = ini -- персонаж не обязательно должен иметь секцию logic
else
-- Иначе это персонаж Gulag-а и ему не задали работу:
abort("ERROR: object '%s': unable to find section '%s' in '%s'", npc:name(), section_logic, tostring(ini_filename))
end
else
local filename = utils.cfg_get_string(ini, section_logic, "cfg", npc, false, "")
if filename then
actual_ini_filename = filename
actual_ini = ini_file(filename)
if not actual_ini:section_exist(section_logic) then
abort("object '%s' configuration file [%s] NOT FOUND or section [logic] isn't assigned ", npc:name(), filename)
end
--printf("_bp: enable_scripts: object '%s' has external configuration file '%s'", npc:name(), filename)
-- Рекурсивно обработать конфигурационный файл, на который ссылается поле cfg
return configure_schemes(npc, actual_ini, actual_ini_filename, stype, section_logic, gulag_name)
--[[
if actual_ini:line_count(section_logic) == 0 then
abort("file '%s' does not exist or is empty, or has no section '%s'",
filename, section_logic)
end
]]--
else
if stype == modules.stype_stalker or stype == modules.stype_mobile then
local current_smart = xr_gulag.get_npc_smart(npc)
if current_smart ~= nil then
local t = current_smart:getJob(npc_id)
if t then
st.job_ini = t.ini_path
else
st.job_ini = nil
end
end
end
--printf("_bp: enable_scripts: object '%s' has NO external configuration file, using '%s'", npc:name(), ini_filename)
actual_ini_filename = ini_filename
actual_ini = ini
end
end
-- Поскольку в момент активации схемы могли работать ранее установленные общие схемы, нужно их все отключить:
disable_generic_schemes(npc, stype)
-- Включаем все общие схемы (раненный, коллбек на попадание и т.д.):
enable_generic_schemes(actual_ini, npc, stype, section_logic)
-- Инициализация торговли
if stype == modules.stype_stalker or
npc:clsid() == clsid.script_trader
then
local trade_ini = utils.cfg_get_string(actual_ini, section_logic, "trade", npc, false, "", "misc\\trade_generic.ltx")
trade_manager.trade_init(npc, trade_ini)
end
-- Вызывается биндером с целью определить первую активную схему
function determine_section_to_activate(npc, ini, section_logic, actor)
if not ini:section_exist(section_logic) then
return "nil"
end
-- Распарсить строку выбора активной секции с учетом команд, заключенных в %%
local active_section_cond = cfg_get_condlist(ini, section_logic, "active", npc)
local active_section
if not active_section_cond then
return "nil"
--'abort("object '%s': section '%s': unable to find field 'active'", npc:name(), section_logic)
else
active_section = pick_section_from_condlist(actor, npc, active_section_cond.condlist)
if not active_section then
abort("object '%s': section '%s': section 'active' has no conditionless else clause",
npc:name(), section_logic)
end
end
return active_section
end
------------------------------------------------------------------------------------------------------------
-- ВНОСЯ ИЗМЕНЕНИЯ В ЭТУ ФУНКЦИЮ, НЕ ЗАБЫВАЙТЕ ДОБАВЛЯТЬ СООТВЕТСТВУЮЩИЕ СТРОКИ И В enable_generic_schemes
------------------------------------------------------------------------------------------------------------
function disable_generic_schemes(npc, stype)
if stype == modules.stype_stalker then
xr_combat.disable_scheme(npc, "combat")
if rx_ai then rx_ai.disable_schemes(npc, stype) end
xr_use.disable_scheme(npc, "use")
xr_hit.disable_scheme(npc, "hit")
xr_meet.disable_scheme(npc, "actor_dialogs")
--'xr_heli_hunter.disable_scheme(npc, "heli_hunter")
xr_combat_ignore.disable_scheme(npc, "combat_ignore")
stalker_generic.disable_invulnerability(npc)
elseif stype == modules.stype_mobile then
mob_combat.disable_scheme(npc, "mob_combat")
xr_combat_ignore.disable_scheme(npc, "combat_ignore")
stalker_generic.disable_invulnerability(npc)
elseif stype == modules.stype_trader then
mob_trade.disable_scheme(npc, "mob_trade")
elseif stype == modules.stype_item then
ph_on_hit.disable_scheme(npc, "ph_on_hit")
elseif stype == modules.stype_heli then
xr_hit.disable_scheme(npc, "hit")
end
end
------------------------------------------------------------------------------------------------------------
-- ВНОСЯ ИЗМЕНЕНИЯ В ЭТУ ФУНКЦИЮ, НЕ ЗАБЫВАЙТЕ ДОБАВЛЯТЬ СООТВЕТСТВУЮЩИЕ СТРОКИ И В disable_generic_schemes
------------------------------------------------------------------------------------------------------------
function enable_generic_schemes(ini, npc, stype, section)
if stype == modules.stype_stalker then
--xr_reactions.set_reactions(npc, ini, "reactions", section)
xr_danger.set_danger(npc, ini, "danger", "danger")
local combat_section = utils.cfg_get_string(ini, section, "on_combat", npc, false, "")
xr_combat.set_combat_checker(npc, ini, "combat", combat_section)
stalker_generic.reset_invulnerability(npc, ini, section)
local use_section = utils.cfg_get_string(ini, section, "on_use", npc, false, "")
if use_section then
xr_use.set_use_checker(npc, ini, "use", use_section)
end
local info_section = utils.cfg_get_string(ini, section, "info", npc, false, "")
if info_section then
stalker_generic.set_npc_info(npc, ini, "info", info_section)
end
local hit_section = utils.cfg_get_string(ini, section, "on_hit", npc, false, "")
if hit_section then
xr_hit.set_hit_checker(npc, ini, "hit", hit_section)
end
if watcher_act then
watcher_act.set_scheme(npc,ini,"watcher_act","watcher_act")
end
local actor_dialogs_section = utils.cfg_get_string (ini, section, "actor_dialogs", npc, false, "")
if actor_dialogs_section then
xr_meet.set_actor_dialogs(npc, ini, "actor_dialogs", actor_dialogs_section)
end
local wounded_section = utils.cfg_get_string (ini, section, "wounded", npc, false, "")
xr_wounded.set_wounded (npc, ini, "wounded", wounded_section)
xr_abuse.set_abuse(npc, ini, "abuse", section)
local meet_section = utils.cfg_get_string (ini, section, "meet", npc, false, "")
xr_meet.set_meet (npc, ini, "meet", meet_section)
local death_section = utils.cfg_get_string (ini, section, "on_death", npc, false, "")
xr_death.set_death (npc, ini, "death", death_section)
xr_combat_ignore.set_combat_ignore_checker(npc, ini, "combat_ignore")
if rx_ai then rx_ai.enable_schemes(ini,npc) end
elseif stype == modules.stype_mobile then
local combat_section = utils.cfg_get_string(ini, section, "on_combat", npc, false, "")
if combat_section then
mob_combat.set_scheme(npc, ini, "mob_combat", combat_section)
end
local death_section = utils.cfg_get_string(ini, section, "on_death", npc, false, "")
mob_death.set_scheme(npc, ini, "mob_death", death_section)
stalker_generic.reset_invulnerability(npc, ini, section)
local hit_section = utils.cfg_get_string(ini, section, "on_hit", npc, false, "")
if hit_section then
xr_hit.set_hit_checker(npc, ini, "hit", hit_section)
end
xr_combat_ignore.set_combat_ignore_checker(npc, ini, "combat_ignore")
elseif stype == modules.stype_trader then
local trade_section = utils.cfg_get_string(ini, section, "on_trade", npc, false, "")
if trade_section then
mob_trade.set_scheme(npc, ini, "mob_trade", trade_section)
end
elseif stype == modules.stype_item then
local hit_section = utils.cfg_get_string(ini, section, "on_hit", npc, false, "")
--printf("HIT SECTION [%s]", tostring(hit_section))
if hit_section then
ph_on_hit.set_scheme(npc, ini, "ph_on_hit", hit_section)
end
elseif stype == modules.stype_heli then
local hit_section = utils.cfg_get_string(ini, section, "on_hit", npc, false, "")
if hit_section then
xr_hit.set_hit_checker(npc, ini, "hit", hit_section)
end
end
end
-- Существует два способа вызова функции: с передаванием секции или без нее
-- В обоих случаях передавать gulag_name ОБЯЗАТЕЛЬНО
-- Если section не передана, то она берется из работы переданного гулага.
function activate_by_section(npc, ini, section, gulag_name, loading)
--printf("LOGIC[%s]: Object '%s': activate_by_section: looking for section '%s'", tostring(time_global()), npc:name(), section)
if loading == nil then
abort("xr_logic: activate_by_section: loading field is nil, true or false expected")
end
local npc_id = npc:id()
if not loading then
db.storage[npc_id].activation_time = time_global()
-- GAMETIME added by Stohe.
db.storage[npc_id].activation_game_time = game.get_game_time()
end
if section == "nil" then
db.storage[npc_id].overrides = nil
reset_generic_schemes_on_scheme_switch(npc, "nil", "nil")
db.storage[npc_id].active_section = nil
db.storage[npc_id].active_scheme = nil
--' db.storage[npc_id].pstor = nil
return
end
if section == nil then
local current_gulag = xr_gulag.get_npc_smart(npc)
if current_gulag == nil then
abort("xr_logic: activate_by_section: section is NIL and NPC not in gulag.")
end
local t = current_gulag:getJob(npc_id)
section = t.section
end
if not ini:section_exist(section) then
abort("object '%s': activate_by_section: section '%s' does not exist", npc:name(), section)
end
local scheme = utils.get_scheme_by_section(section)
if scheme == nil then
abort("object '%s': unable to determine scheme name from section name '%s'", npc:name(), section)
end
-- schemes[scheme] даст имя файла (модуля), в котором реализована схема
-- _G[] даст указатель на неймспейс (таблицу) этого модуля
local filename = schemes[scheme]
if filename == nil then
abort("xr_logic: scheme '%s' is not registered in modules.script", scheme)
end
--printf("_bp: calling module('%s')", filename)
if not _G[filename] then
abort("xr_logic: can't call %s.set_scheme() - a nil value", filename)
end
_G[filename].set_scheme(npc, ini, scheme, section, gulag_name)
if db.storage[npc_id].stype == modules.stype_stalker then
-- чтобы избежать дальнейшего движения по пути при установке рестрикторов
utils.send_to_nearest_accessible_vertex(npc, npc:level_vertex_id())
issue_event(npc, db.storage[npc_id][scheme], "activate_scheme", loading, npc)
else
issue_event(npc, db.storage[npc_id][scheme], "reset_scheme", loading, npc)
end
end
--[[
-- Предназначение:
-- Производит сброс состояния объекта (снимает коллбеки, отключает разговор) непосредственно перед включением
-- новой схемы.
]] --
function reset_generic_schemes_on_scheme_switch(npc, scheme, section)
--printf("_bp: reset_generic_schemes_on_scheme_switch: npc:name()='%s'", npc:name())
local st = db.storage[npc:id()]
elseif st.stype == modules.stype_mobile then
--printf("_bp: disabling talk")
--npc:disable_talk() -- теперь делается в dialog_manager_reset
xr_meet.dialog_manager_reset(npc, st.stype)
mob_release(npc)
if get_clsid(npc) == clsid.bloodsucker_s then
if scheme == "nil" then
npc:set_manual_invisibility(false)
else
npc:set_manual_invisibility(true)
-- Видимый или нет определяет схема, которая возьмет его под контроль:
--npc:set_invisible(false)
end
end
elseif st.stype == modules.stype_item then
npc:set_callback(callback.use_object, nil)
npc:set_nonscript_usable(true)
if get_clsid(npc) == clsid.car then
-- Другие объекты под скрипт не берутся, поэтому для них не надо сбрасывать
npc:destroy_car()
mob_release(npc)
end
end
end
function assign_storage_and_bind(npc, ini, scheme, section)
local npc_id = npc:id()
local st
if not db.storage[npc_id][scheme] then
db.storage[npc_id][scheme] = {}
st = db.storage[npc_id][scheme]
st["npc"] = npc
-- Схема стартует впервые - прибиндить
--printf("DEBUG: assign_storage_and_bind: bind scheme: '%s'", scheme)
_G[schemes[scheme]].add_to_binder(npc, ini, scheme, section, st)
else
st = db.storage[npc_id][scheme]
end
st["scheme"] = scheme
st["section"] = section
st["ini"] = ini
return st
end
function subscribe_action_for_events(npc, storage, new_action)
--printf("DEBUG: registering new action for reset event (npc:name() = '%s')", npc:name())
if not storage.actions then
storage.actions = {}
end
storage.actions[new_action] = true
end
function unsubscribe_action_from_events(npc, storage, new_action)
if not storage.actions then
storage.actions = {}
end
storage.actions[new_action] = nil
end
-- st - storage активной схемы
function issue_event(npc, st, event_fn, ...)
if not st or not st.actions then
return
end
local activation_count = 0
local action_ptr, is_active = 0, 0
for action_ptr, is_active in pairs(st.actions) do
if is_active and action_ptr[event_fn] then
action_ptr[event_fn](action_ptr, ...)
activation_count = activation_count + 1
end
end
-- if activation_count == 0 and
-- event_fn == "activate_scheme"
-- then
-- abort("xr_logic: issue_event: activate_scheme handler not found, active_scheme is '%s'", db.storage[npc:id()].active_scheme)
-- end
end
--' Функция проверяет выполняется ли у активной схемы заданная функция
function check_action(npc, st, event_fn, p)
if not st or not st.actions then
return true
end
for action_ptr, is_active in pairs(st.actions) do
if is_active and action_ptr[event_fn] then
return action_ptr[event_fn](action_ptr, p)
end
end
return true
end
function pick_section_from_condlist(actor, npc, condlist)
local rval = nil -- math.random(100)
--printf("_bp: pick_section_from_condlist: rval = %d", rval)
local newsect = nil
local infop_conditions_met
for n, cond in pairs(condlist) do
infop_conditions_met = true -- изначально считаем, что все условия переключения удовлетворены
for inum, infop in pairs(cond.infop_check) do
if infop.prob then
if not rval then
rval = math.random(100)
end
if infop.prob < rval then
infop_conditions_met = false -- инфопоршен есть, но он не должен присутствовать
break
end
elseif infop.func then
--printf("_bp: infop.func = %s", infop.func)
if not xr_conditions[infop.func] then
if type(npc.name) == "function" then
abort("object '%s': pick_section_from_condlist: function '%s' is " ..
"not defined in xr_conditions.script", npc:name(), infop.func)
else
abort("object '%s': pick_section_from_condlist: function '%s' is " ..
"not defined in xr_conditions.script", tostring(npc.name), infop.func)
end
end
--if xr_conditions[infop.func](actor, npc) then
if infop.params then
if xr_conditions[infop.func](actor, npc, infop.params) then
if not infop.expected then
infop_conditions_met = false -- инфопоршен есть, но не должен присутствовать
break
end
else
if infop.expected then
infop_conditions_met = false -- инфопоршен есть, но не должен присутствовать
break
end
end
else
if xr_conditions[infop.func](actor, npc) then
if not infop.expected then
infop_conditions_met = false -- инфопоршен есть, но не должен присутствовать
break
end
else
if infop.expected then
infop_conditions_met = false -- инфопоршен есть, но не должен присутствовать
break
end
end
end
elseif has_alife_info(infop.name) then
if not infop.required then
--'printf("FAILED: actor has infop '%s', which is NOT needed [%s]", infop.name, tostring(has_alife_info(infop.name)))
infop_conditions_met = false -- инфопоршен есть, но он не должен присутствовать
break
else
--'printf("PASSED: actor has infop '%s', which is needed [%s]", infop.name, tostring(has_alife_info(infop.name)))
end
else
if infop.required then
--'printf("FAILED: actor has NO infop '%s', which is needed [%s]", infop.name, tostring(has_alife_info(infop.name)))
infop_conditions_met = false -- инфопоршена нет, но он нужен
break
else
--'printf("PASSED: actor has NO infop '%s', which is not needed [%s]", infop.name, tostring(has_alife_info(infop.name)))
end
end
end
--printf("_bp: infop_cond_met = %s", utils.to_str(infop_conditions_met))
if infop_conditions_met then
-- Условия выполнены. Независимо от того, задана ли секция, нужно проставить требуемые
-- infoportions:
for inum, infop in pairs(cond.infop_set) do
if db.actor == nil then
abort("TRYING TO SET INFOS THEN ACTOR IS NIL")
end
if infop.func then
if not xr_effects[infop.func] then
abort("object '%s': pick_section_from_condlist: function '%s' is " ..
"not defined in xr_effects.script", if_then_else(npc, npc:name(), "nil"), infop.func)
end
if infop.params then
xr_effects[infop.func](actor, npc, infop.params)
else
xr_effects[infop.func](actor, npc)
end
elseif infop.required then
if not has_alife_info(infop.name) then
actor:give_info_portion(infop.name)
end
else
if has_alife_info(infop.name) then
--printf("*INFO [disabled]*: npc='%s' id='%s'", actor:name(),infop.name)
actor:disable_info_portion(infop.name)
end
end
end
if cond.section == "never" then
return nil
else
return cond.section
end
end
end
--printf("_bp: pick_section_from_condlist: nil")
return nil
end
-- Выполняет переключение на указанную секцию, если задана.
-- Если section == nil, остается работать старая секция.
function switch_to_section(npc, ini, section)
if section == "" or section == nil then
return false
end
--printf("section = [%s]", tostring(section))
local npc_id = npc:id()
local active_section = db.storage[npc_id].active_section
if active_section == section then
--printf("section = [%s]3", tostring(section))
return false
end
if active_section then
issue_event(npc, db.storage[npc_id][db.storage[npc_id].active_scheme], "deactivate", npc)
end
db.storage[npc_id].exit_from_smartcover_initialized = nil
db.storage[npc_id].active_section = nil
db.storage[npc_id].active_scheme = nil
if section == nil then
return true
end
activate_by_section(npc, ini, section, db.storage[npc_id].gulag_name, false)
--printf("section = [%s]5", tostring(section))
return true
end
function see_actor(npc)
return npc:alive() and npc:see(db.actor)
end
function cond_name(cond, etalon)
return string.find( cond, "^"..etalon.."%d*$" ) ~= nil
end
function try_switch_to_another_section(npc, st, actor)
local l = st.logic
local npc_id = npc:id()
if not actor then
abort("try_switch_to_another_section(): error in implementation of scheme '%s': actor is nil", st.scheme)
return
end
if not l then
abort("Can't find script switching information in storage, scheme '%s'", st.active_scheme)
end
local switched = false
for n, c in pairs(l) do
--printf("_bp: %d: %s", time_global(), c.name)
if cond_name(c.name, "on_actor_dist_le") then
--printf("_bp: dist=%d (need <= %d), see_actor: %s", distance_between(actor, npc), c.v1, utils.to_str(see_actor(npc)))
if see_actor(npc) and distance_between(actor, npc) <= c.v1 then
--printf("_bp: conditions met")
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_actor_dist_le_nvis") then
if distance_between(actor, npc) <= c.v1 then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_actor_dist_ge") then
--printf("_bp: dist=%d (need <= %d), see_actor: %s", distance_between(actor, npc), c.v1, utils.to_str(see_actor(npc)))
-- ТУТ УМЫШЛЕННО >, А НЕ >=, потому что оно составляет пару с on_actor_dist_le, где <=
if see_actor(npc) and distance_between(actor, npc) > c.v1 then
--printf("_bp: conditions met")
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_actor_dist_ge_nvis") then
-- ТУТ УМЫШЛЕННО >, А НЕ >=, потому что оно составляет пару с on_actor_dist_le_nvis, где <=
if distance_between(actor, npc) > c.v1 then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_signal") then
--printf("_bp: on_signal (c.v1 = %s)", c.v1)
if st.signals and st.signals[c.v1] then
--printf("_bp: on_signal (c.v1 = %s) signalled [%s]", c.v1, npc:name())
--printf("_bp: signalled")
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
-- FIXME: не дублировать тут имена, оставить один on_info, но добавлять несколько его экземпляров в список
elseif cond_name(c.name, "on_info") then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
elseif cond_name(c.name, "on_timer") then
--printf("_bp: on_timer: %d >= %d", time_global(),
-- db.storage[npc_id].activation_time + c.v1)
if time_global() >= db.storage[npc_id].activation_time + c.v1 then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
-- GAMETIME added by Stohe.
elseif cond_name(c.name, "on_game_timer") then
if game.get_game_time():diffSec(db.storage[npc_id].activation_game_time) >= c.v1 then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_actor_in_zone") then
if utils.npc_in_zone(actor, db.zone_by_name[c.v1]) then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_actor_not_in_zone") then
if not utils.npc_in_zone(actor, db.zone_by_name[c.v1]) then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_npc_in_zone") then
if utils.npc_in_zone(level.object_by_id(c.npc_id), db.zone_by_name[c.v2]) then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_npc_not_in_zone") then
if not utils.npc_in_zone(level.object_by_id(c.npc_id), db.zone_by_name[c.v2]) then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_actor_inside") then
if utils.npc_in_zone(actor, npc) then
-- printf("_bp: TRUE")
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
elseif cond_name(c.name, "on_actor_outside") then
if not utils.npc_in_zone(actor, npc) then
switched = switch_to_section(npc, st.ini, pick_section_from_condlist(actor, npc, c.condlist))
end
else
abort(
"WARNING: object '%s': try_switch_to_another_section: unknown condition '%s' encountered",
npc:name(), c.name)
end
if switched == true then
break
end
end
return switched
end
function is_active(npc, st)
if st.section == nil then
abort("npc '%s': st.section is nil, active section is '%s'",
npc:name(), utils.to_str(db.storage[npc:id()].active_section))
end
local is_act = (st.section == db.storage[npc:id()].active_section)
-- Текущая секция активна и не сработало ни одно из условий переключения на другие секции
return is_act
end
function abort_syntax_error_in_cond(npc, section, field)
abort("object '%s': section '%s': field '%s': syntax error in switch condition",
npc:name(), section, field)
end
-- На входе имеем пустой массив и строку вида " +infop1 -infop2 +infop3 ... "
-- Заполнить массив:
-- { "infop_name" = true/false }.
function parse_infop1(rslt, str)
--printf("_bp: parse_infop: %s", utils.to_str(str))
if str then
local infop_name, sign
local infop_n = 1
for s in string.gfind(str, "%s*([%-%+%~%=%!][^%-%+%~%=%!%s]+)%s*") do
--printf("_bp: parse_infop: s=%s", utils.to_str(s))
sign = string.sub(s, 1, 1)
infop_name = string.sub(s, 2)
if sign == "+" then
rslt[infop_n] = { name = infop_name, required = true }
elseif sign == "-" then
rslt[infop_n] = { name = infop_name, required = false }
elseif sign == "~" then
rslt[infop_n] = { prob = tonumber(infop_name) }
elseif sign == "=" then
rslt[infop_n] = { func = infop_name, expected = true }
elseif sign == "!" then
rslt[infop_n] = { func = infop_name, expected = false }
else
abort_syntax_error_in_cond(npc, section, field)
end
infop_n = infop_n + 1
end
end
end
function parse_func_params(str)
local lst = {}
local n
for par in string.gfind(str, "%s*([^:]+)%s*") do
n = tonumber(par)
if n then table.insert(lst, n)
else table.insert(lst, par) end
end
return lst
end
function parse_infop(rslt, str)
--printf("_bp: parse_infop1: %s", utils.to_str(str))
if str then
local infop_name, sign
local infop_n = 1
local at, params
for s in string.gfind(str, "%s*([%-%+%~%=%!][^%-%+%~%=%!%s]+)%s*") do
--printf("_bp: parse_infop: s=%s", utils.to_str(s))
sign = string.sub(s, 1, 1)
infop_name = string.sub(s, 2)
params = nil
-- парсим параметры функций
at = string.find(infop_name, "%(")
if at then
if string.sub(infop_name, -1) ~= ")" then
abort("wrong condlist %s", str)
end
if at < string.len(infop_name) - 1 then
params = parse_func_params(string.sub(infop_name, at + 1, -2))
else
params = {}
end
infop_name = string.sub(infop_name, 1, at - 1)
end
if sign == "+" then
rslt[infop_n] = { name = infop_name, required = true }
elseif sign == "-" then
rslt[infop_n] = { name = infop_name, required = false }
elseif sign == "~" then
rslt[infop_n] = { prob = tonumber(infop_name) }
elseif sign == "=" then
--printf("_bp: n = %s; r = %s", infop_name, utils.to_str(params))
rslt[infop_n] = { func = infop_name, expected = true, params = params }
elseif sign == "!" then
--printf("_bp: n = %s; r = %s", infop_name, utils.to_str(params))
rslt[infop_n] = { func = infop_name, expected = false, params = params }
else
abort_syntax_error_in_cond(npc, section, field)
end
infop_n = infop_n + 1
end
end
end
-- 1) Разбиваем на разделенные запятыми части:
local at, to, infop_check_lst, remainings, infop_set_lst, newsect
--printf("_bp: src = %s", src)
local n = 1
for fld in string.gfind(src, "%s*([^,]+)%s*") do
-- Здесь fld это набор infoportions в {} и имя секции, на которую переключиться.
lst[n] = {}
--printf("_bp: iter %d: fld = %s", n, fld)
-- Выделяем список infoportions для проверки:
at, to, infop_check_lst = string.find(fld, "{%s*(.*)%s*}")
if infop_check_lst then
--printf("_bp: infop_check_lst: [%s]", infop_check_lst)
-- Выделяем оставшуюся часть поля, т.е. имя секции плюс список infoportions для установки:
remainings = string.sub(fld, 1, at - 1) .. string.sub(fld, to + 1)
else
-- Список infoportions для проверки не был задан, следовательно, ничего не удаляем:
remainings = fld
end
--printf("_bp: remainings: %s", remainings)
-- Выделяем список infoportions для установки из remainings:
at, to, infop_set_lst = string.find(remainings, "%%%s*(.*)%s*%%")
if infop_set_lst then
-- Выделяем оставшуюся часть поля, т.е. имя секции:
newsect = string.sub(remainings, 1, at - 1) .. string.sub(remainings, to + 1)
else
-- Список infoportions для установки не был задан, следовательно, remainings и есть имя секции.
newsect = remainings
end
--printf("_bp: newsect: %s", newsect)
-- И сразу trim имя секции:
at, to, newsect = string.find(newsect, "%s*(.*)%s*")
if not newsect then
abort_syntax_error_in_cond(npc, section, field)
end
-- Имя секции теперь можно сохранить:
lst[n].section = newsect
-- Теперь нужно распарсить infoportions в строке infop_check_lst и
-- заполнить массив infop_check: { "infop_name" = true/false }.
-- На входе имеем строку вида " +infop1 -infop2 +infop3 ... "
lst[n].infop_check = {}
parse_infop(lst[n].infop_check, infop_check_lst)
-- То же самое для устанавливаемых infoportions:
lst[n].infop_set = {}
parse_infop(lst[n].infop_set, infop_set_lst)
n = n + 1
end
return lst
end
function cfg_get_number_and_condlist(ini, section, field, npc)
local str = utils.cfg_get_string(ini, section, field, npc, false, "")
if not str then
return nil
end
local par = utils.parse_params(str)
if not par[1] or not par[2] then
abort_syntax_error_in_cond(npc, section, field)
end
function cfg_get_string_and_condlist(ini, section, field, npc)
local str = utils.cfg_get_string(ini, section, field, npc, false, "")
if not str then
return nil
end
local par = utils.parse_params(str)
if not par[1] or not par[2] then
abort_syntax_error_in_cond(npc, section, field)
end
function cfg_get_two_strings_and_condlist(ini, section, field, npc)
local str = utils.cfg_get_string(ini, section, field, npc, false, "")
if not str then
return nil
end
local par = utils.parse_params(str)
if not par[1] or not par[2] or not par[3] then
abort_syntax_error_in_cond(npc, section, field)
end
function cfg_get_condlist(ini, section, field, npc)
local str = utils.cfg_get_string(ini, section, field, npc, false, "")
if not str then
return nil
end
local par = utils.parse_params(str)
if not par[1] then
abort_syntax_error_in_cond(npc, section, field)
end
local t = {}
t.name = field
t.condlist = parse_condlist(npc, section, field, par[1])
return t
end
function add_condition(lst, at, cond)
if cond then
lst[at] = cond
return at + 1
end
return at
end
function cfg_get_switch_conditions(ini, section, npc)
local l = {}
local t
local n = 1
local function add_conditions(func, cond)
local i = 1
local c = func(ini, section, cond, npc)
local tmp = utils.cfg_get_string(ini, section, "heli_hunter", npc, false, "")
if tmp then
l.heli_hunter = xr_logic.parse_condlist(npc, section, "heli_hunter", tmp)
end
-- l.wounded_enabled = utils.cfg_get_bool(ini, section, "wounded_enabled", npc, false)
l.combat_ignore = cfg_get_condlist(ini, section, "combat_ignore_cond", npc)
l.combat_ignore_keep_when_attacked = utils.cfg_get_bool(ini, section, "combat_ignore_keep_when_attacked", npc, false)
l.combat_type = cfg_get_condlist(ini, section, "combat_type", npc)
l.on_combat = cfg_get_condlist(ini, section, "on_combat", npc)
-- l.companion_enabled = utils.cfg_get_bool(ini, section, "companion_enabled", npc, false)
local st = db.storage[npc:id()]
if ini:line_exist(st.section_logic, "post_combat_time") then
l.min_post_combat_time,l.max_post_combat_time = utils.r_2nums( ini, st.section_logic, "post_combat_time", 10, 15 )
else
l.min_post_combat_time,l.max_post_combat_time = utils.r_2nums( ini, section, "post_combat_time", 10, 15 )
end
if string.find(section, "kamp") ~= nil then
l.soundgroup = utils.cfg_get_string(ini, section, "center_point", npc, false, "")
else
l.soundgroup = utils.cfg_get_string(ini, section, "soundgroup", npc, false, "")
end
return l
end
function cfg_get_npc_and_zone(ini, section, field, npc)
local t = cfg_get_two_strings_and_condlist(ini, section, field, npc)
if t then
local sim = alife()
if sim then
local se_obj = sim:story_object(tonumber(t.v1))
if se_obj then
t.npc_id = se_obj.id
else
t.npc_id = -1
abort("object '%s': section '%s': field '%s': there is no object with story_id '%s'",
npc:name(), section, field, t.v1)
end
else
t.npc_id = -1
--printf("WARNING: object '%s': section '%s': field '%s': can't use story_id without simulation!", npc:name(), section, field)
end
end
return t
end
-- Возвращает ссылку на оверрайды, зарегистрированные в активной на данный момент секции,
-- либо nil, если ни одна из секций не активна, или оверрайдов нет.
function generic_scheme_overrides(npc)
return db.storage[npc:id()].overrides
end
function mob_release(mob)
if mob:get_script() then
mob:script(false, script_name())
end
end
function mob_capture(mob, reset_actions)
if reset_actions == nil then
abort("mob_capture: reset_actions parameter's value is not specified")
end
if reset_actions then
reset_action(mob, script_name())
else
if not mob:get_script() then
mob:script(true, script_name())
end
end
end
function mob_captured(mob)
return mob:get_script()
end
Как изменить цвет свечения артефакта?
Ну например в файле том я медузу пробовал настроить, но она горит ярче но только красным, теперь опять менять пытаюсь а оно не меняется, хочу чтоб горела она дневным светом.. Какие цифры за что отвечают?
Здравствуйте! помогите пожалуйста с таким вопросом: опробовал много разных модов, но в основном играю в OGSM, и хочется именно его модернизировать, потому что остановил свое внимание на нем. Не люблю игры, которые заканчиваются, поэтому хочу внести изменения для более интересного свободного прохождения.
ВОПРОС: 1)хочу, чтобы в игре было много врагов, мутантов, зомби и разных сталкеров, чтобы они повсюду бродили в большом количестве, например как в ТЧ на Янтаре среди гаражей ходили орды зомби, когда их убивал через некоторое время они появлялись снова. Как это сделать без всяких программ, пользуясь только папкой gamedata? Возможно ли это и как?
2)хочу перекидать с разных модов оружие в этот мод. Пробовал перекинуть модель путем: meshes/dynamics/weapons модель оружия переносится, а текстуру не могу наложить. Как это сделать?
как можно сделать в игре оружие имеющее разные текстуры? допустим два разных ПМ. копирвал модель,преписывал к ней другую текстуру, харктеристики отличающимися получаются, а вот текстура всё равно одна и та же остаётся ...
отредактировал(а) sem27: 23-10-2011 09:50 GMT3 час.
Эта тема закрыта, публикация новых сообщений недоступна.
Продолжая пользоваться сайтом, вы соглашаетесь с использованием файлов cookie. Страницы сайта могут содержать информацию, запрещенную для просмотра посетителям младше 18 лет. Авторское право на серию игр «S.T.A.L.K.E.R» и используемые в ней материалы принадлежит GSC Game World.