So i’m utilising weaponDamageEvent server side to do several things
score management - players kills a player, up their score
profile management - up a players XP / Level / Cash
assists - track assists
now, 2/3 are done however there are a few underlying issues ive had so far
willKill gets called several times for 1 kill, ofc this is sent by the client so it makes sense but how could I circumvent this from reciprocating twice, I’ve tried checking if the entity is dead / health <= 0, however I assume this event runs before damage is done so i also take the damage away however the health still sometimes appears to be >= 0 even when willKill is set to true
Weapons like projectiles & melee don’t seem to set willKill, I believe projectiles is the “sender” in this case (unchecked) and thus I need to get who actually fired the shot, I’m not sure of a good approach currently and havent looked too into it yet but its a point none-the-less, and melees ( like punching ) don’t seem to work.
tldr; Projectiles don’t seem to be from the player when they kill / hit, melee doesn’t seem to get picked up and willKill is sometimes sent multiple times even when the victim is dead, how can I cirvumvent these issues
if anyone has any good pointers / resources or solutions they can think off, I have a few in mind but want to hear from a wider perspective
I need server-side damage / kill detection, it can’t be client sided.
True, could just store the death so it doesn’t pop twice and when a client requests a respawn get rid of it, only issue I found is that sometimes willKill will pop even if the player didn’t die - the client just be gaslighting the server so thats another issue
Do you have the event name at all? I want to avoid getting any info from the client that I can, but push comes to shove I’ll just not support projectiles.
Citizen.CreateThread(function()
local DeathReason, Killer, DeathCauseHash, Weapon
while true do
Citizen.Wait(0)
if IsEntityDead(GetPlayerPed(PlayerId())) then
Citizen.Wait(0)
local PedKiller = GetPedSourceOfDeath(GetPlayerPed(PlayerId()))
local killername = GetPlayerName(PedKiller)
DeathCauseHash = GetPedCauseOfDeath(GetPlayerPed(PlayerId()))
Weapon = WeaponNames[tostring(DeathCauseHash)] -- <-- Table of weapon hashes, i.e. [1234567] = "Your Weapon"
if IsEntityAPed(PedKiller) and IsPedAPlayer(PedKiller) then
Killer = NetworkGetPlayerIndexFromPed(PedKiller)
elseif IsEntityAVehicle(PedKiller) and IsEntityAPed(GetPedInVehicleSeat(PedKiller, -1)) and IsPedAPlayer(GetPedInVehicleSeat(PedKiller, -1)) then
Killer = NetworkGetPlayerIndexFromPed(GetPedInVehicleSeat(PedKiller, -1))
end
if not ((Killer == PlayerId()) or (Killer == nil)) then
-- Send event to server
-- Victim: GetPlayerServerId(PlayerId())
-- Killer: GetPlayerServerId(Killer)
-- Weapon Name: Weapon
end
Killer = nil
DeathCauseHash = nil
Weapon = nil
end
while IsEntityDead(PlayerPedId()) do
Citizen.Wait(0)
end
end
end)
This includes other things like running a player over.
The server has no concept of the “world” and how clients interact in it. If you want this kind of information you need to get it from the clients and send it to the server to be processed and sent back to the respective client.
I mean thats technically whats happening with weaponDamageEvent no? willKill is set by the client, so technically it’s still receiving trust from the client, in which sometimes the client gets too eager and doesn’t know if its right or wrong which was my issue.
However, I’ve seemed to have solved it a bit, in which I check GetEntityHealth a few ms after the event is fired, and use that alongside willKill seems to be working for me for the moment but I’m a little scared as I’m relying on a delay which isn’t ideall.
I need to work in the limitations of GTA but can’t help but want a bit of server authority for database stuff, which seems to be going the right way at the moment