Page MenuHomeCode

No OneTemporary

This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/Engines/Builder/Map/OctocubeBuilder.php b/Engines/Builder/Map/OctocubeBuilder.php
new file mode 100644
index 0000000..1cbb8d2
--- /dev/null
+++ b/Engines/Builder/Map/OctocubeBuilder.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Zed\Engines\Builder\Map;
+
+use Hypership\Geo\Octocube;
+use Hypership\Geo\Point3D;
+
+use GeoLocation;
+
+class OctocubeBuilder {
+
+ private Point3D $localLocation;
+
+ public function __construct (GeoLocation $location) {
+ $this->localLocation = Point3D::fromString($location->local);
+ }
+
+ private function getSector () : int {
+ return Octocube::getSectorFromPoint3D($this->localLocation);
+ }
+
+ /**
+ * Gets SQL RLIKE pattern for the specified sector
+ *
+ * @return string a SQL clause like "([0-9]+, -[0,9]+, [0,9]+)"
+ */
+ public function getRlikePattern() : string {
+ $sector = $this->getSector();
+
+ if ($sector == 0) {
+ return "(0, 0, 0)";
+ }
+
+ $vector = Octocube::getBaseVector($sector);
+
+ //x
+ if ($vector[0] == 1) {
+ $query = "([0-9]+, ";
+ } else {
+ $query = "(-[0-9]+, ";
+ }
+
+ //y
+ if ($vector[1] == 1) {
+ $query .= "[0-9]+, ";
+ } else {
+ $query .= "-[0-9]+, ";
+ }
+
+ //z
+ $query .= $this->localLocation->z . ")";
+
+ return $query;
+ }
+
+ static public function canBuildAt($location) : bool {
+ return $location->global == 'B00001002';
+ }
+
+}
diff --git a/Engines/Templates/Smarty/Plugins/modifier.sector.php b/Engines/Templates/Smarty/Plugins/modifier.sector.php
new file mode 100644
index 0000000..2b01819
--- /dev/null
+++ b/Engines/Templates/Smarty/Plugins/modifier.sector.php
@@ -0,0 +1,27 @@
+<?php
+declare(strict_types=1);
+
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifier
+ */
+
+use Hypership\Geo\Octocube;
+
+/**
+ * Smarty sector modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: sector<br>
+ * Purpose: prints the sector from a location
+ */
+function smarty_modifier_sector (GeoLocation $location) : string {
+ $xyz = explode(',', substr($location->local, 1, -1));
+ $x = (int)$xyz[0];
+ $y = (int)$xyz[1];
+ $z = (int)$xyz[2];
+
+ return (string)Octocube::getSector($x, $y, $z);
+}
diff --git a/composer.json b/composer.json
index b5b0d53..b7499c6 100644
--- a/composer.json
+++ b/composer.json
@@ -1,29 +1,30 @@
{
"name": "zed/zed",
"description": "Hypership and galaxy",
"type": "project",
"require": {
"smarty/smarty": "dev-master",
"keruald/globalfunctions": "^0.5.1",
- "keruald/omnitools": "^0.1.0"
+ "keruald/omnitools": "^0.1.0",
+ "hypership/geo": "^0.1.0"
},
"require-dev": {
"nasqueron/codestyle": "^0.0.1",
"phan/phan": "^5.3.1",
"squizlabs/php_codesniffer": "^3.6",
"phpunit/phpunit": "^9.5"
},
"autoload": {
"psr-4": {
"Zed\\Engines\\": "Engines",
"Zed\\Tests\\": "dev/tests"
}
},
"license": "BSD-2-Clause",
"authors": [
{
"name": "Sébastien Santoro",
"email": "dereckson@espace-win.org"
}
]
}
diff --git a/controllers/builder.php b/controllers/builder.php
index 94d9373..edc6b1c 100644
--- a/controllers/builder.php
+++ b/controllers/builder.php
@@ -1,135 +1,137 @@
<?php
/**
* Builder
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/gpl-2.0.php GPLv2
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
+use Zed\Engines\Builder\Map\OctocubeBuilder;
+
require_once('includes/content/zone.php');
//
// Helper methods
//
/**
* Determines if a specified location is buildable
*
* @param GeoLocation $location the location to check
* @param string if the location isn't buildable, a textual description of why.
* @return bool true if the location is buildable ; otherwise, false
*
* @todo create a build.xml document to set what's buildable, and by who
*/
function is_buildable ($location, &$error = '') {
//We currently allow build only in the hypership tower and core.
if (!$location->body->hypership) {
$error = "You can only invoke the HyperShip builder facilities inside the HyperShip.";
return false;
}
//if ($build_location->place->code == "001") {
// //Don't allow custom builds in the corridor (T?C?)
//}
if ($build_location->place->code == "003") {
message_die("Bays aren't buildable.");
return false;
}
return true;
}
//
// Determines mode and initializes resources
//
switch ($build_mode = $url[1]) {
case 'map':
- require_once('includes/geo/octocube.php');
-
$build_mode = 'map';
//Get zones at this floor
- if ($CurrentPerso->location->global == 'B00001002') {
- $point = GeoPoint3D::fromString($CurrentPerso->location->local);
- $sector = GeoOctocube::getSectorFromPoint3D($point);
- $pattern = GeoOctocube::getRlikePatternFromSector($sector, $point->z);
- $zones = ContentZone::search($CurrentPerso->location->global, $pattern, true);
- } else {
+ if (!OctocubeBuilder::canBuildAt($CurrentPerso->location)) {
message_die(GENERAL_ERROR, "Can't map this area.", "Builder :: Map");
}
+ $builder = new OctocubeBuilder($CurrentPerso->location);
+ $zones = ContentZone::search(
+ $CurrentPerso->location->global,
+ $builder->getRlikePattern(),
+ true
+ );
+
//Template
define('DOJO', true);
$smarty->assign('zones', $zones);
$template = "builder_map.tpl";
break;
case '':
case 'hotglue':
//Temporary initialization code, to allow some build during the Zed alphatest
$build_location = $CurrentPerso->location;
$build_mode = 'hotglue';
$error = '';
if (!is_buildable($build_location, $error)) {
message_die(GENERAL_ERROR, $error, "Can't build");
}
//Gets or creates a new zone at build location
$zone = ContentZone::at($build_location->global, $build_location->local, true);
switch ($zone->type) {
case 'hotglue':
//All rulez
break;
case '':
//New zone
$zone->title = "Sandbox hotglue zone for $build_location->global $build_location->local";
$zone->type = 'hotglue';
$zone->save_to_database();
break;
default:
message_die("This isn't a zone managed by hotglue.");
}
unset($error);
//Template
$smarty->assign('location', $build_location);
$smarty->assign('zone', $zone);
$smarty->assign('IFRAME_SRC', '/apps/hotglue/index.php?zone_' . $zone->id . '/edit');
$template = 'builder_hotglue.tpl';
break;
default:
message_die(GENERAL_ERROR, "Unknown build mode: $build_mode");
}
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', 'Builder');
include('header.php');
//Serves content
$smarty->display($template);
//Serves footer
include('footer.php');
diff --git a/dev/quux.php b/dev/quux.php
index 54f34a6..21b9488 100644
--- a/dev/quux.php
+++ b/dev/quux.php
@@ -1,161 +1,162 @@
<?php
+ use Hypership\Geo\PointPolarZ;
+
require_once('includes/objects/ship.php');
require_once('includes/objects/port.php');
require_once('includes/objects/application.php');
require_once('includes/objects/content.php');
require_once('includes/objects/message.php');
require_once('includes/objects/invite.php');
require_once('includes/cache/cache.php');
include('controllers/header.php');
$case = 'YubiCloud';
switch ($case) {
case 'YubiCloud':
require_once('Auth/Yubico.php');
echo '<h2>YubiKey</h2>';
if (!array_key_exists('YubiCloud', $Config)) {
message_die(GENERAL_ERROR, "YubiCloud authentication not configured. Add \$Config['YubiCloud']['ClientID'] and \$Config['YubiCloud']['SecretKey'] to your config.");
}
if (!$key = $_GET['OTP']) {
message_die(GENERAL_ERROR, "Please add in URL ?OTP=, then put your cursor at right of the = and press your YubiKey button");
}
$yubi = new Auth_Yubico($Config['YubiCloud']['ClientID'], $Config['YubiCloud']['SecretKey']);
if (!$data = $yubi->parsePasswordOTP($key)) {
message_die(GENERAL_ERROR, "This is not an YubiKey OTP.");
}
$prefix = $data['prefix'];
$auth = $yubi->verify($key);
if (@PEAR::isError($auth)) {
if ($auth->getMessage() == 'REPLAYED_OTP') {
message_die("This OTP has already been used.");
}
message_die(HACK_ERROR, "<p>Authentication failed: " . $auth->getMessage() . "</p><p>Debug: " . $yubi->getLastResponse() . "</p>");
} else {
print "<p>You are authenticated!</p>";
}
break;
- case 'GeoPointPolarZ':
- require_once('includes/geo/pointPolarZ.php');
- echo "<H2>GeoPointPolarZ</H2>";
- $point = GeoPointPolarZ::fromString("(48, 30°, 3)");
- printf("Secteur T%dC%d, zone %d-%d");
+ case 'PointPolarZ':
+ echo "<H2>PointPolarZ</H2>";
+ $point = PointPolarZ::fromString("(48, 30°, 3)");
+ printf("Secteur T%dC%d", $point->getSection(), $point->z);
dprint_r($point);
break;
case 'index_scenes':
$time[] = microtime();
require_once('includes/geo/scene.php');
require_once('includes/geo/sceneindex.php');
$cache = Cache::load();
if ($index = $cache->get('GeoSceneIndex')) {
$index = unserialize($index);
} else {
$index = GeoSceneIndex::Load(SCENE_DIR);
$cache->set('GeoSceneIndex', serialize($index));
}
$time[] = microtime();
echo '<H2>GeoSceneIndex</H2>';
dprint_r($index);
echo '<H2>Time (ms)</H2>';
dprint_r(1000 * ($time[1] - $time[0]));
dprint_r($time);
break;
case 'travel':
require_once('includes/travel/travel.php');
$travel = Travel::load();
dieprint_r($travel);
break;
case 'spherical':
require_once('includes/geo/galaxy.php');
echo '<H2>Spherical coordinates test</H2>';
echo '<table cellpadding=8>';
echo "<tr><th>Name</th><th>Type</th><th>Cartesian coords</th><th>Spherical I</th><th>Spherical II</th><th>Pencil coordinates</th></tr>";
$objects = GeoGalaxy::getCoordinates();
foreach ($objects as $row) {
echo "<tr><th style='text-align: left'>$row[0]</th><td>$row[1]</td><td>$row[2]</td>";
$pt = $row[2];
echo '<td>(', implode(', ', $pt->toSpherical()), ')</td>';
echo '<td>(', implode(', ', $pt->toSphericalAlternative()), ')</td>';
$pt->translate(500, 300, 200, 2);
echo '<td>', $pt, '</td>';
echo '</tr>';
}
echo '</table>';
break;
case 'travel':
require_once('includes/travel/travel.php');
require_once('includes/travel/place.php');
$cache = Cache::load();
$travel = $cache->get('zed_travel');
if ($travel == '') {
$travel_nocached = new Travel();
$travel_nocached->load_xml("content/travel.xml");
$cache->set('zed_travel', serialize($travel_nocached));
} else {
$travel = unserialize($travel);
}
dieprint_r($travel);
break;
case 'perso.create.notify':
$testperso = Perso::get(4733);
$message = new Message();
$message->from = 0;
$message->to = invite::who_invited(4733);
$url = get_server_url() . get_url('who', $testperso->nickname);
$message->text = sprintf(lang_get('InvitePersoCreated'), $testperso->name, $url);
$message->send();
dieprint_r($message);
break;
case 'pushdata';
echo '
<h2>/api.php/app/pushdata</h2>
<form method="post" action="/api.php/app/pushdata?mode=file&key=37d839ba-f9fc-42ca-a3e8-28053e979b90" enctype="multipart/form-data">
<input type="file" name="datafile" /><br />
<input type="submit" value="Send file" />
</form>
';
break;
case 'thumbnail':
$content = new Content(1);
dprint_r($content);
$content->generate_thumbnail();
break;
case 'port':
echo '<h2>Port::from_location test</h2>';
$locations = array("B00002", "B00002123", "B00001001", "xyz: [800, 42, 220]");
foreach ($locations as $location) {
dprint_r(Port::from_location($location));
}
break;
case 'ext':
$file = 'dev/foo.tar';
echo "<h2>$file</h2>";
echo "<h3>.tar.bz2</h3>";
echo ereg('\.tar\.bz2$', $file);
echo "<h3>.tar</h3>";
echo ereg('\.tar$', $file);
break;
case 'app':
echo Application::from_api_key("37d839ba-f9fc-42ca-a3e8-28053e979b90")->generate_userkey();
break;
case '':
dieprint_r("No case currently selected.");
break;
}
include('controllers/footer.php');
diff --git a/dev/tests/Engines/Templates/Smarty/Plugins/SectorModifierTest.php b/dev/tests/Engines/Templates/Smarty/Plugins/SectorModifierTest.php
new file mode 100644
index 0000000..80b409b
--- /dev/null
+++ b/dev/tests/Engines/Templates/Smarty/Plugins/SectorModifierTest.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace Zed\Tests\Engines\Templates\Smarty\Plugins;
+
+use GeoLocation;
+
+require_once 'includes/geo/location.php';
+
+class SectorModifierTest extends SmartyPluginTestCase {
+
+ public function setUp () : void {
+ $this->requirePlugin('modifier', 'sector');
+ }
+
+ public function testPluginWithValidData () {
+ $location = new GeoLocation("B00001002", "(4,2,7)");
+ $this->assertEquals("6", smarty_modifier_sector($location));
+ }
+
+}
diff --git a/dev/tests/GeoOctocubeTest.php b/dev/tests/GeoOctocubeTest.php
deleted file mode 100644
index 1946bdf..0000000
--- a/dev/tests/GeoOctocubeTest.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-/**
- * Unit testing : class GeoOctocube
- *
- * Zed. The immensity of stars. The HyperShip. The people.
- *
- * (c) 2010, Dereckson, some rights reserved.
- * Released under BSD license.
- *
- * @package Zed
- * @subpackage Tests
- * @author S�bastien Santoro aka Dereckson <dereckson@espace-win.org>
- * @copyright 2010 S�bastien Santoro aka Dereckson
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version 0.1
- * @link http://scherzo.dereckson.be/doc/zed
- * @link http://zed.dereckson.be/
- * @filesource
- */
-
-use PHPUnit\Framework\TestCase;
-
-require_once(__DIR__ . '/../../includes/geo/octocube.php');
-
-/**
- * Test cases for the class GeoPlace
- */
-class GeoOctocubeTest extends TestCase {
-
- /**
- * Tests the GeoPlace::is_valid_local_location($local_location) method.
- */
- public function testGetSector () {
- //Testing HyperShip Tower T2C3 format
- $this->assertTrue(GeoOctocube::getSector(0, 0, 0) == 0);
- $this->assertTrue(GeoOctocube::getSector(-10, 6, -4) == 1);
- $this->assertTrue(GeoOctocube::getSector(10, 6, -4) == 2);
- $this->assertTrue(GeoOctocube::getSector(-10, -6, -4) == 3);
- $this->assertTrue(GeoOctocube::getSector(10, -6, -4) == 4);
- $this->assertTrue(GeoOctocube::getSector(-10, 6, 4) == 5);
- $this->assertTrue(GeoOctocube::getSector(10, 6, 4) == 6);
- $this->assertTrue(GeoOctocube::getSector(-10, -6, 4) == 7);
- $this->assertTrue(GeoOctocube::getSector(10, -6, 4) == 8);
- }
-
-}
diff --git a/do.php b/do.php
index 24ff63c..2f2f877 100644
--- a/do.php
+++ b/do.php
@@ -1,467 +1,466 @@
<?php
/**
* AJAX callbacks
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* As main controller could potentially be interrupted (e.g. if site.requests
* flag is at 1, user is redirected to controllers/userrequest.php), all AJAX
* queries should be handled by this script and not directly by the controllers.
*
* Standard return values:
* -7 user is logged but perso isn't selected,
* -9 user is not logged.
*
* @package Zed
* @subpackage EntryPoints
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
use Zed\Engines\Templates\Smarty\Engine as SmartyEngine;
+use Hypership\Geo\Point3D;
////////////////////////////////////////////////////////////////////////////////
///
/// Constants
///
//We define one negative number constant by standard erroneous return value.
/**
* Magic number which indicates the user is not logged in.
*/
define('USER_NOT_LOGGED', -9);
/**
* Magic number which indicates the user is logged in, but haven't selected its perso.
*/
define('PERSO_NOT_SELECTED', -7);
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
include('includes/core.php');
//Session
$IP = $_SERVER["REMOTE_ADDR"];
require_once('includes/story/story.php'); //this class can be stored in session
session_start();
$_SESSION['ID'] = session_id();
session_update(); //updates or creates the session
//Gets current perso
require_once('includes/objects/perso.php');
$CurrentUser = get_logged_user(); //Gets current user infos
if ($perso_id = $CurrentUser->session['perso_id']) {
$CurrentPerso = new Perso($perso_id);
}
//Requires user and perso
if ($CurrentUser->id < 1000) {
echo USER_NOT_LOGGED;
exit;
}
if (!$CurrentPerso) {
echo PERSO_NOT_SELECTED;
exit;
}
//Loads Smarty (as it handles l10n, it will be used by lang_get)
$smarty = SmartyEngine::load()->getSmarty();
//Loads language files
initialize_lang();
lang_load('core.conf');
////////////////////////////////////////////////////////////////////////////////
///
/// Actions definitions
///
/**
* Actions class
*
* Each method is called by first part of your URL, other parts are arguments
* e.g. /do.php/validate_quux_request/52 = Actions::validate_quux_request(52);
*
* You can also use $_GET, $_POST or better $_REQUEST.
*
* Don't print the value but return it, so we can in the future implement custom
* formats like api_output();
*/
class Actions {
/**
* Checks the arguments hash and determines whether it is valid.
*
* @param Array $args the arguments, the last being the hash
* @return boolean true if the hash is valid ; otherwise, false.
*/
static private function is_hash_valid ($args) {
global $Config;
return array_pop($args) == md5($_SESSION['ID'] . $Config['SecretKey'] . implode('', $args));
}
/**
* Handles a allow/deny perso request.
*
* @param string $request_flag the request flag to clear
* @param string $store 'perso' or 'registry'
* @param string $key the perso flag or registry key
* @param string $value the value to store
* @param string $hash the security hash
* @return boolean true if the request is valid and have been processed ; otherwise, false.
*/
static function perso_request ($request_flag, $store, $key, $value, $hash) {
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 4) {
return false;
}
//Checks hash
$args = func_get_args();
if (!self::is_hash_valid($args)) {
return false;
}
//Sets flag
switch ($store) {
case 'perso':
$CurrentPerso->set_flag($key, $value);
break;
case 'registry':
registry_set($key, $value);
break;
default:
//Unknown storage location
return false;
}
//Clears request flag
if ((string)$request_flag !== "0") {
$CurrentPerso->delete_flag($request_flag);
}
return true;
}
/**
* Sets current perso's local location.
*
* We don't require a security hash. If the users want to play with it, no problem.
* You generally move inside a global location as you wish.
* So, if you write a story capturing a perso, use flags to handle this escape!
*
* @param string $location_local the local location
* @return GeoLocation the current perso's GeoLocation object
*/
static function set_local_location ($location_local) {
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Moves current perso to specified location
$location_local = urldecode($location_local);
$CurrentPerso->move_to(null, $location_local);
//Returns GeoLocation relevant instance
return $CurrentPerso->location;
}
/**
* Moves the current perso's, setting a new local location.
*
* We don't require a security hash. If the users want to play with it, no problem.
* You generally move inside a global location as you wish.
* So, if you write a story capturing a perso, use flags to handle this escape!
*
* @param string $move the move (coordinates or direction)
* @param int $factor a number multiplying the specified move [optional]
* @return GeoLocation the current perso's GeoLocation object
*
* e.g. to move from 2 units to east, you can use one of those instructions:
* local_move('east', 2);
* local_move('2,0,0');
* local_move('1,0,0', 2);
*
* Valid moves string are north, east, south, west, up and down.
* Valid moves coordinates are x,y,z (3 integers, comma as separator)
*/
static function local_move ($move, $factor = 1) {
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Parses $move
switch ($move) {
case 'north':
$move = [0, 1, 0];
break;
case 'east':
$move = [1, 0, 0];
break;
case 'south':
$move = [0, -1, 0];
break;
case 'west':
$move = [-1, 0, 0];
break;
case 'up':
$move = [0, 0, 1];
break;
case 'down':
$move = [0, 0, -1];
break;
default:
$move = split(',', $move, 3);
foreach ($move as $coordinate) {
if (!is_numeric($coordinate)) {
return null;
}
}
}
//Moves current perso to specified location
- if ($location_local = GeoPoint3D::fromString($CurrentPerso->location->local)) {
- $location_local->translate($move[0] * $factor, $move[1] * $factor, $move[2] * $factor);
+ if ($location_local = Point3D::fromString($CurrentPerso->location->local)) {
+ $location_local->translate(
+ (float)$move[0] * $factor,
+ (float)$move[1] * $factor,
+ (float)$move[2] * $factor
+ );
$CurrentPerso->move_to(null, $location_local->sprintf("(%d, %d, %d)"));
//Returns GeoLocation relevant instance
return $CurrentPerso->location;
}
- //Old local location weren't a GeoPoint3D
+ //Old local location weren't a Point3D
return null;
}
/**
* Moves the current perso's, setting a new local location, using polar+z coordinates.
* Polar+z coordinates are polar coordinates, plus a cartesian z dimension.
*
* We don't require a security hash. If the users want to play with it, no problem.
* You generally move inside a global location as you wish.
* So, if you write a story capturing a perso, use flags to handle this escape!
*
* @param string $move the move (coordinates or direction)
* @param int $factor a number multiplying the specified move [optional]
* @return GeoLocation the current perso's GeoLocation object
*
* Valid moves string are cw, ccw, out, in, up and down.
* r: out = +12 in = -12
* °: cw = +20° ccw = -20
* Valid moves coordinates are r,°,z (3 integers, comma as separator)
* (the medium value can also be integer + °)
*
* e.g. to move of two units (the unit is 20°) clockwise:
* polarz_local_move('cw', 2);
* polarz_local_move('(0, 20°, 0)', 2);
* polarz_local_move('(0, 40°, 0)');
* Or if you really want to use radians (PI/9 won't be parsed):
* polarz_local_move('(0, 0.6981317007977318, 0)';
*
*/
static function polarz_local_move ($move, $factor = 1) {
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Parses $move
$move = urldecode($move);
switch ($move) {
case 'cw':
$move = [0, '20°', 0];
break;
case 'ccw':
$move = [0, '-20°', 0];
break;
case 'in':
$move = [+12, 0, 0];
break;
case 'out':
$move = [-12, 0, 0];
break;
case 'up':
$move = [0, 0, 1];
break;
case 'down':
$move = [0, 0, -1];
break;
default:
$move = split(',', $move, 3);
foreach ($move as $coordinate) {
if (!is_numeric($coordinate) && !preg_match("/^[0-9]+ *°$/", $coordinate)) {
return null;
}
}
}
dieprint_r($move);
//Moves current perso to specified location
- if ($location_local = GeoPoint3D::fromString($CurrentPerso->location->local)) {
- $location_local->translate($move[0] * $factor, $move[1] * $factor, $move[2] * $factor);
- $CurrentPerso->move_to(null, $location_local->sprintf("(%d, %d, %d)"));
-
- //Returns GeoLocation relevant instance
- return $CurrentPerso->location;
- }
+ throw new Exception("Move is not implemented.");
- //Old local location weren't a GeoPoint3D
+ //Old local location weren't a 3D point
return null;
}
/**
* Moves the current perso's, setting a new global and local location.
*
* @param string $location_global The global location
* @param string $location_local The local location
* @return GeoLocation the current perso's GeoLocation object
*/
static function global_move ($location_global, $location_local = null) {
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Checks hash
$args = func_get_args();
if (!self::is_hash_valid($args)) {
return false;
}
//Moves
global $CurrentPerso;
$CurrentPerso->move_to($location_global, $location_local);
return $CurrentPerso->location;
}
/**
* Handles upload content form.
*
* @return string new content path
*/
static function upload_content () {
global $CurrentPerso, $CurrentUser;
require_once('includes/objects/content.php');
//Initializes a new content instance
$content = new Content();
$content->load_from_form();
$content->user_id = $CurrentUser->id;
$content->perso_id = $CurrentPerso->id;
$content->location_global = $CurrentPerso->location_global;
//Saves file
if ($content->handle_uploaded_file($_FILES['artwork'])) {
$content->save_to_database();
$content->generate_thumbnail();
return true;
}
return false;
}
/**
* Gets multimedia content for the specified location
*
* @param string $location_global The global location (local is to specified in ?location_local parameter)
* @return Array an array of Content instances
*/
static function get_content ($location_global) {
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Checks hash
$args = func_get_args();
if (!self::is_hash_valid($args)) {
return false;
}
//Checks local location is specified somewhere (usually in $_GET)
if (!array_key_exists('location_local', $_REQUEST)) {
return false;
}
//Gets content
require_once('includes/objects/content.php');
return Content::get_local_content($location_global, $_REQUEST['location_local']);
}
}
////////////////////////////////////////////////////////////////////////////////
///
/// Handles request
///
//Parses URL
$Config['SiteURL'] = get_server_url() . $_SERVER["PHP_SELF"];
$args = get_current_url_fragments();
$method = array_shift($args);
if ($_REQUEST['debug']) {
//Debug version
//Most of E_STRICT errors are evaluated at the compile time thus such errors
//are not reported
ini_set('display_errors', 'stderr');
error_reporting(-1);
if (method_exists('Actions', $method)) {
$result = call_user_func_array(['Actions', $method], $args);
echo json_encode($result);
} else {
echo "<p>Method doesn't exist: $method</p>";
}
if (array_key_exists('redirectTo', $_REQUEST)) {
//If user JS disabled, you can add ?redirectTo= followed by an URL
echo "<p>Instead to print a callback value, redirects to <a href=\"$_REQUEST[redirectTo]\">$_REQUEST[redirectTo]</a></p>";
}
} else {
//Prod version doesn't prints warning <== silence operator
if (method_exists('Actions', $method)) {
$result = @call_user_func_array(['Actions', $method], $args);
if (array_key_exists('redirectTo', $_REQUEST)) {
//If user JS disabled, you can add ?redirectTo= followed by an URL
header("location: " . $_REQUEST['redirectTo']);
} else {
echo json_encode($result);
}
}
}
diff --git a/includes/autoload.php b/includes/autoload.php
index bbb4a16..3aca728 100644
--- a/includes/autoload.php
+++ b/includes/autoload.php
@@ -1,60 +1,57 @@
<?php
spl_autoload_register(function (string $className) {
//Classes
$classes['IAuthentication'] = './includes/auth/IAuthentication.php';
$classes['UserPasswordAuthentication'] = './includes/auth/UserPasswordAuthentication.php';
$classes['YubiCloudAuthentication'] = './includes/auth/YubiCloudAuthentication.php';
$classes['Cache'] = './includes/cache/cache.php';
$classes['CacheMemcached'] = './includes/cache/memcached.php';
$classes['CacheVoid'] = './includes/cache/void.php';
$classes['ContentFile'] = './includes/content/file.php';
$classes['ContentLocation'] = './includes/content/location.php';
$classes['ContentZone'] = './includes/content/zone.php';
$classes['GeoBody'] = './includes/geo/body.php';
$classes['GeoGalaxy'] = './includes/geo/galaxy.php';
$classes['GeoLocation'] = './includes/geo/location.php';
- $classes['GeoOctocube'] = './includes/geo/octocube.php';
$classes['GeoPlace'] = './includes/geo/place.php';
- $classes['GeoPoint3D'] = './includes/geo/point3D.php';
- $classes['GeoPointPolarZ'] = './includes/geo/pointPolarZ.php';
$classes['GeoScene'] = './includes/geo/scene.php';
$classes['GeoSceneIndex'] = './includes/geo/sceneindex.php';
$classes['Application'] = './includes/objects/application.php';
$classes['Content'] = './includes/objects/content.php';
$classes['Invite'] = './includes/objects/invite.php';
$classes['Message'] = './includes/objects/message.php';
$classes['MOTD'] = './includes/objects/motd.php';
$classes['Perso'] = './includes/objects/perso.php';
$classes['Port'] = './includes/objects/port.php';
$classes['Profile'] = './includes/objects/profile.php';
$classes['ProfileComment'] = './includes/objects/profilecomment.php';
$classes['ProfilePhoto'] = './includes/objects/profilephoto.php';
$classes['Request'] = './includes/objects/request.php';
$classes['RequestReply'] = './includes/objects/requestreply.php';
$classes['Ship'] = './includes/objects/ship.php';
$classes['User'] = './includes/objects/user.php';
$classes['SettingsPage'] = './includes/settings/page.php';
$classes['Setting'] = './includes/settings/setting.php';
$classes['Settings'] = './includes/settings/settings.php';
$classes['StoryChoice'] = './includes/story/choice.php';
$classes['StoryHook'] = './includes/story/hook.php';
$classes['DemoStoryHook'] = './includes/story/hook_demo.php';
$classes['SpatioportStoryHook'] = './includes/story/hook_spatioport.php';
$classes['StorySection'] = './includes/story/section.php';
$classes['Story'] = './includes/story/story.php';
$classes['TravelPlace'] = './includes/travel/place.php';
$classes['Travel'] = './includes/travel/travel.php';
//Loader
if (array_key_exists($className, $classes)) {
require_once($classes[$className]);
}
});
diff --git a/includes/geo/galaxy.php b/includes/geo/galaxy.php
index 728f04a..cc604ae 100644
--- a/includes/geo/galaxy.php
+++ b/includes/geo/galaxy.php
@@ -1,123 +1,60 @@
<?php
/**
* Geo galaxy class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* A 3D grid of objects
*
* 0.1 2010-02-08 14:02 Initial version [DcK]
* 0.2 2010-07-25 9:20 Spherical conversion, get objects
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
+use Hypership\Geo\Point3D;
+
/**
* Geo galaxy class
- *
- * This class provides methods to convert coordinate polars.
- *
- * @todo create a unit testing file dev/tests/GeoGalaxyTest.php
- * @todo add unit testing for the normalizeAngle method in dev/tests/GeoGalaxyTest.php
*/
class GeoGalaxy {
/*
* ----------------------------------------------------------------------- *
* Objects fetchers
* ----------------------------------------------------------------------- *
*/
/**
* Gets all the coordinates of the objects in the galaxy.
*
- * @return array An array of array. Each item is [string object_name, string object_type, GeoPoint3D coordinates]
+ * @return array An array of array. Each item is [string object_name, string object_type, Point3D coordinates]
*/
static function getCoordinates () {
global $db;
$sql = "SELECT * FROM geo_coordinates";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't query geo_coordinates view.", '', __LINE__, __FILE__, $sql);
}
$objects = [];
while ($row = $db->sql_fetchrow($result)) {
//Demios ship xyz: [-50, 30, 40]
//Kaos asteroid xyz: [150, -129, 10]
- $objects[] = [$row[0], $row[1], GeoPoint3D::fromString($row[2])];
+ $objects[] = [$row[0], $row[1], Point3D::fromString($row[2])];
}
return $objects;
}
- /*
- * ----------------------------------------------------------------------- *
- * Helper methods - math
- * ----------------------------------------------------------------------- *
- */
-
- /**
- * Normalizes an angle, so 0 =< angle < 2 PI
- *
- * @param float $angle angle in radians (use deg2rad() if you've degrees)
- * @return an angle in the 0 =< angle < 2 PI interval
- */
- static function normalizeAngle ($angle) {
- while ($angle < 0) {
- $angle += 2 * M_PI;
- }
- while ($angle >= 2 * M_PI) {
- $angle -= 2 * M_PI;
- }
- return $angle;
- }
-
- /**
- * Converts (x, y, z) cartesian to (ρ, φ, θ) spherical coordinates
- *
- * The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
- *
- * @param int $x the x coordinate
- * @param int $y the y coordinate
- * @param int $z the z coordinate
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- static function cartesianToSpherical ($x, $y, $z) {
- $rho = sqrt($x * $x + $y * $y + $z * $z); //ρ = sqrt(x² + y² + z²)
- $theta= acos($z / $rho); //φ = acos z/φ
- $phi = acos($x / sqrt($x * $x + $y * $y)); //θ = acos x / sqrt(x² + y²)
- if (y < 0) {
- $phi = 2 * M_PI - $phi; //∀ y < 0 θ = 2π - θ
- }
-
- return [round($rho, 2), round(rad2deg($theta), 2), round(rad2deg($phi), 2)];
- }
-
- /**
- * Converts (x, y, z) cartesian to (ρ, φ, θ) spherical coordinates
- *
- * The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
- *
- * @param int $x the x coordinate
- * @param int $y the y coordinate
- * @param int $z the z coordinate
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- static function cartesianToSphericalAlternative ($x, $y, $z) {
- $rho = sqrt($x * $x + $y * $y + $z * $z); //ρ = sqrt(x² + y² + z²)
- $theta= atan2($y, $x); //φ = atan2 $y $x
- $phi = acos($z / $rho); //θ = acos z/φ
-
- return [round($rho, 2), round(rad2deg($theta), 2), round(rad2deg($phi), 2)];
- }
}
diff --git a/includes/geo/location.php b/includes/geo/location.php
index 1ae0834..026e8a4 100644
--- a/includes/geo/location.php
+++ b/includes/geo/location.php
@@ -1,447 +1,446 @@
<?php
/**
* Geo location class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-28 18:52 DcK
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
+use Hypership\Geo\Point3D;
+
require_once('body.php');
require_once('place.php');
-require_once('point3D.php');
require_once('includes/objects/ship.php');
/**
* Geo location class
*
* This class contains properties to get, set or compare a location and
* explore the geo classes linked to.
*
* It quickly allow to parse through the location classes in templates and
* controllers.
*
* @todo Initialize $point3D from $body or $ship own locations
* @todo Improve GeoLocation documentation (especially magic properties)
*/
class GeoLocation {
/**
* An array of strings containing location data.
*
* In the current class implementation,
* the first element is the global location
* and the second element is the local location.
*
* @var Array
*/
private $data;
/**
* A body object
*
* It contains a GeoBody value when the global location is a body
* ie if $this->data[0][0] == 'B'
*
* Otherwise, its value is null.
*
* @var GeoBody
*/
public $body = null;
/**
* A place object
*
* It contains a GeoPlacevalue when the global location is a place
* ie if $this->data[0][0] == 'B' && strlen($this->data[0]) == 9
*
* Otherwise, its value is null.
*
* @var GeoPlace
*/
public $place = null;
/**
* A point identified by x, y, z coordinates
- *
- * @var GeoPoint3D
*/
- public $point3D = null;
+ public Point3D|null $point3D = null;
/**
* A ship object
*
* It contains a Ship value when the global location is a ship
* ie if $this->data[0][0] == 'S'
*
* Otherwise, its value is null.
*
* @var Ship
*/
public $ship = null;
/**
* Initializes a new location instance
*
* @param string $global the global location
* @param string local the locallocation
*
* @todo Improve local location handling
*/
function __construct ($global = null, $local = null) {
if (!$global) {
$this->data = [];
} elseif (preg_match("/[BS][0-9]{5}[0-9]{3}/", $global)) {
$this->data[0] = $global;
} elseif (preg_match("/[BS][0-9]{5}/", $global)) {
$this->data[0] = $global;
} elseif (preg_match("/^xyz\:/", $global)) {
$coords = sscanf($global, "xyz: [%d, %d, %d]");
if (count($coords) == 3) {
$this->data[0] = $global;
} else {
throw new Exception("Invalid expression: $global");
}
} else {
global $db;
$name = $db->sql_escape($global);
$sql = "SELECT location_code FROM " . TABLE_LOCATIONS . " WHERE location_name LIKE '$name'";
$code = $db->sql_query_express($sql);
if ($code) {
$this->data[0] = $code;
return;
}
throw new Exception("Invalid expression: $global");
}
//TODO: handle $local in a better way: from the global location, gets
//a local location handler. Or a some inheritance, like a class
//HypershipGeoLocation extending GeoLocation.
if ($local !== null) {
$this->data[1] = $local;
}
$this->load_classes();
}
/**
* Gets $place, $body and $ship instances if they're needed
*/
function load_classes () {
//No data, no class to load
if (!count($this->data)) {
return;
}
//Loads global classes
$global = $this->data[0];
$code = substr($global, 1, 5);
switch ($global[0]) {
case 'B':
switch (strlen($global)) {
case 9:
$this->place = GeoPlace::from_code($global);
case 6:
$this->body = new GeoBody($code);
break;
}
break;
case 'S':
$this->ship = new Ship($code);
break;
case 'x':
- $coords = sscanf($global, "xyz: [%d, %d, %d]");
+ $coords = sscanf($global, "xyz: [%f, %f, %f]");
if (count($coords) == 3) {
- $this->point3D = new GeoPoint3D($coords[0], $coords[1], $coords[2]);
+ $this->point3D = new Point3D(...$coords);
}
break;
}
}
/**
* Magic method called when a unknown property is get.
*
* Handles $global, $local, $type, $body_code, $ship_code, $place_code,
* $body_kind, $containsGlobalLocation, $containsLocalLocation.
*/
function __get ($variable) {
switch ($variable) {
/* main variables */
case 'global':
return $this->data[0];
break;
case 'local':
return (count($this->data) > 1) ? $this->data[1] : null;
break;
/* global location */
case 'type':
return $this->data[0][0];
case 'body_code':
if ($this->data[0][0] == 'B') {
return substr($this->data[0], 1, 5);
}
return null;
case 'place_code':
if ($this->data[0][0] == 'B') {
return substr($this->data[0], 6, 3);
}
return null;
case 'ship_code':
if ($this->data[0][0] == 'S') {
return substr($this->data[0], 1, 5);
}
return null;
case 'body_kind':
if ($this->data[0][0] == 'B' && $this->body != null) {
if ($kind = $this->body->kind()) {
return $kind;
}
} elseif ($this->data[0][0] == 'S') {
return 'ship';
}
return 'place';
case 'containsGlobalLocation':
return count($this->data) > 0;
case 'containsLocalLocation':
return count($this->data) > 1;
default:
throw new Exception("Unknown variable: $variable");
break;
}
}
/**
* Checks if the place exists
*
* @return bool true if the place exists ; otherwise, false.
*
* @todo Handle alias
*/
function exists () {
$n = count($this->data);
//If not defined, it doesn't exist
if ($n == 0) {
return false;
}
//Checks global location
switch ($this->data[0][0]) {
case 'B':
switch (strlen($this->data[0])) {
case 9:
if (!$place = GeoPlace::from_code($this->data[0])) {
return false;
}
break;
case 6:
$body = new GeoBody(substr($this->data[0], 1));
if ($body->lastError) {
return false;
}
break;
default:
message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
}
break;
case 'S':
$ship = new Ship(substr($this->data[0], 1));
if ($body->lastError) {
return false;
}
break;
default:
message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
return false;
}
if ($n > 1) {
if (!isset($place)) {
message_die(GENERAL_ERROR, "Can't check if a local place exists for the following location: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
}
if (!$place->is_valid_local_location($this->data[1])) {
return false;
}
}
return true;
}
/**
* Checks if the place is equals at the specified expression or place
*
* @return bool true if the places are equals ; otherwise, false.
*
* @todo Create a better set of rules to define when 2 locations are equal.
*/
function equals ($expression) {
//Are global location equals?
//TODO: create a better set of rules to define when 2 locations are equal.
if (is_a($expression, 'GeoLocation')) {
if (!$this->equals($expression->data[0])) {
return false;
}
if (count($expression->data) + count($this->data) > 2) {
return $expression->data[1] == $this->data[1];
}
}
if ($expression == $this->data[0]) {
return true;
}
$n1 = strlen($expression);
$n2 = strlen($this->data[0]);
if ($n1 > $n2) {
return substr($expression, 0, $n2) == $this->data[0];
}
return false;
}
/**
* Represents the current location instance as a string
*
* @return string a string representing the current location
*/
function __toString () {
if (!$this->data[0]) {
return "";
}
switch ($this->data[0][0]) {
case 'S':
$ship = new Ship($this->ship_code);
$location[] = $ship->name;
break;
case 'B':
$body = new GeoBody($this->body_code);
$location[] = $body->name ? $body->name : lang_get('UnknownBody');
if (strlen($this->data[0]) == 9) {
$place = GeoPlace::from_code($this->data[0]);
$location[] = $place->name ? $place->name : lang_get('UnknownPlace');
}
break;
case 'x':
$pt = $this->point3D->toSpherical();
return sprintf("(%d, %d°, %d°)", $pt[0], $pt[1], $pt[2]);
default:
message_die(GENERAL_ERROR, "Unknown location identifier: $type.<br />Expected: B or S.");
}
return implode(", ", array_reverse($location));
}
/**
* Magic method called when a unknown property is set.
*
* Handles $global, $local, $type, $body_code, $ship_code, $place_code
*/
function __set ($variable, $value) {
switch ($variable) {
/* main variables */
case 'global':
$this->data[0] = $value;
break;
case 'local':
$this->data[1] = $value;
break;
/* global location */
case 'type':
if ($value == 'B' || $value == 'S') {
if (!$this->data[0]) {
$this->data[0] = $value;
} else {
$this->data[0][0] = $value;
}
}
break;
case 'body_code':
if (preg_match("/[0-9]{1,5}/", $value)) {
$value = sprintf("%05d", $value);
if (!$this->data[0]) {
$this->data[0] = "B" . $value;
return;
} elseif ($this->data[0][0] == 'B') {
$this->data[0] = "B" . $value . substr($this->data[0], 6);
return;
}
throw new Exception("Global location isn't a body.");
}
throw new Exception("$value isn't a valid body code");
case 'ship_code':
if (preg_match("/[0-9]{1,5}/", $value)) {
$value = sprintf("%05d", $value);
if (!$this->data[0]) {
$this->data[0] = "S" . $value;
return;
} elseif ($this->data[0][0] == 'S') {
$this->data[0] = "S" . $value . substr($this->data[0], 6);
return;
}
throw new Exception("Global location isn't a ship.");
}
throw new Exception("$value isn't a valid ship code");
case 'place_code':
if (!preg_match("/[0-9]{1,3}/", $value)) {
throw new Exception("$value isn't a valid place code");
}
$value = sprintf("%03d", $value);
if ($this->data[0][0] == 'B') {
$this->data[0] = substr($this->data[0], 0, 6) . $value;
}
throw new Exception("Global location isn't a body.");
default:
throw new Exception("Unknown variable: $variable");
break;
}
}
}
diff --git a/includes/geo/octocube.php b/includes/geo/octocube.php
deleted file mode 100644
index 5b047df..0000000
--- a/includes/geo/octocube.php
+++ /dev/null
@@ -1,153 +0,0 @@
-<?php
-
-/**
- * Geo octocube class.
- *
- * Zed. The immensity of stars. The HyperShip. The people.
- *
- * (c) 2010, Dereckson, some rights reserved.
- * Released under BSD license.
- *
- * @package Zed
- * @subpackage Geo
- * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
- * @copyright 2010 Sébastien Santoro aka Dereckson
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version 0.1
- * @link http://scherzo.dereckson.be/doc/zed
- * @link http://zed.dereckson.be/
- * @filesource
- */
-
-/**
- * Geo octocube class
- *
- * An octocube is a cube divided in 8 parts (sliced in two in x, y and z)
- *
- * The coordinates (0, 0, 0) represents the octocube center.
- */
-class GeoOctocube {
- /**
- * Gets the sector from the (x, y, z) specified coordinates
- *
- * Sector will be:
- * <code>
- * // _____ _____
- * // / 5 / 6 /|
- * // /- - -/- - -/ |
- * // /_____/____ /| |
- * // | | | |/|
- * // | 7 | 8 | / | 2
- * // |_____|_____|/| |
- * // | | | |/
- * // | 3 | 4 | /
- * // |_____|_____|/
- * </code>
- *
- * @param int $x the x coordinate
- * @param int $y the y coordinate
- * @param int $z the z coordinate
- * @return int the number of the sector (0 if x = y = z = 0 ; otherwise, 1 to 8)
- */
- static function getSector ($x, $y, $z) {
- //Cube center
- if ($x == 0 && $y == 0 && $z == 0) {
- return 0;
- }
-
- //One of the 8 cubes
- $sector = 1;
- if ($x >= 0) {
- $sector++; //we're at right
- }
- if ($y < 0) {
- $sector += 2; //we're at bottom
- }
- if ($z >= 0) {
- $sector += 4; //we're on the top layer
- }
-
- return $sector;
- }
-
- /**
- * Gets the sector from the (x, y, z) specified coordinates
- * @see getSector
- *
- * @param mixed $pt a GeoPoint3D object for the x, y, z coordinates or a parsable string
- * @return int the number of the sector (0 if x = y = z 0 ; otherwise, 1 to 8)
- */
- static function getSectorFromPoint3D ($pt) {
- if (is_string($pt)) {
- $pt = GeoPoint3D::fromString($pt);
- }
- return self::getSector($pt->x, $pt->y, $pt->z);
- }
-
- /**
- * Gets the base vector for the specified sector
- *
- * Example code:
- *
- * $vector = GeoOctocube::getBaseVector(4);
- * //$vector is a (1, -1, -1) array
- *
- * @param int $sector the sector number (0-8)
- * @return array if the sector is 0, (0, 0, 0) ; otherwise, an array with three signed 1 values.
- */
- static function getBaseVector ($sector) {
- switch ($sector) {
- case 0: return [0, 0, 0];
- case 1: return [-1, 1, -1];
- case 2: return [1, 1, -1];
- case 3: return [-1, -1, -1];
- case 4: return [1, -1, -1];
- case 5: return [-1, 1, 1];
- case 6: return [1, 1, 1];
- case 7: return [-1, -1, 1];
- case 8: return [1, -1, 1];
- default: message_die(GENERAL_ERROR, "Invalid sector: $sector", "GeoOctocube::getBaseVector");
- }
- }
-
-
- /**
- * Gets SQL RLIKE pattern for the specified sector
- *
- * @param int $sector the sector number (0-8)
- * @param int $z if not null, limits the query to the specified z coordinate [optional]
- * @return string a SQL clause like "([0-9]+, -[0,9]+, [0,9]+)"
- */
- static function getRlikePatternFromSector ($sector, $z = null) {
- if ($sector == 0) {
- return "(0, 0, 0)";
- }
-
- $vector = self::getBaseVector($sector);
-
- //x
- if ($vector[0] == 1) {
- $query = "([0-9]+, ";
- } else {
- $query = "(-[0-9]+, ";
- }
-
- //y
- if ($vector[1] == 1) {
- $query .= "[0-9]+, ";
- } else {
- $query .= "-[0-9]+, ";
- }
-
- //z
- if ($z !== null) {
- $query .= "$z)";
- } elseif ($vector[2] == "1") {
- $query .= "[0-9]+)";
- } else {
- $query .= "-[0-9]+)";
- }
-
- return $query;
- }
-}
diff --git a/includes/geo/point3D.php b/includes/geo/point3D.php
deleted file mode 100644
index 82cc85c..0000000
--- a/includes/geo/point3D.php
+++ /dev/null
@@ -1,239 +0,0 @@
-<?php
-
-/**
- * Geo point 3D class.
- *
- * Zed. The immensity of stars. The HyperShip. The people.
- *
- * (c) 2010, Dereckson, some rights reserved.
- * Released under BSD license.
- *
- * 0.1 2010-02-23 14:14 DcK
- *
- * @package Zed
- * @subpackage Geo
- * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
- * @copyright 2010 Sébastien Santoro aka Dereckson
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version 0.1
- * @link http://scherzo.dereckson.be/doc/zed
- * @link http://zed.dereckson.be/
- * @filesource
- */
-
-require_once("galaxy.php");
-
-/**
- * Geo point 3D class.
- *
- * This class represents a x, y, z point.
- *
- * It implements IteratorAggregate to allow the foreach instruction
- * on a GeoPoint3D object:
- *
- * <code>
- * $point = new GeoPoint3D(17, 24, -6);
- * foreach ($point as $axis => $coordinate) {
- * echo "\n\t$axis = $coordinate";
- * }
- * //This will output:
- * // x = 17
- * // y = 24
- * // z = -6
- * </code>
- *
- * The point 3D representation is xyz: [x, y, z] ; you can print it as a string
- * and get this format:
- *
- * <code>
- * $point = new GeoPoint3D(17, 24, -6);
- * echo (string)$point; //will output xyz: [17, 24, -6]
- * </code>
- *
- */
-class GeoPoint3D implements IteratorAggregate {
- //
- // x, y, z public properties
- //
-
- /**
- * the x coordinate
- *
- * @var integer
- */
- public $x;
-
- /**
- * the y coordinate
- *
- * @var integer
- */
- public $y;
-
- /**
- * the z coordinate
- *
- * @var integer
- */
- public $z;
-
- //
- // constructor / toString
- //
-
- /**
- * Initializes a new instance of GeoPoint3D class
- *
- * @param int $x the x coordinate
- * @param int $y the y coordinate
- * @param int $z the z coordinate
- */
- function __construct ($x, $y, $z) {
- $this->x = (int)$x;
- $this->y = (int)$y;
- $this->z = (int)$z;
- }
-
- /**
- * Parses a string expression and gets a GeoPoint3D object
- *
- * Formats recognized are:
- * - xyz: [x, y, z]
- * - (x, y, z)
- *
- * @param string $expression the expression to parse
- * @return GeoPoint3D If the specified expression could be parsed, a GeoPoint3D instance ; otherwise, null.
- */
- static function fromString ($expression) {
- if (string_starts_with($expression, 'xyz:', false)) {
- $pos1 = strpos($expression, '[', 4) + 1;
- $pos2 = strpos($expression, ']', $pos1);
- if ($pos1 > -1 && $pos2 > -1) {
- $expression = substr($expression, $pos1, $pos2 - $pos1);
- $xyz = explode(',', $expression, 3);
- return new GeoPoint3D($xyz[0], $xyz[1], $xyz[2]);
- }
- } elseif ($expression[0] = '(') {
- $expression = substr($expression, 1, -1);
- $xyz = explode(',', $expression, 3);
- return new GeoPoint3D($xyz[0], $xyz[1], $xyz[2]);
- }
- return null;
- }
-
- /**
- * Returns a string representation of the point coordinates.
- *
- * @param $format the format to use
- * @return string a string representation of the coordinates
- *
- * To print a "xyz: [10, 20, 40]" string:
- * $point = new GeoPoint3D(10, 20, 40);
- * echo $point->sprintf("xyz: [%d, %d, %d]");
- *
- * //Of course, you could have (implicitly) use the __toString method:
- * echo $point;
- *
- * To print a (10, 20, 40) string:
- * $point = new GeoPoint3D(10, 20, 40);
- * echo $point->sprintf("(%d, %d, %d)");
- */
- function sprintf ($format) {
- return sprintf($format, $this->x, $this->y, $this->z);
- }
-
- /**
- * Returns a xyz: [x, y, z] string representation of the point coordinates.
- *
- * @return string a xyz: [x, y, z] string representation of the coordinates
- */
- function __toString () {
- return $this->sprintf("xyz: [%d, %d, %d]");
- }
-
- /**
- * Determines if this point is equal to the specified point.
- *
- * @param GeoPoint3D $point The point to compare
- * @return bool true if the two points are equal ; otherwise, false.
- */
- function equals ($point) {
- return ($this->x == $point->x) && ($this->y == $point->y) && ($this->z == $point->z);
- }
-
- //
- // Math
- //
-
- /**
- * Gets the (ρ, φ, θ) spherical coordinates from the current x, y, z cartesian point
- *
- * The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
- *
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- function toSpherical () {
- return GeoGalaxy::cartesianToSpherical($this->x, $this->y, $this->z);
- }
-
- /**
- * Gets the (ρ, φ, θ) spherical coordinates from the current x, y, z cartesian point
- *
- * The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
- *
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- function toSphericalAlternative () {
- return GeoGalaxy::cartesianToSphericalAlternative($this->x, $this->y, $this->z);
- }
-
- /**
- * Translates the center and rescales.
- *
- * This method allow to help to represent coordinate in a new system
- *
- * This method is used to represent Zed objects in dojo with the following
- * parameters:
- * <code>
- * $pointKaos = GeoPoint3D(800, 42, 220);
- * $pointKaos->translate(500, 300, 200, 2);
- * echo $pointKaos;
- * //This will output xyz: [150, -129, 10]
- * </code>
- *
- * @param int $dx the difference between the old x and new x (ie the value of x = 0 in the new system)
- * @param int $dy the difference between the old y and new y (ie the value of y = 0 in the new system)
- * @param int $dz the difference between the old y and new z (ie the value of z = 0 in the new system)
- * @param float $scale if specified, divides each coordinate by this value (optional)
- */
- function translate ($dx, $dy, $dz, $scale = 1) {
- if ($scale == 1) {
- $this->x += $dx;
- $this->y += $dy;
- $this->z += $dz;
- } elseif ($scale == 0) {
- $this->x = 0;
- $this->y = 0;
- $this->z = 0;
- } else {
- $this->x = $this->x * $scale + $dx;
- $this->y = $this->y * $scale + $dy;
- $this->z = $this->z * $scale + $dz;
- }
- }
-
- //
- // Implementing IteratorAggregate
- //
-
- /**
- * Retrieves class iterator. It traverses x, y and z.
- *
- * @return Traversable the iterator
- */
- function getIterator () {
- return new ArrayIterator($this);
- }
-
-
-}
diff --git a/includes/geo/pointPolarZ.php b/includes/geo/pointPolarZ.php
deleted file mode 100644
index 54039dc..0000000
--- a/includes/geo/pointPolarZ.php
+++ /dev/null
@@ -1,376 +0,0 @@
-<?php
-
-/**
- * Geo point polar+z class.
- *
- * Zed. The immensity of stars. The HyperShip. The people.
- *
- * (c) 2010, Dereckson, some rights reserved.
- * Released under BSD license.
- *
- * @package Zed
- * @subpackage Geo
- * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
- * @copyright 2010 Sébastien Santoro aka Dereckson
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version 0.1
- * @link http://scherzo.dereckson.be/doc/zed
- * @link http://zed.dereckson.be/
- * @filesource
- */
-
-require_once("point3D.php");
-
-/**
- * Geo point polar+z class.
- *
- * This class represents a r, ρ, z point.
- *
- * They are useful to express coordinates in a cylinder shape, like a tower
- * where it make senses to use polar coordinates instead x, y but where the
- * height is not relative to a center, like it would be in a sphere.
- *
- * It implements IteratorAggregate to allow the foreach instruction
- * on a GeoPointPolarZ object:
- *
- * <code>
- * $point = new GeoPointPolarZ(17, '24°', -6);
- * foreach ($point as $axis => $coordinate) {
- * echo "\n\t$axis = $coordinate";
- * }
- * //This will output:
- * // r = 17
- * // t = 24°
- * // z = -6
- * </code>
- *
- * The point 3D representation is rtz: [ρ, θ, z] ; you can print it as a string
- * and get this format:
- *
- * <code>
- * $point = new GeoPointPolarZ(17, '24°', -6);
- * echo (string)$point; //will output rρz: [17, 24°, -6]
- * </code>
- *
- */
-class GeoPointPolarZ implements IteratorAggregate {
- //
- // ρ, θ, z public properties
- //
-
- /**
- * the ρ coordinate
- *
- * @var float
- */
- public $r;
-
- /**
- * the θ coordinate
- *
- * This coordinate could be expressed as:
- * - a string with a float, appended by "°" or " °" (in degree)
- * - as a float (in radian)
- *
- * @var mixed
- */
- public $t;
-
- /**
- * the z coordinate
- *
- * @var float
- */
- public $z;
-
- //
- // constructor / toString
- //
-
- /**
- * Initializes a new instance of GeoPointPolarZ class
- *
- * @param float $r the ρ coordinate
- * @param mixed $t the θ coordinate, in ° (string) or radian (float)
- * @param float $z the z coordinate
- */
- function __construct ($r, $t, $z) {
- $this->r = (float)$r;
- $this->t = trim($t);
- $this->z = (float)$z;
- }
-
- /**
- * Parses a string expression and gets a GeoPointPolarZ object
- *
- * Formats recognized are:
- * - rtz: [ρ, θ, z]
- * - (ρ, θ, z)
- *
- * @param string $expression the expression to parse
- * @return GeoPointPolarZ If the specified expression could be parsed, a GeoPointPolarZ instance ; otherwise, null.
- */
- static function fromString ($expression) {
- if (string_starts_with($expression, 'rtz:', false)) {
- $pos1 = strpos($expression, '[', 4) + 1;
- $pos2 = strpos($expression, ']', $pos1);
- if ($pos1 > -1 && $pos2 > -1) {
- $expression = substr($expression, $pos1, $pos2 - $pos1);
- $rtz = explode(',', $expression, 3);
- return new GeoPointPolarZ($rtz[0], $rtz[1], $rtz[2]);
- }
- } elseif ($expression[0] = '(') {
- $expression = substr($expression, 1, -1);
- $rtz = explode(',', $expression, 3);
- return new GeoPointPolarZ($rtz[0], $rtz[1], $rtz[2]);
- }
- return null;
- }
-
- /**
- * Returns a string representation of the point coordinates.
- *
- * @param $format the format to use
- * @return string a string representation of the coordinates
- *
- * To print a "rtz: [10, 20°, 40]" string:
- * $point = new GeoPointPolarZ(10, '20°', 40);
- * echo $point->sprintf("rtz: [%d, %s, %d]");
- *
- * //Of course, you could have (implicitly) use the __toString method:
- * echo $point;
- *
- * To print a (10, 20°, 40) string:
- * $point = new GeoPointPolarZ(10, 20°, 40);
- * echo $point->sprintf("(%d, %s, %d)");
- */
- function sprintf ($format) {
- return sprintf($format, $this->r, self::getDegrees($this->t), $this->z);
- }
-
- /**
- * Returns a rρz: [r, ρ, z] string representation of the point coordinates.
- *
- * @return string a rtz: [ρ, θ, z] string representation of the coordinates
- */
- function __toString () {
- return $this->sprintf("rtz: [%d, %s, %d]");
- }
-
- /**
- * Determines if this point is equal to the specified point.
- *
- * @param GeoPointPolarZ $point The point to compare
- * @return bool true if the two points are equal ; otherwise, false.
- */
- function equals ($point) {
- return ($this->r == $point->r) && self::areAngleEqual($this->t, $point->t) && ($this->z == $point->z);
- }
-
- /**
- * Determines if two angles are equal
- * @param mixed $angle1 the first angle value, ie a float (angle in radian) or a string formed by an integer appended by ° (degrees)
- * @param mixed $angle2 the second angle value, a float (angle in radian) or a string formed by an integer appended by ° (degrees)
- * @return bool true if the angles are equal ; otherwise, false.
- */
- static function areAngleEqual ($angle1, $angle2) {
- if ($angle1 === $angle2) {
- return true;
- }
- if (!is_numerical($angle1)) {
- $angle1 = deg2rad((float)$angle1);
- }
- if (!is_numerical($angle2)) {
- $angle2 = deg2rad((float)$angle2);
- }
- $angle1 = self::normalizeAngle($angle1);
- $angle2 = self::normalizeAngle($angle2);
- return ($angle1 == $angle2);
- }
-
- /**
- * Normalizes an angle (in radians) in the interval [0, π[ (or a custom interval)
- *
- * @param float $angle the angle (in radians)
- * @param float $min the radians value the angle must be greater or equal than [optional, default value: 0]
- * @param float $max the radians value the angle must be strictly lesser than [optional, default value: M_PI]
- * @param float $interval the increment interval [optional, default value: 360]
- */
- static function normalizeAngle ($angle, $min = 0, $max = M_PI, $interval = M_PI) {
- while ($angle < $min) {
- $angle += $interval;
- }
- while ($angle >= $max) {
- $angle -= $interval;
- }
- return $angle;
- }
-
- /**
- * Normalizes an angle (in degrees) in the interval [0, 360[ (or a custom interval)
- *
- * @param float $angle the angle to normalize, in degrees
- * @param float $min the degrees value the angle must be greater or equal than [optional, default value: 0]
- * @param float $max the degrees value the angle must be strictly lesser than [optional, default value: 360]
- * @param float $interval the increment interval [optional, default value: 360]
- */
- static function normalizeAngleInDegrees ($angle, $min = 0, $max = 360, $interval = 360) {
- while ($angle < $min) {
- $angle += $interval;
- }
- while ($angle >= $max) {
- $angle -= $interval;
- }
- return $angle;
- }
-
- /**
- * Gets the specified angle in radians
- *
- * @param mixed $angle the angle, a float in radians or a string (a float + "°" or " °" in degrees
- * @return float the angle in radians
- */
- static function getRadians ($angle) {
- return is_numeric($angle) ? $angle : deg2rad((float)$angle);
- }
-
- /**
- * Gets the specified angle in degrees
- *
- * @param mixed $angle the angle, a float in radians or a string (a float + "°" or " °" in degrees
- * @return string the angle (float) in degrees followed by "°"
- */
- static function getDegrees ($angle) {
- return is_numeric($angle) ? rad2deg((float)$angle) . '°' : $angle;
- }
-
- /**
- * Converts a polar coordinate angle to a 0-360° CW angle
- */
- static function getNaturalDegrees ($angle) {
- return self::normalizeAngleinDegrees(90 - self::getDegrees($angle));
- }
-
- //
- // Math
- //
-
- /**
- * Gets the (x, y, z) cartesian coordinates from the current ρ, θ, z polar+z point
- *
- * @return array an array of 3 floats number, representing the (x, y, z) cartesian coordinates
- */
- function toCartesian () {
- $x = $this->r * cos(self::getRadians($this->t));
- $y = $this->r * sin(self::getRadians($this->t));
- return [$x, $y, $this->z];
- }
-
- /**
- * Converts the current GeoPointPolarZ instance to a GeoPoint3D instance
- *
- * @return GeoPoint3D an instance of the GeoPoint3D class representing the (x, y, z) cartesian coordinates
- */
- function toPoint3D () {
- $pt = $this->toCartesian();
- return new GeoPoint3D($pt[0], $pt[1], $pt[2]);
- }
-
- /**
- * Gets the (ρ, φ, θ) spherical coordinates from the current (ρ, θ, z) polar+z point
- *
- * The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
- *
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- function toSpherical () {
- $pt = $this->toCartesian();
- return GeoGalaxy::cartesianToSpherical($pt[0], $pt[1], $pt[2]);
- }
-
- /**
- * Gets the (ρ, φ, θ) spherical coordinates from the current (ρ, θ, z) polar+z point
- *
- * The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
- *
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- function toSphericalAlternative () {
- $pt = $this->toCartesian();
- return GeoGalaxy::cartesianToSphericalAlternative($pt[0], $pt[1], $pt[2]);
- }
-
- /**
- * Translates the center and rescales.
- *
- * This method allow to help to represent coordinate in a new system
- *
- * This method is used to represent Zed objects in dojo with the following
- * parameters:
- * <code>
- * $pointKaos = GeoPointPolarZ(800, 42, 220);
- * $pointKaos->translate(500, 300, 200, 2);
- * echo $pointKaos;
- * //This will output rρz: [150, -129, 10]
- * </code>
- *
- * @param float $dr the difference between the old ρ and new ρ (ie the value of ρ = 0 in the new system)
- * @param float $dt the difference between the old θ and new θ (ie the value of θ = 0 in the new system)
- * @param float $dz the difference between the old y and new z (ie the value of z = 0 in the new system)
- * @param int $scale if specified, divides each coordinate by this value (optional)
- */
- function translate ($dr, $dt, $dz, $scale = 1) {
- if ($scale == 1) {
- $this->r += $dr;
- $this->t += $dt;
- $this->z += $dz;
- } elseif ($scale == 0) {
- $this->r = 0;
- $this->t = 0;
- $this->z = 0;
- } else {
- $this->r = $this->r * $scale + $dr;
- $this->t = $this->t * $scale + $dt;
- $this->z = $this->z * $scale + $dz;
- }
- }
-
- /**
- * Calculates the section number the specified angle belongs
- *
- * @param $angle float The natural angle in degree (North 0°, East 90°, etc. clockwise)
- * @param int $count the number of sections (default value: 6)
- * @return $int the section number
- */
- static function calculateSection ($angle, $count = 6) {
- if ($angle < 90) {
- $angle += 270;
- } else {
- $angle -= 90;
- }
- return 1 + (int)($angle / (360/$count));
- }
-
- /**
- * Gets the section number the θ angle belongs to.
- *
- * @param int $count the number of sections
- * @return $int the section number
- */
- function getSection ($count = 6) {
- return self::calculateSection(self::getNaturalDegrees($this->t), $count);
- }
-
- //
- // Implementing IteratorAggregate
- //
-
- /**
- * Retrieves class iterator. It traverses ρ, θ and z.
- *
- * @return Traversable the iterator
- */
- function getIterator () {
- return new ArrayIterator($this);
- }
-}
diff --git a/skins/zed/builder_map.tpl b/skins/zed/builder_map.tpl
index dbdba27..fd4d732 100644
--- a/skins/zed/builder_map.tpl
+++ b/skins/zed/builder_map.tpl
@@ -1,49 +1,47 @@
<div class="grid_7 alpha">
-{$xyz = explode(',', substr($CurrentPerso->location_local, 1, -1))}
-{$x = $xyz[0]}{$y = $xyz[1]}{$z = $xyz[2]}
- Sector C<span id="sector">{GeoOctocube::getSector($x, $y, $z)}</span>
+ Sector C<span id="sector">{$CurrentPerso->location|sector}</span>
</div>
<div class="grid_2" style="text-align: center;" id="info_area">
Zone <span id="area">{abs($x)}-{abs($y)}</span>
</div>
<div class="grid_7 omega" style="text-align: right; margin-bottom: 1em;">
Niveau <span id="level">{abs($z)}</span>
</div>
<div class="clear"></div>
<!-- Map -->
{if $zones}
<div id="map"></div>
<style>
.zone-build img {
opacity: 0.10;
}
</style>
<script type="text/javascript" src="/js/builder/map.js"></script>
<script>
var zones = [
{foreach from=$zones item=zone name=zones}
['{$zone->location_local}', {$zone->id}, '{$zone->type}', '{$zone->params}']{if !$smarty.foreach.zones.last},{/if}
{/foreach}
];
dojo.ready(function() {
map.init('map', zones);
});
</script>
<noscript>
<p>You've zones at:</p>
<ul>
{foreach from=$zones item=zone}
<li>{$zone->location_local}</li>
{/foreach}
</ul>
<p>A patch for a pure HTML renderer to print a map without javascript is welcome.</p>
</noscript>
{else}
<div class="grid_16 alpha omega">
<div class="notify">This area is empty.</div>
</div>
<div class="clear"></div>
{/if}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 5, 04:40 (3 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
20981
Default Alt Text
(79 KB)

Event Timeline