0 && $posx + $GLOBALS->map->grid->view->x > $GLOBALS->map->grid->x) $posx = $GLOBALS->map->grid->x - $GLOBALS->map->grid->view->x; elseif ($posx < 0 && $posx - $GLOBALS->map->grid->view->x < -($GLOBALS->map->grid->x)) $posx = -($GLOBALS->map->grid->x) + $GLOBALS->map->grid->view->x; if ($posy > 0 && $posy + $GLOBALS->map->grid->view->y > $GLOBALS->map->grid->y) $posy = $GLOBALS->map->grid->y - $GLOBALS->map->grid->view->y; elseif ($posy < 0 && $posy - $GLOBALS->map->grid->view->y < -($GLOBALS->map->grid->y)) $posy = -($GLOBALS->map->grid->y) + $GLOBALS->map->grid->view->y; $return = Kernel_Api::joinScript(Kernel_Api::Plugins, "tooltips").Kernel_Api::joinScript(Kernel_Api::AppGame, "map"); $return .= ""; $return .= self::event_html(self::event_select($posx, $posy), $posx, $posy); if (isset($post)) exit($return); return $return; } /** * Récupérer les actions possibles lors d'un clic sur une case de la map. * @param POST $x * @param POST $y */ public function action() { autoload_sql("map"); $_SESSION["map"] = (object) array( "cursor" => (object) array( "x" => (int) post("x"), "y" => (int) post("y") )); $html = Kernel_Api::joinScript(Kernel_Api::AppGame, "map.action"); $case = self::event_select_by_coord($_SESSION["map"]->cursor->x, $_SESSION["map"]->cursor->y); if ($case != array()) { if (self::is_current($case->vid)) $html .= Game_Build::propose($case->bid); else { } } else { echo "
Oups, aucune action possible
"; } echo $html; } /** * Générer aléatoirement des positions pour les villages (SANS COLLISIONS) * - On calcul d'abord les coordonnées de base en respectant les marges imposées par la configuration * - On boucle toutes les positions en générant des variantes de point * - On parcours tous les points généré * - On insert dans la base de données * - On créé le fichier XML associé contenant les zones de constructions ayant pour origine ce point */ public static function event_create_point() { $startx = $tmpx = -($GLOBALS->map->grid->x) + $GLOBALS->map->create->fixed; $starty = $tmpy = -($GLOBALS->map->grid->y) + $GLOBALS->map->create->fixed; $endx = $GLOBALS->map->grid->x - $GLOBALS->map->create->fixed; $endy = $GLOBALS->map->grid->y - $GLOBALS->map->create->fixed; $map_points = array(); while (true) { if ($tmpx > $endx) { if (($tmpy += $GLOBALS->map->create->fixed) > $endy) break; $tmpx = $startx; continue; } $map_points[$tmpx + mt_rand(-(floor($GLOBALS->map->create->rand / 2)), floor($GLOBALS->map->create->rand / 2))][$tmpy + mt_rand(-(floor($GLOBALS->map->create->rand / 2)), floor($GLOBALS->map->create->rand / 2))] = ""; $tmpx += $GLOBALS->map->create->fixed; } foreach ($map_points as $x => &$value) foreach (array_keys($value) as $y) { Kernel_Sql::get()->exec(sprintf(sql_game_map_point_insert, $x, $y)); self::event_create_area($x, $y); } } /** * Compiler le fichier XML d'un village et l'insérer dans la base de données * - On charge le fichier XML contenant les propriétés du village aux coordonnées $x et $y. * - On prépare la requête de suppression (on supprime tous les éléments déjà en place) * - On insert les nouveaux éléments du village. * @param $x, $y, $vid, $mid */ public static function event_parse_area($x, $y, $vid) { autoload_sql("map"); $mapfile = New SimpleXMLElement(file_get_contents(sprintf("%s%d,%d.xml", $GLOBALS->dir->xml->map, $x, $y))); $sql_delete = $sql_insert = ""; foreach($mapfile->case as $case) { $sql_delete .= " (posx = {$case['x']} && posy = {$case['y']}) ||"; $sql_insert .= " ({$case['x']}, {$case['y']}, ". (int) $vid .", '{$case}'),"; } $request = Kernel_Sql::get()->exec(sprintf(sql_game_map_case_delete, (int) $vid, substr($sql_delete, 0, -2)) .";". sprintf(sql_game_map_case_insert, "VALUES". substr($sql_insert, 0, -1))); } /** * Génère un décor aléatoire sur la map. * @global array $config */ public static function event_rand(){ autoload_cfg("map"); autoload_sql("map"); autoload_models("map"); $x = -($GLOBALS->map->grid->x); $y = -($GLOBALS->map->grid->y); $end_x = $GLOBALS->map->grid->x; $end_y = ($GLOBALS->map->grid->y); while (true) { $rand = mt_rand(1, 30); if (isset($GLOBALS->map->rand[$rand])) Kernel_Sql::get()->exec(sprintf(sql_game_map_rand_insert, $x, $y, $GLOBALS->map->rand[$rand][array_rand($GLOBALS->map->rand[$rand])])); if ($x === $end_x && $y === $end_y) break; if ($x === $end_x) { $x = -($GLOBALS->map->grid->x); ++$y; } ++$x; } } /** * Compiler et assembler tous les éléments de la map. * On vérifie qu'un élément existe * - Si cet élément est celui du joueur * - On vérifie si c'est un bâtiment * - Si c'est la muraille et que le niveau est à 0, on ne l'affiche pas * - Si c'est un élément naturel, on propose de construire le bâtiment adéquat * - Si c'est un bâtiment, on affiche son niveau * - On propose de construire un bâtiment * - Si cela appartient à un autre joueur * - * - Sinon c'est un élément naturel * - On détermine l'élément et on affiche les informations adéquates * @param $elements * @params $posx, $posy */ protected static function event_html($elements, $posx, $posy){ $return = ''; $map = array(); $villages = &session("villages"); $buildings = &session("buildings"); $startx = $temp_x = $posx - $GLOBALS->map->grid->view->x; $starty = $temp_y = $posy + $GLOBALS->map->grid->view->y; $endy = $posy - $GLOBALS->map->grid->view->y; $endx = $posx + $GLOBALS->map->grid->view->x; while(true) { $content = ""; $infos = $GLOBALS->lang->map->text->empty; if (isset($elements[$temp_x][$temp_y])) { $element = &$elements[$temp_x][$temp_y]; if (self::is_current($element->vid)) { if ($element->bid !== "") { if (self::is_wall($element->bid)) { if (!$buildings->wall) { $content = ""; $infos = $GLOBALS->lang->map->text->wall; } else { $content = self::case_img($element->bid); $infos = sprintf($GLOBALS->lang->map->text->building, $GLOBALS->buildings->wall->name, $buildings->wall, "wall"); if ($GLOBALS->game->level > $buildings->wall) $infos .= $GLOBALS->lang->map->text->upgrade; else $infos .= $GLOBALS->lang->map->text->limit; } } else { if (self::is_trees($element->bid)) if ($buildings->wood > 0) $infos = $GLOBALS->lang->map->text->build; else $infos = $GLOBALS->lang->map->build->wood; elseif(self::is_flowers($element->bid)) $infos = $GLOBALS->lang->map->text->build; elseif (self::is_rocks($element->bid)) $infos = $GLOBALS->lang->map->build->stone; elseif (self::is_rocki($element->bid)) $infos = $GLOBALS->lang->map->text->iron; else { $infos = sprintf($GLOBALS->lang->map->text->building, $GLOBALS->buildings->{$element->bid}->name, $buildings->{$element->bid}, $element->bid); if ($GLOBALS->game->level > $buildings->{$element->bid}) $infos .= $GLOBALS->lang->map->text->upgrade; else $infos .= $GLOBALS->lang->map->text->limit; } $content = self::case_img($element->bid); } } else { $infos = $GLOBALS->lang->map->text->build; } } elseif ($element->vid > 0) { if ($element->bid !== "") $content = self::case_img($element->bid); } else { if (self::is_trees($element->bid)) $infos = $GLOBALS->lang->map->text->trees; elseif (self::is_flowers($element->bid)) $infos = $GLOBALS->lang->map->text->flowers; elseif(self::is_rock($element->bid)) $infos = $GLOBALS->lang->map->text->rock; $content = self::case_img($element->bid); } } $return .= sprintf($GLOBALS->models->map->case, $content, $temp_x, $temp_y, $infos); if ($temp_x === $endx && $temp_y === $endy) break; if ($temp_x === $endx) { $temp_x = $startx; --$temp_y; continue; } ++$temp_x; } return $return; } /** * Sélectionner les éléments de la MAP * - Récupération des éléments entre plusieurs positions... * - On boucle chaque élément dans un tableau à deux dimensions rangés par X et Y * @params integer $posx, $posy * @return object */ protected static function event_select($posx, $posy){ $request = Kernel_Sql::get()->prepare(sql_game_map_select); $request->execute(array($posx - $GLOBALS->map->grid->view->x, $posx + $GLOBALS->map->grid->view->x, $posy - $GLOBALS->map->grid->view->y, $posy + $GLOBALS->map->grid->view->y)); $map = array(); while($data = $request->fetch(PDO::FETCH_OBJ)) $map[$data->posx][$data->posy] = $data; return $map; } /** * Récupérer les informations d'une coordonnées. * @params $x, $y * @return */ public static function event_select_by_coord($x, $y){ $request = Kernel_Sql::get()->prepare(sql_game_map_coord_select); $request->execute(array($x, $y)); return $request->fetch(PDO::FETCH_OBJ); } /** * Calculer les coordonnées des zones constructibles * - On calcul l'ensemble des coordonnées du village * - Création de la grille + Mise en place des positions prédéfinies de la muraille * - On met en place le Donjon sur la nouvelle grille * - Récupération des Z.C(**Zones Constructibles**) sur la grille * - On empute le Donjon de la Z.C * - On détermine le nombre d'élément à afficher * - On injecte aléatoirement les éléments à afficher (sans doublons) * - Création du fichier XML contenant toutes les propiétés du village * @params integer $x, $y */ protected static function event_create_area($x, $y){ $area_mx = mt_rand(0, $GLOBALS->map->area->merge->x); $area_my = mt_rand(0, $GLOBALS->map->area->merge->y); $start_x = $temp_x = $x - $GLOBALS->map->area->x - $area_mx; $end_x = $x + $GLOBALS->map->area->x + $area_mx; $start_y = $temp_y = $y - $GLOBALS->map->area->y - $area_my; $end_y = $y + $GLOBALS->map->area->y + $area_my; $map_area = $area = array(); while(true) { if ($temp_y === $start_y && $temp_x > $start_x && $temp_x < $end_x) $content = "walld"; elseif ($temp_y === $end_y && $temp_x > $start_x && $temp_x < $end_x) $content = "wallu"; elseif ($temp_x === $start_x && $temp_y > $start_y && $temp_y < $end_y) $content = "walll"; elseif ($temp_x === $end_x && $temp_y > $start_y && $temp_y < $end_y) $content = "wallr"; else $content = ""; $map_area[$temp_x][$temp_y] = $content; if ($temp_x == $end_x && $temp_y == $end_y) break; if ($temp_x === $end_x) { $temp_x = $start_x; ++$temp_y; } else ++$temp_x; } $map_area[$x][$y] = $GLOBALS->map->default; $map_area[$start_x][$start_y] = "walltdl"; $map_area[$start_x][$end_y] = "walltul"; $map_area[$end_x][$start_y] = "walltdr"; $map_area[$end_x][$end_y] = "walltur"; foreach(array_slice($map_area, 1, -1, true) as $tmpx => $tmpy) $area[$tmpx] = array_slice($tmpy, 1, -1, true); unset($area[$x][$y]); foreach(array_keys($GLOBALS->map->elements) as $element) for($i = 0; $i < $GLOBALS->map->elements[$element]; ++$i) { $tmpx = array_rand($area); $tmpy = array_rand($area[$tmpx]); $map_area[$tmpx][$tmpy] = $GLOBALS->map->element->{$element}[array_rand($GLOBALS->map->element->{$element})]; unset($area[$tmpx][$tmpy]); } $mapfile = New Kernel_File($GLOBALS->dir->xml->map, "{$x},{$y}.xml", true); $mapfile->add($GLOBALS->models->map->xml->head) ->add($GLOBALS->models->map->xml->begin); foreach($map_area as $x => &$value) foreach($value as $y => &$element) $mapfile->add(sprintf($GLOBALS->models->map->xml->case, $x, $y, $element)); $mapfile->add($GLOBALS->models->map->xml->end) ->end(false); } /** * Retourner l'image associé à une case * @params string $file * @return string */ protected static function case_img($file){ return sprintf('', $file); } /** * Déterminer si l'élément appartient au joueur. * @param integer $vid * @return boolean */ protected function is_current($vid){ return ($_SESSION["villages"]["current"]->vid === $vid); } /** * Déterminer si l'élément est un rocher * @param $bid * @return */ public function is_rock($bid = ""){ $bid = substr($bid, 0, 4); return ($bid === "rock"); } /** * Déterminer si l'élément est un mur * @param $bid * @return */ public function is_wall($bid = ""){ return (substr($bid, 0, 4) === "wall"); } /** * Déterminer si l'élément est un arbre * @param $bid * @return */ public function is_trees($bid = ""){ return (substr($bid, 0, 5) === "trees"); } /** * Déterminer si l'élément est un buisson/fleur * @param $bid * @return */ public function is_flowers($bid = ""){ return (substr($bid, 0, 7) === "flowers"); } /** * Déterminer si l'élément est un minerai * @param $bid * @return */ public function is_rocks($bid = ""){ return ($bid === "rock_stone"); } /** * Déterminer si l'élément est un rocher producteur de pierre * @param $bid * @return */ public function is_rocki($bid = ""){ return ($bid === "rock_iron"); } } Couplé avec un système de construction: vid); while($data = $request->fetch(PDO::FETCH_OBJ)) $construct[$data->building] = $data; } else $construct = &session("construct"); foreach($construct as $bid => &$data) { if (time() >= $data->end) { if (self::event_select_by_cid($data->cid)) { try { Kernel_Sql::get()->beginTransaction(); if (!Kernel_Sql::get()->exec(sprintf(sql_game_building_up, (string) $bid, (int) $village["current"]->vid)) || !Kernel_Sql::get()->exec(sprintf(sql_game_construct_delete, (int) $data->cid))) Throw New PDOException(); Kernel_Sql::get()->commit(); ++$_SESSION["buildings"]->{$bid}; } Catch(PDOException $e) { Kernel_Sql::get()->rollback(); } Game_Event::add(sprintf($GLOBALS->lang->build->success->construct, $GLOBALS->buildings->{$data->building}->name, $buildings->{$data->building})); } unset($construct[$bid]); } else $construct[$bid]->pourcent = floor((($GLOBALS->config->time - $data->start) / ($data->end - $data->start)) * 100); } session_create(array("construct" => $construct)); foreach($construct as $build) $return .= sprintf($GLOBALS->models->build->list, $build->building, $GLOBALS->buildings->{$build->building}->name, $build->pourcent, time_rest($build->end - $GLOBALS->config->time), '%'); if (!$refresh) exit($return); } /** * Game_Build::event_add() * Procédure d'ajout d'un bâtiment en construction * - On détecte si le bâtiment est un leure (un faux) * - On détecte si c'est un vrai bâtiment, si niveau 0 c'est qu'il est en construction * - On détecte si il est déjà au niveau maximum * - Si il a assez de ressources * - On démarre une transaction * - On modifie son nombre de ressources * - On inclus la construction du batiments * - Si tous va bien, on met en commit * - Sinon on effectue un rollback * @global $config * @return */ public function add(){ autoload_lang("build"); autoload_cfg("buildings"); $x = (int) post("x"); $y = (int) post("y"); $bid = (string) post("bid"); $buildings = &session("buildings"); if (!self::can_be_build()) exit($GLOBALS->lang->build->text->max); if (!isset($GLOBALS->buildings->{$bid})) exit($GLOBALS->lang->build->error->nfound); if (!$buildings->{$bid} && self::is_current_construct($bid)) exit($GLOBALS->lang->build->error->already); if ($buildings->{$bid} === $GLOBALS->game->level) exit($GLOBALS->lang->build->error->level); if (self::is_current_construct($bid)) exit($GLOBALS->lang->build->error->current); autoload_sql("construct", "map", "resources"); $case = Game_Map::event_select_by_coord($x, $y); if (!isset($case->vid) || $case->vid !== $_SESSION["villages"]["current"]->vid) exit($GLOBALS->lang->build->error->area); if ($case->bid !== $bid) { if ($bid !== "wall" && $buildings->{$bid}) exit($GLOBALS->lang->build->error->balready); elseif(Game_map::is_trees($case->bid)) { if ($buildings->wood && $bid === "wood") exit($GLOBALS->lang->build->error->balready); elseif (!$buildings->wood && $bid !== "wood") exit($GLOBALS->lang->build->error->breserved); } elseif(Game_Map::is_rocki($case->bid) && $bid !== "iron") exit($GLOBALS->lang->build->error->breserved); elseif(Game_Map::is_rocks($case->bid) && $bid !== "stone") exit($GLOBALS->lang->build->error->breserved); elseif($case->bid === "" && ($bid === "wood" || $bid === "stone" || $bid === "iron")) exit($GLOBALS->lang->build->error->area_nc); } if (!self::is_buyable($prices = Game_Building::price_by_bid($bid), $resources = Game_Resource::event_select(array(Kernel_member::get()->id, $vid = $_SESSION["villages"]["current"]->vid)))) exit($GLOBALS->lang->build->error->resources); try { Kernel_Sql::get()->beginTransaction(); if (Game_Map::is_trees($case->bid) || Game_Map::is_rocki($case->bid) || Game_Map::is_rocks($case->bid) || Game_Map::is_flowers($case->bid) || $case->bid === "") { Kernel_Sql::get()->exec(sprintf(sql_game_map_case_delete, $vid, sprintf("posx = %d AND posy = %d", $x, $y))); Kernel_Sql::get()->exec(sprintf(sql_game_map_case_insert, sprintf("VALUES({$x}, {$y}, {$vid}, '{$bid}')"))); } if (!Game_Resource::add($vid, -($prices["food"]), -($prices["wood"]), -($prices["stone"]), -($prices["iron"])) || !Kernel_Sql::get()->exec(sprintf(sql_game_construct_insert, $vid, $bid, $GLOBALS->config->time, $GLOBALS->config->time + $prices["time"]))) Throw New PDOException(); Game_Event::add(sprintf($GLOBALS->lang->build->success->add, $GLOBALS->buildings->{$bid}->name)); Kernel_Sql::get()->commit(); $build = New Game_Build(); $build->select(true); } catch(PDOException $e){ Kernel_Sql::get()->rollback(); exit($GLOBALS->lang->build->error->intern); } } /** * Proposer la construction d'un bâtiment/de plusieurs bâtiments * - On récupère les informations sur les bâtiments * - Dans le cas où c'est un élément naturel, et qu'aucune construction a été effectué sur ce point, on modifie la valeur de l'élément * - Si c'est un bâtiment déjà construit, on propose de l'amélioré si il n'est pas au niveau maximum * - Si il n'y a rien sur la case, on propose une liste de bâtiment constructible * @param $bid */ public static function propose($bid = "*") { autoload_lang("build", "map"); autoload_cfg("buildings"); $buildings = &session("buildings"); $exist = true; $return = ""; if (Game_Map::is_trees($bid) && !$buildings->wood) { $bid = "wood"; $exist = false; } elseif(Game_Map::is_rocki($bid) && !$buildings->iron){ $bid = "iron"; $exist = false; } elseif(Game_Map::is_rocks($bid) && !$buildings->stone){ $bid = "stone"; $exist = false; } elseif(Game_Map::is_wall($bid)){ $bid = "wall"; } elseif(Game_Map::is_flowers($bid) || Game_Map::is_trees($bid)){ $bid = ""; $exist = false; } if ($bid != "") $return .= (($buildings->{$bid} > 0) ? $GLOBALS->lang->map->act->upgrade : $GLOBALS->lang->map->act->build) . self::create_infos(Game_Building::price_by_bid($bid), $bid, $exist); else { foreach(self::$list_all as &$build_propose) $return .= self::propose_by_require($build_propose); if ($return == "") $return .= (self::all_is_build()) ? $GLOBALS->lang->map->text->all : $GLOBALS->lang->map->text->require; $return = $GLOBALS->lang->map->act->build . $return; } return $GLOBALS->lang->map->act->start . $return . $GLOBALS->lang->map->act->end; } /** * Proposer un bâtiment sur une case vide respectant les critères requis * @param $bid */ public static function propose_by_require($bid){ if (self::is_current_construct($bid)) return; $buildings = &session("buildings"); foreach($GLOBALS->buildings->{$bid}->require AS $building => &$level) if ($buildings->{$bid} > 0 || $buildings->{$building} < $level) return; return self::create_infos(Game_Building::price_by_bid($bid), $bid, false); } /** * Détermine si tous les bâtiments on été construits */ public static function all_is_build(){ $buildings = &session("buildings"); while(list($building) = each($GLOBALS->buildings)) if (!$buildings->{$building}) return false; } /** * Sélectionner les constructions du villages courrant * @param $vid */ public static function event_select($vid){ $request = Kernel_Sql::get()->prepare(sql_game_construct_select); $request->execute(array($vid)); return $request; } /** * Vérifie si le joueur a assez de ressources pour valider une construction * @param $price * @param $resources */ public function is_buyable($price, $resources){ return ($price["wood"] <= $resources->wood && $price["stone"] <= $resources->stone && $price["iron"] <= $resources->iron && $price["food"] <= $resources->food); } /** * Vérifie si le bâtiment se trouve dans la liste de construction * @param $bid */ public static function is_current_construct($bid){ return isset($_SESSION["construct"][$bid]); } /** * Créer la bulle d'information pour les constructions * @param $infos * @param $bid */ public static function create_infos($infos, $bid, $exist = false){ autoload_models("build", "map"); autoload_lang("build"); $buildings = &session("buildings"); $construct = Game_Build::can_be_build(); $status = ($construct && $infos["buyable"]) ? "successS" : "errorS"; $button = (!self::is_current_construct($bid)) ? (($infos["buyable"] === true) ? (($construct === true) ? (($exist === false) ? sprintf($GLOBALS->lang->build->text->can, $bid) : sprintf($GLOBALS->lang->build->text->upgrade, $bid)) : $GLOBALS->lang->build->text->limit) : $GLOBALS->lang->build->text->cant) : $GLOBALS->lang->build->text->current; return sprintf($GLOBALS->models->build->item, $bid, $status, ($buildings->{$bid} < $GLOBALS->game->level) ? self::create_table($infos) . $button : $GLOBALS->lang->build->text->max); } /** * Création du tableau d'informations sur la construction d'un bâtiment * @param $data */ public static function create_table($data){ $resources = &session("resources"); if ($data["buyable"] === true) $color[0] = $color[1] = $color[2] = $color[3] = "lime"; else { $color[0] = ($data["food"] <= $resources->food) ? "lime" : "red"; $color[1] = ($data["wood"] <= $resources->wood) ? "lime" : "red"; $color[2] = ($data["stone"] <= $resources->stone) ? "lime" : "red"; $color[3] = ($data["iron"] <= $resources->iron) ? "lime" : "red"; } return sprintf($GLOBALS->models->map->act->build, $color[0], $data["food"], $color[1], $data["wood"], $color[2], $data["stone"], $color[3], $data["iron"], time_rest($data["time"])); } /** * Déterminer si le batiment est constructible */ public static function can_be_build(){ return (count(session("construct")) < $GLOBALS->game->construct); } /** * Récupération des informations sur une fin d'une construction. * @param $cid */ protected static function event_select_by_cid($cid){ $request = Kernel_Sql::get()->prepare(sql_game_construct_end_select); $request->execute(array($cid)); return ($request->fetch(PDO::FETCH_OBJ)->number); } }