void PreferencesPanel::DrawSettings() { Color back = *GameData::Colors().Get("faint"); Color dim = *GameData::Colors().Get("dim"); Color medium = *GameData::Colors().Get("medium"); Color bright = *GameData::Colors().Get("bright"); Table table; table.AddColumn(-115, Table::LEFT); table.AddColumn(115, Table::RIGHT); table.SetUnderline(-120, 120); int firstY = -248; table.DrawAt(Point(-130, firstY)); static const string SETTINGS[] = { "Display", ZOOM_FACTOR, "Show status overlays", "Show planet labels", "Show mini-map", "", "AI", "Automatic aiming", "Automatic firing", EXPEND_AMMO, "", "Performance", "Show CPU / GPU load", "Render motion blur", "Reduce large graphics", "Draw background haze", "Show hyperspace flash", "\n", "Other", REACTIVATE_HELP, SCROLL_SPEED, "Warning siren", "Hide unexplored map regions" }; bool isCategory = true; for(const string &setting : SETTINGS) { // Check if this is a category break or column break. if(setting.empty() || setting == "\n") { isCategory = true; if(!setting.empty()) table.DrawAt(Point(130, firstY)); continue; } if(isCategory) { isCategory = false; table.DrawGap(10); table.DrawUnderline(medium); table.Draw(setting, bright); table.Advance(); table.DrawGap(5); continue; } // Record where this setting is displayed, so the user can click on it. prefZones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), setting); // Get the "on / off" text for this setting. bool isOn = Preferences::Has(setting); string text; if(setting == ZOOM_FACTOR) { isOn = true; text = to_string(Screen::Zoom()); } else if(setting == EXPEND_AMMO) text = Preferences::AmmoUsage(); else if(setting == REACTIVATE_HELP) { // Check how many help messages have been displayed. const map<string, string> &help = GameData::HelpTemplates(); int shown = 0; for(const auto &it : help) shown += Preferences::Has("help: " + it.first); if(shown) text = to_string(shown) + " / " + to_string(help.size()); else { isOn = true; text = "done"; } } else if(setting == SCROLL_SPEED) text = to_string(Preferences::ScrollSpeed()); else text = isOn ? "on" : "off"; if(setting == hoverPreference) table.DrawHighlight(back); table.Draw(setting, isOn ? medium : dim); table.Draw(text, isOn ? bright : medium); } }
void ShipInfoPanel::DrawCargo(const Rectangle &bounds) { Color dim = *GameData::Colors().Get("medium"); Color bright = *GameData::Colors().Get("bright"); Color backColor = *GameData::Colors().Get("faint"); const Ship &ship = **shipIt; // Cargo list. const CargoHold &cargo = (player.Cargo().Used() ? player.Cargo() : ship.Cargo()); Table table; table.AddColumn(0, Table::LEFT); table.AddColumn(WIDTH - 20, Table::RIGHT); table.SetUnderline(-5, WIDTH - 15); table.DrawAt(bounds.TopLeft() + Point(10., 8.)); double endY = bounds.Bottom() - 30. * (cargo.Passengers() != 0); bool hasSpace = (table.GetRowBounds().Bottom() < endY); if((cargo.CommoditiesSize() || cargo.HasOutfits() || cargo.MissionCargoSize()) && hasSpace) { table.Draw("Cargo", bright); table.Advance(); hasSpace = (table.GetRowBounds().Bottom() < endY); } if(cargo.CommoditiesSize() && hasSpace) { for(const auto &it : cargo.Commodities()) { if(!it.second) continue; commodityZones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), it.first); if(it.first == selectedCommodity) table.DrawHighlight(backColor); table.Draw(it.first, dim); table.Draw(to_string(it.second), bright); // Truncate the list if there is not enough space. if(table.GetRowBounds().Bottom() >= endY) { hasSpace = false; break; } } table.DrawGap(10.); } if(cargo.HasOutfits() && hasSpace) { for(const auto &it : cargo.Outfits()) { if(!it.second) continue; plunderZones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), it.first); if(it.first == selectedPlunder) table.DrawHighlight(backColor); // For outfits, show how many of them you have and their total mass. bool isSingular = (it.second == 1 || it.first->Get("installable") < 0.); string name = (isSingular ? it.first->Name() : it.first->PluralName()); if(!isSingular) name += " (" + to_string(it.second) + "x)"; table.Draw(name, dim); double mass = it.first->Mass() * it.second; table.Draw(Format::Number(mass), bright); // Truncate the list if there is not enough space. if(table.GetRowBounds().Bottom() >= endY) { hasSpace = false; break; } } table.DrawGap(10.); } if(cargo.HasMissionCargo() && hasSpace) { for(const auto &it : cargo.MissionCargo()) { // Capitalize the name of the cargo. table.Draw(Format::Capitalize(it.first->Cargo()), dim); table.Draw(to_string(it.second), bright); // Truncate the list if there is not enough space. if(table.GetRowBounds().Bottom() >= endY) break; } table.DrawGap(10.); } if(cargo.Passengers() && endY >= bounds.Top()) { table.DrawAt(Point(bounds.Left(), endY) + Point(10., 8.)); table.Draw("passengers:", dim); table.Draw(to_string(cargo.Passengers()), bright); } }
void PreferencesPanel::DrawControls() { Color back = *GameData::Colors().Get("faint"); Color dim = *GameData::Colors().Get("dim"); Color medium = *GameData::Colors().Get("medium"); Color bright = *GameData::Colors().Get("bright"); // Check for conflicts. Color red(.3, 0., 0., .3); Table table; table.AddColumn(-115, Table::LEFT); table.AddColumn(115, Table::RIGHT); table.SetUnderline(-120, 120); int firstY = -248; table.DrawAt(Point(-130, firstY)); static const string CATEGORIES[] = { "Navigation", "Weapons", "Targeting", "Menus", "Fleet" }; const string *category = CATEGORIES; static const Command COMMANDS[] = { Command::NONE, Command::FORWARD, Command::LEFT, Command::RIGHT, Command::BACK, Command::AFTERBURNER, Command::LAND, Command::JUMP, Command::NONE, Command::PRIMARY, Command::SELECT, Command::SECONDARY, Command::CLOAK, Command::NONE, Command::NEAREST, Command::TARGET, Command::HAIL, Command::BOARD, Command::SCAN, Command::NONE, Command::MENU, Command::MAP, Command::INFO, Command::FULLSCREEN, Command::NONE, Command::DEPLOY, Command::FIGHT, Command::GATHER, Command::HOLD, Command::AMMO }; static const Command *BREAK = &COMMANDS[19]; for(const Command &command : COMMANDS) { // The "BREAK" line is where to go to the next column. if(&command == BREAK) table.DrawAt(Point(130, firstY)); if(!command) { table.DrawGap(10); table.DrawUnderline(medium); if(category != end(CATEGORIES)) table.Draw(*category++, bright); else table.Advance(); table.Draw("Key", bright); table.DrawGap(5); } else { int index = zones.size(); // Mark conflicts. bool isConflicted = command.HasConflict(); bool isEditing = (index == editing); if(isConflicted || isEditing) { table.SetHighlight(66, 120); table.DrawHighlight(isEditing ? dim: red); } // Mark the selected row. bool isHovering = (index == hover && !isEditing); if(!isHovering && index == selected) { table.SetHighlight(-120, 64); table.DrawHighlight(back); } // Highlight whichever row the mouse hovers over. table.SetHighlight(-120, 120); if(isHovering) table.DrawHighlight(back); zones.emplace_back(table.GetCenterPoint(), table.GetRowSize(), command); table.Draw(command.Description(), medium); table.Draw(command.KeyName(), isEditing ? bright : medium); } } Table shiftTable; shiftTable.AddColumn(125, Table::RIGHT); shiftTable.SetUnderline(0, 130); shiftTable.DrawAt(Point(-400, 52)); shiftTable.DrawUnderline(medium); shiftTable.Draw("With <shift> key", bright); shiftTable.DrawGap(5); shiftTable.Draw("Select nearest ship", medium); shiftTable.Draw("Select next escort", medium); shiftTable.Draw("Talk to planet", medium); shiftTable.Draw("Board disabled escort", medium); }
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()))); } }