files as $keyF => $file) { foreach ($file as $keyE => $element) { if ($element[0] == $object) { return array($keyF, $keyE); } } } return false; } public function nbObjectInFile($object, $type = null) { $c = 0; if (!isset($object)) { foreach ($this->files as $file) { $c += count($file); } } else { if (!isset($type) || $type) { foreach ($this->files as $file) { $c += count(array_keys($file, array($object, true))); } } if (!isset($type) || !$type) { foreach ($this->files as $file) { $c += count(array_keys($file, array($object, false))); } } } return $c; } public function addObjet($object, $nombre, surface $planete) { //On vérifie que l'on ne dépasse pas la taille maximale de la file if (!$this->checkMaxSize($planete)) { throw new ExceptionHB(1, 1); } //Validation des conditions de construction if (!dBatiments::needed($object, $planete)) { throw new ExceptionHB(1, 2); } //On vérifie qu'il n'y ait pas une demande de démolition du même bâtiment if ($this->nbObjectInFile($object, true) >= 1) { throw new ExceptionHB(1, 7); } //On vérifie qu'il reste suffisamment de place sur la planète if ($planete->casesRest <= 0 || $planete->casesRest <= $this->nbObjectInFile(null)) { throw new ExceptionHB(1, 0); } //Calcul du prochain niveau du batiment $nextLvl = $planete->batiments[$object] + $this->nbObjectInFile($object, false) + 1; //On recherche le lieu ayant le moins de construction en cours $lieu = $this->findShorter(); //On rafraîchit le temps de la file si aucun objet n'est en file d'attente $this->refreshTime($lieu); //On vérifie qu'il y ait assez de ressources sur la planète if ($planete->checkAndRetireRessources(dBatiments::metal($object, $nextLvl, $planete), dBatiments::cristal($object, $nextLvl, $planete), dBatiments::hydrogene($object, $nextLvl, $planete), dBatiments::credits($object, $nextLvl, $planete))) { $this->files[$lieu][] = array($object, false); $planete->addModif("file_bat"); return true; } else { throw new ExceptionHB(1, 4); } } public function addDemolition($object, $nombre, surface $planete) { //On vérifie que l'on ne dépasse pas la taille maximale de la file if (!$this->checkMaxSize($planete)) { throw new ExceptionHB(1, 1); } //On vérifie que le niveau actuel du batiment ne soit non nul if ($planete->batiments[$object] <= $this->nbObjectInFile($object, false)) { throw new ExceptionHB(1, 6); } //On vérifie qu'il n'y ait pas une demande de construction du même bâtiment if ($this->nbObjectInFile($object, false) >= 1) { throw new ExceptionHB(1, 7); } //On recherche le lieu ayant le moins de construction en cours $lieu = $this->findShorter(); //On rafraîchit le temps de la file si aucun objet n'est en file d'attente $this->refreshTime($lieu); $this->files[$lieu][] = array($object, true); $planete->addModif("file_bat"); return true; } public function delObjet($id, $nombre, $lieu, surface $planete) { //Vérification de l'existance de l'objet en file d'attente if (empty($this->files[$lieu][$id])) { throw new ExceptionHB(1, 5); } //On récupère le type de batiment $object = $this->files[$lieu][$id][0]; //On gère les démolition //@todo -cFileBatiments Est-ce vraiment utile de calculer le niveau du batiment en cas de démolition ? if ($this->files[$lieu][$id][1]) { $lvlAnnule = $planete->batiments[$object] - $this->nbObjectInFile($object, true) + 1; } else { $lvlAnnule = $planete->batiments[$object] + $this->nbObjectInFile($object, false); } //On met à jour le temps si on vient d'annuler le premier batiment en lice if ($id == $this->findFirstKey($lieu)) { $this->times[$lieu] = time(); } $planete->addModif("file_bat"); if (!$this->files[$lieu][$id][1]) { //On redonne 60% des ressources au joueur si c'est la première construction dans la file d'attente if ($id == 0) { $planete->addRessources(dBatiments::metal($object, $lvlAnnule, $planete)*0.6, dBatiments::cristal($object, $lvlAnnule, $planete)*0.6, dBatiments::hydrogene($object, $lvlAnnule, $planete)*0.6, dBatiments::credits($object, $lvlAnnule, $planete)*0.6); } else { $planete->addRessources(dBatiments::metal($object, $lvlAnnule, $planete), dBatiments::cristal($object, $lvlAnnule, $planete), dBatiments::hydrogene($object, $lvlAnnule, $planete), dBatiments::credits($object, $lvlAnnule, $planete)); } } //Effacement de la file unset($this->files[$lieu][$id]); return true; } public function ready(SURFACE $planete) { //On parcourt la liste des lieux de construction foreach ($this->files as $keyF => $file) { //On vérifie qu'il y a bien des éléments dans cette file d'attente if (count($file) == 0) { continue; } //On parcourt la file foreach ($file as $keyE => $element) { $tempsEcoule = time() - $this->times[$keyF]; //On gère les démolitions if ($element[1]) { //On récupère le niveau actuel du batiment $lvl = $planete->batiments[$element[0]]; //On calcul le temps de démolition nécessaire (60% du niveau actuel) $tempsNecessaire = dBatiments::temps($element[0], $lvl, $planete, true); if ($tempsEcoule >= $tempsNecessaire) { $metal = dBatiments::metal($element[0], $lvl, $planete); $cristal = dBatiments::cristal($element[0], $lvl, $planete); $hydrogene = dBatiments::hydrogene($element[0], $lvl, $planete); //On redonne 70% des ressources du batiment au joueur $planete->addRessources($metal*0.7, $cristal*0.7, $hydrogene*0.7); //On retire un niveau au batiment $planete->batiments[$element[0]]--; //On efface l'entrée de la file et on met à jour le temps de la file unset($this->files[$keyF][$keyE]); $this->times[$keyF] += $tempsNecessaire; //On demande la mise à jour des champs modifiés $planete->addModif(array("batiments", $element[0])); $planete->addModif("file_bat"); //On retire les points $planete->addPoints($metal, $cristal, $hydrogene, 0, true); unset($metal, $cristal, $hydrogene); } //Si le temps écoulé n'est pas suffisant pour ce batiment, on annule tous les suivants else { break; } } else { //Cas de la construction //Récupération du niveau du batiment $lvl = $planete->batiments[$element[0]] + 1; $tempsNecessaire = dBatiments::temps($element[0], $lvl, $planete); //Si le temps écoulé est suffisant if ($tempsEcoule >= $tempsNecessaire) { //On ajoute un niveau au batiment $planete->batiments[$element[0]]++; //On efface l'entrée de la file et on met à jour le temps de la file unset($this->files[$keyF][$keyE]); $this->times[$keyF] += $tempsNecessaire; //On demande la mise à jour des champs modifiés $planete->addModif(array("batiments", $element[0])); $planete->addModif("file_bat"); //On ajoute les points $planete->addPoints(dBatiments::metal($element[0], $planete->batiments[$element[0]], $planete), dBatiments::cristal($element[0], $planete->batiments[$element[0]], $planete), dBatiments::hydrogene($element[0], $planete->batiments[$element[0]], $planete)); } //Si le temps écoulé n'est pas suffisant pour ce batiment, on annule tous les suivants else { break; } } } } } public function printFile(SURFACE $planete, $lieu = null) { $out = array(); foreach ($this->files as $keyF => $file) { if (isset($lieu) && $lieu != $keyF) { continue; } $prems = true; foreach ($file as $keyE => $element) { if ($element[1]) { //Cas d'une démolition $temps = dBatiments::temps($element[0], $planete->batiments[$element[0]], $planete, true); if ($prems) { $temps -= time() - $this->times[$keyF]; } $out[$keyF][$keyE] = array($element[0], $element[1], ceil($temps), $prems); } else { //Cas d'une construction $temps = dBatiments::temps($element[0], $planete->batiments[$element[0]]+1, $planete); if ($prems) { $temps -= time() - $this->times[$keyF]; } $out[$keyF][$keyE] = array($element[0], $element[1], ceil($temps), $prems); } $prems = false; } } return $out; } }