This commit is contained in:
A-lex-Ra 2024-01-08 12:36:11 +06:00
commit c4e77999e9
28 changed files with 540 additions and 218 deletions

53
res/texts/fi_FI.txt Normal file
View File

@ -0,0 +1,53 @@
# Общее
Yes=Joo
No=Ei
Ok = Kyllä
Cancel= Hylää
Back = Takaisin
Continue=Jatka
error.pack-not-found=Pakettia ei löytynyt!
# Меню
menu.New World = Uusi Maailma
menu.Quit=Poistu
menu.Continue=Jatka
menu.Save and Quit to Menu=Tallenna ja Takaisin valikoon
menu.missing-content=Puuttuu jotkut lisäosat!
menu.Controls=Ohjaus
menu.Back to Main Menu=Takaisin Valikoon
menu.Settings=Asetukset
menu.Content=Lisäosat
menu.Seed=Siemen
menu.Name=Nimi
menu.Create World=Luo Maailma
world.convert-request=Indeksit vaihdettu! Lataa maailma uudeleen?
# Настройки
settings.Load Distance=Lataus Alue
settings.Load Speed=Lataus Nopeus
settings.Fog Curve=Sumun valaistus
settings.Backlight=Valaistus
settings.V-Sync=Pystytahdistus
settings.FOV=Näkökenttä
settings.Mouse Sensitivity=Hiiren nopeus
settings.Language=Kieli
# Управление
movement.forward=Eteenpäin
movement.back=Taaksepäin
movement.left=Vaseemalle
movement.right=Oikealle
movement.jump=Hyppy
movement.sprint=Kiihtyvyys
movement.crouch=Istu alas
movement.cheat=Huijata
hud.inventory=Varasto
player.pick=Ottaa lohko
player.attack=Lyödä / Rikkoa
player.build=Aseta lohko
player.flight=Lento
camera.zoom=Lähentäminen
camera.mode=Vaihda Kameratila

View File

@ -14,6 +14,9 @@
}, },
"uk_UA": { "uk_UA": {
"name": "Українська" "name": "Українська"
},
"fi_FI": {
"name": "Suomi"
} }
}, },
"fallback": "en_US" "fallback": "en_US"

View File

@ -4,22 +4,43 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "../voxels/Block.h" #include "../voxels/Block.h"
#include "../content/ItemDef.h"
using glm::vec3; using glm::vec3;
using std::vector;
using std::string; using std::string;
using std::unordered_map; using std::unordered_map;
void ContentBuilder::add(Block* def) { void ContentBuilder::add(Block* def) {
if (blockDefs.find(def->name) != blockDefs.end()) { checkIdentifier(def->name);
throw std::runtime_error("block name duplicate: "+def->name);
}
blockDefs[def->name] = def; blockDefs[def->name] = def;
blockIds.push_back(def->name); blockIds.push_back(def->name);
} }
void ContentBuilder::add(ItemDef* def) {
checkIdentifier(def->name);
itemDefs[def->name] = def;
itemIds.push_back(def->name);
}
void ContentBuilder::checkIdentifier(std::string id) {
contenttype result;
if ((checkContentType(id) != contenttype::none)) {
throw contentindexreuse_error("identifier "+id+" is already used", result);
}
}
contenttype ContentBuilder::checkContentType(std::string id) {
if (blockDefs.find(id) != blockDefs.end()) {
return contenttype::block;
}
if (itemDefs.find(id) != itemDefs.end()) {
return contenttype::item;
}
return contenttype::none;
}
Content* ContentBuilder::build() { Content* ContentBuilder::build() {
vector<Block*> blockDefsIndices; std::vector<Block*> blockDefsIndices;
DrawGroups* groups = new DrawGroups; DrawGroups* groups = new DrawGroups;
for (const string& name : blockIds) { for (const string& name : blockIds) {
Block* def = blockDefs[name]; Block* def = blockDefs[name];
@ -42,15 +63,26 @@ Content* ContentBuilder::build() {
if (groups->find(def->drawGroup) == groups->end()) { if (groups->find(def->drawGroup) == groups->end()) {
groups->insert(def->drawGroup); groups->insert(def->drawGroup);
} }
} }
ContentIndices* indices = new ContentIndices(blockDefsIndices);
std::vector<ItemDef*> itemDefsIndices;
for (const string& name : itemIds) {
ItemDef* def = itemDefs[name];
// Generating runtime info
def->rt.id = itemDefsIndices.size();
itemDefsIndices.push_back(def);
}
auto indices = new ContentIndices(blockDefsIndices, itemDefsIndices);
return new Content(indices, groups, blockDefs); return new Content(indices, groups, blockDefs);
} }
ContentIndices::ContentIndices(vector<Block*> blockDefs) ContentIndices::ContentIndices(
: blockDefs(blockDefs) { std::vector<Block*> blockDefs,
std::vector<ItemDef*> itemDefs)
: blockDefs(blockDefs),
itemDefs(itemDefs) {
} }
Content::Content(ContentIndices* indices, DrawGroups* drawGroups, Content::Content(ContentIndices* indices, DrawGroups* drawGroups,
@ -80,3 +112,19 @@ Block* Content::requireBlock(string id) const {
} }
return found->second; return found->second;
} }
ItemDef* Content::findItem(string id) const {
auto found = itemDefs.find(id);
if (found == itemDefs.end()) {
return nullptr;
}
return found->second;
}
ItemDef* Content::requireItem(string id) const {
auto found = itemDefs.find(id);
if (found == itemDefs.end()) {
throw std::runtime_error("missing item "+id);
}
return found->second;
}

View File

