---------------------------------------------------------------------------------------------------- --' Cutscene trigger ---------------------------------------------------------------------------------------------------- --' Временные переменные local object_cutscene = nil local storage_scene = nil class "cam_effector_set" function cam_effector_set:__init(set,storage) self.set = set self.state = "start" self.cur_effect = 0 self.playing = false self.looped = false self.enabled = true self.st = storage end function cam_effector_set:start_effect(eff) --printf("playing effect [camera_effects\\"..eff.anim..".anm], time [%s]", device():time_global()) --callstack() if not (eff.global_cameffect) then level.add_cam_effector("camera_effects\\"..eff.anim..".anm", 210408, false, "sr_cutscene.effector_callback") else level.add_cam_effector2("camera_effects\\"..eff.anim..".anm", 210408, false, "sr_cutscene.effector_callback", self.st.fov or db.actor:fov()*0.75) end self.playing = true end function cam_effector_set:stop_effect() level.remove_cam_effector(210408) self.playing = false self.state = "release" self.cur_effect = 0 end function cam_effector_set:update() if(device().precache_frame > 0) then return end if(self.playing) then local eff = self.set[self.state][self.cur_effect] if(eff) and (eff.looped~=false) then local cond = xr_logic.pick_section_from_condlist(db.actor, nil, self.condlist) if(cond=="false") then self.looped = false -- self:stop_effect() end end else local eff = self:select_effect() if(eff) then self:start_effect(eff) end end end function cam_effector_set:select_effect() local state = self.state local cur_effect = self.cur_effect if(self.looped) then return self.set[state][cur_effect] end if(state=="start") then cur_effect = cur_effect + 1 if(self.set.start[cur_effect]) then self.cur_effect = cur_effect if type(self.set.start[cur_effect].enabled)=="string" then local condlist = xr_logic.parse_condlist(db.actor, "sr_cutscene", "enabled_condlist", self.set.start[cur_effect].enabled) if xr_logic.pick_section_from_condlist(db.actor, nil, condlist) == "false" then return self:select_effect() end end if(type(self.set.start[cur_effect].looped)=="string") then self.looped = true self.condlist = xr_logic.parse_condlist(db.actor, "sr_cutscene", "effect_condlist", self.set.start[cur_effect].looped) end return self.set.start[cur_effect] else self.state = "idle" self.cur_effect = 0 return self:select_effect() end elseif(state=="idle") then cur_effect = cur_effect + 1 if(self.set.idle[cur_effect]) then self.cur_effect = cur_effect if type(self.set.idle[cur_effect].enabled)=="string" then local condlist = xr_logic.parse_condlist(db.actor, "sr_cutscene", "enabled_condlist", self.set.idle[cur_effect].enabled) if xr_logic.pick_section_from_condlist(db.actor, nil, condlist) == "false" then return self:select_effect() end end if(type(self.set.idle[cur_effect].looped)=="string") then self.looped = true self.condlist = xr_logic.parse_condlist(db.actor, "sr_cutscene", "effect_condlist", self.set.idle[cur_effect].looped) end return self.set.idle[cur_effect] else self.state = "finish" self.cur_effect = 0 return self:select_effect() end elseif(state=="finish") then cur_effect = cur_effect + 1 if(self.set.finish[cur_effect]) then self.cur_effect = cur_effect if type(self.set.finish[cur_effect].enabled)=="string" then local condlist = xr_logic.parse_condlist(db.actor, "sr_cutscene", "enabled_condlist", self.set.finish[cur_effect].enabled) if xr_logic.pick_section_from_condlist(db.actor, nil, condlist) == "false" then return self:select_effect() end end if(type(self.set.finish[cur_effect].looped)=="string") then self.looped = true self.condlist = xr_logic.parse_condlist(db.actor, "sr_cutscene", "effect_condlist", self.set.finish[cur_effect].looped) end return self.set.finish[cur_effect] else self.state = "release" self.cur_effect = 0 sr_cutscene.effector_callback() return nil end end end -------------------------------------------------------------------------------- class "action_cutscene" --' инициализация объекта класса function action_cutscene:__init(obj, storage) self.object = obj self.st = storage self.ui_disabled = false self.motion_id = 1 self.postprocess = false end --' инициализация схемы поведения function action_cutscene:reset_scheme() self.state = "" self.st.signals = {} --' обнуляем сигналы self.motion = nil self:zone_enter() end --' функция обновления, вызываемая конвеером function action_cutscene:update(delta) local state = self.state -- if(state~="run") then -- self:zone_enter() -- end if(self.motion) then self.motion:update() if(self.st.signals["cam_effector_stop"]~=nil) then self.motion:stop_effect() self:cutscene_callback() self.st.signals["cam_effector_stop"] = nil end end --' выполняем архитектурное требование if(xr_logic.try_switch_to_another_section(self.object, self.st, db.actor)) then return end end --' тут нужно запустить сцену function action_cutscene:zone_enter() self.state = "run" --' телепорт в выбранную точку --printf("%s ZONE ENTER %s", self.object:name(), device():time_global()) xr_effects.teleport_actor(db.actor, self.object, {self.st.point, self.st.look}) if self.st.pp_effector ~= "nil.ppe" then level.add_pp_effector(self.st.pp_effector, 234, false) end xr_effects.disable_ui(db.actor, nil) self.ui_disabled = true if self.st.outdoor and db.actor ~= nil and (level.get_time_hours() < 6 or level.get_time_hours() > 21) then self.postprocess = true level.add_complex_effector("brighten", 1999) --level.add_pp_effector("brighten.ppe", 1999, true) end self.motion_id = 1 self:select_next_motion() object_cutscene = self.object storage_scene = self.st end --' Выбор и начало отыгрыша следующего пролета function action_cutscene:select_next_motion() local motion = self.st.cam_effector[self.motion_id] if cam_effector_sets[motion] == nil then --Это имя файла, а не имя таблицы. self.motion = cam_effector_set({start={},idle={{anim=motion, looped=false, global_cameffect = self.st.global_cameffect}},finish={}}, self.st) else self.motion = cam_effector_set(cam_effector_sets[motion], self.st) end local effect = self.motion:select_effect() self.motion:start_effect(effect) self.motion_id = self.motion_id + 1 end --' Ивент об окончании пролета function action_cutscene:cutscene_callback() if(self.motion.state=="release") then self.motion = nil if(self.motion_id<=#self.st.cam_effector) then self:select_next_motion() --printf("SELECTING MOTION %s from %s", tostring(self.motion_id), tostring(#self.st.cam_effector)) else if self.postprocess then self.postprocess = false level.remove_complex_effector(1999) --level.remove_pp_effector(1999) end if(self.ui_disabled) then if not db.actor:is_talking() and self.st.enable_ui_on_end then xr_effects.enable_ui(db.actor, nil) elseif self.st.enable_ui_on_end then level.enable_input() end db.actor:set_actor_direction(-patrol(self.st.look):point(0):sub(patrol(self.st.point):point(0)):getH()) self.ui_disabled = false self.st.signals["cameff_end"] = true end end else self.motion.playing = false local eff = self.motion:select_effect() if(eff) then self.motion:start_effect(eff) end end end -------------------------------------------------------------------------------- function add_to_binder(npc, ini, scheme, section, storage) local new_action = action_cutscene(npc, storage) storage.cutscene_action = new_action --' Зарегистрировать все actions, в которых должен быть вызван метод reset_scheme при изменении настроек схемы: xr_logic.subscribe_action_for_events(npc, storage, new_action) end function set_scheme(obj, ini, scheme, section, gulag_name) local st = xr_logic.assign_storage_and_bind(obj, ini, scheme, section) st.logic = xr_logic.cfg_get_switch_conditions(ini, section, obj) st.point = utils.cfg_get_string(ini, section, "point", obj, true, "", "none") st.look = utils.cfg_get_string(ini, section, "look", obj, true, "", "none") st.global_cameffect = utils.cfg_get_bool(ini, section, "global_cameffect", obj, false, false) st.pp_effector = utils.cfg_get_string(ini, section, "pp_effector", obj, false, "", "nil")..".ppe" st.cam_effector = parse_names(utils.cfg_get_string(ini, section, "cam_effector", obj, true, "")) st.fov = utils.cfg_get_number(ini, section, "fov", obj, true) st.enable_ui_on_end = utils.cfg_get_bool(ini, section, "enable_ui_on_end", obj, false, true) st.outdoor = utils.cfg_get_bool(ini, section, "outdoor", obj, false, false) end function effector_callback(obj) xr_logic.issue_event(object_scene, storage_scene, "cutscene_callback") end