Skip to content

Commit 8b4b420

Browse files
committed
[Shell] blockstate builder
1 parent 671ef0a commit 8b4b420

3 files changed

Lines changed: 148 additions & 6 deletions

File tree

include/openminecraft/world/om_world_chunk.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ template <int Cs> class OMChunk
2020
{
2121
}
2222

23-
void setBlock(int x, int y, int z, uint32_t block)
23+
void setBlock(int x, int y, int z, uint32_t blockstate)
2424
{
25-
blocks[y * Cs * Cs + x * Cs + z] = block;
25+
blocks[y * Cs * Cs + x * Cs + z] = blockstate;
2626
dirty = true;
2727
}
2828
auto getBlock(int x, int y, int z) -> uint32_t

src/openminecraft/data/block/om_blockstate_resolver.cpp

Lines changed: 145 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
#include "openminecraft-shell/data/block/om_block.hpp"
33
#include "openminecraft-shell/data/block/om_blockstate.hpp"
44
#include "openminecraft-shell/data/om_identifier.hpp"
5+
#include "openminecraft/io/json/om_io_ast_json.hpp"
56
#include "openminecraft/vfs/om_vfs_base.hpp"
67
#include "openminecraft/io/json/om_io_ast_builder_json.hpp"
8+
#include <memory>
9+
#include <vector>
710

811
using namespace openminecraft::io;
912

@@ -41,19 +44,117 @@ void OMBlockstateResolver::resolve(OMBlock &blk)
4144
{
4245
for (auto &l : ll->getMap()["variants"]->getMap())
4346
{
44-
resolveModel(blk, l.second);
47+
if (l.second->type() == openminecraft::io::json::Object)
48+
{
49+
resolveModel(blk, l.second);
50+
}
51+
else
52+
{
53+
for (auto &lp : l.second->getArray())
54+
{
55+
resolveModel(blk, lp);
56+
}
57+
}
4558
}
4659
}
4760
else if (ll->getMap().count("multipart"))
4861
{
4962
for (auto &l : ll->getMap()["multipart"]->getArray())
5063
{
51-
resolveModel(blk, l->getMap()["apply"]);
64+
auto &ll = l->getMap()["apply"];
65+
if (ll->type() == openminecraft::io::json::Object)
66+
{
67+
resolveModel(blk, ll);
68+
}
69+
else
70+
{
71+
for (auto &lp : ll->getArray())
72+
{
73+
resolveModel(blk, lp);
74+
}
75+
}
5276
}
5377
}
5478
blk.resolverCache = ll;
5579
}
5680

81+
static auto caseCheck(OMBlockState &bs, std::shared_ptr<json::OMJsonNode> node) -> bool
82+
{
83+
if (!node)
84+
return true;
85+
86+
if (node->type() != json::Object)
87+
return true;
88+
89+
for (auto &st : node->getMap())
90+
{
91+
if (st.first == "AND")
92+
{
93+
if (st.second->type() == json::Array)
94+
{
95+
for (auto &p : st.second->getArray())
96+
if (!caseCheck(bs, p))
97+
return false;
98+
}
99+
else
100+
{
101+
if (!caseCheck(bs, st.second))
102+
return false;
103+
}
104+
}
105+
else if (st.first == "OR")
106+
{
107+
bool any_match = false;
108+
if (st.second->type() == json::Array)
109+
{
110+
for (auto &p : st.second->getArray())
111+
if (caseCheck(bs, p))
112+
{
113+
any_match = true;
114+
break;
115+
}
116+
}
117+
else
118+
{
119+
any_match = caseCheck(bs, st.second);
120+
}
121+
if (!any_match)
122+
return false;
123+
}
124+
else
125+
{
126+
if (!bs.properties.count(st.first))
127+
return false;
128+
129+
std::string target;
130+
if (st.second->type() == openminecraft::io::json::String)
131+
{
132+
target = st.second->getString();
133+
}
134+
else if (st.second->type() == openminecraft::io::json::Primitive)
135+
{
136+
target = st.second->getBoolean() ? "true" : "false";
137+
}
138+
else if (st.second->type() == openminecraft::io::json::Number)
139+
{
140+
target = st.second->getNumber();
141+
}
142+
143+
auto pos = target.find('|');
144+
if (pos != std::string::npos)
145+
{
146+
return target.find(bs.properties[st.first]) != std::string::npos;
147+
}
148+
else
149+
{
150+
if (bs.properties[st.first] != target)
151+
return false;
152+
}
153+
}
154+
}
155+
return true;
156+
}
157+
57158
auto OMBlockstateResolver::fetchModel(OMBlock &blk, std::string state) -> int
58159
{
59160
auto st = OMBlockState(state);
@@ -70,12 +171,53 @@ auto OMBlockstateResolver::fetchModel(OMBlock &blk, std::string state) -> int
70171
{
71172
if (OMBlockState(var.first).hash() == hsh)
72173
{
73-
auto i = compiler.composeBlock({}, blk.soild);
174+
std::vector<int> ids = {};
175+
if (var.second->type() == openminecraft::io::json::Object)
176+
{
177+
ids.emplace_back(blk.requiredModels[identFrom(var.second)]);
178+
}
179+
else
180+
{
181+
for (auto &lp : var.second->getArray())
182+
{
183+
ids.emplace_back(blk.requiredModels[identFrom(lp)]);
184+
}
185+
}
186+
187+
auto i = compiler.composeBlock(ids, blk.soild);
74188
blk.states[st] = i;
75189
return i;
76190
}
77191
}
78192
}
193+
else if (blk.resolverCache->getMap().count("multipart"))
194+
{
195+
std::vector<int> ids = {};
196+
for (auto &l : blk.resolverCache->getMap()["multipart"]->getArray())
197+
{
198+
if (!caseCheck(st, l->getMap().count("when") ? l->getMap()["when"] : nullptr))
199+
{
200+
continue;
201+
}
202+
203+
auto &ll = l->getMap()["apply"];
204+
if (ll->type() == openminecraft::io::json::Object)
205+
{
206+
ids.emplace_back(blk.requiredModels[identFrom(ll)]);
207+
}
208+
else
209+
{
210+
for (auto &lp : ll->getArray())
211+
{
212+
ids.emplace_back(blk.requiredModels[identFrom(lp)]);
213+
}
214+
}
215+
}
216+
217+
auto i = compiler.composeBlock(ids, blk.soild);
218+
blk.states[st] = i;
219+
return i;
220+
}
79221

80222
return -1;
81223
}

src/openminecraft/renderer/entrypoint_testrenderer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ OMTestRenderer::OMTestRenderer(OMRenderer *renderer, std::function<OMRendererTex
106106
cnk.setBlock(15, 1, 2, 6);
107107
cnk.setBlock(15, 1, 0, 13);
108108
cnk.setBlock(15, 2, 2, 16);
109-
cnk.setBlock(15, 2, 1, 17);
109+
cnk.setBlock(15, 2, 1, 18);
110110
chunkManager->loadChunk(cnk);
111111
}
112112
}

0 commit comments

Comments
 (0)