All kinds of stuff happened, I can't even. Everything seems to work OK though.
This commit is contained in:
parent
cfbfe0c227
commit
ba26006bac
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<widget xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0" id="com.netsyms.terranquest.TerranQuest" version="1.1.2">
|
||||
<widget xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0" id="com.netsyms.terranquest.TerranQuest" version="1.2">
|
||||
<name>TerranQuest</name>
|
||||
<description>
|
||||
Augmented Reality fantasy game
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<manifest android:hardwareAccelerated="true" android:versionCode="10102" android:versionName="1.1.2" package="com.netsyms.terranquest.TerranQuest" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest android:hardwareAccelerated="true" android:versionCode="10200" android:versionName="1.2" package="com.netsyms.terranquest.TerranQuest" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name" android:supportsRtl="true">
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
@ -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
|
||||
});
|
355
platforms/android/assets/www/js/home.js
Normal file
355
platforms/android/assets/www/js/home.js
Normal file
@ -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 = "<span class='marker-popup-text' onclick='openplace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
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 += "<span class='chat-username' onclick='openProfile(\"" + msg.username + "\");'>" + msg.username + "</span> " + msg.message + "<br />";
|
||||
});
|
||||
$('#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');
|
||||
}
|
@ -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();
|
||||
// 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) {
|
||||
var url = mkApiUrl('places', 'gs') + "?lat=" + lat + "&long=" + long + "&radius=.25&names=1";
|
||||
try {
|
||||
$.getJSON(
|
||||
"http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1",
|
||||
url,
|
||||
function (data) {
|
||||
if (data.type === 'FeatureCollection') {
|
||||
placeLayer.clearLayers();
|
||||
data.features.forEach(function (item) {
|
||||
item.properties.popupContent = "<span class='marker-popup-text' onclick='openplace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
item.properties.popupContent = "<span class='marker-popup-text' onclick='openPlace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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') {
|
||||
|
@ -6,25 +6,28 @@
|
||||
<h4 class="modal-title" id="intro-box-header">Welcome to TerranQuest!</h4>
|
||||
</div>
|
||||
<div class="modal-body" id="intro-box-body-1">
|
||||
<p>TerranQuest is a video game that makes you go outside. Step outdoors and discover a fantasy world overlapping our own.</p>
|
||||
<p>It's dangerous to adventure alone, read this:</p>
|
||||
<ol class="list-group">
|
||||
<li class="list-group-item">There are different types of magic in the world.</li>
|
||||
<li class="list-group-item">Some types of magic are stronger in certain types of terrain.</li>
|
||||
<li class="list-group-item">Weather can also affect the flow of magic through the land.</li>
|
||||
<li class="list-group-item">There are strong points of magic near important landmarks.</li>
|
||||
<li class="list-group-item">These points of magic can be transmuted into different types of magic.</li>
|
||||
</ol>
|
||||
<p>There are seven types of magic in this world. Six elements of nature: water, fire, earth, wind, light, and dark. There is also a seventh element: life. Life is the source of all magical power.</p>
|
||||
<p>Long ago, the wielders of the six elements were united as one. The magics were harnessed with responsibility and respect.</p>
|
||||
<p>Then disagreement and discord arose. Some become jealous of others. A great war followed, destroying much life. As a result of this bloodshed, the magic wilted and died.</p>
|
||||
<p>Over time, the magic sunk deep into the Earth, living on only in dreams. Science forgot magic, and ancient knowledge was lost.</p>
|
||||
<p>Now, however, the world has come full circle. Science has become magic in a different form. The new sorcerers, scientists, harness the powers of the elements with their modern tools. They know little, but the whispers of ancient power has influenced their actions.</p>
|
||||
<p>The old is become new. Magic is real, it only seems different. Control the elements and bring peace to the Earth. Channel the powers of magic through your smartphone or tablet. It is up to you to give your technology a true purpose. There are those who do not want unity, who thrive in chaos. They are all the more reason to go out and fight.</p>
|
||||
<p><em>Will you join the quest?</em></p>
|
||||
</div>
|
||||
<div class="modal-body" id="intro-box-body-2" style='display: none;'>
|
||||
<p>Many years ago, there was a disagreement between the
|
||||
different magical clans. A secret war, hidden from
|
||||
non-magical peoples, has festered just under the surface.
|
||||
Whichever clan controls all the magical points, controls the world.</p>
|
||||
<p>You have chosen well.</p>
|
||||
<p>There is some knowledge you must have now. You must discover the rest of the secrets on your own.</p>
|
||||
<ol class="list-group">
|
||||
<li class="list-group-item">Some types of magic are stronger in certain types of terrain.</li>
|
||||
<li class="list-group-item">Weather can also affect the flow of magic.</li>
|
||||
<li class="list-group-item">There are strong points of magic near important landmarks.</li>
|
||||
<li class="list-group-item">These points of magic can be controlled and enhanced by the different elements to achieve good and evil.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" onclick="gotointropage2();" class="btn btn-default" id="gotopage2-btn"><i class="fa fa-arrow-right"></i> Next</button>
|
||||
<button type="button" data-dismiss="modal" class="btn btn-default" style="display: none;" id="close-intro"><i class="fa fa-check"></i> OK</button>
|
||||
<button type="button" onclick="navigator.app.exitApp();" class="btn btn-danger" id="lolnope-btn"><i class="fa fa-arrow-right"></i> I will not</button>
|
||||
<button type="button" onclick="gotointropage2();" class="btn btn-success" id="gotopage2-btn"><i class="fa fa-arrow-right"></i> I will</button>
|
||||
<button type="button" data-dismiss="modal" class="btn btn-default" style="display: none;" id="close-intro"><i class="fa fa-check"></i> I am ready!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -34,6 +37,7 @@ function gotointropage2() {
|
||||
$('#intro-box-body-1').css('display', 'none');
|
||||
$('#intro-box-body-2').css('display', '');
|
||||
$('#gotopage2-btn').css('display', 'none');
|
||||
$('#lolnope-btn').css('display', 'none');
|
||||
$('#close-intro').css('display', '');
|
||||
}
|
||||
</script>
|
@ -1,10 +1,39 @@
|
||||
<div class="scrollable-box">
|
||||
<div class="list-group" id="inventory-list">
|
||||
<div class="list-group-item">
|
||||
<i class="fa fa-spinner fa-pulse fa-fw"></i> Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function loadinventory() {
|
||||
|
||||
function getitemhtmlfromjson(item) {
|
||||
return "\
|
||||
<div class='list-group-item inventory-item' id='item-" + item.itemuuid + "'>\
|
||||
<h4 class='itemname'>" + item.itemname + "</h4>\
|
||||
<p class='itemdesc'>" + item.itemdesc + "</p>\
|
||||
<span class='itemid' style='display: none;'>" + item.itemid + "</span>\
|
||||
<span class='itemclassid' style='display: none;'>" + item.classid + "</span>\
|
||||
<span class='itemjson' style='display: none;'>" + item.itemjson + "</span>\
|
||||
</div>";
|
||||
}
|
||||
|
||||
function loadinventory() {
|
||||
$.getJSON(mkApiUrl('inventory'), {
|
||||
user: username
|
||||
}, function (data) {
|
||||
var content = "";
|
||||
if (data.status == 'OK') {
|
||||
items = data.items;
|
||||
items.forEach(function (item) {
|
||||
content += getitemhtmlfromjson(item);
|
||||
});
|
||||
} else {
|
||||
content = "<div class='list-group-item'>An error occurred.</div>";
|
||||
}
|
||||
$('#inventory-list').html(content);
|
||||
});
|
||||
}
|
||||
|
||||
loadinventory();
|
||||
</script>
|
@ -1,9 +1,13 @@
|
||||
<div class="scrollable-box">
|
||||
<div class="h4" id="place-name" style="max-width: 90%;"></div>
|
||||
<div id="team-label"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function loadPlace(feature) {
|
||||
$("#place-name").text(feature.properties.name);
|
||||
|
||||
$("#team-label").text(getTeamNameFromId(feature.properties.gameinfo.teamid));
|
||||
$("#team-label").css("color", "#" + getTeamColorFromId(feature.properties.gameinfo.teamid));
|
||||
}
|
||||
</script>
|
@ -5,9 +5,11 @@
|
||||
<div id="loading-badges">
|
||||
<i class="fa fa-spinner fa-pulse"></i> Loading...
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row" id="badges">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function popBadge(name, desc) {
|
||||
navigator.notification.alert(desc, null, name, "Close");
|
||||
|
20
platforms/android/assets/www/screens/servererror.html
Normal file
20
platforms/android/assets/www/screens/servererror.html
Normal file
@ -0,0 +1,20 @@
|
||||
<div style="position: absolute; width: 100%; height: 100%; top: 0; left: 0; background-color: #324150; z-index: 9999;">
|
||||
<img src="assets/logonobg.svg" alt="" style="display: block; position: absolute; max-width: 90%; top: 0; left: 0; right: 0; bottom: 25%; margin: auto; max-height: 20%;" />
|
||||
<p style="font-family: sans-serif; color: white; position: absolute; max-width: 90%; left: 0; right: 0; bottom: 30%; margin: auto; text-align: center;">
|
||||
We are experiencing server problems. Try again later.
|
||||
<br />
|
||||
<i class="fa fa-exclamation-triangle fa-3x"></i>
|
||||
<br />
|
||||
(sorry)
|
||||
<div style="background: url(assets/mountains-simple.svg) repeat-x; background-size: auto 100%; height: 20%; position: absolute; bottom: 0; width: 100%;"></div>
|
||||
</div>
|
||||
<script>
|
||||
/*
|
||||
* Stop all scheduled network activity
|
||||
*/
|
||||
var id = window.setTimeout(function () {}, 0);
|
||||
|
||||
while (id--) {
|
||||
window.clearTimeout(id);
|
||||
}
|
||||
</script>
|
@ -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
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<widget id="com.netsyms.terranquest.TerranQuest" version="1.1.2" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0">
|
||||
<widget id="com.netsyms.terranquest.TerranQuest" version="1.2" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0">
|
||||
<preference name="loglevel" value="DEBUG" />
|
||||
<feature name="Whitelist">
|
||||
<param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin" />
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<widget id="com.netsyms.terranquest.TerranQuest" version="1.1.2" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0">
|
||||
<widget id="com.netsyms.terranquest.TerranQuest" version="1.2" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0">
|
||||
<feature name="Device">
|
||||
<param name="browser-package" value="Device" />
|
||||
</feature>
|
||||
|
@ -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
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<widget id="com.netsyms.terranquest.TerranQuest" version="1.1.2" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0">
|
||||
<widget id="com.netsyms.terranquest.TerranQuest" version="1.2" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:gap="http://phonegap.com/ns/1.0">
|
||||
<feature name="Device">
|
||||
<param name="browser-package" value="Device" />
|
||||
</feature>
|
||||
|
2
platforms/browser/www/cordova_plugins.js
vendored
2
platforms/browser/www/cordova_plugins.js
vendored
@ -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
|
||||
});
|
355
platforms/browser/www/js/home.js
Normal file
355
platforms/browser/www/js/home.js
Normal file
@ -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 = "<span class='marker-popup-text' onclick='openplace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
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 += "<span class='chat-username' onclick='openProfile(\"" + msg.username + "\");'>" + msg.username + "</span> " + msg.message + "<br />";
|
||||
});
|
||||
$('#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');
|
||||
}
|
@ -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();
|
||||
// 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) {
|
||||
var url = mkApiUrl('places', 'gs') + "?lat=" + lat + "&long=" + long + "&radius=.25&names=1";
|
||||
try {
|
||||
$.getJSON(
|
||||
"http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1",
|
||||
url,
|
||||
function (data) {
|
||||
if (data.type === 'FeatureCollection') {
|
||||
placeLayer.clearLayers();
|
||||
data.features.forEach(function (item) {
|
||||
item.properties.popupContent = "<span class='marker-popup-text' onclick='openplace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
item.properties.popupContent = "<span class='marker-popup-text' onclick='openPlace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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') {
|
||||
|
@ -6,25 +6,28 @@
|
||||
<h4 class="modal-title" id="intro-box-header">Welcome to TerranQuest!</h4>
|
||||
</div>
|
||||
<div class="modal-body" id="intro-box-body-1">
|
||||
<p>TerranQuest is a video game that makes you go outside. Step outdoors and discover a fantasy world overlapping our own.</p>
|
||||
<p>It's dangerous to adventure alone, read this:</p>
|
||||
<ol class="list-group">
|
||||
<li class="list-group-item">There are different types of magic in the world.</li>
|
||||
<li class="list-group-item">Some types of magic are stronger in certain types of terrain.</li>
|
||||
<li class="list-group-item">Weather can also affect the flow of magic through the land.</li>
|
||||
<li class="list-group-item">There are strong points of magic near important landmarks.</li>
|
||||
<li class="list-group-item">These points of magic can be transmuted into different types of magic.</li>
|
||||
</ol>
|
||||
<p>There are seven types of magic in this world. Six elements of nature: water, fire, earth, wind, light, and dark. There is also a seventh element: life. Life is the source of all magical power.</p>
|
||||
<p>Long ago, the wielders of the six elements were united as one. The magics were harnessed with responsibility and respect.</p>
|
||||
<p>Then disagreement and discord arose. Some become jealous of others. A great war followed, destroying much life. As a result of this bloodshed, the magic wilted and died.</p>
|
||||
<p>Over time, the magic sunk deep into the Earth, living on only in dreams. Science forgot magic, and ancient knowledge was lost.</p>
|
||||
<p>Now, however, the world has come full circle. Science has become magic in a different form. The new sorcerers, scientists, harness the powers of the elements with their modern tools. They know little, but the whispers of ancient power has influenced their actions.</p>
|
||||
<p>The old is become new. Magic is real, it only seems different. Control the elements and bring peace to the Earth. Channel the powers of magic through your smartphone or tablet. It is up to you to give your technology a true purpose. There are those who do not want unity, who thrive in chaos. They are all the more reason to go out and fight.</p>
|
||||
<p><em>Will you join the quest?</em></p>
|
||||
</div>
|
||||
<div class="modal-body" id="intro-box-body-2" style='display: none;'>
|
||||
<p>Many years ago, there was a disagreement between the
|
||||
different magical clans. A secret war, hidden from
|
||||
non-magical peoples, has festered just under the surface.
|
||||
Whichever clan controls all the magical points, controls the world.</p>
|
||||
<p>You have chosen well.</p>
|
||||
<p>There is some knowledge you must have now. You must discover the rest of the secrets on your own.</p>
|
||||
<ol class="list-group">
|
||||
<li class="list-group-item">Some types of magic are stronger in certain types of terrain.</li>
|
||||
<li class="list-group-item">Weather can also affect the flow of magic.</li>
|
||||
<li class="list-group-item">There are strong points of magic near important landmarks.</li>
|
||||
<li class="list-group-item">These points of magic can be controlled and enhanced by the different elements to achieve good and evil.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" onclick="gotointropage2();" class="btn btn-default" id="gotopage2-btn"><i class="fa fa-arrow-right"></i> Next</button>
|
||||
<button type="button" data-dismiss="modal" class="btn btn-default" style="display: none;" id="close-intro"><i class="fa fa-check"></i> OK</button>
|
||||
<button type="button" onclick="navigator.app.exitApp();" class="btn btn-danger" id="lolnope-btn"><i class="fa fa-arrow-right"></i> I will not</button>
|
||||
<button type="button" onclick="gotointropage2();" class="btn btn-success" id="gotopage2-btn"><i class="fa fa-arrow-right"></i> I will</button>
|
||||
<button type="button" data-dismiss="modal" class="btn btn-default" style="display: none;" id="close-intro"><i class="fa fa-check"></i> I am ready!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -34,6 +37,7 @@ function gotointropage2() {
|
||||
$('#intro-box-body-1').css('display', 'none');
|
||||
$('#intro-box-body-2').css('display', '');
|
||||
$('#gotopage2-btn').css('display', 'none');
|
||||
$('#lolnope-btn').css('display', 'none');
|
||||
$('#close-intro').css('display', '');
|
||||
}
|
||||
</script>
|
@ -1,10 +1,39 @@
|
||||
<div class="scrollable-box">
|
||||
<div class="list-group" id="inventory-list">
|
||||
<div class="list-group-item">
|
||||
<i class="fa fa-spinner fa-pulse fa-fw"></i> Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function loadinventory() {
|
||||
|
||||
function getitemhtmlfromjson(item) {
|
||||
return "\
|
||||
<div class='list-group-item inventory-item' id='item-" + item.itemuuid + "'>\
|
||||
<h4 class='itemname'>" + item.itemname + "</h4>\
|
||||
<p class='itemdesc'>" + item.itemdesc + "</p>\
|
||||
<span class='itemid' style='display: none;'>" + item.itemid + "</span>\
|
||||
<span class='itemclassid' style='display: none;'>" + item.classid + "</span>\
|
||||
<span class='itemjson' style='display: none;'>" + item.itemjson + "</span>\
|
||||
</div>";
|
||||
}
|
||||
|
||||
function loadinventory() {
|
||||
$.getJSON(mkApiUrl('inventory'), {
|
||||
user: username
|
||||
}, function (data) {
|
||||
var content = "";
|
||||
if (data.status == 'OK') {
|
||||
items = data.items;
|
||||
items.forEach(function (item) {
|
||||
content += getitemhtmlfromjson(item);
|
||||
});
|
||||
} else {
|
||||
content = "<div class='list-group-item'>An error occurred.</div>";
|
||||
}
|
||||
$('#inventory-list').html(content);
|
||||
});
|
||||
}
|
||||
|
||||
loadinventory();
|
||||
</script>
|
@ -1,9 +1,13 @@
|
||||
<div class="scrollable-box">
|
||||
<div class="h4" id="place-name" style="max-width: 90%;"></div>
|
||||
<div id="team-label"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function loadPlace(feature) {
|
||||
$("#place-name").text(feature.properties.name);
|
||||
|
||||
$("#team-label").text(getTeamNameFromId(feature.properties.gameinfo.teamid));
|
||||
$("#team-label").css("color", "#" + getTeamColorFromId(feature.properties.gameinfo.teamid));
|
||||
}
|
||||
</script>
|
@ -5,9 +5,11 @@
|
||||
<div id="loading-badges">
|
||||
<i class="fa fa-spinner fa-pulse"></i> Loading...
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row" id="badges">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function popBadge(name, desc) {
|
||||
navigator.notification.alert(desc, null, name, "Close");
|
||||
|
20
platforms/browser/www/screens/servererror.html
Normal file
20
platforms/browser/www/screens/servererror.html
Normal file
@ -0,0 +1,20 @@
|
||||
<div style="position: absolute; width: 100%; height: 100%; top: 0; left: 0; background-color: #324150; z-index: 9999;">
|
||||
<img src="assets/logonobg.svg" alt="" style="display: block; position: absolute; max-width: 90%; top: 0; left: 0; right: 0; bottom: 25%; margin: auto; max-height: 20%;" />
|
||||
<p style="font-family: sans-serif; color: white; position: absolute; max-width: 90%; left: 0; right: 0; bottom: 30%; margin: auto; text-align: center;">
|
||||
We are experiencing server problems. Try again later.
|
||||
<br />
|
||||
<i class="fa fa-exclamation-triangle fa-3x"></i>
|
||||
<br />
|
||||
(sorry)
|
||||
<div style="background: url(assets/mountains-simple.svg) repeat-x; background-size: auto 100%; height: 20%; position: absolute; bottom: 0; width: 100%;"></div>
|
||||
</div>
|
||||
<script>
|
||||
/*
|
||||
* Stop all scheduled network activity
|
||||
*/
|
||||
var id = window.setTimeout(function () {}, 0);
|
||||
|
||||
while (id--) {
|
||||
window.clearTimeout(id);
|
||||
}
|
||||
</script>
|
@ -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",
|
||||
|
@ -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">
|
||||
|
||||
<name>BarcodeScanner</name>
|
||||
<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.</description>
|
||||
|
@ -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);
|
||||
|
||||
|
BIN
res/splash.9.png
BIN
res/splash.9.png
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 65 KiB |
355
www/js/home.js
Normal file
355
www/js/home.js
Normal file
@ -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 = "<span class='marker-popup-text' onclick='openplace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
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 += "<span class='chat-username' onclick='openProfile(\"" + msg.username + "\");'>" + msg.username + "</span> " + msg.message + "<br />";
|
||||
});
|
||||
$('#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');
|
||||
}
|
@ -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();
|
||||
// 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) {
|
||||
var url = mkApiUrl('places', 'gs') + "?lat=" + lat + "&long=" + long + "&radius=.25&names=1";
|
||||
try {
|
||||
$.getJSON(
|
||||
"http://earth.apis.netsyms.net/places.php?format=geojson&lat=" + lat + "&long=" + long + "&radius=.25&names=1",
|
||||
url,
|
||||
function (data) {
|
||||
if (data.type === 'FeatureCollection') {
|
||||
placeLayer.clearLayers();
|
||||
data.features.forEach(function (item) {
|
||||
item.properties.popupContent = "<span class='marker-popup-text' onclick='openplace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
item.properties.popupContent = "<span class='marker-popup-text' onclick='openPlace(" + item.properties.osm_id + ")'>" + item.properties.name + "</span>";
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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') {
|
||||
|
@ -6,25 +6,28 @@
|
||||
<h4 class="modal-title" id="intro-box-header">Welcome to TerranQuest!</h4>
|
||||
</div>
|
||||
<div class="modal-body" id="intro-box-body-1">
|
||||
<p>TerranQuest is a video game that makes you go outside. Step outdoors and discover a fantasy world overlapping our own.</p>
|
||||
<p>It's dangerous to adventure alone, read this:</p>
|
||||
<ol class="list-group">
|
||||
<li class="list-group-item">There are different types of magic in the world.</li>
|
||||
<li class="list-group-item">Some types of magic are stronger in certain types of terrain.</li>
|
||||
<li class="list-group-item">Weather can also affect the flow of magic through the land.</li>
|
||||
<li class="list-group-item">There are strong points of magic near important landmarks.</li>
|
||||
<li class="list-group-item">These points of magic can be transmuted into different types of magic.</li>
|
||||
</ol>
|
||||
<p>There are seven types of magic in this world. Six elements of nature: water, fire, earth, wind, light, and dark. There is also a seventh element: life. Life is the source of all magical power.</p>
|
||||
<p>Long ago, the wielders of the six elements were united as one. The magics were harnessed with responsibility and respect.</p>
|
||||
<p>Then disagreement and discord arose. Some become jealous of others. A great war followed, destroying much life. As a result of this bloodshed, the magic wilted and died.</p>
|
||||
<p>Over time, the magic sunk deep into the Earth, living on only in dreams. Science forgot magic, and ancient knowledge was lost.</p>
|
||||
<p>Now, however, the world has come full circle. Science has become magic in a different form. The new sorcerers, scientists, harness the powers of the elements with their modern tools. They know little, but the whispers of ancient power has influenced their actions.</p>
|
||||
<p>The old is become new. Magic is real, it only seems different. Control the elements and bring peace to the Earth. Channel the powers of magic through your smartphone or tablet. It is up to you to give your technology a true purpose. There are those who do not want unity, who thrive in chaos. They are all the more reason to go out and fight.</p>
|
||||
<p><em>Will you join the quest?</em></p>
|
||||
</div>
|
||||
<div class="modal-body" id="intro-box-body-2" style='display: none;'>
|
||||
<p>Many years ago, there was a disagreement between the
|
||||
different magical clans. A secret war, hidden from
|
||||
non-magical peoples, has festered just under the surface.
|
||||
Whichever clan controls all the magical points, controls the world.</p>
|
||||
<p>You have chosen well.</p>
|
||||
<p>There is some knowledge you must have now. You must discover the rest of the secrets on your own.</p>
|
||||
<ol class="list-group">
|
||||
<li class="list-group-item">Some types of magic are stronger in certain types of terrain.</li>
|
||||
<li class="list-group-item">Weather can also affect the flow of magic.</li>
|
||||
<li class="list-group-item">There are strong points of magic near important landmarks.</li>
|
||||
<li class="list-group-item">These points of magic can be controlled and enhanced by the different elements to achieve good and evil.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" onclick="gotointropage2();" class="btn btn-default" id="gotopage2-btn"><i class="fa fa-arrow-right"></i> Next</button>
|
||||
<button type="button" data-dismiss="modal" class="btn btn-default" style="display: none;" id="close-intro"><i class="fa fa-check"></i> OK</button>
|
||||
<button type="button" onclick="navigator.app.exitApp();" class="btn btn-danger" id="lolnope-btn"><i class="fa fa-arrow-right"></i> I will not</button>
|
||||
<button type="button" onclick="gotointropage2();" class="btn btn-success" id="gotopage2-btn"><i class="fa fa-arrow-right"></i> I will</button>
|
||||
<button type="button" data-dismiss="modal" class="btn btn-default" style="display: none;" id="close-intro"><i class="fa fa-check"></i> I am ready!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -34,6 +37,7 @@ function gotointropage2() {
|
||||
$('#intro-box-body-1').css('display', 'none');
|
||||
$('#intro-box-body-2').css('display', '');
|
||||
$('#gotopage2-btn').css('display', 'none');
|
||||
$('#lolnope-btn').css('display', 'none');
|
||||
$('#close-intro').css('display', '');
|
||||
}
|
||||
</script>
|
@ -1,10 +1,39 @@
|
||||
<div class="scrollable-box">
|
||||
<div class="list-group" id="inventory-list">
|
||||
<div class="list-group-item">
|
||||
<i class="fa fa-spinner fa-pulse fa-fw"></i> Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function loadinventory() {
|
||||
|
||||
function getitemhtmlfromjson(item) {
|
||||
return "\
|
||||
<div class='list-group-item inventory-item' id='item-" + item.itemuuid + "'>\
|
||||
<h4 class='itemname'>" + item.itemname + "</h4>\
|
||||
<p class='itemdesc'>" + item.itemdesc + "</p>\
|
||||
<span class='itemid' style='display: none;'>" + item.itemid + "</span>\
|
||||
<span class='itemclassid' style='display: none;'>" + item.classid + "</span>\
|
||||
<span class='itemjson' style='display: none;'>" + item.itemjson + "</span>\
|
||||
</div>";
|
||||
}
|
||||
|
||||
function loadinventory() {
|
||||
$.getJSON(mkApiUrl('inventory'), {
|
||||
user: username
|
||||
}, function (data) {
|
||||
var content = "";
|
||||
if (data.status == 'OK') {
|
||||
items = data.items;
|
||||
items.forEach(function (item) {
|
||||
content += getitemhtmlfromjson(item);
|
||||
});
|
||||
} else {
|
||||
content = "<div class='list-group-item'>An error occurred.</div>";
|
||||
}
|
||||
$('#inventory-list').html(content);
|
||||
});
|
||||
}
|
||||
|
||||
loadinventory();
|
||||
</script>
|
@ -1,9 +1,13 @@
|
||||
<div class="scrollable-box">
|
||||
<div class="h4" id="place-name" style="max-width: 90%;"></div>
|
||||
<div id="team-label"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function loadPlace(feature) {
|
||||
$("#place-name").text(feature.properties.name);
|
||||
|
||||
$("#team-label").text(getTeamNameFromId(feature.properties.gameinfo.teamid));
|
||||
$("#team-label").css("color", "#" + getTeamColorFromId(feature.properties.gameinfo.teamid));
|
||||
}
|
||||
</script>
|
@ -5,9 +5,11 @@
|
||||
<div id="loading-badges">
|
||||
<i class="fa fa-spinner fa-pulse"></i> Loading...
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row" id="badges">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function popBadge(name, desc) {
|
||||
navigator.notification.alert(desc, null, name, "Close");
|
||||
|
20
www/screens/servererror.html
Normal file
20
www/screens/servererror.html
Normal file
@ -0,0 +1,20 @@
|
||||
<div style="position: absolute; width: 100%; height: 100%; top: 0; left: 0; background-color: #324150; z-index: 9999;">
|
||||
<img src="assets/logonobg.svg" alt="" style="display: block; position: absolute; max-width: 90%; top: 0; left: 0; right: 0; bottom: 25%; margin: auto; max-height: 20%;" />
|
||||
<p style="font-family: sans-serif; color: white; position: absolute; max-width: 90%; left: 0; right: 0; bottom: 30%; margin: auto; text-align: center;">
|
||||
We are experiencing server problems. Try again later.
|
||||
<br />
|
||||
<i class="fa fa-exclamation-triangle fa-3x"></i>
|
||||
<br />
|
||||
(sorry)
|
||||
<div style="background: url(assets/mountains-simple.svg) repeat-x; background-size: auto 100%; height: 20%; position: absolute; bottom: 0; width: 100%;"></div>
|
||||
</div>
|
||||
<script>
|
||||
/*
|
||||
* Stop all scheduled network activity
|
||||
*/
|
||||
var id = window.setTimeout(function () {}, 0);
|
||||
|
||||
while (id--) {
|
||||
window.clearTimeout(id);
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user