Reducing Fall Damage
From GMod Wiki
Lua:Articles:Scripted Weapons: Reduce fall damage |
Description: | Tutorial explaining how to reduce fall damage only while holding this SWEP. It also explains how to use hooks. |
Original Author: | Vampired |
Created: | 26 August 2007 |
This tutorial expects you to already have your basic SWEP code. Also note that all this code is SERVER side.
Contents |
Holster and Deploy
First we create the Holster and Deploy functions. Inside the functions at the moment are 'return true'. This tells what ever calls the script that we want to allow holstering and deploying.
Deploy is when we bring the weapon out and hold it. Holster is when we put it back in our inventory.
function SWEP:Deploy() return true end function SWEP:Holster() return true end
Now we want to make it set a variable on our player object. I'll focus first on the Deploy function
function SWEP:Deploy() self.Owner.ShouldReduceFallDamage = true return true end
The 'self' bit refers to the weapon object, you can see this from the word before the colon in the function, which in this case is SWEP. The 'Owner' part is a variable attached to the weapon which is the player who owns the weapon. And the 'ShouldReduceFallDamage' is a variable I have just made up. It can be called anything but I chose a variable that makes sense. Now you can do the same for Holster but replace the word 'true' with 'false'
Setting up the hook
Now we need to hook into the EntityTakeDamage hook. Firstly we need to make a new function.
local function ReduceFallDamage(ent, inflictor, attacker, amount, dmginfo) end
Now we hook it with a special function that calls our function whenever an entity will take some damage.
hook.Add("EntityTakeDamage", "ReduceFallDamage", ReduceFallDamage)
The first argument is 'EntityTakeDamage' and it is in quotes. This is the actual hook that we want. The hook can be any [Hook] but for this script we need EntityTakeDamage.
The second argument is 'ReduceFallDamage' and this is also in quotes. This is a unique string that is used to identify our hook. This can be anything but I've chosen something that is obvious what it does.
The third and final argument is 'ReduceFallDamage' and is NOT in quotes. This is exactly the same name as our function we created earlier, remember it is capital sensitive.
Make the hook do something
Firstly we want to make sure the entity is a player.
if ent:IsPlayer() then
Then we want to make sure that the player is holding our weapon, this is why we have set up our variable in the Holster and Deploy functions.
if ent.ShouldReduceFallDamage == true then
And finally we want to make sure the damage taken is fall damage (and not shoot or explosion damage).
if dmginfo:IsFallDamage() then
Right, now we can combine these if statements together into our function.
local function ReduceFallDamage(ent, inflictor, attacker, amount, dmginfo) if ent:IsPlayer() and ent.ShouldReduceFallDamage and dmginfo:IsFallDamage() then -- commands end end
Notice how I've combined them with an 'and'. Also notice that I have removed the ' == true', because 'if x == true then' is the same as 'if x then' (this is not universally true, but in this case they are equivalent).
Reducing the damage
Right now, nothing will actually happen in-game, so we need to change the amount of damage the player will receive.
local function ReduceFallDamage(ent, inflictor, attacker, amount, dmginfo) if ent:IsPlayer() and ent.ShouldReduceFallDamage and dmginfo:IsFallDamage() then dmginfo:SetDamage(1) end end
I've used SetDamage here, but you can also use ScaleDamage instead. This line that I have added changes the amount of damage to 1 so when the player lands, he will only lose 1 health, if any, even from a great height.
All together
All this code will go in your SWEP file. If you're using an init.lua file, it will go in there. Otherwise wrap it around with 'if SERVER then ... end' and it will go in shared.lua
function SWEP:Deploy() self.Owner.ShouldReduceFallDamage = true return true end function SWEP:Holster() self.Owner.ShouldReduceFallDamage = false return true end local function ReduceFallDamage(ent, inflictor, attacker, amount, dmginfo) if ent:IsPlayer() and ent.ShouldReduceFallDamage and dmginfo:IsFallDamage() then dmginfo:SetDamage(1) end end hook.Add("EntityTakeDamage", "ReduceFallDamage", ReduceFallDamage)
The author has tested and proven this code to work.