Skip to content

Commit

Permalink
feat(ui): Double clicking selects similar ships in shop sidebars (end…
Browse files Browse the repository at this point in the history
…less-sky#11048)

Co-authored-by: Nicholas Shanks <[email protected]>
  • Loading branch information
TomGoodIdea and nickshanks authored Feb 26, 2025
1 parent 6aaa63a commit 8c91d72
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 13 deletions.
3 changes: 3 additions & 0 deletions data/_ui/help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ help "map advanced danger"
help "multiple ships"
`Now that you have more than one ship, while landed on a planet you can reorder the ships in your fleet by clicking and dragging them in the shipyard, outfitter, or player info panel. Ships can also be sorted by clicking on the column headers in the player info panel. You will use the first ship in the list as your flagship. In the player info panel (accessed with <View player info>) you can also "park" a ship on a planet if you want to travel somewhere without it coming with you.`

help "shop with multiple ships"
`If you want to select a few similar ships from your fleet at once, double-click one of them. Other ships of the same model, with the same outfits as the one you selected will be added to your selection.`

help "ship info"
`The ship info tab lets you view detailed information about ships in your fleet at any time. This includes any information you could see at a shipyard or outfitter, as well as the cargo and passengers distributed among each ship.`
`Ships can be renamed in this panel by clicking on the ship's name. While landed on a planet, you are able to change how guns and turrets are arranged by dragging the name of a weapon to another gun or turret location. While in flight, you are able to jettison individual pieces of cargo by clicking on the name of the cargo.`
Expand Down
7 changes: 7 additions & 0 deletions source/Ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3814,6 +3814,13 @@ void Ship::Linger()



bool Ship::Immitates(const Ship &other) const
{
return displayModelName == other.DisplayModelName() && outfits == other.Outfits();
}



// Check if this ship has been in a different system from the player for so
// long that it should be "forgotten." Also eliminate ships that have no
// system set because they just entered a fighter bay. Clear the hyperspace
Expand Down
3 changes: 3 additions & 0 deletions source/Ship.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ class Ship : public Body, public std::enable_shared_from_this<Ship> {
// The AI wants the ship to linger for one AI step.
void Linger();

// Check if this ship looks the same as another, based on model display names and outfits.
bool Immitates(const Ship &other) const;


private:
// Various steps of Ship::Move:
Expand Down
86 changes: 74 additions & 12 deletions source/ShopPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,29 @@ ShopPanel::ShopPanel(PlayerInfo &player, bool isOutfitter)

void ShopPanel::Step()
{
// If the player has acquired a second ship for the first time, explain to
// them how to reorder the ships in their fleet.
if(player.Ships().size() > 1)
DoHelp("multiple ships");
if(!checkedHelp && GetUI()->IsTop(this) && player.Ships().size() > 1)
{
if(DoHelp("multiple ships"))
{
// Nothing to do here, just don't want to execute the other branch.
}
else if(!Preferences::Has("help: shop with multiple ships"))
{
set<string> modelNames;
for(const auto &it : player.Ships())
{
if(!CanShowInSidebar(*it, player.GetPlanet()))
continue;
if(modelNames.contains(it->DisplayModelName()))
{
DoHelp("shop with multiple ships");
break;
}
modelNames.insert(it->DisplayModelName());
}
}
checkedHelp = true;
}
}


Expand Down Expand Up @@ -537,7 +556,7 @@ bool ShopPanel::Click(int x, int y, int clicks)
{
dragShip = ship.get();
dragPoint.Set(x, y);
SideSelect(dragShip);
SideSelect(dragShip, clicks);
break;
}

Expand Down Expand Up @@ -1198,7 +1217,7 @@ void ShopPanel::SideSelect(int count)



void ShopPanel::SideSelect(Ship *ship)
void ShopPanel::SideSelect(Ship *ship, int clicks)
{
bool shift = (SDL_GetModState() & KMOD_SHIFT);
bool control = (SDL_GetModState() & (KMOD_CTRL | KMOD_GUI));
Expand All @@ -1220,14 +1239,57 @@ void ShopPanel::SideSelect(Ship *ship)
}
}
else if(!control)
{
playerShips.clear();
else if(playerShips.contains(ship))
if(clicks > 1)
for(const shared_ptr<Ship> &it : player.Ships())
{
if(!CanShowInSidebar(*it, player.GetPlanet()))
continue;
if(it.get() != ship && it->Immitates(*ship))
playerShips.insert(it.get());
}
}
else
{
playerShips.erase(ship);
if(playerShip == ship)
playerShip = playerShips.empty() ? nullptr : *playerShips.begin();
CheckSelection();
return;
if(clicks > 1)
{
vector<Ship *> similarShips;
// If the ship isn't selected now, it was selected at the beginning of the whole "double click" action,
// because the first click was handled normally.
bool unselect = !playerShips.contains(ship);
for(const shared_ptr<Ship> &it : player.Ships())
{
if(!CanShowInSidebar(*it, player.GetPlanet()))
continue;
if(it.get() != ship && it->Immitates(*ship))
{
similarShips.push_back(it.get());
unselect &= playerShips.contains(it.get());
}
}
for(Ship *it : similarShips)
{
if(unselect)
playerShips.erase(it);
else
playerShips.insert(it);
}
if(unselect && find(similarShips.begin(), similarShips.end(), playerShip) != similarShips.end())
{
playerShip = playerShips.empty() ? nullptr : *playerShips.begin();
CheckSelection();
return;
}
}
else if(playerShips.contains(ship))
{
playerShips.erase(ship);
if(playerShip == ship)
playerShip = playerShips.empty() ? nullptr : *playerShips.begin();
CheckSelection();
return;
}
}

playerShip = ship;
Expand Down
4 changes: 3 additions & 1 deletion source/ShopPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class ShopPanel : public Panel {
bool SetScrollToTop();
bool SetScrollToBottom();
void SideSelect(int count);
void SideSelect(Ship *ship);
void SideSelect(Ship *ship, int clicks = 1);
void MainAutoScroll(const std::vector<Zone>::const_iterator &selected);
void MainLeft();
void MainRight();
Expand All @@ -222,4 +222,6 @@ class ShopPanel : public Panel {
std::string shipName;
std::string warningType;
int hoverCount = 0;

bool checkedHelp = false;
};
1 change: 1 addition & 0 deletions tests/integration/config/preferences.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"help: outfitter with multiple ships" 1
"help: ship info" 1
"help: shipyard" 1
"help: shop with multiple ships" 1
"help: stranded" 1
"help: trading" 1
"help: try out fighters transfer cargo" 1
Expand Down

0 comments on commit 8c91d72

Please sign in to comment.