add GeneratorScript
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "lua_commons.hpp"
|
||||
#include "maths/Heightmap.hpp"
|
||||
|
||||
namespace lua {
|
||||
class Userdata {
|
||||
@@ -27,37 +28,42 @@ namespace lua {
|
||||
}
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "bytearray";
|
||||
inline static std::string TYPENAME = "Bytearray";
|
||||
};
|
||||
|
||||
class Heightmap : public Userdata {
|
||||
std::vector<float> buffer;
|
||||
uint width, height;
|
||||
class LuaHeightmap : public Userdata {
|
||||
std::shared_ptr<Heightmap> map;
|
||||
public:
|
||||
Heightmap(uint width, uint height);
|
||||
virtual ~Heightmap();
|
||||
LuaHeightmap(uint width, uint height)
|
||||
: map(std::make_shared<Heightmap>(width, height)) {}
|
||||
|
||||
virtual ~LuaHeightmap() = default;
|
||||
|
||||
uint getWidth() const {
|
||||
return width;
|
||||
return map->getWidth();
|
||||
}
|
||||
|
||||
uint getHeight() const {
|
||||
return height;
|
||||
return map->getHeight();
|
||||
}
|
||||
|
||||
float* getValues() {
|
||||
return map->getValues();
|
||||
}
|
||||
|
||||
const float* getValues() const {
|
||||
return map->getValues();
|
||||
}
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
float* getValues() {
|
||||
return buffer.data();
|
||||
}
|
||||
|
||||
const float* getValues() const {
|
||||
return buffer.data();
|
||||
std::shared_ptr<Heightmap> getHeightmap() const {
|
||||
return map;
|
||||
}
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "heightmap";
|
||||
inline static std::string TYPENAME = "Heightmap";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ void lua::initialize() {
|
||||
initialize_libs_extends(L);
|
||||
|
||||
newusertype<Bytearray, Bytearray::createMetatable>(L, "Bytearray");
|
||||
newusertype<Heightmap, Heightmap::createMetatable>(L, "Heightmap");
|
||||
newusertype<LuaHeightmap, LuaHeightmap::createMetatable>(L, "Heightmap");
|
||||
}
|
||||
|
||||
void lua::finalize() {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "util/functional_util.hpp"
|
||||
#include "maths/FastNoiseLite.h"
|
||||
#include "coders/png.hpp"
|
||||
#include "files/util.hpp"
|
||||
#include "graphics/core/ImageData.hpp"
|
||||
#include "lua_util.hpp"
|
||||
|
||||
@@ -15,16 +16,12 @@ using namespace lua;
|
||||
|
||||
static fnl_state noise = fnlCreateState();
|
||||
|
||||
Heightmap::Heightmap(uint width, uint height) : width(width), height(height) {
|
||||
buffer.resize(width*height);
|
||||
}
|
||||
|
||||
Heightmap::~Heightmap() {
|
||||
}
|
||||
|
||||
static int l_dump(lua::State* L) {
|
||||
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
|
||||
if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) {
|
||||
auto filename = tostring(L, 2);
|
||||
if (!files::is_valid_name(filename)) {
|
||||
throw std::runtime_error("invalid file name");
|
||||
}
|
||||
uint w = heightmap->getWidth();
|
||||
uint h = heightmap->getHeight();
|
||||
ImageData image(ImageFormat::rgb888, w, h);
|
||||
@@ -46,7 +43,7 @@ static int l_dump(lua::State* L) {
|
||||
}
|
||||
|
||||
static int l_noise(lua::State* L) {
|
||||
if (auto heightmap = touserdata<Heightmap>(L, 1)) {
|
||||
if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) {
|
||||
uint w = heightmap->getWidth();
|
||||
uint h = heightmap->getHeight();
|
||||
auto heights = heightmap->getValues();
|
||||
@@ -62,13 +59,13 @@ static int l_noise(lua::State* L) {
|
||||
if (gettop(L) > 4) {
|
||||
multiplier = tonumber(L, 5);
|
||||
}
|
||||
const Heightmap* shiftMapX = nullptr;
|
||||
const Heightmap* shiftMapY = nullptr;
|
||||
const LuaHeightmap* shiftMapX = nullptr;
|
||||
const LuaHeightmap* shiftMapY = nullptr;
|
||||
if (gettop(L) > 5) {
|
||||
shiftMapX = touserdata<Heightmap>(L, 6);
|
||||
shiftMapX = touserdata<LuaHeightmap>(L, 6);
|
||||
}
|
||||
if (gettop(L) > 6) {
|
||||
shiftMapY = touserdata<Heightmap>(L, 7);
|
||||
shiftMapY = touserdata<LuaHeightmap>(L, 7);
|
||||
}
|
||||
for (uint y = 0; y < h; y++) {
|
||||
for (uint x = 0; x < w; x++) {
|
||||
@@ -159,13 +156,13 @@ static int l_meta_meta_call(lua::State* L) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
throw std::runtime_error("width and height must be greather than 0");
|
||||
}
|
||||
return newuserdata<Heightmap>(
|
||||
return newuserdata<LuaHeightmap>(
|
||||
L, static_cast<uint>(width), static_cast<uint>(height)
|
||||
);
|
||||
}
|
||||
|
||||
static int l_meta_index(lua::State* L) {
|
||||
auto map = touserdata<Heightmap>(L, 1);
|
||||
auto map = touserdata<LuaHeightmap>(L, 1);
|
||||
if (map == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
@@ -186,7 +183,7 @@ static int l_meta_index(lua::State* L) {
|
||||
}
|
||||
|
||||
static int l_meta_tostring(lua::State* L) {
|
||||
auto map = touserdata<Heightmap>(L, 1);
|
||||
auto map = touserdata<LuaHeightmap>(L, 1);
|
||||
if (map == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
@@ -201,7 +198,7 @@ static int l_meta_tostring(lua::State* L) {
|
||||
);
|
||||
}
|
||||
|
||||
int Heightmap::createMetatable(lua::State* L) {
|
||||
int LuaHeightmap::createMetatable(lua::State* L) {
|
||||
createtable(L, 0, 2);
|
||||
pushcfunction(L, lua::wrap<l_meta_tostring>);
|
||||
setfield(L, "__tostring");
|
||||
|
||||
@@ -153,6 +153,14 @@ namespace lua {
|
||||
return 3;
|
||||
}
|
||||
|
||||
template<int n>
|
||||
inline int pushivec_stack(lua::State* L, glm::vec<n, int> vec) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
pushinteger(L, vec[i]);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
inline int pushivec3_stack(lua::State* L, glm::ivec3 vec) {
|
||||
pushinteger(L, vec.x);
|
||||
pushinteger(L, vec.y);
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include "items/ItemDef.hpp"
|
||||
#include "logic/BlocksController.hpp"
|
||||
#include "logic/LevelController.hpp"
|
||||
#include "lua/lua_engine.hpp"
|
||||
#include "lua/lua_custom_types.hpp"
|
||||
#include "maths/Heightmap.hpp"
|
||||
#include "objects/Entities.hpp"
|
||||
#include "objects/EntityDef.hpp"
|
||||
#include "objects/Player.hpp"
|
||||
@@ -21,7 +24,7 @@
|
||||
#include "util/timeutil.hpp"
|
||||
#include "voxels/Block.hpp"
|
||||
#include "world/Level.hpp"
|
||||
#include "lua/lua_engine.hpp"
|
||||
#include "world/generator/GeneratorDef.hpp"
|
||||
|
||||
using namespace scripting;
|
||||
|
||||
@@ -62,6 +65,15 @@ void scripting::initialize(Engine* engine) {
|
||||
return std::make_shared<int>(0);
|
||||
}
|
||||
|
||||
[[nodiscard]] scriptenv scripting::create_environment() {
|
||||
auto L = lua::get_main_thread();
|
||||
int id = lua::create_environment(L, 0);
|
||||
return std::shared_ptr<int>(new int(id), [=](int* id) { //-V508
|
||||
lua::removeEnvironment(L, *id);
|
||||
delete id;
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] scriptenv scripting::create_pack_environment(
|
||||
const ContentPack& pack
|
||||
) {
|
||||
@@ -672,6 +684,35 @@ void scripting::load_entity_component(
|
||||
lua::store_in(L, lua::CHUNKS_TABLE, name);
|
||||
}
|
||||
|
||||
class LuaGeneratorScript : public GeneratorScript {
|
||||
scriptenv env;
|
||||
public:
|
||||
LuaGeneratorScript(scriptenv env) : env(std::move(env)) {}
|
||||
|
||||
std::shared_ptr<Heightmap> generateHeightmap(
|
||||
const glm::ivec2& offset, const glm::ivec2& size
|
||||
) override {
|
||||
auto L = lua::get_main_thread();
|
||||
lua::pushenv(L, *env);
|
||||
if (lua::getfield(L, "generate_heightmap")) {
|
||||
lua::pushivec_stack(L, offset);
|
||||
lua::pushivec_stack(L, size);
|
||||
if (lua::call_nothrow(L, 4)) {
|
||||
return lua::touserdata<lua::LuaHeightmap>(L, -1)->getHeightmap();
|
||||
}
|
||||
}
|
||||
return std::make_shared<Heightmap>(size.x, size.y);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<GeneratorScript> scripting::load_generator(
|
||||
const fs::path& file
|
||||
) {
|
||||
auto env = create_environment();
|
||||
load_script(*env, "generator", file);
|
||||
return std::make_unique<LuaGeneratorScript>(std::move(env));
|
||||
}
|
||||
|
||||
void scripting::load_world_script(
|
||||
const scriptenv& senv,
|
||||
const std::string& prefix,
|
||||
|
||||
@@ -32,6 +32,7 @@ class BlocksController;
|
||||
class LevelController;
|
||||
class Entity;
|
||||
struct EntityDef;
|
||||
class GeneratorScript;
|
||||
|
||||
namespace scripting {
|
||||
extern Engine* engine;
|
||||
@@ -50,6 +51,7 @@ namespace scripting {
|
||||
|
||||
scriptenv get_root_environment();
|
||||
scriptenv create_pack_environment(const ContentPack& pack);
|
||||
scriptenv create_environment();
|
||||
scriptenv create_doc_environment(
|
||||
const scriptenv& parent, const std::string& name
|
||||
);
|
||||
@@ -144,6 +146,10 @@ namespace scripting {
|
||||
|
||||
void load_entity_component(const std::string& name, const fs::path& file);
|
||||
|
||||
std::unique_ptr<GeneratorScript> load_generator(
|
||||
const fs::path& file
|
||||
);
|
||||
|
||||
/// @brief Load package-specific world script
|
||||
/// @param env environment
|
||||
/// @param packid content-pack id
|
||||
|
||||
Reference in New Issue
Block a user