@ -3,6 +3,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdexcept>
#include <unordered_map> #include <unordered_map>
#include <set> #include <set>
#include "../typedefs.h" #include "../typedefs.h"
@ -10,23 +11,47 @@
typedef std::set<unsigned char> DrawGroups; typedef std::set<unsigned char> DrawGroups;
class Block; class Block;
class ItemDef;
class Content; class Content;
enum class contenttype {
none, block, item
};
class contentindexreuse_error: public std::runtime_error {
contenttype type;
public:
contentindexreuse_error(const std::string& msg, contenttype type)
: std::runtime_error(msg), type(type) {}
inline contenttype getType() const {
return type;
}
};
class ContentBuilder { class ContentBuilder {
std::unordered_map<std::string, Block*> blockDefs; std::unordered_map<std::string, Block*> blockDefs;
std::vector<std::string> blockIds; std::vector<std::string> blockIds;
std::unordered_map<std::string, ItemDef*> itemDefs;
std::vector<std::string> itemIds;
public: public:
void add(Block* def); void add(Block* def);
void add(ItemDef* def);
void checkIdentifier(std::string id);
contenttype checkContentType(std::string id);
Content* build(); Content* build();
}; };
/* Runtime defs cache: indices */ /* Runtime defs cache: indices */
class ContentIndices { class ContentIndices {
// blockDefs must be a plain vector with block id used as index
std::vector<Block*> blockDefs; std::vector<Block*> blockDefs;
std::vector<ItemDef*> itemDefs;
public: public:
ContentIndices(std::vector<Block*> blockDefs); ContentIndices(std::vector<Block*> blockDefs,
std::vector<ItemDef*> itemDefs);
inline Block* getBlockDef(blockid_t id) const { inline Block* getBlockDef(blockid_t id) const {
if (id >= blockDefs.size()) if (id >= blockDefs.size())
@ -34,19 +59,34 @@ public:
return blockDefs[id]; return blockDefs[id];
} }
inline ItemDef* getItemDef(itemid_t id) const {
if (id >= itemDefs.size())
return nullptr;
return itemDefs[id];
}
inline size_t countBlockDefs() const { inline size_t countBlockDefs() const {
return blockDefs.size(); return blockDefs.size();
} }
inline size_t countItemDefs() const {
return itemDefs.size();
}
// use this for critical spots to prevent range check overhead // use this for critical spots to prevent range check overhead
const Block* const* getBlockDefs() const { const Block* const* getBlockDefs() const {
return blockDefs.data(); return blockDefs.data();
} }
const ItemDef* const* getItemDefs() const {
return itemDefs.data();
}
}; };
/* Content is a definitions repository */ /* Content is a definitions repository */
class Content { class Content {
std::unordered_map<std::string, Block*> blockDefs; std::unordered_map<std::string, Block*> blockDefs;
std::unordered_map<std::string, ItemDef*> itemDefs;
public: public:
ContentIndices* const indices; ContentIndices* const indices;
DrawGroups* const drawGroups; DrawGroups* const drawGroups;
@ -57,6 +97,9 @@ public:
Block* findBlock(std::string id) const; Block* findBlock(std::string id) const;
Block* requireBlock(std::string id) const; Block* requireBlock(std::string id) const;
ItemDef* findItem(std::string id) const;
ItemDef* requireItem(std::string id) const;
}; };
#endif // CONTENT_CONTENT_H_ #endif // CONTENT_CONTENT_H_

View File

