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
46 changes: 29 additions & 17 deletions src/gui/gui2_resizabledialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,54 @@
GuiResizableDialog::GuiResizableDialog(GuiContainer* owner, string id, string title)
: GuiPanel(owner, id)
{
auto title_bar_layout = new GuiElement(this, "");
title_bar_layout->setMargins(25, 0)->setSize(GuiElement::GuiSizeMax, title_bar_height)->setAttribute("layout", "horizontalright");

close_button = new GuiButton(title_bar_layout, "", "x", [this](){
onClose();
});
close_button->setSize(50, GuiElement::GuiSizeMax);

minimize_button = new GuiToggleButton(title_bar_layout, "", "_", [this](bool value)
auto layout = new GuiElement(this, "RESIZABLE_LAYOUT");
layout->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);
layout->setAttribute("layout", "vertical");
const float button_size = title_bar_height - 4.0f;

auto title_bar_layout = new GuiElement(layout, "RESIZABLE_TITLE_BAR_LAYOUT");
title_bar_layout->setMargins(25.0f, 0.0f, 10.0f, 0.0f)->setSize(GuiElement::GuiSizeMax, title_bar_height);
title_bar_layout->setAttribute("layout", "horizontal");
title_bar = new GuiAutoSizeLabel(title_bar_layout, "RESIZABLE_TITLE_BAR", title, glm::vec2(100.0f, title_bar_height), glm::vec2(500.0f, title_bar_height), 20.0f, 20.0f);
title_bar->setClipped()->addBackground()->setAlignment(sp::Alignment::CenterLeft)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

minimize_button = new GuiToggleButton(title_bar_layout, "RESIZABLE_MINIMIZE", "", [this](bool value)
{
minimize(value);
});
minimize_button->setSize(50, GuiElement::GuiSizeMax);
minimize_button->setTextSize(20.0f)->setIcon("gui/widget/IndicatorArrow.png", sp::Alignment::Center, 90.0f)->setSize(button_size, button_size)->setMargins(0.0f, 2.0f);

title_bar = new GuiLabel(title_bar_layout, "", title, 20);
title_bar->addBackground()->setAlignment(sp::Alignment::CenterLeft)->setPosition(0, 0, sp::Alignment::TopLeft)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);
close_button = new GuiButton(title_bar_layout, "RESIZABLE_CLOSE", "X", [this]()
{
onClose();
});
close_button->setTextSize(20.0f)->setSize(button_size, button_size)->setMargins(0.0f, 2.0f);

contents = new GuiElement(this, "");
contents->setPosition(resize_icon_size / 2.0f, title_bar_height, sp::Alignment::TopLeft);
contents = new GuiElement(layout, "RESIZABLE_CONTENTS");
contents->setMargins(25.0f, 0.0f, 25.0f, 10.0f)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);
contents->setAttribute("layout", "vertical");

min_size = glm::vec2(200, title_bar_height + resize_icon_size);
min_size = glm::vec2(200.0f, title_bar_height + resize_icon_size);
minimized = false;
}

