@@ -50,6 +50,7 @@ function aSpectator.Open()
50
50
end
51
51
guiGridListRemoveColumn (aSpectator .Slaps , 1 )
52
52
53
+ aSpectator .CollideWithWalls = guiCreateCheckBox ( 0.08 , 0.8 , 0.84 , 0.04 , " Collide with walls" , true , true , aSpectator .Actions )
53
54
aSpectator .Skip = guiCreateCheckBox (0.08 , 0.85 , 0.84 , 0.04 , " Skip dead players" , true , true , aSpectator .Actions )
54
55
guiCreateLabel (0.08 , 0.89 , 0.84 , 0.04 , " ____________________" , true , aSpectator .Actions )
55
56
aSpectator .Back = guiCreateButton (0.10 , 0.93 , 0.80 , 0.05 , " Back" , true , aSpectator .Actions )
@@ -244,10 +245,19 @@ function aSpectator.Render()
244
245
return
245
246
end
246
247
248
+ local offset = aSpectator .Offset
249
+
250
+ if guiCheckBoxGetSelected (aSpectator .CollideWithWalls ) then
251
+ local nearest_hit = aSpectator .CheckCollision (x , y , z )
252
+ if nearest_hit and (nearest_hit < offset ) then
253
+ offset = nearest_hit
254
+ end
255
+ end
256
+
247
257
local ox , oy , oz
248
- ox = x - math.sin (math.rad (aSpectator .AngleX )) * aSpectator . Offset
249
- oy = y - math.cos (math.rad (aSpectator .AngleX )) * aSpectator . Offset
250
- oz = z + math.tan (math.rad (aSpectator .AngleZ )) * aSpectator . Offset
258
+ ox = x - math.sin (math.rad (aSpectator .AngleX )) * offset
259
+ oy = y - math.cos (math.rad (aSpectator .AngleX )) * offset
260
+ oz = z + math.tan (math.rad (aSpectator .AngleZ )) * offset
251
261
setCameraMatrix (ox , oy , oz , x , y , z )
252
262
253
263
local sx , sy = guiGetScreenSize ()
@@ -300,6 +310,30 @@ function aSpectator.Render()
300
310
end
301
311
end
302
312
313
+ local checks = {
314
+ {- 1 , - 0.5 },
315
+ {- 1 , 0.5 },
316
+ {1 , 0.5 },
317
+ {1 , - 0.5 },
318
+ }
319
+
320
+ function aSpectator .CheckCollision (x , y , z )
321
+ local nearest_distance
322
+
323
+ for k , v in ipairs (checks ) do
324
+ local xx , yy , zz = getPositionFromOffset (getCamera (), v [1 ], 0 , v [2 ])
325
+ local hit , hitx , hity , hitz = processLineOfSight (xx , yy , zz , x , y , z , true , true , false , true , true , false , false , false , (getPedOccupiedVehicle (localPlayer ) or nil ))
326
+ if hit then
327
+ local dist = getDistanceBetweenPoints3D (x , y , z , hitx , hity , hitz )
328
+ if (dist <= (nearest_distance or math.huge )) then
329
+ nearest_distance = dist
330
+ end
331
+ end
332
+ end
333
+
334
+ return nearest_distance or false
335
+ end
336
+
303
337
function aSpectator .MoveOffset (key , state , inc )
304
338
if (not isCursorShowing ()) then
305
339
aSpectator .Offset = aSpectator .Offset + tonumber (inc )
@@ -320,3 +354,11 @@ function aSpectator.GetAlive()
320
354
end
321
355
return alive
322
356
end
357
+
358
+ function getPositionFromOffset (element , x , y , z )
359
+ local matrix = getElementMatrix (element )
360
+ local offX = x * matrix [1 ][1 ] + y * matrix [2 ][1 ] + z * matrix [3 ][1 ] + matrix [4 ][1 ]
361
+ local offY = x * matrix [1 ][2 ] + y * matrix [2 ][2 ] + z * matrix [3 ][2 ] + matrix [4 ][2 ]
362
+ local offZ = x * matrix [1 ][3 ] + y * matrix [2 ][3 ] + z * matrix [3 ][3 ] + matrix [4 ][3 ]
363
+ return offX , offY , offZ
364
+ end
0 commit comments