//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()); } } }
//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; }
//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); } }
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(); }