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; } } ?>