Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions resources/gui/default.theme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,33 @@
color: #000000D0
}
}
[ship_waypoint_set2] {
image: waypoint.png
[ship_waypoint_set2.background] {
color: #FF4040D0
}
[ship_waypoint_set2.text] {
color: #000000D0
}
}
[ship_waypoint_set3] {
image: waypoint.png
[ship_waypoint_set3.background] {
color: #40FF40D0
}
[ship_waypoint_set3.text] {
color: #000000D0
}
}
[ship_waypoint_set4] {
image: waypoint.png
[ship_waypoint_set4.background] {
color: #40FFFFD0
}
[ship_waypoint_set4.text] {
color: #000000D0
}
}

[radar] {
font: gui/fonts/BigShouldersDisplay-ExtraBold.ttf
Expand Down
98 changes: 66 additions & 32 deletions scripts/api/entity/playerspaceship.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,54 @@ function PlayerSpaceship()
end

--- Returns the coordinates of a waypoint with the given index that's been set by this player ship.
--- Waypoints are 1-indexed.
--- Example:
--- x, y = ship:getWaypoint(1)
function Entity:getWaypoint(index)
if self.components.waypoints and index > 0 and index <= #self.components.waypoints then
local wp = self.components.waypoints[index]
return wp.x, wp.y
--- Waypoints are 1-indexed. Optional set_id (1-4, default 1) selects the waypoint set.
--- Example:
--- x, y = ship:getWaypoint(1) -- wp 1 from set 1
--- x, y = ship:getWaypoint(1, 2) -- wp 1 from set 2
function Entity:getWaypoint(index, set_id)
set_id = set_id or 1
if self.components.waypoints then
local n = 0
for _, wp in ipairs(self.components.waypoints) do
if wp.set_id == set_id then
n = n + 1
if n == index then return wp.x, wp.y end
end
end
end
return 0, 0
end
--- Returns the numeric label for the given waypoint index.
--- Waypoints are 1-indexed.
--- Example:
--- id = ship:getWaypointID(1)
function Entity:getWaypointID(index)
if self.components.waypoints and index > 0 and index <= #self.components.waypoints then
local wp = self.components.waypoints[index]
return wp.id
--- Waypoints are 1-indexed. Optional set_id (1-4, default 1) selects the waypoint set.
--- Example:
--- id = ship:getWaypointID(1) -- wp 1 from set 1
--- id = ship:getWaypointID(1, 2) -- wp 1 from set 2
function Entity:getWaypointID(index, set_id)
set_id = set_id or 1
if self.components.waypoints then
local n = 0
for _, wp in ipairs(self.components.waypoints) do
if wp.set_id == set_id then
n = n + 1
if n == index then return wp.id end
end
end
end
return 0
end
--- Returns the total number of active waypoints owned by this player ship.
--- Optional set_id (1-4, default 1) selects the waypoint set.
--- Example:
--- ship:getWaypointCount()
function Entity:getWaypointCount()
if self.components.waypoints then return #self.components.waypoints end
return 0
--- ship:getWaypointCount() -- count in set 1
--- ship:getWaypointCount(2) -- count in set 2
function Entity:getWaypointCount(set_id)
set_id = set_id or 1
if not self.components.waypoints then return 0 end
local count = 0
for _, wp in ipairs(self.components.waypoints) do
if wp.set_id == set_id then count = count + 1 end
end
return count
end
--- Returns this player ship's EAlertLevel.
--- Returns "Normal", "YELLOW ALERT", "RED ALERT", which differ from the valid values for commandSetAlertLevel().
Expand Down Expand Up @@ -610,27 +631,40 @@ function Entity:commandSetShieldFrequency(index)
return self
end
--- Commands this player ship to add a waypoint at the given coordinates.
--- This respects the 9-waypoint limit and won't add more waypoints if 9 already exist.
--- This respects the 9-waypoint limit per set and won't add more waypoints if 9 already exist.
--- Optional set_id (1-4, default 1) selects the waypoint set.
--- Example:
--- ship:commandAddWaypoint(1000, 2000) -- add wp to set 1
--- ship:commandAddWaypoint(1000, 2000, 2) -- add wp to set 2
function Entity:commandAddWaypoint(x, y, set_id)
commandAddWaypoint(self, x, y, set_id or 1)
return self
end
--- Commands this player ship to remove the waypoint with the given ID.
--- Optional set_id (1-4, default 1) selects the waypoint set.
--- Example:
--- ship:commandAddWaypoint(1000, 2000)
function Entity:commandAddWaypoint(x, y)
commandAddWaypoint(self, x, y)
--- ship:commandRemoveWaypoint(1) -- remove wp 1 from set 1
--- ship:commandRemoveWaypoint(1, 2) -- remove wp 1 from set 2
function Entity:commandRemoveWaypoint(index, set_id)
commandRemoveWaypoint(self, index, set_id or 1)
return self
end
--- Commands this player ship to remove the waypoint with the given index.
--- This uses a 0-index, while waypoints are numbered on player screens with a 1-index.
--- Commands this player ship to move the waypoint with the given ID to the given coordinates.
--- Optional set_id (1-4, default 1) selects the waypoint set.
--- Example:
--- ship:commandRemoveWaypoint(0) -- removes waypoint 1
function Entity:commandRemoveWaypoint(index)
commandRemoveWaypoint(self, index)
--- ship:commandMoveWaypoint(1, -1000, -2000) -- move wp 1 from set 1
--- ship:commandMoveWaypoint(1, -1000, -2000, 2) -- move wp 1 from set 2
function Entity:commandMoveWaypoint(index, x, y, set_id)
commandMoveWaypoint(self, index, x, y, set_id or 1)
return self
end
--- Commands this player ship to move the waypoint with the given index to the given coordinates.
--- This uses a 0-index, while waypoints are numbered on player screens with a 1-index.
--- Commands this player ship to set or clear the route flag for a waypoint set.
--- Optional set_id (1-4, default 1) selects the waypoint set.
--- Example:
--- ship:commandMoveWaypoint(0,-1000,-2000) -- moves waypoint 1 to -1000,-2000
function Entity:commandMoveWaypoint(index, x, y)
commandMoveWaypoint(self, index, x, y)
--- ship:commandSetWaypointRoute(true) -- make set 1 a route
--- ship:commandSetWaypointRoute(false, 2) -- remove routes from set 2
function Entity:commandSetWaypointRoute(is_route, set_id)
commandSetWaypointRoute(self, is_route, set_id or 1)
return self
end
--- Commands this player ship to activate its self-destruct sequence.
Expand Down
47 changes: 30 additions & 17 deletions src/components/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,45 +28,58 @@ string alertLevelToLocaleString(AlertLevel level)
}
}

