AirRice / zs_banditwarfare

Derivative PVP Gmod gamemode based on Zombie Survival
https://steamcommunity.com/sharedfiles/filedetails/?id=2744583080
6 stars 5 forks source link

Client-side hitscan #11

Closed Honsal closed 2 years ago

Honsal commented 2 years ago

SWEP:ShootBullets(number dmg, number numbul, vector cone) modified for run SWEP:ShootCSBullets(entity attacker, number dmg, number numbul, vector cone)

Logic:

  1. On SWEP:ShootBullets called, SWEP:ShootCSBullets will be called internally.
  2. In SWEP:ShootCSBullets, it will fire client side bullets from its owner.
  3. In ClientSideBulletCallback function, it will generates networked message to send TraceResult and CTakeDamageInfo to the server. ("bw_fire")
  4. When server receives network message named "bw_fire", restore TraceResult and CTakeDamageInfo from its body.
  5. If TraceResult.Entity is Player entity, call GM.ScalePlayerDamage to get correct damage from each hitgroup.
  6. Server will processing CTakeDamageInfo from client-side TraceResult and CTakeDamageInfo data.

Caution: I called 0-damage Entity:FireBullets on server receives "bw_fire" network message because of bullet traces. But it causing weird user experience, like latency between shoot and bullet trace or so.

I suggest using util.Effect on client-side.

Attacker will see effect immediately on shoot. All other players will see effect on network message "bw-fire" received.

Like this.

-- ATTACKER (Client Side)
SWEP:ShootCSBullets(owner, dmg, numbul, cone)
    -- logics...
    util.Effect(...) -- Tracer effect. immediately.
end

-- SERVER
net.Receive("bw_fire", function(len, pl)
    -- logics...
    for i, target in pairs(player.GetAll()) do
        if (target != attacker) then
                net.Start("bw_fire")
                    net.WriteVector(tr.StartPos)
                    net.WriteVector(tr.HitPos)
                net.Send(target)
        end
   end
end)

-- Players Except Attacker (Client Side)
net.Receive("bw_fire", function(len)
    local startPos = net.ReadVector()
    local endPos = net.ReadVector()
    local dir = (endPos - startPos):GetNormalized()

    util.Effect(...) -- Tracer effect. On network message received.
end)