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 local PLAYER_OFFSET_Y = 0.5 -- игрок actor_player = inherit_table(actor_base) actor_player.m_camera_offset_y = PLAYER_OFFSET_Y function actor_player:on_init() actor_base.on_init(self) g_player = self self.m_bobbing = 0.0 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() if action == ACTION_USE then self:on_use_action() end --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 function actor_player:on_use_action() local front_x, front_y, front_z = camera.get_front() local ray_x, ray_y, ray_z = camera.get_position() ray_x = ray_x + front_x ray_y = ray_y + front_y ray_z = ray_z + front_z local ray_end_x, ray_end_y, ray_end_z = camera.get_position() ray_end_x = ray_end_x + front_x * 1000 ray_end_y = ray_end_y + front_y * 1000 ray_end_z = ray_end_z + front_z * 1000 local trace = engine.trace_ray(ray_x, ray_y, ray_z, ray_end_x, ray_end_y, ray_end_z, self) if trace.hit then local traced_ent = engine.get_entity_from_id(trace.entity_id) if traced_ent then local classname = traced_ent:get_classname() put_debug_string_to_screen(string.format("actor_player:on_use_action: %s", traced_ent:get_classname()), 1) end end end function actor_player:update_camera_bobbing(dt) local vel_x, vel_y, vel_z = self:get_velocity() self.m_bobbing = self.m_bobbing + dt end function actor_player:update_player_movement(dt) local movement = self:get_movement() local speed = 2.5 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