int Waypoints::addNew(glm::vec2 position)
int Waypoints::addNew(glm::vec2 position, int set_id)
{
if (waypoints.size() == 9)
if (set_id < 1 || set_id > MAX_SETS) return -1;
int count = 0;
for (auto& p : waypoints)
if (p.set_id == set_id) count++;
if (count >= 9)
return -1;
for(int id=1; id<10; id++) {
for (int id = 1; id < 10; id++)
{
bool used = false;
for(auto& p : waypoints)
if (p.id == id)
used = true;
if (!used) {
waypoints.push_back({id, position});
for (auto& p : waypoints)
if (p.id == id && p.set_id == set_id) used = true;
if (!used)
{
waypoints.push_back({id, set_id, position});
dirty = true;
return id;
}
}
return -1;
}

void Waypoints::move(int id, glm::vec2 position)
void Waypoints::move(int id, glm::vec2 position, int set_id)
{
for(auto& p : waypoints) {
if (p.id == id) {
for (auto& p : waypoints)
{
if (p.id == id && p.set_id == set_id)
{
p.position = position;
dirty = true;
return;
}
}
}

void Waypoints::remove(int id)
void Waypoints::remove(int id, int set_id)
{
waypoints.erase(std::remove_if(waypoints.begin(), waypoints.end(), [id](auto& p) { return p.id == id; }), waypoints.end());
waypoints.erase(std::remove_if(waypoints.begin(), waypoints.end(), [id, set_id](auto& p) { return p.id == id && p.set_id == set_id; }), waypoints.end());
dirty = true;
}

std::optional<glm::vec2> Waypoints::get(int id)
std::optional<glm::vec2> Waypoints::get(int id, int set_id)
{
for(auto& p : waypoints)
if (p.id == id)
return p.position;
for (auto& p : waypoints)
if (p.id == id && p.set_id == set_id) return p.position;
return {};
}

void Waypoints::setRoute(bool value, int set_id)
{
if (set_id < 1 || set_id > MAX_SETS) return;
is_route[set_id - 1] = value;
dirty = true;
}
14 changes: 10 additions & 4 deletions src/components/player.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <array>
#include "stringImproved.h"
#include "crewPosition.h"

Expand Down Expand Up @@ -50,17 +51,22 @@ class PlayerControl
class Waypoints
{
public:
static constexpr int MAX_SETS = 4;
bool dirty = true;
// IDs are 1-9 within sets 1-4
struct Point {
int id;
int set_id;
glm::vec2 position;
};
std::vector<Point> waypoints;
std::array<bool, MAX_SETS> is_route{};

int addNew(glm::vec2 position);
void move(int id, glm::vec2 position);
void remove(int id);
std::optional<glm::vec2> get(int id);
int addNew(glm::vec2 position, int set_id = 1);
void move(int id, glm::vec2 position, int set_id = 1);
void remove(int id, int set_id = 1);
std::optional<glm::vec2> get(int id, int set_id = 1);
void setRoute(bool value, int set_id = 1);
};

string alertLevelToString(AlertLevel level);
Expand Down
4 changes: 4 additions & 0 deletions src/gameGlobalInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ GameGlobalInfo::GameGlobalInfo()
hacking_games = HG_All;
use_beam_shield_frequencies = true;
use_system_damage = true;
enable_multiple_waypoint_sets = false;
enable_waypoint_routes = false;
allow_main_screen_tactical_radar = true;
allow_main_screen_long_range_radar = true;
allow_main_screen_strategic_map = true;
Expand All @@ -48,6 +50,8 @@ GameGlobalInfo::GameGlobalInfo()
registerMemberReplication(&victory_faction);
registerMemberReplication(&use_beam_shield_frequencies);
registerMemberReplication(&use_system_damage);
registerMemberReplication(&enable_multiple_waypoint_sets);
registerMemberReplication(&enable_waypoint_routes);
registerMemberReplication(&allow_main_screen_tactical_radar);
registerMemberReplication(&allow_main_screen_long_range_radar);
registerMemberReplication(&allow_main_screen_strategic_map);
Expand Down
2 changes: 2 additions & 0 deletions src/gameGlobalInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class GameGlobalInfo : public MultiplayerObject, public Updatable
EHackingGames hacking_games;
bool use_beam_shield_frequencies;
bool use_system_damage;
bool enable_multiple_waypoint_sets;
bool enable_waypoint_routes;
bool allow_main_screen_tactical_radar;
bool allow_main_screen_long_range_radar;
bool allow_main_screen_strategic_map;
Expand Down
2 changes: 2 additions & 0 deletions src/gui/hotkeyConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ Keys::Keys() :
gm_delete("GM_DELETE", "Delete"),
gm_clipboardcopy("GM_CLIPBOARD_COPY", "F5"),
gm_show_callsigns("GM_SHOW_CALLSIGNS", "C"),
gm_show_waypoints("GM_SHOW_WAYPOINTS", "W"),

// Spectator screen
spectator_show_callsigns("SPECTATOR_SHOW_CALLSIGNS", "C")
Expand Down Expand Up @@ -513,6 +514,7 @@ void Keys::init()
gm_delete.setLabel(tr("hotkey_menu", "GM screen"), tr("hotkey_GM", "Delete"));
gm_clipboardcopy.setLabel(tr("hotkey_menu", "GM screen"), tr("hotkey_GM", "Copy to clipboard"));
gm_show_callsigns.setLabel(tr("hotkey_menu", "GM screen"), tr("hotkey_GM", "Show callsigns (GM)"));
gm_show_waypoints.setLabel(tr("hotkey_menu", "GM screen"), tr("hotkey_GM", "Show waypoints (GM)"));

// Spectator screen
spectator_show_callsigns.setLabel(tr("hotkey_menu", "Spectator view"), tr("hotkey_Spectator", "Show callsigns (spectator)"));
Expand Down
1 change: 1 addition & 0 deletions src/gui/hotkeyConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ class Keys
sp::io::Keybinding gm_delete;
sp::io::Keybinding gm_clipboardcopy;
sp::io::Keybinding gm_show_callsigns;
sp::io::Keybinding gm_show_waypoints;

// Spectator screen binds
sp::io::Keybinding spectator_show_callsigns;
Expand Down
29 changes: 28 additions & 1 deletion src/menus/shipSelectionScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,10 @@ ShipSelectionScreen::ShipSelectionScreen()
if (game_server)
{
auto extra_settings_panel = new GuiPanel(this, "");
extra_settings_panel->setSize(600, 325)->setPosition(0, 0, sp::Alignment::Center)->hide();
extra_settings_panel
->setSize(600.0f, 375.0f)
->setPosition(0.0f, 0.0f, sp::Alignment::Center)
->hide();
auto extra_settings = new GuiElement(extra_settings_panel, "");
extra_settings->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax)->setMargins(25)->setAttribute("layout", "vertical");
// Science scan complexity selector.
Expand Down Expand Up @@ -376,6 +379,30 @@ ShipSelectionScreen::ShipSelectionScreen()
gameGlobalInfo->use_system_damage = value == 1;
}))->setValue(gameGlobalInfo->use_system_damage)->setSize(275, GuiElement::GuiSizeMax)->setPosition(0, 0, sp::Alignment::CenterRight);

// Waypoint settings row.
row = new GuiElement(extra_settings, "");
row
->setSize(GuiElement::GuiSizeMax, 50.0f)
->setAttribute("layout", "horizontal");

(new GuiToggleButton(row, "GAME_MULTI_WP_SETS_TOGGLE", tr("Multiple waypoint sets"),
[](bool value)
{
gameGlobalInfo->enable_multiple_waypoint_sets = value == 1;
}
))->setValue(gameGlobalInfo->enable_multiple_waypoint_sets)
->setSize(275.0f, GuiElement::GuiSizeMax)
->setPosition(0.0f, 0.0f, sp::Alignment::CenterLeft);

(new GuiToggleButton(row, "GAME_WP_ROUTES_TOGGLE", tr("Waypoint routes"),
[](bool value)
{
gameGlobalInfo->enable_waypoint_routes = value == 1;
}
))->setValue(gameGlobalInfo->enable_waypoint_routes)
->setSize(275.0f, GuiElement::GuiSizeMax)
->setPosition(0.0f, 0.0f, sp::Alignment::CenterRight);

auto close_button = new GuiButton(extra_settings_panel, "", tr("Close"), [this, extra_settings_panel](){
extra_settings_panel->hide();
container->show();
Expand Down
21 changes: 19 additions & 2 deletions src/multiplayer/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,24 @@
#include "multiplayer.h"

namespace sp::io {
static inline DataBuffer& operator << (DataBuffer& packet, const Waypoints::Point& p) { return packet << p.id << p.position; }
static inline DataBuffer& operator >> (DataBuffer& packet, Waypoints::Point& p) { packet >> p.id >> p.position; return packet; }
static inline DataBuffer& operator << (DataBuffer& packet, const Waypoints::Point& p) { return packet << p.id << p.set_id << p.position; }
static inline DataBuffer& operator >> (DataBuffer& packet, Waypoints::Point& p) { packet >> p.id >> p.set_id >> p.position; return packet; }

static inline DataBuffer& operator << (DataBuffer& packet, const std::array<bool, Waypoints::MAX_SETS>& arr)
{
uint8_t bits = 0;
for (int i = 0; i < Waypoints::MAX_SETS; i++)
if (arr[i]) bits |= (1 << i);
return packet << bits;
}
static inline DataBuffer& operator >> (DataBuffer& packet, std::array<bool, Waypoints::MAX_SETS>& arr)
{
uint8_t bits;
packet >> bits;
for (int i = 0; i < Waypoints::MAX_SETS; i++)
arr[i] = (bits >> i) & 1;
return packet;
}
}


Expand All @@ -18,4 +34,5 @@ BASIC_REPLICATION_IMPL(PlayerControlReplication, PlayerControl)

BASIC_REPLICATION_IMPL(WaypointsReplication, Waypoints)
REPLICATE_VECTOR_IF_DIRTY(waypoints, dirty);
BASIC_REPLICATION_FIELD(is_route);
}
Loading
Loading