@@ -41,6 +41,7 @@ import VSection from './../../Components/Section';
4141import L from " leaflet" ;
4242import {GestureHandling } from " leaflet-gesture-handling" ;
4343import " leaflet-rotatedmarker" ;
44+ import custom_icons from " ../../data/vehicles.json" ;
4445
4546(function (global ){
4647 let MarkerMixin = {
@@ -72,7 +73,8 @@ export default {
7273 data: this .t (' map.loading' ),
7374 connection: null ,
7475 isPaused: false ,
75- isDevelopment: false // For local development set it to true
76+ trackedPlayer: window .location .hash .substr (1 ),
77+ firstRefresh: true
7678 };
7779 },
7880 methods: {
@@ -86,10 +88,12 @@ export default {
8688 }
8789 },
8890 hostname (isSocket ) {
91+ const isDev = window .location .hostname === ' localhost' ;
92+
8993 if (isSocket) {
90- return this . isDevelopment ? ' ws://' + window .location .hostname + ' :8080/ ' : ' wss://' + window .location .hostname + ' :8443' ;
94+ return isDev ? ' ws://' + window .location .hostname + ' :8080' : ' wss://' + window .location .hostname + ' :8443' ;
9195 } else {
92- return this . isDevelopment ? ' http://' + window .location .hostname + ' :8080/ ' : ' https://' + window .location .hostname + ' :8443' ;
96+ return isDev ? ' http://' + window .location .hostname + ' :8080' : ' https://' + window .location .hostname + ' :8443' ;
9397 }
9498 },
9599 async doMapRefresh (server ) {
@@ -107,6 +111,8 @@ export default {
107111 const data = JSON .parse (event .data );
108112
109113 _this .renderMapData (data);
114+
115+ _this .firstRefresh = false ;
110116 } catch (e) {
111117 console .error (' Failed to parse socket message ' , e)
112118 }
@@ -147,32 +153,54 @@ export default {
147153
148154 return _this .coords (coords);
149155 };
150- const getIcon = (isDriving , isPassenger ) => {
156+ const getIcon = (player , isDriving , isPassenger , isInvisible ) => {
151157 const zoom = _this .map .getZoom ();
152- const zoomModifier = zoom === 7 ? 1.1 : 1 ;
158+ const zoomModifier = zoom === 7 ? 1.2 : 1 ;
159+ let size = {
160+ car: 23 ,
161+ circle: 17 ,
162+ circle_red: 12 ,
163+ circle_green: 13
164+ };
153165
154166 let icon = new L.Icon (
155167 {
156168 iconUrl: ' /images/circle.png' ,
157- iconSize: [17 * zoomModifier, 17 * zoomModifier],
158- iconAnchor: [(17 * zoomModifier) / 2 , (17 * zoomModifier) / 2 ]
169+ iconSize: [size . circle * zoomModifier, size . circle * zoomModifier],
170+ iconAnchor: [(size . car * zoomModifier) / 2 , (size . car * zoomModifier) / 2 ]
159171 }
160172 );
161173
162- if (isDriving ) {
174+ if (isInvisible ) {
163175 icon = new L.Icon (
164176 {
165- iconUrl: ' /images/car.png' ,
166- iconSize: [20 * zoomModifier, 20 * zoomModifier],
167- iconAnchor: [(20 * zoomModifier) / 2 , (20 * zoomModifier) / 2 ]
177+ iconUrl: ' /images/circle_green.png' ,
178+ iconSize: [size .circle_green * zoomModifier, size .circle_green * zoomModifier],
179+ iconAnchor: [(size .car * zoomModifier) / 2 , (size .car * zoomModifier) / 2 ]
180+ }
181+ );
182+ } else if (isDriving) {
183+ let iconImage = ' car.png' ;
184+ $ .each (custom_icons, function (image , cfg ) {
185+ if (cfg .models .includes (player .vehicle .model )) {
186+ iconImage = image;
187+ size .car = cfg .size ;
188+ }
189+ });
190+
191+ icon = new L.Icon (
192+ {
193+ iconUrl: ' /images/' + iconImage,
194+ iconSize: [size .car * zoomModifier, size .car * zoomModifier],
195+ iconAnchor: [(size .car * zoomModifier) / 2 , (size .car * zoomModifier) / 2 ]
168196 }
169197 );
170198 } else if (isPassenger) {
171199 icon = new L.Icon (
172200 {
173201 iconUrl: ' /images/circle_red.png' ,
174- iconSize: [12 * zoomModifier, 12 * zoomModifier],
175- iconAnchor: [(12 * zoomModifier) / 2 , (12 * zoomModifier) / 2 ]
202+ iconSize: [size . circle_red * zoomModifier, size . circle_red * zoomModifier],
203+ iconAnchor: [(size . car * zoomModifier) / 2 , (size . car * zoomModifier) / 2 ]
176204 }
177205 )
178206 }
@@ -185,14 +213,33 @@ export default {
185213 const _this = this ;
186214 let markers = this .markers ;
187215
216+ let vehicles = {};
217+ $ .each (data, function (index , player ) {
218+ if (! (' character' in player) || ! player .character ) {
219+ player .character = {
220+ id: 0 ,
221+ fullName: ' N/A'
222+ };
223+ }
224+
225+ if (' vehicle' in player && player .vehicle && player .vehicle .driving ) {
226+ vehicles[player .vehicle .id ] = player .character .id === 0 ? ' Nobody' : player .character .fullName ;
227+ }
228+
229+ data[index] = player
230+ });
231+
232+ let hasTracked = false ;
188233 let validIds = [];
189234 $ .each (data, function (_ , player ) {
190235 const id = " player_" + player .character .id ,
191236 coords = convert (player .coords ),
192237 heading = _this .mapNumber (- player .heading , - 180 , 180 , 0 , 360 ) - 180 ,
193238 isDriving = ' vehicle' in player && player .vehicle && player .vehicle .driving ,
194239 isPassenger = ' vehicle' in player && player .vehicle && ! player .vehicle .driving ,
195- icon = getIcon (isDriving, isPassenger);
240+ isInvisible = ' invisible' in player && player .invisible ,
241+ speed = ' vehicle' in player && player .vehicle && ' speed' in player .vehicle ? player .vehicle .speed : null ,
242+ icon = getIcon (player, isDriving, isPassenger, isInvisible);
196243
197244 validIds .push (id);
198245
@@ -215,24 +262,44 @@ export default {
215262 markers[id] = marker;
216263 }
217264
218- let extra = ' ' ;// '<br>Altitude: ' + Math.round(player.coords.z);
265+ let extra = ' <br>Altitude: ' + Math .round (player .coords .z ) + ' m' ;
266+ if (speed) {
267+ extra += ' <br>Speed: ' + Math .round (speed * 2.236936 ) + ' mph' ;
268+ }
269+
270+ let attributes = [];
271+ if (isInvisible) {
272+ attributes .push (' invisible' );
273+ markers[id].options .forceZIndex = 101 ;
274+ }
219275 if (isDriving) {
220- extra += ' <br>Is driving' ;
276+ attributes . push ( ' driving' ) ;
221277 markers[id].options .forceZIndex = 100 ;
222- // markers[id].setZIndexOffset(2);
223278 } else if (isPassenger) {
224- extra += ' <br>Is a passenger ' ;
279+ attributes . push ( ' passenger of ' + ( player . vehicle . id in vehicles ? vehicles[ player . vehicle . id ] : ' Nobody ' )) ;
225280 markers[id].options .forceZIndex = 102 ;
226- // markers[id].setZIndexOffset(3);
227281 } else {
228- extra += ' <br>Is on foot' ;
282+ attributes . push ( ' on foot' ) ;
229283 markers[id].options .forceZIndex = 101 ;
230- // markers[id].setZIndexOffset(1);
284+ }
285+ extra += ' <br><i>Is ' + attributes .shift () + (attributes .length > 0 ? ' and ' + attributes .join (' , ' ) : ' ' ) + ' </i>' ;
286+ if (_this .trackedPlayer === id) {
287+ extra += ' <br><br><a href="#" class="track-cid" data-trackid="stop"">' + _this .t (' map.stop_track' ) + ' </a>' ;
288+
289+ _this .map .dragging .disable ();
290+ _this .map .setView (coords, _this .firstRefresh ? 6 : _this .map .getZoom ());
291+ hasTracked = true ;
292+ } else {
293+ extra += ' <br><br><a href="#" class="track-cid" data-trackid="' + id + ' "">' + _this .t (' map.track' ) + ' </a>' ;
231294 }
232295
233296 markers[id]._popup .setContent (player .character .fullName + ' (<a href="/players/' + player .steamIdentifier + ' ">#' + player .character .id + ' </a>)' + extra);
234297 });
235298
299+ if (! hasTracked) {
300+ this .map .dragging .enable ();
301+ }
302+
236303 $ .each (markers, function (id , marker ) {
237304 if (! validIds .includes (id)) {
238305 _this .map .removeLayer (marker);
@@ -264,8 +331,7 @@ export default {
264331
265332 L .Map .addInitHook (" addHandler" , " gestureHandling" , GestureHandling);
266333
267- const _this = this ,
268- url = this .hostname (false );
334+ const url = this .hostname (false );
269335 L .TileLayer .GTA = L .TileLayer .extend ({
270336 getTileUrl : function (coords ) {
271337 coords .x = coords .x < 0 ? 0 : coords .x ;
@@ -323,6 +389,22 @@ export default {
323389 this .map .on (' click' , function (e ) {
324390 console .log (' map' , e .latlng );
325391 });
392+
393+ const _this = this ;
394+ $ (' #map' ).on (' click' , ' .track-cid' , function (e ) {
395+ e .preventDefault ();
396+
397+ const track = $ (this ).data (' trackid' );
398+ if (track === ' stop' ) {
399+ _this .trackedPlayer = null ;
400+ window .location .hash = ' ' ;
401+ } else {
402+ _this .trackedPlayer = track;
403+ window .location .hash = track;
404+
405+ _this .map .closePopup ();
406+ }
407+ });
326408 }
327409 },
328410 mounted () {
0 commit comments