void AVACombat::resolveCombat(Fleet* fleet){ Logger::getLogger()->debug("AVACombat::resolveCombat : Entering"); Game* game = Game::getGame(); DesignStore::Ptr ds = game->getDesignStore(); typedef std::map<uint32_t, uint32_t> shipList; shipList ships = fleet->getShips(); uint32_t damage = fleet->getDamage(); uint32_t hpPropID = ds->getPropertyByName("HitPoints"); for (shipList::reverse_iterator itcurr = ships.rbegin(); itcurr != ships.rend(); ++itcurr){ uint32_t shipNumber = itcurr->first; uint32_t shipQuantity = itcurr->second; Logger::getLogger()->debug("Working on ship %s", ds->getDesign(shipNumber)->getName().c_str()); uint32_t damageNeeded = static_cast<uint32_t>(ds->getDesign(shipNumber)->getPropertyValue(hpPropID)); Logger::getLogger()->debug("Damage needed to destroy this ship: %d Damage available: %d", damageNeeded, damage); if (damage >= damageNeeded) { uint32_t factor = damage % damageNeeded; if (factor > shipQuantity) { factor = shipQuantity; } fleet->removeShips(shipNumber, factor); fleet->setDamage(damage - (damageNeeded*factor)); Logger::getLogger()->debug("Damage is greater than a ship can take, Total(%d), Delivering(%d), factor (%d), new setDamage(%d)", damage, damageNeeded*factor, factor, fleet->getDamage()); } } Logger::getLogger()->debug("AVACombat::resolveCombat : Exiting"); }
void Build::inputFrame(InputFrame::Ptr f, uint32_t playerid) { Order::inputFrame(f, playerid); Player::Ptr player = Game::getGame()->getPlayerManager()->getPlayer(playerid); DesignStore::Ptr ds = Game::getGame()->getDesignStore(); uint32_t bldTmPropID = ds->getPropertyByName( "BuildTime"); IdMap fleettype = fleetlist->getList(); uint32_t usedshipres = 0; for(IdMap::iterator itcurr = fleettype.begin(); itcurr != fleettype.end(); ++itcurr) { uint32_t type = itcurr->first; uint32_t number = itcurr->second; // number to build if(player->getPlayerView()->isUsableDesign(type) && number >= 0){ Design::Ptr design = ds->getDesign(type); usedshipres += (int)(ceil(number * design->getPropertyValue(bldTmPropID))); design->addUnderConstruction(number); ds->designCountsUpdated(design); }else{ throw FrameException( fec_FrameError, "The requested design was not valid."); } } if(usedshipres == 0 && !fleettype.empty()){ throw FrameException( fec_FrameError, "To build was empty..."); } resources[1] = usedshipres; if(fleetname->getString().length() == 0){ fleetname->setString("A Fleet"); } }
std::map<uint32_t, std::pair<std::string, uint32_t> > Build::generateListOptions(){ std::map<uint32_t, std::pair<std::string, uint32_t> > options; std::set<uint32_t> designs = Game::getGame()->getPlayerManager()->getPlayer(((Planet*)(Game::getGame()->getObjectManager()->getObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId())->getObjectBehaviour()))->getOwner())->getPlayerView()->getUsableDesigns(); Game::getGame()->getObjectManager()->doneWithObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId()); DesignStore::Ptr ds = Game::getGame()->getDesignStore(); std::set<Design::Ptr> usable; for(std::set<uint32_t>::iterator itcurr = designs.begin(); itcurr != designs.end(); ++itcurr){ Design::Ptr design = ds->getDesign(*itcurr); if(design->getCategoryId() == 1){ usable.insert(design); } } for(std::set<Design::Ptr>::iterator itcurr = usable.begin(); itcurr != usable.end(); ++itcurr){ Design::Ptr design = (*itcurr); options[design->getDesignId()] = std::pair<std::string, uint32_t>(design->getName(), 100); } return options; }
ListParameter::Options BuildFleet::generateListOptions(){ ListParameter::Options options; IdSet designs = Game::getGame()->getPlayerManager()->getPlayer(((Planet*)(Game::getGame()->getObjectManager()->getObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId())->getObjectBehaviour()))->getOwner())->getPlayerView()->getUsableDesigns(); Game::getGame()->getObjectManager()->doneWithObject(Game::getGame()->getOrderManager()->getOrderQueue(orderqueueid)->getObjectId()); DesignStore::Ptr ds = Game::getGame()->getDesignStore(); std::set<Design::Ptr> usable; for(IdSet::iterator itcurr = designs.begin(); itcurr != designs.end(); ++itcurr){ Design::Ptr design = ds->getDesign(*itcurr); if(design->getCategoryId() == 1){ usable.insert(design); } } for(std::set<Design::Ptr>::iterator itcurr = usable.begin(); itcurr != usable.end(); ++itcurr){ Design::Ptr design = (*itcurr); options[design->getDesignId()] = ListParameter::Option(design->getName(), 100); } Logger::getLogger()->debug("Exiting BuildFleet::generateListOptions"); return options; }
//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); } } } } } } } }
//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 ); } }
// This routine handles one combat round. // fleets[2] are the combatants. // msgs[0] is sent to the owner of fleet1, // msgs[1] is sent to the owner of fleet2. // // Assume that 'number of missiles/torpedoes a ship can carry' // really means 'number of missiles/torpedoes a ship can fire in one round'. // Ships have an infinite amount of ammunition. // // Further assume that everyone fires his/her full load, // then all the damage is done. No 'this ship was destroyed // in this round, so it can't fire any missiles'. // // I keep (for now) the policy of always targetting the largest // ship. // // Likelihood of (correct) impact is 100% for missiles, and // (1-dodge likelihood) for torpedoes. // // How about armor as a recurring damage absorber? Like // 20HP of damage hitting a ship that has 5HP of armor // results in only 15HP of damage to that ship. The next // round, another 15HP of damage hits the ship, resulting // in another 10HP of damage. The armor itself is not // damaged until the ship is destroyed. // // Keep the same damage effects? Ships are at full // capacity until they are destroyed? // // All that being said, I decreased the damage the two sides // do to each other by a random 0-39% because I wanted some // randomness involved. bool AVACombat::doCombatRound( Fleet* fleet1, Message::Ptr msg1, Fleet* fleet2, Message::Ptr msg2) { Logger::getLogger()->debug("doCombatRound Entering"); Game* game = Game::getGame(); DesignStore::Ptr ds = game->getDesignStore(); ResourceManager::Ptr resman = game->getResourceManager(); typedef std::map<uint32_t, std::pair<uint32_t, uint32_t> > weaponList; // ID/TYPE AMOUNT typedef std::map<uint32_t, uint32_t> shipList; std::map<uint32_t, std::string> tubes; tubes[ds->getPropertyByName("AlphaMissileTube")] = "AlphaMissileTube"; tubes[ds->getPropertyByName("BetaMissileTube")] = "BetaMissileTube"; tubes[ds->getPropertyByName("GammaMissileTube")] = "GammaMissileTube"; tubes[ds->getPropertyByName("DeltaMissileTube")] = "DeltaMissileTube"; tubes[ds->getPropertyByName("EpsilonMissileTube")] = "EpsilonMissileTube"; tubes[ds->getPropertyByName("OmegaTorpedoeTube")] = "OmegaTorpedoeTube"; tubes[ds->getPropertyByName("UpsilonTorpedoeTube")] = "UpsilonTorpedoeTube"; tubes[ds->getPropertyByName("TauTorpedoeTube")] = "TauTorpedoeTube"; tubes[ds->getPropertyByName("SigmaTorpedoeTube")] = "SigmaTorpedoeTube"; tubes[ds->getPropertyByName("RhoTorpedoeTube")] = "RhoTorpedoeTube"; tubes[ds->getPropertyByName("XiTorpedoeTube")] = "XiTorpedoeTube"; std::map<uint32_t, uint32_t> tubeList; std::set<Design::Ptr> designList; weaponList fleetweaponry[2]; shipList fleetships[2]; Fleet* fleets[2]; std::map<uint32_t, std::pair<std::string, uint32_t> > fleettubes[2]; std::map<uint32_t, uint32_t> fleetusable[2]; // resourceid, designid fleetweaponry[0] = fleet1->getResources(); fleetweaponry[1] = fleet2->getResources(); fleetships[0] = fleet1->getShips(); fleetships[1] = fleet2->getShips(); fleets[0] = fleet1; fleets[1] = fleet2; uint32_t damage[2] = {0}; for (int i=0; i < 2; i++) { for (shipList::iterator itcurr = fleetships[i].begin(); itcurr != fleetships[i].end(); ++itcurr) { for (std::map<uint32_t, std::string>::iterator tubeit = tubes.begin(); tubeit != tubes.end(); ++tubeit) { if (ds->getDesign(itcurr->first)->getPropertyValue(tubeit->first) > 0.0) { Logger::getLogger()->debug("Found usable Tube %s, inserting into Fleet %d", tubeit->second.c_str(), i); //size of weapon uint32_t weapSizePropID = ds->getPropertyByName(tubeit->second); uint32_t weapNumPropID = ds->getPropertyByName("num-" + tubeit->second); uint32_t weapSizePropValue = static_cast<uint32_t>(ds->getDesign(itcurr->first)->getPropertyValue(weapSizePropID)); uint32_t weapNumPropValue = static_cast<uint32_t>(ds->getDesign(itcurr->first)->getPropertyValue(weapNumPropID)); if (fleettubes[i].find(weapSizePropValue) != fleettubes[i].end()) { std::pair<std::string, uint32_t>fleetpair = fleettubes[i][weapSizePropValue]; fleetpair.second += weapNumPropValue; fleettubes[i][weapSizePropValue] = fleetpair; Logger::getLogger()->debug("Adding %d into Tube List", weapSizePropValue); } else { fleettubes[i][weapSizePropValue] = std::pair<std::string, uint32_t> (tubeit->second, weapNumPropValue); } } } for (weaponList::iterator weapit = fleetweaponry[i].begin(); weapit != fleetweaponry[i].end(); ++weapit) { Design::Ptr weapDesign; std::string weapName = resman->getResourceDescription(weapit->first)->getNameSingular(); std::set<uint32_t>dIDs = ds->getDesignIds(); for (std::set<uint32_t>::iterator dit = dIDs.begin(); dit != dIDs.end(); ++dit) { if (weapName == ds->getDesign(*dit)->getName()) { weapDesign = ds->getDesign(*dit); Logger::getLogger()->debug("Found design %s", weapDesign->getName().c_str()); for (std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator tubeit = fleettubes[i].begin(); tubeit != fleettubes[i].end(); ++tubeit) { //property ID, name of the TUBE uint32_t propID = ds->getPropertyByName("MissileSize"); //Logger::getLogger()->debug("Checking fleettubes list for propID %s", ds->getProperty(propID)->getName().c_str()); uint32_t weapPropVal = static_cast<uint32_t>(weapDesign->getPropertyValue(propID)); if (fleettubes[i].find(weapPropVal) != fleettubes[i].end()) { Logger::getLogger()->debug("Found it, trying to remove resource %d from fleet", weapit->first); fleetusable[i][weapit->first] = weapDesign->getDesignId(); if (fleets[i]->removeResource(weapit->first, 1)) { uint32_t explPropID = ds->getPropertyByName("AmmoExplosiveness"); //damage to be deliveredt damage[!i] += static_cast<uint32_t>(weapDesign->getPropertyValue(explPropID)); Logger::getLogger()->debug("Adding Damage (%d) Total (%d)", static_cast<uint32_t>(weapDesign->getPropertyValue(explPropID)), damage[!i]); } else { Logger::getLogger()->debug("No available Weapon for this tube!"); } } } } } } } } fleet1->setDamage(damage[0]); fleet2->setDamage(damage[1]); resolveCombat(fleet1); resolveCombat(fleet2); //Tube format: std::map<double, std::pair<std::string, uint32_t> > // tube size name number bool tte = false; std::string body[2]; if (fleet1->totalShips() == 0) { body[0] += "Your fleet was destroyed. "; body[1] += "You destroyed their fleet. "; c1.reset(); tte = true; }; if (fleet2->totalShips() == 0) { body[0] += "Your fleet was destroyed."; body[1] += "You destroyed their fleet."; c2.reset(); tte = true; } if ( tte) { msg1->setBody( body[0]); msg2->setBody( body[1]); } Logger::getLogger()->debug("doCombatRound Exiting"); return false; }
// Combat always takes place between two fleets. If one combatant // or the other is actually a planet, the planet simulated by two // battleships. void AVACombat::doCombat() { Logger::getLogger()->debug("AVACombat::doCombat : Entering"); Fleet *fleets[2]; Game* game = Game::getGame(); DesignStore::Ptr ds = game->getDesignStore(); uint32_t obT_Fleet = game->getObjectTypeManager()->getObjectTypeByName("Fleet"); uint32_t obT_Planet = game->getObjectTypeManager()->getObjectTypeByName("Planet"); // If one combatant or the other is actually a planet, // simulate this with two battleships. if ( c1->getType() == obT_Fleet) { fleets[0] = dynamic_cast<Fleet*>( c1->getObjectBehaviour()); } else if ( c1->getType() == obT_Planet) { fleets[0] = new DummyFleet(); std::set<uint32_t> dIDs = ds->getDesignIds(); uint32_t scoutID=0; for (std::set<uint32_t>::iterator it = dIDs.begin(); it != dIDs.end(); ++it) { if (ds->getDesign(*it)->getName() == "Scout") { scoutID = *it; } } fleets[0] = new DummyFleet(); fleets[0]->addShips(scoutID , 2); fleets[0]->setOwner( dynamic_cast<Planet*>(c1->getObjectBehaviour())->getOwner()); } if ( c2->getType() == obT_Fleet) { fleets[1] = dynamic_cast<Fleet*>( c2->getObjectBehaviour()); } else if ( c2->getType() == obT_Planet) { std::set<uint32_t> dIDs = ds->getDesignIds(); uint32_t scoutID=0; for (std::set<uint32_t>::iterator it = dIDs.begin(); it != dIDs.end(); ++it) { if (ds->getDesign(*it)->getName() == "Scout") { scoutID = *it; } } fleets[1] = new DummyFleet(); fleets[1]->addShips(scoutID, 2); fleets[1]->setOwner( dynamic_cast<Planet*>(c2->getObjectBehaviour())->getOwner()); } if ( fleets[0] == NULL || fleets[1] == NULL) { return; } Message::Ptr msg1( new Message() ); Message::Ptr msg2( new Message() ); msg1->setSubject( "Combat"); msg2->setSubject( "Combat"); msg1->addReference( rst_Object, c1->getID()); msg1->addReference( rst_Object, c2->getID()); msg1->addReference( rst_Player, fleets[1]->getOwner()); msg2->addReference( rst_Object, c2->getID()); msg2->addReference( rst_Object, c1->getID()); msg2->addReference( rst_Player, fleets[0]->getOwner()); while ( doCombatRound( fleets[0], msg1, fleets[1], msg2)) { ; } Game::getGame()->getPlayerManager()->getPlayer( fleets[0]->getOwner())->postToBoard( msg1); Game::getGame()->getPlayerManager()->getPlayer( fleets[1]->getOwner())->postToBoard( msg2); return; }
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(); }
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; }