Skip to content

Instantly share code, notes, and snippets.

@Toliak
Last active February 4, 2021 09:31
Show Gist options
  • Save Toliak/e65a4b3f7e7f6f7d81a98e4cda092298 to your computer and use it in GitHub Desktop.
Save Toliak/e65a4b3f7e7f6f7d81a98e4cda092298 to your computer and use it in GitHub Desktop.
MTASA has some interesting caveats with NPC damage synchronization and processLineOfSight function
SERVER_SIDE = guiGetScreenSize == nil
CLIENT_SIDE = guiGetScreenSize ~= nil
---------------
-- LIFECYCLE --
---------------
if SERVER_SIDE then
addEventHandler('onResourceStart', resourceRoot, function()
SERVER_PED_A = Ped(17, -1316, -59,15)
SERVER_PED_C = Ped(19, -1320, -59,15)
SERVER_PED_C:setRotation(0,0,270)
SERVER_PED_C:giveWeapon(25, 9999, true)
end)
addEvent('syncPed', true)
addEventHandler('syncPed', resourceRoot, function()
triggerClientEvent(root, 'syncPed', resourceRoot, SERVER_PED_A, SERVER_PED_C)
SYNCER_HOST = getPlayerFromName('toliak')
SYNCER_HELPER = getPlayerFromName('toliak_helper')
if SERVER_PED_A:getSyncer() ~= SYNCER_HOST then
SERVER_PED_A:setSyncer(SYNCER_HOST)
end
--
if SERVER_PED_C:getSyncer() ~= SYNCER_HELPER then
SERVER_PED_C:setSyncer(SYNCER_HELPER)
end
end)
end
if CLIENT_SIDE then
addEventHandler('onClientResourceStart', resourceRoot, function()
triggerServerEvent('syncPed', resourceRoot)
end)
addEvent('syncPed', true)
addEventHandler('syncPed', resourceRoot, function(b,c)
CLIENT_PED_A = b
CLIENT_PED_C = c
local marker = Marker(0,0,0,'arrow',.5,0,255,0,200)
marker:attach(CLIENT_PED_A, 0, 0, 1.6)
end)
end
-------------------
-- LINE OF SIGHT --
-------------------
if CLIENT_SIDE then
LOS_POSITION = {}
for i=1,10 do --100
for j=1,5 do --50
table.insert(LOS_POSITION, {
Vector3(-1331 + i/10, 23 - j*1.01,14.3),
Vector3(-1331 + i/10, 22 - j*1.01,14.3)
})
end
end
lineOfSightElement = nil
addEventHandler('onClientPreRender', root, function()
if localPlayer.name ~= 'toliak' then
return
end
local hitElemenAccum = nil
for _,v in ipairs(LOS_POSITION) do
-- or isLineOfSightClear
local hit, x,y,z, hitElement = isLineOfSightClear(
v[1],
v[2])
-- `not hit`, if `isLineOfSightClear` selected
hitElemenAccum = hitElemenAccum or not hit
end
lineOfSightElement = hitElemenAccum
end)
addEventHandler('onClientRender', root, function()
for _,v in ipairs(LOS_POSITION) do
dxDrawLine3D(v[1], v[2])
end
end)
end
---------------
-- STATISTIC --
---------------
if CLIENT_SIDE then
SCREEN_W, SCREEN_H = guiGetScreenSize()
addEventHandler('onClientPedDamage', root, function()
if source ~= CLIENT_PED_A then
return
end
outputChatBox(tostring(getRealTime().timestamp) .. ' damaged (client) ')
end)
addEventHandler('onClientRender', root, function()
if localPlayer.name ~= 'toliak' then
return
end
if not CLIENT_PED_A then
return
end
local syncerText = 'Not syncer'
if CLIENT_PED_A:isSyncer() then
syncerText = 'Syncer'
end
local streamedInText = 'Not streamed in'
if CLIENT_PED_A:isStreamedIn() then
streamedInText = 'Streamed in'
end
local streamableText = 'Always streamable'
if CLIENT_PED_A:isStreamable() then
streamableText = 'Streamable'
end
local position = ('%d %d %d'):format(
CLIENT_PED_A.position.x,
CLIENT_PED_A.position.y,
CLIENT_PED_A.position.z
)
dxDrawText(
tostring(math.floor(CLIENT_PED_A.health))
.. '\n' .. syncerText
.. '\n'.. streamedInText
.. '\n' .. streamableText
.. '\n' .. position
.. '\n',
SCREEN_W - 600,
SCREEN_H - 500,
SCREEN_W,
SCREEN_H,
0xFFFFFFFF,
3.5
)
end)
end
-----------
-- BINDS --
-----------
if CLIENT_SIDE then
bindKey('num_2', 'down', function()
CLIENT_PED_C:setAimTarget(CLIENT_PED_A.position)
CLIENT_PED_C:setControlState('aim_weapon', true)
end)
bindKey('num_3', 'down', function()
CLIENT_PED_C:setControlState('fire', true)
end)
bindKey('num_3', 'up', function()
CLIENT_PED_C:setControlState('fire', false)
end)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment