----------------------------------------------------------- -- weapon_base.lua, Базовый скрипт оружия ----------------------------------------------------------- -- индификаторы состояний FSM WEAPON_FSM_STATE_NONE = 0 WEAPON_FSM_STATE_IDLE = 1 WEAPON_FSM_STATE_ATTACK = 2 WEAPON_FSM_STATE_ATTACK2 = 3 WEAPON_FSM_STATE_RELOAD = 4 -- базовый класс оружия weapon_base = inherit_table(game_object) -- инициализация FSM weapon_base.m_fsm = {} function weapon_base:on_init() game_object.on_init(self) -- начальное состояние FSM self.m_state = WEAPON_FSM_STATE_NONE self.m_next_state = WEAPON_FSM_STATE_IDLE self.m_state_time = 0.0 self.m_end_state_time = 0.0 self.m_damage = 25 end function weapon_base:on_shutdown() game_object.on_shutdown(self) end function weapon_base:on_update(dt) game_object.on_update(self, dt) self:on_fsm_state_update(dt) end function weapon_base:on_fsm_state_update(dt) -- обновления времени self.m_state_time = self.m_state_time + dt -- проверка на стрельбу if (self.m_state == WEAPON_FSM_STATE_ATTACK or self.m_state == WEAPON_FSM_STATE_ATTACK2 or self.m_state == WEAPON_FSM_STATE_RELOAD) and self.m_state_time >= self.m_end_state_time then -- переходим в ожидание self:set_state(WEAPON_FSM_STATE_IDLE) end -- костыль, нету анимаций бесконечных if self.m_state == WEAPON_FSM_STATE_IDLE and self.m_state_time >= self.m_end_state_time then -- переходим в ожидание self:set_state(WEAPON_FSM_STATE_IDLE) end self:fsm_update(dt) end function weapon_base:set_state(next_state) if self.m_state == next_state or self.m_next_state == next_state then return end if (self.m_state == WEAPON_FSM_STATE_ATTACK or self.m_state == WEAPON_FSM_STATE_RELOAD) and next_state ~= WEAPON_FSM_STATE_IDLE then return end self.m_next_state = next_state console.print(string.format("weapon_base:set_state: switich to '%d' ", next_state)) end function weapon_base:fsm_update(dt) -- надо ли менять состояние if self.m_next_state ~= self.m_state then self:on_state_switch(self.m_next_state) -- сброс времени и установка его на таймер анимации self.m_state_time = 0.0 self.m_end_state_time = self:get_animation_time(self:get_current_animation()) console.print(string.format("weapon_base:fsm_update: switched from '%d' to '%d', end time %f ", self.m_state, self.m_next_state, self.m_end_state_time)) self.m_state = self.m_next_state end end function weapon_base:find_fsm_state(state) for k, v in pairs(self.m_fsm) do if k == state then return v end end console.print(string.format("weapon_base:find_fsm_state: state '%d' not found or not registered", state)) return nil end function weapon_base:on_state_switch(state) -- ищем стейт в таблице local fsm_state = self:find_fsm_state(state) if not fsm_state then return end local anim_id = self:find_animation(fsm_state.anim) self:play_animation(anim_id, fsm_state.anim_playback) if fsm_state.anim_sound then engine.play_sound(fsm_state.anim_sound) end if fsm_state.anim_speed then self:set_animation_speed(fsm_state.anim_speed) end end function weapon_base:set_relative_position_to_camera( ent ) local camX, camY, camZ = camera.get_position() local frontX, frontY, frontZ = camera.get_front() local rightX, rightY, rightZ = camera.get_right() local upX, upY, upZ = camera.get_up() self:set_rotation_from_vectors(frontX, frontY, frontZ, rightX, rightY, rightZ, upX, upY, upZ) local offsetx = 0.0 local offsety = 0.0 local offsetz = 0.0 local x = camX + (rightX * offsetx) + (upX * offsety) + (frontX * offsetz) local y = camY + (rightY * offsetx) + (upY * offsety) + (frontY * offsetz) local z = camZ + (rightZ * offsetx) + (upZ * offsety) + (frontZ * offsetz) self:set_position(x, y, z) -- force update transform self:update_transform() end