Skip to content
This repository was archived by the owner on May 26, 2023. It is now read-only.

Commit 636fc16

Browse files
committed
- Better map icons
- Tracking players
1 parent 33044b6 commit 636fc16

File tree

10 files changed

+240
-24
lines changed

10 files changed

+240
-24
lines changed

public/images/boat.png

4.67 KB
Loading

public/images/car.png

-1.38 KB
Loading

public/images/circle_green.png

4.58 KB
Loading

public/images/helicopter.png

4.31 KB
Loading

public/images/jet.png

1.27 KB
Loading

public/images/plane.png

1.44 KB
Loading

public/images/tank.png

3.47 KB
Loading

resources/js/Pages/Map/Index.vue

Lines changed: 105 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import VSection from './../../Components/Section';
4141
import L from "leaflet";
4242
import {GestureHandling} from "leaflet-gesture-handling";
4343
import "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() {

resources/js/data/vehicles.json

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
{
2+
"helicopter.png": {
3+
"size": 28,
4+
"models": [
5+
"906515397",
6+
"1346171487",
7+
"990116733",
8+
"polmav",
9+
"akula",
10+
"annihilator",
11+
"buzzard",
12+
"buzzard2",
13+
"cargobob",
14+
"cargobob2",
15+
"cargobob3",
16+
"cargobob4",
17+
"frogger",
18+
"frogger2",
19+
"havok",
20+
"hunter",
21+
"maverick",
22+
"savage",
23+
"seasparrow",
24+
"skylift",
25+
"supervolito",
26+
"supervolito2",
27+
"swift",
28+
"swift2",
29+
"valkyrie",
30+
"valkyrie2",
31+
"volatus",
32+
"annihilator2",
33+
"seasparrow2",
34+
"seasparrow3",
35+
"thruster"
36+
]
37+
},
38+
"boat.png": {
39+
"size": 28,
40+
"models": [
41+
"dinghy",
42+
"dinghy2",
43+
"dinghy3",
44+
"dinghy4",
45+
"jetmax",
46+
"marquis",
47+
"seashark",
48+
"seashark2",
49+
"seashark3",
50+
"speeder",
51+
"speeder2",
52+
"squalo",
53+
"submersible",
54+
"submersible2",
55+
"suntrap",
56+
"toro",
57+
"toro2",
58+
"tropic",
59+
"tropic2",
60+
"tug",
61+
"avisa",
62+
"dinghy5",
63+
"kosatka",
64+
"longfin",
65+
"patrolboat",
66+
"predator"
67+
]
68+
},
69+
"plane.png": {
70+
"size": 28,
71+
"models": [
72+
"alphaz1",
73+
"avenger",
74+
"avenger2",
75+
"blimp",
76+
"blimp2",
77+
"blimp3",
78+
"bombushka",
79+
"cargoplane",
80+
"cuban800",
81+
"dodo",
82+
"duster",
83+
"howard",
84+
"jet",
85+
"luxor",
86+
"luxor2",
87+
"mammatus",
88+
"microlight",
89+
"miljet",
90+
"mogul",
91+
"molotok",
92+
"nimbus",
93+
"nokota",
94+
"pyro",
95+
"rogue",
96+
"seabreeze",
97+
"shamal",
98+
"starling",
99+
"stunt",
100+
"titan",
101+
"tula",
102+
"velum",
103+
"velum2",
104+
"vestra"
105+
]
106+
},
107+
"jet.png": {
108+
"size": 25,
109+
"models": [
110+
"besra",
111+
"hydra",
112+
"lazer",
113+
"strikeforce",
114+
"volatol",
115+
"alkonost"
116+
]
117+
},
118+
119+
"tank.png": {
120+
"size": 27,
121+
"models": [
122+
"apc",
123+
"khanjali",
124+
"minitank",
125+
"rhino",
126+
"scarab",
127+
"scarab2",
128+
"scarab3",
129+
"trailersmall2"
130+
]
131+
}
132+
}

resources/js/locales/en-us.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@
5858
"closed": "Data connection for {0} was closed.",
5959
"data": "Currently {0} online players.",
6060
"play": "Continue update",
61-
"pause": "Pause update"
61+
"pause": "Pause update",
62+
"track": "Track character",
63+
"stop_track": "Stop tracking character"
6264
},
6365
"nav": {
6466
"dark": "Dark",

0 commit comments

Comments
 (0)