lib = $lib; $this->game = $this->lib->game; $this->db = $this->game->db; $this->fleets = $this->game->getLib('beta5/fleet'); $this->planets = $this->game->getLib('beta5/planet'); $this->players = $this->game->getLib('beta5/player'); } public function run($winningTeam) { // Starts by increasing the team's score $cPoints = $this->increaseScore($winningTeam); // Did the team win the whole game ? if ($cPoints == 100) { $this->endGame($winningTeam); return; } // Neutralize all planets that are owned by players of a team in an area allocated to another team // as well as planets owned by players in other players' spawning systems $this->neutralizeColonies(); // Reset all planets that had been WHSN'd $this->resetWHSN(); // Remove all WHSN penalties $this->removePenalties(); // Neutralize and consolidate planets in target systems $this->neutralizeTargets(); // And the dead shall rise again ... $this->respawnPlayers(); // Equalize fleet sizes and send the fleets home $this->equalizeFleets(); // Update corruption, happiness and attack status for all planets $this->updatePlanets(); // Send messages $this->sendRoundMessages($winningTeam); } private function increaseScore($winningTeam) { $q = $this->db->query("SELECT points FROM ctf_points WHERE team = $winningTeam FOR UPDATE"); if (dbCount($q)) { list($cPoints) = dbFetchArray($q); $cPoints = min(100, $cPoints + $this->game->params['v2points']); $this->db->query("UPDATE ctf_points SET points = $cPoints WHERE team = $winningTeam"); } else { $cPoints = $this->game->params['v2points']; $this->db->query("INSERT INTO ctf_points (team, points) VALUES ($winningTeam, $cPoints)"); } return $cPoints; } private function endGame($winningTeam) { // Fetch the list of players and their teams $q = $this->db->query("SELECT id,alliance FROM player"); while ($r = dbFetchArray($q)) { $this->lib->call('message', $r[0], ($r[1] == $winningTeam ? 14 : 15), $winningTeam); } // Update the rankings $this->game->getLib()->call('updateRankings'); } private function neutralizeColonies() { // Get the list of all planets to neutralize $q = $this->db->query( "SELECT p.id, y.id FROM planet p, ctf_alloc a, player y " . "WHERE p.owner = y.id AND p.system = a.system " . "AND a.alliance <> y.alliance " . "UNION SELECT p.id, y.id FROM planet p, ctf_alloc a, player y " . "WHERE p.system = a.system AND y.id = p.owner AND a.alliance = y.alliance " . "AND a.spawn_point AND a.player <> y.id" ); // Neutralize the planets while ($r = dbFetchArray($q)) { $this->planets->call('ownerChange', $r[0]); $this->players->call('losePlanet', $r[1], $r[0]); } } private function resetWHSN() { // Get the list of WHSN'd planets $q = $this->db->query( "SELECT p.id FROM planet p, system s WHERE s.nebula = 0 AND p.status <> 0 AND p.system = s.id" ); // Recreate planets instead while ($r = dbFetchArray($q)) { $this->regenPlanet($r[0]); } } private function regenPlanet($id) { $ttn = rand(3, 12); do { $rn = strtoupper(substr(md5(uniqid(rand())), 0, 7)); $q = $this->db->query("SELECT id FROM planet WHERE name='P-[$rn]'"); } while (dbCount($q)); $q = $this->db->query("SELECT max_pop FROM planet_max_pop WHERE planet = $id AND tech_level = 0"); list($maxPop) = dbFetchArray($q); $this->db->query( "UPDATE planet SET status = 0, pop = 2000, ifact = 3, mfact = 3, " . "turrets = $ttn, name = 'P-[$rn]', max_pop = $maxPop " . "WHERE id = $id" ); } private function removePenalties() { $this->db->query("UPDATE planet SET bh_unhappiness = 0"); $this->db->query("UPDATE player SET bh_unhappiness = 0"); } private function neutralizeTargets() { // Reset target status $this->db->query("UPDATE ctf_target SET held_by = NULL, held_since = NULL, grace_expires = NULL"); // Get the list of all planets to neutralize $q = $this->db->query( "SELECT p.id, y.id, p.pop FROM planet p, ctf_target t, player y " . "WHERE p.owner = y.id AND p.system = t.system" ); while ($r = dbFetchArray($q)) { // Neutralize the planet $this->planets->call('ownerChange', $r[0]); $this->players->call('losePlanet', $r[1], $r[0]); // Compute factories and turrets for the planet $x = ($r[2] - 2000) / 48000; $facts = floor((($r[2] / 30) - 754 * $x * $x) / 2); $turrets = floor(($r[2] / 22) - 510 * $x * $x); // Set the planet's factories and turrets, reset its corruption $this->db->query( "UPDATE planet SET ifact = $facts, mfact = $facts, turrets = $turrets, corruption = 0 " . "WHERE id = {$r[0]}" ); } } private function respawnPlayers() { // Get the list of players who don't have planets $q = $this->db->query( "SELECT id FROM player WHERE NOT hidden AND id NOT IN (" . "SELECT DISTINCT owner FROM planet WHERE owner IS NOT NULL)" ); while ($r = dbFetchArray($q)) { $this->respawn($r[0]); } } private function respawn($player) { // Get the player's initial system $q = $this->db->query("SELECT system FROM ctf_alloc WHERE player = $player"); list($system) = dbFetchArray($q); // Choose a random planet $orbit = rand(0, 5); $q = $this->db->query("SELECT id FROM planet WHERE system = $system AND orbit = $orbit"); list($planet) = dbFetchArray($q); // Assign the planet $this->planets->call('ownerChange', $planet, $player); $this->players->call('takePlanet', $player, $planet); } private function equalizeFleets() { // Get the list of fleets list($pFleets, $aFleets) = $this->getAllFleets(); // Compute fleet reduction based on alliance fleets $fleetReductions = $this->computeReductions($aFleets); // Compute the reductions for each player foreach ($pFleets as $player => $fleets) { $team = array_shift($fleets); $pFleets[$player] = $this->playerReduction($fleets, $aFleets[$team], $fleetReductions[$team]); } // Reinsert each player's fleet at one of his planets foreach ($pFleets as $player => $fleet) { $this->insertFleet($player, $fleet); } } private function getAllFleets() { // Get the list of all fleets $q = $this->db->query( "SELECT f.id, p.id, p.alliance FROM fleet f, player p WHERE f.owner = p.id" ); // Compute totals and disband the fleets as we go $playerFleets = array(); $allianceFleets = array(); while ($r = dbFetchArray($q)) { list($fleetID, $player, $alliance) = $r; if (is_null($playerFleets[$player])) { $playerFleets[$player] = array($alliance,0,0,0,0); } if (is_null($allianceFleets[$alliance])) { $allianceFleets[$alliance] = array(0,0,0,0); } $fleet = $this->fleets->call('get', $fleetID); for ($i = 0; $i < 4; $i ++) { $playerFleets[$player][$i + 1] += $fleet[self::$ftFields[$i]]; $allianceFleets[$alliance][$i] += $fleet[self::$ftFields[$i]]; } $this->fleets->call('disband', $fleetID); } return array($playerFleets, $allianceFleets); } private function computeReductions($fleets) { // Find the smallest values for each type of ship $smallest = null; foreach ($fleets as $team => $tFleets) { if (is_null($smallest)) { $smallest = $tFleets; continue; } for ($i = 0; $i < 4; $i ++) { if ($tFleets[$i] < $smallest[$i]) { $smallest[$i] = $tFleets[$i]; } } } // Compute reductions for each team $reductions = array(); foreach ($fleets as $team => $tFleets) { $reductions[$team] = array(); for ($i = 0; $i < 4; $i ++) { if ($tFleets[$i] == $smallest[$i]) { $nAmount = 0; } else { $rnd = ($smallest == 0) ? rand(101, 105) : rand(98, 105); $nAmount = $tFleets[$i] - floor($rnd * $smallest[$i] / 100); } $reductions[$team][$i] = $nAmount; } } return $reductions; } private function playerReduction($pFleets, $aFleets, $aReduction) { $reduc = array(); for ($i = 0; $i < 4; $i ++) { if ($aFleets[$i] == 0) { continue; } $ratio = $pFleets[$i] / $aFleets[$i]; $reduction = floor($aReduction[$i] * $ratio); $reduc[$i] = $pFleets[$i] - $reduction; } return $reduc; } private function insertFleet($player, $fleet) { if ($fleet[0] + $fleet[1] + $fleet[2] + $fleet[3] == 0) { return; } // Get a planet belonging to the player $q = $this->db->query("SELECT id FROM planet WHERE owner = $player LIMIT 1"); list($planet) = dbFetchArray($q); $qString1 = "INSERT INTO fleet (owner, location"; $qString2 = ") VALUES ($player, $planet"; for ($i = 0; $i < 4; $i ++) { if ($fleet[$i] == 0) { continue; } $qString1 .= ", " . self::$ftFields[$i]; $qString2 .= ", {$fleet[$i]}"; } $this->db->query("$qString1$qString2)"); } private function updatePlanets() { $this->db->query("UPDATE planet SET corruption = corruption / 2"); $q = $this->db->query( "SELECT p.id FROM planet p, system s " . "WHERE s.id = p.system AND s.nebula = 0" ); while ($r = dbFetchArray($q)) { $this->planets->call('updateHappiness', $r[0]); $this->planets->call('updateMilStatus', $r[0]); } } private function sendRoundMessages($winningTeam) { $q = $this->db->query("SELECT id,alliance FROM player"); while ($r = dbFetchArray($q)) { $this->lib->call('message', $r[0], ($r[1] == $winningTeam ? 12 : 13), $winningTeam); } } }