Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ dependencies {
compileOnly('com.github.GTNewHorizons:Angelica:1.0.0-beta68a:dev')
compileOnly("com.github.GTNewHorizons:FindIt:1.4.0:dev")
compileOnly('com.github.GTNewHorizons:TinkersConstruct:1.14.14-GTNH:dev')
compileOnly("com.github.GTNewHorizons:Backhand:1.8.2:dev")
compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.52.296:dev')


devOnlyNonPublishable("com.github.GTNewHorizons:Baubles-Expanded:2.2.4-GTNH:dev")
Expand All @@ -57,4 +59,8 @@ dependencies {
// For testing glove
// runtimeOnlyNonPublishable("com.github.GTNewHorizons:Translocators:1.4.0:dev")
// runtimeOnlyNonPublishable("com.github.GTNewHorizons:Backhand:1.8.2:dev")

// For testing trowel + wand
// runtimeOnlyNonPublishable("com.github.GTNewHorizons:Backhand:1.8.2:dev")
// runtimeOnlyNonPublishable('com.github.GTNewHorizons:GT5-Unofficial:5.09.52.296:dev')
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,19 @@ public static void IMCSender() {
sendInfoPage("<utilitiesinexcess:precision_shears>", "nei.infopage.uie.precision_shears.1");
sendInfoPage("<utilitiesinexcess:etheric_sword>", "nei.infopage.uie.etheric_sword.1");
sendInfoPage("<utilitiesinexcess:reversing_hoe>", "nei.infopage.uie.reversing_hoe.1");

sendInfoPage(
"<utilitiesinexcess:architects_wand>,<utilitiesinexcess:super_architects_wand>",
"nei.infopage.uie.architects_wand.1");

if (Mods.Backhand.isLoaded()) {
sendInfoPage(
"<utilitiesinexcess:architects_wand>,<utilitiesinexcess:super_architects_wand>",
"nei.infopage.uie.architects_wand.2");
if (Mods.GT.isLoaded()) sendInfoPage(
"<utilitiesinexcess:architects_wand>,<utilitiesinexcess:super_architects_wand>",
"nei.infopage.uie.architects_wand.3");
}
sendInfoPage("<utilitiesinexcess:mob_jar>", "nei.infopage.uie.mob_jar.1");

sendInfoPage("utilitiesinexcess:glove", "nei.infopage.uie.glove.1");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package com.fouristhenumber.utilitiesinexcess.common.items;

import static com.fouristhenumber.utilitiesinexcess.utils.ArchitectsWandUtils.getItemStackToPlace;

import java.util.List;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MovingObjectPosition;
Expand All @@ -19,8 +17,11 @@
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

import org.jetbrains.annotations.NotNull;

import com.fouristhenumber.utilitiesinexcess.UtilitiesInExcess;
import com.fouristhenumber.utilitiesinexcess.common.renderers.WireframeRenderer;
import com.fouristhenumber.utilitiesinexcess.utils.ArchitectsSelection;
import com.fouristhenumber.utilitiesinexcess.utils.ArchitectsWandUtils;
import com.gtnewhorizon.gtnhlib.api.ITranslucentItem;
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
Expand Down Expand Up @@ -85,24 +86,60 @@ public void onUpdate(ItemStack stack, World world, Entity entity, int slot, bool
}

// 4. Target block to place
ItemStack itemStackToPlace = getItemStackToPlace(world, target, movingObjectPosition, player);
if (itemStackToPlace == null || !(itemStackToPlace.getItem() instanceof ItemBlock)) {
WireframeRenderer.clearCandidatePositions();
return;
}
ArchitectsSelection selection = new ArchitectsSelection(player, world, movingObjectPosition);
List<ItemStack> itemStackToPlace = selection.blockToPlace(player);

// 3. Total amount to place
int placeCount = player.capabilities.isCreativeMode ? this.buildLimit
: Math.min(ArchitectsWandUtils.countItemInInventory(player, itemStackToPlace), this.buildLimit);

Set<BlockPos> blocksToPlace = ArchitectsWandUtils
.findAdjacentBlocks(world, itemStackToPlace, placeCount, forgeSide, target, movingObjectPosition, player);
int placeCount = selection.maxPlaceCount(player, buildLimit);

Set<BlockPos> blocksToPlace = ArchitectsWandUtils.findAdjacentBlocks(
world,
itemStackToPlace,
placeCount,
forgeSide,
target,
movingObjectPosition,
player,
selection);
WireframeRenderer.clearCandidatePositions();
for (BlockPos pos : blocksToPlace) {
WireframeRenderer.addCandidatePosition(pos.offset(forgeSide.offsetX, forgeSide.offsetY, forgeSide.offsetZ));
}
}

private void placeBlock(World world, EntityPlayer player, @NotNull ItemStack itemStack, BlockPos pos, int side,
float hitX, float hitY, float hitZ, ForgeDirection forgeSide) {
// This block is here because some mods want to use TEs to
ItemStack itemCopy = itemStack.copy();
itemCopy.stackSize = 1;
Block comparisonBlock = world.getBlock(pos.x, pos.y, pos.z);
int comparisonMeta = world.getBlockMetadata(pos.x, pos.y, pos.z);
ItemStack comparisonItemStack = new ItemStack(comparisonBlock, 1, comparisonMeta);

boolean useCompatPlacement = !ItemStack.areItemStacksEqual(itemCopy, comparisonItemStack);
if (useCompatPlacement) {
itemStack.getItem()
.onItemUse(itemCopy, player, world, pos.x, pos.y, pos.z, side, hitX, hitY, hitZ);
} else {
Block block = Block.getBlockFromItem(itemCopy.getItem());
world.setBlock(
pos.x + forgeSide.offsetX,
pos.y + forgeSide.offsetY,
pos.z + forgeSide.offsetZ,
block,
comparisonMeta,
3);

world.playSoundEffect(
pos.x + forgeSide.offsetX,
pos.y + forgeSide.offsetY,
pos.z + forgeSide.offsetZ,
block.stepSound.func_150496_b(),
(block.stepSound.getVolume() + 1.0F) / 2.0F,
block.stepSound.getPitch() * 0.8F);
}
}

@Override
public boolean onItemUse(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int side,
float hitX, float hitY, float hitZ) {
Expand All @@ -116,42 +153,28 @@ public boolean onItemUse(ItemStack itemstack, EntityPlayer player, World world,

BlockPos target = new BlockPos(x, y, z);
MovingObjectPosition mop = new MovingObjectPosition(x, y, z, side, Vec3.createVectorHelper(hitX, hitY, hitZ));
ItemStack itemStackToPlace = getItemStackToPlace(world, target, mop, player);
if (itemStackToPlace == null || !(itemStackToPlace.getItem() instanceof ItemBlock)) return false;
ArchitectsSelection selection = new ArchitectsSelection(player, world, mop);

// This block is here because some mods want to use TEs to
Block comparisonBlock = world.getBlock(x, y, z);
int comparisonMeta = world.getBlockMetadata(x, y, z);
ItemStack comparisonItemStack = new ItemStack(comparisonBlock, 1, comparisonMeta);

boolean useCompatPlacement = !ItemStack.areItemStacksEqual(itemStackToPlace, comparisonItemStack);
List<ItemStack> itemStackToPlace = selection.blockToPlace(player);

int inventoryBlockCount = ArchitectsWandUtils.countItemInInventory(player, itemStackToPlace);
if (!player.capabilities.isCreativeMode && inventoryBlockCount == 0) return false;
int placeCount = player.capabilities.isCreativeMode ? this.buildLimit
: Math.min(inventoryBlockCount, this.buildLimit);
int placeCount = selection.maxPlaceCount(player, buildLimit);

Set<BlockPos> blocksToPlace = ArchitectsWandUtils
.findAdjacentBlocks(world, itemStackToPlace, placeCount, forgeSide, target, mop, player);
itemStackToPlace.stackSize = blocksToPlace.size(); // Since now, we actually create a stack we have to set the
// size. Strange kinda...
.findAdjacentBlocks(world, itemStackToPlace, placeCount, forgeSide, target, mop, player, selection);

ItemStack nowPlacing;

for (BlockPos pos : blocksToPlace) {
// TODO: Group these by a bigger number instead of decreasing by 1 every time.
if (player.capabilities.isCreativeMode
|| ArchitectsWandUtils.decreaseFromInventory(player, itemStackToPlace)) {
if (useCompatPlacement) {
itemStackToPlace.getItem()
.onItemUse(itemStackToPlace, player, world, pos.x, pos.y, pos.z, side, hitX, hitY, hitZ);
} else {
world.setBlock(
pos.x + forgeSide.offsetX,
pos.y + forgeSide.offsetY,
pos.z + forgeSide.offsetZ,
comparisonBlock,
comparisonMeta,
3);
}
List<ItemStack> candidates = selection.blockToPlace(player);
if (candidates.size() == 1) {
nowPlacing = candidates.get(0);
} else {
nowPlacing = candidates.get(
ThreadLocalRandom.current()
.nextInt(candidates.size()));
}
if (player.capabilities.isCreativeMode || ArchitectsWandUtils.decreaseFromInventory(player, nowPlacing)) {
placeBlock(world, player, nowPlacing, pos, side, hitX, hitY, hitZ, forgeSide);
}
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public enum Mods {
NEI("NotEnoughItems"),
CraftTweaker("MineTweaker3"),
FindIt("findit"),
Tinkers("TConstruct")
Tinkers("TConstruct"),
Backhand("backhand"),
GT("gregtech_nh")
;
// spotless:on

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package com.fouristhenumber.utilitiesinexcess.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;

import org.jetbrains.annotations.Nullable;

import com.fouristhenumber.utilitiesinexcess.compat.Mods;
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;

import gregtech.api.items.MetaGeneratedTool;
import gregtech.common.tools.ToolTrowel;
import xonin.backhand.api.core.BackhandUtils;

public class ArchitectsSelection {

private final Set<ItemStack> validBlocks;
private final ItemStack backhand;
private final ItemStack lookAtBlock;

public ArchitectsSelection(EntityPlayer player, World world, MovingObjectPosition movingObjectPosition) {
this.validBlocks = new HashSet<>();
backhand = Mods.Backhand.isLoaded() ? BackhandUtils.getOffhandItem(player) : null;
lookAtBlock = getBlockByLocation(world, movingObjectPosition, player);

// No logic is executed if we don't look at any block, no need to bother checking other cases
if (lookAtBlock == null) {
return;
}

this.validBlocks.add(lookAtBlock); // Clicked block is always valid

if (backhand == null) {
return;
}
if (isValidBlock(backhand)) {
this.validBlocks.add(backhand.copy());
return;
}
if (isTrowel(backhand)) {
this.validBlocks.addAll(hotbarBlocks(player));
}
}

/**
*
* @param player
* @return Always a valid block list or null
*/
public List<ItemStack> blockToPlace(EntityPlayer player) {

if (backhand == null) {
return Collections.singletonList((lookAtBlock));
}
if (isValidBlock(backhand)) {
return Collections.singletonList(backhand);
} else if (isTrowel(backhand)) {
return hotbarBlocks(player);
} else {
return Collections.singletonList(lookAtBlock);
}
}

public int maxPlaceCount(EntityPlayer player, int wandLimit) {
if (player.capabilities.isCreativeMode) return wandLimit;
int count = 0;
for (ItemStack block : blockToPlace(player)) {
count += ArchitectsWandUtils.countItemInInventory(player, block);
}
return Math.min(count, wandLimit);
}

public boolean matches(ItemStack other) {
if (other == null) return false;
return this.validBlocks.stream()
.anyMatch(
validBlock -> validBlock.getItem() == other.getItem()
&& ItemStack.areItemStackTagsEqual(validBlock, other));
}

private static boolean isTrowel(@Nullable ItemStack stack) {
if (stack == null) {
return false;
}
if (Mods.GT.isLoaded() && stack.getItem() instanceof MetaGeneratedTool metaGeneratedTool) {
return metaGeneratedTool.getToolStats(stack) instanceof ToolTrowel;
}
return false;
}

private static boolean isValidBlock(@Nullable ItemStack stack) {
return (stack != null && stack.getItem() instanceof ItemBlock);
}

private static List<ItemStack> hotbarBlocks(EntityPlayer player) {
List<ItemStack> candidates = new ArrayList<>();

for (int i = 0; i < 9; i++) {
if (i == player.inventory.currentItem) {
continue;
}
ItemStack item = player.inventory.mainInventory[i];
if (!isValidBlock(item)) {
continue;
}
candidates.add(item);
}
return candidates;
}

public static ItemStack getBlockByLocation(World world, MovingObjectPosition movingObjectPosition,
EntityPlayer player) {

BlockPos blockPos = new BlockPos(
movingObjectPosition.blockX,
movingObjectPosition.blockY,
movingObjectPosition.blockZ);

Block block = world.getBlock(blockPos.x, blockPos.y, blockPos.z);
if (block == null) {
return null;
}
return block.getPickBlock(movingObjectPosition, world, blockPos.x, blockPos.y, blockPos.z, player);
}
}
Loading