I want to disable fall damage while a player has the SWEP equipped, so the jump height isn't obnoxious. Here's my current code:
[CODE]function SWEP:Think()
if self.Owner:KeyPressed(IN_JUMP) && ( jumpcd + 5 <= CurTime() ) then
self.Owner:EmitSound("weapons/jump.wav")
jumpcd = CurTime()
end
function self.Owner:GetFallDamage( self.Owner, speed )
return 0
end
end[/CODE]
I know that I'm not supposed to use "self.Owner" when using global(?) functions, but I was experimenting. Here's the Wiki page for the function: [url]http://wiki.garrysmod.com/page/GM/GetFallDamage[/url]
Explanation of the solution would be nice, but is by no means required, as I'll probably figure it out myself and cry a little at my stupidity.
Just set a variable when they equip the gun to true, and when they put it away set it to false. That's one way.
[QUOTE=Nookyava;46701453]Just set a variable when they equip the gun to true, and when they put it away set it to false. That's one way.[/QUOTE]
Disregard that the function is in think. I want to know how to use it, period. I have no idea what the argument before the colon is (the Wiki says to use GM, but that's a global, nil value.) And the arguments in the parentheses: what is their relevance?
The way that function is used is it is called when a player lands on the ground to calculate how much damage they should take. It shouldn't be called on its own but should be called using local _damage = hook.Call( "GetFallDamage", GAMEMODE, _p, _p:GetVelocity( ) ); ..... although it'll only return a number, you'd need to apply damage manually if you do that. BUT, since it is a hook already implemented in the damage system, you'd need to create a hook to let it return 0 when the players current weapon is the specific weapon....
Take a look at this: [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/_systems/simple_godmode_system/sv_godmode.lua.html[/url]
Modify IsPlayerGodded function to include
[code]if ( IsValid( _p:GetActiveWeapon( ) ) && _p:GetActiveWeapon( ):GetClass( ) == "weapon_name" ) then return true; end[/code]
Then if they have "weapon_name" equipped and active, It'll make them immune to damage.
Only keep the falldamage hook though to make it so falldamage is removed but they can still take normal damage.
Also, don't overwrite the player_meta-table GetFallDamage function, otherwise the player will KEEP that setting. You need to use a hook.Add to achieve the functionality you want, but not for each player... Just a generalized one like I have in the godmode system..
...
It's a hook. You don't need anything before it. hook.Add.
[QUOTE=Nookyava;46701602]...
It's a hook. You don't need anything before it. hook.Add.[/QUOTE]
Using hook.Add in a Think hook isn't a good solution. Also, adding / re-creating a hook for each instance of the weapon isn't a good solution either. My post outlines where to create it ( same place as the godmode file ).
Never said to use it in a Think Hook. Don't put words in my mouth. Same goes for creating a hook for each instance. You overcomplicate things.
He just simply wants to know about using the hook correctly (assuming by his question of what goes before the :) he doesn't need you giving him something that will make absolutely no sense and looks confusing as hell to someone who is used to seeing it drawn out basic. Not to mention you're just giving the answer instead of letting them figure it out, which is the way I best learn and I feel many others do.
I explained how it is properly used at the top of my post before giving a link to a tutorial that essentially does the same thing while missing one check and having more than the hook that was needed. That tut also showed how the hook was used.
You simply said hook.Add with nothing before it which could've been confused for changing it to hook.Add inside the think function.
Saying hook.Add is directing him towards what he should be using. Any research into the matter (a simple google search) would show that hook.Add is used to call different, well, hooks.
He understand about returning 0, he just needed to know how to use the hook and see if the player was holding the weapon. He doesn't need some "magic" tutorial that Acecool whipped up. He just needs simple explanations.
[QUOTE=Nookyava;46701772]Saying hook.Add is directing him towards what he should be using. Any research into the matter (a simple google search) would show that hook.Add is used to call different, well, hooks.
He understand about returning 0, he just needed to know how to use the hook and see if the player was holding the weapon. He doesn't need some "magic" tutorial that Acecool whipped up. He just needs simple explanations.[/QUOTE]
So, from what you guys are saying, it should look like this?
[CODE]function SWEP:Think()
if self.Owner:KeyPressed(IN_JUMP) && speedmod == true && ( jumpcd + 5 <= CurTime() ) then
self.Owner:EmitSound("weapons/jump.wav")
jumpcd = CurTime()
end
function GetFall()
return 0
end
end
hook.Add ("GetFallDamage", "Fall", GetFall)[/CODE]
You may be right, but I wasn't sure how much experience the OP has with Lua which is why I posted the GodMode tut which shows how to add hooks and functions in addition to including the weapon check example.
Lua does allow creating functions inside functions so his code may not have given an error which is why I also explained why the hook was needed instead of replacing the original meta function for that player. Also, because of that idea I felt it more-so appropriate to explain the process in more detail coupled with the request of "I want to know how to use it, period".
Maybe I try to explain too many things, but I'm no Harry Potter, and the tuts are there to provide more information and more examples because I don't always have the ability to type up a lot of things in one sitting so they help me express myself better while hopefully helping the OP.
Alright, despite you guys' incessant, childish, unnecessary bickering, I found out what I was supposed to do, though I don't fully understand it. As someone just starting with Lua, coming from rudimentary knowledge of C#, hooks are a confusing ordeal and you guys' arguing about the correct way to use a function didn't help me whatsoever.
I have a variable that is toggled when the SWEP is equipped named "speedmod"
Here's what I did, nonetheless:
[CODE]function GetFall()
if (speedmod == true) then
return 0
end
end
hook.Add ("GetFallDamage", "Fall", GetFall)[/CODE]
[QUOTE=CornThatLefty;46702053]So, from what you guys are saying, it should look like this?[/QUOTE]
Not quite. You'd add the hook in a server-file.
Something like this also changing your jumpcd to a local player var instead of a global var which could be overwritten by other players,
those player variables need to be either self.jumpcd or _p.jumpcd...
In the first example I used self.Owner.__jumpcd and self.Owner.__speedmod... If they're weapon vars, change _p.__speedmod / _p.__jumpcd or _p.speedmod / _p.jumpcd depending on the example you choose to self.__speedmod / self.__jumpcd or self.speedmod / self.jumpcd. I wasn't sure if they're weapon variables, or supposed to be for the player. The way they are in your example makes them global and makes it so only one player can play the jump sound once every 5 seconds. I added a nil check too to ensure that if the value wasn't set, it would initialize within...
[code]function SWEP:Think()
local _p = self.Owner;
// If no owner, don't continue...
if ( !IsValid( _p ) ) then return; end
// Player jump key?
local _bInJump = _p:KeyPressed( IN_JUMP );
// Turned the global vars into LOCAL self.Owner vars... Update your swep to these or rename them without __
if ( _bInJump && _p.__speedmod && ( !_p.__jumpcd || CurTime( ) - _p.__jumpcd > 5 ) ) then
self.Owner:EmitSound( "weapons/jump.wav" );
_p.__jumpcd = CurTime( );
end
end
//
// String names of the SWEP which allows godmode, just add them all in lower-case.
// If the name contains spaces or starts with a number, use [ "123 name of weapon" ] = true;
// instead of name_of_weapon = true;
//
GODMODE_SWEP_LIST = {
// Normal String
admin_baton = true;
// Or if the weapon has spaces / numbers / non-normal string
-- [ "admin baton" ] = true;
};
//
// This function should return true for players that don't take damage; for my system IsAdmin is only
// true when player is in admin character / admin-mode which makes it impossible to play the game which
// prevents accidental abuse. For you, you may need to check TEAM_ADMIN, or group, etc...
//
// Uncomment the rules you want; feel free to add your own.
//
local function IsPlayerGodded( _p )
// If the player is invalid ( ie possibly connecting ), don't take damage
if ( !IsValid( _p ) ) then return true; end
// If player is on TEAM_ADMIN ( DarkRP? Etc may use this check )
-- if ( _p:Team( ) == TEAM_ADMIN ) then return true; end
// If player is in group admin ( DarkRP or other game-modes may use this )
-- if ( _p:IsUserGroup( "superadmin" ) || _p:IsUserGroup( "admin" ) ) then return true; end
// If player is holding a specific weapon
local _w = _p:GetActiveWeapon( );
if ( IsValid( _w ) && _w.GetClass && GODMODE_SWEP_LIST[ string.lower( _w:GetClass( ) ) ] ) then return true; end
// Maybe it is a variable we set ( on the server... )
if ( _p.__GodModeActive ) then return true; end
// All other cases...
return false;
end
//
// GetFallDamage GodMode; because of the way hooks work, we will only RETURN a value if all conditions are met
//
hook.Add( "GetFallDamage", "GetFallDamage:SWEPGodMode", function( _p, _fallspeed )
// We let IsPlayerGodded determine who takes damage or not ( such as connecting players, admins, etc... )
if ( IsPlayerGodded( _p ) ) then
return 0;
end
end );[/code]
shorter would be:
[code]function SWEP:Think()
local _p = self.Owner;
// If no owner, don't continue...
if ( !IsValid( _p ) ) then return; end
// Player jump key?
local _bInJump = _p:KeyPressed( IN_JUMP );
// Turned the global vars into LOCAL self.Owner vars... Update your swep to these or rename them without __
if ( _bInJump && _p.speedmod && ( !_p.jumpcd || CurTime( ) - _p.jumpcd > 5 ) ) then
self.Owner:EmitSound( "weapons/jump.wav" );
_p.jumpcd = CurTime( );
end
end
//
// String names of the SWEP which allows godmode, just add them all in lower-case.
// If the name contains spaces or starts with a number, use [ "123 name of weapon" ] = true;
// instead of name_of_weapon = true;
//
GODMODE_SWEP_LIST = {
// Normal String
admin_baton = true;
// Or if the weapon has spaces / numbers / non-normal string
-- [ "admin baton" ] = true;
};
//
// GetFallDamage GodMode; because of the way hooks work, we will only RETURN a value if all conditions are met
//
hook.Add( "GetFallDamage", "GetFallDamage:SWEPGodMode", function( _p, _fallspeed )
// We let IsPlayerGodded determine who takes damage or not ( such as connecting players, admins, etc... )
local _w = _p:GetActiveWeapon( );
// We make sure the weapon is valid first, and we make sure the GetClass function exists ( HL2 weapons would give an error ) then we check the class against existing keys in the db.
if ( IsValid( _w ) && _w.GetClass && GODMODE_SWEP_LIST[ string.lower( _w:GetClass( ) ) ] ) then
return 0;
end
end );
[/code]
[editline]13th December 2014[/editline]
[QUOTE=CornThatLefty;46702098]Alright, despite you guys' incessant, childish, unnecessary bickering, I found out what I was supposed to do, though I don't fully understand it. As someone just starting with Lua, coming from rudimentary knowledge of C#, hooks are a confusing ordeal and you guys' arguing about the correct way to use a function didn't help me whatsoever.
I have a variable that is toggled when the SWEP is equipped named "speedmod"
Here's what I did, nonetheless:
[CODE]function GetFall()
if (speedmod == true) then
return 0
end
end
hook.Add ("GetFallDamage", "Fall", GetFall)[/CODE][/QUOTE]
Alright, that would assign a global var which will affect EVERYONE in the server if true. Read this response to see how it can be resolved along with two examples, one using the godmode function, the other just using the hook.
Here are some other tutorials which may help:
Lua is a language of tables, this is used everywhere: [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/tables/quick_intro_to_tables.lua.html[/url]
Tables are optimized in Lua when utilized "correctly": [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/tables/searching_vs_managed_lists.lua.html[/url]
String concatenation: [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/strings/string_concatenation.lua.html[/url]
Autorefreshing and how / why things may or may not work ( depends on load-order ) [url]https://dl.dropboxusercontent.com/u/26074909/tutoring/includes/file_only_works_on_autorefresh_possible_reasons.lua.html[/url]
Some of these you may not need but when coming from a strict language, it may help to see some examples..
Here are some other topics which may help:
-------------------------------------------------------------
Generalized Lua Help ( Links to Wikis, Answers the question of "Where do I post a simple question or DarkRP Specific question", links to other resources compiled by forum members )
[url]https://dl.dropboxusercontent.com/u/26074909/tutoring/___welcome_docs/_welcome_general_lua_learning.lua.html[/url]
Useful Programs ( SteamCMD, Autosizer, Desktops, Process Explorer ) and Notepad++ Upgrades
[url]https://dl.dropboxusercontent.com/u/26074909/tutoring/___welcome_docs/_welcome_useful_programs_and_notepadpp_upgrades.lua.html[/url]
And, sorry about the bickering. It is good to know that you're coming from a stricter language and may need more examples. Hopefully they help. I also tutor when I can on Steam ( ask questions and I answer when I'm on; also have over 400 tuts I've written and still working on finalizing my website for relaunch which will include an online "class" for Lua and possibly other languages in the future )
Alternately, we can use features that have been added to the game with hook.Add and just pass the weapon.
[code]function SWEP:GetFallDamage( pl, speed )
if self.Owner == pl and self.Owner:GetActiveWeapon( ) == self then
return 0
end
end
function SWEP:Initialize( )
if SERVER then
hook.Add( "GetFallDamage", self, self.GetFallDamage )
end
self:SetHoldType( "desired hold type" )
end[/code]
It is fairly straight forward - GetFallDamage supplies us with the player, so first we check to see if the player who might be taking fall damage has this weapon. If they do, we see if they have it equipped at the time ( you could remove the "and self.Owner:GetActiveWeapon( ) == self" part if you want them to not take fall damage as long as they have the weapon ). If they meet these conditions, we return 0 for no fall damage.
The only setup is to create the hook in Initialize on the server ( and set the hold type, along with anything else you want to do in there ).
This way, we don't have to manage any global variables, track variables on the player, or anything like that.
Sorry, you need to Log In to post a reply to this thread.