Merge branch 'chat'
This commit is contained in:
commit
3fc12923ce
@ -684,8 +684,9 @@ void ClientApplication::changeState(MainAppState newState) {
|
||||
m_mainInterface = make_shared<MainInterface>(m_universeClient, m_worldPainter, m_cinematicOverlay);
|
||||
m_universeClient->setLuaCallbacks("interface", LuaBindings::makeInterfaceCallbacks(m_mainInterface.get()));
|
||||
m_universeClient->setLuaCallbacks("chat", LuaBindings::makeChatCallbacks(m_mainInterface.get(), m_universeClient.get()));
|
||||
m_universeClient->startLua();
|
||||
m_mainInterface->displayDefaultPanes();
|
||||
|
||||
m_universeClient->startLua();
|
||||
m_mainMixer->setWorldPainter(m_worldPainter);
|
||||
|
||||
if (auto renderer = Application::renderer()) {
|
||||
|
@ -537,8 +537,16 @@ LuaContext LuaEngine::createContext() {
|
||||
LuaDetail::shallowCopy(m_state, -1, -2);
|
||||
lua_pop(m_state, 1);
|
||||
|
||||
auto context = LuaContext(LuaDetail::LuaHandle(RefPtr<LuaEngine>(this), popHandle(m_state)));
|
||||
// Add loadstring
|
||||
auto handleIndex = context.handleIndex();
|
||||
context.set("loadstring", createFunction([this, handleIndex](String const& source, Maybe<String> const& name, Maybe<LuaTable> const& env) -> LuaFunction {
|
||||
String functionName = name ? strf("loadstring: {}", *name) : "loadstring";
|
||||
return createFunctionFromSource(env ? env->handleIndex() : handleIndex, source.utf8Ptr(), source.utf8Size(), functionName.utf8Ptr());
|
||||
}));
|
||||
|
||||
// Then set that environment as the new context environment in the registry.
|
||||
return LuaContext(LuaDetail::LuaHandle(RefPtr<LuaEngine>(this), popHandle(m_state)));
|
||||
return context;
|
||||
}
|
||||
|
||||
void LuaEngine::collectGarbage(Maybe<unsigned> steps) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
namespace Star {
|
||||
|
||||
BaseScriptPane::BaseScriptPane(Json config) : Pane(), m_rawConfig(config) {
|
||||
BaseScriptPane::BaseScriptPane(Json config, bool construct) : Pane(), m_rawConfig(config) {
|
||||
auto& root = Root::singleton();
|
||||
auto assets = root.assets();
|
||||
|
||||
@ -35,15 +35,8 @@ BaseScriptPane::BaseScriptPane(Json config) : Pane(), m_rawConfig(config) {
|
||||
});
|
||||
}
|
||||
|
||||
m_reader->construct(assets->fetchJson(m_config.get("gui")), this);
|
||||
|
||||
for (auto pair : m_config.getObject("canvasClickCallbacks", {}))
|
||||
m_canvasClickCallbacks.set(findChild<CanvasWidget>(pair.first), pair.second.toString());
|
||||
for (auto pair : m_config.getObject("canvasKeyCallbacks", {}))
|
||||
m_canvasKeyCallbacks.set(findChild<CanvasWidget>(pair.first), pair.second.toString());
|
||||
|
||||
m_script.setScripts(jsonToStringList(m_config.get("scripts", JsonArray())));
|
||||
m_script.setUpdateDelta(m_config.getUInt("scriptDelta", 1));
|
||||
if (construct)
|
||||
this->construct(assets->fetchJson(m_config.get("gui")));
|
||||
|
||||
m_callbacksAdded = false;
|
||||
}
|
||||
@ -140,4 +133,16 @@ GuiReaderPtr BaseScriptPane::reader() {
|
||||
return m_reader;
|
||||
}
|
||||
|
||||
void BaseScriptPane::construct(Json config) {
|
||||
m_reader->construct(config, this);
|
||||
|
||||
for (auto pair : m_config.getObject("canvasClickCallbacks", {}))
|
||||
m_canvasClickCallbacks.set(findChild<CanvasWidget>(pair.first), pair.second.toString());
|
||||
for (auto pair : m_config.getObject("canvasKeyCallbacks", {}))
|
||||
m_canvasKeyCallbacks.set(findChild<CanvasWidget>(pair.first), pair.second.toString());
|
||||
|
||||
m_script.setScripts(jsonToStringList(m_config.get("scripts", JsonArray())));
|
||||
m_script.setUpdateDelta(m_config.getUInt("scriptDelta", 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ STAR_CLASS(BaseScriptPane);
|
||||
|
||||
class BaseScriptPane : public Pane {
|
||||
public:
|
||||
BaseScriptPane(Json config);
|
||||
BaseScriptPane(Json config, bool construct = true);
|
||||
|
||||
virtual void show() override;
|
||||
void displayed() override;
|
||||
@ -34,6 +34,8 @@ public:
|
||||
Maybe<String> cursorOverride(Vec2I const& screenPosition) override;
|
||||
protected:
|
||||
virtual GuiReaderPtr reader() override;
|
||||
void construct(Json config);
|
||||
|
||||
Json m_config;
|
||||
Json m_rawConfig;
|
||||
|
||||
@ -45,7 +47,7 @@ protected:
|
||||
bool m_interactive;
|
||||
|
||||
bool m_callbacksAdded;
|
||||
LuaUpdatableComponent<LuaBaseComponent> m_script;
|
||||
mutable LuaUpdatableComponent<LuaBaseComponent> m_script;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -13,14 +13,25 @@
|
||||
#include "StarPlayerStorage.hpp"
|
||||
#include "StarTeamClient.hpp"
|
||||
|
||||
#include "StarPlayer.hpp"
|
||||
#include "StarConfigLuaBindings.hpp"
|
||||
#include "StarPlayerLuaBindings.hpp"
|
||||
#include "StarStatusControllerLuaBindings.hpp"
|
||||
#include "StarCelestialLuaBindings.hpp"
|
||||
#include "StarLuaGameConverters.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
Chat::Chat(UniverseClientPtr client) : m_client(client) {
|
||||
Chat::Chat(UniverseClientPtr client, Json const& baseConfig) : BaseScriptPane(baseConfig, false) {
|
||||
m_client = client;
|
||||
m_scripted = baseConfig.get("scripts", Json()).isType(Json::Type::Array);
|
||||
m_script.setLuaRoot(m_client->luaRoot());
|
||||
m_script.addCallbacks("world", LuaBindings::makeWorldCallbacks((World*)m_client->worldClient().get()));
|
||||
m_chatPrevIndex = 0;
|
||||
m_historyOffset = 0;
|
||||
|
||||
auto assets = Root::singleton().assets();
|
||||
auto config = assets->json("/interface/chat/chat.config:config");
|
||||
auto config = baseConfig.get("config");
|
||||
m_timeChatLastActive = Time::monotonicMilliseconds();
|
||||
m_chatTextStyle = config.get("textStyle");
|
||||
m_chatTextStyle.lineSpacing = config.get("lineHeight").toFloat();
|
||||
@ -45,15 +56,13 @@ Chat::Chat(UniverseClientPtr client) : m_client(client) {
|
||||
m_colorCodes[MessageContext::CommandResult] = config.query("colors.commandResult").toString();
|
||||
m_colorCodes[MessageContext::RadioMessage] = config.query("colors.radioMessage").toString();
|
||||
m_colorCodes[MessageContext::World] = config.query("colors.world").toString();
|
||||
if (!m_scripted) {
|
||||
m_reader->registerCallback("textBox", [=](Widget*) { startChat(); });
|
||||
m_reader->registerCallback("upButton", [=](Widget*) { scrollUp(); });
|
||||
m_reader->registerCallback("downButton", [=](Widget*) { scrollDown(); });
|
||||
m_reader->registerCallback("bottomButton", [=](Widget*) { scrollBottom(); });
|
||||
|
||||
GuiReader reader;
|
||||
|
||||
reader.registerCallback("textBox", [=](Widget*) { startChat(); });
|
||||
reader.registerCallback("upButton", [=](Widget*) { scrollUp(); });
|
||||
reader.registerCallback("downButton", [=](Widget*) { scrollDown(); });
|
||||
reader.registerCallback("bottomButton", [=](Widget*) { scrollBottom(); });
|
||||
|
||||
reader.registerCallback("filterGroup", [=](Widget* widget) {
|
||||
m_reader->registerCallback("filterGroup", [=](Widget* widget) {
|
||||
Json data = as<ButtonWidget>(widget)->data();
|
||||
auto filter = data.getArray("filter", {});
|
||||
m_modeFilter.clear();
|
||||
@ -62,41 +71,49 @@ Chat::Chat(UniverseClientPtr client) : m_client(client) {
|
||||
m_sendMode = ChatSendModeNames.getLeft(data.getString("sendMode", "Broadcast"));
|
||||
m_historyOffset = 0;
|
||||
});
|
||||
}
|
||||
|
||||
construct(baseConfig.get("gui"));
|
||||
|
||||
m_sendMode = ChatSendMode::Broadcast;
|
||||
|
||||
reader.construct(assets->json("/interface/chat/chat.config:gui"), this);
|
||||
|
||||
m_chatLog = fetchChild<CanvasWidget>("chatLog");
|
||||
m_bottomButton = fetchChild<ButtonWidget>("bottomButton");
|
||||
m_upButton = fetchChild<ButtonWidget>("upButton");
|
||||
m_textBox = fetchChild<TextBoxWidget>("textBox");
|
||||
m_say = fetchChild<LabelWidget>("say");
|
||||
|
||||
m_chatLog = fetchChild<CanvasWidget>("chatLog");
|
||||
if (!m_scripted) {
|
||||
if (auto logPadding = config.optQuery("padding")) {
|
||||
m_chatLogPadding = jsonToVec2I(logPadding.get());
|
||||
m_chatLog->setSize(m_chatLog->size() + m_chatLogPadding * 2);
|
||||
m_chatLog->setPosition(m_chatLog->position() - m_chatLogPadding);
|
||||
}
|
||||
else
|
||||
} else
|
||||
m_chatLogPadding = Vec2I();
|
||||
|
||||
m_bottomButton = fetchChild<ButtonWidget>("bottomButton");
|
||||
m_upButton = fetchChild<ButtonWidget>("upButton");
|
||||
|
||||
m_chatHistory.appendAll(m_client->playerStorage()->getMetadata("chatHistory").opt().apply(jsonToStringList).value());
|
||||
} else {
|
||||
m_script.addCallbacks("player", LuaBindings::makePlayerCallbacks(m_client->mainPlayer().get()));
|
||||
m_script.addCallbacks("status", LuaBindings::makeStatusControllerCallbacks(m_client->mainPlayer()->statusController()));
|
||||
m_script.addCallbacks("celestial", LuaBindings::makeCelestialCallbacks(m_client.get()));
|
||||
}
|
||||
|
||||
show();
|
||||
|
||||
updateBottomButton();
|
||||
//if (!m_scripted) {
|
||||
//updateBottomButton();
|
||||
|
||||
m_background = fetchChild<ImageStretchWidget>("background");
|
||||
m_defaultHeight = m_background->size()[1];
|
||||
m_expanded = false;
|
||||
updateSize();
|
||||
//}
|
||||
}
|
||||
|
||||
void Chat::update(float dt) {
|
||||
Pane::update(dt);
|
||||
|
||||
if (m_scripted)
|
||||
return;
|
||||
|
||||
auto team = m_client->teamClient()->currentTeam();
|
||||
for (auto button : fetchChild<ButtonGroup>("filterGroup")->buttons()) {
|
||||
auto mode = ChatSendModeNames.getLeft(button->data().getString("sendMode", "Broadcast"));
|
||||
@ -108,40 +125,64 @@ void Chat::update(float dt) {
|
||||
}
|
||||
|
||||
void Chat::startChat() {
|
||||
if (m_scripted)
|
||||
m_script.invoke("startChat");
|
||||
else {
|
||||
show();
|
||||
m_textBox->focus();
|
||||
}
|
||||
}
|
||||
|
||||
void Chat::startCommand() {
|
||||
if (m_scripted)
|
||||
m_script.invoke("startCommand");
|
||||
else {
|
||||
show();
|
||||
m_textBox->setText("/");
|
||||
m_textBox->focus();
|
||||
}
|
||||
}
|
||||
|
||||
bool Chat::hasFocus() const {
|
||||
if (m_scripted)
|
||||
return m_script.invoke<bool>("hasFocus").value();
|
||||
return m_textBox->hasFocus();
|
||||
}
|
||||
|
||||
void Chat::stopChat() {
|
||||
if (m_scripted)
|
||||
m_script.invoke("stopChat");
|
||||
else {
|
||||
m_textBox->setText("");
|
||||
m_textBox->blur();
|
||||
m_timeChatLastActive = Time::monotonicMilliseconds();
|
||||
}
|
||||
}
|
||||
|
||||
String Chat::currentChat() const {
|
||||
if (m_scripted)
|
||||
return m_script.invoke<String>("currentChat").value();
|
||||
return m_textBox->getText();
|
||||
}
|
||||
|
||||
bool Chat::setCurrentChat(String const& chat, bool moveCursor) {
|
||||
if (m_scripted)
|
||||
return m_script.invoke<bool>("setCurrentChat").value();
|
||||
return m_textBox->setText(chat, true, moveCursor);
|
||||
}
|
||||
|
||||
void Chat::clearCurrentChat() {
|
||||
if (m_scripted)
|
||||
m_script.invoke("clearCurrentChat");
|
||||
else {
|
||||
m_textBox->setText("");
|
||||
m_chatPrevIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ChatSendMode Chat::sendMode() const {
|
||||
if (m_scripted)
|
||||
return ChatSendModeNames.getLeft(m_script.invoke<String>("sendMode").value());
|
||||
return m_sendMode;
|
||||
}
|
||||
|
||||
@ -171,6 +212,13 @@ void Chat::addMessages(List<ChatReceivedMessage> const& messages, bool showPane)
|
||||
if (messages.empty())
|
||||
return;
|
||||
|
||||
if (m_scripted) {
|
||||
m_script.invoke("addMessages", messages.transformed([](ChatReceivedMessage const& message) {
|
||||
return message.toJson();
|
||||
}), showPane);
|
||||
return;
|
||||
}
|
||||
|
||||
GuiContext& guiContext = GuiContext::singleton();
|
||||
|
||||
for (auto const& message : messages) {
|
||||
@ -209,17 +257,22 @@ void Chat::addMessages(List<ChatReceivedMessage> const& messages, bool showPane)
|
||||
}
|
||||
|
||||
void Chat::addHistory(String const& chat) {
|
||||
if (m_chatHistory.size() > 0 && m_chatHistory.get(0).equals(chat))
|
||||
if (m_scripted)
|
||||
m_script.invoke("addHistory", chat);
|
||||
else if (m_chatHistory.size() > 0 && m_chatHistory.get(0).equals(chat))
|
||||
return;
|
||||
|
||||
else {
|
||||
m_chatHistory.prepend(chat);
|
||||
m_chatHistory.resize(std::min((unsigned)m_chatHistory.size(), m_chatHistoryLimit));
|
||||
m_timeChatLastActive = Time::monotonicMilliseconds();
|
||||
m_client->playerStorage()->setMetadata("chatHistory", JsonArray::from(m_chatHistory));
|
||||
}
|
||||
}
|
||||
|
||||
void Chat::clear(size_t count) {
|
||||
if (count > m_receivedMessages.size())
|
||||
if (m_scripted)
|
||||
m_script.invoke("clear", count);
|
||||
else if (count > m_receivedMessages.size())
|
||||
m_receivedMessages.clear();
|
||||
else
|
||||
m_receivedMessages.erase(m_receivedMessages.begin(), m_receivedMessages.begin() + count);
|
||||
@ -227,6 +280,8 @@ void Chat::clear(size_t count) {
|
||||
|
||||
void Chat::renderImpl() {
|
||||
Pane::renderImpl();
|
||||
if (m_scripted)
|
||||
return;
|
||||
if (m_textBox->hasFocus())
|
||||
m_timeChatLastActive = Time::monotonicMilliseconds();
|
||||
Vec4B fade = {255, 255, 255, 255};
|
||||
@ -303,6 +358,9 @@ void Chat::hide() {
|
||||
}
|
||||
|
||||
float Chat::visible() const {
|
||||
if (m_scripted)
|
||||
return m_script.invoke<float>("visible").value(1.0f);
|
||||
|
||||
double difference = (Time::monotonicMilliseconds() - m_timeChatLastActive) / 1000.0;
|
||||
if (difference < m_chatVisTime)
|
||||
return 1;
|
||||
@ -310,7 +368,7 @@ float Chat::visible() const {
|
||||
}
|
||||
|
||||
bool Chat::sendEvent(InputEvent const& event) {
|
||||
if (active()) {
|
||||
if (!m_scripted && active()) {
|
||||
if (hasFocus()) {
|
||||
if (event.is<KeyDownEvent>()) {
|
||||
auto actions = context()->actions(event);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "StarPane.hpp"
|
||||
#include "StarBaseScriptPane.hpp"
|
||||
#include "StarChatTypes.hpp"
|
||||
|
||||
namespace Star {
|
||||
@ -13,9 +13,9 @@ STAR_CLASS(ImageStretchWidget);
|
||||
STAR_CLASS(CanvasWidget);
|
||||
STAR_CLASS(Chat);
|
||||
|
||||
class Chat : public Pane {
|
||||
class Chat : public BaseScriptPane {
|
||||
public:
|
||||
Chat(UniverseClientPtr client);
|
||||
Chat(UniverseClientPtr client, Json const&);
|
||||
|
||||
void startChat();
|
||||
void startCommand();
|
||||
@ -57,6 +57,7 @@ private:
|
||||
void updateBottomButton();
|
||||
|
||||
UniverseClientPtr m_client;
|
||||
bool m_scripted;
|
||||
|
||||
TextBoxWidgetPtr m_textBox;
|
||||
LabelWidgetPtr m_say;
|
||||
|
@ -141,7 +141,7 @@ MainInterface::MainInterface(UniverseClientPtr client, WorldPainterPtr painter,
|
||||
m_collections = make_shared<ScriptPane>(m_client, "/interface/scripted/collections/collectionsgui.config");
|
||||
m_paneManager.registerPane(MainInterfacePanes::Collections, PaneLayer::Window, m_collections);
|
||||
|
||||
m_chat = make_shared<Chat>(m_client);
|
||||
m_chat = make_shared<Chat>(m_client, Root::singleton().assets()->json("/interface/chat/chat.config"));
|
||||
m_paneManager.registerPane(MainInterfacePanes::Chat, PaneLayer::Hud, m_chat);
|
||||
m_clientCommandProcessor = make_shared<ClientCommandProcessor>(m_client, m_cinematicOverlay, &m_paneManager, m_config->macroCommands);
|
||||
|
||||
@ -171,11 +171,6 @@ MainInterface::MainInterface(UniverseClientPtr client, WorldPainterPtr painter,
|
||||
m_nameplatePainter = make_shared<NameplatePainter>();
|
||||
m_questIndicatorPainter = make_shared<QuestIndicatorPainter>(m_client);
|
||||
m_chatBubbleManager = make_shared<ChatBubbleManager>();
|
||||
|
||||
m_paneManager.displayRegisteredPane(MainInterfacePanes::ActionBar);
|
||||
m_paneManager.displayRegisteredPane(MainInterfacePanes::Chat);
|
||||
m_paneManager.displayRegisteredPane(MainInterfacePanes::TeamBar);
|
||||
m_paneManager.displayRegisteredPane(MainInterfacePanes::StatusPane);
|
||||
}
|
||||
|
||||
MainInterface::~MainInterface() {
|
||||
@ -997,6 +992,13 @@ void MainInterface::reviveScriptPanes(List<ScriptPaneInfo>& panes) {
|
||||
}
|
||||
}
|
||||
|
||||
void MainInterface::displayDefaultPanes() {
|
||||
m_paneManager.displayRegisteredPane(MainInterfacePanes::ActionBar);
|
||||
m_paneManager.displayRegisteredPane(MainInterfacePanes::Chat);
|
||||
m_paneManager.displayRegisteredPane(MainInterfacePanes::TeamBar);
|
||||
m_paneManager.displayRegisteredPane(MainInterfacePanes::StatusPane);
|
||||
}
|
||||
|
||||
PanePtr MainInterface::createEscapeDialog() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
|
@ -132,6 +132,7 @@ public:
|
||||
|
||||
void takeScriptPanes(List<ScriptPaneInfo>& out);
|
||||
void reviveScriptPanes(List<ScriptPaneInfo>& panes);
|
||||
void displayDefaultPanes();
|
||||
private:
|
||||
PanePtr createEscapeDialog();
|
||||
|
||||
|
@ -519,6 +519,10 @@ void UniverseClient::stopLua() {
|
||||
m_scriptContexts.clear();
|
||||
}
|
||||
|
||||
LuaRootPtr UniverseClient::luaRoot() {
|
||||
return m_luaRoot;
|
||||
}
|
||||
|
||||
bool UniverseClient::reloadPlayer(Json const& data, Uuid const&, bool resetInterfaces, bool showIndicator) {
|
||||
auto player = mainPlayer();
|
||||
bool playerInWorld = player->inWorld();
|
||||
|
@ -89,6 +89,7 @@ public:
|
||||
void setLuaCallbacks(String const& groupName, LuaCallbacks const& callbacks);
|
||||
void startLua();
|
||||
void stopLua();
|
||||
LuaRootPtr luaRoot();
|
||||
|
||||
bool reloadPlayer(Json const& data, Uuid const& uuid, bool resetInterfaces = false, bool showIndicator = false);
|
||||
bool switchPlayer(Uuid const& uuid);
|
||||
|
@ -106,13 +106,6 @@ LuaContext LuaRoot::createContext(StringList const& scriptPaths) {
|
||||
}
|
||||
});
|
||||
|
||||
auto handleIndex = newContext.handleIndex();
|
||||
auto engine = m_luaEngine.get();
|
||||
newContext.set("loadstring", m_luaEngine->createFunction([engine, handleIndex](String const& source, Maybe<String> const& name, Maybe<LuaTable> const& env) -> LuaFunction {
|
||||
String functionName = name ? strf("loadstring: {}", *name) : "loadstring";
|
||||
return engine->createFunctionFromSource(env ? env->handleIndex() : handleIndex, source.utf8Ptr(), source.utf8Size(), functionName.utf8Ptr());
|
||||
}));
|
||||
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
for (auto const& scriptPath : scriptPaths) {
|
||||
|
@ -411,6 +411,18 @@ LuaCallbacks Pane::makePaneCallbacks() {
|
||||
return isDisplayed();
|
||||
});
|
||||
|
||||
callbacks.registerCallback("hasFocus", [this]() {
|
||||
hasFocus();
|
||||
});
|
||||
|
||||
callbacks.registerCallback("show", [this]() {
|
||||
show();
|
||||
});
|
||||
|
||||
callbacks.registerCallback("hide", [this]() {
|
||||
hide();
|
||||
});
|
||||
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user