void MainPanel::ShowScanDialog(const ShipEvent &event) { shared_ptr<Ship> target = event.Target(); ostringstream out; if(event.Type() & ShipEvent::SCAN_CARGO) { bool first = true; for(const auto &it : target->Cargo().Commodities()) if(it.second) { if(first) out << "This ship is carrying:\n"; first = false; out << "\t" << it.second << (it.second == 1 ? " ton of " : " tons of ") << it.first << "\n"; } if(first) out << "This ship is not carrying any cargo.\n"; } if(event.Type() & ShipEvent::SCAN_OUTFITS) { out << "This ship is equipped with:\n"; for(const auto &it : target->Outfits()) if(it.first && it.second) { out << "\t" << it.first->Name(); if(it.second != 1) out << " (" << it.second << ")"; out << "\n"; } vector<shared_ptr<Ship>> carried = target->CarriedShips(); if(!carried.empty()) { out << "This ship is carrying:\n"; map<string, int> count; for(const shared_ptr<Ship> &fighter : carried) ++count[fighter->ModelName()]; for(const auto &it : count) out << "\t" << it.second << " " << it.first << (it.second == 1 ? "\n" : "s\n"); } } GetUI()->Push(new Dialog(out.str())); }
// Update mission status based on an event. void PlayerInfo::HandleEvent(const ShipEvent &event, UI *ui) { // Combat rating increases when you disable an enemy ship. if(event.ActorGovernment()->IsPlayer()) if((event.Type() & ShipEvent::DISABLE) && event.Target()) conditions["combat rating"] += event.Target()->RequiredCrew(); for(Mission &mission : missions) mission.Do(event, *this, ui); // If the player's flagship was destroyed, the player is dead. if((event.Type() & ShipEvent::DESTROY) && !ships.empty() && event.Target() == ships.front()) Die(); }
// If any event occurs between two ships, check to see if this mission cares // about it. This may affect the mission status or display a message. void Mission::Do(const ShipEvent &event, PlayerInfo &player, UI *ui) { if(event.TargetGovernment()->IsPlayer() && !hasFailed && (event.Type() & ShipEvent::DESTROY)) { bool failed = false; for(const auto &it : event.Target()->Cargo().MissionCargo()) failed |= (it.first == this); for(const auto &it : event.Target()->Cargo().PassengerList()) failed |= (it.first == this); if(failed) { hasFailed = true; if(isVisible) Messages::Add("Ship lost. Mission failed: \"" + displayName + "\"."); } } // Jump events are only created for the player's flagship. if((event.Type() & ShipEvent::JUMP) && event.Actor()) { const System *system = event.Actor()->GetSystem(); auto it = waypoints.find(system); if(it != waypoints.end()) waypoints.erase(it); auto eit = onEnter.find(system); if(eit != onEnter.end()) { eit->second.Do(player, ui); onEnter.erase(eit); } } for(NPC &npc : npcs) npc.Do(event, player, ui); }
void MainPanel::ShowScanDialog(const ShipEvent &event) { shared_ptr<Ship> target = event.Target(); ostringstream out; if(event.Type() & ShipEvent::SCAN_CARGO) { bool first = true; for(const auto &it : target->Cargo().Commodities()) if(it.second) { if(first) out << "This " + target->Noun() + " is carrying:\n"; first = false; out << "\t" << it.second << (it.second == 1 ? " ton of " : " tons of ") << it.first << "\n"; } for(const auto &it : target->Cargo().Outfits()) if(it.second) { if(first) out << "This " + target->Noun() + " is carrying:\n"; first = false; out << "\t" << it.second; if(it.first->Get("installable") < 0.) { int tons = ceil(it.second * it.first->Mass()); out << (tons == 1 ? " ton of " : " tons of ") << Format::LowerCase(it.first->PluralName()) << "\n"; } else out << " " << (it.second == 1 ? it.first->Name(): it.first->PluralName()) << "\n"; } if(first) out << "This " + target->Noun() + " is not carrying any cargo.\n"; } if((event.Type() & ShipEvent::SCAN_OUTFITS) && target->Attributes().Get("inscrutable")) out << "Your scanners cannot make any sense of this " + target->Noun() + "'s interior."; else if(event.Type() & ShipEvent::SCAN_OUTFITS) { out << "This " + target->Noun() + " is equipped with:\n"; for(const auto &it : target->Outfits()) if(it.first && it.second) out << "\t" << it.second << " " << (it.second == 1 ? it.first->Name() : it.first->PluralName()) << "\n"; map<string, int> count; for(const Ship::Bay &bay : target->Bays()) if(bay.ship) { int &value = count[bay.ship->ModelName()]; if(value) { // If the name and the plural name are the same string, just // update the count. Otherwise, clear the count for the // singular name and set it for the plural. int &pluralValue = count[bay.ship->PluralModelName()]; if(!pluralValue) { value = -1; pluralValue = 1; } ++pluralValue; } else ++value; } if(!count.empty()) { out << "This " + target->Noun() + " is carrying:\n"; for(const auto &it : count) if(it.second > 0) out << "\t" << it.second << " " << it.first << "\n"; } } GetUI()->Push(new Dialog(out.str())); }