$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);
}
}