Reset script panes on character swap
This commit is contained in:
parent
35fc2679de
commit
224ad2c2c0
@ -510,10 +510,23 @@ void ClientApplication::changeState(MainAppState newState) {
|
|||||||
m_universeClient->setLuaCallbacks("input", LuaBindings::makeInputCallbacks());
|
m_universeClient->setLuaCallbacks("input", LuaBindings::makeInputCallbacks());
|
||||||
m_universeClient->setLuaCallbacks("voice", LuaBindings::makeVoiceCallbacks());
|
m_universeClient->setLuaCallbacks("voice", LuaBindings::makeVoiceCallbacks());
|
||||||
|
|
||||||
m_universeClient->playerReloadCallback() = [&]() {
|
auto heldScriptPanes = make_shared<List<MainInterface::ScriptPaneInfo>>();
|
||||||
if (auto paneManager = m_mainInterface->paneManager()) {
|
|
||||||
|
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))
|
if (auto inventory = paneManager->registeredPane<InventoryPane>(MainInterfacePanes::Inventory))
|
||||||
inventory->clearChangedSlots();
|
inventory->clearChangedSlots();
|
||||||
|
|
||||||
|
if (resetInterface) {
|
||||||
|
m_mainInterface->reviveScriptPanes(*heldScriptPanes);
|
||||||
|
heldScriptPanes->clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
BaseScriptPane::BaseScriptPane(Json config) : Pane() {
|
BaseScriptPane::BaseScriptPane(Json config) : Pane(), m_rawConfig(config) {
|
||||||
auto& root = Root::singleton();
|
auto& root = Root::singleton();
|
||||||
auto assets = root.assets();
|
auto assets = root.assets();
|
||||||
|
|
||||||
@ -97,6 +97,9 @@ bool BaseScriptPane::sendEvent(InputEvent const& event) {
|
|||||||
return Pane::sendEvent(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) {
|
PanePtr BaseScriptPane::createTooltip(Vec2I const& screenPosition) {
|
||||||
auto result = m_script.invoke<Json>("createTooltip", screenPosition);
|
auto result = m_script.invoke<Json>("createTooltip", screenPosition);
|
||||||
if (result && !result.value().isNull()) {
|
if (result && !result.value().isNull()) {
|
||||||
|
@ -26,11 +26,15 @@ public:
|
|||||||
|
|
||||||
bool sendEvent(InputEvent const& event) override;
|
bool sendEvent(InputEvent const& event) override;
|
||||||
|
|
||||||
|
Json const& config() const;
|
||||||
|
Json const& rawConfig() const;
|
||||||
|
|
||||||
PanePtr createTooltip(Vec2I const& screenPosition) override;
|
PanePtr createTooltip(Vec2I const& screenPosition) override;
|
||||||
Maybe<String> cursorOverride(Vec2I const& screenPosition) override;
|
Maybe<String> cursorOverride(Vec2I const& screenPosition) override;
|
||||||
protected:
|
protected:
|
||||||
virtual GuiReaderPtr reader();
|
virtual GuiReaderPtr reader();
|
||||||
Json m_config;
|
Json m_config;
|
||||||
|
Json m_rawConfig;
|
||||||
|
|
||||||
GuiReaderPtr m_reader;
|
GuiReaderPtr m_reader;
|
||||||
|
|
||||||
|
@ -498,22 +498,8 @@ void MainInterface::handleInteractAction(InteractAction interactAction) {
|
|||||||
m_paneManager.dismissPane(m_interactionScriptPanes[sourceEntity]);
|
m_paneManager.dismissPane(m_interactionScriptPanes[sourceEntity]);
|
||||||
|
|
||||||
ScriptPanePtr scriptPane = make_shared<ScriptPane>(m_client, interactAction.data, sourceEntity);
|
ScriptPanePtr scriptPane = make_shared<ScriptPane>(m_client, interactAction.data, sourceEntity);
|
||||||
// keep any number of script panes open with null source entities
|
displayScriptPane(scriptPane, sourceEntity);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else if (interactAction.type == InteractActionType::Message) {
|
} else if (interactAction.type == InteractActionType::Message) {
|
||||||
m_client->mainPlayer()->receiveMessage(connectionForEntity(interactAction.entityId),
|
m_client->mainPlayer()->receiveMessage(connectionForEntity(interactAction.entityId),
|
||||||
interactAction.data.getString("messageType"), interactAction.data.getArray("messageArgs"));
|
interactAction.data.getString("messageType"), interactAction.data.getArray("messageArgs"));
|
||||||
@ -952,6 +938,38 @@ CanvasWidgetPtr MainInterface::fetchCanvas(String const& canvasName, bool ignore
|
|||||||
return canvas;
|
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() {
|
PanePtr MainInterface::createEscapeDialog() {
|
||||||
auto assets = Root::singleton().assets();
|
auto assets = Root::singleton().assets();
|
||||||
|
|
||||||
@ -1542,4 +1560,23 @@ bool MainInterface::overlayClick(Vec2I const& mousePos, MouseButton mouseButton)
|
|||||||
return false;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -119,6 +119,16 @@ public:
|
|||||||
|
|
||||||
CanvasWidgetPtr fetchCanvas(String const& canvasName, bool ignoreInterfaceScale = false);
|
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:
|
private:
|
||||||
PanePtr createEscapeDialog();
|
PanePtr createEscapeDialog();
|
||||||
|
|
||||||
@ -142,6 +152,8 @@ private:
|
|||||||
|
|
||||||
bool overlayClick(Vec2I const& mousePos, MouseButton mouseButton);
|
bool overlayClick(Vec2I const& mousePos, MouseButton mouseButton);
|
||||||
|
|
||||||
|
void displayScriptPane(ScriptPanePtr& scriptPane, EntityId sourceEntity);
|
||||||
|
|
||||||
GuiContext* m_guiContext;
|
GuiContext* m_guiContext;
|
||||||
MainInterfaceConfigConstPtr m_config;
|
MainInterfaceConfigConstPtr m_config;
|
||||||
InterfaceCursor m_cursor;
|
InterfaceCursor m_cursor;
|
||||||
|
@ -88,4 +88,8 @@ bool ScriptPane::openWithInventory() const {
|
|||||||
return m_config.getBool("openWithInventory", false);
|
return m_config.getBool("openWithInventory", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityId ScriptPane::sourceEntityId() const {
|
||||||
|
return m_sourceEntityId;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ public:
|
|||||||
|
|
||||||
bool openWithInventory() const;
|
bool openWithInventory() const;
|
||||||
|
|
||||||
|
EntityId sourceEntityId() const;
|
||||||
|
|
||||||
LuaCallbacks makePaneCallbacks() override;
|
LuaCallbacks makePaneCallbacks() override;
|
||||||
private:
|
private:
|
||||||
UniverseClientPtr m_client;
|
UniverseClientPtr m_client;
|
||||||
|
@ -477,7 +477,7 @@ void UniverseClient::stopLua() {
|
|||||||
m_scriptContexts.clear();
|
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();
|
auto player = mainPlayer();
|
||||||
bool playerInWorld = player->inWorld();
|
bool playerInWorld = player->inWorld();
|
||||||
auto world = as<WorldClient>(player->world());
|
auto world = as<WorldClient>(player->world());
|
||||||
@ -487,7 +487,7 @@ bool UniverseClient::reloadPlayer(Json const& data, Uuid const& uuid) {
|
|||||||
: connectionEntitySpace(world->connection()).first;
|
: connectionEntitySpace(world->connection()).first;
|
||||||
|
|
||||||
if (m_playerReloadPreCallback)
|
if (m_playerReloadPreCallback)
|
||||||
m_playerReloadPreCallback();
|
m_playerReloadPreCallback(resetInterfaces);
|
||||||
|
|
||||||
if (playerInWorld) {
|
if (playerInWorld) {
|
||||||
world->removeEntity(player->entityId(), false);
|
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());
|
player->universeMap()->filterMappedObjects(coordinate, m_systemWorldClient->objectKeys());
|
||||||
|
|
||||||
if (m_playerReloadCallback)
|
if (m_playerReloadCallback)
|
||||||
m_playerReloadCallback();
|
m_playerReloadCallback(resetInterfaces);
|
||||||
|
|
||||||
if (exception)
|
if (exception)
|
||||||
std::rethrow_exception(exception);
|
std::rethrow_exception(exception);
|
||||||
@ -527,7 +527,7 @@ bool UniverseClient::switchPlayer(Uuid const& uuid) {
|
|||||||
if (uuid == mainPlayer()->uuid())
|
if (uuid == mainPlayer()->uuid())
|
||||||
return false;
|
return false;
|
||||||
else if (auto data = m_playerStorage->maybeGetPlayerData(uuid))
|
else if (auto data = m_playerStorage->maybeGetPlayerData(uuid))
|
||||||
return reloadPlayer(*data, uuid);
|
return reloadPlayer(*data, uuid, true);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -546,11 +546,11 @@ bool UniverseClient::switchPlayer(String const& name) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniverseClient::Callback& UniverseClient::playerReloadPreCallback() {
|
UniverseClient::ReloadPlayerCallback& UniverseClient::playerReloadPreCallback() {
|
||||||
return m_playerReloadPreCallback;
|
return m_playerReloadPreCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniverseClient::Callback& UniverseClient::playerReloadCallback() {
|
UniverseClient::ReloadPlayerCallback& UniverseClient::playerReloadCallback() {
|
||||||
return m_playerReloadCallback;
|
return m_playerReloadCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,14 +91,15 @@ public:
|
|||||||
void startLua();
|
void startLua();
|
||||||
void stopLua();
|
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(Uuid const& uuid);
|
||||||
bool switchPlayer(size_t index);
|
bool switchPlayer(size_t index);
|
||||||
bool switchPlayer(String const& name);
|
bool switchPlayer(String const& name);
|
||||||
|
|
||||||
typedef std::function<void()> Callback;
|
typedef std::function<void()> Callback;
|
||||||
Callback& playerReloadPreCallback();
|
typedef std::function<void(bool)> ReloadPlayerCallback;
|
||||||
Callback& playerReloadCallback();
|
ReloadPlayerCallback& playerReloadPreCallback();
|
||||||
|
ReloadPlayerCallback& playerReloadCallback();
|
||||||
|
|
||||||
ClockConstPtr universeClock() const;
|
ClockConstPtr universeClock() const;
|
||||||
CelestialLogConstPtr celestialLog() const;
|
CelestialLogConstPtr celestialLog() const;
|
||||||
@ -161,8 +162,8 @@ private:
|
|||||||
typedef shared_ptr<ScriptComponent> ScriptComponentPtr;
|
typedef shared_ptr<ScriptComponent> ScriptComponentPtr;
|
||||||
StringMap<ScriptComponentPtr> m_scriptContexts;
|
StringMap<ScriptComponentPtr> m_scriptContexts;
|
||||||
|
|
||||||
Callback m_playerReloadPreCallback;
|
ReloadPlayerCallback m_playerReloadPreCallback;
|
||||||
Callback m_playerReloadCallback;
|
ReloadPlayerCallback m_playerReloadCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,23 @@ void PaneManager::setBackgroundWidget(WidgetPtr bg) {
|
|||||||
m_backgroundWidget = 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 {
|
PanePtr PaneManager::keyboardCapturedPane() const {
|
||||||
for (auto const& layerPair : m_displayedPanes) {
|
for (auto const& layerPair : m_displayedPanes) {
|
||||||
for (auto const& panePair : layerPair.second) {
|
for (auto const& panePair : layerPair.second) {
|
||||||
|
@ -63,6 +63,8 @@ public:
|
|||||||
|
|
||||||
void setBackgroundWidget(WidgetPtr bg);
|
void setBackgroundWidget(WidgetPtr bg);
|
||||||
|
|
||||||
|
void dismissWhere(function<bool(PanePtr const&)> func);
|
||||||
|
|
||||||
// Returns the pane that has captured the keyboard, if any.
|
// Returns the pane that has captured the keyboard, if any.
|
||||||
PanePtr keyboardCapturedPane() const;
|
PanePtr keyboardCapturedPane() const;
|
||||||
// Returns true if the current pane that has captured the keyboard is
|
// Returns true if the current pane that has captured the keyboard is
|
||||||
|
@ -219,6 +219,10 @@ void Widget::hide() {
|
|||||||
m_visible = false;
|
m_visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Widget::visibility() const {
|
||||||
|
return m_visible;
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::toggleVisibility() {
|
void Widget::toggleVisibility() {
|
||||||
m_visible = !m_visible;
|
m_visible = !m_visible;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
|
|
||||||
virtual void show();
|
virtual void show();
|
||||||
virtual void hide();
|
virtual void hide();
|
||||||
|
virtual bool visibility() const;
|
||||||
virtual void toggleVisibility();
|
virtual void toggleVisibility();
|
||||||
virtual void setVisibility(bool visibility);
|
virtual void setVisibility(bool visibility);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user