bool UnloadArmament::doOrder(IGObject::Ptr ob){ Fleet* fleet = dynamic_cast<Fleet*>(ob->getObjectBehaviour()); ObjectManager* obman = Game::getGame()->getObjectManager(); ObjectTypeManager* otman = Game::getGame()->getObjectTypeManager(); ResourceManager::Ptr resman = Game::getGame()->getResourceManager(); std::set<uint32_t>objs = obman->getObjectsByPos(fleet->getPosition(), 10000); IGObject::Ptr planetObj; Planet* planet; for (std::set<uint32_t>::const_iterator itcurr = objs.begin(); itcurr != objs.end(); ++itcurr) { if (obman->getObject(*itcurr)->getType() == otman->getObjectTypeByName("Planet")) { planetObj = obman->getObject(*itcurr); planet = dynamic_cast<Planet*>(planetObj->getObjectBehaviour()); Logger::getLogger()->debug("UnloadArmaments::doOrder Found Planet %s for Unload Armaments Order", planetObj->getName().c_str()); const uint32_t factoryType = resman->getResourceDescription("Factories")->getResourceType(); IdMap weapontype = weaponlist->getList(); for(IdMap::iterator weaponit = weapontype.begin(); weaponit != weapontype.end(); ++weaponit) { if (planet->removeResource(factoryType, 1)) { if (fleet->removeResource(weaponit->first, weaponit->second)) { Logger::getLogger()->debug("UnloadArmaments::doOrder success, adding to resource %d: #:%d", weaponit->first, weaponit->second); planet->addResource(weaponit->first, weaponit->second); planetObj->touchModTime(); return true; } } else { turns = 1; return true; } } } } return false; }
std::map<uint32_t, std::pair<std::string, uint32_t> > LoadArmament::generateListOptions(){ Logger::getLogger()->debug("Entering LoadArmament::generateListOptions"); std::map<uint32_t, std::pair<std::string, uint32_t> > options; Game* game = Game::getGame(); IGObject::Ptr selectedObj = game->getObjectManager()->getObject( game->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId()); Fleet* fleet = dynamic_cast<Fleet*>(selectedObj->getObjectBehaviour()); ObjectManager* obman = Game::getGame()->getObjectManager(); ObjectTypeManager* otman = Game::getGame()->getObjectTypeManager(); ResourceManager::Ptr resman = Game::getGame()->getResourceManager(); std::set<uint32_t>objs = obman->getObjectsByPos(fleet->getPosition(), 10000); for (std::set<uint32_t>::iterator itcurr = objs.begin(); itcurr != objs.end(); ++itcurr) { if (obman->getObject(*itcurr)->getType() == otman->getObjectTypeByName("Planet")) { IGObject::Ptr planetObj = obman->getObject(*itcurr); Planet* planet = dynamic_cast<Planet*>(planetObj->getObjectBehaviour()); Logger::getLogger()->debug("Found Planet %s for Load Armaments Order", planetObj->getName().c_str()); std::map<uint32_t, std::pair<uint32_t, uint32_t> > reslist = planet->getResources(); for (std::map<uint32_t, std::pair<uint32_t, uint32_t> >::iterator it = reslist.begin(); it != reslist.end(); ++it) { if (resman->getResourceDescription(it->first)->getUnitSingular() == "weapon") { options[it->first] = std::pair<std::string, uint32_t>(resman->getResourceDescription(it->first)->getNamePlural(), planet->getResourceSurfaceValue(it->first)); } } } } Logger::getLogger()->debug("Exiting LoadArmament::generateListOptions"); return options; }
//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()); } } }
map<uint32_t, pair<string, uint32_t> > Colonize::generateListOptions() { map<uint32_t, pair<string,uint32_t> > options; Game* game = Game::getGame(); ObjectManager* om = game->getObjectManager(); IGObject::Ptr selectedObj = game->getObjectManager()->getObject( game->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId()); Planet* planet = dynamic_cast<Planet*>(selectedObj->getObjectBehaviour()); assert(planet); om->doneWithObject(selectedObj->getID()); set<uint32_t> allObjs = om->getAllIds(); uint32_t availibleUnits = planet->getResource("Army").first + planet->getResource("Army").second - 1; /* This for loop will iterate over every adjacent planet. This is where the majority of the work occurs, and we populate our list. You see here we select an item of the map, in my case (*i)->getID(), and for that item we create a pair. If its a little hard to read, here is what I am doing: options[#] = pair<string,uint32_t>( "title", max# ); For my pair I set the title as the adjacent planet to move to, and set the max to availible units. */ for(set<uint32_t>::iterator i = allObjs.begin(); i != allObjs.end(); i++) { IGObject::Ptr currObj = om->getObject((*i)); Planet* owned = dynamic_cast<Planet*>(currObj->getObjectBehaviour()); if ( owned != NULL && owned->getOwner() == 0) { options[owned->getID()] = pair<string,uint32_t>( owned->getName(), availibleUnits ); } } return options; }
void Colonize::inputFrame(InputFrame::Ptr f, uint32_t playerid) { FleetOrder::inputFrame(f, playerid); Game *game = Game::getGame(); ObjectManager *obm = game->getObjectManager(); ObjectTypeManager *obtm = game->getObjectTypeManager(); IGObject::Ptr starSysObj = obm->getObject(starSys->getObjectId()); StarSystem* starSysData = (StarSystem*) starSysObj->getObjectBehaviour(); // Check to see if it is a legal system to colonize if(starSysObj->getType() == obtm->getObjectTypeByName("Star System") && !starSysData->canBeColonized(isMining)) { starSys->setObjectId(0); Logger::getLogger()->debug("Player tried to colonize a system which cannot be colonized."); } }
std::map<uint32_t, std::pair<std::string, uint32_t> > UnloadArmament::generateListOptions(){ Logger::getLogger()->debug("Entering UnloadArmament::generateListOptions"); std::map<uint32_t, std::pair<std::string, uint32_t> > options; Game* game = Game::getGame(); IGObject::Ptr selectedObj = game->getObjectManager()->getObject( game->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId()); Fleet* fleet = dynamic_cast<Fleet*>(selectedObj->getObjectBehaviour()); ResourceManager::Ptr resman = Game::getGame()->getResourceManager(); std::map<uint32_t, std::pair<uint32_t, uint32_t> > objs = fleet->getResources(); for (std::map<uint32_t, std::pair<uint32_t, uint32_t> >::iterator itcurr = objs.begin(); itcurr != objs.end(); ++itcurr) { options[itcurr->first] = std::pair<std::string, uint32_t>(resman->getResourceDescription(itcurr->first)->getNamePlural(), itcurr->second.first); } Logger::getLogger()->debug("Exiting UnloadArmament::generateListOptions"); return options; }
void Colonize::sendPlayerMessages(IGObject::Ptr obj, map<IGObject::Ptr ,uint32_t> bids, pair<IGObject::Ptr ,uint32_t> winner) { PlayerManager::Ptr pm = Game::getGame()->getPlayerManager(); Planet* target = dynamic_cast<Planet*>(obj->getObjectBehaviour()); assert(target); //Message subjects string loserSubject = "Colonize Bid for " + target->getName() + " Rejected"; string winnerSubject = "Colonize Bid for " + target->getName() + " Accepted"; for(map<IGObject::Ptr ,uint32_t>::iterator i = bids.begin(); i != bids.end(); i++ ) { Planet* ownerPlanet = dynamic_cast<Planet*>(i->first->getObjectBehaviour()); assert(ownerPlanet); Player::Ptr player = pm->getPlayer(ownerPlanet->getOwner()); assert(player); //Populate message's subject and body string subject; format body ("Colonize bid via %1% to colonize %2% with %3% units was %4%."); body % ownerPlanet->getName(); body % target->getName(); body % i->second; if ( i->first == winner.first ) { //If this is the winning bid subject = winnerSubject; body % "Accepted"; } else { //The bid did not win subject = loserSubject; body % "Rejected"; } Message::Ptr msg( new Message() ); msg->setSubject(subject); msg->setBody(body.str()); player->postToBoard(msg); } }
//Recurrsively rebuilds regions given a system. //If the system already has a region or is not occupied or //colonized, then this function returns. Otherwise it //sets the region based on its neighbors. void TaeTurn::rebuildRegion(uint32_t system) { Game* game = Game::getGame(); ObjectManager* obm = game->getObjectManager(); ObjectTypeManager* obtm = game->getObjectTypeManager(); set<uint32_t>::iterator itcurr; IGObject::Ptr sys = obm->getObject(system); StarSystem* sysData = (StarSystem*) sys->getObjectBehaviour(); //Check to make sure the system doesnt already have a region if(sysData->getRegion() != 0) { return; } //Check to make sure it is colonized or occupied set<uint32_t> children = sys->getContainedObjects(); for(itcurr = children.begin(); itcurr != children.end(); itcurr++) { IGObject::Ptr ob = obm->getObject(*itcurr); bool resource = true; bool occupied = false; if(ob->getType() == obtm->getObjectTypeByName("Planet")) { Planet* p = (Planet*) ob->getObjectBehaviour(); if(p->getResource(4) == 0 && p->getResource(5) == 0 && p->getResource(6) == 0 && p->getResource(7) == 0) { resource = false; } } else if(ob->getType() == obtm->getObjectTypeByName("Fleet")) { if(!Move::isBorderingScienceColony(sysData)) { sendHome(*itcurr); occupied = false; } else { occupied = true; } } if(!(resource || occupied)) { return; } } //Check to make sure this isnt a home system if(sys->getName().find("'s System") != string::npos) { return; } //Get neighbors set<uint32_t> regions; set<uint32_t> emptyNeighbors; Vector3d pos = sysData->getPosition(); //east-west neighbors for(int i = -1; i < 2; i+=2) { set<uint32_t> ids = obm->getObjectsByPos(pos+Vector3d(80000*i,0,0), 1); for(set<uint32_t>::iterator j=ids.begin(); j != ids.end(); j++) { IGObject::Ptr tempObj = obm->getObject(*j); if(tempObj->getType() == obtm->getObjectTypeByName("Star System")) { uint32_t r = ((StarSystem*)(tempObj->getObjectBehaviour()))->getRegion(); if(r == 0) { emptyNeighbors.insert(*j); } else if (regions.count(r) == 0) { regions.insert(r); } } } } //north-south neighbors for(int i = -1; i < 2; i+=2) { set<uint32_t> ids = obm->getObjectsByPos(pos+Vector3d(0,80000*i,0), 1); for(set<uint32_t>::iterator j=ids.begin(); j != ids.end(); j++) { IGObject::Ptr tempObj = obm->getObject(*j); if(tempObj->getType() == obtm->getObjectTypeByName("Star System")) { uint32_t r = ((StarSystem*)(tempObj->getObjectBehaviour()))->getRegion(); if(r == 0) { emptyNeighbors.insert(*j); } else if (regions.count(r) == 0) { regions.insert(r); } } } } //Set Region if(regions.size() == 0) { //If neighbors have no region, then create a new region sysData->setRegion(sys->getID()); stringstream out; out << sysData->getRegion(); Logger::getLogger()->debug(string("System " + sys->getName() + " added to region " + out.str()).c_str()); } else if(regions.size() == 1) { //If it neighbors 1 region, then set as that region sysData->setRegion(*(regions.begin())); stringstream out; out << sysData->getRegion(); Logger::getLogger()->debug(string("System " + sys->getName() + " added to region " + out.str()).c_str()); } else { //It should never border more than one region. If it reaches this point, then there is an error somewhere Logger::getLogger()->debug(string("** Unable to rebuild region! System, " + sys->getName() + " is bordering more than one region! ***").c_str()); } //Recurse on neighbors for(itcurr = emptyNeighbors.begin(); itcurr != emptyNeighbors.end(); itcurr++) { rebuildRegion(*itcurr); } }
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; }
//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::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"); } }
//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 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()); } } }
//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; }
bool Colonize::doOrder(IGObject::Ptr obj) { bool result = true; --turns; Planet* origin = dynamic_cast<Planet*>(obj->getObjectBehaviour()); assert(origin); Logger::getLogger()->debug("Starting a Colonize::doOrder on %s.",origin->getName().c_str()); //Get the list of objects and the # of units to colonize IdMap list = targetPlanet->getList(); //Collect all of the players bids and restrain them to 1 less than the current units map<IGObject::Ptr ,uint32_t> bids; for(IdMap::iterator i = list.begin(); i != list.end(); ++i) { uint32_t planetID = i->first; uint32_t numUnits = i->second; IGObject::Ptr target = Game::getGame()->getObjectManager()->getObject(planetID); //Restrain the number of units moved off of origin uint32_t maxUnits = origin->getResource("Army").first; numUnits = numUnits + bids[target]; //Add current bid on target to requests units (no tricksy bidding!) if ( numUnits >= maxUnits && maxUnits > 0) { if ( maxUnits > 0) numUnits = maxUnits - 1; else numUnits = 0; } bids[target] = numUnits; } //for each seperate planet bid on run the bid routine for(map<IGObject::Ptr ,uint32_t>::iterator i = bids.begin(); i != bids.end(); ++i) { Logger::getLogger()->debug("\tStarting to iterate over all players bids"); Planet* biddedPlanet = dynamic_cast<Planet*>(i->first->getObjectBehaviour()); assert(biddedPlanet); //Ensure the object IS a planet and the object is unowned //The object MAY be owned if a bid has occured and a winner was chosen //then all other bids on that planet will simply be ignored if ( biddedPlanet != NULL && biddedPlanet->getOwner() == 0) { Logger::getLogger()->debug("\tGetting the top player and bid for planet %s",biddedPlanet->getName().c_str()); //Get pair <owner's planet,bid> of top bidder pair<IGObject::Ptr ,uint32_t> topBidder = getTopPlayerAndBid(i->first); //Check if players bid is bigger than top bidder elsewhere - only did this because I wasn't sure //BUG: this code would force the reset of bid restriction // if ( i->second > topBidder.second ) { // topBidder.second = i->second; // topBidder.first = obj; // } Planet* ownerPlanet = dynamic_cast<Planet*>(topBidder.first->getObjectBehaviour()); assert(ownerPlanet); uint32_t player = ownerPlanet->getOwner(); biddedPlanet->setOwner(player); biddedPlanet->addResource("Army",topBidder.second); ownerPlanet->removeResource("Army",topBidder.second); //Inform colonize winner, and obj owner } else //Bidded planet is now owned { Logger::getLogger()->debug("\tNot getting top bidders, planet is already owned"); //inform player bid failed, obj is now owned by _person_, won bid with _#units_ } } return result; }
void BuildFleet::createFrame(OutputFrame::Ptr f, int pos) { Logger::getLogger()->debug("Enter: BuildFleet::createFrame()"); // set it to the high end of the production cost... this is a best case scenario where it gets all the factories IGObject::Ptr planet = Game::getGame()->getObjectManager()->getObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId()); // number of turns std::map<uint32_t, std::pair<uint32_t, uint32_t> > presources = static_cast<Planet*>(planet->getObjectBehaviour())->getResources(); Game::getGame()->getObjectManager()->doneWithObject(planet->getID()); uint32_t res_current; if(presources.find(1) != presources.end()){ res_current = presources.find(1)->second.first; }else{ res_current = 0; } uint32_t usedshipres = resources[1]; if(pos != 0 || usedshipres == 0){ turns = usedshipres; }else{ if(usedshipres <= res_current){ turns = 1; }else{ turns = usedshipres - res_current; } } Order::createFrame(f, pos); Logger::getLogger()->debug("Exit: BuildFleet::createFrame()"); }
bool BuildFleet::doOrder(IGObject::Ptr ob) { Logger::getLogger()->debug("Entering BuildFleet::doOrder"); Planet* planet = static_cast<Planet*>(ob->getObjectBehaviour()); Game* game = Game::getGame(); ResourceManager::Ptr resman = game->getResourceManager(); const uint32_t resType = resman->getResourceDescription("Factories")->getResourceType(); const uint32_t resValue = planet->getResourceSurfaceValue(resType); int ownerid = planet->getOwner(); if(ownerid == 0){ Logger::getLogger()->debug("Exiting BuildFleet::doOrder ownerid == 0"); //currently not owned by anyone, just forget about it return true; } uint32_t runningTotal = resources[1]; if (resValue == 0) { Message::Ptr msg(new Message()); msg->setSubject("Build Fleet order error"); msg->setBody(std::string("The construction of your new fleet \"") + fleetname->getString() + "\" has been delayed, you do not have any production points this turn."); Game::getGame()->getPlayerManager()->getPlayer(ownerid)->postToBoard(msg); return false; } else if(runningTotal > resValue) { if (planet->removeResource(resType, resValue)) { removeResource(1, resValue); runningTotal = resources[1]; uint32_t planetFactories = planet->getFactoriesPerTurn(); turns = static_cast<uint32_t>(ceil(runningTotal / planetFactories)); Message::Ptr msg(new Message()); msg->setSubject("Build Fleet order slowed"); msg->setBody(std::string("The construction of your new fleet \"") + fleetname->getString() + "\" has been delayed."); Game::getGame()->getPlayerManager()->getPlayer(ownerid)->postToBoard(msg); return false; } } else if(runningTotal <= resValue && planet->removeResource(resType, runningTotal)){ //create fleet //this is probably unnecessary resources[1] = 0; Game* game = Game::getGame(); IGObject::Ptr fleet = game->getObjectManager()->createNewObject(); game->getObjectTypeManager()->setupObject(fleet, game->getObjectTypeManager()->getObjectTypeByName("Fleet")); //add fleet to container fleet->addToParent(ob->getID()); fleet->setName(fleetname->getString().c_str()); Fleet * thefleet = dynamic_cast<Fleet*>(fleet->getObjectBehaviour()); thefleet->setSize(2); thefleet->setOwner(ownerid); // set ownerid thefleet->setPosition(planet->getPosition()); thefleet->setVelocity(Vector3d(0LL, 0ll, 0ll)); uint32_t queueid = Game::getGame()->getOrderManager()->addOrderQueue(fleet->getID(), ownerid); OrderQueueObjectParam* oqop = static_cast<OrderQueueObjectParam*>(fleet->getParameterByType(obpT_Order_Queue)); oqop->setQueueId(queueid); thefleet->setDefaultOrderTypes(); //set ship type IdMap fleettype = fleetlist->getList(); for(IdMap::iterator itcurr = fleettype.begin(); itcurr != fleettype.end(); ++itcurr){ thefleet->addShips(itcurr->first, itcurr->second); Design::Ptr design = Game::getGame()->getDesignStore()->getDesign(itcurr->first); design->addComplete(itcurr->second); Game::getGame()->getDesignStore()->designCountsUpdated(design); } //add fleet to universe Game::getGame()->getObjectManager()->addObject(fleet); Game::getGame()->getPlayerManager()->getPlayer(ownerid)->getPlayerView()->addOwnedObject(fleet->getID()); Message::Ptr msg( new Message() ); msg->setSubject("Build Fleet order complete"); msg->setBody(std::string("The construction of your new fleet \"") + fleetname->getString() + "\" is complete."); msg->addReference(rst_Action_Order, rsorav_Completion); msg->addReference(rst_Object, fleet->getID()); msg->addReference(rst_Object, ob->getID()); Game::getGame()->getPlayerManager()->getPlayer(ownerid)->postToBoard(msg); Logger::getLogger()->debug("Exiting BuildFleet::doOrder on Success"); return true; } Logger::getLogger()->debug("Exiting BuildFleet::doOrder on failure"); return false; }
bool Build::doOrder(IGObject::Ptr ob) { Planet* planet = static_cast<Planet*>(ob->getObjectBehaviour()); uint32_t usedshipres = resources[1]; if(usedshipres == 0) return true; int ownerid = planet->getOwner(); if(ownerid == 0){ //currently not owned by anyone, just forget about it return true; } planet->addResource(1, 1); if(planet->removeResource(1, usedshipres)){ //create fleet Game* game = Game::getGame(); IGObject::Ptr fleet = game->getObjectManager()->createNewObject(); game->getObjectTypeManager()->setupObject(fleet, game->getObjectTypeManager()->getObjectTypeByName("Fleet")); //add fleet to container fleet->addToParent(ob->getID()); fleet->setName(fleetname->getString().c_str()); Fleet * thefleet = ((Fleet*)(fleet->getObjectBehaviour())); thefleet->setSize(2); thefleet->setOwner(ownerid); // set ownerid thefleet->setPosition(planet->getPosition()); thefleet->setVelocity(Vector3d(0LL, 0ll, 0ll)); uint32_t queueid = Game::getGame()->getOrderManager()->addOrderQueue(fleet->getID(), ownerid); OrderQueueObjectParam* oqop = static_cast<OrderQueueObjectParam*>(fleet->getParameterByType(obpT_Order_Queue)); oqop->setQueueId(queueid); thefleet->setDefaultOrderTypes(); thefleet->setIcon("common/object-icons/ship"); thefleet->setMedia("common-2d/foreign/vegastrike/ship-small/" + ((MiniSec*)(game->getRuleset()))->getFleetMediaNames()->getName()); //set ship type IdMap fleettype = fleetlist->getList(); for(IdMap::iterator itcurr = fleettype.begin(); itcurr != fleettype.end(); ++itcurr){ thefleet->addShips(itcurr->first, itcurr->second); Design::Ptr design = Game::getGame()->getDesignStore()->getDesign(itcurr->first); design->addComplete(itcurr->second); Game::getGame()->getDesignStore()->designCountsUpdated(design); } //add fleet to universe Game::getGame()->getObjectManager()->addObject(fleet); Game::getGame()->getPlayerManager()->getPlayer(ownerid)->getPlayerView()->addOwnedObject(fleet->getID()); Message::Ptr msg( new Message() ); msg->setSubject("Build Fleet order complete"); msg->setBody(std::string("The construction of your new fleet \"") + fleetname->getString() + "\" is complete."); msg->addReference(rst_Action_Order, rsorav_Completion); msg->addReference(rst_Object, fleet->getID()); msg->addReference(rst_Object, ob->getID()); Game::getGame()->getPlayerManager()->getPlayer(ownerid)->postToBoard(msg); return true; } return false; }
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; }
void Build::createFrame(OutputFrame::Ptr f, int pos) { IGObject::Ptr planet = Game::getGame()->getObjectManager()->getObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId()); // number of turns std::map<uint32_t, std::pair<uint32_t, uint32_t> > presources = static_cast<Planet*>(planet->getObjectBehaviour())->getResources(); Game::getGame()->getObjectManager()->doneWithObject(planet->getID()); uint32_t res_current; if(presources.find(1) != presources.end()){ res_current = presources.find(1)->second.first; }else{ res_current = 0; } uint32_t usedshipres = resources[1]; if(pos != 0 || usedshipres == 0){ turns = usedshipres; }else{ if(usedshipres <= res_current){ turns = 1; }else{ turns = usedshipres - res_current; } } Order::createFrame(f, pos); }
//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 ); } }
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; }
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(); }