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
45 changes: 45 additions & 0 deletions scripts/api/entity/spaceobject.lua
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,48 @@ function Entity:onDestroyed(callback)
if self.components.hull then self.components.hull.on_destruction = callback end
return self
end
--- Defines a function to call when a scan is initiated against this entity.
--- The callback receives three parameters:
--- - target: The entity being scanned (the entity this callback is registered on)
--- - scanner: The entity performing the scan (player ship or probe)
--- - source: The entity that initiated the scan command (player ship, or probe if scan was initiated via radar link)
--- Example:
--- obj:onScanInitiated(function(target, scanner, source)
--- print(target:getCallSign() .. " is being scanned by " .. scanner:getCallSign())
--- if source ~= scanner then
--- print("(Scan initiated via radar-linked probe)")
--- end
--- end)
function Entity:onScanInitiated(callback)
if self.components.scan_state then self.components.scan_state.on_scan_initiated = callback end
return self
end
--- Defines a function to call when a scan is completed against this entity.
--- The callback receives three parameters:
--- - target: The entity being scanned (the entity this callback is registered on)
--- - scanner: The entity performing the scan (player ship or probe)
--- - source: The entity that initiated the scan command (player ship, or probe if scan was initiated via radar link)
--- Example:
--- obj:onScanCompleted(function(target, scanner, source)
--- print(target:getCallSign() .. " has been scanned by " .. scanner:getCallSign())
--- if source ~= scanner then
--- print("(Scan completed via radar-linked probe)")
--- end
--- end)
function Entity:onScanCompleted(callback)
if self.components.scan_state then self.components.scan_state.on_scan_completed = callback end
return self
end
--- Defines a function to call when a scan is cancelled against this entity.
--- The callback receives three parameters:
--- - target: The entity being scanned (the entity this callback is registered on)
--- - scanner: The entity performing the scan (player ship or probe)
--- - source: The entity that initiated the scan command (player ship, or probe if scan was initiated via radar link)
--- Example:
--- obj:onScanCancelled(function(target, scanner, source)
--- print("Scan of " .. target:getCallSign() .. " was cancelled")
--- end)
function Entity:onScanCancelled(callback)
if self.components.scan_state then self.components.scan_state.on_scan_cancelled = callback end
return self
end
6 changes: 6 additions & 0 deletions src/components/scanning.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "ecs/entity.h"
#include "script/callback.h"
#include <vector>


Expand Down Expand Up @@ -35,6 +36,10 @@ class ScanState
void setStateFor(sp::ecs::Entity entity, State state);
State getStateForFaction(sp::ecs::Entity entity);
void setStateForFaction(sp::ecs::Entity entity, State state);

sp::script::Callback on_scan_initiated;
sp::script::Callback on_scan_completed;
sp::script::Callback on_scan_cancelled;
};

class ScienceDescription
Expand All @@ -52,4 +57,5 @@ class ScienceScanner
float delay = 0.0f; // When a delay based scan is done, this will count down.
float max_scanning_delay = 6.0f;
sp::ecs::Entity target;
sp::ecs::Entity source;
};
1 change: 1 addition & 0 deletions src/multiplayer/scanning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ BASIC_REPLICATION_IMPL(ScienceScannerReplication, ScienceScanner)
BASIC_REPLICATION_FIELD(delay);
BASIC_REPLICATION_FIELD(max_scanning_delay);
BASIC_REPLICATION_FIELD(target);
BASIC_REPLICATION_FIELD(source);
}
32 changes: 26 additions & 6 deletions src/playerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,10 @@ void PlayerInfo::commandMainScreenOverlay(MainScreenOverlay mainScreen)
sendClientCommand(packet);
}

void PlayerInfo::commandScan(sp::ecs::Entity object)
void PlayerInfo::commandScan(sp::ecs::Entity object, sp::ecs::Entity scan_source)
{
sp::io::DataBuffer packet;
packet << CMD_SCAN_OBJECT << object;
packet << CMD_SCAN_OBJECT << object << scan_source;
sendClientCommand(packet);
}

