Exemple #1
0
 /**
  * Calculate time when job would be completed, and expend production queues.
  * @global Product $ChronoBoost
  * @global Product $Nexus
  * @global Product $Warpgate
  * @param Job $job
  * @param float $time
  * @param bool $tentative If true, chronoboosts will not be logged. Use this
  * to perform dry runs of the queue use.
  * @return array(int,array) First element is time job would be completed,
  * second element is list of production queues used.
  */
 public function queue($job, $time = null, $tentative = false)
 {
     global $ChronoBoost, $Nexus, $Warpgate;
     if ($this->debug) {
         tracemsg("Timeline::queue(" . $job . ", " . simple_time($time) . ", " . ($tentative ? "true" : "false") . ")");
     }
     if ($time === null) {
         $time = $job->timeStarted;
     }
     if ($this->debug) {
         tracemsg("Timeline::queue(), job starts at " . simple_time($time));
     }
     // choose queues
     list($queueTypesExpended, $expendAll) = $job->queueTypesExpended();
     if ($queueTypesExpended !== null) {
         $queues = $this->queues->choose($time, $queueTypesExpended, $expendAll, $job->tagsRequired);
     }
     // build time
     $buildTime = $job->duration();
     if (isset($queues) && count($queues) == 1 && $queues[0]->structure == $Warpgate) {
         $buildTime -= WARPGATE_QUEUE_REDUCTION;
     }
     // previous chrono boost overlaps this job
     if (isset($queues) && count($queues) == 1 && $queues[0]->chronoboosted + $ChronoBoost->timeCost > $time) {
         $boostTime = $queues[0]->chronoboosted;
         // calculate overlap with job
         $overlapStart = max($boostTime, $time);
         $overlapEnd = min($boostTime + $ChronoBoost->timeCost * CHRONO_BOOST_RATE, $time + $buildTime);
         $overlap = max(0, $overlapEnd - $overlapStart);
         // reduce build time
         $buildTime -= $overlap - $overlap / CHRONO_BOOST_RATE;
     }
     // chrono boosts
     if (isset($queues) && count($queues) == 1) {
         // process chronoboosts in an alternate reality
         $spellcasters = clone $this->spellcasters;
         for ($i = 0; $i < $job->chronoboost; $i++) {
             // start time of chrono boost
             $boostTime = max($queues[0]->chronoboosted + $ChronoBoost->timeCost, $spellcasters->when($Nexus, $ChronoBoost->energyCost));
             if ($boostTime < $time + $buildTime) {
                 $boostTime = max($boostTime, $time + CHRONO_BOOST_HUMAN_DELAY);
                 // calculate overlap with job
                 $overlapStart = max($boostTime, $time);
                 $overlapEnd = min($boostTime + $ChronoBoost->timeCost * CHRONO_BOOST_RATE, $time + $buildTime);
                 $overlap = max(0, $overlapEnd - $overlapStart);
                 // reduce build time
                 $buildTime -= $overlap - $overlap / CHRONO_BOOST_RATE;
                 // expend spellcasters
                 $spellcasters->update($boostTime);
                 $spellcasters->expend($Nexus, $ChronoBoost->energyCost, $boostTime);
                 // log chronoboost & reserve energy
                 if (!$tentative) {
                     $this->addCheckpoint(new Checkpoint("<em>CB: " . $job->description() . "</em>", $boostTime, $boostTime + $ChronoBoost->timeCost));
                     $spellcaster = $this->spellcasters->reserve($Nexus, $ChronoBoost->energyCost, $boostTime);
                 }
                 // queue is now chrono boosted
                 $queues[0]->chronoboosted = $boostTime;
             }
         }
     }
     // build complete
     $completed = $time + $buildTime;
     // queue is now unavailable
     if (isset($queues)) {
         foreach ($queues as $queue) {
             $queue->busy($time, $completed, $job->busiesQueues());
         }
         return array($completed, $queues);
     } else {
         return array($completed, null);
     }
 }