@@ -1405,3 +1405,125 @@ function disableCharacterSounds()
14051405 -- CJ stealth breathing, fall screaming etc.
14061406 setWorldSoundEnabled ( 25 , false )
14071407end
1408+
1409+ ---- -------------------------------------------------------
1410+ -- Extra: Highlight on hover (Transparency + Animated Color Box)
1411+ ---- -------------------------------------------------------
1412+
1413+ local screenW , screenH = guiGetScreenSize ()
1414+ local highlightedObject = nil
1415+
1416+ -- HSV to RGB conversion
1417+ local function hsvToRgb (h , s , v )
1418+ local r , g , b
1419+
1420+ local i = math.floor (h * 6 )
1421+ local f = h * 6 - i
1422+ local p = v * (1 - s )
1423+ local q = v * (1 - f * s )
1424+ local t = v * (1 - (1 - f * s ))
1425+
1426+ i = i % 6
1427+
1428+ if i == 0 then r , g , b = v , t , p
1429+ elseif i == 1 then r , g , b = q , v , p
1430+ elseif i == 2 then r , g , b = p , v , t
1431+ elseif i == 3 then r , g , b = p , q , v
1432+ elseif i == 4 then r , g , b = t , p , v
1433+ elseif i == 5 then r , g , b = v , p , q
1434+ end
1435+
1436+ return r * 255 , g * 255 , b * 255
1437+ end
1438+
1439+ -- Get the object under the cursor
1440+ local function getObjectFromCursor ()
1441+ local cx , cy = getCursorPosition ()
1442+ if not cx or not cy then return false end
1443+
1444+ local camX , camY , camZ = getCameraMatrix ()
1445+ local worldX , worldY , worldZ = getWorldFromScreenPosition (cx * screenW , cy * screenH , 1000 )
1446+
1447+ local hit , _ , _ , _ , hitElement = processLineOfSight (
1448+ camX , camY , camZ ,
1449+ worldX , worldY , worldZ ,
1450+ true ,true ,true ,true ,true ,true ,true ,true
1451+ )
1452+
1453+ if hit and hitElement and getElementType (hitElement ) == " object" then
1454+ return hitElement
1455+ end
1456+ return false
1457+ end
1458+
1459+ -- Get object bounding box corners
1460+ local function getObjectBoundingBox (obj )
1461+ if not isElement (obj ) then return false end
1462+ local minX , minY , minZ , maxX , maxY , maxZ = getElementBoundingBox (obj )
1463+ if not minX then return false end
1464+
1465+ local x , y , z = getElementPosition (obj )
1466+
1467+ return {
1468+ {x + minX , y + minY , z + minZ },
1469+ {x + maxX , y + minY , z + minZ },
1470+ {x + maxX , y + maxY , z + minZ },
1471+ {x + minX , y + maxY , z + minZ },
1472+ {x + minX , y + minY , z + maxZ },
1473+ {x + maxX , y + minY , z + maxZ },
1474+ {x + maxX , y + maxY , z + maxZ },
1475+ {x + minX , y + maxY , z + maxZ }
1476+ }
1477+ end
1478+
1479+ -- Draw 3D bounding box lines
1480+ local function drawBoundingBox (corners , r ,g ,b ,a )
1481+ if not corners then return end
1482+ -- base
1483+ dxDrawLine3D (corners [1 ][1 ],corners [1 ][2 ],corners [1 ][3 ], corners [2 ][1 ],corners [2 ][2 ],corners [2 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1484+ dxDrawLine3D (corners [2 ][1 ],corners [2 ][2 ],corners [2 ][3 ], corners [3 ][1 ],corners [3 ][2 ],corners [3 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1485+ dxDrawLine3D (corners [3 ][1 ],corners [3 ][2 ],corners [3 ][3 ], corners [4 ][1 ],corners [4 ][2 ],corners [4 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1486+ dxDrawLine3D (corners [4 ][1 ],corners [4 ][2 ],corners [4 ][3 ], corners [1 ][1 ],corners [1 ][2 ],corners [1 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1487+ -- top
1488+ dxDrawLine3D (corners [5 ][1 ],corners [5 ][2 ],corners [5 ][3 ], corners [6 ][1 ],corners [6 ][2 ],corners [6 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1489+ dxDrawLine3D (corners [6 ][1 ],corners [6 ][2 ],corners [6 ][3 ], corners [7 ][1 ],corners [7 ][2 ],corners [7 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1490+ dxDrawLine3D (corners [7 ][1 ],corners [7 ][2 ],corners [7 ][3 ], corners [8 ][1 ],corners [8 ][2 ],corners [8 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1491+ dxDrawLine3D (corners [8 ][1 ],corners [8 ][2 ],corners [8 ][3 ], corners [5 ][1 ],corners [5 ][2 ],corners [5 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1492+ -- vertical
1493+ dxDrawLine3D (corners [1 ][1 ],corners [1 ][2 ],corners [1 ][3 ], corners [5 ][1 ],corners [5 ][2 ],corners [5 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1494+ dxDrawLine3D (corners [2 ][1 ],corners [2 ][2 ],corners [2 ][3 ], corners [6 ][1 ],corners [6 ][2 ],corners [6 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1495+ dxDrawLine3D (corners [3 ][1 ],corners [3 ][2 ],corners [3 ][3 ], corners [7 ][1 ],corners [7 ][2 ],corners [7 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1496+ dxDrawLine3D (corners [4 ][1 ],corners [4 ][2 ],corners [4 ][3 ], corners [8 ][1 ],corners [8 ][2 ],corners [8 ][3 ], tocolor (r ,g ,b ,a ), 2 )
1497+ end
1498+
1499+ -- Main render event
1500+ local function onRenderHighlight ()
1501+ local obj = getObjectFromCursor ()
1502+
1503+ if obj and obj ~= highlightedObject then
1504+ -- Reset previous object
1505+ if highlightedObject and isElement (highlightedObject ) then
1506+ setElementAlpha (highlightedObject , 255 )
1507+ end
1508+
1509+ highlightedObject = obj
1510+ setElementAlpha (highlightedObject , 150 ) -- semi-transparent
1511+
1512+ elseif not obj and highlightedObject then
1513+ if isElement (highlightedObject ) then
1514+ setElementAlpha (highlightedObject , 255 )
1515+ end
1516+ highlightedObject = nil
1517+ end
1518+
1519+ -- Draw animated bounding box
1520+ if highlightedObject and isElement (highlightedObject ) then
1521+ local box = getObjectBoundingBox (highlightedObject )
1522+ if box then
1523+ local tick = getTickCount () / 2000 -- animation speed
1524+ local r ,g ,b = hsvToRgb (tick % 1 , 1 , 1 ) -- rainbow color cycle
1525+ drawBoundingBox (box , r , g , b , 255 )
1526+ end
1527+ end
1528+ end
1529+ addEventHandler (" onClientRender" , root , onRenderHighlight )
0 commit comments