Expand Down Expand Up @@ -702,26 +702,46 @@ void PlayerInfo::onReceiveClientCommand(int32_t client_id, sp::io::DataBuffer& p
packet >> mso;
if (auto pc = ship.getComponent<PlayerControl>())
pc->main_screen_overlay = mso;
}break;
}
break;
case CMD_SCAN_OBJECT:
{
sp::ecs::Entity e;
packet >> e;
sp::ecs::Entity source;
packet >> e >> source;

if (auto scanner = ship.getComponent<ScienceScanner>())
{
scanner->delay = scanner->max_scanning_delay;
scanner->target = e;
if (source) scanner->source = source;
else scanner->source = ship;

// Fire onScanInitiated callback
if (auto ss = e.getComponent<ScanState>())
{
if (ss->on_scan_initiated)
LuaConsole::checkResult(ss->on_scan_initiated.call<void>(e, ship, scanner->source));
}
}
}
break;
case CMD_SCAN_DONE:
ScanningSystem::scanningFinished(ship);
break;
case CMD_SCAN_CANCEL:
if (auto ss = ship.getComponent<ScienceScanner>()) {
ss->target = {};
if (auto scanner = ship.getComponent<ScienceScanner>()) {
// Fire onScanCancelled callback
if (scanner->target)
{
if (auto ss = scanner->target.getComponent<ScanState>())
{
if (ss->on_scan_cancelled)
LuaConsole::checkResult(ss->on_scan_cancelled.call<void>(scanner->target, ship, scanner->source));
}
}
scanner->target = {};
scanner->source = {};
}
break;
case CMD_SET_SYSTEM_POWER_REQUEST:
Expand Down
2 changes: 1 addition & 1 deletion src/playerInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class PlayerInfo : public MultiplayerObject
void commandSetShields(bool enabled);
void commandMainScreenSetting(MainScreenSetting mainScreen);
void commandMainScreenOverlay(MainScreenOverlay mainScreen);
void commandScan(sp::ecs::Entity object);
void commandScan(sp::ecs::Entity object, sp::ecs::Entity link_source = sp::ecs::Entity());
void commandSetSystemPowerRequest(ShipSystem::Type system, float power_level);
void commandSetSystemCoolantRequest(ShipSystem::Type system, float coolant_level);
void commandDock(sp::ecs::Entity station);
Expand Down
21 changes: 17 additions & 4 deletions src/screenComponents/scanTargetButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "targetsContainer.h"
#include "gui/gui2_button.h"
#include "gui/gui2_progressbar.h"
#include "components/radar.h"
#include "components/scanning.h"
#include "components/target.h"
#include "i18n.h"
Expand All @@ -11,10 +12,22 @@
GuiScanTargetButton::GuiScanTargetButton(GuiContainer* owner, string id, TargetsContainer* targets)
: GuiElement(owner, id), targets(targets)
{
button = new GuiButton(this, id + "_BUTTON", tr("scienceButton", "Scan"), [this]() {
if (my_spaceship && this->targets && this->targets->get())
my_player_info->commandScan(this->targets->get());
});
button = new GuiButton(this, id + "_BUTTON", tr("scienceButton", "Scan"),
[this]()
{
if (my_spaceship && this->targets && this->targets->get())
{
// Check for active radar link and validate the linked entity
auto rl = my_spaceship.getComponent<RadarLink>();
if (rl && rl->linked_entity && rl->linked_entity.hasComponent<AllowRadarLink>())
my_player_info->commandScan(this->targets->get(), rl->linked_entity);
else
my_player_info->commandScan(this->targets->get());
}


}
);
button->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);
progress = new GuiProgressbar(this, id + "_PROGRESS", 0, 6.0f, 0.0);
progress->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);
Expand Down
5 changes: 1 addition & 4 deletions src/screenComponents/scanTargetButton.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef SCAN_TARGET_BUTTON_H
#define SCAN_TARGET_BUTTON_H
#pragma once

