9
9
#include " api/McAPI.h"
10
10
#include " api/NbtAPI.h"
11
11
#include " ll/api/service/Bedrock.h"
12
- #include " mc/deps/core/string/HashedString .h"
12
+ #include " lse/api/helper/BlockHelper .h"
13
13
#include " mc/deps/core/utility/optional_ref.h"
14
14
#include " mc/world/level/BlockSource.h"
15
15
#include " mc/world/level/ChunkBlockPos.h"
16
16
#include " mc/world/level/block/BedrockBlockNames.h"
17
17
#include " mc/world/level/block/Block.h"
18
+ #include " mc/world/level/block/DetectionRule.h"
19
+ #include " mc/world/level/block/LiquidReaction.h"
18
20
#include " mc/world/level/block/actor/BlockActor.h"
19
21
#include " mc/world/level/block/block_serialization_utils/BlockSerializationUtils.h"
20
- #include " mc/world/level/block/components/BlockLiquidDetectionComponent .h"
22
+ #include " mc/world/level/block/components/BlockComponentDirectData .h"
21
23
#include " mc/world/level/chunk/LevelChunk.h"
22
24
#include " mc/world/level/dimension/Dimension.h"
25
+ #include " mc/world/level/dimension/DimensionHeightRange.h"
23
26
24
27
#include < exception>
25
28
29
+ using lse::api::BlockHelper;
30
+
26
31
// ////////////////// Class Definition ////////////////////
27
32
28
33
ClassDefine<BlockClass> BlockClassBuilder =
@@ -66,24 +71,6 @@ ClassDefine<BlockClass> BlockClassBuilder =
66
71
.instanceFunction(" getTag" , &BlockClass::getNbt)
67
72
.build();
68
73
69
- namespace lse ::BlockAPI {
70
- inline bool isValidHeight (WeakRef<Dimension> dim, std::variant<int , float > height) {
71
- if (dim) {
72
- if (std::holds_alternative<int >(height)) {
73
- int y = std::get<int >(height);
74
- return dim->getMinHeight () <= y && dim->getHeight () >= y;
75
- } else {
76
- float y = std::get<float >(height);
77
- return dim->getMinHeight () <= y && dim->getHeight () >= y;
78
- }
79
- }
80
-
81
- return false ;
82
- }
83
- } // namespace lse::BlockAPI
84
-
85
- using lse::BlockAPI::isValidHeight;
86
-
87
74
// ////////////////// Classes ////////////////////
88
75
89
76
BlockClass::BlockClass (Block const & block) : ScriptClass(ScriptClass::ConstructFromCpp<BlockClass>{}), block(&block) {
@@ -103,8 +90,8 @@ Local<Object> BlockClass::newBlock(Block const& block, BlockPos const& pos, Dime
103
90
}
104
91
105
92
Local<Object> BlockClass::newBlock (BlockPos const & pos, DimensionType dim) {
106
- if (auto dimension = ll::service::getLevel ()->getDimension (dim)) {
107
- if (isValidHeight (dimension, pos.y )) {
93
+ if (auto dimension = ll::service::getLevel ()->getDimension (dim). lock () ) {
94
+ if (BlockHelper:: isValidHeight (dimension, pos.y )) {
108
95
auto & bl = dimension->getBlockSourceFromMainChunkSource ().getBlock (pos);
109
96
return BlockClass::newBlock (bl, pos, dim);
110
97
}
@@ -123,8 +110,8 @@ Local<Object> BlockClass::newBlock(Block const& block, BlockPos const& pos, Bloc
123
110
124
111
Local<Object> BlockClass::newBlock (IntVec4 pos) {
125
112
BlockPos bp = {(float )pos.x , (float )pos.y , (float )pos.z };
126
- if (auto dimension = ll::service::getLevel ()->getDimension (pos.dim )) {
127
- if (isValidHeight (dimension, pos.y )) {
113
+ if (auto dimension = ll::service::getLevel ()->getDimension (pos.dim ). lock () ) {
114
+ if (BlockHelper:: isValidHeight (dimension, pos.y )) {
128
115
auto & bl = dimension->getBlockSourceFromMainChunkSource ().getBlock (bp);
129
116
return BlockClass::newBlock (bl, bp, pos.dim );
130
117
}
@@ -185,28 +172,28 @@ Local<Value> BlockClass::getPos() {
185
172
Local<Value> BlockClass::getTileData () {
186
173
try {
187
174
// preloaded
188
- return Number::newNumber (block->getVariant ());
175
+ return Number::newNumber (block->getLegacyBlock (). getVariant (*block ));
189
176
}
190
177
CATCH (" Fail in getTileData!" );
191
178
}
192
179
193
180
Local<Value> BlockClass::getVariant () {
194
181
try {
195
- return Number::newNumber (block->getVariant ());
182
+ return Number::newNumber (block->getLegacyBlock (). getVariant (*block ));
196
183
}
197
184
CATCH (" Fail in getVariant!" );
198
185
}
199
186
200
187
Local<Value> BlockClass::getTranslucency () {
201
188
try {
202
- return Number::newNumber (block->getTranslucency () );
189
+ return Number::newNumber (block->getLegacyBlock (). mTranslucency );
203
190
}
204
191
CATCH (" Fail in getTranslucency!" );
205
192
}
206
193
207
194
Local<Value> BlockClass::getThickness () {
208
195
try {
209
- return Number::newNumber (block->getThickness () );
196
+ return Number::newNumber (block->getLegacyBlock (). mThickness );
210
197
}
211
198
CATCH (" Fail in getThickness!" );
212
199
}
@@ -220,7 +207,7 @@ Local<Value> BlockClass::isAir() {
220
207
221
208
Local<Value> BlockClass::isBounceBlock () {
222
209
try {
223
- return Boolean::newBoolean (block->isBounceBlock ());
210
+ return Boolean::newBoolean (block->getLegacyBlock (). isBounceBlock ());
224
211
}
225
212
CATCH (" Fail in isBounceBlock!" );
226
213
}
@@ -248,35 +235,35 @@ Local<Value> BlockClass::isDoorBlock() {
248
235
249
236
Local<Value> BlockClass::isFenceBlock () {
250
237
try {
251
- return Boolean::newBoolean (block->isFenceBlock ());
238
+ return Boolean::newBoolean (block->getLegacyBlock (). isFenceBlock ());
252
239
}
253
240
CATCH (" Fail in isFenceBlock!" );
254
241
}
255
242
256
243
Local<Value> BlockClass::isFenceGateBlock () {
257
244
try {
258
- return Boolean::newBoolean (block->isFenceGateBlock ());
245
+ return Boolean::newBoolean (block->getLegacyBlock (). isFenceGateBlock ());
259
246
}
260
247
CATCH (" Fail in isFenceGateBlock!" );
261
248
}
262
249
263
250
Local<Value> BlockClass::isThinFenceBlock () {
264
251
try {
265
- return Boolean::newBoolean (block->isThinFenceBlock ());
252
+ return Boolean::newBoolean (block->getLegacyBlock (). isThinFenceBlock ());
266
253
}
267
254
CATCH (" Fail in isThinFenceBlock!" );
268
255
}
269
256
270
257
Local<Value> BlockClass::isHeavyBlock () {
271
258
try {
272
- return Boolean::newBoolean (block->isFallingBlock () );
259
+ return Boolean::newBoolean (block->getLegacyBlock (). mFalling );
273
260
}
274
261
CATCH (" Fail in isHeavyBlock!" );
275
262
}
276
263
277
264
Local<Value> BlockClass::isStemBlock () {
278
265
try {
279
- return Boolean::newBoolean (block->isStemBlock ());
266
+ return Boolean::newBoolean (block->getLegacyBlock (). isStemBlock ());
280
267
}
281
268
CATCH (" Fail in isStemBlock!" );
282
269
}
@@ -290,14 +277,17 @@ Local<Value> BlockClass::isSlabBlock() {
290
277
291
278
Local<Value> BlockClass::isUnbreakable () {
292
279
try {
293
- return Boolean::newBoolean (block->isUnbreakable () );
280
+ return Boolean::newBoolean (block->mDirectData -> mUnkc08fbd . as < float >() < 0 . 0f );
294
281
}
295
282
CATCH (" Fail in isUnbreakable!" );
296
283
}
297
284
298
285
Local<Value> BlockClass::isWaterBlockingBlock () {
299
286
try {
300
- return Boolean::newBoolean (BlockLiquidDetectionComponent::isLiquidBlocking (*block));
287
+ return Boolean::newBoolean (
288
+ block->mDirectData ->mUnkd3e7c9 .as <DetectionRule>().mUnk21e36d .as <LiquidReaction>()
289
+ == LiquidReaction::Blocking
290
+ );
301
291
}
302
292
CATCH (" Fail in isWaterBlockingBlock!" );
303
293
}
@@ -309,7 +299,8 @@ Local<Value> BlockClass::destroyBlock(const Arguments& args) {
309
299
try {
310
300
// same as `Level::getBlockInstance(pos.getBlockPos(),
311
301
// pos.dim).breakNaturally()` when drop
312
- BlockSource& bl = ll::service::getLevel ()->getDimension (blockPos.dim )->getBlockSourceFromMainChunkSource ();
302
+ BlockSource& bl =
303
+ ll::service::getLevel ()->getDimension (blockPos.dim ).lock ()->getBlockSourceFromMainChunkSource ();
313
304
return Boolean::newBoolean (
314
305
ll::service::getLevel ()->destroyBlock (bl, blockPos.getBlockPos (), args[0 ].asBoolean ().value ())
315
306
);
@@ -319,7 +310,7 @@ Local<Value> BlockClass::destroyBlock(const Arguments& args) {
319
310
320
311
Local<Value> BlockClass::getNbt (const Arguments&) {
321
312
try {
322
- return NbtCompoundClass::pack (block->getSerializationId (). clone ());
313
+ return NbtCompoundClass::pack (block->mSerializationId -> clone ());
323
314
}
324
315
CATCH (" Fail in getNbt!" );
325
316
}
@@ -337,6 +328,7 @@ Local<Value> BlockClass::setNbt(const Arguments& args) {
337
328
if (bl) {
338
329
ll::service::getLevel ()
339
330
->getDimension (blockPos.dim )
331
+ .lock ()
340
332
->getBlockSourceFromMainChunkSource ()
341
333
.setBlock (blockPos.getBlockPos (), *bl, 3 , nullptr , nullptr );
342
334
}
@@ -347,11 +339,10 @@ Local<Value> BlockClass::setNbt(const Arguments& args) {
347
339
}
348
340
349
341
Local<Value> BlockClass::getBlockState (const Arguments&) {
350
- return Local<Value>();
351
342
try {
352
- auto list = block->getSerializationId () ;
343
+ auto list = block->mSerializationId ;
353
344
try {
354
- return Tag2Value (&list. at (" states" ).get (), true );
345
+ return Tag2Value (&list-> at (" states" ).get (), true );
355
346
} catch (...) {
356
347
return Array::newArray ();
357
348
}
@@ -365,9 +356,10 @@ Local<Value> BlockClass::hasContainer(const Arguments&) {
365
356
try {
366
357
auto & bl = ll::service::getLevel ()
367
358
->getDimension (blockPos.dim )
359
+ .lock ()
368
360
->getBlockSourceFromMainChunkSource ()
369
361
.getBlock (blockPos.getBlockPos ());
370
- return Boolean::newBoolean (bl.isContainerBlock ());
362
+ return Boolean::newBoolean (bl.getLegacyBlock (). isContainerBlock ());
371
363
}
372
364
CATCH (" Fail in hasContainer!" );
373
365
}
@@ -376,6 +368,7 @@ Local<Value> BlockClass::getContainer(const Arguments&) {
376
368
try {
377
369
Container* container = ll::service::getLevel ()
378
370
->getDimension (blockPos.dim )
371
+ .lock ()
379
372
->getBlockSourceFromMainChunkSource ()
380
373
.getBlockEntity (blockPos.getBlockPos ())
381
374
->getContainer ();
@@ -386,7 +379,7 @@ Local<Value> BlockClass::getContainer(const Arguments&) {
386
379
387
380
Local<Value> BlockClass::hasBlockEntity (const Arguments&) {
388
381
try {
389
- return Boolean::newBoolean (block->hasBlockEntity () );
382
+ return Boolean::newBoolean (block->getLegacyBlock (). mBlockEntityType != BlockActorType::Undefined );
390
383
}
391
384
CATCH (" Fail in hasBlockEntity!" );
392
385
}
@@ -395,6 +388,7 @@ Local<Value> BlockClass::getBlockEntity(const Arguments&) {
395
388
try {
396
389
BlockActor* be = ll::service::getLevel ()
397
390
->getDimension (blockPos.dim )
391
+ .lock ()
398
392
->getBlockSourceFromMainChunkSource ()
399
393
.getBlockEntity (blockPos.getBlockPos ());
400
394
return be ? BlockEntityClass::newBlockEntity (be, blockPos.dim ) : Local<Value>();
@@ -404,11 +398,16 @@ Local<Value> BlockClass::getBlockEntity(const Arguments&) {
404
398
405
399
Local<Value> BlockClass::removeBlockEntity (const Arguments&) {
406
400
try {
407
- ll::service::getLevel ()
408
- ->getDimension (blockPos.dim )
409
- ->getBlockSourceFromMainChunkSource ()
410
- .removeBlockEntity (blockPos.getBlockPos ());
411
- return Boolean::newBoolean (true );
401
+ auto chunk = ll::service::getLevel ()
402
+ ->getDimension (blockPos.dim )
403
+ .lock ()
404
+ ->getBlockSourceFromMainChunkSource ()
405
+ .getChunkAt (blockPos.getBlockPos ());
406
+ if (chunk) {
407
+ return Boolean::newBoolean (chunk->removeBlockEntity (blockPos.getBlockPos ()) != nullptr );
408
+ } else {
409
+ return Boolean::newBoolean (false );
410
+ }
412
411
}
413
412
CATCH (" Fail in removeBlockEntity!" );
414
413
}
@@ -456,23 +455,21 @@ Local<Value> McClass::getBlock(const Arguments& args) {
456
455
return Local<Value>();
457
456
}
458
457
459
- auto dimPtr = ll::service::getLevel ()->getDimension (pos.dim ).get ();
458
+ auto dimPtr = ll::service::getLevel ()->getDimension (pos.dim ).lock ();
460
459
if (!dimPtr) {
461
460
return {};
462
461
}
463
462
BlockSource& bs = dimPtr->getBlockSourceFromMainChunkSource ();
464
- short minHeight = dimPtr->getMinHeight () ;
465
- if (pos.y < minHeight || pos.y > dimPtr->getHeight () ) {
463
+ short minHeight = dimPtr->mHeightRange -> mMin ;
464
+ if (pos.y < minHeight || pos.y > dimPtr->mHeightRange -> mMax ) {
466
465
return {};
467
466
}
468
467
auto lc = bs.getChunkAt (pos.getBlockPos ());
469
468
if (!lc) {
470
469
return {};
471
470
}
472
- ChunkBlockPos cbpos = ChunkBlockPos (pos.getBlockPos (), minHeight);
473
- auto & block = lc->getBlock (cbpos);
474
- BlockPos bp{pos.x , pos.y , pos.z };
475
- return BlockClass::newBlock (block, bp, pos.dim );
471
+ auto & block = lc->getBlock (ChunkBlockPos{(uchar)pos.x , (uchar)pos.z , minHeight});
472
+ return BlockClass::newBlock (block, pos.getBlockPos (), pos.dim );
476
473
}
477
474
CATCH (" Fail in GetBlock!" )
478
475
}
@@ -538,7 +535,8 @@ Local<Value> McClass::setBlock(const Arguments& args) {
538
535
if (!bl.has_value ()) {
539
536
return Boolean::newBoolean (false );
540
537
}
541
- BlockSource& bs = ll::service::getLevel ()->getDimension (pos.dim )->getBlockSourceFromMainChunkSource ();
538
+ BlockSource& bs =
539
+ ll::service::getLevel ()->getDimension (pos.dim ).lock ()->getBlockSourceFromMainChunkSource ();
542
540
return Boolean::newBoolean (bs.setBlock (pos.getBlockPos (), bl, 3 , nullptr , nullptr ));
543
541
} else if (IsInstanceOf<NbtCompoundClass>(block)) {
544
542
// Nbt
@@ -547,7 +545,8 @@ Local<Value> McClass::setBlock(const Arguments& args) {
547
545
if (!bl.has_value ()) {
548
546
return Boolean::newBoolean (false );
549
547
}
550
- BlockSource& bs = ll::service::getLevel ()->getDimension (pos.dim )->getBlockSourceFromMainChunkSource ();
548
+ BlockSource& bs =
549
+ ll::service::getLevel ()->getDimension (pos.dim ).lock ()->getBlockSourceFromMainChunkSource ();
551
550
return Boolean::newBoolean (bs.setBlock (pos.getBlockPos (), bl, 3 , nullptr , nullptr ));
552
551
} else {
553
552
// other block object
@@ -556,7 +555,8 @@ Local<Value> McClass::setBlock(const Arguments& args) {
556
555
LOG_WRONG_ARG_TYPE (__FUNCTION__);
557
556
return Local<Value>();
558
557
}
559
- BlockSource& bs = ll::service::getLevel ()->getDimension (pos.dim )->getBlockSourceFromMainChunkSource ();
558
+ BlockSource& bs =
559
+ ll::service::getLevel ()->getDimension (pos.dim ).lock ()->getBlockSourceFromMainChunkSource ();
560
560
return Boolean::newBoolean (bs.setBlock (pos.getBlockPos (), *bl, 3 , nullptr , nullptr ));
561
561
}
562
562
}
@@ -620,7 +620,7 @@ Local<Value> McClass::spawnParticle(const Arguments& args) {
620
620
ll::service::getLevel ()->spawnParticleEffect (
621
621
type.asString ().toString (),
622
622
pos.getVec3 (),
623
- ll::service::getLevel ()->getDimension (pos.dim ).get ()
623
+ ll::service::getLevel ()->getDimension (pos.dim ).lock (). get ()
624
624
);
625
625
return Boolean::newBoolean (true );
626
626
}
0 commit comments