GetFallDamage not working?

I’m using Gmod 13 if it makes a difference (I don’t think it’s changed).
So I put this basic code together just to test it, it doesn’t work however.

[lua]
function GetFallDamage( ply, speed )
return 20
end

hook.Add(“GetFallDamage”, “Get Fall Damage”, GetFallDamage)
[/lua]

It doesn’t change the fall damage.

Try not using the hood.Add but rather calling the function directly, like:

[lua]
function GM:GetFallDamage( ply, speed )
return 20
end
[/lua]

Would it still work without it being in a gamemode?
Sorry if that’s a dumb question, I’m still new to Gmod’s Lua and can’t test it right now.

No, none of the GM functions will not work without being in a gamemode.

Are you saying the answer is “it won’t work”, then directly after saying the opposite?

Anyway, without putting it inside the gamemode files, you should do it like this (if someone knows a better way, go ahead and post it):
[lua]
hook.Add( “Initialize”, “GetFallDamage Init”, function( )
function GAMEMODE:GetFallDamage( ply, speed )
return 20
end
end )
[/lua]
You’ll have to load it in the Initialize hook, since GAMEMODE won’t exist before that.

Does the same apply to all other GM hooks? And since the GetFallDamage function is placed in that Initialize hook, wont it only run once when the server(in this case, my client) starts up?

No, it’s just only going to be defined after the gamemode has initialized. The function isn’t placed in the initialize hook, it replaces the original function when the initialize hook is called.

I guess the way I understood it was that hooks have a condition that must be met before calling the assigned function. I’m just trying to wrap my brain around why that works. Because the Initialize function only runs once at the start. So you would think it wouldn’t run that function when the player took fall damage.

You’re missing the point, read the code closer. See functions as variables. Without parenthesis after them, they’re just values representing the function. If you put parenthesis after the functions (or use them on another variable as a method), you call that function. The “return” command in a function determines what value you get from running a function.

In hooks, the regular way to hook a function is by defining the function, and then supplying the function itself to the hook, not by calling the function. A function “variable” is defined like so;


local function DoStuffOnInit()
        print("Doing stuff")
        local ididthis = "I did stuff"
        return ididthis
end

Now you have a variable called “DoStuffOnInit”, which is of the function type of value. If you run print( tostring( DoStuffOnInit ) ) (note: didn’t put any parenthesis after the function, therefore didn’t call/run it), it’ll print something like “function: 00414FB0”. Running print( tostring( DoStuffOnInit( ) ) ) (note: parenthesis after function; I called it) will print “I did stuff”.

Hooking this function to an event is done by supplying the hook.Add function with the function you want to hook, as a value. That is, you give it the function, not whatever the function returns. Hooked functions are then called when the function they’re hooked to is called; that is, functions hooked to the “Initialize” hook are called when the function GM:Initialize() is called (remember that calling a function is the same as running it).

What Shadow did above was hook a function to Initialize which overwrites the GM:GetFallDamage function with a new one. All he did was define the function inside the hook.Add call, instead of putting it in a variable before. The equivalent to that would be writing ‘return “I did stuff”’ in my function above, instead of first setting a variable with the same value.

In short, he did this:



local function GetFallDamageInit()
        function GAMEMODE:GetFallDamage( ply, speed )   -- overwrite GAMEMODE:GetFallDamage
                return 20
        end
end
hook.Add("Initialize", "GetFallDamage Init", GetFallDamageInit)


Also, as far as I know, the source engine is event driven, or at least the Lua engine in Garry’s mod. This means that hooks aren’t called when a condition is met per sé (as in checking if the condition is met every tick; did player touch ground last tick? Apply fall damage. Has damage been applied? Reduce health. Has health been reduced? Bloody screen), but rather that it runs as soon as something which would mean the condition is met happens (like player touches ground -> apply fall damage -> reduce health -> bloody screen… SO REAL), which in my opinion is a much better technique.

Thanks dude, it finally clicked for me. Gmod’s Lua is pretty different than what I’m used to (Java), so thanks for clearing that up!

You’re very welcome :slight_smile: I’m glad I could help.

I have one more question if you don’t mind, why is it that for things like **[Gamemode.PlayerEnteredVehicle

http://wiki.garrysmod.com/favicon.ico](wiki.garrysmod.com/?title=Gamemode.PlayerEnteredVehicle)** and **[Gamemode.PlayerDeath

http://wiki.garrysmod.com/favicon.ico](wiki.garrysmod.com/?title=Gamemode.PlayerDeath)** don’t require you to override them using the Initialize hook? Because they both use GM, but you can simply use a Hook with them, but you can’t do that with the GetFallDamage.

When you do GM:GetFallDamage()
You are substituting the whole preset(Of the base gamemode) code, and when you do the hook.Add, you are adding code to the preset function code.
Imagine the base code being like:
[lua]
function GM:GetFallDamage()

return 10

end
[/lua]

When you do

[lua]
hook.Add(“GetFallDamage”, “ChangeFallDamage”, function()
return 20
end)

[/lua]

The base code then becomes:
[lua]

function GM:GetFallDamage()

return 20
return 10

end

[/lua]
Which the 2 returns conflict.
And when you do the GM:GetFallDamage, you re-set the whole code, the base then becomes:

[lua]

function GM:GetFallDamage()

return 20

end

[/lua]

Stuff like the PlayerDeath hooks accept the use of the hook.Add because it won’t really conflict with the base code.

If that’s how hooks work, wouldn’t it just return whatever comes first? I understand that having two returns in one function will only actually return the first one, but I don’t see how that is any different from just having the first one. I.e. I don’t see why “return 20” is different from “return 20 return 10” in practice. I honestly don’t see why GetFallDamage doesn’t work without overwriting it either, it’s been quite frustrating at times because it’s not the only hook acting like that.

I think that the second return overwrites the first, like if you did:

[lua]

Foo = 10 // Declares Foo and sets it to 10
Foo = 20 // Changes Foo to 20
[/lua]

This thread is awful so far, you guys seem to know nearly nothing about the gmod internals.

A hook will always work except another hook is returning something before it.

Overriding the gamemode function is BAD and you should FEEL BAD for doing it, because it’s an ugly and unclean way.

Also, whenever you test hooks, do debug printing or anything to make sure that the hook is actually called.

If you test scripts in gmod13 do not use the file name “test.lua” when you are in /lua/ because garry already has a test.lua there which will be ran rather than your file!

So then, what should I do? From the appearance of it I shouldn’t override it, so… should this be what I’m doing:
I haven’t tested it by the way.
[lua]
hook.Add(“Initialize”, “Init”, Funct)

function Funct()
hook.Add(“GetFallDamage”, “Fall”, function( ply, speed )
return 25
end )
end
[/lua]

Just add the hook, don’t add the hook within another hook.

It doesn’t work though. Didn’t you read the OP?

How and where did you run the code?

Did you make sure the code is actually being run?

Did you run the code on the server?