local npc_role = {noone=0, listener=1, director=2} CAMP_SECTION = "camp" -------------------------------------------------------------------------------- -- Precondition functions -------------------------------------------------------------------------------- function sr_camp_idle_precondition(camp) return true end function sr_camp_harmonica_precondition(camp) --printf("camp harmonica precondition") if(#camp.harmonica_table>0) then local n = 0 for k,v in pairs(camp.npc) do n = n + 1 end if(n>1) then for k,v in pairs(camp.npc) do local scheme = db.storage[k] and db.storage[k].active_scheme and db.storage[k][db.storage[k].active_scheme] local npc = db.storage[k] and db.storage[k].object --printf(" is director %s", tostring(v.harmonica==npc_role.director)) --printf(" base_action %s", tostring(scheme.base_action) ) --printf(" description %s", tostring(scheme.description) ) if(v.harmonica==npc_role.director) and (scheme ~= nil and scheme.base_action == scheme.description) and npc ~= nil and not xr_meet.is_meet(npc) then --if(v.harmonica==npc_role.director) then --printf(" return true [%s]", k) return true end end end end --printf(" return false") return false end function sr_camp_guitar_precondition(camp) --printf("camp guitar precondition") if(#camp.guitar_table>0) then local n = 0 for k,v in pairs(camp.npc) do n = n + 1 end if(n>1) then for k,v in pairs(camp.npc) do local scheme = db.storage[k] and db.storage[k].active_scheme and db.storage[k][db.storage[k].active_scheme] local npc = db.storage[k] and db.storage[k].object --printf(" is director %s", tostring(v.guitar==npc_role.director)) --printf(" base_action %s", tostring(scheme.base_action) ) --printf(" description %s", tostring(scheme.description) ) if(v.guitar==npc_role.director) and (scheme ~= nil and scheme.base_action == scheme.description) and npc ~= nil and not xr_meet.is_meet(npc) then --if(v.guitar==npc_role.director) then --printf(" return true [%s]", k) return true end end end end --printf(" return false") return false end function sr_camp_story_precondition(camp) if(#camp.story_table>0) then local n = 0 for k,v in pairs(camp.npc) do local npc = db.storage[k] and db.storage[k].object if npc ~= nil and not xr_meet.is_meet(npc) then n = n + 1 end end if(n>1) then return true end end return false end -------------------------------------------------------------------------------- -- Класс CCampManager -------------------------------------------------------------------------------- -- Кемп содержит свои действия в терминах состояния кемпа (рассказ истории, музыка, ожидание), а не в терминах анимаций персонажей -- Кемп возвращает свое состояние, а решение какую именно анимацию играть принимает финальная схема, например xr_animpoint class "CCampManager" function CCampManager:__init(object, ini) self.object = object self.ini = ini local stories = utils.cfg_get_string(ini, CAMP_SECTION, "stories", nil, false, "", "test_story") self.story_table = parse_names(stories) local guitars = utils.cfg_get_string(ini, CAMP_SECTION, "guitar_themes", nil, false, "", "test_guitar") self.guitar_table = parse_names(guitars) local harmonicas = utils.cfg_get_string(ini, CAMP_SECTION, "harmonica_themes", nil, false, "", "test_harmonica") self.harmonica_table = parse_names(harmonicas) self.npc = {} self.schemes = {} -- Хранилище для режиссера лагеря. Режиссерем является сталкер, затеявший необычное поведение self.director = nil -- Текущее состояние self.active_state = "idle" --' Для теста создаем объект истории self.sound_manager = sound_manager.get_sound_manager(CAMP_SECTION..self.object:id()) self.sound_manager_started = true -- Состояния кемпа self.states = { idle = { director_state = nil, general_state = "idle", min_time = 30000, max_time = 40000, timeout = 0, transitions = {harmonica = 30, guitar = 30, story = 40}, precondition = sr_camp_idle_precondition }, harmonica = { director_state = "play_harmonica", general_state = "listen", min_time = 10000, max_time = 11000, timeout = 3000, transitions = {idle = 100, harmonica = 0, guitar = 0, story = 0}, precondition = sr_camp_harmonica_precondition }, guitar = { director_state = "play_guitar", general_state = "listen", min_time = 10000, max_time = 11000, timeout = 4500, transitions = {idle = 100, harmonica = 0, guitar = 0, story = 0}, precondition = sr_camp_guitar_precondition }, story = { director_state = "tell", general_state = "listen", min_time = 10000, max_time = 11000, timeout = 0, transitions = {idle = 100, harmonica = 0, guitar = 0, story = 0}, precondition = sr_camp_story_precondition }, } self.active_state_time = 0 self.timeout = 0 self.idle_talker = nil end -- Переключает состояния кемпа function CCampManager:update() -- Если саундменеджер говорит какую то историю - ждем окончания. if not self.sound_manager:is_finished() then self.sound_manager:update() return end if self.sound_manager_started == false then return end -- Если кто-то говорит айдловую фразу, ждем пока он договорит. if(self.idle_talker~=nil) then if(xr_sound.sound_table[self.idle_talker]) then return else self.idle_talker = nil end end -- Выбор состояния кемпа. Тут решается что делать дальше. --printf("camp time %s", tostring(self.active_state_time - time_global())) if(self.active_state_time < time_global()) then self:set_next_state() if self:get_director() == false then self.active_state = "idle" for k,v in pairs(self.npc) do v.state = self.active_state end --self:set_next_state() end self.sound_manager_started = false for k,v in pairs(self.npc) do if(db.storage[k]) then xr_logic.issue_event(db.storage[k].object, db.storage[k][db.storage[k].active_scheme], "update") end local meet = db.storage[k] and db.storage[k].meet and db.storage[k].meet.meet_manager if meet then meet.npc_is_camp_director = self.director == k end end end -- Выбираем новую тему для саундменеджера (Для гитары и гармошки нужно будет юзать другой метод, чтобы не начали играть звук до того, как достанут инструмент) if(self.timeout~=0) and (self.timeout<=time_global()) then self:set_story() self.timeout = 0 end -- Болтовня в айдле if(self.active_state=="idle") then local npc_count = 0 local talkers = {} for k,v in pairs(self.npc) do npc_count = npc_count + 1 table.insert(talkers, k) end if(npc_count~=0) then self.idle_talker = talkers[math.random(#talkers)] xr_sound.set_sound_play(self.idle_talker, "state") end end end function CCampManager:set_next_state() --printf("CAMP set_next_state") local transitions = self.states[self.active_state].transitions local rnd = math.random(100) for k,v in pairs(transitions) do --printf("check %s value %s rnd %s", k, v, rnd ) if(rnd