---------------------------------------------------------------------------------------------------------------------- -- Схема изменений положения тела -- автор: Диденко Руслан (Stohe) -- TODO: ---------------------------------------------------------------------------------------------------------------------- stand = 0 sit = 2 sit_wait = 3 sleep = 4 class "body_state" function body_state:__init(npc) self.npc = npc self.target_state = xr_state.stand self.current_state = xr_state.stand self.tanim = { [xr_state.stand] = { [xr_state.sit] = {"stalker_2_down"}, [xr_state.sit_wait] = {"stalker_3_down"}, [xr_state.sleep] = {"stalker_2_down", "spit_0"} }, [xr_state.sit] = { [xr_state.stand] = {"stalker_2_up"}, [xr_state.sit_wait] = {"stalker_2v3"}, [xr_state.sleep] = {"spit_0"} }, [xr_state.sit_wait] = { [xr_state.stand] = {"stalker_3_up"}, [xr_state.sit] = {"stalker_3v2"} }, [xr_state.sleep] = { [xr_state.stand] = {"spit_3", "stalker_2_up"}, [xr_state.sit] = {"spit_3"}}} self.ianim = { [xr_state.sit] = "stalker_2_1", [xr_state.sit_wait] = "item_0_idle_0", [xr_state.sleep] = "spit_2" } self.states = { last_id = nil, current_state = nil, begin = nil, idle = nil } self.animations = { idle = { state_id = xr_state.stand, prop = { maxidle = 5, sumidle = 3, rnd = 80 }, into = nil, out = nil, idle = { [0] = "idle_0_idle_1", [1] = "idle_1_idle_1", [2] = "idle_2_idle_1", [3] = "idle_3_idle_1", [4] = "idle_4_idle_1" }, rnd = { [0] = { "idle_0_idle_0", "idle_0_idle_2", "idle_0_idle_3", "idle_0_idle_4" }, [1] = { "idle_1_idle_0", "idle_1_idle_2", "idle_1_idle_3", "idle_1_idle_4" }, [2] = { "idle_2_idle_0", "idle_2_idle_2", "idle_2_idle_3", "idle_2_idle_4", "idle_2_idle_5", "idle_2_idle_6", "idle_2_idle_7", "idle_2_idle_8", "idle_2_idle_9" }, [3] = { "idle_3_idle_0", "idle_3_idle_2", "idle_3_idle_3", "idle_3_idle_4" }, [4] = { "idle_4_idle_0", "idle_4_idle_2", "idle_4_idle_3", "idle_4_idle_4" }}}, prisluh = { state_id = xr_state.stand, prop = { maxidle = 5, sumidle = 3, rnd = 80 }, into = { [0] = "prisluh_0_idle_0", [1] = "prisluh_1_idle_0", [2] = "prisluh_2_idle_0", [3] = "prisluh_3_idle_0", [4] = "prisluh_4_idle_0" }, out = { [0] = "prisluh_0_idle_5", [1] = "prisluh_1_idle_5", [2] = "prisluh_2_idle_6", [3] = "prisluh_3_idle_5", [4] = "prisluh_4_idle_5" }, idle = { [0] = "prisluh_0_idle_1", [1] = "prisluh_1_idle_1", [2] = "prisluh_2_idle_1", [3] = "prisluh_3_idle_1", [4] = "prisluh_4_idle_1" }, rnd = { [0] = { "prisluh_0_idle_2", "prisluh_0_idle_3", "prisluh_0_idle_4" }, [1] = { "prisluh_1_idle_2", "prisluh_1_idle_3", "prisluh_1_idle_4" }, [2] = { "prisluh_2_idle_2", "prisluh_2_idle_3", "prisluh_2_idle_4", "prisluh_2_idle_5" }, [3] = { "prisluh_3_idle_2", "prisluh_3_idle_3", "prisluh_3_idle_4" }, [4] = { "prisluh_4_idle_2", "prisluh_4_idle_3", "prisluh_4_idle_4" }}}, poisk = { state_id = xr_state.stand, prop = { maxidle = 5, sumidle = 3, rnd = 80 }, into = nil, out = nil, idle = { [0] = "poisk_0_idle_1", [1] = "poisk_1_idle_1", [2] = "poisk_2_idle_1", [3] = "poisk_3_idle_1", [4] = "poisk_4_idle_1" }, rnd = { [0] = { "poisk_0_idle_0", "poisk_0_idle_2", "poisk_0_idle_3", "poisk_0_idle_4" }, [1] = { "poisk_1_idle_0", "poisk_1_idle_2", "poisk_1_idle_3", "poisk_1_idle_4" }, [2] = { "poisk_2_idle_0", "poisk_2_idle_2", "poisk_2_idle_3", "poisk_2_idle_4" }, [3] = { "poisk_3_idle_0", "poisk_3_idle_2", "poisk_3_idle_3", "poisk_3_idle_4" }, [4] = { "poisk_4_idle_0", "poisk_4_idle_2", "poisk_4_idle_3", "poisk_4_idle_4" }}}, hide = { state_id = xr_state.stand, prop = { maxidle = 5, sumidle = 3, rnd = 80 }, into = nil, out = nil, idle = { [0] = "d_0_idle_1", [1] = "d_1_idle_1", [2] = "d_2_idle_1", [3] = "d_3_idle_1", [4] = "d_4_idle_1" }, rnd = { [0] = { "d_0_idle_0", "d_0_idle_2" }, [1] = { "d_1_idle_0", "d_1_idle_2" }, [2] = { "d_2_idle_0", "d_2_idle_2" }, [3] = { "d_3_idle_0", "d_3_idle_2" }, [4] = { "d_4_idle_0", "d_4_idle_2" }}}, hello = { state_id = xr_state.stand, prop = { maxidle = 3, sumidle = 1, rnd = 100 }, into = nil, out = nil, idle = { [0] = "idle_0_idle_1", [1] = "idle_1_idle_1", [2] = "idle_2_idle_1", [3] = "idle_3_idle_1", [4] = "idle_4_idle_1" }, rnd = { [0] = { "hello_0_idle_0" }, [1] = { "hello_1_idle_0" }, [2] = { "hello_2_idle_0" }, [3] = { "hello_3_idle_0" }, [4] = { "hello_4_idle_0" }}}, refuse = { state_id = xr_state.stand, prop = { maxidle = 3, sumidle = 3, rnd = 100 }, into = nil, out = nil, idle = nil, rnd = { [0] = { "net_0_0", "net_0_1" }, [1] = { "net_1_0" }, [2] = { "net_2_0" }, [3] = { "net_3_0" }, [4] = { "net_4_0" }}}, claim = { state_id = xr_state.stand, prop = { maxidle = 5, sumidle = 2, rnd = 100 }, into = nil, out = nil, idle = nil, rnd = { [0] = { "gop_stop_1_0" }, [1] = { "gop_stop_1_0" }, [2] = { "gop_stop_2_0" }, [3] = { "gop_stop_3_0" }, [4] = { "gop_stop_4_0" }}}, backoff = { state_id = xr_state.stand, prop = { maxidle = 5, sumidle = 2, rnd = 100 }, into = nil, out = nil, idle = nil, rnd = { [0] = { "uhodi_1_0" }, [1] = { "uhodi_1_0" }, [2] = { "uhodi_2_0" }, [3] = { "uhodi_3_0" }, [4] = { "uhodi_4_0" }}}, backoff2 = { state_id = xr_state.stand, prop = { maxidle = 5, sumidle = 2, rnd = 100 }, into = nil, out = nil, idle = nil, rnd = { [0] = { "uhodi_1_1" }, [1] = { "uhodi_1_1" }, [2] = { "uhodi_2_1" }, [3] = { "uhodi_3_1" }, [4] = { "uhodi_4_1" }}} } --print_table(self.animations) end --' Проверяет закончили ли мы изменение положения тела function body_state:finish_state() if self.target_state == xr_state.stand and self.npc:animation_count() == 0 then self.current_state = self.target_state end if self.target_state ~= xr_state.stand and self.npc:animation_count() <= 1 then self.current_state = self.target_state end return self.target_state == self.current_state end function body_state:set_state(id) if id ~= self.current_state and id ~= self.target_state then self.npc:clear_animations() self.target_state = id self:transanim(self.npc, id) return true end return false end function body_state:transanim(object, target_state) if self.tanim[self.current_state][target_state] ~= nil then for k,v in pairs(self.tanim[self.current_state][target_state]) do object:add_animation(v, true) end end if self.ianim[target_state] ~= nil then object:add_animation(self.ianim[target_state], true) end end function body_state:weapon_slot() local weapon = self.npc:active_item() if weapon == nil or self.npc:weapon_strapped() == true then return 0 end local id = get_clsid(weapon) if id == nil then return 0 end if id == clsid.wpn_pm_s or id == clsid.wpn_walther_s or id == clsid.wpn_hpsa_s or id == clsid.wpn_fort_s or id == clsid.wpn_usp45_s then return 1 end if id == clsid.wpn_vintorez_s or id == clsid.wpn_val_s or id == clsid.wpn_groza_s or id == clsid.wpn_fn2000_s or id == clsid.wpn_ak74_s or id == clsid.wpn_lr300_s or id == clsid.wpn_svd_s or id == clsid.wpn_svu_s then return 2 end if id == clsid.wpn_shotgun_S then return 3 end if id == clsid.wpn_rpg7_s then return 4 end return 0 end function body_state:anim_update(type) --' Определяем - это у нас включение новой анимации или продолжение старой if type ~= self.states.current_state then if type ~= nil then printf("ANIMS: |%s| for %s", type, self.npc:name()) else printf("ANIMS: |nil| for %s", self.npc:name()) end --' Проверка на существование темы if type ~= nil and self.animations[type] == nil then printf("ERROR: Non existen ANIM STATEd called: %s", type) return end --' завершение старой self.npc:clear_animations() if self.states.current_state ~= nil then if self.animations[self.states.current_state].out ~= nil then self.npc:add_animation(self.animations[self.states.current_state].out[self:weapon_slot()], true) end end --' простановка новой if type ~= nil then --' Проверка соответствия состояния. if self.current_state ~= self.animations[type].state_id then self:set_state(self.animations[type].state_id) end if self.animations[type].into ~= nil then self.npc:add_animation(self.animations[type].into[self:weapon_slot()], true) end if self.animations[type].idle ~= nil then self.npc:add_animation(self.animations[type].idle[self:weapon_slot()], true) end else self:set_state(xr_state.stand) end self.states.current_state = type self.states.last_id = nil self.states.begin = nil self.states.idle = nil end --' Определяем нужно ли добавлять анимацию или ждать if (self.states.begin == nil or time_global() - self.states.begin > self.states.idle) and self.npc:animation_count() <= 1 and self.states.current_state ~= nil then --' Определение промежутков времени между анимациями self.states.begin = time_global() self.states.idle = (math.random(self.animations[self.states.current_state].prop.maxidle) + self.animations[self.states.current_state].prop.sumidle) * 1000 if math.random(100) < self.animations[self.states.current_state].prop.rnd then local r if #self.animations[self.states.current_state].rnd[self:weapon_slot()] > 1 then if self.states.last_id == nil then r = math.random(#self.animations[self.states.current_state].rnd[self:weapon_slot()]) else r = math.random(#self.animations[self.states.current_state].rnd[self:weapon_slot()]-1) if r >= self.states.last_id then r = r + 1 end end self.states.last_id = r else r = 1 end self.npc:clear_animations() if self.animations[self.states.current_state].rnd[self:weapon_slot()][r] ~= nil then self.npc:add_animation (self.animations[self.states.current_state].rnd[self:weapon_slot()][r], true) else printf("ANIM ERROR: Select wrong animation %d of %d, type: %s, weapon_slot: %d", r, #self.animations[self.states.current_state].rnd[self:weapon_slot()], self.states.current_state, self:weapon_slot() ) end if self.animations[type].idle ~= nil then self.npc:add_animation (self.animations[self.states.current_state].idle[self:weapon_slot()], true) end end end --printf("animcount %d", self.npc:animation_count()) return self:finish_state() and self.npc:animation_count() == 0 end ---------------------------------------------------------------------------------------------------------------------- -- Functions ---------------------------------------------------------------------------------------------------------------------- -- Проверка, изменилось ли уже положение тела или нет function finish_state(npc) return db.storage[npc:id()].state:finish_state() end function change_state(npc, id) return db.storage[npc:id()].state:set_state(id) end function anim_update(type, npc) return db.storage[npc:id()].state:anim_update(type) end