How to completely lock the player's mouse

I’m making a script that spawns antlion worker heads on people’s heads when they spawn. I have it Freezing the player on spawn and setting the position and angle of the antlion worker head according to the position and angle of the player’s Forward attachment. Then after 0.25 seconds, the head parents to the player. Then after 0.75 seconds, the head parents to the attachment point “forward”. If you don’t move your mouse before/while spawning, it works fine:

But if you do, the position gets fucked up bad:

How do I fix? I’ve tried everything I can. I’ve locked the player, I’ve tried the InputMouseApply hooks and the AdjustMouseSensitivity hooks. I’m really at a loss for an answer, and was hoping you guys could help me find a solution.

Here’s the code:

[lua]function CreateHeadOnSpawn( ply )
local prev_head = ply:GetNWEntity( “head” )

local eyeAttachID = ply:LookupAttachment( "forward" )
local eyeAngPos = ply:GetAttachment( eyeAttachID )
local eyeAng = ( eyeAngPos.Ang:Right() * -1 ):Angle()
local eyePos = eyeAngPos.Pos - eyeAng:Up()*25 - eyeAng:Forward()*16

if ply:GetNWEntity("phys_head"):IsValid() then
	ply:GetNWEntity("phys_head"):Remove()
end

if prev_head:IsValid() then
	if prev_head:GetParent() != ply then
		prev_head:SetParent( ply )
		prev_head:SetPos( eyePos )
		prev_head:SetAngles( eyeAng )
		prev_head:Fire( "SetParentAttachmentMaintainOffset", "forward", 0.01 )
	end
else
	local head = ents.Create( "prop_dynamic" )
	head:SetModel( "models/Gibs/antlion_worker_gibs_head.mdl" )
	head:Spawn()
	
	head:SetPos( eyePos )
	head:SetAngles( eyeAng )
	
	head:SetCollisionGroup( COLLISION_GROUP_DEBRIS )
	
	ply:SetNWEntity( "head", head )
	
	ply:Freeze( true )
	
	timer.Create( "parentheadtoplayer", 0.25, 1, ParentHeadToPlayer, head, ply )
	timer.Create( "playerunfreeze", 1, 1, PlayerUnfreeze, ply )
end

end
hook.Add( “PlayerSpawn”, “CreateHeadOnSpawn”, CreateHeadOnSpawn )

function ParentHeadToPlayer( head, ply )
head:SetParent( ply )
head:Fire( “SetParentAttachmentMaintainOffset”, “forward”, 0.5 )
end

function PlayerUnfreeze( ply )
ply:Freeze( false )
end

function GetPlayerHeadPosAndVelocityOnDeath( prey, pred, dinfo )
local head = prey:GetNWEntity( “head” )

if head:IsValid() then
	prey:SetNWVector( "death_head_pos", head:GetPos() )
	prey:SetNWVector( "death_head_ang", head:GetAngles() )
end

prey:SetNWVector( "death_vel", prey:GetPhysicsObject():GetVelocity() )

end
hook.Add( “DoPlayerDeath”, “GetPlayerHeadPosAndVelocityOnDeath”, GetPlayerHeadPosAndVelocityOnDeath )

function DetachHeadFromRagdollOnDeath( prey, pred, dinfo )
local head = prey:GetNWEntity( “head” )
local headPos = prey:GetNWVector( “death_head_pos” )
local headAng = prey:GetNWVector( “death_head_ang” )

if head:IsValid() then
	head:Remove()
	
	local phys_head = ents.Create("prop_physics")
	phys_head:SetModel( "models/Gibs/antlion_worker_gibs_head.mdl" )
	phys_head:Spawn()
	
	if headAng != nil then
		phys_head:SetAngles( headAng )
	end
	
	if headPos != nil then
		phys_head:SetPos( headPos )
	else
		phys_head:SetPos( prey:GetPos() + Vector(0,0,32) )
	end
	
	phys_head:SetMoveType( MOVETYPE_VPHYSICS )
	phys_head:SetCollisionGroup( COLLISION_GROUP_DEBRIS )
	
	local preyDeathVel = prey:GetNWVector( "death_vel" )
	if preyDeathVel != nil then
		phys_head:GetPhysicsObject():SetVelocity( preyDeathVel )
	end
	
	prey:SetNWEntity( "phys_head", phys_head )
end

end
hook.Add( “PlayerDeath”, “DetachHeadFromRagdollOnDeath”, DetachHeadFromRagdollOnDeath )[/lua]

Please help me fix this. I’ve spent the last 3 days on it…

-snip- gimme a second.

[editline]03:01PM[/editline]

Why is it running on timers? Can’t it just be done instantly…

Or try freezing the player before you create the head as lua reads top to bottom.

The head is placed correctly, but it’s position gets screwed up when it parents to the player.

[editline]01:25AM[/editline]

And it can’t be done instantly because then it always screws up.

You can always update the positions and angles in the entities Draw() function that way it will still work even if they move and you won’t need to stop the player from moving.

I tried doing that in a think function and it didn’t work, the angles and position were inconsistent for some reason…and the entities are prop_dynamic so I don’t know if it’s possible to do a think function for a prop_dynamic…

Update the positions and angles in a think hook and remove all instances of SetParent this will work i just finished helping someone with this and it was a success. Positioning doesn’t like to work very well on a parented prop… At least not the way i do it.

Rawr that doesn’t work. Like expected, that makes it lag behind the player noticeably. Does anybody else know of a solution? Is there ANY way to do this without making it into a SENT? Please please please halp :3

Here is a hacky method to lock the players movements.

Freeze them then do gui.EnableScreenClicker(true) while they are frozen…

I’ll give it a shot later. Work soon :frowning:

I have probably read this wrong but to freeze someone cant you do ply:Lock() and ply:UnLock()

That works exactly like player freeze.

Attach it to the player instantly. If the offsets are wrong just change them.