bool Bombard::doOrder(IGObject *fleet) { Game *game = Game::getGame(); ObjectManager *om = game->getObjectManager(); ObjectTypeManager *odm = game->getObjectTypeManager(); Random *rand = game->getRandom(); IGObject *planetObj = om->getObject(planet->getObjectId()); if(planetObj->getType() != odm->getObjectTypeByName("Planet")) { Logger::getLogger()->debug("Player tried to bombard something illogical"); return true; } Fleet *fleetData = dynamic_cast<Fleet*>(fleet->getObjectBehaviour()); Planet *planetData = dynamic_cast<Planet*>(planetObj->getObjectBehaviour()); char planetShipTech = PlayerInfo::getPlayerInfo(planetData->getOwner()).getShipTechLevel(); double attack = fleetData->getAttack(); planetData->removeResource("Industry", static_cast<uint32_t>(attack * INDUSTRY_DMG * (1+rand->getInRange(-2,2)/100.) )); planetData->removeResource("Social Environment", static_cast<uint32_t>(attack * SOCIAL_DMG * (1+rand->getInRange(-2,2)/100.) )); planetData->removeResource("Planetary Environment", static_cast<uint32_t>(attack * PLANETARY_DMG * (1+rand->getInRange(-2,2)/100.) )); planetData->removeResource(string("PDB") + planetShipTech, static_cast<uint32_t>(attack * PDB_DMG / 10. * (1+rand->getInRange(-2,2)/100.) )); PlayerInfo::getPlayerInfo(fleetData->getOwner()).addVictoryPoints(VICTORY_POINTS); // PDBs counter-attack at: PDB level * 6 * numPDBs fleetData->takeDamage( (planetShipTech - '0') * 6 * planetData->getResource(string("PDB") + planetShipTech).first); Message *msg = new Message(); msg->setSubject("Bombard complete"); string body = "Fleet \"" + fleet->getName() + "\" bombarded " + planetObj->getName(); msg->setBody(PlayerInfo::appAllVictoryPoints(body)); msg->addReference(rst_Action_Order, rsorav_Completion); msg->addReference(rst_Object, fleet->getID()); msg->addReference(rst_Object, planetObj->getID()); game->getPlayerManager()->getPlayer(fleetData->getOwner())->postToBoard(msg); game->getPlayerManager()->getPlayer(planetData->getOwner())->postToBoard(msg); return true; }
std::string PlanetWarsGame::toString(Player* pov) const { std::stringstream gameState; const int numPlanets = static_cast<int>(m_planets.size()); //Write the planets. for (int i = 0; i < numPlanets; ++i) { Planet* planet = m_planets[i]; gameState << "P " << planet->getX() << " " << planet->getY() << " " << pov->povId(planet->getOwner()) << " " << planet->getNumShips() << " " << planet->getGrowthRate() << std::endl; } //Write the fleets. for (FleetList::const_iterator it = m_fleets.begin(); it != m_fleets.end(); ++it) { Fleet* fleet = (*it); gameState << "F " << pov->povId(fleet->getOwner()) << " " << fleet->getNumShips() << " " << fleet->getSource()->getId() << " " << fleet->getDestination()->getId() << " " << fleet->getTotalTripLength() << " " << fleet->getTurnsRemaining() << std::endl; } gameState << "go" << std::endl; return gameState.str(); }
//Sends a fleet back to it's home planet void TaeTurn::sendHome(uint32_t fleet) { Game* game = Game::getGame(); ObjectManager* obm = game->getObjectManager(); ObjectTypeManager* obtm = game->getObjectTypeManager(); PlayerManager::Ptr pm = game->getPlayerManager(); IGObject::Ptr fleetobj = obm->getObject(fleet); //Check to make sure it is really a fleet if(fleetobj->getType() != obtm->getObjectTypeByName("Fleet")) { return; } //Get all the required objects Fleet* f = (Fleet*) fleetobj->getObjectBehaviour(); Player::Ptr p = pm->getPlayer(f->getOwner()); IGObject::Ptr sys = obm->getObject(fleetobj->getParent()); StarSystem* sysData = (StarSystem*) sys->getObjectBehaviour(); //Remove fleet from system sysData->setRegion(0); fleetobj->removeFromParent(); //Find it's home planet std::set<uint32_t> objects = obm->getAllIds(); std::set<uint32_t>::iterator itcurr; for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = obm->getObject(*itcurr); if(ob->getName().compare(string(p->getName() + "'s Home Planet")) == 0) { Planet* p = (Planet*) ob->getObjectBehaviour(); f->setPosition(p->getPosition()); fleetobj->addToParent(ob->getID()); } } }
void Planet::welcomeArrivedFleets() { const int ownerId = m_owner->getId(); //Tally up the ships for each force. const int numArrivedFleets = static_cast<int>(m_landedFleets.size()); if (numArrivedFleets == 0) { return; } int playerShips[3]; playerShips[0] = (ownerId == 0) ? m_numShips : 0; playerShips[1] = (ownerId == 1) ? m_numShips : 0; playerShips[2] = (ownerId == 2) ? m_numShips : 0; for (int i = 0; i < numArrivedFleets; ++i) { Fleet* fleet = m_landedFleets[i]; playerShips[fleet->getOwner()->getId()] += fleet->getNumShips(); } m_landedFleets.clear(); //Check who won. //Check whether the owner stays the same. if (playerShips[ownerId] >= std::max(playerShips[(ownerId+1)%3], playerShips[(ownerId+2)%3])) { this->setNumShips(playerShips[ownerId] - std::max(playerShips[(ownerId+1)%3], playerShips[(ownerId+2)%3])); return; } //Otherwise, find the new owner. if (playerShips[1] > playerShips[2]) { this->setOwner(m_game->getFirstPlayer()); const int remainingShips = playerShips[1] - std::max(playerShips[2], playerShips[0]); this->setNumShips(remainingShips); } else if (playerShips[2] > playerShips[1]) { this->setOwner(m_game->getSecondPlayer()); const int remainingShips = playerShips[2] - std::max(playerShips[1], playerShips[0]); this->setNumShips(remainingShips); } else if (ownerId == 0 && playerShips[2] == playerShips[1]) { //The invading fleets are larger than the neutral planet, but equal in size. //Planet stays neutral. this->setNumShips(0); } //There should be no other cases. }
//The colonize order checks to make sure the system is valid, then adds a resource to the planet, checks for //external combat, and awards one point to the player with the leader in the region of the new colony. bool Colonize::doOrder(IGObject::Ptr obj) { ObjectManager* obm = Game::getGame()->getObjectManager(); ObjectTypeManager* obtm = Game::getGame()->getObjectTypeManager(); Fleet* fleetData = (Fleet*)(obj->getObjectBehaviour()); Player::Ptr player = Game::getGame()->getPlayerManager()->getPlayer(fleetData->getOwner()); IGObject::Ptr newStarSys = obm->getObject(starSys->getObjectId()); //Perform last minute checks to make sure the system can be colonized if(newStarSys->getType() != obtm->getObjectTypeByName("Star System")) { //Not a star system Logger::getLogger()->debug("Trying to colonize to an object which is not a star system"); Message::Ptr msg( new Message() ); msg->setSubject("Colonize order failed"); msg->setBody(string("You're fleet, \"" + obj->getName() + "\" tried to colonize an object which is not a star system!")); msg->addReference(rst_Object, obj->getID()); player->postToBoard(msg); return false; } if(!((StarSystem*)(newStarSys->getObjectBehaviour()))->canBeColonized(isMining)) { //Not colonizable Logger::getLogger()->debug("Player tried to colonize a system which cannot be colonized."); Message::Ptr msg( new Message() ); msg->setSubject("Colonize order failed"); msg->setBody(string("You're fleet, \"" + obj->getName() + "\" tried to colonize a fleet which cannot be colonized!")); msg->addReference(rst_Object, obj->getID()); player->postToBoard(msg); return false; } //Find the star system's planet set<uint32_t> children = newStarSys->getContainedObjects(); uint32_t pid; bool planetFound = false; for(set<uint32_t>::iterator i=children.begin(); i != children.end(); i++) { if(obm->getObject(*i)->getType() == obtm->getObjectTypeByName("Planet")) { pid = *i; planetFound = true; } } if(!planetFound) { Logger::getLogger()->debug("Colonize Order: No planet found in target star system"); return false; } //Add resource to planet Planet* planet = (Planet*)(obm->getObject(pid)->getObjectBehaviour()); Design::Ptr ship = Game::getGame()->getDesignStore()->getDesign(fleetData->getShips().begin()->first); uint32_t scoreType = 0; string leaderName; if(ship->getName().compare("MerchantShip") == 0) { planet->addResource(4, 1); scoreType = 1; leaderName = "MerchantLeaderShip"; } else if(ship->getName().compare("ScientistShip") == 0) { planet->addResource(5, 1); scoreType = 2; leaderName = "ScientistLeaderShip"; } else if(ship->getName().compare("SettlerShip") == 0) { planet->addResource(6, 1); scoreType = 3; leaderName = "SettlerLeaderShip"; } else if(ship->getName().compare("MiningShip") == 0) { planet->addResource(7, 1); scoreType = 4; leaderName = "MiningLeaderShip"; } //Get bordering star systems' regions StarSystem* starSysData = (StarSystem*)(newStarSys->getObjectBehaviour()); set<uint32_t> regions = getBorderingRegions(); //Put the newly colonized ship into the proper region //If it does not border any regions, then set it to a new one with a unique id if(regions.size() == 0) { starSysData->setRegion(starSys->getObjectId()); stringstream out; out << starSysData->getRegion(); Logger::getLogger()->debug(string("System " + newStarSys->getName() + " added to region " + out.str()).c_str()); } else if(regions.size() == 1) { // Add +1 to the resource score of the player with the correct leader // in this region int leaderID = getLeaderInRegion(*(regions.begin()), leaderName); if(leaderID < 0 && leaderName.compare("SettlerLeaderShip") != 0) { leaderID = getLeaderInRegion(*(regions.begin()), "SettlerLeaderShip"); } if(leaderID >= 0) { Fleet* leader = (Fleet*) ((obm->getObject((uint32_t) leaderID))->getObjectBehaviour()); Player::Ptr owner = Game::getGame()->getPlayerManager()->getPlayer(leader->getOwner()); owner->setScore(scoreType, owner->getScore(scoreType) + 1); } //Add the newly colonized system to the region starSysData->setRegion(*(regions.begin())); stringstream out; out << starSysData->getRegion(); Logger::getLogger()->debug(string("System " + newStarSys->getName() + " added to region " + out.str()).c_str()); } else { // This means that 2 regions are being connected. Perform check // for external combat map<uint32_t, uint32_t> settlers; map<uint32_t, uint32_t> scientists; map<uint32_t, uint32_t> merchants; map<uint32_t, uint32_t> miners; for(set<uint32_t>::iterator i = regions.begin(); i != regions.end(); i++) { int temp = getLeaderInRegion(*i, "SettlerLeaderShip"); if(temp != -1) { settlers[temp] = *i; } temp = getLeaderInRegion(*i, "ScientistLeaderShip"); if(temp != -1) { scientists[temp] = *i; } temp = getLeaderInRegion(*i, "MerchantLeaderShip"); if(temp != -1) { merchants[temp] = *i; } temp = getLeaderInRegion(*i, "MiningLeaderShip"); if(temp != -1) { miners[temp] = *i; } } TaeTurn* turn = (TaeTurn*) Game::getGame()->getTurnProcess(); bool conflict = false; if(settlers.size() > 1) { //Settler Conflict! turn->queueCombatTurn(false, settlers); conflict = true; } if(scientists.size() > 1) { //Scientist Conflict! turn->queueCombatTurn(false, scientists); conflict = true; } if(merchants.size() > 1) { //Merchant Conflict! turn->queueCombatTurn(false, merchants); conflict = true; } if(miners.size() > 1) { //Miner Conflict! turn->queueCombatTurn(false, miners); conflict = true; } if(!conflict) { uint32_t region = *(regions.begin()); set<uint32_t> objects = obm->getAllIds(); for(set<uint32_t>::iterator i = objects.begin(); i != objects.end(); i++) { IGObject::Ptr ob = obm->getObject(*i); if(ob->getType() == obtm->getObjectTypeByName("Star System")) { StarSystem* sys = (StarSystem*) ob->getObjectBehaviour(); uint32_t r = sys->getRegion(); if(r != region && regions.count(r) > 0) { sys->setRegion(region); } } } } } obm->doneWithObject(newStarSys->getID()); // post completion message Message::Ptr msg( new Message() ); msg->setSubject("Colonize fleet order complete"); msg->setBody(string("You're fleet, \"" + obj->getName() + "\" has colonized ") + newStarSys->getName() + "."); msg->addReference(rst_Action_Order, rsorav_Completion); msg->addReference(rst_Object, starSys->getObjectId()); msg->addReference(rst_Object, obj->getID()); player->postToBoard(msg); //Remove fleet obj->removeFromParent(); obm->scheduleRemoveObject(obj->getID()); return true; }
void PlanetWarsGame::completeStep() { //Proceed only if there's an unfinished step. if (STEPPING != m_state) { return; } m_state = PROCESSING; //Clear the old new fleets. m_newFleets.clear(); //Read and process the the responses from each of the players. std::string firstPlayerOutput(m_firstPlayer->readCommands()); std::string secondPlayerOutput(m_secondPlayer->readCommands()); bool isFirstPlayerRunning = this->processOrders(firstPlayerOutput, m_firstPlayer); bool isSecondPlayerRunning = this->processOrders(secondPlayerOutput, m_secondPlayer); //Check whether the players are still alive. if (!isFirstPlayerRunning || !isSecondPlayerRunning) { this->stop(); return; } this->advanceGame(); //Check each player's position. int firstPlayerShips = 0; int secondPlayerShips = 0; const int numPlanets = static_cast<int>(m_planets.size()); for (int i = 0; i < numPlanets; ++i) { Planet* planet = m_planets[i]; const int ownerId = planet->getOwner()->getId(); if (1 == ownerId) { firstPlayerShips += planet->getNumShips(); } else if (2 == ownerId) { secondPlayerShips += planet->getNumShips(); } } for (FleetList::iterator it = m_fleets.begin(); it != m_fleets.end(); ++it) { Fleet* fleet = *it; if (1 == fleet->getOwner()->getId()) { firstPlayerShips += fleet->getNumShips(); } else { secondPlayerShips += fleet->getNumShips(); } } emit turnEnded(); //Check for game end conditions. bool isGameOver = false; if (firstPlayerShips == 0 && secondPlayerShips == 0) { this->logMessage("Draw."); isGameOver = true; } else if (firstPlayerShips == 0) { this->logMessage("Player 2 wins."); isGameOver = true; } else if (secondPlayerShips == 0) { this->logMessage("Player 1 wins."); isGameOver = true; } else if (m_turn >= m_maxTurns) { if (firstPlayerShips > secondPlayerShips) { this->logMessage("Player 1 wins."); isGameOver = true; } else if (firstPlayerShips < secondPlayerShips) { this->logMessage("Player 2 wins."); isGameOver = true; } else { this->logMessage("Draw."); isGameOver = true; } } if (isGameOver) { this->stop(); return; } //Game is not over. m_state = READY; this->continueRunning(); }
void GameController::onChangeTurn() { currentTurn++; /* impose production on owned planets */ for(int i=0; i<players.size(); i++) { Player* tempP = players[i]; for(int j=0; j<players[i]->getPlanets().size(); j++) { Planet* tempPl = tempP->getPlanets()[j]; tempPl->setShips( tempPl->getShips() + tempPl->getProduction()); } } for(int k=0; k<fleets.size(); k++) { Fleet* tempF = fleets[k]; /* fleet has arrived */ if(fleets[k]->getArrivalTurn() == currentTurn) { /* fleet owner same as destination owner, so reinforcing a planet */ if(tempF->getOwner() == tempF->getDestination()->getOwner()) { tempF->getDestination()->setShips(tempF->getDestination()->getShips() + tempF->getNumShips()); } else /* attacking planet */ { double attackScore, defenseScore; attackScore = tempF->getNumShips()*tempF->getKillPercent(); defenseScore = tempF->getDestination()->getShips()*tempF->getDestination()->getKillPercent(); if(attackScore >= defenseScore) /* attackers win */ { if(tempF->getDestination()->getOwner() != NULL) tempF->getDestination()->getOwner()->removeFromPlanets(tempF->getDestination()); tempF->getOwner()->addToPlanets(tempF->getDestination()); tempF->getDestination()->setOwner(tempF->getOwner()); tempF->getDestination()->setShips((int)attackScore-defenseScore); emit displayInfo(QString("Turn %1: Planet %2 has fallen to %3").arg(currentTurn).arg(tempF->getDestination()->getName()).arg(tempF->getOwner()->getName())); } else /* defense wins */ { tempF->getDestination()->setShips((int)defenseScore-attackScore); emit displayInfo(QString("Turn %1: Planet %2 has held against an attack from %3.").arg(currentTurn).arg(tempF->getDestination()->getName()).arg(tempF->getOwner()->getName())); } } /* processed fleet, so remove it */ fleets.removeAt(k); } } if(currentPlayer < players.size() - 1) currentPlayer++; else currentPlayer = 0; emit displayControl(QString("<font color=%1>%2</font>:Select source planet").arg(players[currentPlayer]->getColor().name()).arg(players[currentPlayer]->getName())); }
//Award artifacts to any players who have a merchant leader //in a region with two artifacts void TaeTurn::awardArtifacts() { Game* game = Game::getGame(); ObjectTypeManager* obtm = game->getObjectTypeManager(); ObjectManager* objectmanager = game->getObjectManager(); std::set<uint32_t> artifacts; std::set<uint32_t> regions; std::set<uint32_t> objects = objectmanager->getAllIds(); std::set<uint32_t>::iterator itcurr; //Find any regions with 2 or more alien artifacts for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->getType() == obtm->getObjectTypeByName("Planet")) { Planet* p = (Planet*) ob->getObjectBehaviour(); if(p->getResource(3) > 0) { StarSystem* sys = (StarSystem*)(objectmanager->getObject(ob->getParent())->getObjectBehaviour()); if(sys->getRegion() != 0) { if(regions.count(sys->getRegion()) > 0) { artifacts.insert(*itcurr); } else { regions.insert(sys->getRegion()); } } } } } if(!artifacts.empty()) { uint32_t type; DesignStore::Ptr ds = game->getDesignStore(); PlayerManager::Ptr pm = game->getPlayerManager(); std::set<uint32_t> designs = ds->getDesignIds(); //get leader ID for(itcurr = designs.begin(); itcurr != designs.end(); ++itcurr) { if(ds->getDesign(*itcurr)->getName().compare("MerchantLeaderShip")) { type = *itcurr; } } //Search the objects for a merchant leader for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->getType() == obtm->getObjectTypeByName("Fleet")) { Fleet* f = (Fleet*) (ob->getObjectBehaviour()); if(f->getShips().count(type) > 0) { IGObject::Ptr parent = objectmanager->getObject(ob->getParent()); if(parent->getType() == obtm->getObjectTypeByName("Star System")) { StarSystem* parentData = (StarSystem*) (parent->getObjectBehaviour()); //See if this leader is in a region with //2 or more alien artifacts for(std::set<uint32_t>::iterator i = artifacts.begin(); i != artifacts.end(); ++i) { IGObject::Ptr obj = objectmanager->getObject(*i); Planet* p = (Planet*) obj->getObjectBehaviour(); StarSystem* sys = (StarSystem*)(objectmanager->getObject(obj->getParent())->getObjectBehaviour()); if(sys->getRegion() == parentData->getRegion()) { //+1 to leader's owner's artifact score Player::Ptr owner = pm->getPlayer(f->getOwner()); owner->setScore(5, owner->getScore(5) + 1); p->removeResource(3, 1); artifacts.erase(*i); } } } } } } } }
void TaeTurn::doCombatTurn() { std::set<uint32_t>::iterator itcurr; Game* game = Game::getGame(); OrderManager* ordermanager = game->getOrderManager(); ObjectManager* objectmanager = game->getObjectManager(); ObjectTypeManager* obtm = game->getObjectTypeManager(); PlayerManager::Ptr playermanager = game->getPlayerManager(); containerids.clear(); // Do orders std::set<uint32_t> objects = objectmanager->getAllIds(); for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->getType() == planettype || ob->getType() == fleettype) { OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(ob->getParameterByType(obpT_Order_Queue)); if(oqop != NULL) { OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(oqop->getQueueId()); if(orderqueue != NULL) { Order * currOrder = orderqueue->getFirstOrder(); if(currOrder != NULL) { if(currOrder->doOrder(ob)) { orderqueue->removeFirstOrder(); } else { orderqueue->updateFirstOrder(); } } if(ob->getContainerType() >= 1) { containerids.insert(ob->getID()); } objectmanager->doneWithObject((ob)->getID()); } } } } //Determine winner uint32_t winner = 0; uint32_t loser = 0; for(map<uint32_t, int>::iterator i = strength.begin(); i != strength.end(); ++i) { if(winner == 0) { winner = i->first; } else { if(strength[winner] < i->second) { winner = i->first; } else { loser = i->first; } } } //Remove losing combatants uint32_t losingRegion; uint32_t winningRegion; set<uint32_t> removedSystems; if(isInternal) { //Internal combat removes losing leader and awards one point to the winner for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) { IGObject::Ptr ob = objectmanager->getObject(i->first); Fleet* f = (Fleet*) ob->getObjectBehaviour(); if(f->getOwner() != winner) { sendHome(i->first); Player::Ptr p = playermanager->getPlayer(winner); p->setScore(2, p->getScore(2) + 1); losingRegion = i->second; winningRegion = losingRegion; } } objects = objectmanager->getAllIds(); for(itcurr = objects.begin(); itcurr!= objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->getType() == obtm->getObjectTypeByName("Star System")) { StarSystem* sysData = (StarSystem*) ob->getObjectBehaviour(); if(sysData->getRegion() == losingRegion) { sysData->setRegion(0); removedSystems.insert(*itcurr); } } } } else { //External combat removes the losing leader and losing colonies. //1 point is awarded for the leader and each colony removed string shipType; //set shiptype, losing/winning regions, and send home the losing leader for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) { IGObject::Ptr ob = objectmanager->getObject(i->first); Fleet* f = (Fleet*) ob->getObjectBehaviour(); if(f->getOwner() != winner) { losingRegion = i->second; shipType = ob->getName(); sendHome(i->first); } else { winningRegion = i->second; } } //set the correct resource type int resourceType; if(shipType.compare("Merchant Leader") == 0) { resourceType = 4; } else if(shipType.compare("Scientist Leader") == 0) { resourceType = 5; } else if(shipType.compare("Settler Leader") == 0) { resourceType = 6; } else { resourceType = 7; } //add 1 to the winner for removing the leader Player::Ptr player = playermanager->getPlayer(winner); player->setScore(resourceType - 3, player->getScore(resourceType-3) + 1); //remove all losing colonies objects = objectmanager->getAllIds(); for(itcurr = objects.begin(); itcurr!= objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->getType() == obtm->getObjectTypeByName("Planet")) { IGObject::Ptr sys = objectmanager->getObject(ob->getParent()); StarSystem* sysData = (StarSystem*) sys->getObjectBehaviour(); if(sysData->getRegion() == losingRegion) { Planet* p = (Planet*) ob->getObjectBehaviour(); sysData->setRegion(0); if(p->getResource(resourceType) > 0) { p->removeResource(resourceType, 1); player->setScore(resourceType - 3, player->getScore(resourceType-3) + 1); } else { removedSystems.insert(sys->getID()); } } else if(sysData->getRegion() == winningRegion) { sysData->setRegion(0); removedSystems.insert(sys->getID()); } } } } //rebuild region for(itcurr = removedSystems.begin(); itcurr!= removedSystems.end(); ++itcurr) { rebuildRegion(*itcurr); } //Check for combat combat = false; while(!combatQueue.empty() && !combat) { pair<bool, map<uint32_t, uint32_t> > temp = combatQueue.front(); combatQueue.pop(); isInternal = temp.first; combatants = temp.second; combat = true; uint32_t region = 0; for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end() && combat; i++) { IGObject::Ptr ob = objectmanager->getObject(i->first); IGObject::Ptr sys = objectmanager->getObject(ob->getParent()); StarSystem* sysData = (StarSystem*) sys->getObjectBehaviour(); i->second = sysData->getRegion(); if(region == 0) { region = sysData->getRegion(); } else if(region != sysData->getRegion()) { combat = false; } } } //Cleanup and Set visibility objects = objectmanager->getAllIds(); set<uint32_t> views; for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->getType() == obtm->getObjectTypeByName("Fleet") && !combat) { Fleet* f = (Fleet*) ob->getObjectBehaviour(); f->toggleCombat(); f->setCombatant(false); } //Set visibility views.insert(ob->getID()); } std::set<uint32_t> players = playermanager->getAllIds(); std::set<uint32_t> vis = objectmanager->getAllIds(); //clear the removed objecs objectmanager->clearRemovedObjects(); objects = objectmanager->getAllIds(); for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->isAlive()) { ob->getObjectBehaviour()->doOnceATurn(); } objectmanager->doneWithObject(ob->getID()); } for(std::set<uint32_t>::iterator itplayer = players.begin(); itplayer != players.end(); ++itplayer) { Player::Ptr player = playermanager->getPlayer(*itplayer); PlayerView::Ptr playerview = player->getPlayerView(); //Update visibility playerview->addVisibleObjects(views); for(std::set<uint32_t>::iterator itob = vis.begin(); itob != vis.end(); ++itob) { ObjectView::Ptr obv = playerview->getObjectView(*itob); if(obv == NULL) { if(objectmanager->getObject(*itob)->isAlive()) { playerview->addVisibleObject(*itob, true); } objectmanager->doneWithObject(*itob); } else { IGObject::Ptr ro = objectmanager->getObject(*itob); uint64_t obmt = ro->getModTime(); objectmanager->doneWithObject(*itob); if(obmt > obv->getModTime()) { obv->setModTime(obmt); playerview->updateObjectView(*itob); } } } // remove dead objects std::set<uint32_t> goneobjects; std::set<uint32_t> knownobjects = playerview->getVisibleObjects(); set_difference(knownobjects.begin(), knownobjects.end(), vis.begin(), vis.end(), inserter(goneobjects, goneobjects.begin())); for(std::set<uint32_t>::iterator itob = goneobjects.begin(); itob != goneobjects.end(); ++itob) { ObjectView::Ptr obv = playerview->getObjectView(*itob); if(!obv->isGone()) { obv->setGone(true); playerview->updateObjectView(*itob); } } //Replace colonist fleets int fleets = 0; IGObject::Ptr homePlanet; for(std::set<uint32_t>::iterator itob = objects.begin(); itob != objects.end(); ++itob) { IGObject::Ptr ob = objectmanager->getObject(*itob); if(ob->getName().compare("Colonist Fleet") == 0) { uint32_t owner = ((OwnedObject*)(ob->getObjectBehaviour()))->getOwner(); if(owner == *itplayer) { fleets++; } } if(ob->getName().compare(string(player->getName() + "'s Home Planet")) == 0) { homePlanet = ob; } } for(int i = fleets; i < 6; i++) { IGObject::Ptr fleet = fleetBuilder->createFleet(FleetBuilder::PASSENGER_FLEET, FleetBuilder::RANDOM_SHIP, player, homePlanet, "Colonist Fleet"); game->getObjectManager()->addObject(fleet); player->getPlayerView()->addVisibleObject(fleet->getID(), true); } //Send end of turn message to each player Message::Ptr msg( new Message() ); msg->setSubject("Combat Complete!"); stringstream out; Player::Ptr win = playermanager->getPlayer(winner); out << win->getName() << " has won the battle with a strength of "; out << strength[winner] << "!"; msg->setBody(out.str()); player->postToBoard(msg); msg.reset( new Message() ); msg->setSubject("Turn complete"); stringstream out2; out2 << "Your Current Score: \n"; out2 << "Money: " << player->getScore(1) << "\n"; out2 << "Technology: " << player->getScore(2) << "\n"; out2 << "People: " << player->getScore(3) << "\n"; out2 << "Raw Materials: " << player->getScore(4) << "\n"; out2 << "Alien Artifacts: " << player->getScore(5); msg->setBody(out2.str()); player->postToBoard(msg); } if(combat) { initCombat(); } playermanager->updateAll(); }
//Setup the next turn to be ready for combat void TaeTurn::initCombat() { std::set<uint32_t>::iterator itcurr; Game* game = Game::getGame(); ObjectManager* objectmanager = game->getObjectManager(); PlayerManager::Ptr playermanager = game->getPlayerManager(); ObjectTypeManager* obtm = game->getObjectTypeManager(); DesignStore::Ptr ds = game->getDesignStore(); //Pop the combat queue and set the combatants pair<bool, map<uint32_t, uint32_t> > temp; temp = combatQueue.front(); combatQueue.pop(); isInternal = temp.first; combatants = temp.second; strength.clear(); for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) { IGObject::Ptr ob = Game::getGame()->getObjectManager()->getObject(i->first); Fleet* f = (Fleet*) ob->getObjectBehaviour(); strength[f->getOwner()] = 0; } set<uint32_t> owners; set<uint32_t> regions; string shipType; for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) { IGObject::Ptr ob = objectmanager->getObject(i->first); Fleet* leader = (Fleet*) (ob)->getObjectBehaviour(); //look for the shiptype which this combat is associated with if(shipType.empty()) { if(isInternal) { shipType = "ScientistShip"; } else { //Set shiptype to the type corresponding to the leader uint32_t ship = leader->getShips().begin()->first; shipType = ds->getDesign(ship)->getName(); size_t pos = shipType.find("Leader"); if(pos != shipType.npos) { shipType.erase(pos, 6); } } } owners.insert(leader->getOwner()); //Set which regions are involved in combat if(regions.count(i->second) <= 0) { regions.insert(i->second); } //Set initial internal combat strength if(isInternal) { IGObject::Ptr starSys = objectmanager->getObject(ob->getParent()); StarSystem* starSysData = (StarSystem*)(starSys->getObjectBehaviour()); Vector3d pos = starSysData->getPosition(); //Search for bordering science colonies //east-west neighbors for(int i = -1; i < 2; i+=2) { set<uint32_t> ids = objectmanager->getObjectsByPos(pos+Vector3d(80000*i,0,0), 1); for(set<uint32_t>::iterator j=ids.begin(); j != ids.end(); j++) { IGObject::Ptr tempObj = objectmanager->getObject(*j); if(tempObj->getType() == obtm->getObjectTypeByName("Planet")) { Planet* p = (Planet*)(tempObj->getObjectBehaviour()); if(p->getResource(5) > 0) { addReinforcement(leader->getOwner()); } } } } //north-south neighbors for(int i = -1; i < 2; i+=2) { set<uint32_t> ids = objectmanager->getObjectsByPos(pos+Vector3d(0,80000*i,0), 1); for(set<uint32_t>::iterator j=ids.begin(); j != ids.end(); j++) { IGObject::Ptr tempObj = objectmanager->getObject(*j); if(tempObj->getType() == obtm->getObjectTypeByName("Planet")) { Planet* p = (Planet*)(tempObj->getObjectBehaviour()); if(p->getResource(5) > 0) { addReinforcement(leader->getOwner()); } } } } } } //Set which resource will be awarded int resourceType; if(shipType.compare("MerchantShip") == 0) { resourceType = 4; } else if(shipType.compare("ScientistShip") == 0) { resourceType = 5; } else if(shipType.compare("SettlerShip") == 0) { resourceType = 6; } else { resourceType = 7; } //Set all fleets to combat mode. Flag the fleets whose owners are //directly involved in combat. std::set<uint32_t> views; std::set<uint32_t> objects = objectmanager->getAllIds(); for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->getType() == obtm->getObjectTypeByName("Fleet")) { Fleet* f = (Fleet*) ob->getObjectBehaviour(); f->toggleCombat(); //check to see if this fleet is a combatant if(owners.count(f->getOwner()) > 0) { uint32_t ship = f->getShips().begin()->first; string name = ds->getDesign(ship)->getName(); if(name.compare(shipType) == 0) { f->setCombatant(true); } } //Set visibility views.insert(ob->getID()); } //Set initial external combat strength else if(ob->getType() == obtm->getObjectTypeByName("Planet") && !isInternal) { Planet* p = (Planet*) ob->getObjectBehaviour(); StarSystem* sys = (StarSystem*) objectmanager->getObject(ob->getParent())->getObjectBehaviour(); if(regions.count(sys->getRegion()) > 0) { if(p->getResource(resourceType) > 0) { for(map<uint32_t, uint32_t>::iterator i = combatants.begin(); i != combatants.end(); ++i) { if(i->second == sys->getRegion()) { Fleet* leader = (Fleet*) (objectmanager->getObject(i->first))->getObjectBehaviour(); addReinforcement(leader->getOwner()); } } } } } } //Send message to players letting them know about combat Message::Ptr msg( new Message() ); msg->setSubject("COMBAT!"); stringstream out; out << "The next turn is an "; if(isInternal) { out << "INTERNAL "; } else { out << "EXTERNAL "; } out << "combat turn! Combatants are: "; out << playermanager->getPlayer(*owners.begin())->getName(); out << " with an initial strength of "; out << strength[*owners.begin()] << " and "; out << playermanager->getPlayer(*owners.end())->getName(); out << " with an initial strength of "; out << strength[*owners.end()]; msg->setBody(out.str()); std::set<uint32_t> players = playermanager->getAllIds(); for(itcurr = players.begin(); itcurr != players.end(); ++itcurr) { Player::Ptr player = playermanager->getPlayer(*itcurr); player->postToBoard(Message::Ptr( new Message(*msg))); player->getPlayerView()->addVisibleObjects( views ); } }
bool Move::doOrder(IGObject * ob){ Vector3d dest = coords->getPosition(); Fleet* fleet = ((Fleet*)(ob->getObjectBehaviour())); unsigned long long distance = dest.getDistance(fleet->getPosition()); unsigned long long max_speed = 3000000; Logger::getLogger()->debug("Moving %lld at %lld speed", distance, max_speed); if(distance <= max_speed){ uint32_t parentid; Logger::getLogger()->debug("Object(%d)->Move->doOrder(): Is arriving at [%lld, %lld, %lld] ", ob->getID(), dest.getX(), dest.getY(), dest.getZ()); fleet->setVelocity(Vector3d(0,0,0)); parentid = ob->getParent(); // recontainerise if necessary int containertype = Game::getGame()->getObjectManager()->getObject(parentid)->getContainerType(); Game::getGame()->getObjectManager()->doneWithObject(parentid); if(fleet->getPosition() != dest && containertype >= 1){ //removeFromParent(); std::set<unsigned int> oblist = ((MTSecTurn*)(Game::getGame()->getTurnProcess()))->getContainerIds(); for(std::set<unsigned int>::reverse_iterator itcurr = oblist.rbegin(); itcurr != oblist.rend(); ++itcurr){ IGObject* testedobject = Game::getGame()->getObjectManager()->getObject(*itcurr); Position3dObjectParam * pos = dynamic_cast<Position3dObjectParam*>(testedobject->getParameterByType(obpT_Position_3D)); SizeObjectParam * size = dynamic_cast<SizeObjectParam*>(testedobject->getParameterByType(obpT_Size)); if(pos == NULL || size == NULL){ Game::getGame()->getObjectManager()->doneWithObject(*itcurr); continue; } Vector3d pos1 = pos->getPosition(); uint64_t size1 = size->getSize(); uint64_t diff = dest.getDistance(pos1); if(diff <= fleet->getSize() / 2 + size1 / 2){ Logger::getLogger()->debug("Container object %d", *itcurr); //if(Game::getGame()->getObject(*itcurr)->getType() <= 2){ //if(*itcurr != id){ if(size1 >= fleet->getSize()){ if(*itcurr != parentid){ ob->removeFromParent(); ob->addToParent(*itcurr); } Game::getGame()->getObjectManager()->doneWithObject(*itcurr); parentid = *itcurr; break; } } Game::getGame()->getObjectManager()->doneWithObject(*itcurr); //} } if(parentid == 0){ ob->removeFromParent(); ob->addToParent(0); } } fleet->setPosition(dest); Message * msg = new Message(); msg->setSubject("Move order complete"); msg->setBody("The fleet '" + ob->getName() + "' has reached it's destination."); msg->addReference(rst_Action_Order, rsorav_Completion); msg->addReference(rst_Object, ob->getID()); msg->addReference(rst_Object, parentid); /* It's parent */ Game::getGame()->getPlayerManager()->getPlayer(fleet->getOwner())->postToBoard(msg); return true; }else{ Vector3d velo = (dest - fleet->getPosition()).makeLength(max_speed); Vector3d arriveat = fleet->getPosition()+velo; Logger::getLogger()->debug("Move->doOrder(%d): Velocity is [%lld, %lld, %lld] (will arrive at [%lld, %lld, %lld])", ob->getID(), velo.getX(), velo.getY(), velo.getZ(), arriveat.getX(), arriveat.getY(), arriveat.getZ()); fleet->setVelocity(velo); uint32_t parentid = ob->getParent(); // recontainerise if necessary uint32_t containertype = Game::getGame()->getObjectManager()->getObject(parentid)->getContainerType(); Game::getGame()->getObjectManager()->doneWithObject(parentid); if(fleet->getPosition() != arriveat && containertype >= 1){ //removeFromParent(); std::set<uint32_t> oblist = ((MTSecTurn*)(Game::getGame()->getTurnProcess()))->getContainerIds(); for(std::set<uint32_t>::reverse_iterator itcurr = oblist.rbegin(); itcurr != oblist.rend(); ++itcurr){ IGObject* testedobject = Game::getGame()->getObjectManager()->getObject(*itcurr); Position3dObjectParam * pos = dynamic_cast<Position3dObjectParam*>(testedobject->getParameterByType(obpT_Position_3D)); SizeObjectParam * size = dynamic_cast<SizeObjectParam*>(testedobject->getParameterByType(obpT_Size)); if(pos == NULL || size == NULL){ Game::getGame()->getObjectManager()->doneWithObject(*itcurr); continue; } Vector3d pos1 = pos->getPosition(); uint64_t size1 = size->getSize(); uint64_t diff = arriveat.getDistance(pos1); if(diff <= fleet->getSize() / 2 + size1 / 2){ Logger::getLogger()->debug("Container object %d", *itcurr); //if(Game::getGame()->getObject(*itcurr)->getType() <= 2){ //if(*itcurr != id){ if(size1 >= fleet->getSize()){ if(*itcurr != parentid){ ob->removeFromParent(); ob->addToParent(*itcurr); } Game::getGame()->getObjectManager()->doneWithObject(*itcurr); parentid = *itcurr; break; } } Game::getGame()->getObjectManager()->doneWithObject(*itcurr); //} } if(parentid == 0){ ob->removeFromParent(); ob->addToParent(0); } } fleet->setPosition(arriveat); return false; } }
void RSPCombat::resolveCombatantsToObjects(std::vector<Combatant*> combatants) { std::map<objectid_t, bool> colonydead; std::map<objectid_t, uint32_t> damagemap; for(std::vector<Combatant*>::iterator itcombat = combatants.begin(); itcombat != combatants.end(); ++itcombat) { Combatant* combatant = *itcombat; if(combatant->getShipType() == 0) { //special for planets std::map<objectid_t, bool>::iterator itplanet = colonydead.find(combatant->getObject()); if(itplanet == colonydead.end()) { colonydead[combatant->getObject()] = combatant->isDead(); } else { itplanet->second &= combatant->isDead(); } } else if(combatant->isDead()) { IGObject::Ptr obj = objectcache[combatant->getObject()]; Fleet* fleet = dynamic_cast<Fleet*>(obj->getObjectBehaviour()); if(fleet != NULL) { fleet->removeShips(combatant->getShipType(), 1); if(fleet->totalShips() == 0) { //the fleet dead //message player msgstrings[combatant->getOwner()] += str(boost::format("Your fleet %1% was destroyed. ") % obj->getName()); //remove object uint32_t queueid = static_cast<OrderQueueObjectParam*>(obj->getParameterByType(obpT_Order_Queue))->getQueueId(); OrderQueue::Ptr queue = Game::getGame()->getOrderManager()->getOrderQueue(queueid); queue->removeOwner(combatant->getOwner()); queue->removeAllOrders(); Game::getGame()->getObjectManager()->scheduleRemoveObject(obj->getID()); Game::getGame()->getPlayerManager()->getPlayer(fleet->getOwner())->getPlayerView()->removeOwnedObject(obj->getID()); } } } else { if(damagemap.find(combatant->getObject()) == damagemap.end()) { damagemap[combatant->getObject()] = combatant->getDamage(); } else { damagemap[combatant->getObject()] += combatant->getDamage(); } } } for(std::map<objectid_t, uint32_t>::iterator itobj = damagemap.begin(); itobj != damagemap.end(); ++itobj) { IGObject::Ptr obj = objectcache[itobj->first]; Fleet* fleet = dynamic_cast<Fleet*>(obj->getObjectBehaviour()); if(fleet == NULL) { warningLog("Fleet was not a fleet"); continue; } fleet->setDamage(itobj->second); } for(std::map<objectid_t, bool>::iterator itplanet = colonydead.begin(); itplanet != colonydead.end(); ++itplanet) { if(itplanet->second) { IGObject::Ptr obj = objectcache[itplanet->first]; Planet* planet = dynamic_cast<Planet*>(obj->getObjectBehaviour()); if(planet == NULL) { warningLog("Planet was not a planet"); continue; } resourcetypeid_t homeplanetres = Game::getGame()->getResourceManager()->getResourceDescription("Home Planet")->getResourceType(); bool ishomeplanet = (planet->getResource(homeplanetres) == 1); //planet has fallen if(ishomeplanet) { planet->removeResource(homeplanetres, 1); } uint32_t oldowner = planet->getOwner(); planet->setOwner(0); uint32_t queueid = static_cast<OrderQueueObjectParam*>(obj->getParameterByType(obpT_Order_Queue))->getQueueId(); OrderQueue::Ptr queue = Game::getGame()->getOrderManager()->getOrderQueue(queueid); queue->removeOwner(oldowner); queue->removeAllOrders(); Game::getGame()->getPlayerManager()->getPlayer(oldowner)->getPlayerView()->removeOwnedObject(obj->getID()); } } }
bool MergeFleet::doOrder(IGObject::Ptr ob){ IGObject::Ptr parent = Game::getGame()->getObjectManager()->getObject(ob->getParent()); Fleet *myfleet = (Fleet*)(ob->getObjectBehaviour()); //find fleet to merge with uint32_t targetid = 0; std::set<uint32_t> oblist = parent->getContainedObjects(); for(std::set<uint32_t>::iterator itcurr = oblist.begin(); itcurr != oblist.end(); ++itcurr){ if(*itcurr == ob->getID()) continue; IGObject::Ptr ptarget = Game::getGame()->getObjectManager()->getObject(*itcurr); if(ptarget->getType() == ob->getType()){ Fleet* pfleet = (Fleet*)(ptarget->getObjectBehaviour()); if(pfleet->getOwner() == myfleet->getOwner()){ if(pfleet->getSize() + myfleet->getSize() > pfleet->getPosition().getDistance(myfleet->getPosition())){ targetid = *itcurr; Game::getGame()->getObjectManager()->doneWithObject(*itcurr); break; } } } Game::getGame()->getObjectManager()->doneWithObject(*itcurr); } if(targetid == 0){ Message::Ptr msg( new Message() ); msg->setSubject("Merge Fleet order canceled"); msg->setBody("No target fleet at this location"); msg->addReference(rst_Action_Order, rsorav_Canceled); msg->addReference(rst_Object, ob->getID()); Game::getGame()->getPlayerManager()->getPlayer(((Fleet*)(ob->getObjectBehaviour()))->getOwner())->postToBoard(msg); }else{ IGObject::Ptr target = Game::getGame()->getObjectManager()->getObject(targetid); Message::Ptr msg( new Message() ); msg->setSubject("Merge Fleet order complete"); msg->setBody("The two fleets have been merged"); msg->addReference(rst_Action_Order, rsorav_Completion); msg->addReference(rst_Object, ob->getID()); msg->addReference(rst_Object, target->getID()); Fleet *tfleet = (Fleet*)(target->getObjectBehaviour()); IdMap ships = myfleet->getShips(); for(IdMap::iterator itcurr = ships.begin(); itcurr != ships.end(); ++itcurr){ tfleet->addShips(itcurr->first, itcurr->second); } //remove the fleet from the physical universe ob->removeFromParent(); Game::getGame()->getObjectManager()->scheduleRemoveObject(ob->getID()); Game::getGame()->getPlayerManager()->getPlayer(myfleet->getOwner())->getPlayerView()->removeOwnedObject(ob->getID()); Game::getGame()->getObjectManager()->doneWithObject(target->getID()); Game::getGame()->getPlayerManager()->getPlayer(myfleet->getOwner())->postToBoard(msg); } return true; }
bool Colonise::doOrder(IGObject::Ptr ob){ //if not close, move IGObject::Ptr target = Game::getGame()->getObjectManager()->getObject(ob->getParent()); if(target == NULL || target->getType() != Game::getGame()->getObjectTypeManager()->getObjectTypeByName("Planet")){ Logger::getLogger()->debug("Object(%d)->Colonise->doOrder(): Target was not valid.", ob->getID()); Game::getGame()->getObjectManager()->doneWithObject(ob->getParent()); Message::Ptr msg( new Message() ); msg->setSubject("Colonise order canceled"); msg->setBody("Not at a planet, colonisation canceled"); msg->addReference(rst_Action_Order, rsorav_Canceled); msg->addReference(rst_Object, ob->getID()); Game::getGame()->getPlayerManager()->getPlayer(((Fleet*)(ob->getObjectBehaviour()))->getOwner())->postToBoard(msg); return true; } Fleet* fleet = (Fleet*)(ob->getObjectBehaviour()); Planet* planet = (Planet*)(target->getObjectBehaviour()); Message::Ptr msg( new Message() ); msg->addReference(rst_Object, ob->getID()); msg->addReference(rst_Object, target->getID()); if(planet->getOwner() != fleet->getOwner()){ if(planet->getOwner() != 0){ Logger::getLogger()->debug("Object(%d)->Colonise->doOrder(): Planet already owned.", ob->getID()); msg->setSubject("Colonisation failed"); msg->setBody("The planet you tried to colonise, is already owned by someone else."); msg->addReference(rst_Action_Order, rsorav_Canceled); }else{ DesignStore::Ptr ds = Game::getGame()->getDesignStore(); int shiptype = 0; int shiphp = 2000000; IdMap ships = fleet->getShips(); uint32_t colonisePropID = ds->getPropertyByName( "Colonise"); uint32_t armorPropID = ds->getPropertyByName( "Armour"); for(IdMap::iterator itcurr = ships.begin(); itcurr != ships.end(); ++itcurr){ Design::Ptr design = ds->getDesign(itcurr->first); if(design->getPropertyValue(colonisePropID) != 0.0 && shiphp > (int)design->getPropertyValue(armorPropID)){ shiptype = itcurr->first; shiphp = (int)design->getPropertyValue(armorPropID); } } Logger::getLogger()->debug("Object(%d)->Colonise->doOrder(): shiptype %d", ob->getID(), shiptype); if(shiptype != 0){ uint32_t oldowner = planet->getOwner(); planet->setOwner(fleet->getOwner()); Game::getGame()->getPlayerManager()->getPlayer(fleet->getOwner())->getPlayerView()->addOwnedObject(target->getID()); uint32_t queueid = static_cast<OrderQueueObjectParam*>(target->getParameterByType(obpT_Order_Queue))->getQueueId(); OrderQueue::Ptr queue = Game::getGame()->getOrderManager()->getOrderQueue(queueid); queue->removeOwner(oldowner); queue->addOwner(fleet->getOwner()); fleet->removeShips(shiptype, 1); msg->setSubject("Colonised planet"); msg->setBody("You have colonised a planet!"); msg->addReference(rst_Action_Order, rsorav_Completion); }else{ msg->setSubject("Colonisation failed"); msg->setBody("Your fleet did not have a frigate to colonise the planet"); msg->addReference(rst_Action_Order, rsorav_Invalid); } if(fleet->totalShips() == 0){ Game::getGame()->getObjectManager()->scheduleRemoveObject(ob->getID()); Game::getGame()->getPlayerManager()->getPlayer(fleet->getOwner())->getPlayerView()->removeOwnedObject(ob->getID()); } } }else{ Logger::getLogger()->debug("Object(%d)->Colonise->doOrder(): Was already owned by the player!", ob->getID()); msg->setSubject("Colonisation failed"); msg->setBody("You already own the planet you tried to colonise"); msg->addReference(rst_Action_Order, rsorav_Canceled); } Game::getGame()->getPlayerManager()->getPlayer(fleet->getOwner())->postToBoard(msg); Game::getGame()->getObjectManager()->doneWithObject(target->getID()); return true; }
void MinisecTurn::doTurn(){ std::set<uint32_t>::iterator itcurr; Game* game = Game::getGame(); OrderManager* ordermanager = game->getOrderManager(); ObjectManager* objectmanager = game->getObjectManager(); RSPCombat* combatstrategy = new RSPCombat(); PlayerManager::Ptr playermanager = game->getPlayerManager(); //sort by order type std::set<uint32_t> movers; std::set<uint32_t> otherorders; std::set<uint32_t> interceptors; containerids.clear(); std::set<uint32_t> possiblecombatants; std::set<uint32_t> objects = objectmanager->getAllIds(); for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->getType() == planettype || ob->getType() == fleettype){ possiblecombatants.insert(ob->getID()); OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(ob->getParameterByType(obpT_Order_Queue)); if(oqop != NULL){ OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(oqop->getQueueId()); if(orderqueue != NULL){ Order * currOrder = orderqueue->getFirstOrder(); if(currOrder != NULL){ if(currOrder->getType() == ordermanager->getOrderTypeByName("Move")){ movers.insert(ob->getID()); } else if (currOrder->getType() == ordermanager->getOrderTypeByName("Intercept")){ interceptors.insert(ob->getID()); }else{ otherorders.insert(ob->getID()); } } } } } if(ob->getContainerType() >= 1){ containerids.insert(ob->getID()); } objectmanager->doneWithObject(ob->getID()); } // do move for(itcurr = movers.begin(); itcurr != movers.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(ob->getParameterByType(obpT_Order_Queue)); OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(oqop->getQueueId()); Order * currOrder = orderqueue->getFirstOrder(); if(currOrder->doOrder(ob)){ orderqueue->removeFirstOrder(); }else{ orderqueue->updateFirstOrder(); } objectmanager->doneWithObject(ob->getID()); } // do interceptions for(itcurr = interceptors.begin(); itcurr != interceptors.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(ob->getParameterByType(obpT_Order_Queue)); OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(oqop->getQueueId()); Order * currOrder = orderqueue->getFirstOrder(); if(currOrder->doOrder(ob)){ orderqueue->removeFirstOrder(); }else{ orderqueue->updateFirstOrder(); } objectmanager->doneWithObject(ob->getID()); } // do combat std::list<std::map<uint32_t, std::set<uint32_t> > > combats; for(itcurr = possiblecombatants.begin(); itcurr != possiblecombatants.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); uint32_t playerid1; Vector3d pos1; uint32_t size1; if(ob->getType() == planettype){ Planet* planet = (Planet*)(ob->getObjectBehaviour()); playerid1 = planet->getOwner(); pos1 = planet->getPosition(); size1 = planet->getSize(); }else{ Fleet* fleet = (Fleet*)(ob->getObjectBehaviour()); playerid1 = fleet->getOwner(); pos1 = fleet->getPosition(); size1 = fleet->getSize(); } if(playerid1 == 0){ objectmanager->doneWithObject(ob->getID()); continue; } bool placed = false; for(std::list<std::map<uint32_t, std::set<uint32_t> > >::iterator itlist = combats.begin(); itlist != combats.end(); ++itlist){ std::map<uint32_t, std::set<uint32_t> > themap = *itlist; for(std::map<uint32_t, std::set<uint32_t> >::iterator itmap = themap.begin(); itmap != themap.end(); ++itmap){ std::set<uint32_t> theset = itmap->second; for(std::set<uint32_t>::iterator itset = theset.begin(); itset != theset.end(); ++itset){ IGObject::Ptr itbobj = objectmanager->getObject(*itset); uint32_t playerid2; Vector3d pos2; uint32_t size2; if(itbobj->getType() == planettype){ Planet* planet = (Planet*)(itbobj->getObjectBehaviour()); playerid2 = planet->getOwner(); pos2 = planet->getPosition(); size2 = planet->getSize(); }else{ Fleet* fleet = (Fleet*)(itbobj->getObjectBehaviour()); playerid2 = fleet->getOwner(); pos2 = fleet->getPosition(); size2 = fleet->getSize(); } if(playerid2 == 0){ objectmanager->doneWithObject(itbobj->getID()); continue; } uint64_t diff = pos1.getDistance(pos2); if(diff <= size1 / 2 + size2 / 2){ themap[playerid1].insert(ob->getID()); *itlist = themap; placed = true; objectmanager->doneWithObject(itbobj->getID()); break; } objectmanager->doneWithObject(itbobj->getID()); } if(placed) break; } if(placed) break; } if(!placed){ std::map<uint32_t, std::set<uint32_t> > themap; std::set<uint32_t> theset; theset.insert(ob->getID()); themap[playerid1] = theset; combats.push_back(themap); } objectmanager->doneWithObject(ob->getID()); } for(std::list<std::map<uint32_t, std::set<uint32_t> > >::iterator itlist = combats.begin(); itlist != combats.end(); ++itlist){ std::map<uint32_t, std::set<uint32_t> > themap = *itlist; if(themap.size() >= 2){ combatstrategy->doCombat(themap); } } objectmanager->clearRemovedObjects(); // do other orders (nop, buildfleet, colonise) for(itcurr = otherorders.begin(); itcurr != otherorders.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob != NULL){ if(ob->getType() == planettype || ob->getType() == fleettype){ OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(ob->getParameterByType(obpT_Order_Queue)); if(oqop != NULL){ OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(oqop->getQueueId()); if(orderqueue != NULL){ Order * currOrder = orderqueue->getFirstOrder(); if(currOrder != NULL){ if(currOrder->doOrder(ob)){ orderqueue->removeFirstOrder(); }else{ orderqueue->updateFirstOrder(); } } } } } objectmanager->doneWithObject(ob->getID()); } } objectmanager->clearRemovedObjects(); // to once a turn (right at the end) objects = objectmanager->getAllIds(); for(itcurr = objects.begin(); itcurr != objects.end(); ++itcurr) { IGObject::Ptr ob = objectmanager->getObject(*itcurr); if(ob->isAlive()){ ob->getObjectBehaviour()->doOnceATurn(); } objectmanager->doneWithObject(ob->getID()); } // find the objects that are visible to each player std::set<uint32_t> vis = objectmanager->getAllIds(); std::set<uint32_t> players = playermanager->getAllIds(); uint32_t numaliveplayers = 0; uint32_t numdeadplayers = 0; for(std::set<uint32_t>::iterator itplayer = players.begin(); itplayer != players.end(); ++itplayer){ Player::Ptr player = playermanager->getPlayer(*itplayer); PlayerView::Ptr playerview = player->getPlayerView(); for(std::set<uint32_t>::iterator itob = vis.begin(); itob != vis.end(); ++itob){ ObjectView::Ptr obv = playerview->getObjectView(*itob); if(!obv){ if(objectmanager->getObject(*itob)->isAlive()){ playerview->addVisibleObject( *itob, true ); } objectmanager->doneWithObject(*itob); }else{ IGObject::Ptr ro = objectmanager->getObject(*itob); uint64_t obmt = ro->getModTime(); objectmanager->doneWithObject(*itob); if(obmt > obv->getModTime()){ obv->setModTime(obmt); playerview->updateObjectView(*itob); } } } // remove dead objects std::set<uint32_t> goneobjects; std::set<uint32_t> knownobjects = playerview->getVisibleObjects(); set_difference(knownobjects.begin(), knownobjects.end(), vis.begin(), vis.end(), inserter(goneobjects, goneobjects.begin())); for(std::set<uint32_t>::iterator itob = goneobjects.begin(); itob != goneobjects.end(); ++itob){ ObjectView::Ptr obv = playerview->getObjectView(*itob); if(!obv->isGone()){ obv->setGone(true); playerview->updateObjectView(*itob); } } if(!player->isAlive() || playerview->getNumberOwnedObjects() == 0){ if(player->isAlive()){ Message::Ptr msg( new Message() ); msg->setSubject("You lost"); msg->setBody("You do not own any objects, therefore you game has finished."); msg->addReference(rst_Action_Player, rspav_Eliminated); player->postToBoard(msg); player->setIsAlive(false); } numdeadplayers++; }else{ numaliveplayers++; } } if(numaliveplayers == 1){ //find alive player Player::Ptr player; for(std::set<uint32_t>::iterator itplayer = players.begin(); itplayer != players.end(); ++itplayer){ player = playermanager->getPlayer(*itplayer); if(player->isAlive()) break; } if(player->getScore(0) != numdeadplayers - 1){ Message::Ptr msg( new Message() ); msg->setSubject("You won!"); msg->setBody("You have eliminated all the competing players. Congratulations!"); player->postToBoard(msg); player->setScore(0, numdeadplayers - 1); } } playermanager->updateAll(); delete combatstrategy; }