Skip to content

Commit

Permalink
feat: add block state setter and getter
Browse files Browse the repository at this point in the history
  • Loading branch information
Dofes committed Jan 5, 2025
1 parent 4ec94bf commit cdeb1de
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 10 deletions.
21 changes: 21 additions & 0 deletions src/mc/world/level/block/Block.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,27 @@ class Block {
::ll::TypedStorage<1, 1, bool> mHasRuntimeId;
// NOLINTEND

public:
template <typename T>
T getState(uint64 id) const {
return mLegacyBlock->get()->getState<T>(id, mData);
}

template <typename T>
T getState(BlockState const& state) const {
return mLegacyBlock->get()->getState<T>(state, mData);
}

template <typename T>
optional_ref<Block const> setState(uint64 id, T value) const {
return mLegacyBlock->get()->trySetState(id, value, mData);
}

template <typename T>
optional_ref<Block const> setState(BlockState const& state, T value) const {
return mLegacyBlock->get()->trySetState(state, value, mData);
}

public:
// virtual functions
// NOLINTBEGIN
Expand Down
58 changes: 58 additions & 0 deletions src/mc/world/level/block/BlockLegacy.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include "mc/_HeaderOutputPredefine.h"
#include "mc/world/level/block/states/BlockState.h"
#include "mc/world/level/block/states/BlockStateInstance.h"

// auto generated inclusion list
#include "mc/common/WeakPtr.h"
Expand Down Expand Up @@ -331,6 +333,62 @@ class BlockLegacy {
LLNDAPI static optional_ref<BlockLegacy> tryGetFromRegistry(std::string_view name);
LLNDAPI static optional_ref<BlockLegacy const> tryGetFromRegistry(uint legacyBlockID);

template <typename T>
T getState(uint64 id, ushort data) const {
auto it = mStates->lower_bound(id);

if (it == mStates->end() || it->first != id) {
std::optional<int> result = _tryLookupAlteredStateCollection(id, data);
if (result.has_value()) {
return static_cast<T>(result.value());
} else {
return T{};
}
}

return it->second.get<T>(data);
}

template <typename T>
T getState(BlockState const& stateType, ushort data) const {
return getState<T>(stateType.mID, data);
}

template <typename T>
Block const* trySetState(uint64 id, T val, ushort data) {
auto it = mStates->lower_bound(id);

if (it != mStates->end() && it->first == id) {
auto& stateInstance = it->second;

if (static_cast<uchar>(val) < stateInstance.mVariationCount) {
ushort maskedData = (data & ~stateInstance.mMask)
| (static_cast<ushort>(val) << (stateInstance.mEndBit - stateInstance.mNumBits + 1));

if (maskedData < mBlockPermutations->size()) {
return mBlockPermutations->at(maskedData).get();
}
return nullptr;
}
}

Block const* alteredStateBlock = _trySetStateFromAlteredStateCollection(id, static_cast<int>(val), data);
if (alteredStateBlock) {
return alteredStateBlock;
}

if (mReturnDefaultBlockOnUnidentifiedBlockState) {
return &getDefaultState();
}

return nullptr;
}

template <typename T>
Block const* trySetState(BlockState const& stateType, T val, ushort data) {
return trySetState(stateType.mID, val, data);
}

public:
// member variables
// NOLINTBEGIN
Expand Down
21 changes: 11 additions & 10 deletions src/mc/world/level/block/states/BlockStateInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@ class BlockStateInstance {
public:
// member variables
// NOLINTBEGIN
::ll::UntypedStorage<4, 4> mUnkeee94f;
::ll::UntypedStorage<4, 4> mUnk58db0e;
::ll::UntypedStorage<4, 4> mUnk3e3d8a;
::ll::UntypedStorage<4, 4> mUnk787411;
::ll::UntypedStorage<1, 1> mUnk163307;
::ll::UntypedStorage<8, 8> mUnkd127d6;
::ll::TypedStorage<4, 4, uint> mEndBit;
::ll::TypedStorage<4, 4, uint> mNumBits;
::ll::TypedStorage<4, 4, uint> mVariationCount;
::ll::TypedStorage<4, 4, uint> mMask;
::ll::TypedStorage<1, 1, bool> mInitialized;
::ll::TypedStorage<8, 8, ::BlockState const*> mState;
// NOLINTEND

public:
// prevent constructor by default
BlockStateInstance& operator=(BlockStateInstance const&);
BlockStateInstance(BlockStateInstance const&);
BlockStateInstance();
template <typename T>
T get(ushort data) const {
if (sizeof(T) * 8 < mNumBits) return T{};
return static_cast<T>((data >> (mEndBit - mNumBits + 1)) & ((1 << mNumBits) - 1));
}

public:
// member functions
Expand Down

0 comments on commit cdeb1de

Please sign in to comment.