Posted by dmitrig01 on April 21, 2007 at 1:30am
You can see the current code @ http://cvs.drupal.org/viewcvs/drupal/contributions/sandbox/dmitrig01/mapapi, and you can get cvs @ cvs.drupal.org/cvs/drupal-contrib/contributions/sandbox/dmitrig01/mapapi.

Comments
current code & notes
mapapi.module
http://game.dev.dmitrizone.com/pastebin/index.php?show=37
<?php
//$Id: mapapi.module,v 1.5 2007/04/22 02:14:55 dmitrig01 Exp $
/<em>
* Creates and loads maps.
*/
/</em>
* Loads multiple maps
* Currently, the maps have the following syntax:
*
* $maps = array()
* $maps['single_tile'] = array(
* 'mid' => 1,
* 'x' => 5,
* 'y' => 5,
* 'length_x' => 1,
* 'length_y' => 1,
* 'tile_content' => true
* );
* $maps['multi_tile'] = array(
* 'mid' => 1,
* 'x' => 5, //try negative values... you will see them adjust and always return
* 'y' => 5, //the correct box bounds (defined by length_x and length_y)
* 'length_x' => 10,
* 'length_y' => 9, // doesnt have to be exactly square!
* 'tile_content' => true // true/false on whether to load tile content or not.
* );
*
<em>/
function mapapi_load($maps) {
$mapapi_array = array();
foreach($maps as $mapapi_name => $map) {
$mapapi_array[$mapapi_name] = _mapapi_load($map);
}
return $mapapi_array;
}
/</em>
* Loads a single map
<em>/
function _mapapi_load($map){
if($mapapi_limits_query = db_query("SELECT limit_x, limit_y FROM {mapapi_definition} WHERE mid = %d", $map['mid'])) {
$mapapi_limits = db_fetch_array($mapapi_limits_query);
$limits = _mapapi_make_dimentions($map, $mapapi_limits);
}
else {
return NULL;
}
$query_args = array();
$query = "SELECT * FROM {mapapi_tile_definition} WHERE ";
$query .= "coord_x >= 0 AND " ;
$query .= "coord_x <= %d AND "; $query_args[] = $mapapi_limits['limit_x'];
$query .= "coord_x >= %d AND "; $query_args[] = $limit['x']['low'];
$query .= "coord_x <= %d AND "; $query_args[] = $limits['x']['high'];
$query .= "coord_y >= 0 AND " ;
$query .= "coord_y <= %d AND "; $query_args[] = $mapapi_limits['limit_y'];
$query .= "coord_y >= %d AND "; $query_args[] = $limits['y']['low'];
$query .= "coord_y <= %d AND "; $query_args[] = $limits['y']['high'];
$query .= "mid = %d"; $query_args[] = $map['mid'];
if($result = db_query($query, $query_args)) {
$selection = array('dimentions' => $limits);
while($row = db_fetch_array($result)){
$selection[$row['coord_x']][$row['coord_y']] = $row;
unset($selection[$row['coord_x']][$row['coord_y']]['coord_y']);
unset($selection[$row['coord_x']][$row['coord_y']]['coord_x']);
}
return $selection;
}
else {
return array();
}
}
/</em>
* Figure out dimentions of a map, around the x and y.
*/
function _mapapi_make_dimentions($map, $limits) {
//determine number of tiles to go to each direction away from the center
//(up and down should be equal length as well as left and right should be equal)
$x_spacer = floor($map['length_x'] / 2);
$y_spacer = floor($map['length_y'] / 2);
//determine x boundaries
$x_low = $map['x'] - $x_spacer;
$x_high = $map['x'] + $x_spacer;
//determine y boundaries
$y_low = $map['y'] - $y_spacer;
$y_high = $map['y'] + $y_spacer;
if($x_low < 0){//fix if $x_low < 0
$x_high = $x_high - $x_low;
$x_low = 0;
}
if($y_low < 0){//fix if $y_low < 0
$y_high = $y_high - $y_low;
$y_low = 0;
}
if($x_high > $limits['limit_x']){ // fix if x is higher than our upper boundary
$x_low = $x_low - ($x_high - $limits['limit_x']);
$x_high = $limits['limit_x'];
}
if($y_high > $limits['limit_y']){//fix if y is higher than our upper boundary
$y_low = $y_low - ($y_high - $limits['limit_y']);
$y_high = $limits['limit_y'];
}
$dimentions = array();
$dimentions['x'] = array('low' => $x_low , 'high' => $x_high);
$dimentions['y'] = array('low' => $y_low , 'high' => $y_high);
return $dimentions;
}
function mapapi_save($type, $data) {
if(function_exists("mapapi_$type"."_save")) {
call_user_func("mapapi_$type"."_save", $data);
}
else {
_mapapi_save($type, $data);
}
}
function _mapapi_save($type, $data) {
$types = array(
"tile" => array('table' => '{mapapi_tile_definition}',
'id_type' => 'tid',
'make_new_id' => TRUE),
"tile_data" => array('table' => '{mapapi_tile_content}',
'id_type' => 'tid',
'make_new_id' => FALSE),
"map" => array('table' => '{mapapi_map_definition}',
'id_type' => 'mid',
'make_new_id' => TRUE),
"default" => array('table' => '{'. $data['table'] .'}',
'id_type' => $data['id_type'],
'make_new_id' => (isset($data['make_new_id'])? 'make_new_id' : TRUE)),
);
if(isset($types[$type])) {
_mapapi_save_execute($types[$type], $data);
}
else {
unset($data['table']);
unset($data['id_type']);
unset($data['make_new_id']);
_mapapi_save_execute($types['default'], $data);
}
}
function _mapapi_save_execute($options, $data) {
if($options['make_new_id'] == TRUE) {
$data[$options['id_type']] = db_next_id($options['table']);
}
$query = "INSERT INTO `{$options['table']}` (". implode(", ", array_keys($data)) .") VALUES (". implode(", ", $data) .")";
// dpr($query);
db_query($query);
//INSERT INTO {mapapi_tile_definition} (mid, coord_x, coord_y, description, tid) VALUES (1, 5, 6, this is a cool tile, 6)
}
?>
map.module
http://game.dev.dmitrizone.com/pastebin/index.php?show=38
<?php
//current putpose of this module is to print_r() test the mapapi.
function map_menu($may_cache){
if(!$may_cache){
$items[] = array(
'path' => 'testmap',
'title' => t('test map'),
'callback' => '_map_printr',
'access' => user_access('access content'),
'type' => MENU_NORMAL_ITEM
);
$items[] = array(
'path' => 'emtermapdata',
'title' => t('Fill in Map data'),
'callback' => '_map_populate',
'access' => user_access('access content'),
'type' => MENU_NORMAL_ITEM
);
}
return $items;
}
function _map_populate(){
db_query("INSERT INTO <code>{mapapi_definition}</code> (<code>mid</code>, <code>name</code>, <code>limit_x</code>, <code>limit_y</code>) VALUES (1, 'first map', 20, 30)");
db_query("INSERT INTO <code>{mapapi_tile_definition}</code> (<code>tid</code>, <code>mid</code>, <code>coord_x</code>, <code>coord_y</code>, <code>description</code>) VALUES
(1, 1, 5, 5, NULL),
(2, 1, 5, 6, NULL),
(3, 1, 6, 5, NULL),
(4, 1, 6, 6, NULL),
(5, 1, 22, 22, NULL)");
drupal_goto("testmap");
}
function _map_printr(){
$maps = array();
$maps['single_tile'] = array(
'mid' => 1,
'x' => 5,
'y' => 5,
'length_x' => 1,
'length_y' => 1,
'tile_content' => true
);
$maps['multi_tile'] = array(
'mid' => 1,
'x' => 5, //try negative values... you will see them adjust and always return
'y' => 5, //the correct box bounds (defined by length_x and length_y)
'length_x' => 10,
'length_y' => 9, // doesnt have to be exactly square!
'tile_content' => true // true/false on whether to load tile content or not.
);
$data = array("mid" => 1,
"coord_x" => 5,
"coord_y" => 6,
"description" => "this is a cool tile"
);
$output .= print_r(mapapi_save("tile", $data), 1);
$output .= print_r(mapapi_load($maps), 1);
return "<pre>". $output ."</pre>";
}
?>
------------------
Sometimes interesting things appears on http://litwol.com
Few comments on
Few comments on mapapi.module save code
1) we must not use the implode() method to construct queries. this is prone to errors unless (this goes to 2)...
2) all data passed to the query must be escaped. all array keys must be wraped with ` and `, all other fields must be wrapped with ' and '. however i really dont want to trust and expect that every call made to this function is done 'correctly'. so lets not give any one enough rope to hang themselves and escape all data as it comes...
3) _mapapi_save_execute doesnt do much other than save tile description. as per our conversation, the field 'description' is actually more than just text field. it supposed to be a serialized array of what ever describes the tile: tile name, tile picture, etc ...
4)_mapapi_save_execute needs to be renamed to something more meaningful that implies 'new tile creation', in it's current state it is not fit to do tile updates.
overall this seems like the 'save' functionality gears towards taking over the responsibility of other modules to perform their own saving logic, and away from the original purpose of keeping mapapi functionality as limited as possible to loading and saving just the tile content.
lets meet tomorrow to discuss what exactly is it that we are saving and the overall logic.
------------------
Sometimes interesting things appears on http://litwol.com