//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()); } } }
//End the game void gameOver() { Game* game = Game::getGame(); PlayerManager::Ptr pm = game->getPlayerManager(); map<uint32_t, uint32_t> finalScore; set<uint32_t>::iterator itcurr; set<uint32_t> players = pm->getAllIds(); //Find each player's final score for(itcurr = players.begin(); itcurr != players.end(); itcurr++) { Player::Ptr p = pm->getPlayer(*itcurr); uint32_t artifacts = p->getScore(5); //change artifact points to improve the types with the lowest //points while(artifacts > 0) { int lowest = 1; for(int i = 2; i < 5; i++) { if(p->getScore(i) < p->getScore(lowest)) { lowest = i; } } p->setScore(lowest, p->getScore(lowest) + 1); artifacts--; } //Find the final score int low = 1; for(int i = 2; i < 5; i++) { if(p->getScore(i) < p->getScore(low)) { low = i; } } finalScore[*itcurr] = p->getScore(low); } //Find the winner uint32_t winner = 0; for(map<uint32_t, uint32_t>::iterator i = finalScore.begin(); i != finalScore.end(); i++) { if(winner == 0 || i->second > finalScore[winner]) { winner = i->first; } } for(itcurr = players.begin(); itcurr != players.end(); itcurr++) { Player::Ptr p = pm->getPlayer(*itcurr); //Send message to each player Message::Ptr msg( new Message() ); msg->setSubject("GAME OVER!"); stringstream out; Player::Ptr win = pm->getPlayer(winner); out << win->getName() << " has won the game with a score of "; out << finalScore[winner] << "! "; out << "Your final score after distributing your alien artifacts was: "; out << finalScore[*itcurr]; msg->setBody(out.str()); p->postToBoard(msg); p->setIsAlive(false); } }
void TaeTurn::doTurn() { //check to make sure the game is still ging and this is not a combat turn if(isGameOver) { gameOver(); return; } else if(combat) { doCombatTurn(); return; } 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(); //build map for storing orders std::map<uint32_t, std::list<IGObject::Ptr > > playerOrders; containerids.clear(); //separate orders by player 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) { uint32_t owner = ((OwnedObject*)(ob->getObjectBehaviour()))->getOwner(); std::list<IGObject::Ptr >::iterator i = playerOrders[owner].end(); playerOrders[owner].insert(i, ob); } } } } } //Do orders for players in the correct order //The order in which orders are processed is rotated each turn std::set<uint32_t> players = playermanager->getAllIds(); itcurr = players.begin(); for(int i = 0; i < playerTurn; i++) { itcurr++; } for(uint32_t it = 0; it < players.size(); it++) { if(itcurr == players.end()) { itcurr = players.begin(); } if(playerOrders[*itcurr].size() > 0) { for(std::list<IGObject::Ptr >::iterator i = playerOrders[*itcurr].begin(); i != playerOrders[*itcurr].end(); i++) { OrderQueue::Ptr orderqueue = ordermanager->getOrderQueue(((OrderQueueObjectParam*)((*i)->getParameterByType(obpT_Order_Queue)))->getQueueId()); Order* currOrder = orderqueue->getFirstOrder(); if(currOrder!= NULL) { if(currOrder->doOrder(*i)) { orderqueue->removeFirstOrder(); } else { orderqueue->updateFirstOrder(); } } if((*i)->getContainerType() >= 1) { containerids.insert((*i)->getID()); } objectmanager->doneWithObject((*i)->getID()); } } itcurr++; } awardArtifacts(); //Check for end game condition of less than 3 artifacts remaining objects = objectmanager->getAllIds(); int numArtifacts = 0; 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) { numArtifacts++; } } } if(numArtifacts < 3) { isGameOver = true; gameOver(); return; } //Update which player's turn it is playerTurn = (playerTurn + 1) % playermanager->getNumPlayers(); objectmanager->clearRemovedObjects(); // to once a turn 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(); 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 == 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("Turn complete"); stringstream out; out << "Your Current Score: \n"; out << "Money: " << player->getScore(1) << "\n"; out << "Technology: " << player->getScore(2) << "\n"; out << "People: " << player->getScore(3) << "\n"; out << "Raw Materials: " << player->getScore(4) << "\n"; out << "Alien Artifacts: " << player->getScore(5); msg->setBody(out.str()); player->postToBoard(msg); //Alert players to the turn order for next round msg.reset( new Message() ); msg->setSubject("Turn Order"); string body = "The order for the next turn is: "; itcurr = players.begin(); for(int i = 0; i < playerTurn; i++) { itcurr++; } for(uint32_t it = 0; it < players.size(); it++) { if(itcurr == players.end()) { itcurr = players.begin(); } body += playermanager->getPlayer(*itcurr)->getName(); body += " "; itcurr++; } msg->setBody(body); player->postToBoard(msg); } //Initialize combat if the next turn is a combat turn if(combat) { initCombat(); } playermanager->updateAll(); }
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(); }
void RftsTurn::doTurn() { Game* game = Game::getGame(); OrderManager* ordermanager = game->getOrderManager(); ObjectManager* objectmanager = game->getObjectManager(); PlayerManager::Ptr pm = game->getPlayerManager(); set<uint32_t> objectsIds = objectmanager->getAllIds(); // currently just go through each obj and do each order // will be prioritized/sorted soon TODO for(set<uint32_t>::iterator i = objectsIds.begin(); i != objectsIds.end(); ++i) { IGObject::Ptr currObj = objectmanager->getObject(*i); OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(currObj->getParameterByType(obpT_Order_Queue)); OrderQueue::Ptr oq; if(oqop != NULL && (oq = ordermanager->getOrderQueue(oqop->getQueueId())) != NULL) { for(uint32_t j = 0; j < oq->getNumberOrders(); j++) { OwnedObject *orderedObj = dynamic_cast<OwnedObject*>(currObj->getObjectBehaviour()); assert(orderedObj); Order* order = oq->getOrder(j, orderedObj->getOwner()); if(order->doOrder(currObj)) { oq->removeOrder(j, orderedObj->getOwner()); j--; // list has been reordered } else oq->updateFirstOrder(); // CHECK } currObj->touchModTime(); } objectmanager->doneWithObject(currObj->getID()); } objectmanager->clearRemovedObjects(); // re-explore new area setPlayerVisibleObjects(); // to once a turn (right at the end) objectsIds = objectmanager->getAllIds(); for(std::set<uint32_t>::iterator i = objectsIds.begin(); i != objectsIds.end(); ++i) { IGObject::Ptr obj = objectmanager->getObject(*i); obj->getObjectBehaviour()->doOnceATurn(); objectmanager->doneWithObject(obj->getID()); } objectmanager->clearRemovedObjects(); // update in case fleets were destroyed in combat setPlayerVisibleObjects(); set<uint32_t> players = pm->getAllIds(); for(set<uint32_t>::iterator i = players.begin(); i != players.end(); ++i) PlayerInfo::getPlayerInfo(*i).clearPdbUpgrade(); Player::Ptr winner = getWinner(); if(winner != NULL) { string body; Message::Ptr gameOver( new Message() ); gameOver->setSubject("Game over!"); if( game->getTurnNumber() == static_cast<unsigned>(strtol(Settings::getSettings()->get("game_length").c_str(), NULL, 10)) ) body = "Game length elapsed, winner is: "; else body = "Overwhelming victory by: "; body += winner->getName(); gameOver->setBody(PlayerInfo::appAllVictoryPoints(body)); for(set<uint32_t>::iterator i = players.begin(); i != players.end(); ++i) pm->getPlayer(*i)->postToBoard( Message::Ptr( new Message(*gameOver) )); } int turn = game->getTurnNumber() % 3; if(turn == 0){ game->setTurnName("Production, Construction, Movement"); }else if(turn == 1){ game->setTurnName("Construction, Movement"); }else{ game->setTurnName("Movement"); } }
void RSPCombat::doCombat(std::map<uint32_t, IdSet> sides) { Game* game = Game::getGame(); PlayerManager::Ptr playermanager = game->getPlayerManager(); ObjectManager* objectmanager = game->getObjectManager(); DesignStore::Ptr ds = game->getDesignStore(); const char * const rsp[] = {"rock", "scissors", "paper"}; IdSet listallobids; IdSet listallplayerids; std::map<uint32_t, std::vector<Combatant*> > fleetcache; battlelogger.reset(new BattleXML::BattleLogger()); msgstrings.clear(); for(std::map<uint32_t, IdSet>::iterator itmap = sides.begin(); itmap != sides.end(); ++itmap) { std::vector<Combatant*> pcombatant; Player::Ptr player = playermanager->getPlayer(itmap->first); battlelogger->startSide(player->getName()); IdSet theset = itmap->second; for(IdSet::iterator itset = theset.begin(); itset != theset.end(); ++itset) { listallobids.insert(*itset); IGObject::Ptr obj = objectmanager->getObject (*itset); objectcache[*itset] = obj; if(obj->getType() == obT_Fleet) { Fleet* f2 = (Fleet*)(obj->getObjectBehaviour()); IdMap shiplist = f2->getShips(); uint32_t damage = f2->getDamage(); for(IdMap::reverse_iterator itship = shiplist.rbegin(); itship != shiplist.rend(); ++itship) { for(uint32_t i = 0; i < itship->second; i++) { Combatant* f1 = new Combatant(); f1->setOwner(itmap->first); f1->setObject(obj->getID()); f1->setShipType(itship->first); uint32_t mydamage = damage / std::max(1U, (unsigned int)(shiplist.size() - i)); f1->setDamage(mydamage); damage -= mydamage; std::string type = ds->getDesign(itship->first)->getName(); f1->setBattleXmlType(type); f1->setBattleXmlId(str(boost::format("%1%-%2%-%3%") % type % obj->getID() % i)); f1->setBattleXmlName(str(boost::format("%1%'s %2%, %3% %4%") % player->getName() % obj->getName() % type % i)); battlelogger->addCombatant(f1); pcombatant.push_back(f1); } } } else { int shipcount = 2; int homeplanetid = game->getResourceManager()->getResourceDescription("Home Planet")->getResourceType(); if(((Planet*)(obj->getObjectBehaviour()))->getResource(homeplanetid) == 1) { //three more for home planets shipcount += 3; } for(int i = 0; i < shipcount; i++) { Combatant* f1 = new Combatant(); f1->setOwner(itmap->first); f1->setObject(obj->getID()); f1->setShipType(0); f1->setBattleXmlType("planet"); f1->setBattleXmlId(str(boost::format("planet-%1%-%2%") % obj->getID() % i)); f1->setBattleXmlName(str(boost::format("%1%'s colony on %2%, Defense battery %3%") % player->getName() % obj->getName() % i)); battlelogger->addCombatant(f1); pcombatant.push_back(f1); } } } listallplayerids.insert(itmap->first); battlelogger->endSide(); //sort combatant list by ship type, descending sort(pcombatant.begin(), pcombatant.end(), CombatantSorter()); fleetcache[itmap->first] = pcombatant; } for(std::set<uint32_t>::iterator itplayer = listallplayerids.begin(); itplayer != listallplayerids.end(); ++itplayer) { msgstrings[*itplayer] = ""; } Random* random = Game::getGame()->getRandom(); Logger::getLogger()->debug("Combat start"); while(fleetcache.size() >= 2) { battlelogger->startRound(); uint32_t pos1, pos2; if(fleetcache.size() == 2) { pos1 = 0; pos2 = 1; } else { pos1 = pos2 = random->getInRange(0U, ((uint32_t)(fleetcache.size() - 1))); while(pos2 == pos1) { pos2 = random->getInRange(0U, ((uint32_t)(fleetcache.size() - 1))); } } std::map<uint32_t, std::vector<Combatant*> >::iterator itpa = fleetcache.begin(); advance(itpa, pos1); std::map<uint32_t, std::vector<Combatant*> >::iterator itpb = fleetcache.begin(); advance(itpb, pos2); std::vector<Combatant*> f1 = itpa->second; std::vector<Combatant*> f2 = itpb->second; uint32_t ownerid1 = f1[0]->getOwner(); uint32_t ownerid2 = f2[0]->getOwner(); std::string p1name = playermanager->getPlayer(ownerid1)->getName(); std::string p2name = playermanager->getPlayer(ownerid2)->getName(); int32_t r1 = random->getInRange((int32_t)0, (int32_t)2); int32_t r2 = random->getInRange((int32_t)0, (int32_t)2); std::map<Combatant*, uint32_t> d1, d2; battlelogger->log(str(boost::format("%1%'s fleet chooses %2%.") % p1name % rsp[r2])); battlelogger->log(str(boost::format("%1%'s fleet chooses %2%.") % p2name % rsp[(r2 + r1) % 3])); if(r1 == 0) { //draw battlelogger->log("It's a draw"); d1 = buildShotList(f1, true); d2 = buildShotList(f2, true); if(d1.size() != 0) doDamage(d1, f2); if(d2.size() != 0) doDamage(d2, f1); } else { if(r1 == 1) { //pa win battlelogger->log(str(boost::format("%1% wins.") % p1name)); d1 = buildShotList(f1); if(d1.size() == 0) { battlelogger->log(str(boost::format("%1%'s forces escape") % p1name)); msgstrings[ownerid1] += "Your Fleet escaped. "; for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1) continue; msgit->second += str(boost::format("%1%'s fleet of escaped. ") % p1name); } resolveCombatantsToObjects(f1); for(std::vector<Combatant*>::iterator itcombatant = f1.begin(); itcombatant != f1.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpa); battlelogger->endRound(); continue; } doDamage(d1, f2); } else { //pb win battlelogger->log(str(boost::format("%1% wins.") % p2name)); d2 = buildShotList(f2); if(d2.size() == 0) { battlelogger->log(str(boost::format("%1%'s forces escape") % p2name)); msgstrings[ownerid2] += "Your Fleet escaped. "; for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid2) continue; msgit->second += str(boost::format("%1%'s fleet of escaped. ") % p2name); } resolveCombatantsToObjects(f2); for(std::vector<Combatant*>::iterator itcombatant = f2.begin(); itcombatant != f2.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpb); battlelogger->endRound(); continue; } doDamage(d2, f1); } } if(isAllDead(f1)) { msgstrings[ownerid1] += str(boost::format("Your fleet was destroyed by %1%'s fleet. ") % p2name); msgstrings[ownerid2] += str(boost::format("You destroyed %1%'s fleet. ") % p1name); std::string deathmsg = str(boost::format("%1%'s fleet destroyed %2%'s fleet. ") % p1name % p2name); for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1 || msgit->first == ownerid2) continue; msgit->second += deathmsg; } resolveCombatantsToObjects(f1); for(std::vector<Combatant*>::iterator itcombatant = f1.begin(); itcombatant != f1.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpa); } if(isAllDead(f2)) { msgstrings[ownerid2] += str(boost::format("Your fleet was destroyed by %1%'s fleet. ") % p1name); msgstrings[ownerid1] += str(boost::format("You destroyed %1%'s fleet. ") % p2name); std::string deathmsg = str(boost::format("%1%'s fleet destroyed %2%'s fleet. ") % p2name % p1name); for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1 || msgit->first == ownerid2) continue; msgit->second += deathmsg; } resolveCombatantsToObjects(f2); for(std::vector<Combatant*>::iterator itcombatant = f2.begin(); itcombatant != f2.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpb); } battlelogger->endRound(); } std::string file = battlelogger->save(); if(!fleetcache.empty()) { std::vector<Combatant*> flast = fleetcache.begin()->second; resolveCombatantsToObjects(flast); msgstrings[flast[0]->getOwner()] += "Your Fleet survived combat."; for(std::vector<Combatant*>::iterator itcombatant = flast.begin(); itcombatant != flast.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(fleetcache.begin()); if(!fleetcache.empty()) { Logger::getLogger()->warning("fleetcache not empty at end of combat"); } } for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { Message::Ptr msg( new Message() ); msg->setSubject("Combat"); for(std::set<uint32_t>::iterator itob = listallobids.begin(); itob != listallobids.end(); ++itob) { msg->addReference(rst_Object, *itob); } for(std::set<uint32_t>::iterator itpl = listallplayerids.begin(); itpl != listallplayerids.end(); ++itpl) { msg->addReference(rst_Player, *itpl); } msg->setBody(msgit->second); Game::getGame()->getPlayerManager()->getPlayer(msgit->first)->postToBoard(msg); } for(std::map<uint32_t, IGObject::Ptr>::iterator itob = objectcache.begin(); itob != objectcache.end(); ++itob) { Game::getGame()->getObjectManager()->doneWithObject(itob->first); } objectcache.clear(); }