diff --git a/config.xml b/config.xml index b66354d..b1b64b1 100644 --- a/config.xml +++ b/config.xml @@ -1,5 +1,5 @@ - + TerranQuest Augmented Reality fantasy game diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock b/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock index 7babce5..8850085 100644 Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock and b/platforms/android/.gradle/2.2.1/taskArtifacts/cache.properties.lock differ diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin b/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin index 84b4326..0a261c0 100644 Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin and b/platforms/android/.gradle/2.2.1/taskArtifacts/fileHashes.bin differ diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin b/platforms/android/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin index e9c4e09..3a4115c 100644 Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin and b/platforms/android/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin differ diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/outputFileStates.bin b/platforms/android/.gradle/2.2.1/taskArtifacts/outputFileStates.bin index 8745fad..b2704fe 100644 Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/outputFileStates.bin and b/platforms/android/.gradle/2.2.1/taskArtifacts/outputFileStates.bin differ diff --git a/platforms/android/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin b/platforms/android/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin index 04125ff..6d83b63 100644 Binary files a/platforms/android/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin and b/platforms/android/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin differ diff --git a/platforms/android/AndroidManifest.xml b/platforms/android/AndroidManifest.xml index 67ce55b..5e5ad44 100644 --- a/platforms/android/AndroidManifest.xml +++ b/platforms/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/platforms/android/android.json b/platforms/android/android.json index deff1cf..e2aeb20 100644 --- a/platforms/android/android.json +++ b/platforms/android/android.json @@ -494,6 +494,6 @@ "cordova-plugin-media": "2.2.1-dev", "cordova-plugin-media-capture": "1.2.1-dev", "cordova-plugin-geolocation": "2.1.1-dev", - "phonegap-plugin-barcodescanner": "5.0.1" + "phonegap-plugin-barcodescanner": "6.0.1" } } \ No newline at end of file diff --git a/platforms/android/assets/www/cordova_plugins.js b/platforms/android/assets/www/cordova_plugins.js index 6ea2704..af5f356 100644 --- a/platforms/android/assets/www/cordova_plugins.js +++ b/platforms/android/assets/www/cordova_plugins.js @@ -325,7 +325,7 @@ module.exports.metadata = "cordova-plugin-media": "2.2.1-dev", "cordova-plugin-media-capture": "1.2.1-dev", "cordova-plugin-geolocation": "2.1.1-dev", - "phonegap-plugin-barcodescanner": "5.0.1" + "phonegap-plugin-barcodescanner": "6.0.1" }; // BOTTOM OF METADATA }); \ No newline at end of file diff --git a/platforms/android/assets/www/js/home.js b/platforms/android/assets/www/js/home.js new file mode 100644 index 0000000..ccc6714 --- /dev/null +++ b/platforms/android/assets/www/js/home.js @@ -0,0 +1,355 @@ +/* global PositionError */ + +////////////////////////////////////////////// +// GPS and terrain stuff +////////////////////////////////////////////// + +/** + * Handles GPS and terrain data. + */ + +// Globals +lockGot = false; +terrainGot = false; +latitude = 0.0000; +longitude = 0.0000; +gpsaccuracy = 9999; +// End Globals + +var lastgpstime = 0; +var terraintypeid = 0; +var map = L.map('map'); +var tileurl = "http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg"; +map.setZoom(17); +map.dragging.disable(); +//map.touchZoom.disable(); +//map.doubleClickZoom.disable(); +//map.scrollWheelZoom.disable(); +map.keyboard.disable(); +$(".leaflet-control-zoom").css("visibility", "hidden"); +// Disable tap handler, if present. +//if (map.tap) { +// map.tap.disable(); +//} + +// Tile layer +map.addLayer(new L.tileLayer(tileurl, {minZoom: 17, maxZoom: 18})); +// Places layer +var placeLayer = L.geoJson( + {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null}}]}, + { + onEachFeature: onPlaceTap, + pointToLayer: function (feature, latlng) { + return L.circleMarker(latlng, { + radius: 14, + fillColor: "#ff7800", + color: "#000", + weight: 1, + opacity: 1, + fillOpacity: 0.6 + }); + } + }).addTo(map); + +var lc = L.control.locate({ + position: 'topleft', // set the location of the control + layer: undefined, // use your own layer for the location marker, creates a new layer by default + drawCircle: false, // controls whether a circle is drawn that shows the uncertainty about the location + follow: true, // follow the user's location + setView: true, // automatically sets the map view to the user's location, enabled if `follow` is true + keepCurrentZoomLevel: true, // keep the current map zoom level when displaying the user's location. (if `false`, use maxZoom) + stopFollowingOnDrag: false, // stop following when the map is dragged if `follow` is true (deprecated, see below) + remainActive: true, // if true locate control remains active on click even if the user's location is in view. + markerClass: L.circleMarker, // L.circleMarker or L.marker + circleStyle: {}, // change the style of the circle around the user's location + markerStyle: {}, + followCircleStyle: {}, // set difference for the style of the circle around the user's location while following + followMarkerStyle: {}, + icon: 'fa fa-map-marker', // class for icon, fa-location-arrow or fa-map-marker + iconLoading: 'fa fa-spinner fa-pulse', // class for loading icon + iconElementTag: 'span', // tag for the icon element, span or i + circlePadding: [0, 0], // padding around accuracy circle, value is passed to setBounds + metric: true, // use metric or imperial units + onLocationError: function (err) { + }, // define an error callback function + onLocationOutsideMapBounds: function (context) { // called when outside map boundaries + }, + showPopup: false, // display a popup when the user click on the inner marker + strings: { + title: ".", // title of the locate control + metersUnit: "meters", // string for metric units + feetUnit: "feet", // string for imperial units + popup: "You are within {distance} {unit} from this point", // text to appear if user clicks on circle + outsideMapBoundsMsg: "You seem located outside the boundaries of the map" // default message for onLocationOutsideMapBounds + }, + locateOptions: {} // define location options e.g enableHighAccuracy: true or maxZoom: 10 +}).addTo(map); +lc.start(); +function mapPos(lat, lon) { + lockGot = true; + hideLoading(); + loadPlaces(latitude, longitude); + //map.setView(new L.LatLng(lat, lon), 16, {animate: true}); + //map.panTo(new L.LatLng(lat, lon)); + //map.invalidateSize(); + //redraw('.leaflet-map-pane'); +// $('.leaflet-map-plane').css('height', '90%'); +// setTimeout(function () { +// $('#map').css('width', '100%'); +// $('#map').css('height', '100%'); +// }, 100); +} + +function onPlaceTap(feature, layer) { + layer.on('click', function (e) { + openPlace(feature); + }); +} + +function loadPlaces(lat, long) { + $.getJSON( + "http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1", + function (data) { + if (data.type === 'FeatureCollection') { + placeLayer.clearLayers(); + data.features.forEach(function (item) { + item.properties.popupContent = "" + item.properties.name + ""; + placeLayer.addData(item); + }); + } + }); +} + +function openPlace(feature) { + $('#main-content').load("screens/place.html", null, function () { + loadPlace(feature); + $('#overlay-main').css('display', 'block'); + }); +} + +/** + * Hide the loading overlay if everything is loaded, otherwise do nothing + */ +function hideLoading() { + if (lockGot && terrainGot && gpsaccuracy < 30 && $('#loading').css('display') !== 'none') { + $('#loading').fadeOut('slow', function () { + $('#loading').css('display', 'none'); + }); + } +} + +var updatePosition = function (position) { + latitude = position.coords.latitude; + longitude = position.coords.longitude; + lastgpstime = position.timestamp; + gpsaccuracy = position.coords.accuracy; + if (gpsaccuracy > 30) { + $('#no-lock').css('display', 'block'); + } else { + $('#no-lock').css('display', 'none'); + } + mapPos(latitude, longitude); +}; +var updateTerrain = function (position) { + latitude = position.coords.latitude; + longitude = position.coords.longitude; + lastgpstime = position.timestamp; + gpsaccuracy = position.coords.accuracy; + var rasterurl = "http://earth.apis.netsyms.net/terrain.php?format=json&lat=" + + latitude + "&long=" + longitude; + $.get(rasterurl, function (data) { + if (data.status === 'OK') { + terraintypeid = data.typeid; + terraintypename = data.typename; + $('#terrain-image').attr('src', 'assets/terrain/' + terraintypeid + '.png'); + terrainGot = true; + hideLoading(); + } + }, "json").fail(function (err) { + $('#terrain-image').attr('src', 'assets/terrain/0.png'); + }); +}; +function pingServer() { + if (lockGot && gpsaccuracy < 30) { + $.get(mkApiUrl('ping') + "?user=" + username + "&lat=" + latitude + "&long=" + longitude); + } +} +; +function onError(error) { + $('#loading-error').text("Check your device's network and location settings, and ensure a clear view of the sky."); +} + +function popGPS() { + navigator.notification.alert("Latitude: " + latitude + + "\nLongitude: " + longitude + + "\nAccuracy: " + gpsaccuracy + + "\nTerrain: " + terraintypename + " (" + terraintypeid + ")", + null, + "GPS Information", + "Close"); +} +$('#terrain-image').click(function () { + popGPS(); +}); +// Initial GPS position and stuff +navigator.geolocation.getCurrentPosition(updateTerrain, onError, {timeout: 10000, enableHighAccuracy: true}); +// Update position +setInterval(function () { + navigator.geolocation.getCurrentPosition(updatePosition, onError, {timeout: 10000, enableHighAccuracy: true}); +}, 1000); +// Update position + terrain +setInterval(function () { + navigator.geolocation.getCurrentPosition(updateTerrain, onError, {timeout: 10000, enableHighAccuracy: true}); + loadPlaces(latitude, longitude); +}, 1000 * 20); +// Ping the server with coordinates +setInterval(pingServer, 5000); +// Show error if it's taking too long +setTimeout(function () { + onError(); +}, 15 * 1000); + + +////////////////////////////////////////////// +// Profile, stats, and chat stuff +////////////////////////////////////////////// + + +/* + * Handles general server communication. + */ + +/** + * Syncs the user's stats with the server and calls refreshStats(). + */ +function syncStats() { + $.getJSON(mkApiUrl('getstats'), { + user: username + }, function (data) { + if (data.status === 'OK') { + maxenergy = data.stats.maxenergy; + energy = data.stats.energy; + level = data.stats.level; + refreshStats(); + } + }); +} + +/** + * Display the current stats on the home screen. + */ +function refreshStats() { + energypercent = (energy * 1.0 / maxenergy * 1.0) * 100.0; + $('#energybar').css('width', String(energypercent) + '%'); +} + +function getChat() { + if (lockGot) { + $.getJSON(mkApiUrl('chat', 'cs'), { + lat: latitude, + long: longitude + }, function (data) { + data = sortResults(data, 'time', true); + var content = ""; + data.forEach(function (msg) { + content += "" + msg.username + " " + msg.message + "
"; + }); + $('#chatmsgs').html(content); + }); + } +} + + +syncStats(); +setInterval(function () { + syncStats(); +}, 10 * 1000); +setInterval(function () { + getChat(); +}, 2000); +// Send chat messages +$("#chatsendform").submit(function (event) { + message = $('#chatbox-input').val(); + if (message !== '') { + $.post(mkApiUrl('chat', 'cs'), { + user: username, + lat: latitude, + long: longitude, + msg: message + }, function (data) { + if (data.status === 'OK') { + $('#chatbox-input').val(""); + $("#chatmsgs").animate({scrollTop: $('#chatmsgs').prop("scrollHeight")}, 1000); + } + }, "json"); + } + event.preventDefault(); + return false; +}); +function toggleChat() { + if ($('#chatmsgs').css('display') === 'none') { + openChat(); + } else { + closeChat(); + } +} + +function closeChat() { + $('#chatmsgs').css('display', 'none'); + $('#chatbox').css('height', 'auto'); +} + +function openChat() { + $('#chatbox').css('height', '50%'); + $('#chatmsgs').css('display', 'block'); + $("#chatmsgs").animate({scrollTop: $('#chatmsgs').prop("scrollHeight")}, 1000); +} + +function openProfile(user) { + user = typeof user !== 'undefined' ? user : username; + $('#main-content').load("screens/profile.html", null, function (x) { + $('#overlay-main').css('display', 'block'); + loadProfile(user); + }); +} + +function openRules() { + openmodal('rules', '#rules-modal'); +} + +function openMenu(topage) { + topage = typeof topage !== 'undefined' ? topage : ""; + $('#main-content').load("screens/menu.html", null, function (x) { + $('#overlay-main').css('display', 'block'); + if (topage !== '') { + $('#' + topage + '-tab').tab('show'); + } + }); +} + + + +////////////////////////////////////////////// +// Other things +////////////////////////////////////////////// + +function closeMain() { + $('#overlay-main').slideDown(100, function () { + $('#overlay-main').css('display', 'none'); + $('#main-content').html(""); + }); +} + +// Handle back button to close things +document.addEventListener("backbutton", function (event) { + if ($('#overlay-main').css('display') !== 'none') { + closeMain(); + } else if ($('#chatmsgs').css('display') !== 'none') { + toggleChat(); + } +}, false); +// Show the rules +if (localStorage.getItem("seenrules") !== 'yes') { + openRules(); + localStorage.setItem("seenrules", 'yes'); +} \ No newline at end of file diff --git a/platforms/android/assets/www/js/location.js b/platforms/android/assets/www/js/location.js index f05c7f9..9cdb810 100644 --- a/platforms/android/assets/www/js/location.js +++ b/platforms/android/assets/www/js/location.js @@ -14,8 +14,10 @@ terrainGot = false; latitude = 0.0000; longitude = 0.0000; gpsaccuracy = 9999; +requiredaccuracy = 40; // End Globals +var fetchplacecounter = 0; var lastgpstime = 0; var terraintypeid = 0; var map = L.map('map'); @@ -36,13 +38,14 @@ $(".leaflet-control-zoom").css("visibility", "hidden"); map.addLayer(new L.tileLayer(tileurl, {minZoom: 17, maxZoom: 18})); // Places layer var placeLayer = L.geoJson( - {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null}}]}, + {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null, 'gameinfo': {'teamid': "0"}}}]}, { onEachFeature: onPlaceTap, pointToLayer: function (feature, latlng) { + var teamcolor = "#" + getTeamColorFromId(feature.properties.gameinfo.teamid); return L.circleMarker(latlng, { radius: 14, - fillColor: "#ff7800", + fillColor: teamcolor, color: "#000", weight: 1, opacity: 1, @@ -85,10 +88,19 @@ var lc = L.control.locate({ locateOptions: {} // define location options e.g enableHighAccuracy: true or maxZoom: 10 }).addTo(map); lc.start(); + + function mapPos(lat, lon) { lockGot = true; hideLoading(); - loadPlaces(latitude, longitude); + // Don't update places every time + if (fetchplacecounter === 0) { + loadPlaces(latitude, longitude); + } + fetchplacecounter++; + if (fetchplacecounter > 10) { + fetchplacecounter = 0; + } //map.setView(new L.LatLng(lat, lon), 16, {animate: true}); //map.panTo(new L.LatLng(lat, lon)); //map.invalidateSize(); @@ -107,17 +119,23 @@ function onPlaceTap(feature, layer) { } function loadPlaces(lat, long) { - $.getJSON( - "http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1", - function (data) { - if (data.type === 'FeatureCollection') { - placeLayer.clearLayers(); - data.features.forEach(function (item) { - item.properties.popupContent = "" + item.properties.name + ""; - placeLayer.addData(item); - }); + var url = mkApiUrl('places', 'gs') + "?lat=" + lat + "&long=" + long + "&radius=.25&names=1"; + try { + $.getJSON( + url, + function (data) { + if (data.type === 'FeatureCollection') { + placeLayer.clearLayers(); + data.features.forEach(function (item) { + item.properties.popupContent = "" + item.properties.name + ""; + placeLayer.addData(item); + }); + } } - }); + ); + } catch (ex) { + serverProblemsDialog(); + } } function openPlace(feature) { @@ -131,7 +149,7 @@ function openPlace(feature) { * Hide the loading overlay if everything is loaded, otherwise do nothing */ function hideLoading() { - if (lockGot && terrainGot && gpsaccuracy < 30 && $('#loading').css('display') !== 'none') { + if (lockGot && terrainGot && gpsaccuracy < requiredaccuracy && $('#loading').css('display') !== 'none') { $('#loading').fadeOut('slow', function () { $('#loading').css('display', 'none'); }); @@ -143,7 +161,7 @@ var updatePosition = function (position) { longitude = position.coords.longitude; lastgpstime = position.timestamp; gpsaccuracy = position.coords.accuracy; - if (gpsaccuracy > 30) { + if (gpsaccuracy > requiredaccuracy) { $('#no-lock').css('display', 'block'); } else { $('#no-lock').css('display', 'none'); @@ -170,7 +188,7 @@ var updateTerrain = function (position) { }); }; function pingServer() { - if (lockGot && gpsaccuracy < 30) { + if (lockGot && gpsaccuracy < requiredaccuracy) { $.get(mkApiUrl('ping') + "?user=" + username + "&lat=" + latitude + "&long=" + longitude); } } diff --git a/platforms/android/assets/www/js/main.js b/platforms/android/assets/www/js/main.js index 1e13190..9d3857a 100644 --- a/platforms/android/assets/www/js/main.js +++ b/platforms/android/assets/www/js/main.js @@ -21,6 +21,10 @@ function onDeviceReady() { } } +function serverProblemsDialog() { + openscreen("servererror"); +} + function mkApiUrl(action, server) { server = typeof server !== 'undefined' ? server : "gs"; return "http://" + server + ".terranquest.net/" + action + ".php"; @@ -111,6 +115,50 @@ function closeMain() { }); } +function getTeamInfoFromId(id) { + var team_string = "None"; + var team_color = "FFFFFF"; + switch (id) { + case "1": + team_string = "Water"; + team_color = "00BFFF"; + break; + case "2": + team_string = "Fire"; + team_color = "FF4000"; + break; + case "3": + team_string = "Earth"; + team_color = "D1A000"; + break; + case "4": + team_string = "Wind"; + team_color = "96FFFF"; + break; + case "5": + team_string = "Light"; + team_color = "FFFF96"; + break; + case "6": + team_string = "Dark"; + team_color = "ABABAB"; + break; + default: + team_string = "None"; + team_color = "FFFFFF"; + break; + } + return {'name': team_string, 'color': team_color}; +} + +function getTeamNameFromId(id) { + return getTeamInfoFromId(id)['name']; +} + +function getTeamColorFromId(id) { + return getTeamInfoFromId(id)['color']; +} + // Handle back button to close things document.addEventListener("backbutton", function (event) { if ($('#overlay-main').css('display') !== 'none') { diff --git a/platforms/android/assets/www/screens/intro.html b/platforms/android/assets/www/screens/intro.html index 86c30f6..faa20fc 100644 --- a/platforms/android/assets/www/screens/intro.html +++ b/platforms/android/assets/www/screens/intro.html @@ -6,34 +6,38 @@ + - \ No newline at end of file diff --git a/platforms/android/assets/www/screens/inventory.html b/platforms/android/assets/www/screens/inventory.html index 753bc71..abaf430 100644 --- a/platforms/android/assets/www/screens/inventory.html +++ b/platforms/android/assets/www/screens/inventory.html @@ -1,10 +1,39 @@
+
+ Loading... +
\ No newline at end of file diff --git a/platforms/android/assets/www/screens/place.html b/platforms/android/assets/www/screens/place.html index 5c993a1..7853717 100644 --- a/platforms/android/assets/www/screens/place.html +++ b/platforms/android/assets/www/screens/place.html @@ -1,9 +1,13 @@
+
\ No newline at end of file diff --git a/platforms/android/assets/www/screens/profile.html b/platforms/android/assets/www/screens/profile.html index b7e6a70..bf5f477 100644 --- a/platforms/android/assets/www/screens/profile.html +++ b/platforms/android/assets/www/screens/profile.html @@ -5,8 +5,10 @@
Loading...
-
+
+
+
\ No newline at end of file diff --git a/platforms/android/platform_www/cordova_plugins.js b/platforms/android/platform_www/cordova_plugins.js index 6ea2704..af5f356 100644 --- a/platforms/android/platform_www/cordova_plugins.js +++ b/platforms/android/platform_www/cordova_plugins.js @@ -325,7 +325,7 @@ module.exports.metadata = "cordova-plugin-media": "2.2.1-dev", "cordova-plugin-media-capture": "1.2.1-dev", "cordova-plugin-geolocation": "2.1.1-dev", - "phonegap-plugin-barcodescanner": "5.0.1" + "phonegap-plugin-barcodescanner": "6.0.1" }; // BOTTOM OF METADATA }); \ No newline at end of file diff --git a/platforms/android/res/xml/config.xml b/platforms/android/res/xml/config.xml index 5804569..e89921f 100644 --- a/platforms/android/res/xml/config.xml +++ b/platforms/android/res/xml/config.xml @@ -1,5 +1,5 @@ - + diff --git a/platforms/browser/browser.json b/platforms/browser/browser.json index 53f926e..37bb068 100644 --- a/platforms/browser/browser.json +++ b/platforms/browser/browser.json @@ -458,6 +458,6 @@ "cordova-plugin-media": "2.2.1-dev", "cordova-plugin-media-capture": "1.2.1-dev", "cordova-plugin-geolocation": "2.1.1-dev", - "phonegap-plugin-barcodescanner": "5.0.1" + "phonegap-plugin-barcodescanner": "6.0.1" } } \ No newline at end of file diff --git a/platforms/browser/config.xml b/platforms/browser/config.xml index f90e409..c797fa0 100644 --- a/platforms/browser/config.xml +++ b/platforms/browser/config.xml @@ -1,5 +1,5 @@ - + diff --git a/platforms/browser/platform_www/cordova_plugins.js b/platforms/browser/platform_www/cordova_plugins.js index 12c5902..9abfd5f 100644 --- a/platforms/browser/platform_www/cordova_plugins.js +++ b/platforms/browser/platform_www/cordova_plugins.js @@ -392,7 +392,7 @@ module.exports.metadata = "cordova-plugin-media": "2.2.1-dev", "cordova-plugin-media-capture": "1.2.1-dev", "cordova-plugin-geolocation": "2.1.1-dev", - "phonegap-plugin-barcodescanner": "5.0.1" + "phonegap-plugin-barcodescanner": "6.0.1" } // BOTTOM OF METADATA }); \ No newline at end of file diff --git a/platforms/browser/www/config.xml b/platforms/browser/www/config.xml index f90e409..c797fa0 100644 --- a/platforms/browser/www/config.xml +++ b/platforms/browser/www/config.xml @@ -1,5 +1,5 @@ - + diff --git a/platforms/browser/www/cordova_plugins.js b/platforms/browser/www/cordova_plugins.js index 12c5902..9abfd5f 100644 --- a/platforms/browser/www/cordova_plugins.js +++ b/platforms/browser/www/cordova_plugins.js @@ -392,7 +392,7 @@ module.exports.metadata = "cordova-plugin-media": "2.2.1-dev", "cordova-plugin-media-capture": "1.2.1-dev", "cordova-plugin-geolocation": "2.1.1-dev", - "phonegap-plugin-barcodescanner": "5.0.1" + "phonegap-plugin-barcodescanner": "6.0.1" } // BOTTOM OF METADATA }); \ No newline at end of file diff --git a/platforms/browser/www/js/home.js b/platforms/browser/www/js/home.js new file mode 100644 index 0000000..ccc6714 --- /dev/null +++ b/platforms/browser/www/js/home.js @@ -0,0 +1,355 @@ +/* global PositionError */ + +////////////////////////////////////////////// +// GPS and terrain stuff +////////////////////////////////////////////// + +/** + * Handles GPS and terrain data. + */ + +// Globals +lockGot = false; +terrainGot = false; +latitude = 0.0000; +longitude = 0.0000; +gpsaccuracy = 9999; +// End Globals + +var lastgpstime = 0; +var terraintypeid = 0; +var map = L.map('map'); +var tileurl = "http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg"; +map.setZoom(17); +map.dragging.disable(); +//map.touchZoom.disable(); +//map.doubleClickZoom.disable(); +//map.scrollWheelZoom.disable(); +map.keyboard.disable(); +$(".leaflet-control-zoom").css("visibility", "hidden"); +// Disable tap handler, if present. +//if (map.tap) { +// map.tap.disable(); +//} + +// Tile layer +map.addLayer(new L.tileLayer(tileurl, {minZoom: 17, maxZoom: 18})); +// Places layer +var placeLayer = L.geoJson( + {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null}}]}, + { + onEachFeature: onPlaceTap, + pointToLayer: function (feature, latlng) { + return L.circleMarker(latlng, { + radius: 14, + fillColor: "#ff7800", + color: "#000", + weight: 1, + opacity: 1, + fillOpacity: 0.6 + }); + } + }).addTo(map); + +var lc = L.control.locate({ + position: 'topleft', // set the location of the control + layer: undefined, // use your own layer for the location marker, creates a new layer by default + drawCircle: false, // controls whether a circle is drawn that shows the uncertainty about the location + follow: true, // follow the user's location + setView: true, // automatically sets the map view to the user's location, enabled if `follow` is true + keepCurrentZoomLevel: true, // keep the current map zoom level when displaying the user's location. (if `false`, use maxZoom) + stopFollowingOnDrag: false, // stop following when the map is dragged if `follow` is true (deprecated, see below) + remainActive: true, // if true locate control remains active on click even if the user's location is in view. + markerClass: L.circleMarker, // L.circleMarker or L.marker + circleStyle: {}, // change the style of the circle around the user's location + markerStyle: {}, + followCircleStyle: {}, // set difference for the style of the circle around the user's location while following + followMarkerStyle: {}, + icon: 'fa fa-map-marker', // class for icon, fa-location-arrow or fa-map-marker + iconLoading: 'fa fa-spinner fa-pulse', // class for loading icon + iconElementTag: 'span', // tag for the icon element, span or i + circlePadding: [0, 0], // padding around accuracy circle, value is passed to setBounds + metric: true, // use metric or imperial units + onLocationError: function (err) { + }, // define an error callback function + onLocationOutsideMapBounds: function (context) { // called when outside map boundaries + }, + showPopup: false, // display a popup when the user click on the inner marker + strings: { + title: ".", // title of the locate control + metersUnit: "meters", // string for metric units + feetUnit: "feet", // string for imperial units + popup: "You are within {distance} {unit} from this point", // text to appear if user clicks on circle + outsideMapBoundsMsg: "You seem located outside the boundaries of the map" // default message for onLocationOutsideMapBounds + }, + locateOptions: {} // define location options e.g enableHighAccuracy: true or maxZoom: 10 +}).addTo(map); +lc.start(); +function mapPos(lat, lon) { + lockGot = true; + hideLoading(); + loadPlaces(latitude, longitude); + //map.setView(new L.LatLng(lat, lon), 16, {animate: true}); + //map.panTo(new L.LatLng(lat, lon)); + //map.invalidateSize(); + //redraw('.leaflet-map-pane'); +// $('.leaflet-map-plane').css('height', '90%'); +// setTimeout(function () { +// $('#map').css('width', '100%'); +// $('#map').css('height', '100%'); +// }, 100); +} + +function onPlaceTap(feature, layer) { + layer.on('click', function (e) { + openPlace(feature); + }); +} + +function loadPlaces(lat, long) { + $.getJSON( + "http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1", + function (data) { + if (data.type === 'FeatureCollection') { + placeLayer.clearLayers(); + data.features.forEach(function (item) { + item.properties.popupContent = "" + item.properties.name + ""; + placeLayer.addData(item); + }); + } + }); +} + +function openPlace(feature) { + $('#main-content').load("screens/place.html", null, function () { + loadPlace(feature); + $('#overlay-main').css('display', 'block'); + }); +} + +/** + * Hide the loading overlay if everything is loaded, otherwise do nothing + */ +function hideLoading() { + if (lockGot && terrainGot && gpsaccuracy < 30 && $('#loading').css('display') !== 'none') { + $('#loading').fadeOut('slow', function () { + $('#loading').css('display', 'none'); + }); + } +} + +var updatePosition = function (position) { + latitude = position.coords.latitude; + longitude = position.coords.longitude; + lastgpstime = position.timestamp; + gpsaccuracy = position.coords.accuracy; + if (gpsaccuracy > 30) { + $('#no-lock').css('display', 'block'); + } else { + $('#no-lock').css('display', 'none'); + } + mapPos(latitude, longitude); +}; +var updateTerrain = function (position) { + latitude = position.coords.latitude; + longitude = position.coords.longitude; + lastgpstime = position.timestamp; + gpsaccuracy = position.coords.accuracy; + var rasterurl = "http://earth.apis.netsyms.net/terrain.php?format=json&lat=" + + latitude + "&long=" + longitude; + $.get(rasterurl, function (data) { + if (data.status === 'OK') { + terraintypeid = data.typeid; + terraintypename = data.typename; + $('#terrain-image').attr('src', 'assets/terrain/' + terraintypeid + '.png'); + terrainGot = true; + hideLoading(); + } + }, "json").fail(function (err) { + $('#terrain-image').attr('src', 'assets/terrain/0.png'); + }); +}; +function pingServer() { + if (lockGot && gpsaccuracy < 30) { + $.get(mkApiUrl('ping') + "?user=" + username + "&lat=" + latitude + "&long=" + longitude); + } +} +; +function onError(error) { + $('#loading-error').text("Check your device's network and location settings, and ensure a clear view of the sky."); +} + +function popGPS() { + navigator.notification.alert("Latitude: " + latitude + + "\nLongitude: " + longitude + + "\nAccuracy: " + gpsaccuracy + + "\nTerrain: " + terraintypename + " (" + terraintypeid + ")", + null, + "GPS Information", + "Close"); +} +$('#terrain-image').click(function () { + popGPS(); +}); +// Initial GPS position and stuff +navigator.geolocation.getCurrentPosition(updateTerrain, onError, {timeout: 10000, enableHighAccuracy: true}); +// Update position +setInterval(function () { + navigator.geolocation.getCurrentPosition(updatePosition, onError, {timeout: 10000, enableHighAccuracy: true}); +}, 1000); +// Update position + terrain +setInterval(function () { + navigator.geolocation.getCurrentPosition(updateTerrain, onError, {timeout: 10000, enableHighAccuracy: true}); + loadPlaces(latitude, longitude); +}, 1000 * 20); +// Ping the server with coordinates +setInterval(pingServer, 5000); +// Show error if it's taking too long +setTimeout(function () { + onError(); +}, 15 * 1000); + + +////////////////////////////////////////////// +// Profile, stats, and chat stuff +////////////////////////////////////////////// + + +/* + * Handles general server communication. + */ + +/** + * Syncs the user's stats with the server and calls refreshStats(). + */ +function syncStats() { + $.getJSON(mkApiUrl('getstats'), { + user: username + }, function (data) { + if (data.status === 'OK') { + maxenergy = data.stats.maxenergy; + energy = data.stats.energy; + level = data.stats.level; + refreshStats(); + } + }); +} + +/** + * Display the current stats on the home screen. + */ +function refreshStats() { + energypercent = (energy * 1.0 / maxenergy * 1.0) * 100.0; + $('#energybar').css('width', String(energypercent) + '%'); +} + +function getChat() { + if (lockGot) { + $.getJSON(mkApiUrl('chat', 'cs'), { + lat: latitude, + long: longitude + }, function (data) { + data = sortResults(data, 'time', true); + var content = ""; + data.forEach(function (msg) { + content += "" + msg.username + " " + msg.message + "
"; + }); + $('#chatmsgs').html(content); + }); + } +} + + +syncStats(); +setInterval(function () { + syncStats(); +}, 10 * 1000); +setInterval(function () { + getChat(); +}, 2000); +// Send chat messages +$("#chatsendform").submit(function (event) { + message = $('#chatbox-input').val(); + if (message !== '') { + $.post(mkApiUrl('chat', 'cs'), { + user: username, + lat: latitude, + long: longitude, + msg: message + }, function (data) { + if (data.status === 'OK') { + $('#chatbox-input').val(""); + $("#chatmsgs").animate({scrollTop: $('#chatmsgs').prop("scrollHeight")}, 1000); + } + }, "json"); + } + event.preventDefault(); + return false; +}); +function toggleChat() { + if ($('#chatmsgs').css('display') === 'none') { + openChat(); + } else { + closeChat(); + } +} + +function closeChat() { + $('#chatmsgs').css('display', 'none'); + $('#chatbox').css('height', 'auto'); +} + +function openChat() { + $('#chatbox').css('height', '50%'); + $('#chatmsgs').css('display', 'block'); + $("#chatmsgs").animate({scrollTop: $('#chatmsgs').prop("scrollHeight")}, 1000); +} + +function openProfile(user) { + user = typeof user !== 'undefined' ? user : username; + $('#main-content').load("screens/profile.html", null, function (x) { + $('#overlay-main').css('display', 'block'); + loadProfile(user); + }); +} + +function openRules() { + openmodal('rules', '#rules-modal'); +} + +function openMenu(topage) { + topage = typeof topage !== 'undefined' ? topage : ""; + $('#main-content').load("screens/menu.html", null, function (x) { + $('#overlay-main').css('display', 'block'); + if (topage !== '') { + $('#' + topage + '-tab').tab('show'); + } + }); +} + + + +////////////////////////////////////////////// +// Other things +////////////////////////////////////////////// + +function closeMain() { + $('#overlay-main').slideDown(100, function () { + $('#overlay-main').css('display', 'none'); + $('#main-content').html(""); + }); +} + +// Handle back button to close things +document.addEventListener("backbutton", function (event) { + if ($('#overlay-main').css('display') !== 'none') { + closeMain(); + } else if ($('#chatmsgs').css('display') !== 'none') { + toggleChat(); + } +}, false); +// Show the rules +if (localStorage.getItem("seenrules") !== 'yes') { + openRules(); + localStorage.setItem("seenrules", 'yes'); +} \ No newline at end of file diff --git a/platforms/browser/www/js/location.js b/platforms/browser/www/js/location.js index f05c7f9..9cdb810 100644 --- a/platforms/browser/www/js/location.js +++ b/platforms/browser/www/js/location.js @@ -14,8 +14,10 @@ terrainGot = false; latitude = 0.0000; longitude = 0.0000; gpsaccuracy = 9999; +requiredaccuracy = 40; // End Globals +var fetchplacecounter = 0; var lastgpstime = 0; var terraintypeid = 0; var map = L.map('map'); @@ -36,13 +38,14 @@ $(".leaflet-control-zoom").css("visibility", "hidden"); map.addLayer(new L.tileLayer(tileurl, {minZoom: 17, maxZoom: 18})); // Places layer var placeLayer = L.geoJson( - {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null}}]}, + {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null, 'gameinfo': {'teamid': "0"}}}]}, { onEachFeature: onPlaceTap, pointToLayer: function (feature, latlng) { + var teamcolor = "#" + getTeamColorFromId(feature.properties.gameinfo.teamid); return L.circleMarker(latlng, { radius: 14, - fillColor: "#ff7800", + fillColor: teamcolor, color: "#000", weight: 1, opacity: 1, @@ -85,10 +88,19 @@ var lc = L.control.locate({ locateOptions: {} // define location options e.g enableHighAccuracy: true or maxZoom: 10 }).addTo(map); lc.start(); + + function mapPos(lat, lon) { lockGot = true; hideLoading(); - loadPlaces(latitude, longitude); + // Don't update places every time + if (fetchplacecounter === 0) { + loadPlaces(latitude, longitude); + } + fetchplacecounter++; + if (fetchplacecounter > 10) { + fetchplacecounter = 0; + } //map.setView(new L.LatLng(lat, lon), 16, {animate: true}); //map.panTo(new L.LatLng(lat, lon)); //map.invalidateSize(); @@ -107,17 +119,23 @@ function onPlaceTap(feature, layer) { } function loadPlaces(lat, long) { - $.getJSON( - "http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1", - function (data) { - if (data.type === 'FeatureCollection') { - placeLayer.clearLayers(); - data.features.forEach(function (item) { - item.properties.popupContent = "" + item.properties.name + ""; - placeLayer.addData(item); - }); + var url = mkApiUrl('places', 'gs') + "?lat=" + lat + "&long=" + long + "&radius=.25&names=1"; + try { + $.getJSON( + url, + function (data) { + if (data.type === 'FeatureCollection') { + placeLayer.clearLayers(); + data.features.forEach(function (item) { + item.properties.popupContent = "" + item.properties.name + ""; + placeLayer.addData(item); + }); + } } - }); + ); + } catch (ex) { + serverProblemsDialog(); + } } function openPlace(feature) { @@ -131,7 +149,7 @@ function openPlace(feature) { * Hide the loading overlay if everything is loaded, otherwise do nothing */ function hideLoading() { - if (lockGot && terrainGot && gpsaccuracy < 30 && $('#loading').css('display') !== 'none') { + if (lockGot && terrainGot && gpsaccuracy < requiredaccuracy && $('#loading').css('display') !== 'none') { $('#loading').fadeOut('slow', function () { $('#loading').css('display', 'none'); }); @@ -143,7 +161,7 @@ var updatePosition = function (position) { longitude = position.coords.longitude; lastgpstime = position.timestamp; gpsaccuracy = position.coords.accuracy; - if (gpsaccuracy > 30) { + if (gpsaccuracy > requiredaccuracy) { $('#no-lock').css('display', 'block'); } else { $('#no-lock').css('display', 'none'); @@ -170,7 +188,7 @@ var updateTerrain = function (position) { }); }; function pingServer() { - if (lockGot && gpsaccuracy < 30) { + if (lockGot && gpsaccuracy < requiredaccuracy) { $.get(mkApiUrl('ping') + "?user=" + username + "&lat=" + latitude + "&long=" + longitude); } } diff --git a/platforms/browser/www/js/main.js b/platforms/browser/www/js/main.js index 1e13190..9d3857a 100644 --- a/platforms/browser/www/js/main.js +++ b/platforms/browser/www/js/main.js @@ -21,6 +21,10 @@ function onDeviceReady() { } } +function serverProblemsDialog() { + openscreen("servererror"); +} + function mkApiUrl(action, server) { server = typeof server !== 'undefined' ? server : "gs"; return "http://" + server + ".terranquest.net/" + action + ".php"; @@ -111,6 +115,50 @@ function closeMain() { }); } +function getTeamInfoFromId(id) { + var team_string = "None"; + var team_color = "FFFFFF"; + switch (id) { + case "1": + team_string = "Water"; + team_color = "00BFFF"; + break; + case "2": + team_string = "Fire"; + team_color = "FF4000"; + break; + case "3": + team_string = "Earth"; + team_color = "D1A000"; + break; + case "4": + team_string = "Wind"; + team_color = "96FFFF"; + break; + case "5": + team_string = "Light"; + team_color = "FFFF96"; + break; + case "6": + team_string = "Dark"; + team_color = "ABABAB"; + break; + default: + team_string = "None"; + team_color = "FFFFFF"; + break; + } + return {'name': team_string, 'color': team_color}; +} + +function getTeamNameFromId(id) { + return getTeamInfoFromId(id)['name']; +} + +function getTeamColorFromId(id) { + return getTeamInfoFromId(id)['color']; +} + // Handle back button to close things document.addEventListener("backbutton", function (event) { if ($('#overlay-main').css('display') !== 'none') { diff --git a/platforms/browser/www/screens/intro.html b/platforms/browser/www/screens/intro.html index 86c30f6..faa20fc 100644 --- a/platforms/browser/www/screens/intro.html +++ b/platforms/browser/www/screens/intro.html @@ -6,34 +6,38 @@
+ - \ No newline at end of file diff --git a/platforms/browser/www/screens/inventory.html b/platforms/browser/www/screens/inventory.html index 753bc71..abaf430 100644 --- a/platforms/browser/www/screens/inventory.html +++ b/platforms/browser/www/screens/inventory.html @@ -1,10 +1,39 @@
+
+ Loading... +
\ No newline at end of file diff --git a/platforms/browser/www/screens/place.html b/platforms/browser/www/screens/place.html index 5c993a1..7853717 100644 --- a/platforms/browser/www/screens/place.html +++ b/platforms/browser/www/screens/place.html @@ -1,9 +1,13 @@
+
\ No newline at end of file diff --git a/platforms/browser/www/screens/profile.html b/platforms/browser/www/screens/profile.html index b7e6a70..bf5f477 100644 --- a/platforms/browser/www/screens/profile.html +++ b/platforms/browser/www/screens/profile.html @@ -5,8 +5,10 @@
Loading...
-
+
+
+
\ No newline at end of file diff --git a/plugins/phonegap-plugin-barcodescanner/package.json b/plugins/phonegap-plugin-barcodescanner/package.json index 7f47c7d..e42593c 100644 --- a/plugins/phonegap-plugin-barcodescanner/package.json +++ b/plugins/phonegap-plugin-barcodescanner/package.json @@ -1,13 +1,12 @@ { "name": "phonegap-plugin-barcodescanner", - "version": "5.0.1", + "version": "6.0.1", "description": "You can use the BarcodeScanner plugin to scan different types of barcodes (using the device's camera) and get the metadata encoded in them for processing within your application.", "cordova": { "id": "phonegap-plugin-barcodescanner", "platforms": [ "ios", "android", - "windows8", "windows", "wp8", "blackberry10", @@ -23,7 +22,6 @@ "ecosystem:phonegap", "cordova-ios", "cordova-android", - "cordova-windows8", "cordova-windows", "cordova-wp8", "cordova-blackberry10", diff --git a/plugins/phonegap-plugin-barcodescanner/plugin.xml b/plugins/phonegap-plugin-barcodescanner/plugin.xml index 704089c..6459857 100644 --- a/plugins/phonegap-plugin-barcodescanner/plugin.xml +++ b/plugins/phonegap-plugin-barcodescanner/plugin.xml @@ -2,7 +2,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:rim="http://www.blackberry.com/ns/widgets" id="phonegap-plugin-barcodescanner" - version="5.0.1"> + version="6.0.1"> BarcodeScanner You can use the BarcodeScanner plugin to scan different types of barcodes (using the device's camera) and get the metadata encoded in them for processing within your application. diff --git a/plugins/phonegap-plugin-barcodescanner/src/windows/BarcodeScannerProxy.js b/plugins/phonegap-plugin-barcodescanner/src/windows/BarcodeScannerProxy.js index e1aff4e..b9b29ca 100644 --- a/plugins/phonegap-plugin-barcodescanner/src/windows/BarcodeScannerProxy.js +++ b/plugins/phonegap-plugin-barcodescanner/src/windows/BarcodeScannerProxy.js @@ -551,7 +551,7 @@ module.exports = { } function checkCancelled() { - if (BarcodeReader.scanCancelled) { + if (BarcodeReader.scanCancelled || BarcodeReader.suspended) { throw new Error('Canceled'); } } @@ -587,8 +587,12 @@ module.exports = { cancelled: !result }); }, function (error) { - destroyPreview(); + // Suppress null result (cancel) on suspending + if (BarcodeReader.suspended) { + return; + } + destroyPreview(); if (error.message == 'Canceled') { success({ cancelled: true @@ -622,20 +626,46 @@ function waitForScanEnd() { return BarcodeReader.scanPromise || WinJS.Promise.as(); } +function suspend(args) { + BarcodeReader.suspended = true; + if (args) { + args.setPromise(BarcodeReader.destroyPreview() + .then(waitForScanEnd, waitForScanEnd)); + } else { + BarcodeReader.destroyPreview(); + } +} + +function resume() { + BarcodeReader.suspended = false; + module.exports.scan(BarcodeReader.scanCallArgs.success, BarcodeReader.scanCallArgs.fail, BarcodeReader.scanCallArgs.args); +} + +function onVisibilityChanged() { + if (document.visibilityState === 'hidden' + && BarcodeReader.videoPreviewIsVisible && BarcodeReader.videoPreviewIsVisible() && BarcodeReader.destroyPreview) { + suspend(); + } else if (BarcodeReader.suspended) { + resume(); + } +} + +// Windows 8.1 projects +document.addEventListener('msvisibilitychange', onVisibilityChanged); +// Windows 10 projects +document.addEventListener('visibilitychange', onVisibilityChanged); + // About to be suspended app.addEventListener('checkpoint', function (args) { if (BarcodeReader.videoPreviewIsVisible && BarcodeReader.videoPreviewIsVisible() && BarcodeReader.destroyPreview) { - BarcodeReader.suspended = true; - args.setPromise(BarcodeReader.destroyPreview() - .then(waitForScanEnd, waitForScanEnd)); + suspend(args); } }); // Resuming from a user suspension Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", function () { if (BarcodeReader.suspended) { - BarcodeReader.suspended = false; - module.exports.scan(BarcodeReader.scanCallArgs.success, BarcodeReader.scanCallArgs.fail, BarcodeReader.scanCallArgs.args); + resume(); } }, false); diff --git a/res/splash.9.png b/res/splash.9.png index 1265052..c718dc5 100644 Binary files a/res/splash.9.png and b/res/splash.9.png differ diff --git a/www/js/home.js b/www/js/home.js new file mode 100644 index 0000000..ccc6714 --- /dev/null +++ b/www/js/home.js @@ -0,0 +1,355 @@ +/* global PositionError */ + +////////////////////////////////////////////// +// GPS and terrain stuff +////////////////////////////////////////////// + +/** + * Handles GPS and terrain data. + */ + +// Globals +lockGot = false; +terrainGot = false; +latitude = 0.0000; +longitude = 0.0000; +gpsaccuracy = 9999; +// End Globals + +var lastgpstime = 0; +var terraintypeid = 0; +var map = L.map('map'); +var tileurl = "http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg"; +map.setZoom(17); +map.dragging.disable(); +//map.touchZoom.disable(); +//map.doubleClickZoom.disable(); +//map.scrollWheelZoom.disable(); +map.keyboard.disable(); +$(".leaflet-control-zoom").css("visibility", "hidden"); +// Disable tap handler, if present. +//if (map.tap) { +// map.tap.disable(); +//} + +// Tile layer +map.addLayer(new L.tileLayer(tileurl, {minZoom: 17, maxZoom: 18})); +// Places layer +var placeLayer = L.geoJson( + {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null}}]}, + { + onEachFeature: onPlaceTap, + pointToLayer: function (feature, latlng) { + return L.circleMarker(latlng, { + radius: 14, + fillColor: "#ff7800", + color: "#000", + weight: 1, + opacity: 1, + fillOpacity: 0.6 + }); + } + }).addTo(map); + +var lc = L.control.locate({ + position: 'topleft', // set the location of the control + layer: undefined, // use your own layer for the location marker, creates a new layer by default + drawCircle: false, // controls whether a circle is drawn that shows the uncertainty about the location + follow: true, // follow the user's location + setView: true, // automatically sets the map view to the user's location, enabled if `follow` is true + keepCurrentZoomLevel: true, // keep the current map zoom level when displaying the user's location. (if `false`, use maxZoom) + stopFollowingOnDrag: false, // stop following when the map is dragged if `follow` is true (deprecated, see below) + remainActive: true, // if true locate control remains active on click even if the user's location is in view. + markerClass: L.circleMarker, // L.circleMarker or L.marker + circleStyle: {}, // change the style of the circle around the user's location + markerStyle: {}, + followCircleStyle: {}, // set difference for the style of the circle around the user's location while following + followMarkerStyle: {}, + icon: 'fa fa-map-marker', // class for icon, fa-location-arrow or fa-map-marker + iconLoading: 'fa fa-spinner fa-pulse', // class for loading icon + iconElementTag: 'span', // tag for the icon element, span or i + circlePadding: [0, 0], // padding around accuracy circle, value is passed to setBounds + metric: true, // use metric or imperial units + onLocationError: function (err) { + }, // define an error callback function + onLocationOutsideMapBounds: function (context) { // called when outside map boundaries + }, + showPopup: false, // display a popup when the user click on the inner marker + strings: { + title: ".", // title of the locate control + metersUnit: "meters", // string for metric units + feetUnit: "feet", // string for imperial units + popup: "You are within {distance} {unit} from this point", // text to appear if user clicks on circle + outsideMapBoundsMsg: "You seem located outside the boundaries of the map" // default message for onLocationOutsideMapBounds + }, + locateOptions: {} // define location options e.g enableHighAccuracy: true or maxZoom: 10 +}).addTo(map); +lc.start(); +function mapPos(lat, lon) { + lockGot = true; + hideLoading(); + loadPlaces(latitude, longitude); + //map.setView(new L.LatLng(lat, lon), 16, {animate: true}); + //map.panTo(new L.LatLng(lat, lon)); + //map.invalidateSize(); + //redraw('.leaflet-map-pane'); +// $('.leaflet-map-plane').css('height', '90%'); +// setTimeout(function () { +// $('#map').css('width', '100%'); +// $('#map').css('height', '100%'); +// }, 100); +} + +function onPlaceTap(feature, layer) { + layer.on('click', function (e) { + openPlace(feature); + }); +} + +function loadPlaces(lat, long) { + $.getJSON( + "http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1", + function (data) { + if (data.type === 'FeatureCollection') { + placeLayer.clearLayers(); + data.features.forEach(function (item) { + item.properties.popupContent = "" + item.properties.name + ""; + placeLayer.addData(item); + }); + } + }); +} + +function openPlace(feature) { + $('#main-content').load("screens/place.html", null, function () { + loadPlace(feature); + $('#overlay-main').css('display', 'block'); + }); +} + +/** + * Hide the loading overlay if everything is loaded, otherwise do nothing + */ +function hideLoading() { + if (lockGot && terrainGot && gpsaccuracy < 30 && $('#loading').css('display') !== 'none') { + $('#loading').fadeOut('slow', function () { + $('#loading').css('display', 'none'); + }); + } +} + +var updatePosition = function (position) { + latitude = position.coords.latitude; + longitude = position.coords.longitude; + lastgpstime = position.timestamp; + gpsaccuracy = position.coords.accuracy; + if (gpsaccuracy > 30) { + $('#no-lock').css('display', 'block'); + } else { + $('#no-lock').css('display', 'none'); + } + mapPos(latitude, longitude); +}; +var updateTerrain = function (position) { + latitude = position.coords.latitude; + longitude = position.coords.longitude; + lastgpstime = position.timestamp; + gpsaccuracy = position.coords.accuracy; + var rasterurl = "http://earth.apis.netsyms.net/terrain.php?format=json&lat=" + + latitude + "&long=" + longitude; + $.get(rasterurl, function (data) { + if (data.status === 'OK') { + terraintypeid = data.typeid; + terraintypename = data.typename; + $('#terrain-image').attr('src', 'assets/terrain/' + terraintypeid + '.png'); + terrainGot = true; + hideLoading(); + } + }, "json").fail(function (err) { + $('#terrain-image').attr('src', 'assets/terrain/0.png'); + }); +}; +function pingServer() { + if (lockGot && gpsaccuracy < 30) { + $.get(mkApiUrl('ping') + "?user=" + username + "&lat=" + latitude + "&long=" + longitude); + } +} +; +function onError(error) { + $('#loading-error').text("Check your device's network and location settings, and ensure a clear view of the sky."); +} + +function popGPS() { + navigator.notification.alert("Latitude: " + latitude + + "\nLongitude: " + longitude + + "\nAccuracy: " + gpsaccuracy + + "\nTerrain: " + terraintypename + " (" + terraintypeid + ")", + null, + "GPS Information", + "Close"); +} +$('#terrain-image').click(function () { + popGPS(); +}); +// Initial GPS position and stuff +navigator.geolocation.getCurrentPosition(updateTerrain, onError, {timeout: 10000, enableHighAccuracy: true}); +// Update position +setInterval(function () { + navigator.geolocation.getCurrentPosition(updatePosition, onError, {timeout: 10000, enableHighAccuracy: true}); +}, 1000); +// Update position + terrain +setInterval(function () { + navigator.geolocation.getCurrentPosition(updateTerrain, onError, {timeout: 10000, enableHighAccuracy: true}); + loadPlaces(latitude, longitude); +}, 1000 * 20); +// Ping the server with coordinates +setInterval(pingServer, 5000); +// Show error if it's taking too long +setTimeout(function () { + onError(); +}, 15 * 1000); + + +////////////////////////////////////////////// +// Profile, stats, and chat stuff +////////////////////////////////////////////// + + +/* + * Handles general server communication. + */ + +/** + * Syncs the user's stats with the server and calls refreshStats(). + */ +function syncStats() { + $.getJSON(mkApiUrl('getstats'), { + user: username + }, function (data) { + if (data.status === 'OK') { + maxenergy = data.stats.maxenergy; + energy = data.stats.energy; + level = data.stats.level; + refreshStats(); + } + }); +} + +/** + * Display the current stats on the home screen. + */ +function refreshStats() { + energypercent = (energy * 1.0 / maxenergy * 1.0) * 100.0; + $('#energybar').css('width', String(energypercent) + '%'); +} + +function getChat() { + if (lockGot) { + $.getJSON(mkApiUrl('chat', 'cs'), { + lat: latitude, + long: longitude + }, function (data) { + data = sortResults(data, 'time', true); + var content = ""; + data.forEach(function (msg) { + content += "" + msg.username + " " + msg.message + "
"; + }); + $('#chatmsgs').html(content); + }); + } +} + + +syncStats(); +setInterval(function () { + syncStats(); +}, 10 * 1000); +setInterval(function () { + getChat(); +}, 2000); +// Send chat messages +$("#chatsendform").submit(function (event) { + message = $('#chatbox-input').val(); + if (message !== '') { + $.post(mkApiUrl('chat', 'cs'), { + user: username, + lat: latitude, + long: longitude, + msg: message + }, function (data) { + if (data.status === 'OK') { + $('#chatbox-input').val(""); + $("#chatmsgs").animate({scrollTop: $('#chatmsgs').prop("scrollHeight")}, 1000); + } + }, "json"); + } + event.preventDefault(); + return false; +}); +function toggleChat() { + if ($('#chatmsgs').css('display') === 'none') { + openChat(); + } else { + closeChat(); + } +} + +function closeChat() { + $('#chatmsgs').css('display', 'none'); + $('#chatbox').css('height', 'auto'); +} + +function openChat() { + $('#chatbox').css('height', '50%'); + $('#chatmsgs').css('display', 'block'); + $("#chatmsgs").animate({scrollTop: $('#chatmsgs').prop("scrollHeight")}, 1000); +} + +function openProfile(user) { + user = typeof user !== 'undefined' ? user : username; + $('#main-content').load("screens/profile.html", null, function (x) { + $('#overlay-main').css('display', 'block'); + loadProfile(user); + }); +} + +function openRules() { + openmodal('rules', '#rules-modal'); +} + +function openMenu(topage) { + topage = typeof topage !== 'undefined' ? topage : ""; + $('#main-content').load("screens/menu.html", null, function (x) { + $('#overlay-main').css('display', 'block'); + if (topage !== '') { + $('#' + topage + '-tab').tab('show'); + } + }); +} + + + +////////////////////////////////////////////// +// Other things +////////////////////////////////////////////// + +function closeMain() { + $('#overlay-main').slideDown(100, function () { + $('#overlay-main').css('display', 'none'); + $('#main-content').html(""); + }); +} + +// Handle back button to close things +document.addEventListener("backbutton", function (event) { + if ($('#overlay-main').css('display') !== 'none') { + closeMain(); + } else if ($('#chatmsgs').css('display') !== 'none') { + toggleChat(); + } +}, false); +// Show the rules +if (localStorage.getItem("seenrules") !== 'yes') { + openRules(); + localStorage.setItem("seenrules", 'yes'); +} \ No newline at end of file diff --git a/www/js/location.js b/www/js/location.js index f05c7f9..9cdb810 100644 --- a/www/js/location.js +++ b/www/js/location.js @@ -14,8 +14,10 @@ terrainGot = false; latitude = 0.0000; longitude = 0.0000; gpsaccuracy = 9999; +requiredaccuracy = 40; // End Globals +var fetchplacecounter = 0; var lastgpstime = 0; var terraintypeid = 0; var map = L.map('map'); @@ -36,13 +38,14 @@ $(".leaflet-control-zoom").css("visibility", "hidden"); map.addLayer(new L.tileLayer(tileurl, {minZoom: 17, maxZoom: 18})); // Places layer var placeLayer = L.geoJson( - {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null}}]}, + {"name": "Places", "type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"osm_id": -1, "name": null, 'gameinfo': {'teamid': "0"}}}]}, { onEachFeature: onPlaceTap, pointToLayer: function (feature, latlng) { + var teamcolor = "#" + getTeamColorFromId(feature.properties.gameinfo.teamid); return L.circleMarker(latlng, { radius: 14, - fillColor: "#ff7800", + fillColor: teamcolor, color: "#000", weight: 1, opacity: 1, @@ -85,10 +88,19 @@ var lc = L.control.locate({ locateOptions: {} // define location options e.g enableHighAccuracy: true or maxZoom: 10 }).addTo(map); lc.start(); + + function mapPos(lat, lon) { lockGot = true; hideLoading(); - loadPlaces(latitude, longitude); + // Don't update places every time + if (fetchplacecounter === 0) { + loadPlaces(latitude, longitude); + } + fetchplacecounter++; + if (fetchplacecounter > 10) { + fetchplacecounter = 0; + } //map.setView(new L.LatLng(lat, lon), 16, {animate: true}); //map.panTo(new L.LatLng(lat, lon)); //map.invalidateSize(); @@ -107,17 +119,23 @@ function onPlaceTap(feature, layer) { } function loadPlaces(lat, long) { - $.getJSON( - "http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1", - function (data) { - if (data.type === 'FeatureCollection') { - placeLayer.clearLayers(); - data.features.forEach(function (item) { - item.properties.popupContent = "" + item.properties.name + ""; - placeLayer.addData(item); - }); + var url = mkApiUrl('places', 'gs') + "?lat=" + lat + "&long=" + long + "&radius=.25&names=1"; + try { + $.getJSON( + url, + function (data) { + if (data.type === 'FeatureCollection') { + placeLayer.clearLayers(); + data.features.forEach(function (item) { + item.properties.popupContent = "" + item.properties.name + ""; + placeLayer.addData(item); + }); + } } - }); + ); + } catch (ex) { + serverProblemsDialog(); + } } function openPlace(feature) { @@ -131,7 +149,7 @@ function openPlace(feature) { * Hide the loading overlay if everything is loaded, otherwise do nothing */ function hideLoading() { - if (lockGot && terrainGot && gpsaccuracy < 30 && $('#loading').css('display') !== 'none') { + if (lockGot && terrainGot && gpsaccuracy < requiredaccuracy && $('#loading').css('display') !== 'none') { $('#loading').fadeOut('slow', function () { $('#loading').css('display', 'none'); }); @@ -143,7 +161,7 @@ var updatePosition = function (position) { longitude = position.coords.longitude; lastgpstime = position.timestamp; gpsaccuracy = position.coords.accuracy; - if (gpsaccuracy > 30) { + if (gpsaccuracy > requiredaccuracy) { $('#no-lock').css('display', 'block'); } else { $('#no-lock').css('display', 'none'); @@ -170,7 +188,7 @@ var updateTerrain = function (position) { }); }; function pingServer() { - if (lockGot && gpsaccuracy < 30) { + if (lockGot && gpsaccuracy < requiredaccuracy) { $.get(mkApiUrl('ping') + "?user=" + username + "&lat=" + latitude + "&long=" + longitude); } } diff --git a/www/js/main.js b/www/js/main.js index 1e13190..9d3857a 100644 --- a/www/js/main.js +++ b/www/js/main.js @@ -21,6 +21,10 @@ function onDeviceReady() { } } +function serverProblemsDialog() { + openscreen("servererror"); +} + function mkApiUrl(action, server) { server = typeof server !== 'undefined' ? server : "gs"; return "http://" + server + ".terranquest.net/" + action + ".php"; @@ -111,6 +115,50 @@ function closeMain() { }); } +function getTeamInfoFromId(id) { + var team_string = "None"; + var team_color = "FFFFFF"; + switch (id) { + case "1": + team_string = "Water"; + team_color = "00BFFF"; + break; + case "2": + team_string = "Fire"; + team_color = "FF4000"; + break; + case "3": + team_string = "Earth"; + team_color = "D1A000"; + break; + case "4": + team_string = "Wind"; + team_color = "96FFFF"; + break; + case "5": + team_string = "Light"; + team_color = "FFFF96"; + break; + case "6": + team_string = "Dark"; + team_color = "ABABAB"; + break; + default: + team_string = "None"; + team_color = "FFFFFF"; + break; + } + return {'name': team_string, 'color': team_color}; +} + +function getTeamNameFromId(id) { + return getTeamInfoFromId(id)['name']; +} + +function getTeamColorFromId(id) { + return getTeamInfoFromId(id)['color']; +} + // Handle back button to close things document.addEventListener("backbutton", function (event) { if ($('#overlay-main').css('display') !== 'none') { diff --git a/www/screens/intro.html b/www/screens/intro.html index 86c30f6..faa20fc 100644 --- a/www/screens/intro.html +++ b/www/screens/intro.html @@ -6,34 +6,38 @@
+ - \ No newline at end of file diff --git a/www/screens/inventory.html b/www/screens/inventory.html index 753bc71..abaf430 100644 --- a/www/screens/inventory.html +++ b/www/screens/inventory.html @@ -1,10 +1,39 @@
+
+ Loading... +
\ No newline at end of file diff --git a/www/screens/place.html b/www/screens/place.html index 5c993a1..7853717 100644 --- a/www/screens/place.html +++ b/www/screens/place.html @@ -1,9 +1,13 @@
+
\ No newline at end of file diff --git a/www/screens/profile.html b/www/screens/profile.html index e13a063..bf5f477 100644 --- a/www/screens/profile.html +++ b/www/screens/profile.html @@ -1,61 +1,63 @@ -
-
-

-
Badges
-
- Loading... -
-
- -
- +
+
+

+
Badges
+
+ Loading... +
+
+
+ +
+
+
\ No newline at end of file diff --git a/www/screens/servererror.html b/www/screens/servererror.html new file mode 100644 index 0000000..d2be1db --- /dev/null +++ b/www/screens/servererror.html @@ -0,0 +1,20 @@ +
+ +

+ We are experiencing server problems. Try again later. +
+ +
+ (sorry) +

+
+ \ No newline at end of file