x = $x; $this->y = $y; $this->type = $type; $this->alloc = $alloc; if (is_bool($spawn)) { $this->spawn = $spawn; } elseif (is_string($spawn)) { $this->spawn = ($spawn == 't'); } else { $this->spawn = null; } } public function setType($type) { if (is_null($type) || !in_array((string) $type, array('S', '1', '2', '3', '4'))) { throw new Exception('Invalid type'); } $this->type = $type; if ($this->type != 'S') { $this->alloc = $this->spawn = null; } elseif (is_null($this->alloc)) { $this->alloc = 0; $this->spawn = null; } } public function setAllocation($alloc) { if ($alloc < 0 || $this->type != 'S') { throw new Exception('Invalid allocation type'); } $this->alloc = $alloc; if ($this->alloc != 0 && is_null($this->spawn)) { $this->spawn = false; } elseif ($this->alloc = 0) { $this->spawn = null; } } public function setSpawn($spawn) { if (is_null($this->alloc) || $this->alloc == 0 || !is_bool($spawn)) { throw new Exception("Invalid spawning value"); } $this->spawn = $spawn; } public function getType() { return $this->type; } public function getAllocation() { return $this->alloc; } public function getSpawn() { return $this->spawn; } public function getX() { return $this->x; } public function getY() { return $this->y; } public function store($db, $map) { $q = pg_query_params($db, "INSERT INTO main.ctf_map_layout(map,sys_x,sys_y,sys_type,alloc_for,spawn_here)" . " VALUES ($map,$1,$2,$3,$4,$5)", array( $this->x, $this->y, $this->type, $this->alloc, ($this->type == 'S' && $this->alloc > 0) ? ($this->spawn ? 't' : 'f') : null )); if (!$q) { throw new Exception("Failed to store system at {$this->x};{$this->y}"); } } } class ctf_map { private $dbID; private $name; private $description; private $width; private $height; private $alliances; private $map; public static function allMaps() { $db = __dbConnect(); if (! $db) { throw new Exception('Unable to connect to the database'); } $result = pg_query($db, "SELECT id FROM main.ctf_map_def ORDER BY id"); if (!$result) { throw new Exception("Database error"); } $IDs = array(); while ($row = pg_fetch_array($result)) { array_push($IDs, $row[0]); } pg_free_result($result); pg_close($db); $maps = array(); foreach ($IDs as $id) { $maps[$id] = new ctf_map($id); } return $maps; } public function __construct($dbID = null) { if (is_null($dbID)) { $this->dbID = $this->name = $this->description = null; $this->alliances = 2; $this->width = $this->height = 3; } else { $db = __dbConnect(); if (! $db) { throw new Exception("Unable to connect to the database"); } $result = pg_query($db, "SELECT * FROM main.ctf_map_def WHERE id = $dbID"); if (!($result && pg_num_rows($result) == 1)) { pg_close($db); throw new Exception("Definition '$dbID' not found"); } $row = pg_fetch_assoc($result); pg_free_result($result); pg_close($db); $this->dbID = $dbID; $this->name = $row['name']; $this->description = $row['description']; $this->width = $row['width']; $this->height = $row['height']; $this->alliances = $row['alliances']; } $this->map = null; } public function getID() { return $this->dbID; } public function getName() { return $this->name; } public function getDescription() { return $this->description; } public function getWidth() { return $this->width; } public function getHeight() { return $this->height; } public function getAlliances() { return $this->alliances; } public function setName($value) { $this->name = $value; } public function setDescription($value) { $this->description = ($value == '') ? null : $value; } public function setAlliances($value) { $this->alliances = $value; } public function setWidth($value) { if (is_null($this->map) && !is_null($this->dbID)) { $this->load(); } $this->width = $value; if (is_array($this->map)) { $this->initBlankMap(); } } public function setHeight($value) { if (is_null($this->map) && !is_null($this->dbID)) { $this->load(); } $this->height = $value; if (is_array($this->map)) { $this->initBlankMap(); } } public function getMapInfo($x, $y) { if (! is_array($this->map)) { if ($this->dbID) { $this->load(); } else { return null; } } $offset = $this->getOffset($x, $y); return $this->map[$offset]; } public function setSystemType($x, $y, $t) { if (! is_array($this->map)) { if ($this->dbID) { $this->load(); } else { $this->initBlankMap(); } } $offset = $this->getOffset($x, $y); $v = $this->map[$offset]; if (is_null($v)) { $v = $this->map[$offset] = new ctf_map_sys($x, $y, $t); } else { $v->setType($t); } } public function setSystemAlloc($x, $y, $a) { if (! is_array($this->map)) { if ($this->dbID) { $this->load(); } else { $this->initBlankMap(); } } $offset = $this->getOffset($x, $y); $v = $this->map[$offset]; if (is_null($v)) { $v = $this->map[$offset] = new ctf_map_sys($x, $y, 'S'); } if ($v->getType() != 'S') { throw new Exception("Can't set allocation type for a nebula"); } if ($a < 0 || $a > $this->alliances) { throw new Exception("Invalid allocation type $a"); } $v->setAllocation($a); } public function setSystemSpawn($x, $y, $s) { if (! is_array($this->map)) { if ($this->dbID) { $this->load(); } else { $this->initBlankMap(); } } $offset = $this->getOffset($x, $y); $v = $this->map[$offset]; if (is_null($v)) { $v = $this->map[$offset] = new ctf_map_sys($x, $y, 'S', 1, $s); } else { if ($v->getType() != 'S' || $v->getAllocation() < 1) { throw new Exception("Can't set spawning point"); } $v->setSpawn($s); } } public function jsDump() { $parts = array(); if (is_null($this->map)) { if ($this->dbID) { $this->load(); } else { $this->initBlankMap(); } } foreach ($this->map as $s) { if (is_null($s)) { continue; } $str = '[' . $s->getX() . ',' . $s->getY() . ',"' . $s->getType() . '",'; if ($s->getType() != 'S') { $str .= 'null,null'; } else { $str .= $s->getAllocation() . ','; if ($s->getAllocation()) { $str .= $s->getSpawn() ? 'true' : 'false'; } else { $str .= 'null'; } } array_push($parts, "$str]"); } return join(',', $parts); } public function save() { $db = __dbConnect(); if (!$db) { throw new Exception("Database error"); } pg_query($db, "BEGIN TRANSACTION"); pg_query($db, "SET search_path = public, main"); if ($this->dbID) { $id = $this->dbID; pg_query_params($db, "UPDATE main.ctf_map_def SET name=$2, description=$3, alliances=$4, " . "width=$5, height=$6 WHERE id=$1", array( $id, $this->name, $this->description, $this->alliances, $this->width, $this->height )); pg_query($db, "DELETE FROM main.ctf_map_layout WHERE map=$id"); } else { pg_query_params($db, "INSERT INTO main.ctf_map_def(name,description,alliances,width,height) " . "VALUES ($1, $2, $3, $4, $5)", array( $this->name, $this->description, $this->alliances, $this->width, $this->height )); $q = pg_query($db, "SELECT last_inserted('ctf_map_def')"); if (!($q && pg_num_rows($q))) { throw new Exception("Database error"); } list($id) = pg_fetch_array($q); } foreach ($this->map as $sys) { $sys->store($db, $id); } pg_query($db, "COMMIT"); pg_close($db); $this->dbID = $id; } public function destroy() { if (! $this->dbID) { return; } $db = __dbConnect(); if (!$db) { throw new Exception("Database error"); } pg_query($db, "DELETE FROM main.ctf_map_def WHERE id={$this->dbID}"); pg_close($db); } private function load() { $db = __dbConnect(); if (!$db) { throw new Exception("Database error"); } $result = pg_query($db, "SELECT * FROM main.ctf_map_layout WHERE map = {$this->dbID}"); if (!($result && pg_num_rows($result) == $this->height * $this->width)) { throw new Exception("Unable to load map"); } $map = array(); while ($row = pg_fetch_assoc($result)) { $offset = $this->getOffset($row['sys_x'], $row['sys_y']); $map[$offset] = new ctf_map_sys($row['sys_x'], $row['sys_y'], $row['sys_type'], $row['alloc_for'], $row['spawn_here']); } $this->map = $map; pg_free_result($result); pg_close($db); } private function initBlankMap() { $map = array(); for ($i = 0; $i < $this->width * $this->height; $i ++) { $map[$i] = null; } $this->map = $map; } private function getOffset($x, $y) { return $this->width * (floor($this->height / 2) + $y) + floor($this->width / 2) + $x; } } ?>