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

summaryrefslogtreecommitdiff
path: root/source/game
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2025-04-30 12:49:47 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2025-04-30 12:49:47 +1000
commitd3d4345e057d95d784e34be9b23e7fe07fb9a7c1 (patch)
treef59fa890e5be1d590e42a337448cecfc6b61850a /source/game
parent86e229012f84744a1e878124d9a6e2991c0460bb (diff)
parent885502bf11057e7de961f178bc85ce93a9f40723 (diff)
Merge branch 'main' into pr/218
Diffstat (limited to 'source/game')
-rw-r--r--source/game/CMakeLists.txt2
-rw-r--r--source/game/StarChatProcessor.cpp18
-rw-r--r--source/game/StarChatProcessor.hpp6
-rw-r--r--source/game/StarChatTypes.cpp10
-rw-r--r--source/game/StarChatTypes.hpp2
-rw-r--r--source/game/StarItemBag.cpp17
-rw-r--r--source/game/StarItemBag.hpp1
-rw-r--r--source/game/StarMonster.cpp2
-rw-r--r--source/game/StarNetPackets.cpp6
-rw-r--r--source/game/StarNetPackets.hpp2
-rw-r--r--source/game/StarNpc.cpp27
-rw-r--r--source/game/StarNpc.hpp3
-rw-r--r--source/game/StarPlayer.cpp5
-rw-r--r--source/game/StarPlayerStorage.cpp2
-rw-r--r--source/game/StarSkyParameters.cpp2
-rw-r--r--source/game/StarSongbook.cpp18
-rw-r--r--source/game/StarSongbook.hpp12
-rw-r--r--source/game/StarStagehand.cpp2
-rw-r--r--source/game/StarUniverseClient.cpp19
-rw-r--r--source/game/StarUniverseClient.hpp4
-rw-r--r--source/game/StarUniverseServer.cpp17
-rw-r--r--source/game/StarUniverseServer.hpp2
-rw-r--r--source/game/scripting/StarBehaviorLuaBindings.cpp2
-rw-r--r--source/game/scripting/StarBehaviorLuaBindings.hpp2
-rwxr-xr-x[-rw-r--r--]source/game/scripting/StarPlayerLuaBindings.cpp11
-rw-r--r--source/game/scripting/StarRootLuaBindings.cpp17
-rw-r--r--source/game/scripting/StarScriptableThread.cpp6
-rw-r--r--source/game/scripting/StarSongbookLuaBindings.cpp21
-rw-r--r--source/game/scripting/StarSongbookLuaBindings.hpp11
29 files changed, 188 insertions, 61 deletions
diff --git a/source/game/CMakeLists.txt b/source/game/CMakeLists.txt
index 11e0024..b1a519c 100644
--- a/source/game/CMakeLists.txt
+++ b/source/game/CMakeLists.txt
@@ -250,6 +250,7 @@ SET (star_game_HEADERS
scripting/StarPlayerLuaBindings.hpp
scripting/StarRootLuaBindings.hpp
scripting/StarScriptedAnimatorLuaBindings.hpp
+ scripting/StarSongbookLuaBindings.hpp
scripting/StarStatusControllerLuaBindings.hpp
scripting/StarTeamClientLuaBindings.hpp
scripting/StarWorldLuaBindings.hpp
@@ -491,6 +492,7 @@ SET (star_game_SOURCES
scripting/StarPlayerLuaBindings.cpp
scripting/StarRootLuaBindings.cpp
scripting/StarScriptedAnimatorLuaBindings.cpp
+ scripting/StarSongbookLuaBindings.cpp
scripting/StarStatusControllerLuaBindings.cpp
scripting/StarTeamClientLuaBindings.cpp
scripting/StarWorldLuaBindings.cpp
diff --git a/source/game/StarChatProcessor.cpp b/source/game/StarChatProcessor.cpp
index 2082529..0dd0c48 100644
--- a/source/game/StarChatProcessor.cpp
+++ b/source/game/StarChatProcessor.cpp
@@ -122,7 +122,7 @@ StringList ChatProcessor::activeChannels() const {
return channels;
}
-void ChatProcessor::broadcast(ConnectionId sourceConnectionId, String const& text) {
+void ChatProcessor::broadcast(ConnectionId sourceConnectionId, String const& text, JsonObject data) {
RecursiveMutexLocker locker(m_mutex);
ChatReceivedMessage message = {
@@ -132,6 +132,8 @@ void ChatProcessor::broadcast(ConnectionId sourceConnectionId, String const& tex
text
};
+ message.data = std::move(data);
+
if (handleCommand(message))
return;
@@ -139,7 +141,7 @@ void ChatProcessor::broadcast(ConnectionId sourceConnectionId, String const& tex
pair.second.pendingMessages.append(message);
}
-void ChatProcessor::message(ConnectionId sourceConnectionId, MessageContext::Mode mode, String const& channelName, String const& text) {
+void ChatProcessor::message(ConnectionId sourceConnectionId, MessageContext::Mode mode, String const& channelName, String const& text, JsonObject data) {
RecursiveMutexLocker locker(m_mutex);
ChatReceivedMessage message = {
@@ -149,6 +151,8 @@ void ChatProcessor::message(ConnectionId sourceConnectionId, MessageContext::Mod
text
};
+ message.data = std::move(data);
+
if (handleCommand(message))
return;
@@ -158,11 +162,17 @@ void ChatProcessor::message(ConnectionId sourceConnectionId, MessageContext::Mod
}
}
-void ChatProcessor::whisper(ConnectionId sourceConnectionId, ConnectionId targetClientId, String const& text) {
+void ChatProcessor::whisper(ConnectionId sourceConnectionId, ConnectionId targetClientId, String const& text, JsonObject data) {
RecursiveMutexLocker locker(m_mutex);
ChatReceivedMessage message = {
- {MessageContext::Whisper}, sourceConnectionId, connectionNick(sourceConnectionId), text};
+ {MessageContext::Whisper},
+ sourceConnectionId,
+ connectionNick(sourceConnectionId),
+ text
+ };
+
+ message.data = std::move(data);
if (handleCommand(message))
return;
diff --git a/source/game/StarChatProcessor.hpp b/source/game/StarChatProcessor.hpp
index 89bb5f5..1c42b75 100644
--- a/source/game/StarChatProcessor.hpp
+++ b/source/game/StarChatProcessor.hpp
@@ -41,9 +41,9 @@ public:
StringList clientChannels(ConnectionId clientId) const;
StringList activeChannels() const;
- void broadcast(ConnectionId sourceConnectionId, String const& text);
- void message(ConnectionId sourceConnectionId, MessageContext::Mode context, String const& channelName, String const& text);
- void whisper(ConnectionId sourceConnectionId, ConnectionId targetClientId, String const& text);
+ void broadcast(ConnectionId sourceConnectionId, String const& text, JsonObject data = {});
+ void message(ConnectionId sourceConnectionId, MessageContext::Mode context, String const& channelName, String const& text, JsonObject data = {});
+ void whisper(ConnectionId sourceConnectionId, ConnectionId targetClientId, String const& text, JsonObject data = {});
// Shorthand for passing ServerConnectionId as sourceConnectionId to
// broadcast / message / whisper
diff --git a/source/game/StarChatTypes.cpp b/source/game/StarChatTypes.cpp
index 79dfc4f..56fa6d9 100644
--- a/source/game/StarChatTypes.cpp
+++ b/source/game/StarChatTypes.cpp
@@ -56,6 +56,7 @@ ChatReceivedMessage::ChatReceivedMessage(Json const& json) : ChatReceivedMessage
fromNick = json.getString("fromNick", "");
portrait = json.getString("portrait", "");
text = json.getString("text", "");
+ data = json.getObject("data", JsonObject());
}
Json ChatReceivedMessage::toJson() const {
@@ -67,7 +68,8 @@ Json ChatReceivedMessage::toJson() const {
{"fromConnection", fromConnection},
{"fromNick", fromNick.empty() ? Json() : fromNick},
{"portrait", portrait.empty() ? Json() : portrait},
- {"text", text}
+ {"text", text},
+ {"data", data}
};
}
@@ -78,7 +80,8 @@ DataStream& operator>>(DataStream& ds, ChatReceivedMessage& receivedMessage) {
ds.read(receivedMessage.fromNick);
ds.read(receivedMessage.portrait);
ds.read(receivedMessage.text);
-
+ if (ds.streamCompatibilityVersion() >= 5)
+ ds.read(receivedMessage.data);
return ds;
}
@@ -88,7 +91,8 @@ DataStream& operator<<(DataStream& ds, ChatReceivedMessage const& receivedMessag
ds.write(receivedMessage.fromNick);
ds.write(receivedMessage.portrait);
ds.write(receivedMessage.text);
-
+ if (ds.streamCompatibilityVersion() >= 5)
+ ds.write(receivedMessage.data);
return ds;
}
diff --git a/source/game/StarChatTypes.hpp b/source/game/StarChatTypes.hpp
index 3feb413..3c23d7c 100644
--- a/source/game/StarChatTypes.hpp
+++ b/source/game/StarChatTypes.hpp
@@ -55,6 +55,8 @@ struct ChatReceivedMessage {
String portrait;
String text;
+
+ JsonObject data;
};
DataStream& operator>>(DataStream& ds, ChatReceivedMessage& receivedMessage);
diff --git a/source/game/StarItemBag.cpp b/source/game/StarItemBag.cpp
index 8abdd6f..1f8f74f 100644
--- a/source/game/StarItemBag.cpp
+++ b/source/game/StarItemBag.cpp
@@ -234,17 +234,22 @@ auto ItemBag::itemsFitWhere(ItemConstPtr const& items, uint64_t max) const -> It
return ItemsFitWhereResult();
List<size_t> slots;
+ StableHashSet<size_t> taken;
uint64_t count = std::min(items->count(), max);
while (true) {
if (count == 0)
break;
- size_t slot = bestSlotAvailable(items, false);
+ size_t slot = bestSlotAvailable(items, false, [&](size_t i) {
+ return !taken.contains(i);
+ });
if (slot == NPos)
break;
- else
+ else {
slots.append(slot);
+ taken.insert(slot);
+ }
uint64_t available = stackTransfer(at(slot), items);
if (available != 0)
@@ -350,9 +355,11 @@ uint64_t ItemBag::stackTransfer(ItemConstPtr const& to, ItemConstPtr const& from
return std::min(to->maxStack() - to->count(), from->count());
}
-size_t ItemBag::bestSlotAvailable(ItemConstPtr const& item, bool stacksOnly) const {
+size_t ItemBag::bestSlotAvailable(ItemConstPtr const& item, bool stacksOnly, std::function<bool(size_t)> test) const {
// First look for any slots that can stack, before empty slots.
for (size_t i = 0; i < m_items.size(); ++i) {
+ if (!test(i))
+ continue;
auto const& storedItem = at(i);
if (storedItem && stackTransfer(storedItem, item) != 0)
return i;
@@ -369,4 +376,8 @@ size_t ItemBag::bestSlotAvailable(ItemConstPtr const& item, bool stacksOnly) con
return NPos;
}
+size_t ItemBag::bestSlotAvailable(ItemConstPtr const& item, bool stacksOnly) const {
+ return bestSlotAvailable(item, stacksOnly, [](size_t) { return true; });
+}
+
}
diff --git a/source/game/StarItemBag.hpp b/source/game/StarItemBag.hpp
index 7b0246d..7480d7c 100644
--- a/source/game/StarItemBag.hpp
+++ b/source/game/StarItemBag.hpp
@@ -109,6 +109,7 @@ private:
// Returns the slot that contains the item already and has the *highest*
// stack count but not full, or an empty slot, or NPos for no room.
+ size_t bestSlotAvailable(ItemConstPtr const& item, bool stacksOnly, std::function<bool(size_t)> test) const;
size_t bestSlotAvailable(ItemConstPtr const& item, bool stacksOnly) const;
List<ItemPtr> m_items;
diff --git a/source/game/StarMonster.cpp b/source/game/StarMonster.cpp
index d9ce986..98f4642 100644
--- a/source/game/StarMonster.cpp
+++ b/source/game/StarMonster.cpp
@@ -144,7 +144,7 @@ void Monster::init(World* world, EntityId entityId, EntityMode mode) {
m_scriptComponent.addCallbacks("entity", LuaBindings::makeEntityCallbacks(this));
m_scriptComponent.addCallbacks("animator", LuaBindings::makeNetworkedAnimatorCallbacks(&m_networkedAnimator));
m_scriptComponent.addCallbacks("status", LuaBindings::makeStatusControllerCallbacks(m_statusController.get()));
- m_scriptComponent.addCallbacks("behavior", LuaBindings::makeBehaviorLuaCallbacks(&m_behaviors));
+ m_scriptComponent.addCallbacks("behavior", LuaBindings::makeBehaviorCallbacks(&m_behaviors));
m_scriptComponent.addActorMovementCallbacks(m_movementController.get());
m_scriptComponent.init(world);
}
diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp
index 4b16ce8..a121beb 100644
--- a/source/game/StarNetPackets.cpp
+++ b/source/game/StarNetPackets.cpp
@@ -495,14 +495,20 @@ ChatSendPacket::ChatSendPacket() : sendMode(ChatSendMode::Broadcast) {}
ChatSendPacket::ChatSendPacket(String text, ChatSendMode sendMode) : text(std::move(text)), sendMode(sendMode) {}
+ChatSendPacket::ChatSendPacket(String text, ChatSendMode sendMode, JsonObject data) : text(std::move(text)), sendMode(sendMode), data(std::move(data)) {}
+
void ChatSendPacket::read(DataStream& ds) {
ds.read(text);
ds.read(sendMode);
+ if (ds.streamCompatibilityVersion() >= 5)
+ ds.read(data);
}
void ChatSendPacket::write(DataStream& ds) const {
ds.write(text);
ds.write(sendMode);
+ if (ds.streamCompatibilityVersion() >= 5)
+ ds.write(data);
}
CelestialRequestPacket::CelestialRequestPacket() {}
diff --git a/source/game/StarNetPackets.hpp b/source/game/StarNetPackets.hpp
index 8db5c03..63a7ee8 100644
--- a/source/game/StarNetPackets.hpp
+++ b/source/game/StarNetPackets.hpp
@@ -371,12 +371,14 @@ struct FlyShipPacket : PacketBase<PacketType::FlyShip> {
struct ChatSendPacket : PacketBase<PacketType::ChatSend> {
ChatSendPacket();
ChatSendPacket(String text, ChatSendMode sendMode);
+ ChatSendPacket(String text, ChatSendMode sendMode, JsonObject data);
void read(DataStream& ds) override;
void write(DataStream& ds) const override;
String text;
ChatSendMode sendMode;
+ JsonObject data;
};
struct CelestialRequestPacket : PacketBase<PacketType::CelestialRequest> {
diff --git a/source/game/StarNpc.cpp b/source/game/StarNpc.cpp
index 388f6e5..7c1cf63 100644
--- a/source/game/StarNpc.cpp
+++ b/source/game/StarNpc.cpp
@@ -2,6 +2,8 @@
#include "StarDataStreamExtra.hpp"
#include "StarWorld.hpp"
#include "StarRoot.hpp"
+#include "StarSongbook.hpp"
+#include "StarSongbookLuaBindings.hpp"
#include "StarDamageManager.hpp"
#include "StarDamageDatabase.hpp"
#include "StarLogging.hpp"
@@ -76,6 +78,8 @@ Npc::Npc(NpcVariant const& npcVariant)
if (!m_statusController->statusProperty("effectDirectives"))
m_statusController->setStatusProperty("effectDirectives", speciesDefinition->effectDirectives());
+ m_songbook = make_shared<Songbook>(species());
+
m_effectEmitter = make_shared<EffectEmitter>();
m_hitDamageNotificationLimiter = 0;
@@ -185,7 +189,8 @@ void Npc::init(World* world, EntityId entityId, EntityMode mode) {
{ return m_npcVariant.scriptConfig.query(name, def); }));
m_scriptComponent.addCallbacks("entity", LuaBindings::makeEntityCallbacks(this));
m_scriptComponent.addCallbacks("status", LuaBindings::makeStatusControllerCallbacks(m_statusController.get()));
- m_scriptComponent.addCallbacks("behavior", LuaBindings::makeBehaviorLuaCallbacks(&m_behaviors));
+ m_scriptComponent.addCallbacks("behavior", LuaBindings::makeBehaviorCallbacks(&m_behaviors));
+ m_scriptComponent.addCallbacks("songbook", LuaBindings::makeSongbookCallbacks(m_songbook.get()));
m_scriptComponent.addActorMovementCallbacks(m_movementController.get());
m_scriptComponent.init(world);
}
@@ -199,6 +204,8 @@ void Npc::uninit() {
m_scriptComponent.removeCallbacks("config");
m_scriptComponent.removeCallbacks("entity");
m_scriptComponent.removeCallbacks("status");
+ m_scriptComponent.removeCallbacks("behavior");
+ m_scriptComponent.removeCallbacks("songbook");
m_scriptComponent.removeActorMovementCallbacks();
}
m_tools->uninit();
@@ -359,6 +366,8 @@ void Npc::destroy(RenderCallback* renderCallback) {
if (renderCallback && m_deathParticleBurst.get())
renderCallback->addParticles(m_humanoid.particles(*m_deathParticleBurst.get()), position());
+
+ m_songbook->stop();
}
void Npc::damagedOther(DamageNotification const& damage) {
@@ -503,6 +512,7 @@ void Npc::render(RenderCallback* renderCallback) {
renderCallback->addDrawables(m_tools->renderObjectPreviews(aimPosition(), walkingDirection(), inToolRange(), favoriteColor()), renderLayer);
m_effectEmitter->render(renderCallback);
+ m_songbook->render(renderCallback);
}
void Npc::renderLightSources(RenderCallback* renderCallback) {
@@ -571,6 +581,8 @@ void Npc::tickShared(float dt) {
if (m_hitDamageNotificationLimiter)
m_hitDamageNotificationLimiter--;
+ m_songbook->update(*entityMode(), world());
+
m_effectEmitter->setSourcePosition("normal", position());
m_effectEmitter->setSourcePosition("mouth", position() + mouthOffset());
m_effectEmitter->setSourcePosition("feet", position() + feetOffset());
@@ -814,6 +826,8 @@ void Npc::setupNetStates() {
m_netGroup.addNetElement(m_statusController.get());
m_netGroup.addNetElement(m_armor.get());
m_netGroup.addNetElement(m_tools.get());
+ m_songbook->setCompatibilityVersion(6);
+ m_netGroup.addNetElement(m_songbook.get());
m_netGroup.setNeedsStoreCallback(bind(&Npc::setNetStates, this));
m_netGroup.setNeedsLoadCallback(bind(&Npc::getNetStates, this, _1));
@@ -1075,10 +1089,13 @@ bool Npc::consumeEnergy(float energy) {
void Npc::queueUIMessage(String const&) {}
bool Npc::instrumentPlaying() {
- return false; // TODO: remove this from tool user entirely
+ return m_songbook->instrumentPlaying();
}
-void Npc::instrumentEquipped(String const&) {}
+void Npc::instrumentEquipped(String const& instrumentKind) {
+ if (canUseTool())
+ m_songbook->keepAlive(instrumentKind, mouthPosition());
+}
void Npc::interact(InteractAction const&) {}
@@ -1102,6 +1119,10 @@ StatusController* Npc::statusController() {
return m_statusController.get();
}
+Songbook* Npc::songbook() {
+ return m_songbook.get();
+}
+
void Npc::setCameraFocusEntity(Maybe<EntityId> const&) {
// players only
}
diff --git a/source/game/StarNpc.hpp b/source/game/StarNpc.hpp
index 0b22702..21c562c 100644
--- a/source/game/StarNpc.hpp
+++ b/source/game/StarNpc.hpp
@@ -25,6 +25,7 @@
namespace Star {
+STAR_CLASS(Songbook);
STAR_CLASS(Item);
STAR_CLASS(RenderCallback);
STAR_CLASS(Npc);
@@ -165,6 +166,7 @@ public:
void requestEmote(String const& emote) override;
ActorMovementController* movementController() override;
StatusController* statusController() override;
+ Songbook* songbook();
void setCameraFocusEntity(Maybe<EntityId> const& cameraFocusEntity) override;
void playEmote(HumanoidEmote emote) override;
@@ -246,6 +248,7 @@ private:
ArmorWearerPtr m_armor;
ToolUserPtr m_tools;
+ SongbookPtr m_songbook;
NetElementBool m_disableWornArmor;
diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp
index 43add67..facde2e 100644
--- a/source/game/StarPlayer.cpp
+++ b/source/game/StarPlayer.cpp
@@ -3,6 +3,7 @@
#include "StarJsonExtra.hpp"
#include "StarRoot.hpp"
#include "StarSongbook.hpp"
+#include "StarSongbookLuaBindings.hpp"
#include "StarEmoteProcessor.hpp"
#include "StarSpeciesDatabase.hpp"
#include "StarDamageManager.hpp"
@@ -331,6 +332,7 @@ void Player::init(World* world, EntityId entityId, EntityMode mode) {
p.second->addActorMovementCallbacks(m_movementController.get());
p.second->addCallbacks("player", LuaBindings::makePlayerCallbacks(this));
p.second->addCallbacks("status", LuaBindings::makeStatusControllerCallbacks(m_statusController.get()));
+ p.second->addCallbacks("songbook", LuaBindings::makeSongbookCallbacks(m_songbook.get()));
if (m_client)
p.second->addCallbacks("celestial", LuaBindings::makeCelestialCallbacks(m_client));
p.second->init(world);
@@ -362,6 +364,7 @@ void Player::uninit() {
p.second->removeCallbacks("player");
p.second->removeCallbacks("mcontroller");
p.second->removeCallbacks("status");
+ p.second->removeCallbacks("songbook");
p.second->removeCallbacks("world");
if (m_client)
p.second->removeCallbacks("celestial");
@@ -2272,7 +2275,7 @@ bool Player::instrumentPlaying() {
void Player::instrumentEquipped(String const& instrumentKind) {
if (canUseTool())
- m_songbook->keepalive(instrumentKind, mouthPosition());
+ m_songbook->keepAlive(instrumentKind, mouthPosition());
}
void Player::interact(InteractAction const& action) {
diff --git a/source/game/StarPlayerStorage.cpp b/source/game/StarPlayerStorage.cpp
index 7687e97..6be4460 100644
--- a/source/game/StarPlayerStorage.cpp
+++ b/source/game/StarPlayerStorage.cpp
@@ -173,7 +173,7 @@ Json PlayerStorage::savePlayer(PlayerPtr const& player) {
VersionedJson versionedJson = entityFactory->storeVersionedJson(EntityType::Player, playerCacheData);
auto fileName = strf("{}.player", uuidFileName(uuid));
VersionedJson::writeFile(versionedJson, File::relativeTo(m_storageDirectory, fileName));
- Logger::info("Saved player {} to {}", Text::stripEscapeCodes(player->name()), fileName);
+ Logger::debug("Saved player {} to {}", Text::stripEscapeCodes(player->name()), fileName);
}
return newPlayerData;
}
diff --git a/source/game/StarSkyParameters.cpp b/source/game/StarSkyParameters.cpp
index e2ed885..3d540b8 100644
--- a/source/game/StarSkyParameters.cpp
+++ b/source/game/StarSkyParameters.cpp
@@ -175,6 +175,8 @@ void SkyParameters::read(DataStream& ds) {
ds >> sunType;
if (ds.streamCompatibilityVersion() >= 3)
ds >> settings;
+ else
+ settings = JsonObject();
}
void SkyParameters::write(DataStream& ds) const {
diff --git a/source/game/StarSongbook.cpp b/source/game/StarSongbook.cpp
index 68db655..72f2b2b 100644
--- a/source/game/StarSongbook.cpp
+++ b/source/game/StarSongbook.cpp
@@ -158,7 +158,7 @@ void Songbook::render(RenderCallback* renderCallback) {
m_pendingAudio.clear();
}
-void Songbook::keepalive(String const& instrument, Vec2F const& position) {
+void Songbook::keepAlive(String const& instrument, Vec2F const& position) {
if (instrument != m_instrument) {
m_instrument = instrument;
m_dataUpdated = true;
@@ -681,11 +681,11 @@ void Songbook::play(Json const& song, String const& timeSource) {
m_activeCooldown = 3;
}
-bool Songbook::active() {
+bool Songbook::active() const {
return m_activeCooldown > 0;
}
-bool Songbook::instrumentPlaying() {
+bool Songbook::instrumentPlaying() const {
if (!active())
return false;
if (m_timeSourceInstance) {
@@ -698,6 +698,18 @@ bool Songbook::instrumentPlaying() {
return false;
}
+Maybe<String> Songbook::timeSource() const {
+ return m_timeSource;
+}
+
+Maybe<String> Songbook::instrument() const {
+ return m_instrument;
+}
+
+Json Songbook::song() const {
+ return m_song;
+}
+
double Songbook::fundamentalFrequency(double p) {
return 55.0 * pow(2.0, (p - 69.0) / 12.0 + 3.0);
}
diff --git a/source/game/StarSongbook.hpp b/source/game/StarSongbook.hpp
index 89a4bfd..6f15242 100644
--- a/source/game/StarSongbook.hpp
+++ b/source/game/StarSongbook.hpp
@@ -24,12 +24,16 @@ public:
// instrument needs to tell the songbook what type it is, and needs to keep
// calling it to signal
// the instrument is still equiped
- void keepalive(String const& instrument, Vec2F const& position);
+ void keepAlive(String const& instrument, Vec2F const& position);
void stop();
- void play(Json const& song, String const& timesource);
- bool active();
- bool instrumentPlaying();
+ void play(Json const& song, String const& timeSource);
+ bool active() const;
+ bool instrumentPlaying() const;
+
+ Maybe<String> timeSource() const;
+ Maybe<String> instrument() const;
+ Json song() const;
private:
struct Note {
diff --git a/source/game/StarStagehand.cpp b/source/game/StarStagehand.cpp
index d85f77b..1207d91 100644
--- a/source/game/StarStagehand.cpp
+++ b/source/game/StarStagehand.cpp
@@ -43,7 +43,7 @@ void Stagehand::init(World* world, EntityId entityId, EntityMode mode) {
return m_config.query(name, def);
}));
m_scriptComponent.addCallbacks("entity", LuaBindings::makeEntityCallbacks(this));
- m_scriptComponent.addCallbacks("behavior", LuaBindings::makeBehaviorLuaCallbacks(&m_behaviors));
+ m_scriptComponent.addCallbacks("behavior", LuaBindings::makeBehaviorCallbacks(&m_behaviors));
m_scriptComponent.init(world);
}
}
diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp
index af33508..b41d19e 100644
--- a/source/game/StarUniverseClient.cpp
+++ b/source/game/StarUniverseClient.cpp
@@ -71,7 +71,7 @@ PlayerPtr UniverseClient::mainPlayer() const {
return m_mainPlayer;
}
-Maybe<String> UniverseClient::connect(UniverseConnection connection, bool allowAssetsMismatch, String const& account, String const& password) {
+Maybe<String> UniverseClient::connect(UniverseConnection connection, bool allowAssetsMismatch, String const& account, String const& password, bool const& forceLegacy) {
auto& root = Root::singleton();
auto assets = root.assets();
@@ -85,9 +85,11 @@ Maybe<String> UniverseClient::connect(UniverseConnection connection, bool allowA
{
auto protocolRequest = make_shared<ProtocolRequestPacket>(StarProtocolVersion);
- protocolRequest->setCompressionMode(PacketCompressionMode::Enabled);
- // Signal that we're OpenStarbound. Vanilla Starbound only compresses
- // packets above 64 bytes - by forcing it, we can communicate this.
+ if (!forceLegacy) {
+ protocolRequest->setCompressionMode(PacketCompressionMode::Enabled);
+ // Signal that we're OpenStarbound. Vanilla Starbound only compresses
+ // packets above 64 bytes - by forcing it, we can communicate this.
+ }
connection.pushSingle(protocolRequest);
}
connection.sendAll(timeout);
@@ -101,7 +103,7 @@ Maybe<String> UniverseClient::connect(UniverseConnection connection, bool allowA
NetCompatibilityRules compatibilityRules;
compatibilityRules.setVersion(LegacyVersion);
- bool legacyServer = protocolResponsePacket->compressionMode() != PacketCompressionMode::Enabled;
+ bool legacyServer = forceLegacy || (protocolResponsePacket->compressionMode() != PacketCompressionMode::Enabled);
if (!legacyServer) {
auto compressedSocket = as<CompressedPacketSocket>(&connection.packetSocket());
if (protocolResponsePacket->info) {
@@ -484,10 +486,13 @@ bool UniverseClient::flying() const {
return false;
}
-void UniverseClient::sendChat(String const& text, ChatSendMode sendMode, Maybe<bool> speak) {
+void UniverseClient::sendChat(String const& text, ChatSendMode sendMode, Maybe<bool> speak, Maybe<JsonObject> data) {
if (speak.value(!text.beginsWith("/")))
m_mainPlayer->addChatMessage(text);
- m_connection->pushSingle(make_shared<ChatSendPacket>(text, sendMode));
+ auto packet = make_shared<ChatSendPacket>(text, sendMode);
+ if (data)
+ packet->data = std::move(*data);
+ m_connection->pushSingle(packet);
}
List<ChatReceivedMessage> UniverseClient::pullChatMessages() {
diff --git a/source/game/StarUniverseClient.hpp b/source/game/StarUniverseClient.hpp
index b770b07..b1c589f 100644
--- a/source/game/StarUniverseClient.hpp
+++ b/source/game/StarUniverseClient.hpp
@@ -41,7 +41,7 @@ public:
PlayerPtr mainPlayer() const;
// Returns error if connection failed
- Maybe<String> connect(UniverseConnection connection, bool allowAssetsMismatch, String const& account = "", String const& password = "");
+ Maybe<String> connect(UniverseConnection connection, bool allowAssetsMismatch, String const& account = "", String const& password = "", bool const& forceLegacy = false);
bool isConnected() const;
void disconnect();
Maybe<String> disconnectReason() const;
@@ -80,7 +80,7 @@ public:
SkyConstPtr currentSky() const;
bool flying() const;
- void sendChat(String const& text, ChatSendMode sendMode, Maybe<bool> speak = {});
+ void sendChat(String const& text, ChatSendMode sendMode, Maybe<bool> speak = {}, Maybe<JsonObject> data = {});
List<ChatReceivedMessage> pullChatMessages();
uint16_t players();
diff --git a/source/game/StarUniverseServer.cpp b/source/game/StarUniverseServer.cpp
index f32f650..977dc71 100644
--- a/source/game/StarUniverseServer.cpp
+++ b/source/game/StarUniverseServer.cpp
@@ -1064,16 +1064,19 @@ void UniverseServer::processChat() {
for (auto const& p : take(m_pendingChat)) {
if (auto clientContext = m_clients.get(p.first)) {
for (auto const& chat : p.second) {
+ auto& message = get<0>(chat);
+ auto sendMode = get<1>(chat);
+ auto& data = get<2>(chat);
if (clientContext->remoteAddress())
- Logger::info("Chat: <{}> {}", clientContext->playerName(), chat.first);
+ Logger::info("Chat: <{}> {}", clientContext->playerName(), message);
auto team = m_teamManager->getTeam(clientContext->playerUuid());
- if (chat.second == ChatSendMode::Broadcast)
- m_chatProcessor->broadcast(p.first, chat.first);
- else if (chat.second == ChatSendMode::Party && team.isValid())
- m_chatProcessor->message(p.first, MessageContext::Mode::Party, team.value().hex(), chat.first);
+ if (sendMode == ChatSendMode::Broadcast)
+ m_chatProcessor->broadcast(p.first, message, std::move(data));
+ else if (sendMode == ChatSendMode::Party && team.isValid())
+ m_chatProcessor->message(p.first, MessageContext::Mode::Party, team.value().hex(), message, std::move(data));
else
- m_chatProcessor->message(p.first, MessageContext::Mode::Local, printWorldId(clientContext->playerWorldId()), chat.first);
+ m_chatProcessor->message(p.first, MessageContext::Mode::Local, printWorldId(clientContext->playerWorldId()), message, std::move(data));
}
}
}
@@ -1527,7 +1530,7 @@ void UniverseServer::packetsReceived(UniverseConnectionServer*, ConnectionId cli
} else if (auto chatSend = as<ChatSendPacket>(packet)) {
RecursiveMutexLocker locker(m_mainLock);
- m_pendingChat[clientId].append({std::move(chatSend->text), chatSend->sendMode});
+ m_pendingChat[clientId].append(make_tuple(std::move(chatSend->text), chatSend->sendMode, std::move(chatSend->data)));
} else if (auto clientContextUpdatePacket = as<ClientContextUpdatePacket>(packet)) {
clientContext->readUpdate(std::move(clientContextUpdatePacket->updateData));
diff --git a/source/game/StarUniverseServer.hpp b/source/game/StarUniverseServer.hpp
index f3db6fc..ddf7d0c 100644
--- a/source/game/StarUniverseServer.hpp
+++ b/source/game/StarUniverseServer.hpp
@@ -254,7 +254,7 @@ private:
HashMap<ConnectionId, String> m_pendingDisconnections;
HashMap<ConnectionId, List<WorkerPoolPromise<CelestialResponse>>> m_pendingCelestialRequests;
List<pair<WorldId, UniverseFlagAction>> m_pendingFlagActions;
- HashMap<ConnectionId, List<pair<String, ChatSendMode>>> m_pendingChat;
+ HashMap<ConnectionId, List<tuple<String, ChatSendMode, JsonObject>>> m_pendingChat;
Maybe<WorkerPoolPromise<CelestialCoordinate>> m_nextRandomizedStarterWorld;
Map<WorldId, List<WorldServerThread::Message>> m_pendingWorldMessages;
diff --git a/source/game/scripting/StarBehaviorLuaBindings.cpp b/source/game/scripting/StarBehaviorLuaBindings.cpp
index 8866746..4bf16f2 100644
--- a/source/game/scripting/StarBehaviorLuaBindings.cpp
+++ b/source/game/scripting/StarBehaviorLuaBindings.cpp
@@ -4,7 +4,7 @@
namespace Star {
-LuaCallbacks LuaBindings::makeBehaviorLuaCallbacks(List<BehaviorStatePtr>* list) {
+LuaCallbacks LuaBindings::makeBehaviorCallbacks(List<BehaviorStatePtr>* list) {
LuaCallbacks callbacks;
callbacks.registerCallback("behavior", [list](Json const& config, JsonObject const& parameters, LuaTable context, Maybe<LuaUserData> blackboard) -> BehaviorStateWeakPtr {
diff --git a/source/game/scripting/StarBehaviorLuaBindings.hpp b/source/game/scripting/StarBehaviorLuaBindings.hpp
index d2a882b..01c04ab 100644
--- a/source/game/scripting/StarBehaviorLuaBindings.hpp
+++ b/source/game/scripting/StarBehaviorLuaBindings.hpp
@@ -9,6 +9,6 @@ STAR_CLASS(Root);
STAR_CLASS(UniverseClient);
namespace LuaBindings {
- LuaCallbacks makeBehaviorLuaCallbacks(List<BehaviorStatePtr>* list);
+ LuaCallbacks makeBehaviorCallbacks(List<BehaviorStatePtr>* list);
}
}
diff --git a/source/game/scripting/StarPlayerLuaBindings.cpp b/source/game/scripting/StarPlayerLuaBindings.cpp
index 5af86d0..ea2bae5 100644..100755
--- a/source/game/scripting/StarPlayerLuaBindings.cpp
+++ b/source/game/scripting/StarPlayerLuaBindings.cpp
@@ -496,6 +496,10 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) {
return QuestStateNames.getRight(player->questManager()->getQuest(questId)->state());
});
+ callbacks.registerCallback("questObjectives", [player](String const& questId) -> Maybe<JsonArray> {
+ return player->questManager()->getQuest(questId)->objectiveList();
+ });
+
callbacks.registerCallback("callQuest", [player](String const& questId, String const& func, LuaVariadic<LuaValue> const& args) -> Maybe<LuaValue> {
if (!player->questManager()->hasQuest(questId))
return {};
@@ -522,8 +526,11 @@ LuaCallbacks LuaBindings::makePlayerCallbacks(Player* player) {
return player->questManager()->trackedQuestId();
});
- callbacks.registerCallback("setTrackedQuest", [player](Maybe<String> const& questId) {
- return player->questManager()->setAsTracked(questId);
+ callbacks.registerCallback("setTrackedQuest", [player](String const& questId) {
+ if (!player->questManager()->isCurrent(questId))
+ return player->questManager()->setAsTracked(questId);
+ else
+ return player->questManager()->setAsTracked({});
});
callbacks.registerCallback("canTurnInQuest", [player](String const& questId) {
diff --git a/source/game/scripting/StarRootLuaBindings.cpp b/source/game/scripting/StarRootLuaBindings.cpp
index c45ef46..4e60595 100644
--- a/source/game/scripting/StarRootLuaBindings.cpp
+++ b/source/game/scripting/StarRootLuaBindings.cpp
@@ -66,13 +66,12 @@ LuaCallbacks LuaBindings::makeRootCallbacks() {
callbacks.registerCallbackWithSignature<Maybe<String>, String, Maybe<String>>("materialMiningSound", bind(RootCallbacks::materialMiningSound, root, _1, _2));
callbacks.registerCallbackWithSignature<Maybe<String>, String, Maybe<String>>("materialFootstepSound", bind(RootCallbacks::materialFootstepSound, root, _1, _2));
- callbacks.registerCallback("assetsByExtension", [root](LuaEngine& engine, String const& extension) -> LuaTable {
- auto& extensions = root->assets()->scanExtension(extension);
- auto table = engine.createTable(extensions.size(), 0);
- size_t i = 0;
- for (auto& file : extensions)
- table.set(++i, file);
- return table;
+ callbacks.registerCallback("assetsByExtension", [root](String const& extension) -> CaseInsensitiveStringSet {
+ return root->assets()->scanExtension(extension);
+ });
+
+ callbacks.registerCallback("assetsScan", [root]( Maybe<String> const& a, Maybe<String> const& b) -> StringList {
+ return b ? root->assets()->scan(a.value(), *b) : root->assets()->scan(a.value());
});
callbacks.registerCallback("assetOrigin", [root](String const& path) -> Maybe<String> {
@@ -116,12 +115,12 @@ LuaCallbacks LuaBindings::makeRootCallbacks() {
return table;
});
- callbacks.registerCallback("assetSourceMetadata", [root](LuaEngine& engine, String const& assetSourcePath) {
+ callbacks.registerCallback("assetSourceMetadata", [root](String const& assetSourcePath) {
auto assets = root->assets();
return assets->assetSourceMetadata(assetSourcePath);
});
- callbacks.registerCallback("itemFile", [root](LuaEngine& engine, String const& itemName) -> Maybe<String> {
+ callbacks.registerCallback("itemFile", [root](String const& itemName) -> Maybe<String> {
return root->itemDatabase()->itemFile(itemName);
});
diff --git a/source/game/scripting/StarScriptableThread.cpp b/source/game/scripting/StarScriptableThread.cpp
index cbd32ad..6bbfece 100644
--- a/source/game/scripting/StarScriptableThread.cpp
+++ b/source/game/scripting/StarScriptableThread.cpp
@@ -14,9 +14,9 @@ namespace Star {
ScriptableThread::ScriptableThread(Json parameters)
: Thread("ScriptableThread: " + parameters.getString("name")), // TODO
m_stop(false),
+ m_parameters(std::move(parameters)),
m_errorOccurred(false),
- m_shouldExpire(true),
- m_parameters(std::move(parameters)) {
+ m_shouldExpire(true) {
m_luaRoot = make_shared<LuaRoot>();
m_name = m_parameters.getString("name");
@@ -78,8 +78,6 @@ void ScriptableThread::passMessage(Message&& message) {
void ScriptableThread::run() {
try {
- auto& root = Root::singleton();
-
double updateMeasureWindow = m_parameters.getDouble("updateMeasureWindow",0.5);
TickRateApproacher tickApproacher(1.0f / m_timestep, updateMeasureWindow);
diff --git a/source/game/scripting/StarSongbookLuaBindings.cpp b/source/game/scripting/StarSongbookLuaBindings.cpp
new file mode 100644
index 0000000..7831ed6
--- /dev/null
+++ b/source/game/scripting/StarSongbookLuaBindings.cpp
@@ -0,0 +1,21 @@
+#include "StarSongbookLuaBindings.hpp"
+#include "StarLuaConverters.hpp"
+
+namespace Star {
+
+LuaCallbacks LuaBindings::makeSongbookCallbacks(Songbook* songbook) {
+ LuaCallbacks callbacks;
+
+ callbacks.registerCallbackWithSignature<void, Json, String>("play", bind(mem_fn(&Songbook::play), songbook, _1, _2));
+ callbacks.registerCallbackWithSignature<void, String, Vec2F>("keepAlive", bind(mem_fn(&Songbook::keepAlive), songbook, _1, _2));
+ callbacks.registerCallbackWithSignature<void>("stop", bind(mem_fn(&Songbook::stop), songbook));
+ callbacks.registerCallbackWithSignature<bool>("active", bind(mem_fn(&Songbook::active), songbook));
+ callbacks.registerCallbackWithSignature<Maybe<String>>("band", bind(mem_fn(&Songbook::timeSource), songbook));
+ callbacks.registerCallbackWithSignature<Maybe<String>>("instrument", bind(mem_fn(&Songbook::instrument), songbook));
+ callbacks.registerCallbackWithSignature<bool>("instrumentPlaying", bind(mem_fn(&Songbook::instrumentPlaying), songbook));
+ callbacks.registerCallbackWithSignature<Json>("song", bind(mem_fn(&Songbook::song), songbook));
+
+ return callbacks;
+}
+
+}
diff --git a/source/game/scripting/StarSongbookLuaBindings.hpp b/source/game/scripting/StarSongbookLuaBindings.hpp
new file mode 100644
index 0000000..cc55ec6
--- /dev/null
+++ b/source/game/scripting/StarSongbookLuaBindings.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "StarLua.hpp"
+#include "StarSongbook.hpp"
+
+namespace Star {
+
+namespace LuaBindings {
+ LuaCallbacks makeSongbookCallbacks(Songbook* songbook);
+}
+}