Be sure that when you say something "does not work", you say both it's intended response (even if your question implies it) and what the expected response is (again, even if it's implied). Also be sure to say any errors you may be getting.
There's one thing with it, when you use this command on someone it will only do anything if,
at that moment, they are holding down their jump key and are on the ground. You'd need something that does this at any time. (Also you have a param of "ULib.cmds.PlayerArg" when your code suggests that it should be "ULib.cmds.PlayersArg" (due to the #target_ply))
Another thing is that clientside logic takes precedence over serverside logic. For example, you telling the client to +jump can be overridden by a client's +jump. Also even if they jump, your -jump immediately just makes them stop. Overall, your code does nothing but makes the person jump.
function ulx.bhop( calling_ply, target_ply, should_bhop )
target_ply:SetNWBool( "bhop", should_bhop ) -- A networked bool allows you to access values on a specific player.
ulx.fancyLogAdmin( calling_ply, "#A enabled Sick-Hops on #T", target_ply ) -- You have the "amount" in your fancyLogAdmin(), which is not necessary.
end
local bhop = ulx.command( "Fun", "ulx bhop", ulx.bhop, "!bhop" )
bhop:addParam{ type = ULib.cmds.PlayerArg }
bhop:addParam{ type = ULib.cmds.BoolArg, invisible = true }
bhop:defaultAccess( ULib.ACCESS_ALL ) -- I don't recommend this because this allows anyone to target anyone else (that their inheritance lets them)
bhop:setOpposite( "ulx unbhop", { _, _, false }, "!unbhop" )
bhop:help( "Enables Auto Hop on the target" )
And now you need something on the client to edit how a player moves. The best way to do this is by using
GM:CreateMove. Now I'd recommend making the bhop key something that isn't their IN_JUMP key. This is because of what I said earlier: their logic will override CreateMove's logic, even if it's clientside. According to the CreateMove wiki:
Due to this hook being clientside only, it could be overridden by the user allowing them to completely skip your logic, it is recommended to use GM:StartCommand in a shared file instead.Now, if you use something that isn't IN_JUMP, you don't have to worry about this.
For example:
if ( CLIENT ) then -- Put this in the same file as ulx.bhop() so you can do this
hook.Add( "CreateMove", "bhop", function( ucmd )
local ply = LocalPlayer() -- Just easier.
if ply:GetNWBool( "bhop" ) and ply:GetNWBool( "bhop" ) == true --[[ not necessary, but for more readability ]] and IsValid( ply ) and bit.band( ucmd:GetButtons(), IN_DUCK ) > 0 then -- bit.band performs bitwise "and" on GetButtons() and IN_DUCK (so basically, checks if IN_DUCK (their duck) is being performed).
if ply:OnGround() then -- If they're not on the ground, don't do anything
ucmd:SetButtons( bit.bor( ucmd:GetButtons(), IN_JUMP ) ) -- Performs bitwise "or" on GetButtons() and IN_JUMP. Basically, sets their status to either crouch (IN_DUCK) or jump (IN_JUMP).
end
end
end )
end
Sorry I kinda wrote it for you, I tried to comment it so you'd understand what it was, but that should work (it's actually taken from a separate addon I wrote that had this exact thing in it). Basically, you need something that is globally accessible, and actually does something after it ends the jump.