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
811using 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+
57158auto 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}
0 commit comments