Skip to content

Commit

Permalink
Merge branch 'printing-temp' into printing-1-19-4
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksilassila committed Apr 18, 2023
2 parents 70d8dbd + c28ce7a commit 0931cf5
Show file tree
Hide file tree
Showing 53 changed files with 432 additions and 157 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ big structures more quickly by automatically placing the correct blocks around y
## Installation

1. Download and install [Fabric](https://fabricmc.net/use/installer/) if you haven't already.
2. Download the latest release for your Minecraft version from the
[releases page](https://github.com/aleksilassila/litematica-printing/releases/latest).
2. Download the latest Litematica Printer release for your Minecraft version from the
[releases page](https://github.com/aleksilassila/litematica-printing/releases/latest) (The files can be found under
"assets").
3. Download [Litematica + MaLiLib](https://www.curseforge.com/minecraft/mc-mods/litematica)
and [Fabric API](https://www.curseforge.com/minecraft/mc-mods/fabric-api/).
and [Fabric API](https://www.curseforge.com/minecraft/mc-mods/fabric-api/) (≠ Fabric).
4. Place the downloaded .jar files in your `mods/` folder.

[If this is the first fabric mod you are installing, here's an informative video on how to install Fabric mods.](https://www.youtube.com/watch?v=x7gmfib4gHg)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package me.aleksilassila.litematica.printer.v1_17;

import net.minecraft.block.*;
import net.minecraft.item.Item;
import net.minecraft.item.Items;

import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -16,5 +18,14 @@ abstract public class BlockHelper {
DropperBlock.class, DispenserBlock.class, ShulkerBoxBlock.class, LecternBlock.class,
FlowerPotBlock.class, BarrelBlock.class, BellBlock.class, SmithingTableBlock.class,
LoomBlock.class, CartographyTableBlock.class, GrindstoneBlock.class,
StonecutterBlock.class, AbstractSignBlock.class));
StonecutterBlock.class, AbstractSignBlock.class, AbstractCandleBlock.class));

public static final Item[] SHOVEL_ITEMS = new Item[]{
Items.NETHERITE_SHOVEL,
Items.DIAMOND_SHOVEL,
Items.GOLDEN_SHOVEL,
Items.IRON_SHOVEL,
Items.STONE_SHOVEL,
Items.WOODEN_SHOVEL
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.aleksilassila.litematica.printer.v1_17;

import fi.dy.masa.litematica.data.DataManager;
import fi.dy.masa.litematica.util.RayTraceUtils;
import fi.dy.masa.litematica.world.SchematicWorldHandler;
import fi.dy.masa.litematica.world.WorldSchematic;
import me.aleksilassila.litematica.printer.v1_17.actions.Action;
Expand All @@ -13,8 +14,11 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -54,7 +58,8 @@ public boolean onGameTick() {

Guide[] guides = interactionGuides.getInteractionGuides(state);

boolean isCurrentlyLooking = ((BlockHitResult) player.raycast(20, 1, false)).getBlockPos().equals(position);
BlockHitResult result = RayTraceUtils.traceToSchematicWorld(player, 10, true, true);
boolean isCurrentlyLookingSchematic = result != null && result.getBlockPos().equals(position);

for (Guide guide : guides) {
if (guide.canExecute(player)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,37 @@
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.io.IOUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Scanner;

public class UpdateChecker {
public static final String version = "v3.1";
public static final String version = "v3.2";

// Try to get this to work at some point
// static {
// try (InputStream in = UpdateChecker.class.getResourceAsStream("/fabric.mod.json")) {
// String jsonString = IOUtils.toString(in, StandardCharsets.UTF_8);
// JsonObject json = JsonParser.parseString(jsonString).getAsJsonObject();
// System.out.println("JSON object: " + json);
// System.out.println("Raw json: " + jsonString);
// System.out.println("File: " + new File(UpdateChecker.class.getResource("/fabric.mod.json").getFile()));
// String version = json.get("version").getAsString();
// System.out.println("Reading fabric.mod.json");
// System.out.println("Parsed version: " + version);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }

@SuppressWarnings("deprecation")
public static String getPrinterVersion() {
try (InputStream inputStream = new URL("https://api.github.com/repos/aleksilassila/litematica-printer/tags").openStream(); Scanner scanner = new Scanner(inputStream)) {
if (scanner.hasNext()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ public Guide(SchematicBlockState state) {
}

protected boolean playerHasRightItem(ClientPlayerEntity player) {
return getStackSlot(player) != -1;
return getRequiredItemStackSlot(player) != -1;
}

protected int getSlotWithItem(ClientPlayerEntity player, ItemStack itemStack) {
PlayerInventory inventory = player.getInventory();

for (int i = 0; i < inventory.main.size(); ++i) {
if (itemStack.isEmpty() && inventory.main.get(i).isOf(itemStack.getItem())) return i;
if (!inventory.main.get(i).isEmpty() && inventory.main.get(i).isItemEqual(itemStack)) {
return i;
}
Expand All @@ -44,7 +45,7 @@ protected int getSlotWithItem(ClientPlayerEntity player, ItemStack itemStack) {
return -1;
}

protected int getStackSlot(ClientPlayerEntity player) {
protected int getRequiredItemStackSlot(ClientPlayerEntity player) {
if (player.getAbilities().creativeMode) {
return player.getInventory().selectedSlot;
}
Expand All @@ -64,7 +65,7 @@ public boolean canExecute(ClientPlayerEntity player) {
return !statesEqual(targetState, currentState);
}

abstract public List<Action> execute(ClientPlayerEntity player);
abstract public @NotNull List<Action> execute(ClientPlayerEntity player);

abstract protected @NotNull List<ItemStack> getRequiredItems();

Expand All @@ -79,7 +80,7 @@ protected Optional<ItemStack> getRequiredItem(ClientPlayerEntity player) {
if (player.getAbilities().creativeMode) return Optional.of(requiredItem);

int slot = getSlotWithItem(player, requiredItem);
if (slot > -1 && !requiredItem.isOf(Items.AIR))
if (slot > -1)
return Optional.of(requiredItem);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ protected static void registerGuide(Class<? extends Guide> guideClass, Class<? e
BambooBlock.class, CactusBlock.class, SaplingBlock.class, ScaffoldingBlock.class, PointedDripstoneBlock.class,
HorizontalConnectingBlock.class, DoorBlock.class, TrapdoorBlock.class, FenceGateBlock.class, ChestBlock.class,
SnowBlock.class, SeaPickleBlock.class, CandleBlock.class, LeverBlock.class, EndPortalFrameBlock.class,
CandleBlock.class, RedstoneTorchBlock.class, CampfireBlock.class, PoweredRailBlock.class, LeavesBlock.class,
TripwireHookBlock.class);
NoteBlock.class, CampfireBlock.class, PoweredRailBlock.class, LeavesBlock.class, TripwireHookBlock.class);
registerGuide(FallingBlockGuide.class, FallingBlock.class);
registerGuide(BlockIndifferentGuesserGuide.class, BambooBlock.class, BigDripleafStemBlock.class, BigDripleafBlock.class,
TwistingVinesPlantBlock.class, TripwireBlock.class);
registerGuide(GuesserGuide.class);

registerGuide(CampfireExtinguishGuide.class, CampfireBlock.class);
registerGuide(LightCandleGuide.class, AbstractCandleBlock.class);
registerGuide(EnderEyeGuide.class, EndPortalFrameBlock.class);
registerGuide(CycleStateGuide.class,
DoorBlock.class, FenceGateBlock.class, TrapdoorBlock.class,
Expand All @@ -50,6 +49,7 @@ protected static void registerGuide(Class<? extends Guide> guideClass, Class<? e
registerGuide(BlockReplacementGuide.class, SnowBlock.class, SeaPickleBlock.class, CandleBlock.class, SlabBlock.class);
registerGuide(LogGuide.class);
registerGuide(LogStrippingGuide.class);
registerGuide(GuesserGuide.class);
}

public ArrayList<Pair<Class<? extends Guide>, Class<? extends Block>[]>> getGuides() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public boolean canExecute(ClientPlayerEntity player) {
}

@Override
public List<Action> execute(ClientPlayerEntity player) {
public @NotNull List<Action> execute(ClientPlayerEntity player) {
return new ArrayList<>();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,21 @@
import java.util.List;

public class CampfireExtinguishGuide extends InteractionGuide {
static final Item[] SHOVEL_ITEMS = new Item[]{
Items.NETHERITE_SHOVEL,
Items.DIAMOND_SHOVEL,
Items.GOLDEN_SHOVEL,
Items.IRON_SHOVEL,
Items.STONE_SHOVEL,
Items.WOODEN_SHOVEL
};
boolean shouldBeLit;
boolean isLit;

public CampfireExtinguishGuide(SchematicBlockState state) {
super(state);

shouldBeLit = getProperty(targetState, CampfireBlock.LIT).orElse(false);
isLit = getProperty(currentState, CampfireBlock.LIT).orElse(false);
}

@Override
public boolean canExecute(ClientPlayerEntity player) {
if (!super.canExecute(player)) return false;

if (currentState.getBlock() instanceof CampfireBlock && targetState.getBlock() instanceof CampfireBlock) {
return currentState.get(CampfireBlock.LIT) && !targetState.get(CampfireBlock.LIT);
}

return false;
return (currentState.getBlock() instanceof CampfireBlock) && !shouldBeLit && isLit;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import me.aleksilassila.litematica.printer.v1_17.SchematicBlockState;
import net.minecraft.block.BlockState;
import net.minecraft.block.LeverBlock;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.property.Properties;
Expand All @@ -12,8 +13,9 @@
import java.util.List;

public class CycleStateGuide extends InteractionGuide {
private static final Property<?>[] propertiesToIgnore = new Property[] {
Properties.POWERED
private static final Property<?>[] propertiesToIgnore = new Property[]{
Properties.POWERED,
Properties.LIT
};

public CycleStateGuide(SchematicBlockState state) {
Expand All @@ -34,6 +36,10 @@ public boolean canExecute(ClientPlayerEntity player) {

@Override
protected boolean statesEqual(BlockState state1, BlockState state2) {
if (state2.getBlock() instanceof LeverBlock) {
return super.statesEqual(state1, state2);
}

return statesEqualIgnoreProperties(state1, state2, propertiesToIgnore);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ public InteractionGuide(SchematicBlockState state) {
}

@Override
public List<Action> execute(ClientPlayerEntity player) {
public @NotNull List<Action> execute(ClientPlayerEntity player) {
List<Action> actions = new ArrayList<>();

BlockHitResult hitResult = new BlockHitResult(Vec3d.ofCenter(state.blockPos), Direction.UP, state.blockPos, false);
ItemStack itemStack = getRequiredItem(player).orElse(ItemStack.EMPTY);
PrinterPlacementContext ctx = new PrinterPlacementContext(player, hitResult, itemStack, getSlotWithItem(player, itemStack));
ItemStack requiredItem = getRequiredItem(player).orElse(ItemStack.EMPTY);
int requiredSlot = getRequiredItemStackSlot(player);

if (requiredSlot == -1) return actions;

PrinterPlacementContext ctx = new PrinterPlacementContext(player, hitResult, requiredItem, requiredSlot);

List<Action> actions = new ArrayList<>();
actions.add(new ReleaseShiftAction());
actions.add(new PrepareAction(ctx));
actions.add(new InteractActionImpl(ctx));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package me.aleksilassila.litematica.printer.v1_17.guides.interaction;

import me.aleksilassila.litematica.printer.v1_17.SchematicBlockState;
import net.minecraft.block.AbstractCandleBlock;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.state.property.Properties;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.List;

public class LightCandleGuide extends InteractionGuide {
boolean shouldBeLit;
boolean isLit;

public LightCandleGuide(SchematicBlockState state) {
super(state);

shouldBeLit = getProperty(targetState, Properties.LIT).orElse(false);
isLit = getProperty(currentState, Properties.LIT).orElse(false);
}

@Override
protected @NotNull List<ItemStack> getRequiredItems() {
return Collections.singletonList(new ItemStack(Items.FLINT_AND_STEEL));
}

@Override
public boolean canExecute(ClientPlayerEntity player) {
if (!super.canExecute(player)) return false;

return (currentState.getBlock() instanceof AbstractCandleBlock) && shouldBeLit && !isLit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,15 @@ public class BlockReplacementGuide extends PlacementGuide {
private static final HashMap<IntProperty, Item> increasingProperties = new HashMap<>();

static {
addProperties();
increasingProperties.put(SnowBlock.LAYERS, null);
increasingProperties.put(SeaPickleBlock.PICKLES, null);
increasingProperties.put(CandleBlock.CANDLES, null);
}

private Integer currentLevel = null;
private Integer targetLevel = null;
private IntProperty increasingProperty = null;

protected static void addProperties() {
increasingProperties.put(SnowBlock.LAYERS, null);
increasingProperties.put(SeaPickleBlock.PICKLES, null);
increasingProperties.put(CandleBlock.CANDLES, null);
// increasingProperties.put(LeveledCauldronBlock.LEVEL, Items.GLASS_BOTTLE);
}

public BlockReplacementGuide(SchematicBlockState state) {
super(state);

Expand All @@ -58,10 +53,11 @@ protected boolean getUseShift(SchematicBlockState state) {
@Override
public @Nullable PrinterPlacementContext getPlacementContext(ClientPlayerEntity player) {
Optional<ItemStack> requiredItem = getRequiredItem(player);
if (requiredItem.isEmpty()) return null;
int slot = getRequiredItemStackSlot(player);
if (requiredItem.isEmpty() || slot == -1) return null;

BlockHitResult hitResult = new BlockHitResult(Vec3d.ofCenter(state.blockPos), Direction.UP, state.blockPos, false);
return new PrinterPlacementContext(player, hitResult, requiredItem.get(), getSlotWithItem(player, requiredItem.get()));
return new PrinterPlacementContext(player, hitResult, requiredItem.get(), slot);
}

@Override
Expand All @@ -71,7 +67,7 @@ public boolean canExecute(ClientPlayerEntity player) {
}

if (currentLevel == null || targetLevel == null || increasingProperty == null) return false;
if (!statesEqualIgnoreProperties(currentState, targetState, increasingProperty)) return false;
if (!statesEqualIgnoreProperties(currentState, targetState, CandleBlock.LIT, increasingProperty)) return false;
if (currentLevel >= targetLevel) return false;

return super.canExecute(player);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,16 @@ public PrinterPlacementContext getPlacementContext(ClientPlayerEntity player) {
Optional<Direction> validSide = getValidSide(state);
Optional<Vec3d> hitVec = getHitVector(state);
Optional<ItemStack> requiredItem = getRequiredItem(player);
int requiredSlot = getRequiredItemStackSlot(player);

if (validSide.isEmpty() || hitVec.isEmpty() || requiredItem.isEmpty()) return null;
if (validSide.isEmpty() || hitVec.isEmpty() || requiredItem.isEmpty() || requiredSlot == -1) return null;

Optional<Direction> lookDirection = getLookDirection();
boolean requiresShift = getUseShift(state);

BlockHitResult blockHitResult = new BlockHitResult(hitVec.get(), validSide.get().getOpposite(), state.blockPos.offset(validSide.get()), false);

return new PrinterPlacementContext(player, blockHitResult, requiredItem.get(), getSlotWithItem(player, requiredItem.get()), lookDirection.orElse(null), requiresShift);
return new PrinterPlacementContext(player, blockHitResult, requiredItem.get(), requiredSlot, lookDirection.orElse(null), requiresShift);
} catch (Exception e) {
e.printStackTrace();
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public PrinterPlacementContext getPlacementContext(ClientPlayerEntity player) {
if (contextCache != null && !LitematicaMixinMod.DEBUG) return contextCache;

ItemStack requiredItem = getRequiredItem(player).orElse(ItemStack.EMPTY);
int slot = getRequiredItemStackSlot(player);

if (slot == -1) return null;

for (Direction lookDirection : directionsToTry) {
for (Direction side : directionsToTry) {
Expand All @@ -71,10 +74,10 @@ public PrinterPlacementContext getPlacementContext(ClientPlayerEntity player) {
multiplier = new Vec3d(multiplier.x == 0 ? 1 : 0, multiplier.y == 0 ? 1 : 0, multiplier.z == 0 ? 1 : 0);

BlockHitResult hitResult = new BlockHitResult(hitVec.add(hitVecToTry.multiply(multiplier)), side.getOpposite(), neighborPos, false);
PrinterPlacementContext context = new PrinterPlacementContext(player, hitResult, requiredItem, getSlotWithItem(player, requiredItem), lookDirection, requiresShift);
PrinterPlacementContext context = new PrinterPlacementContext(player, hitResult, requiredItem, slot, lookDirection, requiresShift);
BlockState result = getRequiredItemAsBlock(player)
.orElse(targetState.getBlock())
.getPlacementState(context);
.getPlacementState(context); // FIXME torch shift clicks another torch and getPlacementState is the clicked block, which is true

if (result != null && (statesEqual(result, targetState) || correctChestPlacement(targetState, result))) {
contextCache = context;
Expand Down
Loading

0 comments on commit 0931cf5

Please sign in to comment.