lib = $lib; $this->game = $this->lib->game; $this->db = $this->game->db; $this->fleets = $this->game->getLib('beta5/fleet'); $this->msgs = $this->game->getLib('beta5/msg'); } public function run() { // Get Peacekeepers player ID $this->peacekeepers = $this->lib->call('getPeacekeepers'); // Check for systems with enemy fleets $rPlanets = $this->checkBattleSystems(); // Check for fleets to evacuate $ePlanets = $this->checkEvacuations($rPlanets); } private function checkBattleSystems() { $reinforce = array(); $enemyFleets = $this->getEnemyFleets(); if (empty($enemyFleets)) { return $reinforce; } $sysOwners = $this->getSystemOwners(array_keys($enemyFleets)); foreach ($enemyFleets as $systemID => $planets) { $ownerID = $sysOwners[$systemID]['owner']; $ownPlanets = $sysOwners[$systemID]['planets']; foreach ($planets as $planetID => $eFleets) { // Check enemy fleet size $q = $this->db->query( "SELECT SUM(fighters + gaships / 2), SUM(cruisers), SUM(bcruisers) " . "FROM fleet " . "WHERE id IN (" . join(',', $eFleets) . ")" ); list($eFighters, $eCruisers, $eBattleCruisers) = dbFetchArray($q); // Check Peacekeeper fleet size $q = $this->db->query( "SELECT SUM(fighters), SUM(cruisers), SUM(bcruisers) FROM fleet " . "WHERE location = $planetID AND owner = {$this->peacekeepers}" ); list($pkFighters, $pkCruisers, $pkBattleCruisers) = dbFetchArray($q); // Compute fleet size requirements for Peacekeepers $rFighters = ceil($eFighters * 2 - (int) $pkFighters); $rCruisers = $eCruisers * 2 - (int) $pkCruisers; $rBattleCruisers = $eBattleCruisers * 2 - (int) $pkBattleCruisers; // Do we need to reinforce ? if ($rFighters > 0 || $rCruisers > 0 || $rBattleCruisers > 0) { // If we need fighters, do we have enough haul space? $haul = $rCruisers * 20 + $rBattleCruisers * 15; if ($haul * 0.9 < $rFighters) { // Add cruisers to match haul size $rCruisers += ceil(($rFighters - ($haul * 0.9)) / 20); } $reinforce[$planetID] = array(true, $rFighters, $rCruisers, $rBattleCruisers); } else { $reinforce[$planetID] = array(false); } // Make sure all enemy fleets are attacking and battle-ready $this->db->query( "UPDATE fleet SET attacking = 't', time_spent = (CASE " . "WHEN time_spent <= 15 THEN 16 " . "ELSE time_spent " . "END) WHERE id IN (" . join(',', $eFleets) . ")" ); // If we're on a planet not owned by the system's owner, // make sure his fleets are defending if (!in_array($planetID, $ownPlanets)) { $this->db->query( "UPDATE fleet SET attacking = 'f' " . "WHERE location = $planetID AND owner = $ownerID" ); } } } foreach ($reinforce as $planetID => $reinforcements) { if (!$reinforcements[0]) { continue; } array_shift($reinforcements); $this->reinforce($planetID, $reinforcements); } return array_keys($reinforce); } private function getEnemyFleets() { $q = $this->db->query( "SELECT f.id, p.id, p.system FROM fleet f, planet p, pk_sys_status s " . "WHERE s.status = 'O' AND p.system = s.system " . "AND f.owner = s.player AND f.location = p.id " . "ORDER BY p.id, f.owner " . "FOR UPDATE OF f, p" ); $result = array(); while ($r = dbFetchArray($q)) { if (!is_array($result[$r[2]])) { $result[$r[2]] = array(); } if (!is_array($result[$r[2]][$r[1]])) { $result[$r[2]][$r[1]] = array(); } array_push($result[$r[2]][$r[1]], $r[0]); } return $result; } private function getSystemOwners($systems) { $q = $this->db->query( "SELECT system, id, owner FROM planet " . "WHERE system IN (" . join(',', $systems) . ") " . "ORDER BY system, (owner IS NOT NULL) DESC" ); $result = array(); while ($r = dbFetchArray($q)) { if (!is_array($result[$r[0]])) { $result[$r[0]] = array( 'owner' => $r[2], 'planets' => array($r[1]) ); } elseif (!is_null($r[2])) { array_push($result[$r[0]]['planets'], $r[1]); } } return $result; } private function reinforce($planetID, $fSize) { // Generate fleet $name = addslashes(self::$fleetName); $this->db->query( "INSERT INTO fleet (location, owner, fighters, cruisers, bcruisers, time_spent, name) " . "VALUES ($planetID, {$this->peacekeepers}, {$fSize[0]}, {$fSize[1]}, " . "{$fSize[2]}, 16, '$name')" ); $fPower = $this->fleets->call('getPower', $this->peacekeepers, 0, $fSize[0], $fSize[1], $fSize[2]); // Get planet name $q = $this->db->query("SELECT name FROM planet WHERE id = $planetID"); list($pName) = dbFetchArray($q); // Get random origin (nebula or planetary remains) $q = $this->db->query( "SELECT id, name FROM planet WHERE status > 0 ORDER BY RANDOM() LIMIT 1" ); list($originID, $origin) = dbFetchArray($q); $origin = addslashes($origin); // Get list of players and status $q = $this->db->query( "SELECT owner AS player, FALSE AS attacking FROM planet " . "WHERE id = $planetID AND owner IS NOT NULL " . "UNION SELECT DISTINCT owner AS player, attacking FROM fleet " . "WHERE location = $planetID AND owner <> {$this->peacekeepers}" ); // Send messages while ($r = dbFetchArray($q)) { $mid = $this->msgs->call('send', $r[0], 'flmove', array( 'p_id' => $planetID, 'p_name' => $pName )); $this->db->query( "INSERT INTO flmove_data VALUES ($mid, '$name', {$this->peacekeepers}, 0, " . "{$fSize[0]}, {$fSize[1]}, {$fSize[2]}, $fPower, '{$r[1]}', 't', " . "$originID, '$origin')" ); } } private function checkEvacuations($noCheck) { if (empty($noCheck)) { $ncQuery = ""; } else { $ncQuery = "AND location NOT IN (" . join(',', $noCheck) . ")"; } // Get PK fleets on planets where no battle is taking place $q = $this->db->query( "SELECT id FROM fleet " . "WHERE owner = {$this->peacekeepers} AND location IS NOT NULL $ncQuery " . "FOR UPDATE" ); if (dbCount($q) == 0) { return; } // Merge PK fleets $fleets = array(); while ($r = dbFetchArray($q)) { array_push($fleets, $r[0]); } $fleets = $this->fleets->call('merge', $fleets, array($this->peacekeepers), ""); // Remove extra fighters and delete empty fleets if required $this->db->query( "UPDATE fleet SET fighters = (CASE " . "WHEN fighters < cruisers * 20 + bcruisers * 10 THEN fighters " . "ELSE cruisers * 20 + bcruisers * 10 " . "END) WHERE id IN (" . join(',', $fleets) . ")" ); $this->db->query( "DELETE FROM fleet WHERE cruisers = 0 AND bcruisers = 0 AND id IN (" . join(',', $fleets) . ")" ); // Fetch all remaining fleets and evacuate them $q = $this->db->query( "SELECT p.id, p.name, f.id, f.fighters, f.cruisers, f.bcruisers FROM fleet f, planet p " . "WHERE p.id = f.location AND f.id IN (" . join(',', $fleets) . ")" ); $locations = array(); $fleets = array(); while ($r = dbFetchArray($q)) { $this->evacuate($r); array_push($locations, $r[0]); array_push($fleets, $r[2]); } // Delete fleets if (! empty($fleets)) { $this->db->query("DELETE FROM fleet WHERE id IN (" . join(',', $fleets) . ")"); } return $locations; } private function evacuate($fleetRecord) { list($planetID, $planet, $fleet, $fighters, $cruisers, $bCruisers) = $fleetRecord; l::trace("Peacekeeper fleet #$fleet leaving planet $planet (#$planetID)"); $planet = addslashes($planet); $fName = addslashes(self::$fleetName); $fPower = $this->fleets->call('getPower', $this->peacekeepers, 0, $fighters, $cruisers, $bCruisers); // Get list of players and status $q = $this->db->query( "SELECT owner AS player, FALSE AS attacking FROM planet " . "WHERE id = $planetID AND owner IS NOT NULL " . "UNION SELECT DISTINCT owner AS player, attacking FROM fleet " . "WHERE location = $planetID AND owner <> {$this->peacekeepers}" ); // Send messages while ($r = dbFetchArray($q)) { $mid = $this->msgs->call('send', $r[0], 'flmove', array( 'p_id' => $planetID, 'p_name' => $planet )); $this->db->query( "INSERT INTO flmove_data VALUES ($mid, '$fName', {$this->peacekeepers}, 0, " . "$fighters, $cruisers, $bCruisers, $fPower, '{$r[1]}', 'f', NULL, NULL)" ); } } } ?>