diff options
-rw-r--r-- | assets/opensb/objects/opensb/object.patch.lua | 19 | ||||
-rw-r--r-- | assets/opensb/scripts/opensb/assets/postload.lua | 9 | ||||
-rw-r--r-- | assets/opensb/tiles/shadows.png | bin | 0 -> 412 bytes | |||
-rw-r--r-- | source/base/StarAssets.cpp | 107 | ||||
-rw-r--r-- | source/base/StarAssets.hpp | 8 | ||||
-rw-r--r-- | source/base/StarCellularLighting.hpp | 12 | ||||
-rw-r--r-- | source/game/StarWorldClient.cpp | 9 |
7 files changed, 116 insertions, 48 deletions
diff --git a/assets/opensb/objects/opensb/object.patch.lua b/assets/opensb/objects/opensb/object.patch.lua new file mode 100644 index 0000000..d2a37a9 --- /dev/null +++ b/assets/opensb/objects/opensb/object.patch.lua @@ -0,0 +1,19 @@ +local function modLight(light) + for i = 1, #light do + light[i] = light[i] * 0.4 + end +end + +function patch(object, path) + if object.lightColor then + modLight(object.lightColor) + object.pointLight = true + return object; + elseif object.lightColors then + for i, v in pairs(object.lightColors) do + modLight(v) + end + object.pointLight = true + return object; + end +end
\ No newline at end of file diff --git a/assets/opensb/scripts/opensb/assets/postload.lua b/assets/opensb/scripts/opensb/assets/postload.lua index 8f84352..d84dd75 100644 --- a/assets/opensb/scripts/opensb/assets/postload.lua +++ b/assets/opensb/scripts/opensb/assets/postload.lua @@ -1,4 +1,4 @@ --- revert cursor frames if a mod replaced cursors.png with a SD version again +-- Revert cursor frames if a mod replaced cursors.png with a SD version again if assets.image("/cursors/cursors.png"):size()[1] == 64 then local path = "/cursors/opensb/revert.cursor.patch" assets.add(path, '{"scale":null}') @@ -8,4 +8,11 @@ if assets.image("/cursors/cursors.png"):size()[1] == 64 then path = "/cursors/opensb/revert.frames.patch" assets.add(path, '{"frameGrid":{"size":[16,16]}}') assets.patch("/cursors/cursors.frames", path) +end + +-- Add object patches +local objects = assets.byExtension("object") +local path = "/objects/opensb/object.patch.lua" +for i = 1, #objects do + assets.patch(objects[i], path) end
\ No newline at end of file diff --git a/assets/opensb/tiles/shadows.png b/assets/opensb/tiles/shadows.png Binary files differnew file mode 100644 index 0000000..fc34769 --- /dev/null +++ b/assets/opensb/tiles/shadows.png diff --git a/source/base/StarAssets.cpp b/source/base/StarAssets.cpp index 6593d3d..2bbe509 100644 --- a/source/base/StarAssets.cpp +++ b/source/base/StarAssets.cpp @@ -110,8 +110,15 @@ Assets::Assets(Settings settings, StringList assetSources) { m_assetSources = std::move(assetSources); auto luaEngine = LuaEngine::create(); + m_luaEngine = luaEngine; + auto pushGlobalContext = [&luaEngine](String const& name, LuaCallbacks & callbacks) { + auto table = luaEngine->createTable(); + for (auto const& p : callbacks.callbacks()) + table.set(p.first, luaEngine->createWrappedFunction(p.second)); + luaEngine->setGlobal(name, table); + }; + pushGlobalContext("sb", LuaBindings::makeUtilityCallbacks()); auto decorateLuaContext = [this](LuaContext& context, MemoryAssetSourcePtr newFiles) { - context.setCallbacks("sb", LuaBindings::makeUtilityCallbacks()); LuaCallbacks callbacks; callbacks.registerCallbackWithSignature<StringSet, String>("byExtension", bind(&Assets::scanExtension, this, _1)); callbacks.registerCallbackWithSignature<Json, String>("json", bind(&Assets::json, this, _1)); @@ -133,38 +140,40 @@ Assets::Assets(Settings settings, StringList assetSources) { return b ? scan(a.value(), *b) : scan(a.value()); }); - callbacks.registerCallback("add", [this, &newFiles](LuaEngine& engine, String const& path, LuaValue const& data) { - ByteArray bytes; - if (auto str = engine.luaMaybeTo<String>(data)) - bytes = ByteArray(str->utf8Ptr(), str->utf8Size()); - else { - auto json = engine.luaTo<Json>(data).repr(); - bytes = ByteArray(json.utf8Ptr(), json.utf8Size()); - } - newFiles->set(path, bytes); - }); + if (newFiles) { + callbacks.registerCallback("add", [this, &newFiles](LuaEngine& engine, String const& path, LuaValue const& data) { + ByteArray bytes; + if (auto str = engine.luaMaybeTo<String>(data)) + bytes = ByteArray(str->utf8Ptr(), str->utf8Size()); + else { + auto json = engine.luaTo<Json>(data).repr(); + bytes = ByteArray(json.utf8Ptr(), json.utf8Size()); + } + newFiles->set(path, bytes); + }); - callbacks.registerCallback("patch", [this, &newFiles](String const& path, String const& patchPath) -> bool { - if (auto file = m_files.ptr(path)) { - if (newFiles->contains(patchPath)) { - file->patchSources.append(make_pair(patchPath, newFiles)); - return true; - } else { - if (auto asset = m_files.ptr(patchPath)) { - file->patchSources.append(make_pair(patchPath, asset->source)); + callbacks.registerCallback("patch", [this, &newFiles](String const& path, String const& patchPath) -> bool { + if (auto file = m_files.ptr(path)) { + if (newFiles->contains(patchPath)) { + file->patchSources.append(make_pair(patchPath, newFiles)); return true; + } else { + if (auto asset = m_files.ptr(patchPath)) { + file->patchSources.append(make_pair(patchPath, asset->source)); + return true; + } } } - } - return false; - }); + return false; + }); - callbacks.registerCallback("erase", [this](String const& path) -> bool { - bool erased = m_files.erase(path); - if (erased) - m_filesByExtension[AssetPath::extension(path).toLower()].erase(path); - return erased; - }); + callbacks.registerCallback("erase", [this](String const& path) -> bool { + bool erased = m_files.erase(path); + if (erased) + m_filesByExtension[AssetPath::extension(path).toLower()].erase(path); + return erased; + }); + } context.setCallbacks("assets", callbacks); }; @@ -883,21 +892,35 @@ Json Assets::readJson(String const& path) const { try { Json result = inputUtf8Json(streamData.begin(), streamData.end(), false); for (auto const& pair : m_files.get(path).patchSources) { - auto patchStream = pair.second->read(pair.first); - auto patchJson = inputUtf8Json(patchStream.begin(), patchStream.end(), false); - if (patchJson.isType(Json::Type::Array)) { - auto patchData = patchJson.toArray(); - try { - result = checkPatchArray(pair.first, pair.second, result, patchData, {}); - } catch (JsonPatchTestFail const& e) { - Logger::debug("Patch test failure from file {} in source: '{}' at '{}'. Caused by: {}", pair.first, pair.second->metadata().value("name", ""), m_assetSourcePaths.getLeft(pair.second), e.what()); - } catch (JsonPatchException const& e) { - Logger::error("Could not apply patch from file {} in source: '{}' at '{}'. Caused by: {}", pair.first, pair.second->metadata().value("name", ""), m_assetSourcePaths.getLeft(pair.second), e.what()); + auto& patchPath = pair.first; + auto& patchSource = pair.second; + auto patchStream = patchSource->read(patchPath); + if (pair.first.endsWith(".lua")) { + MutexLocker luaLocker(m_luaMutex); + // Kae: i don't like that lock. perhaps have a LuaEngine and patch context cache per worker thread later on? + LuaContextPtr& context = m_patchContexts[patchPath]; + if (!context) { + context = make_shared<LuaContext>(as<LuaEngine>(m_luaEngine.get())->createContext()); + context->load(patchStream, patchPath); + } + auto newResult = context->invokePath<Json>("patch", result, path); + if (newResult) + result = std::move(newResult); + } else { + auto patchJson = inputUtf8Json(patchStream.begin(), patchStream.end(), false); + if (patchJson.isType(Json::Type::Array)) { + auto patchData = patchJson.toArray(); + try { + result = checkPatchArray(patchPath, patchSource, result, patchData, {}); + } catch (JsonPatchTestFail const& e) { + Logger::debug("Patch test failure from file {} in source: '{}' at '{}'. Caused by: {}", patchPath, patchSource->metadata().value("name", ""), m_assetSourcePaths.getLeft(patchSource), e.what()); + } catch (JsonPatchException const& e) { + Logger::error("Could not apply patch from file {} in source: '{}' at '{}'. Caused by: {}", patchPath, patchSource->metadata().value("name", ""), m_assetSourcePaths.getLeft(patchSource), e.what()); + } + } else if (patchJson.isType(Json::Type::Object)) {//Kae: Do a good ol' json merge instead if the .patch file is a Json object + result = jsonMergeNulling(result, patchJson.toObject()); + } } - } else if (patchJson.isType(Json::Type::Object)) { //Kae: Do a good ol' json merge instead if the .patch file is a Json object - auto patchData = patchJson.toObject(); - result = jsonMergeNulling(result, patchData); - } } return result; } catch (std::exception const& e) { diff --git a/source/base/StarAssets.hpp b/source/base/StarAssets.hpp index f945cf8..8cfbc52 100644 --- a/source/base/StarAssets.hpp +++ b/source/base/StarAssets.hpp @@ -7,6 +7,7 @@ #include "StarThread.hpp" #include "StarAssetSource.hpp" #include "StarAssetPath.hpp" +#include "StarRefPtr.hpp" namespace Star { @@ -16,6 +17,8 @@ STAR_CLASS(Image); STAR_STRUCT(FramesSpecification); STAR_CLASS(Assets); +STAR_CLASS(LuaContext); + STAR_EXCEPTION(AssetException, StarException); // The contents of an assets .frames file, which can be associated with one or @@ -313,6 +316,11 @@ private: mutable StringMap<String> m_bestFramesFiles; mutable StringMap<FramesSpecificationConstPtr> m_framesSpecifications; + // Lua + RefPtr<RefCounter> m_luaEngine; // dumb but to avoid including Lua.hpp in here... + mutable StringMap<LuaContextPtr> m_patchContexts; + mutable Mutex m_luaMutex; + // Paths of all used asset sources, in load order. StringList m_assetSources; diff --git a/source/base/StarCellularLighting.hpp b/source/base/StarCellularLighting.hpp index 170cbb5..7cb230f 100644 --- a/source/base/StarCellularLighting.hpp +++ b/source/base/StarCellularLighting.hpp @@ -27,6 +27,7 @@ public: void set(unsigned x, unsigned y, float v); void set(unsigned x, unsigned y, Vec3F const& v); + void add(unsigned x, unsigned y, Vec3F const& v); Vec3F get(unsigned x, unsigned y) const; bool empty() const; @@ -64,6 +65,16 @@ inline void Lightmap::set(unsigned x, unsigned y, Vec3F const& v) { ptr[2] = v.z(); } +inline void Lightmap::add(unsigned x, unsigned y, Vec3F const& v) { + if (x >= m_width || y >= m_height) { + throw LightmapException(strf("[{}, {}] out of range in Lightmap::add", x, y)); + return; + } + float* ptr = m_data.get() + (y * m_width * 3 + x * 3); + ptr[0] += v.x(); + ptr[1] += v.y(); + ptr[2] += v.z(); +} inline Vec3F Lightmap::get(unsigned x, unsigned y) const { if (x >= m_width || y >= m_height) { @@ -74,6 +85,7 @@ inline Vec3F Lightmap::get(unsigned x, unsigned y) const { return Vec3F(ptr[0], ptr[1], ptr[2]); } + inline bool Lightmap::empty() const { return m_width == 0 || m_height == 0; } diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 0e63c06..df69b94 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -1382,7 +1382,8 @@ bool WorldClient::waitForLighting(WorldRenderData* renderData) { for (auto& previewTile : m_previewTiles) { if (previewTile.updateLight) { Vec2I lightArrayPos = m_geometry.diff(previewTile.position, m_lightMinPosition); - if (lightArrayPos[0] >= 0 && lightArrayPos[0] < (int)m_lightMap.width() && lightArrayPos[1] >= 0 && lightArrayPos[1] < (int)m_lightMap.height()) + if (lightArrayPos[0] >= 0 && lightArrayPos[0] < (int)m_lightMap.width() + && lightArrayPos[1] >= 0 && lightArrayPos[1] < (int)m_lightMap.height()) m_lightMap.set(lightArrayPos[0], lightArrayPos[1], Color::v3bToFloat(previewTile.light)); } } @@ -1654,15 +1655,13 @@ void WorldClient::lightingCalc() { if (light.pointLight) m_lightingCalculator.addPointLight(position, light.color, light.pointBeam, light.beamAngle, light.beamAmbience); else { - m_lightingCalculator.addSpreadLight(position, light.color * 0.6f); - m_lightingCalculator.addPointLight(position, light.color * 0.4f, 0.0f, 0.0f, 1.0f); + m_lightingCalculator.addSpreadLight(position, light.color); } } for (auto const& lightPair : particleLights) { Vec2F position = m_geometry.nearestTo(Vec2F(m_lightingCalculator.calculationRegion().min()), lightPair.first); - m_lightingCalculator.addSpreadLight(position, lightPair.second * 0.6f); - m_lightingCalculator.addPointLight(position, lightPair.second * 0.4f, 0.0f, 0.0f, 1.0f); + m_lightingCalculator.addSpreadLight(position, lightPair.second); } m_lightingCalculator.calculate(m_pendingLightMap); |