ContentPackRuntime + refactor
This commit is contained in:
parent
54e6d49847
commit
241d15e349
@ -26,6 +26,7 @@ uniform float u_torchlightDistance;
|
||||
void main(){
|
||||
vec3 pos3d = (u_model * vec4(v_position, 1.0)).xyz-u_cameraPos.xyz;
|
||||
vec4 modelpos = u_model * vec4(v_position, 1.0);
|
||||
modelpos.y -= pow(length(pos3d.xz)*0.002, 3.0);
|
||||
vec4 viewmodelpos = u_view * modelpos;
|
||||
vec4 decomp_light = decompress_light(v_light);
|
||||
vec3 light = decomp_light.rgb;
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
#include "../voxels/Block.h"
|
||||
#include "../items/ItemDef.h"
|
||||
|
||||
#include "ContentPack.h"
|
||||
|
||||
ContentBuilder::~ContentBuilder() {
|
||||
}
|
||||
|
||||
@ -22,7 +24,11 @@ void ContentBuilder::add(ItemDef* def) {
|
||||
itemIds.push_back(def->name);
|
||||
}
|
||||
|
||||
Block* ContentBuilder::createBlock(std::string id) {
|
||||
void ContentBuilder::add(ContentPackRuntime* pack) {
|
||||
packs.push_back(std::unique_ptr<ContentPackRuntime>(pack));
|
||||
}
|
||||
|
||||
Block& ContentBuilder::createBlock(std::string id) {
|
||||
auto found = blockDefs.find(id);
|
||||
if (found != blockDefs.end()) {
|
||||
//return found->second;
|
||||
@ -30,20 +36,20 @@ Block* ContentBuilder::createBlock(std::string id) {
|
||||
}
|
||||
Block* block = new Block(id);
|
||||
add(block);
|
||||
return block;
|
||||
return *block;
|
||||
}
|
||||
|
||||
ItemDef* ContentBuilder::createItem(std::string id) {
|
||||
ItemDef& ContentBuilder::createItem(std::string id) {
|
||||
auto found = itemDefs.find(id);
|
||||
if (found != itemDefs.end()) {
|
||||
if (found->second->generated) {
|
||||
return found->second;
|
||||
return *found->second;
|
||||
}
|
||||
throw namereuse_error("name "+id+" is already used", contenttype::item);
|
||||
}
|
||||
ItemDef* item = new ItemDef(id);
|
||||
add(item);
|
||||
return item;
|
||||
return *item;
|
||||
}
|
||||
|
||||
void ContentBuilder::checkIdentifier(std::string id) {
|
||||
@ -65,7 +71,7 @@ contenttype ContentBuilder::checkContentType(std::string id) {
|
||||
|
||||
Content* ContentBuilder::build() {
|
||||
std::vector<Block*> blockDefsIndices;
|
||||
DrawGroups* groups = new DrawGroups;
|
||||
auto groups = std::make_unique<DrawGroups>();
|
||||
for (const std::string& name : blockIds) {
|
||||
Block* def = blockDefs[name];
|
||||
|
||||
@ -100,15 +106,18 @@ Content* ContentBuilder::build() {
|
||||
}
|
||||
|
||||
auto indices = new ContentIndices(blockDefsIndices, itemDefsIndices);
|
||||
std::unique_ptr<Content> content (new Content(indices, groups, blockDefs, itemDefs));
|
||||
|
||||
// Now, it's time to solve foreign keys
|
||||
auto content = std::make_unique<Content>(
|
||||
indices, std::move(groups), blockDefs, itemDefs, std::move(packs)
|
||||
);
|
||||
|
||||
// Now, it's time to resolve foreign keys
|
||||
for (Block* def : blockDefsIndices) {
|
||||
def->rt.pickingItem = content->requireItem(def->pickingItem)->rt.id;
|
||||
def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id;
|
||||
}
|
||||
|
||||
for (ItemDef* def : itemDefsIndices) {
|
||||
def->rt.placingBlock = content->requireBlock(def->placingBlock)->rt.id;
|
||||
def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id;
|
||||
}
|
||||
|
||||
return content.release();
|
||||
@ -121,17 +130,19 @@ ContentIndices::ContentIndices(
|
||||
itemDefs(itemDefs) {
|
||||
}
|
||||
|
||||
Content::Content(ContentIndices* indices, DrawGroups* drawGroups,
|
||||
Content::Content(ContentIndices* indices,
|
||||
std::unique_ptr<DrawGroups> drawGroups,
|
||||
std::unordered_map<std::string, Block*> blockDefs,
|
||||
std::unordered_map<std::string, ItemDef*> itemDefs)
|
||||
std::unordered_map<std::string, ItemDef*> itemDefs,
|
||||
std::vector<std::unique_ptr<ContentPackRuntime>> packs)
|
||||
: blockDefs(blockDefs),
|
||||
itemDefs(itemDefs),
|
||||
indices(indices),
|
||||
drawGroups(drawGroups) {
|
||||
packs(std::move(packs)),
|
||||
drawGroups(std::move(drawGroups)) {
|
||||
}
|
||||
|
||||
Content::~Content() {
|
||||
delete drawGroups;
|
||||
}
|
||||
|
||||
Block* Content::findBlock(std::string id) const {
|
||||
@ -142,12 +153,12 @@ Block* Content::findBlock(std::string id) const {
|
||||
return found->second;
|
||||
}
|
||||
|
||||
Block* Content::requireBlock(std::string id) const {
|
||||
Block& Content::requireBlock(std::string id) const {
|
||||
auto found = blockDefs.find(id);
|
||||
if (found == blockDefs.end()) {
|
||||
throw std::runtime_error("missing block "+id);
|
||||
}
|
||||
return found->second;
|
||||
return *found->second;
|
||||
}
|
||||
|
||||
ItemDef* Content::findItem(std::string id) const {
|
||||
@ -158,10 +169,14 @@ ItemDef* Content::findItem(std::string id) const {
|
||||
return found->second;
|
||||
}
|
||||
|
||||
ItemDef* Content::requireItem(std::string id) const {
|
||||
ItemDef& Content::requireItem(std::string id) const {
|
||||
auto found = itemDefs.find(id);
|
||||
if (found == itemDefs.end()) {
|
||||
throw std::runtime_error("missing item "+id);
|
||||
}
|
||||
return found->second;
|
||||
return *found->second;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<ContentPackRuntime>>& Content::getPacks() const {
|
||||
return packs;
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ using DrawGroups = std::set<unsigned char>;
|
||||
class Block;
|
||||
class ItemDef;
|
||||
class Content;
|
||||
class ContentPackRuntime;
|
||||
|
||||
enum class contenttype {
|
||||
none, block, item
|
||||
@ -46,14 +47,17 @@ class ContentBuilder {
|
||||
|
||||
std::unordered_map<std::string, ItemDef*> itemDefs;
|
||||
std::vector<std::string> itemIds;
|
||||
|
||||
std::vector<std::unique_ptr<ContentPackRuntime>> packs;
|
||||
public:
|
||||
~ContentBuilder();
|
||||
|
||||
void add(Block* def);
|
||||
void add(ItemDef* def);
|
||||
void add(ContentPackRuntime* pack);
|
||||
|
||||
Block* createBlock(std::string id);
|
||||
ItemDef* createItem(std::string id);
|
||||
Block& createBlock(std::string id);
|
||||
ItemDef& createItem(std::string id);
|
||||
|
||||
void checkIdentifier(std::string id);
|
||||
contenttype checkContentType(std::string id);
|
||||
@ -104,12 +108,15 @@ class Content {
|
||||
std::unordered_map<std::string, Block*> blockDefs;
|
||||
std::unordered_map<std::string, ItemDef*> itemDefs;
|
||||
std::unique_ptr<ContentIndices> indices;
|
||||
std::vector<std::unique_ptr<ContentPackRuntime>> packs;
|
||||
public:
|
||||
DrawGroups* const drawGroups;
|
||||
std::unique_ptr<DrawGroups> const drawGroups;
|
||||
|
||||
Content(ContentIndices* indices, DrawGroups* drawGroups,
|
||||
Content(ContentIndices* indices,
|
||||
std::unique_ptr<DrawGroups> drawGroups,
|
||||
std::unordered_map<std::string, Block*> blockDefs,
|
||||
std::unordered_map<std::string, ItemDef*> itemDefs);
|
||||
std::unordered_map<std::string, ItemDef*> itemDefs,
|
||||
std::vector<std::unique_ptr<ContentPackRuntime>> packs);
|
||||
~Content();
|
||||
|
||||
inline ContentIndices* getIndices() const {
|
||||
@ -117,10 +124,12 @@ public:
|
||||
}
|
||||
|
||||
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;
|
||||
ItemDef& requireItem(std::string id) const;
|
||||
|
||||
const std::vector<std::unique_ptr<ContentPackRuntime>>& getPacks() const;
|
||||
};
|
||||
|
||||
#endif // CONTENT_CONTENT_H_
|
||||
@ -92,7 +92,7 @@ void ContentLoader::fixPackIndices() {
|
||||
}
|
||||
|
||||
// TODO: add basic validation and logging
|
||||
void ContentLoader::loadBlock(Block* def, std::string name, fs::path file) {
|
||||
void ContentLoader::loadBlock(Block& def, std::string name, fs::path file) {
|
||||
auto root = files::read_json(file);
|
||||
|
||||
// block texturing
|
||||
@ -100,22 +100,22 @@ void ContentLoader::loadBlock(Block* def, std::string name, fs::path file) {
|
||||
std::string texture;
|
||||
root->str("texture", texture);
|
||||
for (uint i = 0; i < 6; i++) {
|
||||
def->textureFaces[i] = texture;
|
||||
def.textureFaces[i] = texture;
|
||||
}
|
||||
} else if (root->has("texture-faces")) {
|
||||
auto texarr = root->list("texture-faces");
|
||||
for (uint i = 0; i < 6; i++) {
|
||||
def->textureFaces[i] = texarr->str(i);
|
||||
def.textureFaces[i] = texarr->str(i);
|
||||
}
|
||||
}
|
||||
|
||||
// block model
|
||||
std::string model = "block";
|
||||
root->str("model", model);
|
||||
if (model == "block") def->model = BlockModel::block;
|
||||
else if (model == "aabb") def->model = BlockModel::aabb;
|
||||
if (model == "block") def.model = BlockModel::block;
|
||||
else if (model == "aabb") def.model = BlockModel::aabb;
|
||||
else if (model == "custom") {
|
||||
def->model = BlockModel::custom;
|
||||
def.model = BlockModel::custom;
|
||||
if (root->has("model-primitives")) {
|
||||
loadCustomBlockModel(def, root->map("model-primitives"));
|
||||
}
|
||||
@ -124,30 +124,30 @@ void ContentLoader::loadBlock(Block* def, std::string name, fs::path file) {
|
||||
<< name << " parsed: no \"model-primitives\" found" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (model == "X") def->model = BlockModel::xsprite;
|
||||
else if (model == "none") def->model = BlockModel::none;
|
||||
else if (model == "X") def.model = BlockModel::xsprite;
|
||||
else if (model == "none") def.model = BlockModel::none;
|
||||
else {
|
||||
std::cerr << "unknown model " << model << std::endl;
|
||||
def->model = BlockModel::none;
|
||||
def.model = BlockModel::none;
|
||||
}
|
||||
|
||||
// rotation profile
|
||||
std::string profile = "none";
|
||||
root->str("rotation", profile);
|
||||
def->rotatable = profile != "none";
|
||||
def.rotatable = profile != "none";
|
||||
if (profile == "pipe") {
|
||||
def->rotations = BlockRotProfile::PIPE;
|
||||
def.rotations = BlockRotProfile::PIPE;
|
||||
} else if (profile == "pane") {
|
||||
def->rotations = BlockRotProfile::PANE;
|
||||
def.rotations = BlockRotProfile::PANE;
|
||||
} else if (profile != "none") {
|
||||
std::cerr << "unknown rotation profile " << profile << std::endl;
|
||||
def->rotatable = false;
|
||||
def.rotatable = false;
|
||||
}
|
||||
|
||||
// block hitbox AABB [x, y, z, width, height, depth]
|
||||
auto boxarr = root->list("hitbox");
|
||||
if (boxarr) {
|
||||
AABB& aabb = def->hitbox;
|
||||
AABB& aabb = def.hitbox;
|
||||
aabb.a = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2));
|
||||
aabb.b = glm::vec3(boxarr->num(3), boxarr->num(4), boxarr->num(5));
|
||||
aabb.b += aabb.a;
|
||||
@ -156,27 +156,27 @@ void ContentLoader::loadBlock(Block* def, std::string name, fs::path file) {
|
||||
// block light emission [r, g, b] where r,g,b in range [0..15]
|
||||
auto emissionarr = root->list("emission");
|
||||
if (emissionarr) {
|
||||
def->emission[0] = emissionarr->num(0);
|
||||
def->emission[1] = emissionarr->num(1);
|
||||
def->emission[2] = emissionarr->num(2);
|
||||
def.emission[0] = emissionarr->num(0);
|
||||
def.emission[1] = emissionarr->num(1);
|
||||
def.emission[2] = emissionarr->num(2);
|
||||
}
|
||||
|
||||
// primitive properties
|
||||
root->flag("obstacle", def->obstacle);
|
||||
root->flag("replaceable", def->replaceable);
|
||||
root->flag("light-passing", def->lightPassing);
|
||||
root->flag("breakable", def->breakable);
|
||||
root->flag("selectable", def->selectable);
|
||||
root->flag("grounded", def->grounded);
|
||||
root->flag("hidden", def->hidden);
|
||||
root->flag("sky-light-passing", def->skyLightPassing);
|
||||
root->num("draw-group", def->drawGroup);
|
||||
root->str("picking-item", def->pickingItem);
|
||||
root->str("script-name", def->scriptName);
|
||||
root->num("inventory-size", def->inventorySize);
|
||||
root->flag("obstacle", def.obstacle);
|
||||
root->flag("replaceable", def.replaceable);
|
||||
root->flag("light-passing", def.lightPassing);
|
||||
root->flag("breakable", def.breakable);
|
||||
root->flag("selectable", def.selectable);
|
||||
root->flag("grounded", def.grounded);
|
||||
root->flag("hidden", def.hidden);
|
||||
root->flag("sky-light-passing", def.skyLightPassing);
|
||||
root->num("draw-group", def.drawGroup);
|
||||
root->str("picking-item", def.pickingItem);
|
||||
root->str("script-name", def.scriptName);
|
||||
root->num("inventory-size", def.inventorySize);
|
||||
}
|
||||
|
||||
void ContentLoader::loadCustomBlockModel(Block* def, dynamic::Map* primitives) {
|
||||
void ContentLoader::loadCustomBlockModel(Block& def, dynamic::Map* primitives) {
|
||||
if (primitives->has("aabbs")) {
|
||||
auto modelboxes = primitives->list("aabbs");
|
||||
for (uint i = 0; i < modelboxes->size(); i++ ) {
|
||||
@ -186,19 +186,19 @@ void ContentLoader::loadCustomBlockModel(Block* def, dynamic::Map* primitives) {
|
||||
modelbox.a = glm::vec3(boxarr->num(0), boxarr->num(1), boxarr->num(2));
|
||||
modelbox.b = glm::vec3(boxarr->num(3), boxarr->num(4), boxarr->num(5));
|
||||
modelbox.b += modelbox.a;
|
||||
def->modelBoxes.push_back(modelbox);
|
||||
def.modelBoxes.push_back(modelbox);
|
||||
|
||||
if (boxarr->size() == 7)
|
||||
for (uint i = 6; i < 12; i++) {
|
||||
def->modelTextures.push_back(boxarr->str(6));
|
||||
def.modelTextures.push_back(boxarr->str(6));
|
||||
}
|
||||
else if (boxarr->size() == 12)
|
||||
for (uint i = 6; i < 12; i++) {
|
||||
def->modelTextures.push_back(boxarr->str(i));
|
||||
def.modelTextures.push_back(boxarr->str(i));
|
||||
}
|
||||
else
|
||||
for (uint i = 6; i < 12; i++) {
|
||||
def->modelTextures.push_back("notfound");
|
||||
def.modelTextures.push_back("notfound");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,69 +210,70 @@ void ContentLoader::loadCustomBlockModel(Block* def, dynamic::Map* primitives) {
|
||||
glm::vec3 p1(tgonobj->num(0), tgonobj->num(1), tgonobj->num(2)),
|
||||
xw(tgonobj->num(3), tgonobj->num(4), tgonobj->num(5)),
|
||||
yh(tgonobj->num(6), tgonobj->num(7), tgonobj->num(8));
|
||||
def->modelExtraPoints.push_back(p1);
|
||||
def->modelExtraPoints.push_back(p1+xw);
|
||||
def->modelExtraPoints.push_back(p1+xw+yh);
|
||||
def->modelExtraPoints.push_back(p1+yh);
|
||||
def.modelExtraPoints.push_back(p1);
|
||||
def.modelExtraPoints.push_back(p1+xw);
|
||||
def.modelExtraPoints.push_back(p1+xw+yh);
|
||||
def.modelExtraPoints.push_back(p1+yh);
|
||||
|
||||
def->modelTextures.push_back(tgonobj->str(9));
|
||||
def.modelTextures.push_back(tgonobj->str(9));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::loadItem(ItemDef* def, std::string name, fs::path file) {
|
||||
void ContentLoader::loadItem(ItemDef& def, std::string name, fs::path file) {
|
||||
auto root = files::read_json(file);
|
||||
std::string iconTypeStr = "";
|
||||
root->str("icon-type", iconTypeStr);
|
||||
if (iconTypeStr == "none") {
|
||||
def->iconType = item_icon_type::none;
|
||||
def.iconType = item_icon_type::none;
|
||||
} else if (iconTypeStr == "block") {
|
||||
def->iconType = item_icon_type::block;
|
||||
def.iconType = item_icon_type::block;
|
||||
} else if (iconTypeStr == "sprite") {
|
||||
def->iconType = item_icon_type::sprite;
|
||||
def.iconType = item_icon_type::sprite;
|
||||
} else if (iconTypeStr.length()){
|
||||
std::cerr << "unknown icon type" << iconTypeStr << std::endl;
|
||||
}
|
||||
root->str("icon", def->icon);
|
||||
root->str("placing-block", def->placingBlock);
|
||||
root->str("script-name", def->scriptName);
|
||||
root->num("stack-size", def->stackSize);
|
||||
root->str("icon", def.icon);
|
||||
root->str("placing-block", def.placingBlock);
|
||||
root->str("script-name", def.scriptName);
|
||||
root->num("stack-size", def.stackSize);
|
||||
|
||||
// item light emission [r, g, b] where r,g,b in range [0..15]
|
||||
auto emissionarr = root->list("emission");
|
||||
if (emissionarr) {
|
||||
def->emission[0] = emissionarr->num(0);
|
||||
def->emission[1] = emissionarr->num(1);
|
||||
def->emission[2] = emissionarr->num(2);
|
||||
def.emission[0] = emissionarr->num(0);
|
||||
def.emission[1] = emissionarr->num(1);
|
||||
def.emission[2] = emissionarr->num(2);
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::loadBlock(Block* def, std::string full, std::string name) {
|
||||
void ContentLoader::loadBlock(Block& def, std::string full, std::string name) {
|
||||
auto folder = pack->folder;
|
||||
|
||||
fs::path configFile = folder/fs::path("blocks/"+name+".json");
|
||||
loadBlock(def, full, configFile);
|
||||
|
||||
fs::path scriptfile = folder/fs::path("scripts/"+def->scriptName+".lua");
|
||||
fs::path scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua");
|
||||
if (fs::is_regular_file(scriptfile)) {
|
||||
scripting::load_block_script(full, scriptfile, def->rt.funcsset);
|
||||
scripting::load_block_script(full, scriptfile, def.rt.funcsset);
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::loadItem(ItemDef* def, std::string full, std::string name) {
|
||||
void ContentLoader::loadItem(ItemDef& def, std::string full, std::string name) {
|
||||
auto folder = pack->folder;
|
||||
|
||||
fs::path configFile = folder/fs::path("items/"+name+".json");
|
||||
loadItem(def, full, configFile);
|
||||
|
||||
fs::path scriptfile = folder/fs::path("scripts/"+def->scriptName+".lua");
|
||||
fs::path scriptfile = folder/fs::path("scripts/"+def.scriptName+".lua");
|
||||
if (fs::is_regular_file(scriptfile)) {
|
||||
scripting::load_item_script(full, scriptfile, def->rt.funcsset);
|
||||
scripting::load_item_script(full, scriptfile, def.rt.funcsset);
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::load(ContentBuilder* builder) {
|
||||
void ContentLoader::load(ContentBuilder& builder) {
|
||||
std::cout << "-- loading pack [" << pack->id << "]" << std::endl;
|
||||
builder.add(new ContentPackRuntime(*pack));
|
||||
|
||||
fixPackIndices();
|
||||
|
||||
@ -291,17 +292,17 @@ void ContentLoader::load(ContentBuilder* builder) {
|
||||
for (uint i = 0; i < blocksarr->size(); i++) {
|
||||
std::string name = blocksarr->str(i);
|
||||
std::string full = pack->id+":"+name;
|
||||
auto def = builder->createBlock(full);
|
||||
auto& def = builder.createBlock(full);
|
||||
loadBlock(def, full, name);
|
||||
if (!def->hidden) {
|
||||
auto item = builder->createItem(full+BLOCK_ITEM_SUFFIX);
|
||||
item->generated = true;
|
||||
item->iconType = item_icon_type::block;
|
||||
item->icon = full;
|
||||
item->placingBlock = full;
|
||||
if (!def.hidden) {
|
||||
auto& item = builder.createItem(full+BLOCK_ITEM_SUFFIX);
|
||||
item.generated = true;
|
||||
item.iconType = item_icon_type::block;
|
||||
item.icon = full;
|
||||
item.placingBlock = full;
|
||||
|
||||
for (uint j = 0; j < 4; j++) {
|
||||
item->emission[j] = def->emission[j];
|
||||
item.emission[j] = def.emission[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,7 +313,7 @@ void ContentLoader::load(ContentBuilder* builder) {
|
||||
for (uint i = 0; i < itemsarr->size(); i++) {
|
||||
std::string name = itemsarr->str(i);
|
||||
std::string full = pack->id+":"+name;
|
||||
loadItem(builder->createItem(full), full, name);
|
||||
loadItem(builder.createItem(full), full, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,9 +18,9 @@ namespace dynamic {
|
||||
class ContentLoader {
|
||||
const ContentPack* pack;
|
||||
|
||||
void loadBlock(Block* def, std::string full, std::string name);
|
||||
void loadCustomBlockModel(Block* def, dynamic::Map* primitives);
|
||||
void loadItem(ItemDef* def, std::string full, std::string name);
|
||||
void loadBlock(Block& def, std::string full, std::string name);
|
||||
void loadCustomBlockModel(Block& def, dynamic::Map* primitives);
|
||||
void loadItem(ItemDef& def, std::string full, std::string name);
|
||||
public:
|
||||
ContentLoader(ContentPack* pack);
|
||||
|
||||
@ -28,9 +28,9 @@ public:
|
||||
dynamic::Map* indicesRoot,
|
||||
std::string contentSection);
|
||||
void fixPackIndices();
|
||||
void loadBlock(Block* def, std::string name, fs::path file);
|
||||
void loadItem(ItemDef* def, std::string name, fs::path file);
|
||||
void load(ContentBuilder* builder);
|
||||
void loadBlock(Block& def, std::string name, fs::path file);
|
||||
void loadItem(ItemDef& def, std::string name, fs::path file);
|
||||
void load(ContentBuilder& builder);
|
||||
};
|
||||
|
||||
#endif // CONTENT_CONTENT_LOADER_H_
|
||||
|
||||
@ -149,3 +149,6 @@ void ContentPack::readPacks(const EnginePaths* paths,
|
||||
packs.push_back(ContentPack::read(packfolder));
|
||||
}
|
||||
}
|
||||
|
||||
ContentPackRuntime::ContentPackRuntime(ContentPack info) : info(info) {
|
||||
}
|
||||
|
||||
@ -8,16 +8,18 @@
|
||||
|
||||
class EnginePaths;
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
class contentpack_error : public std::runtime_error {
|
||||
std::string packId;
|
||||
std::filesystem::path folder;
|
||||
fs::path folder;
|
||||
public:
|
||||
contentpack_error(std::string packId,
|
||||
std::filesystem::path folder,
|
||||
fs::path folder,
|
||||
std::string message);
|
||||
|
||||
std::string getPackId() const;
|
||||
std::filesystem::path getFolder() const;
|
||||
fs::path getFolder() const;
|
||||
};
|
||||
|
||||
struct ContentPack {
|
||||
@ -26,35 +28,45 @@ struct ContentPack {
|
||||
std::string version = "0.0";
|
||||
std::string creator = "";
|
||||
std::string description = "no description";
|
||||
std::filesystem::path folder;
|
||||
fs::path folder;
|
||||
std::vector<std::string> dependencies;
|
||||
|
||||
std::filesystem::path getContentFile() const;
|
||||
fs::path getContentFile() const;
|
||||
|
||||
static const std::string PACKAGE_FILENAME;
|
||||
static const std::string CONTENT_FILENAME;
|
||||
static const std::filesystem::path BLOCKS_FOLDER;
|
||||
static const std::filesystem::path ITEMS_FOLDER;
|
||||
static const fs::path BLOCKS_FOLDER;
|
||||
static const fs::path ITEMS_FOLDER;
|
||||
static const std::vector<std::string> RESERVED_NAMES;
|
||||
|
||||
static bool is_pack(std::filesystem::path folder);
|
||||
static ContentPack read(std::filesystem::path folder);
|
||||
static bool is_pack(fs::path folder);
|
||||
static ContentPack read(fs::path folder);
|
||||
|
||||
static void scan(std::filesystem::path folder,
|
||||
static void scan(fs::path folder,
|
||||
std::vector<ContentPack>& packs);
|
||||
static void scan(EnginePaths* paths,
|
||||
std::vector<ContentPack>& packs);
|
||||
|
||||
static std::vector<std::string> worldPacksList(std::filesystem::path folder);
|
||||
static std::vector<std::string> worldPacksList(fs::path folder);
|
||||
|
||||
static std::filesystem::path findPack(
|
||||
static fs::path findPack(
|
||||
const EnginePaths* paths,
|
||||
std::filesystem::path worldDir,
|
||||
fs::path worldDir,
|
||||
std::string name);
|
||||
static void readPacks(const EnginePaths* paths,
|
||||
std::vector<ContentPack>& packs,
|
||||
const std::vector<std::string>& names,
|
||||
std::filesystem::path worldDir);
|
||||
fs::path worldDir);
|
||||
};
|
||||
|
||||
class ContentPackRuntime {
|
||||
ContentPack info;
|
||||
public:
|
||||
ContentPackRuntime(ContentPack info);
|
||||
|
||||
inline const std::string& getId() {
|
||||
return info.id;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CONTENT_CONTENT_PACK_H_
|
||||
|
||||
@ -9,18 +9,18 @@
|
||||
|
||||
// All in-game definitions (blocks, items, etc..)
|
||||
void corecontent::setup(ContentBuilder* builder) {
|
||||
Block* block = builder->createBlock("core:air");
|
||||
block->replaceable = true;
|
||||
block->drawGroup = 1;
|
||||
block->lightPassing = true;
|
||||
block->skyLightPassing = true;
|
||||
block->obstacle = false;
|
||||
block->selectable = false;
|
||||
block->model = BlockModel::none;
|
||||
block->pickingItem = "core:empty";
|
||||
Block& block = builder->createBlock("core:air");
|
||||
block.replaceable = true;
|
||||
block.drawGroup = 1;
|
||||
block.lightPassing = true;
|
||||
block.skyLightPassing = true;
|
||||
block.obstacle = false;
|
||||
block.selectable = false;
|
||||
block.model = BlockModel::none;
|
||||
block.pickingItem = "core:empty";
|
||||
|
||||
ItemDef* item = builder->createItem("core:empty");
|
||||
item->iconType = item_icon_type::none;
|
||||
ItemDef& item = builder->createItem("core:empty");
|
||||
item.iconType = item_icon_type::none;
|
||||
}
|
||||
|
||||
void corecontent::setup_bindings() {
|
||||
|
||||
@ -169,7 +169,7 @@ void Engine::loadContent() {
|
||||
resRoots.push_back(pack.folder);
|
||||
contentPacks.push_back(pack);
|
||||
ContentLoader loader(&pack);
|
||||
loader.load(&contentBuilder);
|
||||
loader.load(contentBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,36 +6,34 @@
|
||||
#include "../content/Content.h"
|
||||
#include "../graphics/Atlas.h"
|
||||
#include "../voxels/Block.h"
|
||||
#include "../core_defs.h"
|
||||
#include "UiDocument.h"
|
||||
|
||||
ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) {
|
||||
ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) {
|
||||
auto indices = content->getIndices();
|
||||
sideregions = new UVRegion[indices->countBlockDefs() * 6];
|
||||
Atlas* atlas = assets->getAtlas("blocks");
|
||||
|
||||
for (uint i = 0; i < indices->countBlockDefs(); i++) {
|
||||
Block* def = indices->getBlockDef(i);
|
||||
for (uint side = 0; side < 6; side++) {
|
||||
std::string tex = def->textureFaces[side];
|
||||
if (atlas->has(tex)) {
|
||||
sideregions[i * 6 + side] = atlas->get(tex);
|
||||
} else {
|
||||
if (atlas->has("notfound"))
|
||||
sideregions[i * 6 + side] = atlas->get("notfound");
|
||||
}
|
||||
}
|
||||
for (uint side = 0; side < def->modelTextures.size(); side++)
|
||||
{
|
||||
std::string tex = def->modelTextures[side];
|
||||
if (atlas->has(tex)) {
|
||||
def->modelUVs.push_back(atlas->get(tex));
|
||||
} else {
|
||||
if (atlas->has("notfound"))
|
||||
def->modelUVs.push_back(atlas->get("notfound"));
|
||||
}
|
||||
}
|
||||
sideregions = std::make_unique<UVRegion[]>(indices->countBlockDefs() * 6);
|
||||
Atlas* atlas = assets->getAtlas("blocks");
|
||||
|
||||
for (uint i = 0; i < indices->countBlockDefs(); i++) {
|
||||
Block* def = indices->getBlockDef(i);
|
||||
for (uint side = 0; side < 6; side++) {
|
||||
const std::string& tex = def->textureFaces[side];
|
||||
if (atlas->has(tex)) {
|
||||
sideregions[i * 6 + side] = atlas->get(tex);
|
||||
} else if (atlas->has(TEXTURE_NOTFOUND)) {
|
||||
sideregions[i * 6 + side] = atlas->get(TEXTURE_NOTFOUND);
|
||||
}
|
||||
}
|
||||
for (uint side = 0; side < def->modelTextures.size(); side++) {
|
||||
const std::string& tex = def->modelTextures[side];
|
||||
if (atlas->has(tex)) {
|
||||
def->modelUVs.push_back(atlas->get(tex));
|
||||
} else if (atlas->has(TEXTURE_NOTFOUND)) {
|
||||
def->modelUVs.push_back(atlas->get(TEXTURE_NOTFOUND));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentGfxCache::~ContentGfxCache() {
|
||||
delete[] sideregions;
|
||||
}
|
||||
|
||||
@ -1,15 +1,24 @@
|
||||
#ifndef FRONTEND_BLOCKS_GFX_CACHE_H_
|
||||
#define FRONTEND_BLOCKS_GFX_CACHE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "../graphics/UVRegion.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
class Content;
|
||||
class Assets;
|
||||
class UiDocument;
|
||||
|
||||
using uidocuments_map = std::unordered_map<std::string, std::shared_ptr<UiDocument>>;
|
||||
|
||||
class ContentGfxCache {
|
||||
const Content* content;
|
||||
// array of block sides uv regions (6 per block)
|
||||
UVRegion* sideregions;
|
||||
std::unique_ptr<UVRegion[]> sideregions;
|
||||
// all loaded layouts
|
||||
uidocuments_map layouts;
|
||||
public:
|
||||
ContentGfxCache(const Content* content, Assets* assets);
|
||||
~ContentGfxCache();
|
||||
@ -17,6 +26,8 @@ public:
|
||||
inline const UVRegion& getRegion(blockid_t id, int side) const {
|
||||
return sideregions[id * 6 + side];
|
||||
}
|
||||
|
||||
std::shared_ptr<UiDocument> getLayout(const std::string& id);
|
||||
};
|
||||
|
||||
#endif // FRONTEND_BLOCKS_GFX_CACHE_H_
|
||||
|
||||
@ -150,10 +150,10 @@ void SlotView::draw(const GfxContext* pctx, Assets* assets) {
|
||||
case item_icon_type::none:
|
||||
break;
|
||||
case item_icon_type::block: {
|
||||
Block* cblock = content->requireBlock(item->icon);
|
||||
const Block& cblock = content->requireBlock(item->icon);
|
||||
batch->texture(previews->getTexture());
|
||||
|
||||
UVRegion region = previews->get(cblock->name);
|
||||
UVRegion region = previews->get(cblock.name);
|
||||
batch->rect(
|
||||
coord.x, coord.y, slotSize, slotSize,
|
||||
0, 0, 0, region, false, true, tint);
|
||||
|
||||
@ -40,6 +40,7 @@ public:
|
||||
} rt;
|
||||
|
||||
ItemDef(std::string name);
|
||||
ItemDef(const ItemDef&) = delete;
|
||||
};
|
||||
|
||||
#endif //CONTENT_ITEMS_ITEM_DEF_H_
|
||||
|
||||
@ -46,6 +46,10 @@ int Clock::getTickRate() const {
|
||||
return tickRate;
|
||||
}
|
||||
|
||||
int Clock::getTickId() const {
|
||||
return tickId;
|
||||
}
|
||||
|
||||
BlocksController::BlocksController(Level* level, uint padding)
|
||||
: level(level),
|
||||
chunks(level->chunks),
|
||||
|
||||
@ -25,6 +25,7 @@ public:
|
||||
int getParts() const;
|
||||
int getPart() const;
|
||||
int getTickRate() const;
|
||||
int getTickId() const;
|
||||
};
|
||||
|
||||
class BlocksController {
|
||||
|
||||
@ -245,7 +245,7 @@ static int l_blocks_count(lua_State* L) {
|
||||
|
||||
static int l_block_index(lua_State* L) {
|
||||
auto name = lua_tostring(L, 1);
|
||||
lua_pushinteger(L, scripting::content->requireBlock(name)->rt.id);
|
||||
lua_pushinteger(L, scripting::content->requireBlock(name).rt.id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -110,6 +110,7 @@ public:
|
||||
|
||||
Block(std::string name);
|
||||
Block(std::string name, std::string texture);
|
||||
Block(const Block&) = delete;
|
||||
};
|
||||
|
||||
#endif /* VOXELS_BLOCK_H_ */
|
||||
|
||||
@ -93,7 +93,7 @@ ubyte* Chunk::encode() const {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool Chunk::decode(ubyte* data) {
|
||||
bool Chunk::decode(const ubyte* data) {
|
||||
for (uint i = 0; i < CHUNK_VOL; i++) {
|
||||
voxel& vox = voxels[i];
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ struct ChunkFlag {
|
||||
static const int UNSAVED = 0x10;
|
||||
static const int LOADED_LIGHTS = 0x20;
|
||||
};
|
||||
#define CHUNK_DATA_LEN (CHUNK_VOL*4)
|
||||
constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4;
|
||||
|
||||
class Lightmap;
|
||||
class ContentLUT;
|
||||
@ -88,7 +88,7 @@ public:
|
||||
/**
|
||||
* @return true if all is fine
|
||||
**/
|
||||
bool decode(ubyte* data);
|
||||
bool decode(const ubyte* data);
|
||||
|
||||
static void convert(ubyte* data, const ContentLUT* lut);
|
||||
};
|
||||
|
||||
@ -21,8 +21,7 @@ Chunks::Chunks(int w, int d,
|
||||
WorldFiles* wfile,
|
||||
LevelEvents* events,
|
||||
const Content* content)
|
||||
: content(content),
|
||||
contentIds(content->getIndices()),
|
||||
: contentIds(content->getIndices()),
|
||||
chunks(w*d),
|
||||
chunksSecond(w*d),
|
||||
w(w), d(d), ox(ox), oz(oz),
|
||||
|
||||
@ -19,7 +19,6 @@ class LevelEvents;
|
||||
|
||||
/* Player-centred chunks matrix */
|
||||
class Chunks {
|
||||
const Content* const content;
|
||||
const ContentIndices* const contentIds;
|
||||
public:
|
||||
std::vector<std::shared_ptr<Chunk>> chunks;
|
||||
|
||||
@ -110,16 +110,16 @@ float calc_height(fnl_state *noise, int cur_x, int cur_z){
|
||||
}
|
||||
|
||||
WorldGenerator::WorldGenerator(const Content* content)
|
||||
: idStone(content->requireBlock("base:stone")->rt.id),
|
||||
idDirt(content->requireBlock("base:dirt")->rt.id),
|
||||
idGrassBlock(content->requireBlock("base:grass_block")->rt.id),
|
||||
idSand(content->requireBlock("base:sand")->rt.id),
|
||||
idWater(content->requireBlock("base:water")->rt.id),
|
||||
idWood(content->requireBlock("base:wood")->rt.id),
|
||||
idLeaves(content->requireBlock("base:leaves")->rt.id),
|
||||
idGrass(content->requireBlock("base:grass")->rt.id),
|
||||
idFlower(content->requireBlock("base:flower")->rt.id),
|
||||
idBazalt(content->requireBlock("base:bazalt")->rt.id) {}
|
||||
: idStone(content->requireBlock("base:stone").rt.id),
|
||||
idDirt(content->requireBlock("base:dirt").rt.id),
|
||||
idGrassBlock(content->requireBlock("base:grass_block").rt.id),
|
||||
idSand(content->requireBlock("base:sand").rt.id),
|
||||
idWater(content->requireBlock("base:water").rt.id),
|
||||
idWood(content->requireBlock("base:wood").rt.id),
|
||||
idLeaves(content->requireBlock("base:leaves").rt.id),
|
||||
idGrass(content->requireBlock("base:grass").rt.id),
|
||||
idFlower(content->requireBlock("base:flower").rt.id),
|
||||
idBazalt(content->requireBlock("base:bazalt").rt.id) {}
|
||||
|
||||
int generate_tree(fnl_state *noise,
|
||||
PseudoRandom* random,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user