//This function gets the top bid for the given object pair<IGObject::Ptr ,uint32_t> Colonize::getTopPlayerAndBid(IGObject::Ptr obj) { pair<IGObject::Ptr ,uint32_t> result; result.second = 0; Planet* origin = dynamic_cast<Planet*>(obj->getObjectBehaviour()); assert(origin); Logger::getLogger()->debug("\tCollecting all bids on object %s",origin->getName().c_str()); Game* game = Game::getGame(); OrderManager* ordM = game->getOrderManager(); ObjectManager* objM = game->getObjectManager(); //Construct the map to be used, the identifier is the planet, the value is the bid map<IGObject::Ptr ,uint32_t> bids; //Get all objects from object manager set<uint32_t> objectsIds = objM->getAllIds(); //Iterate over every object for(set<uint32_t>::iterator i = objectsIds.begin(); i != objectsIds.end(); ++i) { //Get current object IGObject::Ptr currObj = objM->getObject(*i); //Print out current planet Planet* bidder = dynamic_cast<Planet*>(currObj->getObjectBehaviour()); if (bidder != NULL) { Logger::getLogger()->debug("\t\tLooking at orders on object %s",bidder->getName().c_str()); } //Get order queue from object OrderQueueObjectParam* oqop = dynamic_cast<OrderQueueObjectParam*>(currObj->getParameterByType(obpT_Order_Queue)); OrderQueue::Ptr oq; //Validate that the oq exists if(oqop != NULL && (oq = ordM->getOrderQueue(oqop->getQueueId())) != NULL) { //Iterate over all orders for (uint32_t j = 0; j < oq->getNumberOrders(); j++) { OwnedObject *orderedObj = dynamic_cast<OwnedObject*>(currObj->getObjectBehaviour()); Order* order = NULL; if ( orderedObj != NULL ) { order = oq->getOrder(j, orderedObj->getOwner()); } Logger::getLogger()->debug("\t\tThere exists a %s order on %s", order->getName().c_str(), bidder->getName().c_str()); //if order is a colonize order if( order != NULL && order->getName() == "Colonize") { Colonize* colonize = dynamic_cast<Colonize*>(order); assert(colonize); //Get the list of planetIDs and the # of units to move IdMap list = colonize->getTargetList()->getList(); //Iterate over all suborders for(IdMap::iterator i = list.begin(); i != list.end(); ++i) { uint32_t planetID = i->first; uint32_t numUnits = i->second; format debug("\t\t\tEncountered suborder to Colonize %1% with %2% units"); debug % planetID; debug % numUnits; Logger::getLogger()->debug(debug.str().c_str()); IGObject::Ptr target = Game::getGame()->getObjectManager()->getObject(planetID); if ( target == obj ) { bids[currObj] += numUnits; } } } else if ( order->getName() != "Colonize") { j = oq->getNumberOrders() + 1; //force the loop to exit, we have "left" the frontal Colonize orders } } currObj->touchModTime(); } objM->doneWithObject(currObj->getID()); } //Iterate over all bids and restrict them to the maximum armies availible on that planet for(map<IGObject::Ptr ,uint32_t>::iterator i = bids.begin(); i != bids.end(); ++i) { Logger::getLogger()->debug("Iterating over all bids to pick the highest legal bid."); //FIXME: Somewhere in this "for" the server crashes when a single bid is created for 1 unit when planet only has 1 unit left //Restrict players bid to 1 less than their current reinforcements Planet* planet = dynamic_cast<Planet*>(i->first->getObjectBehaviour()); assert(planet); result.first = i->first; uint32_t numUnits = i->second; uint32_t maxUnits = planet->getResource("Army").first; //If there is overflow of numUnits, check for maxUnits over 0 insures we don't set unsigned to < 0 if ( numUnits >= maxUnits && maxUnits > 0) { if ( maxUnits > 0) numUnits = maxUnits - 1; else numUnits = 0; } i->second = numUnits; result.second = i->second; } sendPlayerMessages(obj, bids,result); if (result.first == NULL) { } format debugMsg("Found highest bidder to be from planet #%1% with %2% units"); debugMsg % result.first->getName(); debugMsg % result.second; Logger::getLogger()->debug(debugMsg.str().c_str()); return result; }
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"); } }