Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-07-29 02:12:03 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-07-29 02:12:03 +1000
commit224ad2c2c07311475875d1d243354f8647112b45 (patch)
treec8247f22b4ddda345b7f35d7c6ead25d5e1f2791
parent35fc2679dea7b625bf559c6855e101fc62e613f4 (diff)
Reset script panes on character swap
-rw-r--r--source/client/StarClientApplication.cpp21
-rw-r--r--source/frontend/StarBaseScriptPane.cpp5
-rw-r--r--source/frontend/StarBaseScriptPane.hpp4
-rw-r--r--source/frontend/StarMainInterface.cpp67
-rw-r--r--source/frontend/StarMainInterface.hpp12
-rw-r--r--source/frontend/StarScriptPane.cpp4
-rw-r--r--source/frontend/StarScriptPane.hpp2
-rw-r--r--source/game/StarUniverseClient.cpp12
-rw-r--r--source/game/StarUniverseClient.hpp11
-rw-r--r--source/windowing/StarPaneManager.cpp17
-rw-r--r--source/windowing/StarPaneManager.hpp2
-rw-r--r--source/windowing/StarWidget.cpp4
-rw-r--r--source/windowing/StarWidget.hpp1
13 files changed, 131 insertions, 31 deletions
diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp
index ab620b4..efbdcad 100644
--- a/source/client/StarClientApplication.cpp
+++ b/source/client/StarClientApplication.cpp
@@ -510,10 +510,23 @@ void ClientApplication::changeState(MainAppState newState) {
m_universeClient->setLuaCallbacks("input", LuaBindings::makeInputCallbacks());
m_universeClient->setLuaCallbacks("voice", LuaBindings::makeVoiceCallbacks());
- m_universeClient->playerReloadCallback() = [&]() {
- if (auto paneManager = m_mainInterface->paneManager()) {
- if (auto inventory = paneManager->registeredPane<InventoryPane>(MainInterfacePanes::Inventory))
- inventory->clearChangedSlots();
+ auto heldScriptPanes = make_shared<List<MainInterface::ScriptPaneInfo>>();
+
+ m_universeClient->playerReloadPreCallback() = [&, heldScriptPanes](bool resetInterface) {
+ if (!resetInterface)
+ return;
+
+ m_mainInterface->takeScriptPanes(*heldScriptPanes);
+ };
+
+ m_universeClient->playerReloadCallback() = [&, heldScriptPanes](bool resetInterface) {
+ auto paneManager = m_mainInterface->paneManager();
+ if (auto inventory = paneManager->registeredPane<InventoryPane>(MainInterfacePanes::Inventory))
+ inventory->clearChangedSlots();
+
+ if (resetInterface) {
+ m_mainInterface->reviveScriptPanes(*heldScriptPanes);
+ heldScriptPanes->clear();
}
};
diff --git a/source/frontend/StarBaseScriptPane.cpp b/source/frontend/StarBaseScriptPane.cpp
index 90d253c..4164d9e 100644
--- a/source/frontend/StarBaseScriptPane.cpp
+++ b/source/frontend/StarBaseScriptPane.cpp
@@ -14,7 +14,7 @@
namespace Star {
-BaseScriptPane::BaseScriptPane(Json config) : Pane() {
+BaseScriptPane::BaseScriptPane(Json config) : Pane(), m_rawConfig(config) {
auto& root = Root::singleton();
auto assets = root.assets();
@@ -97,6 +97,9 @@ bool BaseScriptPane::sendEvent(InputEvent const& event) {
return Pane::sendEvent(event);
}
+Json const& BaseScriptPane::config() const { return m_config; }
+Json const& BaseScriptPane::rawConfig() const { return m_rawConfig; }
+
PanePtr BaseScriptPane::createTooltip(Vec2I const& screenPosition) {
auto result = m_script.invoke<Json>("createTooltip", screenPosition);
if (result && !result.value().isNull()) {
diff --git a/source/frontend/StarBaseScriptPane.hpp b/source/frontend/StarBaseScriptPane.hpp
index 4a47a4a..df2d4c5 100644
--- a/source/frontend/StarBaseScriptPane.hpp
+++ b/source/frontend/StarBaseScriptPane.hpp
@@ -25,12 +25,16 @@ public:
void tick(float dt) override;
bool sendEvent(InputEvent const& event) override;
+
+ Json const& config() const;
+ Json const& rawConfig() const;
PanePtr createTooltip(Vec2I const& screenPosition) override;
Maybe<String> cursorOverride(Vec2I const& screenPosition) override;
protected:
virtual GuiReaderPtr reader();
Json m_config;
+ Json m_rawConfig;
GuiReaderPtr m_reader;
diff --git a/source/frontend/StarMainInterface.cpp b/source/frontend/StarMainInterface.cpp
index 526ab99..1497b8b 100644
--- a/source/frontend/StarMainInterface.cpp
+++ b/source/frontend/StarMainInterface.cpp
@@ -498,22 +498,8 @@ void MainInterface::handleInteractAction(InteractAction interactAction) {
m_paneManager.dismissPane(m_interactionScriptPanes[sourceEntity]);
ScriptPanePtr scriptPane = make_shared<ScriptPane>(m_client, interactAction.data, sourceEntity);
- // keep any number of script panes open with null source entities
- if (sourceEntity != NullEntityId)
- m_interactionScriptPanes[sourceEntity] = scriptPane;
+ displayScriptPane(scriptPane, sourceEntity);
- if (scriptPane->openWithInventory()) {
- m_paneManager.displayPane(PaneLayer::Window, scriptPane, [this](PanePtr const&) {
- if (auto player = m_client->mainPlayer())
- player->clearSwap();
- m_paneManager.dismissRegisteredPane(MainInterfacePanes::Inventory);
- });
- m_paneManager.displayRegisteredPane(MainInterfacePanes::Inventory);
- m_paneManager.bringPaneAdjacent(m_paneManager.registeredPane(MainInterfacePanes::Inventory),
- scriptPane, Root::singleton().assets()->json("/interface.config:bringAdjacentWindowGap").toFloat());
- } else {
- m_paneManager.displayPane(PaneLayer::Window, scriptPane);
- }
} else if (interactAction.type == InteractActionType::Message) {
m_client->mainPlayer()->receiveMessage(connectionForEntity(interactAction.entityId),
interactAction.data.getString("messageType"), interactAction.data.getArray("messageArgs"));
@@ -952,6 +938,38 @@ CanvasWidgetPtr MainInterface::fetchCanvas(String const& canvasName, bool ignore
return canvas;
}
+// For when the player swaps characters. We need to completely reload ScriptPanes,
+// because a lot of ScriptPanes do not expect the character to suddenly change and may break or spill data over.
+void MainInterface::takeScriptPanes(List<ScriptPaneInfo>& out) {
+ m_paneManager.dismissWhere([&](PanePtr const& pane) {
+ if (auto scriptPane = as<ScriptPane>(pane)) {
+ if (scriptPane->isDismissed())
+ return false;
+ auto sourceEntityId = scriptPane->sourceEntityId();
+ m_interactionScriptPanes.remove(sourceEntityId);
+ auto& info = out.emplaceAppend();
+ info.scriptPane = scriptPane;
+ info.config = scriptPane->rawConfig();
+ info.sourceEntityId = sourceEntityId;
+ info.visible = scriptPane->visibility();
+ info.position = scriptPane->relativePosition();
+
+ return true;
+ }
+ return false;
+ });
+}
+
+void MainInterface::reviveScriptPanes(List<ScriptPaneInfo>& panes) {
+ for (auto& info : panes) { // this is evil and stupid
+ info.scriptPane->~ScriptPane();
+ new(info.scriptPane.get()) ScriptPane(m_client, info.config, info.sourceEntityId);
+ info.scriptPane->setVisibility(info.visible);
+ displayScriptPane(info.scriptPane, info.sourceEntityId);
+ info.scriptPane->setPosition(info.position);
+ }
+}
+
PanePtr MainInterface::createEscapeDialog() {
auto assets = Root::singleton().assets();
@@ -1542,4 +1560,23 @@ bool MainInterface::overlayClick(Vec2I const& mousePos, MouseButton mouseButton)
return false;
}
+void MainInterface::displayScriptPane(ScriptPanePtr& scriptPane, EntityId sourceEntity) {
+ // keep any number of script panes open with null source entities
+ if (sourceEntity != NullEntityId)
+ m_interactionScriptPanes[sourceEntity] = scriptPane;
+
+ if (scriptPane->openWithInventory()) {
+ m_paneManager.displayPane(PaneLayer::Window, scriptPane, [this](PanePtr const&) {
+ if (auto player = m_client->mainPlayer())
+ player->clearSwap();
+ m_paneManager.dismissRegisteredPane(MainInterfacePanes::Inventory);
+ });
+ m_paneManager.displayRegisteredPane(MainInterfacePanes::Inventory);
+ m_paneManager.bringPaneAdjacent(m_paneManager.registeredPane(MainInterfacePanes::Inventory),
+ scriptPane, Root::singleton().assets()->json("/interface.config:bringAdjacentWindowGap").toFloat());
+ } else {
+ m_paneManager.displayPane(PaneLayer::Window, scriptPane);
+ }
+}
+
} \ No newline at end of file
diff --git a/source/frontend/StarMainInterface.hpp b/source/frontend/StarMainInterface.hpp
index ddc4d3d..adba4e6 100644
--- a/source/frontend/StarMainInterface.hpp
+++ b/source/frontend/StarMainInterface.hpp
@@ -119,6 +119,16 @@ public:
CanvasWidgetPtr fetchCanvas(String const& canvasName, bool ignoreInterfaceScale = false);
+ struct ScriptPaneInfo {
+ ScriptPanePtr scriptPane;
+ Json config;
+ EntityId sourceEntityId;
+ bool visible;
+ Vec2I position;
+ };
+
+ void takeScriptPanes(List<ScriptPaneInfo>& out);
+ void reviveScriptPanes(List<ScriptPaneInfo>& panes);
private:
PanePtr createEscapeDialog();
@@ -142,6 +152,8 @@ private:
bool overlayClick(Vec2I const& mousePos, MouseButton mouseButton);
+ void displayScriptPane(ScriptPanePtr& scriptPane, EntityId sourceEntity);
+
GuiContext* m_guiContext;
MainInterfaceConfigConstPtr m_config;
InterfaceCursor m_cursor;
diff --git a/source/frontend/StarScriptPane.cpp b/source/frontend/StarScriptPane.cpp
index 2cd74a5..2105680 100644
--- a/source/frontend/StarScriptPane.cpp
+++ b/source/frontend/StarScriptPane.cpp
@@ -88,4 +88,8 @@ bool ScriptPane::openWithInventory() const {
return m_config.getBool("openWithInventory", false);
}
+EntityId ScriptPane::sourceEntityId() const {
+ return m_sourceEntityId;
+}
+
}
diff --git a/source/frontend/StarScriptPane.hpp b/source/frontend/StarScriptPane.hpp
index e7ed2ae..298d7c0 100644
--- a/source/frontend/StarScriptPane.hpp
+++ b/source/frontend/StarScriptPane.hpp
@@ -22,6 +22,8 @@ public:
bool openWithInventory() const;
+ EntityId sourceEntityId() const;
+
LuaCallbacks makePaneCallbacks() override;
private:
UniverseClientPtr m_client;
diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp
index f12ae28..c17f8bc 100644
--- a/source/game/StarUniverseClient.cpp
+++ b/source/game/StarUniverseClient.cpp
@@ -477,7 +477,7 @@ void UniverseClient::stopLua() {
m_scriptContexts.clear();
}
-bool UniverseClient::reloadPlayer(Json const& data, Uuid const& uuid) {
+bool UniverseClient::reloadPlayer(Json const& data, Uuid const& uuid, bool resetInterfaces) {
auto player = mainPlayer();
bool playerInWorld = player->inWorld();
auto world = as<WorldClient>(player->world());
@@ -487,7 +487,7 @@ bool UniverseClient::reloadPlayer(Json const& data, Uuid const& uuid) {
: connectionEntitySpace(world->connection()).first;
if (m_playerReloadPreCallback)
- m_playerReloadPreCallback();
+ m_playerReloadPreCallback(resetInterfaces);
if (playerInWorld) {
world->removeEntity(player->entityId(), false);
@@ -515,7 +515,7 @@ bool UniverseClient::reloadPlayer(Json const& data, Uuid const& uuid) {
player->universeMap()->filterMappedObjects(coordinate, m_systemWorldClient->objectKeys());
if (m_playerReloadCallback)
- m_playerReloadCallback();
+ m_playerReloadCallback(resetInterfaces);
if (exception)
std::rethrow_exception(exception);
@@ -527,7 +527,7 @@ bool UniverseClient::switchPlayer(Uuid const& uuid) {
if (uuid == mainPlayer()->uuid())
return false;
else if (auto data = m_playerStorage->maybeGetPlayerData(uuid))
- return reloadPlayer(*data, uuid);
+ return reloadPlayer(*data, uuid, true);
else
return false;
}
@@ -546,11 +546,11 @@ bool UniverseClient::switchPlayer(String const& name) {
return false;
}
-UniverseClient::Callback& UniverseClient::playerReloadPreCallback() {
+UniverseClient::ReloadPlayerCallback& UniverseClient::playerReloadPreCallback() {
return m_playerReloadPreCallback;
}
-UniverseClient::Callback& UniverseClient::playerReloadCallback() {
+UniverseClient::ReloadPlayerCallback& UniverseClient::playerReloadCallback() {
return m_playerReloadCallback;
}
diff --git a/source/game/StarUniverseClient.hpp b/source/game/StarUniverseClient.hpp
index 911061c..89c9c39 100644
--- a/source/game/StarUniverseClient.hpp
+++ b/source/game/StarUniverseClient.hpp
@@ -91,14 +91,15 @@ public:
void startLua();
void stopLua();
- bool reloadPlayer(Json const& data, Uuid const& uuid);
+ bool reloadPlayer(Json const& data, Uuid const& uuid, bool resetInterfaces = false);
bool switchPlayer(Uuid const& uuid);
bool switchPlayer(size_t index);
bool switchPlayer(String const& name);
typedef std::function<void()> Callback;
- Callback& playerReloadPreCallback();
- Callback& playerReloadCallback();
+ typedef std::function<void(bool)> ReloadPlayerCallback;
+ ReloadPlayerCallback& playerReloadPreCallback();
+ ReloadPlayerCallback& playerReloadCallback();
ClockConstPtr universeClock() const;
CelestialLogConstPtr celestialLog() const;
@@ -161,8 +162,8 @@ private:
typedef shared_ptr<ScriptComponent> ScriptComponentPtr;
StringMap<ScriptComponentPtr> m_scriptContexts;
- Callback m_playerReloadPreCallback;
- Callback m_playerReloadCallback;
+ ReloadPlayerCallback m_playerReloadPreCallback;
+ ReloadPlayerCallback m_playerReloadCallback;
};
}
diff --git a/source/windowing/StarPaneManager.cpp b/source/windowing/StarPaneManager.cpp
index f34c786..9dd7737 100644
--- a/source/windowing/StarPaneManager.cpp
+++ b/source/windowing/StarPaneManager.cpp
@@ -128,6 +128,23 @@ void PaneManager::setBackgroundWidget(WidgetPtr bg) {
m_backgroundWidget = bg;
}
+void PaneManager::dismissWhere(function<bool(PanePtr const&)> func) {
+ if (!func)
+ return;
+
+ for (auto& layerPair : m_displayedPanes) {
+ eraseWhere(layerPair.second, [&](auto& panePair) {
+ if (func(panePair.first)) {
+ panePair.first->dismissed();
+ if (panePair.second)
+ panePair.second(panePair.first);
+ return true;
+ }
+ return false;
+ });
+ }
+}
+
PanePtr PaneManager::keyboardCapturedPane() const {
for (auto const& layerPair : m_displayedPanes) {
for (auto const& panePair : layerPair.second) {
diff --git a/source/windowing/StarPaneManager.hpp b/source/windowing/StarPaneManager.hpp
index 8adf772..e69f699 100644
--- a/source/windowing/StarPaneManager.hpp
+++ b/source/windowing/StarPaneManager.hpp
@@ -63,6 +63,8 @@ public:
void setBackgroundWidget(WidgetPtr bg);
+ void dismissWhere(function<bool(PanePtr const&)> func);
+
// Returns the pane that has captured the keyboard, if any.
PanePtr keyboardCapturedPane() const;
// Returns true if the current pane that has captured the keyboard is
diff --git a/source/windowing/StarWidget.cpp b/source/windowing/StarWidget.cpp
index 48b945f..0287288 100644
--- a/source/windowing/StarWidget.cpp
+++ b/source/windowing/StarWidget.cpp
@@ -219,6 +219,10 @@ void Widget::hide() {
m_visible = false;
}
+bool Widget::visibility() const {
+ return m_visible;
+}
+
void Widget::toggleVisibility() {
m_visible = !m_visible;
}
diff --git a/source/windowing/StarWidget.hpp b/source/windowing/StarWidget.hpp
index f6e9928..1e78d74 100644
--- a/source/windowing/StarWidget.hpp
+++ b/source/windowing/StarWidget.hpp
@@ -58,6 +58,7 @@ public:
virtual void show();
virtual void hide();
+ virtual bool visibility() const;
virtual void toggleVisibility();
virtual void setVisibility(bool visibility);