@ -7,6 +7,7 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "Content.h" #include "Content.h"
#include "ItemDef.h"
#include "../util/listutil.h" #include "../util/listutil.h"
#include "../voxels/Block.h" #include "../voxels/Block.h"
#include "../files/files.h" #include "../files/files.h"
@ -21,10 +22,56 @@ namespace fs = std::filesystem;
ContentLoader::ContentLoader(ContentPack* pack) : pack(pack) { ContentLoader::ContentLoader(ContentPack* pack) : pack(pack) {
} }
bool ContentLoader::fixPackIndices(fs::path folder,
json::JObject* indicesRoot,
std::string contentSection) {
std::vector<std::string> detected;
std::vector<std::string> indexed;
if (fs::is_directory(folder)) {
for (auto entry : fs::directory_iterator(folder)) {
fs::path file = entry.path();
if (fs::is_regular_file(file) && file.extension() == ".json") {
std::string name = file.stem().string();
if (name[0] == '_')
continue;
detected.push_back(name);
}
}
}
bool modified = false;
if (!indicesRoot->has(contentSection)) {
indicesRoot->putArray(contentSection);
}
json::JArray* arr = indicesRoot->arr(contentSection);
if (arr) {
for (uint i = 0; i < arr->size(); i++) {
std::string name = arr->str(i);
if (!util::contains(detected, name)) {
arr->remove(i);
i--;
modified = true;
continue;
}
indexed.push_back(name);
}
}
for (auto name : detected) {
if (!util::contains(indexed, name)) {
arr->put(name);
modified = true;
}
}
return modified;
}
void ContentLoader::fixPackIndices() { void ContentLoader::fixPackIndices() {
auto folder = pack->folder; auto folder = pack->folder;
auto indexFile = pack->getContentFile(); auto indexFile = pack->getContentFile();
auto blocksFolder = folder/ContentPack::BLOCKS_FOLDER; auto blocksFolder = folder/ContentPack::BLOCKS_FOLDER;
auto itemsFolder = folder/ContentPack::ITEMS_FOLDER;
std::unique_ptr<json::JObject> root; std::unique_ptr<json::JObject> root;
if (fs::is_regular_file(indexFile)) { if (fs::is_regular_file(indexFile)) {
root.reset(files::read_json(indexFile)); root.reset(files::read_json(indexFile));
@ -32,43 +79,11 @@ void ContentLoader::fixPackIndices() {
root.reset(new json::JObject()); root.reset(new json::JObject());
} }
std::vector<std::string> detectedBlocks;
std::vector<std::string> indexedBlocks;
if (fs::is_directory(blocksFolder)) {
for (auto entry : fs::directory_iterator(blocksFolder)) {
fs::path file = entry.path();
if (fs::is_regular_file(file) && file.extension() == ".json") {
std::string name = file.stem().string();
if (name[0] == '_')
continue;
detectedBlocks.push_back(name);
}
}
}
bool modified = false; bool modified = false;
if (!root->has("blocks")) {
root->putArray("blocks"); modified |= fixPackIndices(blocksFolder, root.get(), "blocks");
} modified |= fixPackIndices(itemsFolder, root.get(), "items");
json::JArray* blocksarr = root->arr("blocks");
if (blocksarr) {
for (uint i = 0; i < blocksarr->size(); i++) {
std::string name = blocksarr->str(i);
if (!util::contains(detectedBlocks, name)) {
blocksarr->remove(i);
i--;
modified = true;
continue;
}
indexedBlocks.push_back(name);
}
}
for (auto name : detectedBlocks) {
if (!util::contains(indexedBlocks, name)) {
blocksarr->put(name);
modified = true;
}
}
if (modified){ if (modified){
// rewrite modified json // rewrite modified json
std::cout << indexFile << std::endl; std::cout << indexFile << std::endl;
@ -165,6 +180,39 @@ Block* ContentLoader::loadBlock(std::string name, fs::path file) {
return def.release(); return def.release();
} }
ItemDef* ContentLoader::loadItem(std::string name, std::filesystem::path file) {
std::unique_ptr<json::JObject> root(files::read_json(file));
std::unique_ptr<ItemDef> def(new ItemDef(name));
return def.release();
}
Block* ContentLoader::loadBlock(std::string name) {
auto folder = pack->folder;
std::string prefix = pack->id+":"+name;
fs::path configFile = folder/fs::path("blocks/"+name+".json");
fs::path scriptfile = folder/fs::path("scripts/"+name+".lua");
Block* def = loadBlock(prefix, configFile);
if (fs::is_regular_file(scriptfile)) {
scripting::load_block_script(prefix, scriptfile, &def->rt.funcsset);
}
return def;
}
ItemDef* ContentLoader::loadItem(std::string name) {
auto folder = pack->folder;
std::string prefix = pack->id+":"+name;
fs::path configFile = folder/fs::path("items/"+name+".json");
fs::path scriptfile = folder/fs::path("scripts/"+name+".lua");
ItemDef* def = loadItem(prefix, configFile);
if (fs::is_regular_file(scriptfile)) {
scripting::load_item_script(prefix, scriptfile, &def->rt.funcsset);
}
return def;
}
void ContentLoader::load(ContentBuilder* builder) { void ContentLoader::load(ContentBuilder* builder) {
std::cout << "-- loading pack [" << pack->id << "]" << std::endl; std::cout << "-- loading pack [" << pack->id << "]" << std::endl;
@ -178,15 +226,14 @@ void ContentLoader::load(ContentBuilder* builder) {
json::JArray* blocksarr = root->arr("blocks"); json::JArray* blocksarr = root->arr("blocks");
if (blocksarr) { if (blocksarr) {
for (uint i = 0; i < blocksarr->size(); i++) { for (uint i = 0; i < blocksarr->size(); i++) {
std::string name = blocksarr->str(i); builder->add(loadBlock(blocksarr->str(i)));
std::string prefix = pack->id+":"+name; }
fs::path blockfile = folder/fs::path("blocks/"+name+".json"); }
Block* block = loadBlock(prefix, blockfile);
builder->add(block); json::JArray* itemsarr = root->arr("items");
fs::path scriptfile = folder/fs::path("scripts/"+name+".lua"); if (itemsarr) {
if (fs::is_regular_file(scriptfile)) { for (uint i = 0; i < itemsarr->size(); i++) {
scripting::load_block_script(prefix, scriptfile, &block->rt.funcsset); builder->add(loadItem(itemsarr->str(i)));
}
} }
} }
} }

View File

@ -5,16 +5,28 @@
#include <filesystem> #include <filesystem>
class Block; class Block;
class ItemDef;
class ContentPack; class ContentPack;
class ContentBuilder; class ContentBuilder;
namespace json {
class JObject;
}
class ContentLoader { class ContentLoader {
const ContentPack* pack; const ContentPack* pack;
Block* loadBlock(std::string name);
ItemDef* loadItem(std::string name);
public: public:
ContentLoader(ContentPack* pack); ContentLoader(ContentPack* pack);
bool fixPackIndices(std::filesystem::path folder,
json::JObject* indicesRoot,
std::string contentSection);
void fixPackIndices(); void fixPackIndices();
Block* loadBlock(std::string name, std::filesystem::path file); Block* loadBlock(std::string name, std::filesystem::path file);
ItemDef* loadItem(std::string name, std::filesystem::path file);
void load(ContentBuilder* builder); void load(ContentBuilder* builder);
}; };

View File

@ -11,6 +11,7 @@ namespace fs = std::filesystem;
const std::string ContentPack::PACKAGE_FILENAME = "package.json"; const std::string ContentPack::PACKAGE_FILENAME = "package.json";
const std::string ContentPack::CONTENT_FILENAME = "content.json"; const std::string ContentPack::CONTENT_FILENAME = "content.json";
const fs::path ContentPack::BLOCKS_FOLDER = "blocks"; const fs::path ContentPack::BLOCKS_FOLDER = "blocks";
const fs::path ContentPack::ITEMS_FOLDER = "items";
contentpack_error::contentpack_error( contentpack_error::contentpack_error(
std::string packId, std::string packId,

View File

@ -31,6 +31,7 @@ struct ContentPack {
static const std::string PACKAGE_FILENAME; static const std::string PACKAGE_FILENAME;
static const std::string CONTENT_FILENAME; static const std::string CONTENT_FILENAME;
static const std::filesystem::path BLOCKS_FOLDER; static const std::filesystem::path BLOCKS_FOLDER;
static const std::filesystem::path ITEMS_FOLDER;
static bool is_pack(std::filesystem::path folder); static bool is_pack(std::filesystem::path folder);
static ContentPack read(std::filesystem::path folder); static ContentPack read(std::filesystem::path folder);

4
src/content/ItemDef.cpp Normal file
View File

@ -0,0 +1,4 @@
#include "ItemDef.h"
ItemDef::ItemDef(std::string name) : name(name) {
}

25
src/content/ItemDef.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef CONTENT_ITEM_DEF_H_
#define CONTENT_ITEM_DEF_H_
#include <string>
#include <glm/glm.hpp>
#include "../typedefs.h"
struct item_funcs_set {
bool init: 1;
};
class ItemDef {
public:
std::string name;
struct {
itemid_t id;
item_funcs_set funcsset {};
} rt;
ItemDef(std::string name);
};
#endif //CONTENT_ITEM_DEF_H_

View File

@ -18,6 +18,8 @@
#include "../coders/json.h" #include "../coders/json.h"
#include "../constants.h" #include "../constants.h"
#include "../content/ItemDef.h"
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <cstdint> #include <cstdint>
@ -461,12 +463,21 @@ void WorldFiles::writePacks(const World* world) {
void WorldFiles::writeIndices(const ContentIndices* indices) { void WorldFiles::writeIndices(const ContentIndices* indices) {
json::JObject root; json::JObject root;
uint count;
json::JArray& blocks = root.putArray("blocks"); json::JArray& blocks = root.putArray("blocks");
uint count = indices->countBlockDefs(); count = indices->countBlockDefs();
for (uint i = 0; i < count; i++) { for (uint i = 0; i < count; i++) {
const Block* def = indices->getBlockDef(i); const Block* def = indices->getBlockDef(i);
blocks.put(def->name); blocks.put(def->name);
} }
json::JArray& items = root.putArray("items");
count = indices->countItemDefs();
for (uint i = 0; i < count; i++) {
const ItemDef* def = indices->getItemDef(i);
items.put(def->name);
}
files::write_string(getIndicesFile(), json::stringify(&root, true, " ")); files::write_string(getIndicesFile(), json::stringify(&root, true, " "));
} }

View File

@ -2,6 +2,7 @@
#include <glm/ext.hpp> #include <glm/ext.hpp>
#include "../assets/Assets.h"
#include "../graphics/Viewport.h" #include "../graphics/Viewport.h"
#include "../graphics/Shader.h" #include "../graphics/Shader.h"
#include "../graphics/Texture.h" #include "../graphics/Texture.h"
@ -11,10 +12,10 @@
#include "../voxels/Block.h" #include "../voxels/Block.h"
#include "ContentGfxCache.h" #include "ContentGfxCache.h"
BlocksPreview::BlocksPreview(Shader* shader, BlocksPreview::BlocksPreview(Assets* assets, const ContentGfxCache* cache)
Atlas* atlas, : shader(assets->getShader("ui3d")),
const ContentGfxCache* cache) atlas(assets->getAtlas("blocks")),
: shader(shader), atlas(atlas), cache(cache) { cache(cache) {
batch = std::make_unique<Batch3D>(1024); batch = std::make_unique<Batch3D>(1024);
} }
@ -37,9 +38,8 @@ void BlocksPreview::draw(const Block* def, int x, int y, int size, glm::vec4 tin
uint width = viewport->getWidth(); uint width = viewport->getWidth();
uint height = viewport->getHeight(); uint height = viewport->getHeight();
y = height - y - 1; y = height - y - 1 - 35 /* magic garbage */;
x += 2; x += 2;
y -= 35;
glm::vec3 offset (x/float(width) * 2, y/float(height) * 2, 0.0f); glm::vec3 offset (x/float(width) * 2, y/float(height) * 2, 0.0f);
shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset)); shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset));

View File

@ -5,6 +5,7 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <memory> #include <memory>
class Assets;
class Viewport; class Viewport;
class Shader; class Shader;
class Atlas; class Atlas;
@ -19,7 +20,7 @@ class BlocksPreview {
const ContentGfxCache* const cache; const ContentGfxCache* const cache;
const Viewport* viewport; const Viewport* viewport;
public: public:
BlocksPreview(Shader* shader, Atlas* atlas, const ContentGfxCache* cache); BlocksPreview(Assets* assets, const ContentGfxCache* cache);
~BlocksPreview(); ~BlocksPreview();
void begin(const Viewport* viewport); void begin(const Viewport* viewport);

View File

@ -3,6 +3,7 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "BlocksPreview.h" #include "BlocksPreview.h"
#include "LevelFrontend.h"
#include "../window/Events.h" #include "../window/Events.h"
#include "../assets/Assets.h" #include "../assets/Assets.h"
#include "../graphics/Shader.h" #include "../graphics/Shader.h"
@ -15,44 +16,45 @@
InventoryView::InventoryView( InventoryView::InventoryView(
int columns, int columns,
Player* player,
const Assets* assets,
const ContentIndices* indices, const ContentIndices* indices,
const ContentGfxCache* cache, LevelFrontend* frontend,
std::vector<blockid_t> blocks) std::vector<blockid_t> blocks)
: player(player), : indices(indices),
assets(assets),
indices(indices),
cache(cache),
blocks(blocks), blocks(blocks),
invColumns(columns) { frontend(frontend),
blocksPreview = new BlocksPreview(assets->getShader("ui3d"), columns(columns) {
assets->getAtlas("blocks"), }
cache);
InventoryView::~InventoryView() {
} }
void InventoryView::setPosition(int x, int y) { void InventoryView::setPosition(int x, int y) {
this->invX = x; position.x = x;
this->invY = y; position.y = y;
} }
int InventoryView::getWidth() const { int InventoryView::getWidth() const {
return invColumns * iconSize + (invColumns-1) * interval + padX * 2; return columns * iconSize + (columns-1) * interval + padding.x * 2;
} }
int InventoryView::getHeight() const { int InventoryView::getHeight() const {
uint inv_rows = ceildiv(blocks.size(), invColumns); uint inv_rows = ceildiv(blocks.size(), columns);
return inv_rows * iconSize + (inv_rows-1) * interval + padY * 2; return inv_rows * iconSize + (inv_rows-1) * interval + padding.y * 2;
}
void InventoryView::setSlotConsumer(slotconsumer consumer) {
this->consumer = consumer;
} }
void InventoryView::actAndDraw(const GfxContext* ctx) { void InventoryView::actAndDraw(const GfxContext* ctx) {
Assets* assets = frontend->getAssets();
Shader* uiShader = assets->getShader("ui"); Shader* uiShader = assets->getShader("ui");
auto viewport = ctx->getViewport(); auto viewport = ctx->getViewport();
uint inv_w = getWidth(); uint inv_w = getWidth();
uint inv_h = getHeight(); uint inv_h = getHeight();
int xs = invX + padX; int xs = position.x + padding.x;
int ys = invY + padY; int ys = position.y + padding.y;
glm::vec4 tint (1.0f); glm::vec4 tint (1.0f);
int mx = Events::cursor.x; int mx = Events::cursor.x;
@ -62,15 +64,17 @@ void InventoryView::actAndDraw(const GfxContext* ctx) {
auto batch = ctx->getBatch2D(); auto batch = ctx->getBatch2D();
batch->texture(nullptr); batch->texture(nullptr);
batch->color = glm::vec4(0.0f, 0.0f, 0.0f, 0.5f); batch->color = glm::vec4(0.0f, 0.0f, 0.0f, 0.5f);
batch->rect(invX, invY, inv_w, inv_h); batch->rect(position.x, position.y, inv_w, inv_h);
batch->render(); batch->render();
// blocks & items // blocks & items
if (Events::scroll) { if (Events::scroll) {
inventoryScroll -= Events::scroll * (iconSize+interval); scroll -= Events::scroll * (iconSize+interval);
} }
inventoryScroll = std::min(inventoryScroll, int(inv_h-viewport.getHeight())); scroll = std::min(scroll, int(inv_h-viewport.getHeight()));
inventoryScroll = std::max(inventoryScroll, 0); scroll = std::max(scroll, 0);
auto blocksPreview = frontend->getBlocksPreview();
blocksPreview->begin(&ctx->getViewport()); blocksPreview->begin(&ctx->getViewport());
{ {
Window::clearDepth(); Window::clearDepth();
@ -80,8 +84,8 @@ void InventoryView::actAndDraw(const GfxContext* ctx) {
uint index = 0; uint index = 0;
for (uint i = 0; i < blocks.size(); i++) { for (uint i = 0; i < blocks.size(); i++) {
Block* cblock = indices->getBlockDef(blocks[i]); Block* cblock = indices->getBlockDef(blocks[i]);
int x = xs + (iconSize+interval) * (index % invColumns); int x = xs + (iconSize+interval) * (index % columns);
int y = ys + (iconSize+interval) * (index / invColumns) - inventoryScroll; int y = ys + (iconSize+interval) * (index / columns) - scroll;
if (y < -int(iconSize+interval) || y >= int(viewport.getHeight())) { if (y < -int(iconSize+interval) || y >= int(viewport.getHeight())) {
index++; index++;
continue; continue;
@ -91,7 +95,9 @@ void InventoryView::actAndDraw(const GfxContext* ctx) {
tint.g *= 1.2f; tint.g *= 1.2f;
tint.b *= 1.2f; tint.b *= 1.2f;
if (Events::jclicked(mousecode::BUTTON_1)) { if (Events::jclicked(mousecode::BUTTON_1)) {
player->chosenBlock = blocks[i]; if (consumer) {
consumer(blocks[i]);
}
} }
} else { } else {
tint = glm::vec4(1.0f); tint = glm::vec4(1.0f);

View File

@ -2,44 +2,45 @@
#define FRONTEND_INVENTORY_VIEW_H_ #define FRONTEND_INVENTORY_VIEW_H_
#include <vector> #include <vector>
#include <functional>
#include <glm/glm.hpp>
#include "../typedefs.h" #include "../typedefs.h"
class Player;
class Assets; class Assets;
class GfxContext; class GfxContext;
class ContentIndices; class ContentIndices;
class BlocksPreview; class LevelFrontend;
class ContentGfxCache;
typedef std::function<void(blockid_t)> slotconsumer;
class InventoryView { class InventoryView {
Player* player;
const Assets* assets;
const ContentIndices* indices; const ContentIndices* indices;
const ContentGfxCache* const cache;
std::vector<blockid_t> blocks; std::vector<blockid_t> blocks;
BlocksPreview* blocksPreview; slotconsumer consumer = nullptr;
LevelFrontend* frontend;
int inventoryScroll = 0; int scroll = 0;
int invColumns; int columns;
uint iconSize = 48; uint iconSize = 48;
uint interval = 4; uint interval = 4;
int padX = interval; glm::ivec2 padding {interval, interval};
int padY = interval; glm::ivec2 position {0, 0};
int invX = 0;
int invY = 0;
public: public:
InventoryView( InventoryView(
int columns, int columns,
Player* player,
const Assets* assets,
const ContentIndices* indices, const ContentIndices* indices,
const ContentGfxCache* cache, LevelFrontend* frontend,
std::vector<blockid_t> blocks); std::vector<blockid_t> blocks);
virtual ~InventoryView();
virtual void actAndDraw(const GfxContext* ctx);
void setPosition(int x, int y); void setPosition(int x, int y);
void actAndDraw(const GfxContext* ctx);
int getWidth() const; int getWidth() const;
int getHeight() const; int getHeight() const;
void setSlotConsumer(slotconsumer consumer);
}; };
#endif // FRONTEND_INVENTORY_VIEW_H_ #endif // FRONTEND_INVENTORY_VIEW_H_

View File

@ -0,0 +1,33 @@
#include "LevelFrontend.h"
#include "../world/Level.h"
#include "../assets/Assets.h"
#include "BlocksPreview.h"
#include "ContentGfxCache.h"
LevelFrontend::LevelFrontend(Level* level, Assets* assets)
: level(level),
assets(assets),
contentCache(std::make_unique<ContentGfxCache>(level->content, assets)),
blocksPreview(std::make_unique<BlocksPreview>(assets, contentCache.get())) {
}
LevelFrontend::~LevelFrontend() {
}
Level* LevelFrontend::getLevel() const {
return level;
}
Assets* LevelFrontend::getAssets() const {
return assets;
}
BlocksPreview* LevelFrontend::getBlocksPreview() const {
return blocksPreview.get();
}
ContentGfxCache* LevelFrontend::getContentGfxCache() const {
return contentCache.get();
}

View File

@ -0,0 +1,27 @@
#ifndef FRONTEND_LEVEL_FRONTEND_H_
#define FRONTEND_LEVEL_FRONTEND_H_
#include <memory>
class Level;
class Assets;
class BlocksPreview;
class ContentGfxCache;
class LevelFrontend {
Level* level;
Assets* assets;
std::unique_ptr<ContentGfxCache> contentCache;
std::unique_ptr<BlocksPreview> blocksPreview;
public:
LevelFrontend(Level* level, Assets* assets);
~LevelFrontend();
Level* getLevel() const;
Assets* getAssets() const;
BlocksPreview* getBlocksPreview() const;
ContentGfxCache* getContentGfxCache() const;
};
#endif // FRONTEND_LEVEL_FRONTEND_H_

View File

@ -27,7 +27,7 @@
#include "../maths/voxmaths.h" #include "../maths/voxmaths.h"
#include "../settings.h" #include "../settings.h"
#include "../engine.h" #include "../engine.h"
#include "ContentGfxCache.h" #include "LevelFrontend.h"
#include "graphics/Skybox.h" #include "graphics/Skybox.h"
using glm::vec3; using glm::vec3;
@ -36,14 +36,14 @@ using glm::mat4;
using std::string; using std::string;
using std::shared_ptr; using std::shared_ptr;
WorldRenderer::WorldRenderer(Engine* engine, WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend)
Level* level,
const ContentGfxCache* cache)
: engine(engine), : engine(engine),
level(level), level(frontend->getLevel()),
frustumCulling(new Frustum()), frustumCulling(new Frustum()),
lineBatch(new LineBatch()), lineBatch(new LineBatch()),
renderer( new ChunksRenderer(level, cache, engine->getSettings())) { renderer(new ChunksRenderer(level,
frontend->getContentGfxCache(),
engine->getSettings())) {
auto& settings = engine->getSettings(); auto& settings = engine->getSettings();
level->events->listen(EVT_CHUNK_HIDDEN, level->events->listen(EVT_CHUNK_HIDDEN,

View File

@ -21,7 +21,7 @@ class Texture;
class Frustum; class Frustum;
class Engine; class Engine;
class Chunks; class Chunks;
class ContentGfxCache; class LevelFrontend;
class Skybox; class Skybox;
class WorldRenderer { class WorldRenderer {
@ -34,7 +34,7 @@ class WorldRenderer {
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling); bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling);
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); void drawChunks(Chunks* chunks, Camera* camera, Shader* shader);
public: public:
WorldRenderer(Engine* engine, Level* level, const ContentGfxCache* cache); WorldRenderer(Engine* engine, LevelFrontend* frontend);
~WorldRenderer(); ~WorldRenderer();
void draw(const GfxContext& context, Camera* camera); void draw(const GfxContext& context, Camera* camera);

View File

@ -39,98 +39,66 @@
#include "WorldRenderer.h" #include "WorldRenderer.h"
#include "BlocksPreview.h" #include "BlocksPreview.h"
#include "InventoryView.h" #include "InventoryView.h"
#include "LevelFrontend.h"
#include "../engine.h" #include "../engine.h"
#include "../core_defs.h" #include "../core_defs.h"
using std::wstring;
using std::shared_ptr;
using glm::vec2; using glm::vec2;
using glm::vec3; using glm::vec3;
using glm::vec4; using glm::vec4;
using namespace gui; using namespace gui;
inline Label* create_label(gui::wstringsupplier supplier) { inline std::shared_ptr<Label> create_label(gui::wstringsupplier supplier) {
Label* label = new Label(L"-"); auto label = std::make_shared<Label>(L"-");
label->textSupplier(supplier); label->textSupplier(supplier);
return label; return label;
} }
HudRenderer::HudRenderer(Engine* engine, void HudRenderer::createDebugPanel(Engine* engine) {
Level* level, auto level = frontend->getLevel();
const ContentGfxCache* cache)
: level(level),
assets(engine->getAssets()),
gui(engine->getGUI()),
cache(cache) {
auto menu = gui->getMenu();
blocksPreview = new BlocksPreview(assets->getShader("ui3d"),
assets->getAtlas("blocks"),
cache);
auto content = level->content;
auto indices = content->indices;
std::vector<blockid_t> blocks;
for (blockid_t id = 1; id < indices->countBlockDefs(); id++) {
const Block* def = indices->getBlockDef(id);
if (def->hidden)
continue;
blocks.push_back(id);
}
contentAccess.reset(new InventoryView(
8,
level->player,
assets,
indices,
cache,
blocks));
uicamera = new Camera(vec3(), 1);
uicamera->perspective = false;
uicamera->flipped = true;
Panel* panel = new Panel(vec2(250, 200), vec4(5.0f), 1.0f); Panel* panel = new Panel(vec2(250, 200), vec4(5.0f), 1.0f);
debugPanel = shared_ptr<UINode>(panel); debugPanel = std::shared_ptr<UINode>(panel);
panel->listenInterval(1.0f, [this]() { panel->listenInterval(1.0f, [this]() {
fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin); fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin);
fpsMin = fps; fpsMin = fps;
fpsMax = fps; fpsMax = fps;
}); });
panel->setCoord(vec2(10, 10)); panel->setCoord(vec2(10, 10));
panel->add(shared_ptr<Label>(create_label([this](){ panel->add(create_label([this](){ return L"fps: "+this->fpsString;}));
return L"fps: "+this->fpsString; panel->add(create_label([this](){
})));
panel->add(shared_ptr<Label>(create_label([this](){
return L"meshes: " + std::to_wstring(Mesh::meshesCount); return L"meshes: " + std::to_wstring(Mesh::meshesCount);
}))); }));
panel->add(shared_ptr<Label>(create_label([=](){ panel->add(create_label([=](){
auto& settings = engine->getSettings(); auto& settings = engine->getSettings();
bool culling = settings.graphics.frustumCulling; bool culling = settings.graphics.frustumCulling;
return L"frustum-culling: "+wstring(culling ? L"on" : L"off"); return L"frustum-culling: "+std::wstring(culling ? L"on" : L"off");
}))); }));
panel->add(shared_ptr<Label>(create_label([this, level]() { panel->add(create_label([=]() {
return L"chunks: "+std::to_wstring(this->level->chunks->chunksCount)+ return L"chunks: "+std::to_wstring(level->chunks->chunksCount)+
L" visible: "+std::to_wstring(level->chunks->visible); L" visible: "+std::to_wstring(level->chunks->visible);
}))); }));
panel->add(shared_ptr<Label>(create_label([this](){ panel->add(create_label([=](){
auto player = this->level->player; auto player = level->player;
auto indices = this->level->content->indices; auto indices = level->content->indices;
auto def = indices->getBlockDef(player->selectedVoxel.id); auto def = indices->getBlockDef(player->selectedVoxel.id);
std::wstringstream stream; std::wstringstream stream;
stream << std::hex << this->level->player->selectedVoxel.states; stream << std::hex << level->player->selectedVoxel.states;
if (def) { if (def) {
stream << L" (" << util::str2wstr_utf8(def->name) << L")"; stream << L" (" << util::str2wstr_utf8(def->name) << L")";
} }
return L"block: "+std::to_wstring(player->selectedVoxel.id)+ return L"block: "+std::to_wstring(player->selectedVoxel.id)+
L" "+stream.str(); L" "+stream.str();
}))); }));
panel->add(shared_ptr<Label>(create_label([this](){ panel->add(create_label([=](){
return L"seed: "+std::to_wstring(this->level->world->seed); return L"seed: "+std::to_wstring(level->world->seed);
}))); }));
for (int ax = 0; ax < 3; ax++){ for (int ax = 0; ax < 3; ax++){
Panel* sub = new Panel(vec2(10, 27), vec4(0.0f)); Panel* sub = new Panel(vec2(10, 27), vec4(0.0f));
sub->orientation(Orientation::horizontal); sub->orientation(Orientation::horizontal);
wstring str = L"x: "; std::wstring str = L"x: ";
str[0] += ax; str[0] += ax;
Label* label = new Label(str); Label* label = new Label(str);
label->margin(vec4(2, 3, 2, 3)); label->margin(vec4(2, 3, 2, 3));
@ -139,15 +107,15 @@ HudRenderer::HudRenderer(Engine* engine,
// Coord input // Coord input
TextBox* box = new TextBox(L""); TextBox* box = new TextBox(L"");
box->textSupplier([this, ax]() { box->textSupplier([=]() {
Hitbox* hitbox = this->level->player->hitbox; Hitbox* hitbox = level->player->hitbox;
return std::to_wstring(hitbox->position[ax]); return std::to_wstring(hitbox->position[ax]);
}); });
box->textConsumer([this, ax](wstring text) { box->textConsumer([=](std::wstring text) {
try { try {
vec3 position = this->level->player->hitbox->position; vec3 position = level->player->hitbox->position;
position[ax] = std::stoi(text); position[ax] = std::stoi(text);
this->level->player->teleport(position); level->player->teleport(position);
} catch (std::invalid_argument& _){ } catch (std::invalid_argument& _){
} }
}); });
@ -155,15 +123,15 @@ HudRenderer::HudRenderer(Engine* engine,
sub->add(box); sub->add(box);
panel->add(sub); panel->add(sub);
} }
panel->add(shared_ptr<Label>(create_label([this](){ panel->add(create_label([=](){
int hour, minute, second; int hour, minute, second;
timeutil::from_value(this->level->world->daytime, hour, minute, second); timeutil::from_value(level->world->daytime, hour, minute, second);
std::wstring timeString = std::wstring timeString =
util::lfill(std::to_wstring(hour), 2, L'0') + L":" + util::lfill(std::to_wstring(hour), 2, L'0') + L":" +
util::lfill(std::to_wstring(minute), 2, L'0'); util::lfill(std::to_wstring(minute), 2, L'0');
return L"time: "+timeString; return L"time: "+timeString;
}))); }));
{ {
TrackBar* bar = new TrackBar(0.0f, 1.0f, 1.0f, 0.005f, 8); TrackBar* bar = new TrackBar(0.0f, 1.0f, 1.0f, 0.005f, 8);
bar->supplier([=]() { bar->supplier([=]() {
@ -203,6 +171,34 @@ HudRenderer::HudRenderer(Engine* engine,
panel->add(checkpanel); panel->add(checkpanel);
} }
panel->refresh(); panel->refresh();
}
HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend)
: assets(engine->getAssets()),
gui(engine->getGUI()),
frontend(frontend) {
auto level = frontend->getLevel();
auto menu = gui->getMenu();
auto content = level->content;
auto indices = content->indices;
std::vector<blockid_t> blocks;
for (blockid_t id = 1; id < indices->countBlockDefs(); id++) {
const Block* def = indices->getBlockDef(id);
if (def->hidden)
continue;
blocks.push_back(id);
}
contentAccess.reset(new InventoryView(8, indices, frontend, blocks));
contentAccess->setSlotConsumer([=](blockid_t id) {
level->player->chosenBlock = id;
});
uicamera = new Camera(vec3(), 1);
uicamera->perspective = false;
uicamera->flipped = true;
createDebugPanel(engine);
menu->reset(); menu->reset();
gui->add(this->debugPanel); gui->add(this->debugPanel);
@ -210,7 +206,6 @@ HudRenderer::HudRenderer(Engine* engine,
HudRenderer::~HudRenderer() { HudRenderer::~HudRenderer() {
gui->remove(debugPanel); gui->remove(debugPanel);
delete blocksPreview;
delete uicamera; delete uicamera;
} }
@ -247,6 +242,7 @@ void HudRenderer::update() {
} }
void HudRenderer::draw(const GfxContext& ctx){ void HudRenderer::draw(const GfxContext& ctx){
auto level = frontend->getLevel();
const Content* content = level->content; const Content* content = level->content;
const ContentIndices* contentIds = content->indices; const ContentIndices* contentIds = content->indices;
@ -274,14 +270,14 @@ void HudRenderer::draw(const GfxContext& ctx){
batch->line(width/2-5, height/2-5, width/2+5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f); batch->line(width/2-5, height/2-5, width/2+5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f);
batch->line(width/2+5, height/2-5, width/2-5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f); batch->line(width/2+5, height/2-5, width/2-5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f);
} }
Player* player = level->player; Player* player = level->player;
batch->color = vec4(0.0f, 0.0f, 0.0f, 0.75f); batch->color = vec4(0.0f, 0.0f, 0.0f, 0.75f);
batch->rect(width - 68, height - 68, 68, 68); batch->rect(width - 68, height - 68, 68, 68);
batch->color = vec4(1.0f); batch->color = vec4(1.0f);
batch->render(); batch->render();
auto blocksPreview = frontend->getBlocksPreview();
blocksPreview->begin(&ctx.getViewport()); blocksPreview->begin(&ctx.getViewport());
{ {
Window::clearDepth(); Window::clearDepth();

View File

@ -15,9 +15,8 @@ class Assets;
class Player; class Player;
class Level; class Level;
class Engine; class Engine;
class ContentGfxCache;
class BlocksPreview;
class InventoryView; class InventoryView;
class LevelFrontend;
namespace gui { namespace gui {
class GUI; class GUI;
@ -25,10 +24,8 @@ namespace gui {
} }
class HudRenderer { class HudRenderer {
Level* level;
Assets* assets; Assets* assets;
Camera* uicamera; Camera* uicamera;
BlocksPreview* blocksPreview;
int fps = 60; int fps = 60;
int fpsMin = 60; int fpsMin = 60;
@ -40,11 +37,11 @@ class HudRenderer {
std::unique_ptr<InventoryView> contentAccess; std::unique_ptr<InventoryView> contentAccess;
std::shared_ptr<gui::UINode> debugPanel; std::shared_ptr<gui::UINode> debugPanel;
gui::GUI* gui; gui::GUI* gui;
const ContentGfxCache* const cache; LevelFrontend* frontend;
void createDebugPanel(Engine* engine);
public: public:
HudRenderer(Engine* engine, HudRenderer(Engine* engine, LevelFrontend* frontend);
Level* level,
const ContentGfxCache* cache);
~HudRenderer(); ~HudRenderer();
void update(); void update();

View File

@ -28,6 +28,7 @@
#include "WorldRenderer.h" #include "WorldRenderer.h"
#include "hud.h" #include "hud.h"
#include "ContentGfxCache.h" #include "ContentGfxCache.h"
#include "LevelFrontend.h"
#include "gui/GUI.h" #include "gui/GUI.h"
#include "gui/panels.h" #include "gui/panels.h"
#include "menu.h" #include "menu.h"
@ -47,13 +48,12 @@ MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) {
menu->reset(); menu->reset();
menu->set("main"); menu->set("main");
uicamera = new Camera(glm::vec3(), Window::height); uicamera.reset(new Camera(glm::vec3(), Window::height));
uicamera->perspective = false; uicamera->perspective = false;
uicamera->flipped = true; uicamera->flipped = true;
} }
MenuScreen::~MenuScreen() { MenuScreen::~MenuScreen() {
delete uicamera;
} }
void MenuScreen::update(float delta) { void MenuScreen::update(float delta) {
@ -84,26 +84,20 @@ static bool backlight;
LevelScreen::LevelScreen(Engine* engine, Level* level) LevelScreen::LevelScreen(Engine* engine, Level* level)
: Screen(engine), : Screen(engine),
level(level) { level(level),
frontend(std::make_unique<LevelFrontend>(level, engine->getAssets())),
hud(std::make_unique<HudRenderer>(engine, frontend.get())),
worldRenderer(std::make_unique<WorldRenderer>(engine, frontend.get())),
controller(std::make_unique<LevelController>(engine->getSettings(), level)) {
auto& settings = engine->getSettings(); auto& settings = engine->getSettings();
controller = new LevelController(settings, level);
cache = new ContentGfxCache(level->content, engine->getAssets());
worldRenderer = new WorldRenderer(engine, level, cache);
hud = new HudRenderer(engine, level, cache);
backlight = settings.graphics.backlight; backlight = settings.graphics.backlight;
} }
LevelScreen::~LevelScreen() { LevelScreen::~LevelScreen() {
delete controller;
delete hud;
delete worldRenderer;
delete cache;
std::cout << "-- writing world" << std::endl; std::cout << "-- writing world" << std::endl;
World* world = level->world; World* world = level->world;
world->write(level); world->write(level.get());
delete level;
delete world; delete world;
} }

View File

@ -11,7 +11,7 @@ class HudRenderer;
class Engine; class Engine;
class Camera; class Camera;
class Batch2D; class Batch2D;
class ContentGfxCache; class LevelFrontend;
class LevelController; class LevelController;
/* Screen is a mainloop state */ /* Screen is a mainloop state */
@ -27,7 +27,7 @@ public:
}; };
class MenuScreen : public Screen { class MenuScreen : public Screen {
Camera* uicamera; std::unique_ptr<Camera> uicamera;
public: public:
MenuScreen(Engine* engine); MenuScreen(Engine* engine);
~MenuScreen(); ~MenuScreen();
@ -37,11 +37,11 @@ public:
}; };
class LevelScreen : public Screen { class LevelScreen : public Screen {
Level* level; std::unique_ptr<Level> level;
LevelController* controller; std::unique_ptr<LevelFrontend> frontend;
WorldRenderer* worldRenderer; std::unique_ptr<HudRenderer> hud;
HudRenderer* hud; std::unique_ptr<WorldRenderer> worldRenderer;
ContentGfxCache* cache; std::unique_ptr<LevelController> controller;
bool hudVisible = true; bool hudVisible = true;
void updateHotkeys(); void updateHotkeys();

View File

@ -9,6 +9,7 @@
#include "../../util/timeutil.h" #include "../../util/timeutil.h"
#include "../../world/Level.h" #include "../../world/Level.h"
#include "../../voxels/Block.h" #include "../../voxels/Block.h"
#include "../../content/ItemDef.h"
#include "api_lua.h" #include "api_lua.h"
using namespace scripting; using namespace scripting;
@ -131,6 +132,8 @@ void scripting::on_block_interact(Player* player, const Block* block, int x, int
call_func(L, 3, name); call_func(L, 3, name);
} }
// todo: refactor
void scripting::load_block_script(std::string prefix, fs::path file, block_funcs_set* funcsset) { void scripting::load_block_script(std::string prefix, fs::path file, block_funcs_set* funcsset) {
std::string src = files::read_string(file); std::string src = files::read_string(file);
std::cout << "loading script " << file.u8string() << std::endl; std::cout << "loading script " << file.u8string() << std::endl;
@ -147,6 +150,17 @@ void scripting::load_block_script(std::string prefix, fs::path file, block_funcs
funcsset->oninteract=rename_global(L, "on_interact", (prefix+".oninteract").c_str()); funcsset->oninteract=rename_global(L, "on_interact", (prefix+".oninteract").c_str());
} }
void scripting::load_item_script(std::string prefix, fs::path file, item_funcs_set* funcsset) {
std::string src = files::read_string(file);
std::cout << "loading script " << file.u8string() << std::endl;
if (luaL_loadbuffer(L, src.c_str(), src.size(), file.string().c_str())) {
std::cerr << "Lua error:" << lua_tostring(L,-1) << std::endl;
return;
}
call_func(L, 0, "<script>");
funcsset->init=rename_global(L, "init", (prefix+".init").c_str());
}
void scripting::close() { void scripting::close() {
lua_close(L); lua_close(L);

View File

@ -9,6 +9,7 @@ class Level;
class Block; class Block;
class Player; class Player;
struct block_funcs_set; struct block_funcs_set;
struct item_funcs_set;
namespace scripting { namespace scripting {
extern const Content* content; extern const Content* content;
@ -23,5 +24,6 @@ namespace scripting {
void on_block_broken(Player* player, const Block* block, int x, int y, int z); void on_block_broken(Player* player, const Block* block, int x, int y, int z);
void on_block_interact(Player* player, const Block* block, int x, int y, int z); void on_block_interact(Player* player, const Block* block, int x, int y, int z);
void load_block_script(std::string prefix, fs::path file, block_funcs_set* funcsset); void load_block_script(std::string prefix, fs::path file, block_funcs_set* funcsset);
void load_item_script(std::string prefix, fs::path file, item_funcs_set* funcsset);
void close(); void close();
} }

View File

@ -9,7 +9,10 @@ typedef unsigned int uint;
// use for bytes arrays // use for bytes arrays
typedef uint8_t ubyte; typedef uint8_t ubyte;
// content indices
typedef uint32_t itemid_t;
typedef uint16_t blockid_t; typedef uint16_t blockid_t;
typedef uint16_t blockstate_t; typedef uint16_t blockstate_t;
typedef uint16_t light_t; typedef uint16_t light_t;