Sziasztok. Rengeteg kérdést kaptam az elmúlt időben arra, hogy HL-en hogyan oldottam meg a piroslámpa lekérdezést. Mivel szerintem ez egy elég egyszerű dolog, így szeretnék segíteni azoknak akik nem jöttek eddig rá miként működik.
Egy gyors vázlat a lámpák működéséről (ugyan ez érvényes visszafelé is):
Egyetlen lámpa object státuszát pedig a rotációk alapján lehet lekérdezni (\"meg kell fordítani\" a rotációt először is)
function calculateRotation(rot)
local rot = math.floor(rot)
rot = 360-rot
if rot > 70 and rot < 110 then
return 270
elseif rot > 160 and rot < 200 then
return 180
elseif rot > 250 and rot < 290 then
return 90
elseif rot < 20 then
return 0
else
return nil
end
end
A rotáció megfordítását követően már meg lehet határozni, hogy éppen az a lámpa mit is mutat éppen
if realRot == 270 or realRot == 90 then
if trafficState == 0 or trafficState == 1 or trafficState == 2 then outputChatBox(\"ez a lámpa piros\")
end end
Teljes kész példa script:
-- Rendőrlámpa állapotának lekérdezése példa script by Xenius (netöröld)
local trafficLights = {}
local trafficObjects = {
[1350] = {-3, -2, 0},
[1351] = {-3, -2, 0},
[1352] = {-3, -2, 0},
[3855] = {-3, -2, 0},
[1315] = {-2, -2, -2.5, 3.5},
[1283] = {1.2, -4, -3, 6},
[1284] = {1.2, -4, -3, 6},
}
local trafficAttached = {}
function calculateRotation(rot)
local rot = math.floor(rot)
rot = 360-rot
if rot > 70 and rot < 110 then
return 270
elseif rot > 160 and rot < 200 then
return 180
elseif rot > 250 and rot < 290 then
return 90
elseif rot < 20 then
return 0
else
return nil
end
end
function calculateTicket(rot, veh)
local realRot = calculateRotation(rot)
if realRot then
local _, _, vz = getElementRotation(veh)
local vehRot = calculateRotation(vz)
if realRot == vehRot then
local trafficState = getTrafficLightState()
if realRot == 270 or realRot == 90 then
if trafficState == 0 or trafficState == 1 or trafficState == 2 then
outputChatBox(\"Áthajtottál a piroson!\")
end
elseif realRot == 0 or realRot == 180 then
if trafficState == 2 or trafficState == 3 or trafficState == 4 then
outputChatBox(\"Áthajtottál a piroson!\")
end
end
end
end
end
function addTrafficLightCollision(obj)
if not trafficLights[obj] then
local offset = trafficObjects[getElementModel(obj)]
local x, y, z = getElementPosition(obj)
if getZoneName(x, y, z, true) == \"Unknown\" then return end
trafficLights[obj] = createColTube(x, y, z, offset[4] or 2, 4)
attachElements(trafficLights[obj], obj, offset[1], offset[2], offset[3])
trafficAttached[trafficLights[obj]] = obj
end
end
function removeTrafficLightCollision(obj)
if trafficLights[obj] then
trafficAttached[trafficLights[obj]] = nil
destroyElement(trafficLights[obj])
trafficLights[obj] = nil
end
end
addEventHandler(\"onClientResourceStart\", resourceRoot, function()
for k, v in ipairs(getElementsByType(\"object\", root, true)) do
if trafficObjects[getElementModel(v)] then
addTrafficLightCollision(v)
end
end
end)
addEventHandler(\"onClientElementStreamIn\", root, function()
if getElementType(source) == \"object\" then
if trafficObjects[getElementModel(source)] then
setObjectBreakable(source, false)
addTrafficLightCollision(source)
end
end
end)
addEventHandler(\"onClientElementStreamOut\", root, function()
if getElementType(source) == \"object\" then
if trafficObjects[getElementModel(source)] then
removeTrafficLightCollision(source)
end
end
end)
addEventHandler(\"onClientElementDestroy\", root, function()
if getElementType(source) == \"object\" then
if trafficObjects[getElementModel(source)] then
removeTrafficLightCollision(source)
end
end
end)
function isCar(veh)
if getElementType(veh) == \"vehicle\" then
if getVehicleType(veh) == \"Automobile\" or getVehicleType(veh) == \"Monster Truck\" then
return true
else
return false
end
else
return false
end
end
addEventHandler(\"onClientColShapeLeave\", resourceRoot, function(player)
if player ~= localPlayer then return end
local object = trafficAttached[source]
if object then
local veh = getPedOccupiedVehicle(player)
if veh then
if getPedOccupiedVehicleSeat(player) == 0 then
if isCar(veh) or getVehicleType(veh) == \"Bike\" then
local _, _, rz = getElementRotation(object)
calculateTicket(rz, veh)
end
end
end
end
end)
function renderTrafficDev()
for k, v in pairs(trafficLights) do
if isElementOnScreen(k) then
local px, py, pz = getElementPosition(v)
local x, y = getScreenFromWorldPosition(px, py, pz)
if x and y then
local rx, ry, rz = getElementRotation(k)
dxDrawText(\"Lámpa ROT: \"..math.floor(rz)..\"\\nKalkulálva: \"..(tostring(calculateRotation(rz)) or \"err\")..\"\\nLámpa státusz: \"..getTrafficLightState(), x, y, x, y, tocolor(255,255,255), 1, \"default-bold\", \"center\", \"center\")
end
end
end
end
local devState
addCommandHandler(\"trafficdev\", function()
if devState then
removeEventHandler(\"onClientRender\", root, renderTrafficDev)
else
addEventHandler(\"onClientRender\", root, renderTrafficDev)
end
devState = not devState
end)
Az példa scriptben van lehetőség a lámpa rotációk kiírására is a /trafficdev paranncsal.
Fontos, hogy ez a script az alapból GTA mapon lévő lámpákkal nem működik.