#include "gui/gui2_element.h"

Expand All @@ -19,5 +18,3 @@ class GuiScanTargetButton : public GuiElement
virtual void onUpdate() override;
virtual void onDraw(sp::RenderTarget& target) override;
};

#endif//SCAN_TARGET_BUTTON_H
41 changes: 26 additions & 15 deletions src/screens/crew6/scienceScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ ScienceScreen::ScienceScreen(GuiContainer* owner, CrewPosition crew_position)
probe_radar->setPosition(120, 0, sp::Alignment::CenterLeft)->setSize(900,GuiElement::GuiSizeMax)->hide();
probe_radar->setAutoCentering(false)->longRange()->enableWaypoints()->enableCallsigns()->enableHeadingIndicators()->setStyle(GuiRadarView::Circular)->setFogOfWarStyle(GuiRadarView::NoFogOfWar);
probe_radar->setCallbacks(
[this](sp::io::Pointer::Button button, glm::vec2 position) {
[this](sp::io::Pointer::Button button, glm::vec2 position)
{
if (auto scanner = my_spaceship.getComponent<ScienceScanner>())
if (scanner->delay > 0.0f)
return;
Expand Down Expand Up @@ -188,22 +189,27 @@ ScienceScreen::ScienceScreen(GuiContainer* owner, CrewPosition crew_position)
database_view->hide()->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

// Probe view button
probe_view_button = new GuiToggleButton(radar_view, "PROBE_VIEW", tr("scienceButton", "Probe View"), [this](bool value){
auto rl = my_spaceship.getComponent<RadarLink>();
if (value && rl && rl->linked_entity)
probe_view_button = new GuiToggleButton(radar_view, "PROBE_VIEW", tr("scienceButton", "Probe View"),
[this](bool value)
{
auto transform = rl->linked_entity.getComponent<sp::Transform>();
if (transform) {
science_radar->hide();
probe_radar->show();
probe_radar->setViewPosition(transform->getPosition())->show();
auto rl = my_spaceship.getComponent<RadarLink>();
if (value && rl && rl->linked_entity)
{
if (auto transform = rl->linked_entity.getComponent<sp::Transform>())
{
science_radar->hide();
probe_radar->show();
probe_radar->setViewPosition(transform->getPosition())->show();
}
}
else
{
probe_view_button->setValue(false);
science_radar->show();
probe_radar->hide();
}
}else{
probe_view_button->setValue(false);
science_radar->show();
probe_radar->hide();
}
});
);
probe_view_button->setPosition(20, -120, sp::Alignment::BottomLeft)->setSize(200, 50)->disable();

// Draw the zoom slider.
Expand Down Expand Up @@ -529,7 +535,12 @@ void ScienceScreen::onUpdate()
auto scanstate = obj.getComponent<ScanState>();
if (scanstate && scanstate->getStateFor(my_spaceship) != ScanState::State::FullScan)
{
my_player_info->commandScan(obj);
// Check for active radar link and validate the linked entity
auto rl = my_spaceship.getComponent<RadarLink>();
if (rl && rl->linked_entity && rl->linked_entity.hasComponent<AllowRadarLink>() && probe_radar->isVisible())
my_player_info->commandScan(obj, rl->linked_entity);
else
my_player_info->commandScan(obj);
return;
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/screens/crew6/scienceScreen.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef SCIENCE_SCREEN_H
#define SCIENCE_SCREEN_H
#pragma once

#include "screenComponents/targetsContainer.h"
#include "gui/gui2_overlay.h"
Expand Down Expand Up @@ -68,5 +67,3 @@ class ScienceScreen : public GuiOverlay
float previous_long_range_radar=0;
float previous_short_range_radar=0;
};

#endif//SCIENCE_SCREEN_H
3 changes: 3 additions & 0 deletions src/script/components.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,9 @@ void initComponentScriptBindings()
BIND_MEMBER(ScanState, allow_simple_scan);
BIND_MEMBER(ScanState, complexity);
BIND_MEMBER(ScanState, depth);
BIND_MEMBER(ScanState, on_scan_initiated);
BIND_MEMBER(ScanState, on_scan_completed);
BIND_MEMBER(ScanState, on_scan_cancelled);
BIND_ARRAY_DIRTY_FLAG(ScanState, per_faction, per_faction_dirty);
BIND_ARRAY_DIRTY_FLAG_MEMBER(ScanState, per_faction, faction, per_faction_dirty);
BIND_ARRAY_DIRTY_FLAG_MEMBER(ScanState, per_faction, state, per_faction_dirty);
Expand Down
46 changes: 29 additions & 17 deletions src/systems/scanning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,62 @@
#include "components/scanning.h"
#include "gameGlobalInfo.h"
#include "multiplayer_server.h"
#include "menus/luaConsole.h"

#include <ecs/query.h>


void ScanningSystem::update(float delta)
{
for(auto [entity, scanner] : sp::ecs::Query<ScienceScanner>()) {
if (auto ss = scanner.target.getComponent<ScanState>()) {
// If the scan setting or a target's scan complexity is none/0,
// complete the scan after a delay.
for (auto [entity, scanner] : sp::ecs::Query<ScienceScanner>())
{
// If the scan setting or a target's scan complexity is none/0,
// complete the scan after a delay.
if (auto ss = scanner.target.getComponent<ScanState>())
{
if (ss->complexity == 0 || (ss->complexity < 0 && gameGlobalInfo->scanning_complexity == SC_None))
{
// If scan has just started, fire the onScanInitiated callback.
if (scanner.delay == scanner.max_scanning_delay && ss->on_scan_initiated)
LuaConsole::checkResult(ss->on_scan_initiated.call<void>(scanner.target, entity, scanner.source));

scanner.delay -= delta;
if (scanner.delay < 0 && game_server)
if (scanner.delay < 0.0f && game_server)
scanningFinished(entity);
}
}else{
// Otherwise, ignore the scanning_delay setting.
scanner.delay = 0.0;
}
// Otherwise, ignore the scanning_delay setting.
else scanner.delay = 0.0f;
}
}

void ScanningSystem::scanningFinished(sp::ecs::Entity source)
void ScanningSystem::scanningFinished(sp::ecs::Entity command_source)
{
auto scanner = source.getComponent<ScienceScanner>();
auto scanner = command_source.getComponent<ScienceScanner>();
if (!scanner) return;
auto ss = scanner->target.getComponent<ScanState>();
if (ss) {
switch(ss->getStateFor(source)) {

if (auto ss = scanner->target.getComponent<ScanState>())
{
switch(ss->getStateFor(command_source))
{
case ScanState::State::NotScanned:
case ScanState::State::FriendOrFoeIdentified:
if (ss->allow_simple_scan)
ss->setStateFor(source, ScanState::State::SimpleScan);
ss->setStateFor(command_source, ScanState::State::SimpleScan);
else
ss->setStateFor(source, ScanState::State::FullScan);
ss->setStateFor(command_source, ScanState::State::FullScan);
break;
case ScanState::State::SimpleScan:
ss->setStateFor(source, ScanState::State::FullScan);
ss->setStateFor(command_source, ScanState::State::FullScan);
break;
case ScanState::State::FullScan:
break;
}

LuaConsole::checkResult(ss->on_scan_completed.call<void>(scanner->target, command_source, scanner->source));
}

scanner->target = {};
scanner->delay = 0.0;
scanner->source = {};
scanner->delay = 0.0f;
}
Loading