Lua patches
This commit is contained in:
parent
a096fa3ffc
commit
57ca6776e4
19
assets/opensb/objects/opensb/object.patch.lua
Normal file
19
assets/opensb/objects/opensb/object.patch.lua
Normal file
@ -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
|
@ -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
|
BIN
assets/opensb/tiles/shadows.png
Normal file
BIN
assets/opensb/tiles/shadows.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 412 B |
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user