Files
pke/data/scripts/weapons/weapon_base.lua
2026-03-11 23:25:46 +03:00

146 lines
4.0 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-----------------------------------------------------------
-- 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