// 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; }
bool CombatScreen::onDoneButton() { resolveCombat(); return true; }