use of com.lowdragmc.multiblocked.api.capability.MultiblockCapability in project Multiblocked by Low-Drag-MC.
the class IOPageWidget method setupSceneWidget.
@OnlyIn(Dist.CLIENT)
private void setupSceneWidget(SceneWidget sceneWidget) {
sceneWidget.getRenderer().setAfterWorldRender(renderer -> {
sceneWidget.renderBlockOverLay(renderer);
RenderUtils.useLightMap(240, 240, () -> {
RenderSystem.disableCull();
int inner = 0;
for (Map.Entry<MultiblockCapability<?>, Tuple<IO, Direction>> entry : capabilitySettings.entrySet()) {
if (entry.getValue() != null) {
sceneWidget.drawFacingBorder(new MatrixStack(), new BlockPosFace(pos, entry.getValue().getB()), entry.getKey().color, inner);
inner++;
}
}
RenderSystem.enableCull();
});
});
}
use of com.lowdragmc.multiblocked.api.capability.MultiblockCapability in project Multiblocked by Low-Drag-MC.
the class BlockPattern method checkPatternAt.
public boolean checkPatternAt(MultiblockState worldState, boolean savePredicate) {
ControllerTileEntity controller = worldState.getController();
if (controller == null) {
worldState.setError(new PatternStringError("no controller found"));
return false;
}
BlockPos centerPos = controller.getBlockPos();
Direction frontFacing = controller.getFrontFacing();
Set<MultiblockCapability<?>> inputCapabilities = controller.getDefinition().recipeMap.inputCapabilities;
Set<MultiblockCapability<?>> outputCapabilities = controller.getDefinition().recipeMap.outputCapabilities;
Direction[] facings = controller.getDefinition().allowRotate ? new Direction[] { frontFacing } : new Direction[] { Direction.SOUTH, Direction.NORTH, Direction.EAST, Direction.WEST };
for (Direction facing : facings) {
if (checkPatternAt(worldState, centerPos, facing, savePredicate, inputCapabilities, outputCapabilities)) {
return true;
}
}
return false;
}
use of com.lowdragmc.multiblocked.api.capability.MultiblockCapability in project Multiblocked by Low-Drag-MC.
the class BlockPattern method checkPatternAt.
private boolean checkPatternAt(MultiblockState worldState, BlockPos centerPos, Direction facing, boolean savePredicate, Set<MultiblockCapability<?>> inputCapabilities, Set<MultiblockCapability<?>> outputCapabilities) {
boolean findFirstAisle = false;
int minZ = -centerOffset[4];
worldState.clean();
PatternMatchContext matchContext = worldState.matchContext;
Map<SimplePredicate, Integer> globalCount = worldState.globalCount;
// Checking aisles
for (int c = 0, z = minZ++, r; c < this.fingerLength; c++) {
// Checking repeatable slices
loop: for (r = 0; (findFirstAisle ? r < aisleRepetitions[c][1] : z <= -centerOffset[3]); r++) {
// Checking single slice
for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) {
for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) {
worldState.setError(null);
TraceabilityPredicate predicate = this.blockMatches[c][b][a];
BlockPos pos = setActualRelativeOffset(x, y, z, facing).offset(centerPos.getX(), centerPos.getY(), centerPos.getZ());
if (!worldState.update(pos, predicate)) {
return false;
}
if (!predicate.isAny()) {
worldState.addPosCache(pos);
if (savePredicate) {
worldState.getMatchContext().getOrCreate("predicates", (Supplier<HashMap<BlockPos, TraceabilityPredicate>>) HashMap::new).put(pos, predicate);
}
}
boolean canPartShared = true;
TileEntity tileEntity = worldState.getTileEntity();
if (tileEntity instanceof IPartComponent) {
// add detected parts
if (!predicate.isAny()) {
IPartComponent part = (IPartComponent) tileEntity;
if (part.isFormed() && !part.canShared() && !part.hasController(worldState.controllerPos)) {
// check part can be shared
canPartShared = false;
worldState.setError(new PatternStringError("multiblocked.pattern.error.share"));
} else {
worldState.getMatchContext().getOrCreate("parts", LongOpenHashSet::new).add(worldState.getPos().asLong());
}
}
}
if (!predicate.test(worldState) || !canPartShared) {
// matching failed
if (findFirstAisle) {
if (r < aisleRepetitions[c][0]) {
// retreat to see if the first aisle can start later
r = c = 0;
z = minZ++;
matchContext.reset();
findFirstAisle = false;
}
} else {
// continue searching for the first aisle
z++;
}
continue loop;
}
if (tileEntity != null && !predicate.isAny()) {
Map<Long, EnumMap<IO, Set<MultiblockCapability<?>>>> capabilities = worldState.getMatchContext().getOrCreate("capabilities", Long2ObjectOpenHashMap::new);
if (!capabilities.containsKey(worldState.getPos().asLong()) && worldState.io != null) {
// if predicate has no specific capability requirements. we will check abilities of every blocks
Set<MultiblockCapability<?>> bothFound = new HashSet<>();
for (MultiblockCapability<?> capability : inputCapabilities) {
// IN
if (worldState.io == IO.BOTH && outputCapabilities.contains(capability) && capability.isBlockHasCapability(IO.BOTH, tileEntity)) {
bothFound.add(capability);
capabilities.computeIfAbsent(worldState.getPos().asLong(), l -> new EnumMap<>(IO.class)).computeIfAbsent(IO.BOTH, xx -> new HashSet<>()).add(capability);
} else if (worldState.io != IO.OUT && capability.isBlockHasCapability(IO.IN, tileEntity)) {
capabilities.computeIfAbsent(worldState.getPos().asLong(), l -> new EnumMap<>(IO.class)).computeIfAbsent(IO.IN, xx -> new HashSet<>()).add(capability);
}
}
if (worldState.io != IO.IN) {
for (MultiblockCapability<?> capability : outputCapabilities) {
// OUT
if (!bothFound.contains(capability) && capability.isBlockHasCapability(IO.OUT, tileEntity)) {
capabilities.computeIfAbsent(worldState.getPos().asLong(), l -> new EnumMap<>(IO.class)).computeIfAbsent(IO.OUT, xx -> new HashSet<>()).add(capability);
}
}
}
}
}
}
}
findFirstAisle = true;
z++;
}
// Repetitions out of range
if (r < aisleRepetitions[c][0] || !worldState.isFormed() || !findFirstAisle) {
if (worldState.isFormed()) {
worldState.setError(new PatternError());
}
return false;
}
}
// Check count matches amount
for (Map.Entry<SimplePredicate, Integer> entry : globalCount.entrySet()) {
if (entry.getValue() < entry.getKey().minCount) {
worldState.setError(new SinglePredicateError(entry.getKey(), 1));
return false;
}
}
worldState.setError(null);
return true;
}
use of com.lowdragmc.multiblocked.api.capability.MultiblockCapability in project Multiblocked by Low-Drag-MC.
the class RecipeTypeAdapter method deserializeIO.
private ImmutableMap<MultiblockCapability<?>, ImmutableList<Tuple<Object, Float>>> deserializeIO(JsonElement jsonElement) {
JsonObject json = jsonElement.getAsJsonObject();
ImmutableMap.Builder<MultiblockCapability<?>, ImmutableList<Tuple<Object, Float>>> builder = new ImmutableMap.Builder<>();
for (Map.Entry<String, JsonElement> entry : json.entrySet()) {
MultiblockCapability<?> capability = MbdCapabilities.get(entry.getKey());
if (capability != null) {
ImmutableList.Builder<Tuple<Object, Float>> listBuilder = new ImmutableList.Builder<>();
for (JsonElement element : entry.getValue().getAsJsonArray()) {
JsonObject recipe = element.getAsJsonObject();
Object content;
try {
content = capability.deserialize(recipe.get("content"));
} catch (Exception e) {
Multiblocked.LOGGER.error(e);
content = null;
}
if (content != null) {
listBuilder.add(new Tuple<>(content, recipe.get("chance").getAsFloat()));
}
}
builder.put(capability, listBuilder.build());
}
}
return builder.build();
}
use of com.lowdragmc.multiblocked.api.capability.MultiblockCapability in project Multiblocked by Low-Drag-MC.
the class ComponentTileEntity method save.
@Nonnull
@Override
public CompoundNBT save(@Nonnull CompoundNBT compound) {
super.save(compound);
compound.putString("loc", definition.location.toString());
if (this.owner != null) {
compound.putUUID("owner", this.owner);
}
compound.putString("mbd_def", definition.location.toString());
CompoundNBT traitTag = new CompoundNBT();
for (Map.Entry<MultiblockCapability<?>, CapabilityTrait> entry : traits.entrySet()) {
CompoundNBT tag = new CompoundNBT();
entry.getValue().writeToNBT(tag);
traitTag.put(entry.getKey().name, tag);
}
compound.put("trait", traitTag);
if (persistedData != null) {
compound.put("persisted", persistedData);
}
return compound;
}
Aggregations