local PLAYER_PHYS_MASS = 80.0 local PLAYER_PHYS_RADIUS = 0.40 local PLAYER_PHYS_HEIGHT = 1.79 local PLAYER_PHYS_JUMPDIST = PLAYER_PHYS_RADIUS local PLAYER_PHYS_JUMPHEIGHT = 2.0 local PLAYER_PHYS_JUMPSPEEDY = 5.0 local PLAYER_PHYS_WALK_SPEED = 5.5 local PLAYER_PHYS_RUN_SPEED_MUL = 1.4 local PLAYER_PHYS_MOVE_SPEED_EXP = 1.0 local PLAYER_PHYS_FLY_SPEED_EXP = 4.0 local AIR_CONTROL = 0.2 -- игрок actor_player = inherit_table(actor_base) actor_player.m_camera_offset_y = 0.5 function actor_player:on_init() actor_base.on_init(self) g_player = self self:create_player_body(PLAYER_PHYS_RADIUS, PLAYER_PHYS_HEIGHT - PLAYER_PHYS_RADIUS * 2.0, 80.0, 0.0, 0.0) self:activate_camera() local ent = engine.create_entity("weapon_ump") engine.add_entity_to_world(ent) self.m_weapon_entity_id = ent:get_id() --engine.play_sound_3d("data/sounds/test/test_music_64Kbps.mp3", 0.0, 0.0, 0.0) end function actor_player:on_shutdown() actor_base.on_shutdown(self) g_player = nil end function actor_player:on_update(dt) actor_base.on_update(self, dt) self:update_camera_look() -- C++ --self:update_camera() Lua (for perfomance should call from C++) --self:update_camera_movement(dt) -- C++ flying mode --self:update_body_movement(dt) -- C++ self:update_player_movement(dt) local ent = engine.get_entity_from_id(self.m_weapon_entity_id) ent:set_relative_position_to_camera(self) self:action_update() end function actor_player:action_update() local action = self:get_action() local ent = engine.get_entity_from_id(self.m_weapon_entity_id) if ent then if action == ACTION_FIRE then ent:set_state(WEAPON_FSM_STATE_ATTACK) elseif action == ACTION_RELOAD then ent:set_state(WEAPON_FSM_STATE_RELOAD) end end end -- TODO: remove function vec3_magnitude(_x, _y, _z) return math.sqrt(_x * _x + _y * _y + _z * _z) end function vec3_normalize(_x, _y, _z) local mag = vec3_magnitude(_x, _y, _z) if mag == 0 then return 0, 0, 0 end return _x / mag, _y / mag, _z / mag end function vec3_cross(_x1, _y1, _z1, _x2, _y2, _z2) return _y1 * _z2 - _y2 * _z1, _z1 * _x2 - _z2 * _x1, _x1 * _y2 - _x2 * _y1 end function actor_player:update_player_movement(dt) local movement = self:get_movement() local speed = 4.0 local up_x, up_y, up_z = camera.get_up() local front_x, front_y, front_z = camera.get_front() if not self:is_noclip() then front_y = 0.0 end local final_front_x, final_front_y, final_front_z = vec3_normalize(front_x, front_y, front_z) local cross_x, cross_y, cross_z = vec3_cross(final_front_x, final_front_y, final_front_z, up_x, up_y, up_z) local final_cross_x, final_cross_y, final_cross_z = vec3_normalize(cross_x, cross_y, cross_z) local dir_x, dir_y, dir_z = 0.0, 0.0, 0.0 if (movement & EMovementDir_Forward) ~= 0 then dir_x = dir_x + final_front_x dir_y = dir_y + final_front_y dir_z = dir_z + final_front_z end if (movement & EMovementDir_Backward) ~= 0 then dir_x = dir_x - final_front_x dir_y = dir_y - final_front_y dir_z = dir_z - final_front_z end if (movement & EMovementDir_Left) ~= 0 then dir_x = dir_x - final_cross_x dir_y = dir_y - final_cross_y dir_z = dir_z - final_cross_z end if (movement & EMovementDir_Right) ~= 0 then dir_x = dir_x + final_cross_x dir_y = dir_y + final_cross_y dir_z = dir_z + final_cross_z end local current_vel_x, current_vel_y, current_vel_z = self:get_velocity() local vel_x = dir_x * speed local vel_y = dir_y * speed local vel_z = dir_z * speed if self:is_noclip() then if (movement & EMovementDir_None) ~= 0 then self:set_velocity(vel_x, vel_y, vel_z) else self:set_velocity(0, 0, 0) end return end if self:on_ground() then self:set_velocity(vel_x, current_vel_y, vel_z) if (movement & EMovementDir_Jump) ~= 0 then self:set_velocity(current_vel_x, PLAYER_PHYS_JUMPSPEEDY, current_vel_z) --console.print("!!! JUMP") end else local air_vel_x = current_vel_x + dir_x * speed * AIR_CONTROL * dt local air_vel_y = current_vel_y + dir_y * speed * AIR_CONTROL * dt local air_vel_z = current_vel_z + dir_z * speed * AIR_CONTROL * dt self:set_velocity(air_vel_x, current_vel_y, air_vel_z) end end local g_yaw = 0.0 local g_pitch = 0.0 function actor_player:update_camera() if not input.get_lock_mouse() then return end local mousePosX, mousePosY = input.get_mouse_pos() local sensitivity = 0.15 -- #TODO: input.get_mouse_sensitivity() g_yaw = g_yaw + (mousePosX * sensitivity) g_pitch = g_pitch - (mousePosY * sensitivity) -- lock axis if g_pitch > 89.0 then g_pitch = 89.0 end if g_pitch < -89.0 then g_pitch = -89.0 end camera.set_yaw_pitch(g_yaw, g_pitch) end function actor_player:on_collide(other) --console.print(string.format("actor_player:on_collide: %s", other:get_classname())) -- put_debug_string_to_screen(string.format("actor_player:on_collide: %s", other:get_classname()), 4) -- FOR TEST -- other:mark_for_delete() end function actor_player:get_health() return 100.0 end