From b9e3f41b759607aae6a11897819c7ca5e2101aaf Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Sun, 24 Jan 2021 23:52:34 +0200 Subject: [PATCH 01/18] Replace direct prototype manipulation by defining inenumerable properties instead --- [web]/ajax/json.js | 193 +++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 93 deletions(-) diff --git a/[web]/ajax/json.js b/[web]/ajax/json.js index e91078b1d..c5f12750a 100644 --- a/[web]/ajax/json.js +++ b/[web]/ajax/json.js @@ -59,148 +59,154 @@ if (!Object.prototype.toJSONString) { - Array.prototype.toJSONString = function () { - var a = [], // The array holding the member texts. - i, // Loop counter. - l = this.length, - v; // The value to be stringified. + Object.defineProperty(Array.prototype, 'toJSONString', { + enumerable: false, + value: function () { + let a = [], // The array holding the member texts. + i, // Loop counter. + l = this.length, + v; // The value to be stringified. // For each value in this array... - for (i = 0; i < l; i += 1) { - v = this[i]; - switch (typeof v) { - case 'object': + for (i = 0; i < l; i += 1) { + v = this[i]; + switch (typeof v) { + case 'object': // Serialize a JavaScript object value. Ignore objects thats lack the // toJSONString method. Due to a specification error in ECMAScript, // typeof null is 'object', so watch out for that case. - if (v) { - if (typeof v.toJSONString === 'function') { - a.push(v.toJSONString()); + if (v) { + if (typeof v.toJSONString === 'function') { + a.push(v.toJSONString()); + } + } else { + a.push('null'); } - } else { - a.push('null'); - } - break; + break; - case 'string': - case 'number': - case 'boolean': - a.push(v.toJSONString()); + case 'string': + case 'number': + case 'boolean': + a.push(v.toJSONString()); // Values without a JSON representation are ignored. + } } - } // Join all of the member texts together and wrap them in brackets. - return '[' + a.join(',') + ']'; - }; - - - Boolean.prototype.toJSONString = function () { - return String(this); - }; + return '[' + a.join(',') + ']'; + }, + }); + Object.defineProperty(Boolean.prototype, 'toJSONString', { + enumerable: false, + value: function () { + return String(this); + }, + }); - Date.prototype.toJSONString = function () { + Object.defineProperty(Date.prototype, 'toJSONString', { + enumerable: false, + value: function () { // Ultimately, this method will be equivalent to the date.toISOString method. - function f(n) { + function f(n) { // Format integers to have at least two digits. - return n < 10 ? '0' + n : n; - } - - return '"' + this.getFullYear() + '-' + - f(this.getMonth() + 1) + '-' + - f(this.getDate()) + 'T' + - f(this.getHours()) + ':' + - f(this.getMinutes()) + ':' + - f(this.getSeconds()) + '"'; - }; + return n < 10 ? '0' + n : n; + } + return '"' + this.getFullYear() + '-' + + f(this.getMonth() + 1) + '-' + + f(this.getDate()) + 'T' + + f(this.getHours()) + ':' + + f(this.getMinutes()) + ':' + + f(this.getSeconds()) + '"'; + }, + }); - Number.prototype.toJSONString = function () { + Object.defineProperty(Number.prototype, 'toJSONString', { + enumerable: false, + value: function () { // JSON numbers must be finite. Encode non-finite numbers as null. - return isFinite(this) ? String(this) : 'null'; - }; - + return isFinite(this) ? String(this) : 'null'; + }, + }); - Object.prototype.toJSONString = function () { - var a = [], // The array holding the member texts. - k, // The current key. - v; // The current value. + Object.defineProperty(Object.prototype, 'toJSONString', { + enumerable: false, + value: function () { + let a = [], // The array holding the member texts. + k, // The current key. + v; // The current value. // Iterate through all of the keys in the object, ignoring the proto chain. - for (k in this) { - if (this.hasOwnProperty(k)) { - v = this[k]; - switch (typeof v) { - case 'object': + for (k in this) { + if (this.hasOwnProperty(k)) { + v = this[k]; + switch (typeof v) { + case 'object': // Serialize a JavaScript object value. Ignore objects that lack the // toJSONString method. Due to a specification error in ECMAScript, // typeof null is 'object', so watch out for that case. - if (v) { - if (typeof v.toJSONString === 'function') { - a.push(k.toJSONString() + ':' + v.toJSONString()); + if (v) { + if (typeof v.toJSONString === 'function') { + a.push(k.toJSONString() + ':' + v.toJSONString()); + } + } else { + a.push(k.toJSONString() + ':null'); } - } else { - a.push(k.toJSONString() + ':null'); - } - break; + break; - case 'string': - case 'number': - case 'boolean': - a.push(k.toJSONString() + ':' + v.toJSONString()); + case 'string': + case 'number': + case 'boolean': + a.push(k.toJSONString() + ':' + v.toJSONString()); // Values without a JSON representation are ignored. + } } } - } // Join all of the member texts together and wrap them in braces. - return '{' + a.join(',') + '}'; - }; - - - (function (s) { - -// Augment String.prototype. We do this in an immediate anonymous function to -// avoid defining global variables. + return '{' + a.join(',') + '}'; + } + }); // m is a table of character substitutions. - var m = { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }; - + const m = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }; - s.parseJSON = function (filter) { - var j; + Object.defineProperty(String.prototype, 'parseJSON', { + enumerable: false, + value: function (filter) { + let j; function walk(k, v) { - var i; + let i; if (v && typeof v === 'object') { for (i in v) { if (v.hasOwnProperty(i)) { @@ -242,11 +248,12 @@ if (!Object.prototype.toJSONString) { j = walk('', j); } return j; - }; - - - s.toJSONString = function () { + }, + }); + Object.defineProperty(String.prototype, 'toJSONString', { + enumerable: false, + value: function () { // If the string contains no control characters, no quote characters, and no // backslash characters, then we can simply slap some quotes around it. // Otherwise we must also replace the offending characters with safe @@ -254,7 +261,7 @@ if (!Object.prototype.toJSONString) { if (/["\\\x00-\x1f]/.test(this)) { return '"' + this.replace(/([\x00-\x1f\\"])/g, function (a, b) { - var c = m[b]; + let c = m[b]; if (c) { return c; } @@ -265,6 +272,6 @@ if (!Object.prototype.toJSONString) { }) + '"'; } return '"' + this + '"'; - }; - })(String.prototype); + }, + }); } From 25b2e7e2c2944d873d1e6889095e25119bf0752c Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Sun, 24 Jan 2021 23:53:32 +0200 Subject: [PATCH 02/18] Change OpenLayers tilecache source --- [web]/webmap/script.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index 99d5df4d3..09835057e 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -14,18 +14,18 @@ var bliplist = new Object; function init() { - map = new OpenLayers.Map( $('map'), {'maxResolution': 360/512, 'maxExtent':new OpenLayers.Bounds(-90.0,-90.0,90.0,90.0), - 'numZoomLevels':6, + map = new OpenLayers.Map( 'map', {'maxResolution': 1, 'maxExtent':new OpenLayers.Bounds(-90.0,-90.0,90.0,90.0), + 'numZoomLevels':8, }); map.addControl(new OpenLayers.Control.LayerSwitcher({'div':OpenLayers.Util.getElement('layerswitcher')})); - maplayer = new OpenLayers.Layer.WMS( "San Andreas Map", - "http://code.opencoding.net/tilecache/tilecache.cgi?", {layers: 'sa_map', format: 'image/png' } ); - map.addLayer(maplayer); + // maplayer = new OpenLayers.Layer.WMS( "San Andreas Map", + // "http://code.opencoding.net/tilecache/tilecache.cgi?", {layers: 'sa_map', format: 'image/png' } ); + // map.addLayer(maplayer); - aeriallayer = new OpenLayers.Layer.WMS( "San Andreas Aerial Map", - "http://code.opencoding.net/tilecache/tilecache.cgi?", {layers: 'sa_aerial_map', format: 'image/png' } ); + aeriallayer = new OpenLayers.Layer.XYZ( "San Andreas Aerial Map", + "https://community.mtasa.blue/tilecache/${z}_${x}_${y}.jpg" ); map.addLayer(aeriallayer); map.zoomTo(2); From 6e61c775b52dffaaa98af1c19fd6f02d6208b993 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Sun, 24 Jan 2021 23:57:23 +0200 Subject: [PATCH 03/18] Add sea color as background color --- [web]/webmap/css.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/[web]/webmap/css.css b/[web]/webmap/css.css index bc6dfb823..53fdb57dc 100644 --- a/[web]/webmap/css.css +++ b/[web]/webmap/css.css @@ -12,7 +12,7 @@ body { padding: 0px; - background: #FFFFFF; + background: #00789d; font: bold 1em "Trebuchet MS", Arial, sans-serif; } #map { From 3dc77d90eac58945349246baa9a35ec67b924622 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Mon, 25 Jan 2021 18:11:45 +0200 Subject: [PATCH 04/18] Use the old maxResolution --- [web]/webmap/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index 09835057e..1583256d6 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -14,7 +14,7 @@ var bliplist = new Object; function init() { - map = new OpenLayers.Map( 'map', {'maxResolution': 1, 'maxExtent':new OpenLayers.Bounds(-90.0,-90.0,90.0,90.0), + map = new OpenLayers.Map( 'map', {'maxResolution': 360/512, 'maxExtent':new OpenLayers.Bounds(-90.0,-90.0,90.0,90.0), 'numZoomLevels':8, }); From 02b42865d94d3341558f0291345d069dab6a2a93 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Mon, 25 Jan 2021 18:11:59 +0200 Subject: [PATCH 05/18] Use aeriallayer when adding feature --- [web]/webmap/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index 1583256d6..569e7a3da 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -42,7 +42,7 @@ function init() function addPlayerMarker(player) { - var feature = new OpenLayers.Feature(maplayer, gtaCoordToLonLat(player.pos.x, player.pos.y), {icon:playericon.clone()}); + var feature = new OpenLayers.Feature(aeriallayer, gtaCoordToLonLat(player.pos.x, player.pos.y), {icon:playericon.clone()}); var marker = feature.createMarker(); marker.playerName = player.name; marker.feature = feature; @@ -53,7 +53,7 @@ function addPlayerMarker(player) function addBlipMarker(blip) { - var feature = new OpenLayers.Feature(maplayer, gtaCoordToLonLat(blip.pos.x, blip.pos.y), {icon:radaricons[blip.icon].clone()}); + var feature = new OpenLayers.Feature(aeriallayer, gtaCoordToLonLat(blip.pos.x, blip.pos.y), {icon:radaricons[blip.icon].clone()}); var marker = feature.createMarker(); marker.element = blip.element; marker.feature = feature; From 19671287ea62a504aa1cc53c63c0e8e79a8a6839 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Mon, 25 Jan 2021 18:12:13 +0200 Subject: [PATCH 06/18] Tweak mapx mapy in coord calc --- [web]/webmap/script.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index 569e7a3da..476eb0c65 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -64,16 +64,16 @@ function addBlipMarker(blip) // Takes a GTA x and y and returns a x and y on the map function gtaCoordToMap(x, y) { - var mapx = x * 0.03; - var mapy = y * 0.03; + var mapx = x * 0.03185; + var mapy = y * -0.015; return {x: mapx, y: mapy}; } // Takes a GTA x and y and returns a LonLat function gtaCoordToLonLat(x, y) { - var mapx = x * 0.03; - var mapy = y * 0.03; + var mapx = x * 0.03185; + var mapy = y * -0.015; return new OpenLayers.LonLat(mapx,mapy); } From 14c1e6f67ebb94278a785263e12fce7e647d6801 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Mon, 25 Jan 2021 18:23:23 +0200 Subject: [PATCH 07/18] Fix map missing in feature or marker for some reason --- [web]/webmap/script.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index 476eb0c65..82feb6895 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -48,6 +48,8 @@ function addPlayerMarker(player) marker.feature = feature; marker.events.register("mousedown", marker, showplayerinfo); playermarkers.addMarker(marker); + feature.map = map; + marker.map = map; return feature; } @@ -58,6 +60,8 @@ function addBlipMarker(blip) marker.element = blip.element; marker.feature = feature; blipmarkers.addMarker(marker); + feature.map = map; + marker.map = map; return feature; } From 9ed66a18bac09c83fef689dac2368d80efa51bb5 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Tue, 26 Jan 2021 20:27:44 +0200 Subject: [PATCH 08/18] Update source urls --- [web]/webmap/script.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index 82feb6895..d98473ace 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -15,18 +15,22 @@ var bliplist = new Object; function init() { map = new OpenLayers.Map( 'map', {'maxResolution': 360/512, 'maxExtent':new OpenLayers.Bounds(-90.0,-90.0,90.0,90.0), - 'numZoomLevels':8, + 'numZoomLevels':5, }); map.addControl(new OpenLayers.Control.LayerSwitcher({'div':OpenLayers.Util.getElement('layerswitcher')})); - // maplayer = new OpenLayers.Layer.WMS( "San Andreas Map", - // "http://code.opencoding.net/tilecache/tilecache.cgi?", {layers: 'sa_map', format: 'image/png' } ); - // map.addLayer(maplayer); + maplayer = new OpenLayers.Layer.XYZ( "San Andreas Map", + "https://assets.mtasa.com/mtasa-resources/webmap/sa_map/v1/${z}_${x}_${y}.jpg" ); + map.addLayer(maplayer); - aeriallayer = new OpenLayers.Layer.XYZ( "San Andreas Aerial Map", - "https://community.mtasa.blue/tilecache/${z}_${x}_${y}.jpg" ); - map.addLayer(aeriallayer); + aeriallayerv1 = new OpenLayers.Layer.XYZ( "San Andreas Aerial Map", + "https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v1/${z}_${x}_${y}.jpg" ); + map.addLayer(aeriallayerv1); + + aeriallayerv2 = new OpenLayers.Layer.XYZ( "San Andreas Aerial Map V2", + "https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v2/${z}_${x}_${y}.jpg" ); + map.addLayer(aeriallayerv2); map.zoomTo(2); @@ -42,7 +46,7 @@ function init() function addPlayerMarker(player) { - var feature = new OpenLayers.Feature(aeriallayer, gtaCoordToLonLat(player.pos.x, player.pos.y), {icon:playericon.clone()}); + var feature = new OpenLayers.Feature(maplayer, gtaCoordToLonLat(player.pos.x, player.pos.y), {icon:playericon.clone()}); var marker = feature.createMarker(); marker.playerName = player.name; marker.feature = feature; @@ -55,7 +59,7 @@ function addPlayerMarker(player) function addBlipMarker(blip) { - var feature = new OpenLayers.Feature(aeriallayer, gtaCoordToLonLat(blip.pos.x, blip.pos.y), {icon:radaricons[blip.icon].clone()}); + var feature = new OpenLayers.Feature(maplayer, gtaCoordToLonLat(blip.pos.x, blip.pos.y), {icon:radaricons[blip.icon].clone()}); var marker = feature.createMarker(); marker.element = blip.element; marker.feature = feature; From 0286aefea00e8e63cd11beee868edf076583bc0c Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Wed, 27 Jan 2021 23:49:57 +0200 Subject: [PATCH 09/18] Tweak map position and size --- [web]/webmap/css.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/[web]/webmap/css.css b/[web]/webmap/css.css index 53fdb57dc..a44a5f0f6 100644 --- a/[web]/webmap/css.css +++ b/[web]/webmap/css.css @@ -17,14 +17,14 @@ body { #map { width: 100%; - height: 99%; + height: 100%; } #mainarea { position: absolute; left: 0px; top: 37px; - bottom: 5px; + bottom: 0; right: 5px; } From 6b8ced9aaeff588e6a40b9a80ac7fed06d8dd41d Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Wed, 27 Jan 2021 23:52:29 +0200 Subject: [PATCH 10/18] Use html5 --- [web]/webmap/map.htm | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/[web]/webmap/map.htm b/[web]/webmap/map.htm index 45399b5c6..495c03d79 100644 --- a/[web]/webmap/map.htm +++ b/[web]/webmap/map.htm @@ -1,22 +1,26 @@ - - + + + + + + Web map - - <* = call(getResourceFromName("ajax"),"start", getResourceName(getThisResource()) ) *> - - - - + + <*= call(getResourceFromName("ajax"),"start", getResourceName(getThisResource())) *> + + + + +
Map
+
-
+
From f81527919502f0d7d7fbc46d54e2790c3512301a Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Wed, 27 Jan 2021 23:52:59 +0200 Subject: [PATCH 11/18] Minor style nit tweaks --- [web]/webmap/meta.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/[web]/webmap/meta.xml b/[web]/webmap/meta.xml index be942976e..5a431a1c6 100644 --- a/[web]/webmap/meta.xml +++ b/[web]/webmap/meta.xml @@ -1,12 +1,12 @@ + + + + + @@ -21,6 +25,7 @@
+
diff --git a/[web]/webmap/map.lua b/[web]/webmap/map.lua index 6973a6f93..1e141b8a3 100644 --- a/[web]/webmap/map.lua +++ b/[web]/webmap/map.lua @@ -1,30 +1,49 @@ -function players() - local players = getElementsByType("player") +function getAllPlayers() local tbl = {} - for k,v in ipairs(players) do - local x,y = getElementPosition(v) - local playerinfo = {name=getPlayerName(v), pos={x=x,y=y}, isdead=isPedDead(v)} - if ( isPedInVehicle(v) ) then - playerinfo.vehicle = getVehicleName(getPedOccupiedVehicle(v)) + for _, v in ipairs(getElementsByType("player")) do + local x, y, z = getElementPosition(v) + local _, _, rot = getElementRotation(v) + tbl[#tbl + 1] = { + name = getPlayerName(v), + pos = { + x = x, + y = y, + z = z, + }, + rot = rot, + isdead = isPedDead(v), + } + if (isPedInVehicle(v)) then + tbl[#tbl].vehicle = getVehicleName(getPedOccupiedVehicle(v)) end - table.insert(tbl, playerinfo) end return tbl end -function sendPlayerMessage(playername, message) - local player = getPlayerFromName(playername) - if ( player ) then - outputChatBox(" " .. message, player) - end -end - -function getAllBlips() +function getAllRadarBlips() local tbl = {} - local blips = getElementsByType("blip") - for k,v in ipairs(blips) do - local x,y = getElementPosition(v) - table.insert(tbl, {element=v, icon=getBlipIcon(v), pos={x=x,y=y}}) + for _, v in ipairs(getElementsByType("blip")) do + local x, y, z = getElementPosition(v) + tbl[#tbl + 1] = { + element = v, + icon = getBlipIcon(v), + size = getBlipSize(v), + color = { + getBlipColor(v), + }, + pos = { + x = x, + y = y, + z = z, + }, + } end return tbl end + +function sendPlayerMessage(playername, message) + local player = getPlayerFromName(playername) + if (not player) then return end + outputServerLog(" " .. message, player) + outputChatBox(" " .. message, player) +end diff --git a/[web]/webmap/meta.xml b/[web]/webmap/meta.xml index 5a431a1c6..3730aa99d 100644 --- a/[web]/webmap/meta.xml +++ b/[web]/webmap/meta.xml @@ -8,7 +8,7 @@ - + + - diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index d98473ace..59d62da63 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -1,256 +1,335 @@ -var map, maplayer, aeriallayer, playermarkers, blipmarkers; -var playericon = new OpenLayers.Icon("geticon.htm?id=02", new OpenLayers.Size(15,15)); -var deadicon = new OpenLayers.Icon("geticon.htm?id=23", new OpenLayers.Size(15,15)); -var radaricons = new Array(); -for ( var i =0; i <= 63; i++ ) -{ - var ai = i; - if ( ai <= 9 ) - ai = "0" + ai; - radaricons[i] = new OpenLayers.Icon("geticon.htm?id=" + ai, new OpenLayers.Size(15,15)); -} -var playerlist = new Object; -var bliplist = new Object; +const rad = Math.PI / 180; +const extent = [-3000, -3000, 3000, 3000]; + +const syncedPlayers = {}; +const syncedRadarBlips = {}; + +let popupEl; +let gtasaProjection; +let tilegrid; +let playerVectorSource; +let radarBlipVectorSource; +let mousePositionControl; +let layerSwitcherControl; +let map; +let selectSingleClick; +let selectedPlayer; +let followingPlayer; + +function init() { + popupEl = document.getElementById('popup'); + + gtasaProjection = new ol.proj.Projection({ + code: 'ZOOMIFY', + units: 'pixels', + extent, + }); -function init() -{ - map = new OpenLayers.Map( 'map', {'maxResolution': 360/512, 'maxExtent':new OpenLayers.Bounds(-90.0,-90.0,90.0,90.0), - 'numZoomLevels':5, + tilegrid = new ol.tilegrid.TileGrid({ + extent, + resolutions: [8, 4, 2, 1], }); - map.addControl(new OpenLayers.Control.LayerSwitcher({'div':OpenLayers.Util.getElement('layerswitcher')})); + playerVectorSource = new ol.source.Vector({ + projection: gtasaProjection, + }); - maplayer = new OpenLayers.Layer.XYZ( "San Andreas Map", - "https://assets.mtasa.com/mtasa-resources/webmap/sa_map/v1/${z}_${x}_${y}.jpg" ); - map.addLayer(maplayer); + radarBlipVectorSource = new ol.source.Vector({ + projection: gtasaProjection, + }); - aeriallayerv1 = new OpenLayers.Layer.XYZ( "San Andreas Aerial Map", - "https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v1/${z}_${x}_${y}.jpg" ); - map.addLayer(aeriallayerv1); + mousePositionControl = new ol.control.MousePosition({ + coordinateFormat: ol.coordinate.createStringXY(0), + }); - aeriallayerv2 = new OpenLayers.Layer.XYZ( "San Andreas Aerial Map V2", - "https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v2/${z}_${x}_${y}.jpg" ); - map.addLayer(aeriallayerv2); + layerSwitcherControl = new ol.control.LayerSwitcher({ + tipLabel: 'Layers', + }); - map.zoomTo(2); + popupOverlay = new ol.Overlay({ + autoPan: true, + autoPanAnimation: { + duration: 250, + }, + element: popupEl, + }); - blipmarkers = new OpenLayers.Layer.Markers("Radar Blips"); - map.addLayer(blipmarkers); + map = new ol.Map({ + controls: [ + layerSwitcherControl, + mousePositionControl, + ], + layers: [ + new ol.layer.Group({ + layers: [ + new ol.layer.Tile({ + source: new ol.source.TileDebug({ + tileGrid: tilegrid, + projection: gtasaProjection, + }), + title: "Grid Debug", + visible: false, + zIndex: 100, + }), + new ol.layer.Vector({ + source: radarBlipVectorSource, + title: "Radar Blips", + visible: true, + zIndex: 80, + }), + new ol.layer.Vector({ + source: playerVectorSource, + title: "Players", + visible: true, + zIndex: 90, + }), + ], + title: 'Overlays', + }), + new ol.layer.Group({ + fold: 'open', + layers: [ + new ol.layer.Tile({ + source: new ol.source.XYZ({ + projection: gtasaProjection, + tileSize: 500, + url: 'https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v2/{z}_{x}_{y}.jpg', + wrapX: false, + }), + title: "San Andreas Aerial Map V2", + type: 'base', + visible: true, + }), + new ol.layer.Tile({ + source: new ol.source.XYZ({ + projection: gtasaProjection, + tileSize: 500, + url: 'https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v1/{z}_{x}_{y}.jpg', + wrapX: false, + }), + title: "San Andreas Aerial Map", + type: 'base', + visible: false, + }), + new ol.layer.Tile({ + source: new ol.source.XYZ({ + projection: gtasaProjection, + tileSize: 500, + url: 'https://assets.mtasa.com/mtasa-resources/webmap/sa_map/v1/{z}_{x}_{y}.jpg', + wrapX: false, + }), + title: "San Andreas Map", + type: 'base', + visible: false, + }), + ], + title: 'Map style', + }), + ], + overlays: [popupOverlay], + target: 'map', + view: new ol.View({ + center: ol.extent.getCenter(extent), + extent, + projection: gtasaProjection, + resolutions: tilegrid.getResolutions(), + showFullExtent: true, + zoom: 0, + }), + }); - playermarkers = new OpenLayers.Layer.Markers("Players"); - map.addLayer(playermarkers); + map.on('singleclick', function (e) { + const features = map.getFeaturesAtPixel(e.pixel); - updatePlayerInfo(); - updateBlips(); -} + for (let i = 0; i < features.length; i++) { + const feature = features[i]; + const playerEntry = Object.entries(syncedPlayers).find(function (entry) { + return entry[1].feature === feature; + }); + if (!playerEntry) continue; -function addPlayerMarker(player) -{ - var feature = new OpenLayers.Feature(maplayer, gtaCoordToLonLat(player.pos.x, player.pos.y), {icon:playericon.clone()}); - var marker = feature.createMarker(); - marker.playerName = player.name; - marker.feature = feature; - marker.events.register("mousedown", marker, showplayerinfo); - playermarkers.addMarker(marker); - feature.map = map; - marker.map = map; - return feature; -} + selectedPlayer = playerEntry[0]; -function addBlipMarker(blip) -{ - var feature = new OpenLayers.Feature(maplayer, gtaCoordToLonLat(blip.pos.x, blip.pos.y), {icon:radaricons[blip.icon].clone()}); - var marker = feature.createMarker(); - marker.element = blip.element; - marker.feature = feature; - blipmarkers.addMarker(marker); - feature.map = map; - marker.map = map; - return feature; -} + const player = syncedPlayers[selectedPlayer]; -// Takes a GTA x and y and returns a x and y on the map -function gtaCoordToMap(x, y) -{ - var mapx = x * 0.03185; - var mapy = y * -0.015; - return {x: mapx, y: mapy}; -} + let html = selectedPlayer + "
"; + + if (player.vehicle) + html += "In vehicle: " + player.vehicle + "
"; + + html += "Send: " + if (selectedPlayer === followingPlayer) + var checked = "checked='checked'"; + + html += " "; + html += "
"; + + popupEl.innerHTML = html; + + popupOverlay.setPosition(e.coordinate); + + return; + } -// Takes a GTA x and y and returns a LonLat -function gtaCoordToLonLat(x, y) -{ - var mapx = x * 0.03185; - var mapy = y * -0.015; - return new OpenLayers.LonLat(mapx,mapy); + closePopup(); + }); + + updatePlayerBlips(); + updateRadarBlips(); } -var blipUpdateCount = 0; -function updateBlips() -{ - getAllBlips ( - function ( blips ) - { - for ( var k = 0; k < blips.length; k++ ) - { - if ( bliplist[blips[k].element.id] == null ) { - bliplist[blips[k].element.id] = new Object(); - bliplist[blips[k].element.id].feature = addBlipMarker(blips[k]); - } else { - var latlong = gtaCoordToLonLat(blips[k].pos.x, blips[k].pos.y); - bliplist[blips[k].element.id].feature.lonlat = latlong; - bliplist[blips[k].element.id].feature.marker.moveTo(map.getLayerPxFromLonLat(latlong)); - } - bliplist[blips[k].element.id].data = blips[k]; - bliplist[blips[k].element.id].lastUpdate = blipUpdateCount; - - /*if ( playerinfo[i].isdead ) - playerlist[playerinfo[i].name].feature.marker.icon = deadicon; - else - playerlist[playerinfo[i].name].feature.marker.icon = playericon;*/ - } - for ( var j in bliplist ) - { - if ( j != "toJSONString" ) - { - if ( bliplist[j].lastUpdate != blipUpdateCount ) { - blipmarkers.removeMarker(bliplist[j].feature.marker); - delete bliplist[j]; - } - } - } +function addPlayerBlip(player) { + const feature = new ol.Feature({ + geometry: new ol.geom.Point([player.pos.x, player.pos.y]), + }); + feature.setStyle(new ol.style.Style({ + image: new ol.style.Icon({ + color: player.isdead ? [200, 0, 0, 1] : [255, 255, 255, 1], + rotation: -player.rot * rad, + src: 'geticon.htm?id=02', + }), + })); - blipUpdateCount++; + playerVectorSource.addFeature(feature); - setTimeout(updateBlips, 5000); - } - ); + return feature; } -var updateCount = 0; -function updatePlayerInfo() -{ - players ( - function ( playerinfo ) - { - for ( var i = 0; i < playerinfo.length; i++ ) - { - if ( playerlist[playerinfo[i].name] == null ) { - playerlist[playerinfo[i].name] = new Object(); - playerlist[playerinfo[i].name].feature = addPlayerMarker(playerinfo[i]); +function addRadarBlip(blip) { + const feature = new ol.Feature({ + geometry: new ol.geom.Point([blip.pos.x, blip.pos.y]), + }); + let image; - } else { - var latlong = gtaCoordToLonLat(playerinfo[i].pos.x, playerinfo[i].pos.y); - playerlist[playerinfo[i].name].feature.lonlat = latlong; + const color = blip.color; + color[3] = color[3] / 255; // 0..1 scale + if (blip.icon === 0) { + image = new ol.style.RegularShape({ + angle: 45 * rad, + fill: new ol.style.Fill({ color }), + points: 4, + radius: blip.size * 4, + stroke: new ol.style.Stroke({ color: [0, 0, 0, 1], width: 1.5 }), + }); + } else { + image = new ol.style.Icon({ + // color, // Works, but disabled because tint is not used in GTA/MTA for radar blip icons + src: 'geticon.htm?id=' + String(blip.icon).padStart(2, 0), + }); + } - if ( playerToFollow == playerinfo[i].name ) - map.setCenter(latlong, map.getZoom(), false, false); + feature.setStyle(new ol.style.Style({ image })); - playerlist[playerinfo[i].name].feature.marker.moveTo(map.getLayerPxFromLonLat(latlong)); - } - playerlist[playerinfo[i].name].data = playerinfo[i]; - playerlist[playerinfo[i].name].lastUpdate = updateCount; + radarBlipVectorSource.addFeature(feature); + return feature; +} - /*if ( playerinfo[i].isdead ) - playerlist[playerinfo[i].name].feature.marker.icon = deadicon; - else - playerlist[playerinfo[i].name].feature.marker.icon = playericon;*/ - } - for ( var j in playerlist ) - { - if ( j != "toJSONString" ) - { - if ( playerlist[j].lastUpdate != updateCount ) { - playermarkers.removeMarker(playerlist[j].feature.marker); - delete playerlist[j]; - } - } +function updateRadarBlips() { + getAllRadarBlips(function (blips) { + // Delete destroyed blips + Object.entries(syncedRadarBlips).filter(function (entry) { + return !blips.find(function (blip) { + return blip.element.id === entry[0]; + }); + }).forEach(function (entry) { + radarBlipVectorSource.removeFeature(entry[1].feature); + delete syncedRadarBlips[entry[0]]; + }); + + // Add/refresh existing blips + blips.forEach(function (blip) { + if (!syncedRadarBlips[blip.element.id]) { + syncedRadarBlips[blip.element.id] = {}; + } else { + // We delete the old feature to be able to reset some styles + // not possible to edit through existing methods provided by OL + radarBlipVectorSource.removeFeature(syncedRadarBlips[blip.element.id].feature); } + syncedRadarBlips[blip.element.id].feature = addRadarBlip(blip); + syncedRadarBlips[blip.element.id].data = blip; + }); - updateCount++; - - setTimeout(updatePlayerInfo, 1000); - } - ); + setTimeout(updateRadarBlips, 5000); + }); } -function checkSendMessage(e) -{ - var characterCode +function updatePlayerBlips() { + getAllPlayers(function (players) { + // Delete disconnected players + Object.entries(syncedPlayers).filter(function (entry) { + return !players.find(function (player) { + return player.name === entry[0]; + }); + }).forEach(function (entry) { + playerVectorSource.removeFeature(entry[1].feature); + delete syncedPlayers[entry[0]]; + }); + + if (selectedPlayer) { + if (syncedPlayers[selectedPlayer]) { + popupOverlay.setPosition(syncedPlayers[selectedPlayer].feature.getGeometry().getCoordinates()); + } else { + popupOverlay.setPosition(undefined); + selectedPlayer = null; + } + } - if(e && e.which){ //if which property of event object is supported (NN4) - e = e - characterCode = e.which //character code is contained in NN4's which property + if (followingPlayer) { + if (syncedPlayers[followingPlayer]) { + map.getView().setCenter(syncedPlayers[followingPlayer].feature.getGeometry().getCoordinates()); + } else { + followingPlayer = null; + } } - else{ - e = event - characterCode = e.keyCode //character code is contained in IE's keyCode property - } - if(characterCode == 13){ //if generated character code is equal to ascii 13 (if enter key) - var messageBox = document.getElementById('sendMessageBox'); - sendPlayerMessage ( popupPlayer, messageBox.value, function() { } ); - messageBox.value = ""; - return false - } - else{ - return true - } -} + // Add/refresh connected players + players.forEach(function (player) { + if (!syncedPlayers[player.name]) { + syncedPlayers[player.name] = {}; + } else { + // We delete the old feature to be able to reset some styles + // not possible to edit through existing methods provided by OL + playerVectorSource.removeFeature(syncedPlayers[player.name].feature); + } -var playerToFollow = null; + syncedPlayers[player.name].feature = addPlayerBlip(player); + syncedPlayers[player.name].data = player; + }); -function followPlayer() -{ - var followPlayerCheckbox = document.getElementById("followPlayerCheckbox"); - if ( followPlayerCheckbox.checked == true ) - playerToFollow = popupPlayer; - else - playerToFollow = null; + setTimeout(updatePlayerBlips, 1000); + }); } -var popup; -var popupPlayer = null; -function showplayerinfo(evt) { - // check to see if the popup was hidden by the close box - // if so, then destroy it before continuing - if (popup != null) { - if (!popup.visible()) { - playermarkers.map.removePopup(popup); - popup.destroy(); - popup = null; - } - } - if (popup == null) { - var playerinfo = playerlist[this.playerName].data; - var html = playerinfo.name + "
"; - if ( playerinfo.vehicle != null ) - html += "In vehicle: " + playerinfo.vehicle + "
"; +function checkSendMessage(e) { + // If not enter key, stop here + if (e.keyCode !== 13) return true; - popupPlayer= this.playerName; + const messageBox = document.getElementById('sendMessageBox'); + const message = messageBox.value.trim(); + messageBox.value = ""; - html += "Send: " - if ( popupPlayer == playerToFollow ) - var checked = "checked='checked'"; + // If no message entered, stop here + if (!message) return true; - html += " " - html += "
"; + sendPlayerMessage(selectedPlayer, message, function () {}); + return false; +} - popup = this.feature.createPopup(true); - popup.setContentHTML(html); - popup.setBackgroundColor("#888888"); - popup.setOpacity(0.8); - playermarkers.map.addPopup(popup); +function followPlayer() { + if (document.getElementById("followPlayerCheckbox").checked) { + followingPlayer = selectedPlayer; + map.getView().setCenter(syncedPlayers[followingPlayer].feature.getGeometry().getCoordinates()); } else { - playermarkers.map.removePopup(popup); - popup.destroy(); - popup = null; + followingPlayer = null; } - OpenLayers.Event.stop(evt); } +function closePopup() { + popupOverlay.setPosition(undefined); + selectedPlayer = null; +} \ No newline at end of file From dc32ac48f181e584bfea0e0bdd984af1421e90a7 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:16:00 +0200 Subject: [PATCH 13/18] Add editorconfig, prettierrc and prettify code --- [web]/webmap/.editorconfig | 22 ++ [web]/webmap/.prettierrc | 7 + [web]/webmap/script.js | 606 +++++++++++++++++++------------------ 3 files changed, 344 insertions(+), 291 deletions(-) create mode 100644 [web]/webmap/.editorconfig create mode 100644 [web]/webmap/.prettierrc diff --git a/[web]/webmap/.editorconfig b/[web]/webmap/.editorconfig new file mode 100644 index 000000000..583416960 --- /dev/null +++ b/[web]/webmap/.editorconfig @@ -0,0 +1,22 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# top-most EditorConfig file +root = true + +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 2 +indent_style = space +insert_final_newline = true + +# Get rid of whitespace to avoid diffs with a bunch of EOL changes +trim_trailing_whitespace = true + +[*.md] +max_line_length = 0 +trim_trailing_whitespace = false + +[*.css] +indent_size = 4 diff --git a/[web]/webmap/.prettierrc b/[web]/webmap/.prettierrc new file mode 100644 index 000000000..8e574cb5a --- /dev/null +++ b/[web]/webmap/.prettierrc @@ -0,0 +1,7 @@ +{ + "bracketSpacing": true, + "singleQuote": true, + "trailingComma": "all", + "arrowParens": "always", + "jsxBracketSameLine": true +} diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index 59d62da63..e789f1474 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -17,319 +17,343 @@ let selectedPlayer; let followingPlayer; function init() { - popupEl = document.getElementById('popup'); - - gtasaProjection = new ol.proj.Projection({ - code: 'ZOOMIFY', - units: 'pixels', - extent, - }); - - tilegrid = new ol.tilegrid.TileGrid({ - extent, - resolutions: [8, 4, 2, 1], - }); - - playerVectorSource = new ol.source.Vector({ - projection: gtasaProjection, - }); - - radarBlipVectorSource = new ol.source.Vector({ - projection: gtasaProjection, - }); - - mousePositionControl = new ol.control.MousePosition({ - coordinateFormat: ol.coordinate.createStringXY(0), - }); - - layerSwitcherControl = new ol.control.LayerSwitcher({ - tipLabel: 'Layers', - }); - - popupOverlay = new ol.Overlay({ - autoPan: true, - autoPanAnimation: { - duration: 250, - }, - element: popupEl, - }); - - map = new ol.Map({ - controls: [ - layerSwitcherControl, - mousePositionControl, - ], - layers: [ - new ol.layer.Group({ - layers: [ - new ol.layer.Tile({ - source: new ol.source.TileDebug({ - tileGrid: tilegrid, - projection: gtasaProjection, - }), - title: "Grid Debug", - visible: false, - zIndex: 100, - }), - new ol.layer.Vector({ - source: radarBlipVectorSource, - title: "Radar Blips", - visible: true, - zIndex: 80, - }), - new ol.layer.Vector({ - source: playerVectorSource, - title: "Players", - visible: true, - zIndex: 90, - }), - ], - title: 'Overlays', - }), - new ol.layer.Group({ - fold: 'open', - layers: [ - new ol.layer.Tile({ - source: new ol.source.XYZ({ - projection: gtasaProjection, - tileSize: 500, - url: 'https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v2/{z}_{x}_{y}.jpg', - wrapX: false, - }), - title: "San Andreas Aerial Map V2", - type: 'base', - visible: true, - }), - new ol.layer.Tile({ - source: new ol.source.XYZ({ - projection: gtasaProjection, - tileSize: 500, - url: 'https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v1/{z}_{x}_{y}.jpg', - wrapX: false, - }), - title: "San Andreas Aerial Map", - type: 'base', - visible: false, - }), - new ol.layer.Tile({ - source: new ol.source.XYZ({ - projection: gtasaProjection, - tileSize: 500, - url: 'https://assets.mtasa.com/mtasa-resources/webmap/sa_map/v1/{z}_{x}_{y}.jpg', - wrapX: false, - }), - title: "San Andreas Map", - type: 'base', - visible: false, - }), - ], - title: 'Map style', - }), - ], - overlays: [popupOverlay], - target: 'map', - view: new ol.View({ - center: ol.extent.getCenter(extent), - extent, - projection: gtasaProjection, - resolutions: tilegrid.getResolutions(), - showFullExtent: true, - zoom: 0, - }), - }); - - map.on('singleclick', function (e) { - const features = map.getFeaturesAtPixel(e.pixel); - - for (let i = 0; i < features.length; i++) { - const feature = features[i]; - const playerEntry = Object.entries(syncedPlayers).find(function (entry) { - return entry[1].feature === feature; - }); - if (!playerEntry) continue; - - selectedPlayer = playerEntry[0]; - - const player = syncedPlayers[selectedPlayer]; - - let html = selectedPlayer + "
"; - - if (player.vehicle) - html += "In vehicle: " + player.vehicle + "
"; - - html += "Send: " - if (selectedPlayer === followingPlayer) - var checked = "checked='checked'"; - - html += " "; - html += "
"; - - popupEl.innerHTML = html; - - popupOverlay.setPosition(e.coordinate); - - return; - } - - closePopup(); - }); - - updatePlayerBlips(); - updateRadarBlips(); + popupEl = document.getElementById('popup'); + + gtasaProjection = new ol.proj.Projection({ + code: 'ZOOMIFY', + units: 'pixels', + extent, + }); + + tilegrid = new ol.tilegrid.TileGrid({ + extent, + resolutions: [8, 4, 2, 1], + }); + + playerVectorSource = new ol.source.Vector({ + projection: gtasaProjection, + }); + + radarBlipVectorSource = new ol.source.Vector({ + projection: gtasaProjection, + }); + + mousePositionControl = new ol.control.MousePosition({ + coordinateFormat: ol.coordinate.createStringXY(0), + }); + + layerSwitcherControl = new ol.control.LayerSwitcher({ + tipLabel: 'Layers', + }); + + popupOverlay = new ol.Overlay({ + autoPan: true, + autoPanAnimation: { + duration: 250, + }, + element: popupEl, + }); + + map = new ol.Map({ + controls: [layerSwitcherControl, mousePositionControl], + layers: [ + new ol.layer.Group({ + layers: [ + new ol.layer.Tile({ + source: new ol.source.TileDebug({ + tileGrid: tilegrid, + projection: gtasaProjection, + }), + title: 'Grid Debug', + visible: false, + zIndex: 100, + }), + new ol.layer.Vector({ + source: radarBlipVectorSource, + title: 'Radar Blips', + visible: true, + zIndex: 80, + }), + new ol.layer.Vector({ + source: playerVectorSource, + title: 'Players', + visible: true, + zIndex: 90, + }), + ], + title: 'Overlays', + }), + new ol.layer.Group({ + fold: 'open', + layers: [ + new ol.layer.Tile({ + source: new ol.source.XYZ({ + projection: gtasaProjection, + tileSize: 500, + url: + 'https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v2/{z}_{x}_{y}.jpg', + wrapX: false, + }), + title: 'San Andreas Aerial Map V2', + type: 'base', + visible: true, + }), + new ol.layer.Tile({ + source: new ol.source.XYZ({ + projection: gtasaProjection, + tileSize: 500, + url: + 'https://assets.mtasa.com/mtasa-resources/webmap/sa_aerial_map/v1/{z}_{x}_{y}.jpg', + wrapX: false, + }), + title: 'San Andreas Aerial Map', + type: 'base', + visible: false, + }), + new ol.layer.Tile({ + source: new ol.source.XYZ({ + projection: gtasaProjection, + tileSize: 500, + url: + 'https://assets.mtasa.com/mtasa-resources/webmap/sa_map/v1/{z}_{x}_{y}.jpg', + wrapX: false, + }), + title: 'San Andreas Map', + type: 'base', + visible: false, + }), + ], + title: 'Map style', + }), + ], + overlays: [popupOverlay], + target: 'map', + view: new ol.View({ + center: ol.extent.getCenter(extent), + extent, + projection: gtasaProjection, + resolutions: tilegrid.getResolutions(), + showFullExtent: true, + zoom: 0, + }), + }); + + map.on('singleclick', function (e) { + const features = map.getFeaturesAtPixel(e.pixel); + + for (let i = 0; i < features.length; i++) { + const feature = features[i]; + const playerEntry = Object.entries(syncedPlayers).find(function (entry) { + return entry[1].feature === feature; + }); + if (!playerEntry) continue; + + selectedPlayer = playerEntry[0]; + + const player = syncedPlayers[selectedPlayer]; + + let html = + selectedPlayer + + "
"; + + if (player.vehicle) html += 'In vehicle: ' + player.vehicle + '
'; + + html += + "Send: "; + if (selectedPlayer === followingPlayer) var checked = "checked='checked'"; + + html += + " "; + html += '
'; + + popupEl.innerHTML = html; + + popupOverlay.setPosition(e.coordinate); + + return; + } + + closePopup(); + }); + + updatePlayerBlips(); + updateRadarBlips(); } function addPlayerBlip(player) { - const feature = new ol.Feature({ - geometry: new ol.geom.Point([player.pos.x, player.pos.y]), - }); - - feature.setStyle(new ol.style.Style({ - image: new ol.style.Icon({ - color: player.isdead ? [200, 0, 0, 1] : [255, 255, 255, 1], - rotation: -player.rot * rad, - src: 'geticon.htm?id=02', - }), - })); - - playerVectorSource.addFeature(feature); - - return feature; + const feature = new ol.Feature({ + geometry: new ol.geom.Point([player.pos.x, player.pos.y]), + }); + + feature.setStyle( + new ol.style.Style({ + image: new ol.style.Icon({ + color: player.isdead ? [200, 0, 0, 1] : [255, 255, 255, 1], + rotation: -player.rot * rad, + src: 'geticon.htm?id=02', + }), + }), + ); + + playerVectorSource.addFeature(feature); + + return feature; } function addRadarBlip(blip) { - const feature = new ol.Feature({ - geometry: new ol.geom.Point([blip.pos.x, blip.pos.y]), - }); - - let image; - - const color = blip.color; - color[3] = color[3] / 255; // 0..1 scale - - if (blip.icon === 0) { - image = new ol.style.RegularShape({ - angle: 45 * rad, - fill: new ol.style.Fill({ color }), - points: 4, - radius: blip.size * 4, - stroke: new ol.style.Stroke({ color: [0, 0, 0, 1], width: 1.5 }), - }); - } else { - image = new ol.style.Icon({ - // color, // Works, but disabled because tint is not used in GTA/MTA for radar blip icons - src: 'geticon.htm?id=' + String(blip.icon).padStart(2, 0), - }); - } - - feature.setStyle(new ol.style.Style({ image })); - - radarBlipVectorSource.addFeature(feature); - return feature; + const feature = new ol.Feature({ + geometry: new ol.geom.Point([blip.pos.x, blip.pos.y]), + }); + + let image; + + const color = blip.color; + color[3] = color[3] / 255; // 0..1 scale + + if (blip.icon === 0) { + image = new ol.style.RegularShape({ + angle: 45 * rad, + fill: new ol.style.Fill({ color }), + points: 4, + radius: blip.size * 4, + stroke: new ol.style.Stroke({ color: [0, 0, 0, 1], width: 1.5 }), + }); + } else { + image = new ol.style.Icon({ + // color, // Works, but disabled because tint is not used in GTA/MTA for radar blip icons + src: 'geticon.htm?id=' + String(blip.icon).padStart(2, 0), + }); + } + + feature.setStyle(new ol.style.Style({ image })); + + radarBlipVectorSource.addFeature(feature); + return feature; } function updateRadarBlips() { - getAllRadarBlips(function (blips) { - // Delete destroyed blips - Object.entries(syncedRadarBlips).filter(function (entry) { - return !blips.find(function (blip) { - return blip.element.id === entry[0]; - }); - }).forEach(function (entry) { - radarBlipVectorSource.removeFeature(entry[1].feature); - delete syncedRadarBlips[entry[0]]; - }); - - // Add/refresh existing blips - blips.forEach(function (blip) { - if (!syncedRadarBlips[blip.element.id]) { - syncedRadarBlips[blip.element.id] = {}; - } else { - // We delete the old feature to be able to reset some styles - // not possible to edit through existing methods provided by OL - radarBlipVectorSource.removeFeature(syncedRadarBlips[blip.element.id].feature); - } - - syncedRadarBlips[blip.element.id].feature = addRadarBlip(blip); - syncedRadarBlips[blip.element.id].data = blip; - }); - - setTimeout(updateRadarBlips, 5000); - }); + getAllRadarBlips(function (blips) { + // Delete destroyed blips + Object.entries(syncedRadarBlips) + .filter(function (entry) { + return !blips.find(function (blip) { + return blip.element.id === entry[0]; + }); + }) + .forEach(function (entry) { + radarBlipVectorSource.removeFeature(entry[1].feature); + delete syncedRadarBlips[entry[0]]; + }); + + // Add/refresh existing blips + blips.forEach(function (blip) { + if (!syncedRadarBlips[blip.element.id]) { + syncedRadarBlips[blip.element.id] = {}; + } else { + // We delete the old feature to be able to reset some styles + // not possible to edit through existing methods provided by OL + radarBlipVectorSource.removeFeature( + syncedRadarBlips[blip.element.id].feature, + ); + } + + syncedRadarBlips[blip.element.id].feature = addRadarBlip(blip); + syncedRadarBlips[blip.element.id].data = blip; + }); + + setTimeout(updateRadarBlips, 5000); + }); } function updatePlayerBlips() { - getAllPlayers(function (players) { - // Delete disconnected players - Object.entries(syncedPlayers).filter(function (entry) { - return !players.find(function (player) { - return player.name === entry[0]; - }); - }).forEach(function (entry) { - playerVectorSource.removeFeature(entry[1].feature); - delete syncedPlayers[entry[0]]; - }); - - if (selectedPlayer) { - if (syncedPlayers[selectedPlayer]) { - popupOverlay.setPosition(syncedPlayers[selectedPlayer].feature.getGeometry().getCoordinates()); - } else { - popupOverlay.setPosition(undefined); - selectedPlayer = null; - } - } - - if (followingPlayer) { - if (syncedPlayers[followingPlayer]) { - map.getView().setCenter(syncedPlayers[followingPlayer].feature.getGeometry().getCoordinates()); - } else { - followingPlayer = null; - } - } - - // Add/refresh connected players - players.forEach(function (player) { - if (!syncedPlayers[player.name]) { - syncedPlayers[player.name] = {}; - } else { - // We delete the old feature to be able to reset some styles - // not possible to edit through existing methods provided by OL - playerVectorSource.removeFeature(syncedPlayers[player.name].feature); - } - - syncedPlayers[player.name].feature = addPlayerBlip(player); - syncedPlayers[player.name].data = player; - }); - - setTimeout(updatePlayerBlips, 1000); - }); + getAllPlayers(function (players) { + // Delete disconnected players + Object.entries(syncedPlayers) + .filter(function (entry) { + return !players.find(function (player) { + return player.name === entry[0]; + }); + }) + .forEach(function (entry) { + playerVectorSource.removeFeature(entry[1].feature); + delete syncedPlayers[entry[0]]; + }); + + if (selectedPlayer) { + if (syncedPlayers[selectedPlayer]) { + popupOverlay.setPosition( + syncedPlayers[selectedPlayer].feature.getGeometry().getCoordinates(), + ); + } else { + popupOverlay.setPosition(undefined); + selectedPlayer = null; + } + } + + if (followingPlayer) { + if (syncedPlayers[followingPlayer]) { + map + .getView() + .setCenter( + syncedPlayers[followingPlayer].feature + .getGeometry() + .getCoordinates(), + ); + } else { + followingPlayer = null; + } + } + + // Add/refresh connected players + players.forEach(function (player) { + if (!syncedPlayers[player.name]) { + syncedPlayers[player.name] = {}; + } else { + // We delete the old feature to be able to reset some styles + // not possible to edit through existing methods provided by OL + playerVectorSource.removeFeature(syncedPlayers[player.name].feature); + } + + syncedPlayers[player.name].feature = addPlayerBlip(player); + syncedPlayers[player.name].data = player; + }); + + setTimeout(updatePlayerBlips, 1000); + }); } function checkSendMessage(e) { - // If not enter key, stop here - if (e.keyCode !== 13) return true; + // If not enter key, stop here + if (e.keyCode !== 13) return true; - const messageBox = document.getElementById('sendMessageBox'); - const message = messageBox.value.trim(); - messageBox.value = ""; + const messageBox = document.getElementById('sendMessageBox'); + const message = messageBox.value.trim(); + messageBox.value = ''; - // If no message entered, stop here - if (!message) return true; + // If no message entered, stop here + if (!message) return true; - sendPlayerMessage(selectedPlayer, message, function () {}); + sendPlayerMessage(selectedPlayer, message, function () {}); - return false; + return false; } function followPlayer() { - if (document.getElementById("followPlayerCheckbox").checked) { - followingPlayer = selectedPlayer; - map.getView().setCenter(syncedPlayers[followingPlayer].feature.getGeometry().getCoordinates()); - } else { - followingPlayer = null; - } + if (document.getElementById('followPlayerCheckbox').checked) { + followingPlayer = selectedPlayer; + map + .getView() + .setCenter( + syncedPlayers[followingPlayer].feature.getGeometry().getCoordinates(), + ); + } else { + followingPlayer = null; + } } function closePopup() { - popupOverlay.setPosition(undefined); - selectedPlayer = null; -} \ No newline at end of file + popupOverlay.setPosition(undefined); + selectedPlayer = null; +} From 1589395540cdaa2631a1be70afa52f72f95cfed8 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:16:16 +0200 Subject: [PATCH 14/18] Use closePopup function --- [web]/webmap/script.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/[web]/webmap/script.js b/[web]/webmap/script.js index e789f1474..71a8be343 100644 --- a/[web]/webmap/script.js +++ b/[web]/webmap/script.js @@ -287,8 +287,7 @@ function updatePlayerBlips() { syncedPlayers[selectedPlayer].feature.getGeometry().getCoordinates(), ); } else { - popupOverlay.setPosition(undefined); - selectedPlayer = null; + closePopup(); } } From 47a8d43b3e0ef0eea76f7ebd29ba6aa8a2f4a9c4 Mon Sep 17 00:00:00 2001 From: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:23:24 +0200 Subject: [PATCH 15/18] Clean up meta.xml --- [web]/webmap/meta.xml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/[web]/webmap/meta.xml b/[web]/webmap/meta.xml index 3730aa99d..4d94b66fc 100644 --- a/[web]/webmap/meta.xml +++ b/[web]/webmap/meta.xml @@ -1,11 +1,14 @@ - -