Point ItemInfoDisplay::Draw(Point point, const vector<string> &labels, const vector<string> &values) { // Add ten pixels of padding at the top. point.Y() += 10.; // Get standard colors to draw with. Color labelColor = *GameData::Colors().Get("medium"); Color valueColor = *GameData::Colors().Get("bright"); Table table; // Use 10-pixel margins on both sides. table.AddColumn(10, Table::LEFT); table.AddColumn(WIDTH - 10, Table::RIGHT); table.DrawAt(point); for(unsigned i = 0; i < labels.size() && i < values.size(); ++i) { if(labels[i].empty()) { table.DrawGap(10); continue; } table.Draw(labels[i], values[i].empty() ? valueColor : labelColor); table.Draw(values[i], valueColor); } return table.GetPoint(); }
void InfoPanel::DrawInfo() const { Color dim = *GameData::Colors().Get("medium"); Color bright = *GameData::Colors().Get("bright"); Color elsewhere = *GameData::Colors().Get("dim"); Color dead(.4, 0., 0., 0.); const Font &font = FontSet::Get(14); // Player info. Table table; table.AddColumn(0, Table::LEFT); table.AddColumn(230, Table::RIGHT); table.SetUnderline(0, 230); table.DrawAt(Point(-490., -282.)); table.Draw("player:", dim); table.Draw(player.FirstName() + " " + player.LastName(), bright); table.Draw("net worth:", dim); table.Draw(Format::Number(player.Accounts().NetWorth()) + " credits", bright); // Determine the player's combat rating. table.DrawGap(10); size_t ratingLevel = 0; auto it = player.Conditions().find("combat rating"); if(it != player.Conditions().end() && it->second > 0) { ratingLevel = log(it->second); ratingLevel = min(ratingLevel, RATINGS.size() - 1); } table.DrawUnderline(dim); table.Draw("combat rating:", bright); table.Advance(); table.DrawGap(5); table.Draw(RATINGS[ratingLevel], dim); table.Draw("(" + to_string(ratingLevel) + ")", dim); auto salary = Match(player, "salary: ", ""); sort(salary.begin(), salary.end()); DrawList(salary, table, "salary:", 4); auto tribute = Match(player, "tribute: ", ""); sort(tribute.begin(), tribute.end()); DrawList(tribute, table, "tribute:", 4); int maxRows = static_cast<int>(250. - 30. - table.GetPoint().Y()) / 20; auto licenses = Match(player, "license: ", " License"); DrawList(licenses, table, "licenses:", maxRows, false); // Fleet listing. Point pos = Point(-240., -280.); font.Draw("ship", pos + Point(0., 0.), bright); font.Draw("model", pos + Point(220., 0.), bright); font.Draw("system", pos + Point(350., 0.), bright); font.Draw("shields", pos + Point(550. - font.Width("shields"), 0.), bright); font.Draw("hull", pos + Point(610. - font.Width("hull"), 0.), bright); font.Draw("fuel", pos + Point(670. - font.Width("fuel"), 0.), bright); font.Draw("crew", pos + Point(730. - font.Width("crew"), 0.), bright); FillShader::Fill(pos + Point(365., 15.), Point(730., 1.), dim); if(!player.Ships().size()) return; int lastIndex = player.Ships().size() - 1; const Ship *flagship = player.Flagship(); pos.Y() += 5.; int index = scroll; auto sit = player.Ships().begin() + scroll; for( ; sit < player.Ships().end(); ++sit) { const shared_ptr<Ship> &ship = *sit; pos.Y() += 20.; if(pos.Y() >= 260.) break; bool isElsewhere = (ship->GetSystem() != player.GetSystem()); isElsewhere |= (ship->CanBeCarried() && player.GetSystem()); bool isDead = ship->IsDestroyed() || ship->IsDisabled(); bool isHovered = (index == hover); const Color &color = isDead ? dead : isElsewhere ? elsewhere : isHovered ? bright : dim; font.Draw(ship->Name(), pos + Point(10. * ship->CanBeCarried(), 0.), color); font.Draw(ship->ModelName(), pos + Point(220., 0.), color); const System *system = ship->GetSystem(); if(system) font.Draw(system->Name(), pos + Point(350., 0.), color); string shields = to_string(static_cast<int>(100. * max(0., ship->Shields()))) + "%"; font.Draw(shields, pos + Point(550. - font.Width(shields), 0.), color); string hull = to_string(static_cast<int>(100. * max(0., ship->Hull()))) + "%"; font.Draw(hull, pos + Point(610. - font.Width(hull), 0.), color); string fuel = to_string(static_cast<int>( ship->Attributes().Get("fuel capacity") * ship->Fuel())); font.Draw(fuel, pos + Point(670. - font.Width(fuel), 0.), color); string crew = ship->IsParked() ? "Parked" : to_string(ship.get() == flagship ? ship->Crew() : ship->RequiredCrew()); font.Draw(crew, pos + Point(730. - font.Width(crew), 0.), color); if(index < lastIndex || selected < 0) zones.emplace_back(pos + Point(365, font.Height() / 2), Point(730, 20), index); else { int height = 280. - pos.Y(); zones.emplace_back(pos + Point(365, height / 2), Point(730, height), index); } ++index; } // Re-ordering ships in your fleet. if(selected >= 0) { const string &name = player.Ships()[selected]->Name(); Point pos(hoverPoint.X() - .5 * font.Width(name), hoverPoint.Y()); font.Draw(name, pos + Point(1., 1.), Color(0., 1.)); font.Draw(name, pos, bright); } }
void ShipInfoPanel::DrawOutfits(const Rectangle &bounds, Rectangle &cargoBounds) { // Check that the specified area is big enough. if(bounds.Width() < WIDTH) return; // Colors to draw with. Color dim = *GameData::Colors().Get("medium"); Color bright = *GameData::Colors().Get("bright"); const Ship &ship = **shipIt; // Table attributes. Table table; table.AddColumn(0, Table::LEFT); table.AddColumn(WIDTH - 20, Table::RIGHT); table.SetUnderline(0, WIDTH - 20); Point start = bounds.TopLeft() + Point(10., 8.); table.DrawAt(start); // Draw the outfits in the same order used in the outfitter. for(const string &category : Outfit::CATEGORIES) { auto it = outfits.find(category); if(it == outfits.end()) continue; // Skip to the next column if there is not space for this category label // plus at least one outfit. if(table.GetRowBounds().Bottom() + 40. > bounds.Bottom()) { start += Point(WIDTH, 0.); if(start.X() + WIDTH - 20 > bounds.Right()) break; table.DrawAt(start); } // Draw the category label. table.Draw(category, bright); table.Advance(); for(const Outfit *outfit : it->second) { // Check if we've gone below the bottom of the bounds. if(table.GetRowBounds().Bottom() > bounds.Bottom()) { start += Point(WIDTH, 0.); if(start.X() + WIDTH - 20 > bounds.Right()) break; table.DrawAt(start); table.Draw(category, bright); table.Advance(); } // Draw the outfit name and count. table.Draw(outfit->Name(), dim); string number = to_string(ship.OutfitCount(outfit)); table.Draw(number, bright); } // Add an extra gap in between categories. table.DrawGap(10.); } // Check if this information spilled over into the cargo column. if(table.GetPoint().X() >= cargoBounds.Left()) { double startY = table.GetRowBounds().Top() - 8.; cargoBounds = Rectangle::WithCorners( Point(cargoBounds.Left(), startY), Point(cargoBounds.Right(), max(startY, cargoBounds.Bottom()))); } }