void GuiResizableDialog::minimize(bool minimize)
{
minimize_button->setValue(minimize);
minimize_button->setIcon("gui/widget/IndicatorArrow.png", sp::Alignment::Center, 90.0f * (minimize ? -1.0f : 1.0f));

if (minimize != minimized)
{
if (minimize)
{
contents->hide();
original_height = getSize().y;
setSize(getSize().x, title_bar_height);
}else{
contents->show();
}
else
{
setSize(getSize().x, original_height);
contents->show();
}
}
minimized = minimize;
Expand Down Expand Up @@ -82,6 +93,7 @@ void GuiResizableDialog::onDraw(sp::RenderTarget& renderer)
bool GuiResizableDialog::onMouseDown(sp::io::Pointer::Button button, glm::vec2 position, sp::io::Pointer::ID id)
{
click_state = ClickState::None;

if (title_bar->getRect().contains(position))
{
click_state = ClickState::Drag;
Expand Down
4 changes: 2 additions & 2 deletions src/gui/gui2_resizabledialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "gui2_panel.h"

class GuiLabel;
class GuiAutoSizeLabel;
class GuiButton;
class GuiToggleButton;

Expand All @@ -24,7 +24,7 @@ class GuiResizableDialog : public GuiPanel
static constexpr float resize_icon_size = 25.0f;
static constexpr float title_bar_height = 30.0f;

GuiLabel* title_bar;
GuiAutoSizeLabel* title_bar;
GuiToggleButton* minimize_button;
GuiButton* close_button;
bool minimized;
Expand Down
77 changes: 57 additions & 20 deletions src/screens/gm/chatDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,60 @@

#include "screenComponents/radarView.h"

#include "gui/gui2_button.h"
#include "gui/gui2_textentry.h"
#include "gui/gui2_scrolltext.h"

GameMasterChatDialog::GameMasterChatDialog(GuiContainer* owner, GuiRadarView* radar, sp::ecs::Entity player)
: GuiResizableDialog(owner, "", ""), player(player)
: GuiResizableDialog(owner, "GM_CHAT_DIALOG", ""), player(player)
{
this->radar = radar;

text_entry = new GuiTextEntry(contents, "", "");
text_entry->setTextSize(23)->setPosition(0, 0, sp::Alignment::BottomLeft)->setSize(GuiElement::GuiSizeMax, 30);
text_entry->enterCallback([this](string text){
if (this->player)
chat_text = new GuiScrollText(contents, "GM_CHAT_TEXT", "");
chat_text->enableAutoScrollDown()->setScrollbarWidth(25)->setTextSize(20)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

text_entry = new GuiTextEntry(contents, "GM_CHAT_ENTRY", "");
text_entry->setTextSize(20)->setSize(GuiElement::GuiSizeMax, 25.0f)->setMargins(0.0f, 10.0f, 0.0f, 0.0f);
text_entry->enterCallback(
[this](string text)
{
auto transmitter = this->player.getComponent<CommsTransmitter>();
if (transmitter && transmitter->state == CommsTransmitter::State::ChannelOpenGM)
CommsSystem::addCommsIncommingMessage(this->player, text_entry->getText());
else
CommsSystem::hailByGM(this->player, text_entry->getText());
if (this->player)
{
auto transmitter = this->player.getComponent<CommsTransmitter>();
if (transmitter && transmitter->state == CommsTransmitter::State::ChannelOpenGM)
CommsSystem::addCommsIncommingMessage(this->player, text_entry->getText());
else
CommsSystem::hailByGM(this->player, text_entry->getText());
}
text_entry->setText("");
}
text_entry->setText("");
});
);

auto status_bar = new GuiElement(contents, "GM_CHAT_STATUS_BAR");
status_bar->setSize(GuiElement::GuiSizeMax, 25.0f)->setMargins(0.0f, 10.0f, 0.0f, 0.0f);
status_bar->setAttribute("layout", "horizontalright");

chat_text = new GuiScrollText(contents, "", "");
chat_text->setTextSize(20)->setPosition(0, -30, sp::Alignment::BottomLeft)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);
chat_text->enableAutoScrollDown()->setScrollbarWidth(30);
use_comms_script = new GuiButton(status_bar, "GM_CHAT_SCRIPT", tr("Use comms script"),
[this]()
{
if (this->player)
{
// If the player's comms target can successfully open a scripted
// comms channel with the player, do so immediately and close this
// GM chat.
if (auto transmitter = this->player.getComponent<CommsTransmitter>())
{
if (CommsSystem::openChannel(this->player, transmitter->target))
{
this->disableComms(tr("chatGM", "Target - Using scripted comms"));
transmitter->state = CommsTransmitter::State::ChannelOpen;
this->onClose();
}
}
}
}
);
use_comms_script->setTextSize(20.0f)->setSize(135.0f, 25.0f)->setMargins(0.0f, 0.0f, 10.0f, 0.0f)->hide();

min_size.y += 100;

Expand All @@ -42,7 +71,6 @@ GameMasterChatDialog::GameMasterChatDialog(GuiContainer* owner, GuiRadarView* ra
void GameMasterChatDialog::onDraw(sp::RenderTarget& renderer)
{
GuiResizableDialog::onDraw(renderer);

auto transmitter = player.getComponent<CommsTransmitter>();
if (!player)
{
Expand Down Expand Up @@ -85,26 +113,36 @@ void GameMasterChatDialog::onDraw(sp::RenderTarget& renderer)
setTitle(tr("chatGM", "**{callsign} - Communicating as {target}**").format({{"callsign", callsign}, {"target", transmitter->target_name}}));
else
setTitle(tr("chatGM", "{callsign} - Communicating as {target}").format({{"callsign", callsign}, {"target", transmitter->target_name}}));

chat_text->enable();
text_entry->enable();

if (chat_text->getText() != transmitter->incomming_message)
{
chat_text->setText(transmitter->incomming_message);
notification = true;
}

if (auto transform = transmitter->target.getComponent<sp::Transform>())
renderer.drawLine(rect.center(), radar->worldToScreen(transform->getPosition()), glm::u8vec4(128, 255, 128, 128));

// Hide the use_comms_script button if the comms target can't use it.
// TODO: Confirm this works if callback is present
if (auto comms_receiver = transmitter->target.getComponent<CommsReceiver>())
use_comms_script->setVisible(!comms_receiver->script.empty() || comms_receiver->callback);

break;
}

if (auto transform = player.getComponent<sp::Transform>())
renderer.drawLine(rect.center(), radar->worldToScreen(transform->getPosition()), glm::u8vec4(128, 255, 128, 128));
}

void GameMasterChatDialog::disableComms(string title)
{
if (notification)
title = "**" + title + "**";
if (notification) title = "**" + title + "**";
setTitle(title);
use_comms_script->hide();
chat_text->disable();
text_entry->enable();
}
Expand All @@ -113,9 +151,8 @@ void GameMasterChatDialog::onClose()
{
auto transmitter = player.getComponent<CommsTransmitter>();
if (transmitter && (transmitter->state == CommsTransmitter::State::ChannelOpenGM || transmitter->state == CommsTransmitter::State::BeingHailedByGM))
{
CommsSystem::close(player);
}

hide();
minimize(false);
}
2 changes: 2 additions & 0 deletions src/screens/gm/chatDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "gui/gui2_resizabledialog.h"
#include "ecs/entity.h"

class GuiButton;
class GuiTextEntry;
class GuiScrollText;
class GuiRadarView;
Expand All @@ -23,6 +24,7 @@ class GameMasterChatDialog : public GuiResizableDialog

GuiTextEntry* text_entry;
GuiScrollText* chat_text;
GuiButton* use_comms_script;

void disableComms(string title);

Expand Down
51 changes: 38 additions & 13 deletions src/systems/comms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,59 @@ static sp::ecs::Entity script_active_entity;
void CommsSystem::update(float delta)
{
for(auto [entity, comms] : sp::ecs::Query<CommsTransmitter>()) {
if (comms.open_delay > 0.0f)
comms.open_delay -= delta;
if (game_server) {
if (comms.state == CommsTransmitter::State::OpeningChannel && comms.open_delay <= 0.0f) {
if (!comms.target) {
if (comms.open_delay > 0.0f) comms.open_delay -= delta;

if (game_server)
{
// If the channel opening delay is expired, determine whether to
// initialize comms with the target.
if (comms.state == CommsTransmitter::State::OpeningChannel && comms.open_delay <= 0.0f)
{
// Exit with a broken channel if the target no longer exists.
if (!comms.target)
{
comms.state = CommsTransmitter::State::ChannelBroken;
}else{
return;
}
else
{
comms.script_replies.clear();
comms.script_replies_dirty = true;

// If the other target is itself a comms transmitter, hail it.
if (auto other_transmitter = comms.target.getComponent<CommsTransmitter>())
{
comms.open_delay = channel_open_time;

if (other_transmitter->state == CommsTransmitter::State::Inactive || other_transmitter->state == CommsTransmitter::State::ChannelFailed || other_transmitter->state == CommsTransmitter::State::ChannelBroken || other_transmitter->state == CommsTransmitter::State::ChannelClosed)
if (other_transmitter->state == CommsTransmitter::State::Inactive
|| other_transmitter->state == CommsTransmitter::State::ChannelFailed
|| other_transmitter->state == CommsTransmitter::State::ChannelBroken
|| other_transmitter->state == CommsTransmitter::State::ChannelClosed)
{
other_transmitter->state = CommsTransmitter::State::BeingHailed;
other_transmitter->target = entity;

if (auto callsign = entity.getComponent<CallSign>())
other_transmitter->target_name = callsign->callsign;
else
other_transmitter->target_name = "?";
}
}else if (gameGlobalInfo->intercept_all_comms_to_gm) {
}
// If all other comms are intercepted by the GM, open a chat
// with the GM.
else if (gameGlobalInfo->intercept_all_comms_to_gm && comms.state != CommsTransmitter::State::ChannelOpen)
comms.state = CommsTransmitter::State::ChannelOpenGM;
}else if (openChannel(entity, comms.target)) {
// Otherwise, open a standard comms channel to the target.
else if (openChannel(entity, comms.target))
comms.state = CommsTransmitter::State::ChannelOpen;
} else {
else
comms.state = CommsTransmitter::State::ChannelFailed;
}
}
}

if (comms.state == CommsTransmitter::State::ChannelOpen || comms.state == CommsTransmitter::State::ChannelOpenPlayer)
{
// Exit with a broken channel if the target no longer exists.
if (!comms.target)
comms.state = CommsTransmitter::State::ChannelBroken;
}
Expand Down Expand Up @@ -349,23 +369,28 @@ bool CommsSystem::openChannel(sp::ecs::Entity player, sp::ecs::Entity target)
player.removeComponent<CommsTransmitterEnvironment>();
transmitter->incomming_message = "???";

// comms_script (comms from file) is prioritized over
// comms_callback (comms from inline function). Scenario authors must clear
// comms_script on an entity with a script in order to use comms_callback.
if (script_name != "")
{
auto& env = player.addComponent<CommsTransmitterEnvironment>();
env.script_environment = std::make_unique<sp::script::Environment>(gameGlobalInfo->script_environment_base.get());
setupSubEnvironment(*env.script_environment.get());
// consider "player" deprecated, but keep it for a long time
// Consider "player" deprecated, but keep it for a long time.
env.script_environment->setGlobal("player", player);
env.script_environment->setGlobal("comms_source", player);
env.script_environment->setGlobal("comms_target", target);
i18n::load("locale/" + script_name.replace(".lua", "." + PreferencesManager::get("language", "en") + ".po"));
LuaConsole::checkResult(env.script_environment->runFile<void>(script_name));
}else if (receiver->callback)
}
else if (receiver->callback)
{
receiver->callback.setGlobal("comms_source", player);
receiver->callback.setGlobal("comms_target", transmitter->target);
LuaConsole::checkResult(receiver->callback.call<void>(player, target));
}

script_active_entity = {};
return transmitter->incomming_message != "???";
}
Expand Down
1 change: 0 additions & 1 deletion src/systems/comms.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,5 @@ class CommsSystem : public sp::ecs::System
static int luaSetCommsMessage(lua_State* L);
static int luaAddCommsReply(lua_State* L);
static int luaCommsSwitchToGM(lua_State* L);
private:
static bool openChannel(sp::ecs::Entity player, sp::ecs::Entity target);
};
Loading