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
6 changes: 6 additions & 0 deletions src/screenComponents/radarView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ GuiRadarView::GuiRadarView(GuiContainer* owner, string id, TargetsContainer* tar
view_position(0.0f,0.0f),
view_rotation(0),
auto_center_target(my_spaceship),
track_my_spaceship(true),
auto_center_on_ship(true),
auto_rotate_on_ship(false),
auto_distance(true),
Expand Down Expand Up @@ -93,6 +94,7 @@ GuiRadarView::GuiRadarView(GuiContainer* owner, string id, float distance, Targe
view_position(0.0f, 0.0f),
view_rotation(0),
auto_center_target(my_spaceship),
track_my_spaceship(true),
auto_center_on_ship(true),
auto_rotate_on_ship(false),
distance(distance),
Expand Down Expand Up @@ -123,6 +125,10 @@ GuiRadarView::GuiRadarView(GuiContainer* owner, string id, float distance, Targe

void GuiRadarView::onDraw(sp::RenderTarget& renderer)
{
// Keep centered on my_spaceship when the player's assigned ship changes.
if (track_my_spaceship && my_spaceship)
auto_center_target = my_spaceship;

// Auto-center on the target, defaulting to my_spaceship on creation.
auto transform = auto_center_target.getComponent<sp::Transform>();

Expand Down
3 changes: 2 additions & 1 deletion src/screenComponents/radarView.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class GuiRadarView : public GuiElement
glm::vec2 view_position{0, 0};
float view_rotation;
sp::ecs::Entity auto_center_target;
bool track_my_spaceship;
bool auto_center_on_ship;
bool auto_rotate_on_ship;
bool auto_distance = false;
Expand Down Expand Up @@ -108,7 +109,7 @@ class GuiRadarView : public GuiElement
bool getAutoCentering() { return auto_center_on_ship; }
GuiRadarView* setAutoCentering(bool value) { this->auto_center_on_ship = value; return this; }
sp::ecs::Entity getAutoCenterTarget() { return auto_center_target; }
GuiRadarView* setAutoCenterTarget(sp::ecs::Entity target) { this->auto_center_target = target; return this; }
GuiRadarView* setAutoCenterTarget(sp::ecs::Entity target) { this->auto_center_target = target; this->track_my_spaceship = false; return this; }
bool getAutoRotating() { return auto_rotate_on_ship; }
GuiRadarView* setAutoRotating(bool value) { this->auto_rotate_on_ship = value; return this; }
GuiRadarView* setCallbacks(bpfunc_t mouse_down_func, pfunc_t mouse_drag_func, pfunc_t mouse_up_func, fpfunc_t mouse_wheel_func) { this->mouse_down_func = mouse_down_func; this->mouse_drag_func = mouse_drag_func; this->mouse_up_func = mouse_up_func; this->mouse_wheel_func = mouse_wheel_func; return this; }
Expand Down
71 changes: 57 additions & 14 deletions src/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,18 +464,63 @@ static int luaGetEnemiesInRadiusFor(lua_State* L)

static void luaTransferPlayers(sp::ecs::Entity source, sp::ecs::Entity target, std::optional<CrewPosition> station)
{
if (!target.getComponent<PlayerControl>()) return;
// For each player, move them to the same station on the target.
for(auto i : player_info_list)
if (i->ship == source && (!station.has_value() || i->hasPosition(station.value())))
i->ship = target;
// Relevant only to player-controlled entities.
auto target_pc = target.getOrAddComponent<PlayerControl>();
if (target.hasComponent<AIController>()) target.removeComponent<AIController>();

if (!target_pc.allowed_positions.mask)
{
LOG(Error, "transferPlayersToShip: destination ship has no allowed crew positions. Resetting to Any.");
target_pc.allowed_positions = CrewPositions::all();
}

// For each matching player, reassign their ship, filter crew positions
// against the new ship's allowed positions, and clear their cached ship
// password.
for (auto i : player_info_list)
{
if (i->ship != source || (station.has_value() && !i->hasPosition(station.value())))
continue;

// Move player to new ship.
i->ship = target;

// Check against the destination's allowed crew positions. If a player's
// in a position prohibited by the new ship, log a warning for the
// scenario author and drop the player into the next allowed position.
for (auto& cps : i->crew_positions)
{
CrewPositions lost{cps.mask & ~target_pc.allowed_positions.mask};
if (lost.mask)
{
// This is probably not what the script user intended, so log
// it.
for (auto cp : lost)
LOG(Warning, "transferPlayersToShip: player ", i->name, " held the ", crewPositionToString(cp), " crew position, which is prohibited on the destination ship. Reassigning to next allowed position.");
// Assign the first allowed position not already held on this
// monitor.
for (int n = 0; n < static_cast<int>(CrewPosition::MAX); n++)
{
auto cp = static_cast<CrewPosition>(n);
if (target_pc.allowed_positions.has(cp) && !cps.has(cp))
{
cps.add(cp);
break;
}
}
}
cps.mask &= target_pc.allowed_positions.mask;
}

// Clear last ship password.
i->last_ship_password = "";
}
}

static bool luaHasPlayerAtPosition(sp::ecs::Entity source, CrewPosition station)
{
for(auto i : player_info_list)
if (i->ship == source && i->hasPosition(station))
return true;
for (auto i : player_info_list)
if (i->ship == source && i->hasPosition(station)) return true;
return false;
}

Expand All @@ -484,16 +529,14 @@ static int luaGetPlayersInfo(lua_State* L)
auto source = sp::script::Convert<sp::ecs::Entity>::fromLua(L, 1);
lua_newtable(L);
int index = 1;
for(auto i : player_info_list) {
if (i->ship != source)
continue;
for (auto i : player_info_list)
{
if (i->ship != source) continue;
lua_newtable(L);
lua_pushstring(L, i->name.c_str());
lua_setfield(L, -2, "name");
CrewPositions positions;
for(auto cp : i->crew_positions) {
positions.mask |= cp.mask;
}
for (auto cp : i->crew_positions) positions.mask |= cp.mask;
sp::script::Convert<CrewPositions>::toLua(L, positions);
lua_setfield(L, -2, "positions");
lua_seti(L, -2, index);
Expand Down
Loading