• Get killer name
    18 replies, posted
Hi, I need some help for my script : I create a simple derma openable with a console command and in it i would like to see ( if the player is dead when he open it ) the killer name and the weapon which kill him. I tried this : [CODE]local killer = ply:GetAttacker() local killwith = ply:GetInflictor() -- and then to test if it works print( killer ) print( killwith )[/CODE] But it doens't work [CODE]attempt to call method 'GetAttacker'[/CODE] Can somebody help me please ? :'[
That only works with [URL="https://wiki.garrysmod.com/page/Category:CTakeDamageInfo"]CTakeDamageInfo[/URL], which you can get in [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/GM/DoPlayerDeath]GM:DoPlayerDeath[/url], [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/GM/EntityTakeDamage]GM:EntityTakeDamage[/url], and [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/GM/ScalePlayerDamage]GM:ScalePlayerDamage[/url]. Ply (assuming ply is a player entity) is not a CTakeDamageInfo object, so that's why it doesn't work. [editline]17th August 2017[/editline] You could display the killer on the menu by [URL="https://wiki.garrysmod.com/page/Net_Library_Usage"]using networking[/URL] to send [URL="https://wiki.garrysmod.com/page/net/WriteEntity"]the killer entity[/URL] to [URL="https://wiki.garrysmod.com/page/net/Send"]the killed player[/URL] from a [URL="http://wiki.garrysmod.com/page/GM/DoPlayerDeath"]DoPlayerDeath[/URL] hook. However, this is a pretty annoying method. I just can't think of a better one.
[QUOTE]You could display the killer on the menu by using networking to send the killer entity to the killed player from a DoPlayerDeath hook. However, this is a pretty annoying method. I just can't think of a better one.[/QUOTE] Yes that's exaclly what i want to do but I don't know how to use Networking...
[url]http://wiki.garrysmod.com/page/Net_Library_Usage[/url] In the DoPlayerDeath hook that was posted earlier, send a message containing the killer to the victim. Then on the client save the killer in a variable that you can read in your derma screen
Ok I will try with this thank you ! :)
How, with the Net Usage, can I send information from server to client ? I don't understand very well the library... :/
[QUOTE=Ezotose;52593975]How, with the Net Usage, can I send information from server to client ? I don't understand very well the library... :/[/QUOTE] Think of it like 2 people having a conversation. [B]Person 1 (the server) and person 2 (the client).[/B] Person 1 want's to say something, so they open there mouth (net.Start) and, for example, say a number (net.WriteInt) and then confirm who there saying it to (net.Send). Person 2 will listen for when person 1 say's something relevant (net.Recieve) and will note down what they say (net.ReadInt). For the scenario above to work it does require a few extra details which are explained in the code below. Here is how it would look: [CODE] -- SERVER util.AddNetworkString("message") -- make sure your names are unique and descriptive of what they do local number = 5 -- The number the server will say net.Start("message") -- Where the server open its mouth net.WriteInt(number, 32) -- Where the server says the number, as well as the amount of bits it will use net.Send(ply) -- Where it defines who will receive this message ---------------------------------------------------------------------- -- CLIENT net.Recieve("message", function() -- Where the client hears the message local number = net.ReadInt(32) -- Where the client notes down the number, you MUST have the same bitcount as used in the server code end)[/CODE] Not all data types need to have a bit count defined, check the wiki for the relevant one. A more complex emample is where we send a message from the client to the server and then back to the client. [B] Person 1 (the server) and person 2 (the client).[/B] Person 2 would say (net.Start) a message (net.WriteString) to the Person 1 (net.SendToServer). Person 1 would listen out for the message (net.Recieve) and note down what they have to say (net.ReadString). Person 2 would then respond (net.Start) with saying the same message (net.WriteString) back to Person 1 (net.Send). Person 1 would then say the received message in the console (print) [CODE] -- CLIENT local button = vgui.Create("DButton") -- Makes a interface button:SetPos(0,0) button:SetSize(50,50) button:SetText("Sends message to server") button.DoClick = function() -- When the button is pressed it runs the following code net.Start("messageName") -- Client opens its mouth net.writeString("hi") -- Client says its message net.SendToServer() -- Client sends it to the server end -------------------------------------------------------------- -- SERVER util.AddNetworkString("messageName") -- make sure your names are unique and descriptive of what they do util.AddNetworkString("messageName2") -- make sure your names are unique and descriptive of what they do net.Recieve("messageName", function(_, ply) -- Server hears what the client says and gets there details ( being ply) local message = net.ReadString() -- Server notes down what it says net.Start("messageName2") -- Server opens its mouth net.WriteString(message) -- Server repeats what it noted down earlier net.Send(ply) -- Server defines who its speaking to (it knows this because ply is defined when the original net message was sent) end) -------------------------------------------------------------- -- CLIENT (continued) net.Recieve("messageName2", function() local message = net.ReadString() print(message) -- Prints "hi" in console end) [/CODE] I hope this explanation helps :)
Thank's very munch for your anwser ! And for my script, the server will have to open the mouse (net.Start) in the Hook OnDeath and say (net.WriteString) the attacker and the inflictor ? And then the client will have to listen (net.Recieve) and write the informations (net.ReadString) ? Somethink like this : [CODE] util.AddNetworkString("message") function GM:PlayerDeath( victim, inflictor, attacker ) net.Start("message") net.WriteInt(attacker, 32) net.WriteInt(inflictor, 34) net.Send(ply) end --------------------------------------------------------------------- -- CLIENT net.Recieve("message", function() local killer = net.ReadInt(32) local killwith =net.ReadInt(34) end) [/CODE] ?
Okay here's what you had: [CODE] util.AddNetworkString("message") function GM:PlayerDeath( victim, inflictor, attacker ) net.Start("message") net.WriteInt(attacker, 32) net.WriteInt(inflictor, 34) net.Send(ply) end --------------------------------------------------------------------- -- CLIENT net.Recieve("message", function() local killer = net.ReadInt(32) local killwith =net.ReadInt(34) end) [/CODE] Here's it fixed up: [CODE] util.AddNetworkString("somebodyDroppedDeadFred") function GM:PlayerDeath( victim, inflictor, attacker ) net.Start("somebodyDroppedDeadFred") -- renamed for clarity net.WriteEntity(attacker) -- We don't want to send an integer, let's send instead the attacker entity. net.WriteEntity(inflictor) -- Let's send the inflictor entity (for local translation) net.Send(victim) -- ply isn't defined on the server, victim is end --------------------------------------------------------------------- -- CLIENT net.Receive("somebodyDroppedDeadFred", function() local killer = net.ReadEntity() -- we can read them off like this, I didn't think ReadEntity needed arguments local killwith = net.ReadEntity() chat.AddText("You were killed by " ..killer:Nick().. " with a " .. killwith:GetName()) end) [/CODE]
Okay thank's very munch everybody, but when i try he say : [code]attempt to concatenate global 'killwith' (a nil value) [/code]
[QUOTE] [CODE] util.AddNetworkString("message") function GM:PlayerDeath( victim, inflictor, attacker ) net.Start("message") net.WriteInt(attacker, 32) net.WriteInt(inflictor, 34) net.Send(ply) end --------------------------------------------------------------------- -- CLIENT net.Recieve("message", function() local killer = net.ReadInt(32) local killwith =net.ReadInt(34) end) [/CODE][/QUOTE] You got the server-client logic right, but you got hooks muddled up and I don't think you are familiar with datatypes and bits! So firstly, GM:PlayerDeath is [B]NOT[/B] a hook. You shouldn't touch this unless you are making a gamemode or you know what you are doing. A hook is like a listener. It To run code every time a hook is run you will use [URL="http://wiki.garrysmod.com/page/hook/Add"]hook.Add[/URL]. An example if what a hook will look like is: [CODE]hook.Add("hookName", "uniqueHookName", function(argument1, agument2) -- (limited to how many the hook has) -- your code here end)[/CODE] You are trying to do is listen to the PlayerDeath hook. You would simple replace "hookName" with "PlayerDeath" and make sure you have the correct arguments. [CODE]hook.Add("PlayerDeath", "uniqueHookName", function(victim, weapon, attacker) -- (limited to how many the hook has) -- your code here end)[/CODE] Next you want to send the data to the client. To know what datatype we are going to use we need to know what datatypes are. I made a table of the common datatypes used (there are more but its up to you to research): [IMG]https://i.gyazo.com/af4e6b075357912924dbd242f81ee03d.png[/IMG] If you are even unsure of the datatype of something you can use [URL="http://wiki.garrysmod.com/page/Global/type"]type()[/URL] to find out. For example print(type("hi")) and it will return string. [CODE] print(type("hi")) -- returns "string" [/CODE] To know what datatypes the arguments are it says on the wiki page of the hook you are calling. [IMG]https://i.gyazo.com/1327828294e620c6c7b6e95358dd8e76.png[/IMG] [B]and also[/B] [IMG]https://i.gyazo.com/dd3bea40223418e93d31f5936b718708.png[/IMG] So going back to sending the message to the client, we want to send the data as a entity datatype (we can send player data as an entity datatype as a player is a entity). This is what it will look like: [CODE] hook.Add("PlayerDeath", "uniqueHookName", function(victim, weapon, attacker) -- (limited to how many the hook has) net.Start("name") net.WriteEntity(victim) net.WriteEntity(attacker) net.Send(victim) -- depends on who you want to send this message to end) [/CODE] Another thing I noticed is on your second WriteInt you put 34 bits [CODE] local killwith =net.ReadInt(34) [/CODE] The maximum is 32 bits. If you are unsure of what bits I highlt advise some research in your own time! Edit: Milkshaker got to the code before me but I still give some explanations so I wont ninja :)
[QUOTE=Bings;52594526]So going back to sending the message to the client, we want to send the data as a entity datatype[/QUOTE] When you use net.WriteEntity you don't send the entity, you send the entity's index. net.Read/WriteEntity are Lua functions, you can check the source [URL="https://github.com/Facepunch/garrysmod/blob/master/garrysmod/lua/includes/extensions/net.lua#L50-L67"]here[/URL].
[QUOTE=txike;52594573]When you use net.WriteEntity you don't send the entity, you send the entity's index. net.Read/WriteEntity are Lua functions, you can check the source [URL="https://github.com/Facepunch/garrysmod/blob/master/garrysmod/lua/includes/extensions/net.lua#L50-L67"]here[/URL].[/QUOTE] Very true - I wasn't thinking 100%. Thanks for spotting that :happy:
He already say [code]attempt to concatenate global 'killwith' (a nil value)[/code] in the client side. But it make this like you : [code] net.Receive("DeathInfo", function() local killer = net.ReadEntity() local killwith = net.ReadEntity() end) [/code]
Where are you using killwith? That code shouldn't cause an error.
Did i need to use the killwith and killer in the net.Receive ?
You should read up on [URL="http://lua-users.org/wiki/ScopeTutorial"]scoping[/URL]. It will probably help you a lot in the future too.
I know how to use a function() but is net.Receive no... :/
[QUOTE=Ezotose;52594666]I know how to use a function() but is net.Receive no... :/[/QUOTE] [QUOTE=Lua Wiki]Local variables only exist in the block they were created in. Outside of the block, they do not exist any more.[/QUOTE]
Sorry, you need to Log In to post a reply to this thread.