Skip to content
Closed
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: 3 additions & 3 deletions src/main/java/gregtech/common/items/MetaItem1.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import gregtech.common.creativetab.GTCreativeTabs;
import gregtech.common.entities.GTBoatEntity.GTBoatType;
import gregtech.common.items.behaviors.ClipboardBehavior;
import gregtech.common.items.behaviors.ColorSprayBehaviour;
import gregtech.common.items.behaviors.ColorSprayBehavior;
import gregtech.common.items.behaviors.DataItemBehavior;
import gregtech.common.items.behaviors.DoorBehavior;
import gregtech.common.items.behaviors.DynamiteBehaviour;
Expand Down Expand Up @@ -180,13 +180,13 @@ public void registerSubItems() {

// out of registry order so it can reference the Empty Spray Can
SPRAY_SOLVENT = addItem(60, "spray.solvent").setMaxStackSize(1)
.addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 1024, -1))
.addComponents(new ColorSprayBehavior(SPRAY_EMPTY.getStackForm(), 1024, -1))
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);

for (int i = 0; i < EnumDyeColor.values().length; i++) {
SPRAY_CAN_DYES[i] = addItem(62 + i, "spray.can.dyes." + EnumDyeColor.values()[i].getName())
.setMaxStackSize(1)
.addComponents(new ColorSprayBehaviour(SPRAY_EMPTY.getStackForm(), 512, i))
.addComponents(new ColorSprayBehavior(SPRAY_EMPTY.getStackForm(), 512, i))
.setCreativeTabs(GTCreativeTabs.TAB_GREGTECH_TOOLS);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import gregtech.api.pipenet.tile.IPipeTile;
import gregtech.api.util.GradientUtil;
import gregtech.api.util.Mods;
import gregtech.common.pipelike.PipeCollectorWalker;
import gregtech.core.sound.GTSoundEvents;

import net.minecraft.block.Block;
Expand All @@ -20,7 +21,11 @@
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

Expand All @@ -32,13 +37,13 @@
import java.awt.*;
import java.util.List;

public class ColorSprayBehaviour extends AbstractUsableBehaviour implements IItemDurabilityManager {
public class ColorSprayBehavior extends AbstractUsableBehaviour implements IItemDurabilityManager {

private final ItemStack empty;
private final EnumDyeColor color;
private final Pair<Color, Color> durabilityBarColors;

public ColorSprayBehaviour(ItemStack empty, int totalUses, int color) {
public ColorSprayBehavior(ItemStack empty, int totalUses, int color) {
super(totalUses);
this.empty = empty;
EnumDyeColor[] colors = EnumDyeColor.values();
Expand All @@ -55,7 +60,7 @@ public ActionResult<ItemStack> onItemUse(EntityPlayer player, World world, Block
if (!player.canPlayerEdit(pos, facing, stack)) {
return ActionResult.newResult(EnumActionResult.FAIL, player.getHeldItem(hand));
}
if (!tryPaintBlock(player, world, pos, facing)) {
if (!tryPaintBlock(player, world, pos, facing, hand)) {
return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand));
}
useItemDurability(player, hand, stack, empty.copy());
Expand All @@ -64,16 +69,17 @@ public ActionResult<ItemStack> onItemUse(EntityPlayer player, World world, Block
return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand));
}

private boolean tryPaintBlock(EntityPlayer player, World world, BlockPos pos, EnumFacing side) {
private boolean tryPaintBlock(EntityPlayer player, World world, BlockPos pos, EnumFacing side, EnumHand hand) {
IBlockState blockState = world.getBlockState(pos);
Block block = blockState.getBlock();
if (color == null) {
return tryStripBlockColor(player, world, pos, block, side);
return tryStripBlockColor(player, world, pos, block, side, hand);
}
return block.recolorBlock(world, pos, side, this.color) || tryPaintSpecialBlock(player, world, pos, block);
return tryPaintSpecialBlock(player, world, pos, block, hand) ||
block.recolorBlock(world, pos, side, this.color);
}

private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos pos, Block block) {
private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos pos, Block block, EnumHand hand) {
if (block == Blocks.GLASS) {
IBlockState newBlockState = Blocks.STAINED_GLASS.getDefaultState()
.withProperty(BlockStainedGlass.COLOR, this.color);
Expand All @@ -92,10 +98,12 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos
world.setBlockState(pos, newBlockState);
return true;
}
TileEntity te = world.getTileEntity(pos);
if (player.isSneaking() && te instanceof IPipeTile<?, ?>) {
return traversePipes(player, world, hand, pos);
}
if (Mods.AppliedEnergistics2.isModLoaded()) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof TileCableBus) {
TileCableBus cable = (TileCableBus) te;
if (te instanceof TileCableBus cable) {
// do not try to recolor if it already is this color
if (cable.getColor().ordinal() != color.ordinal()) {
cable.recolourBlock(null, AEColor.values()[color.ordinal()], player);
Expand All @@ -106,9 +114,45 @@ private boolean tryPaintSpecialBlock(EntityPlayer player, World world, BlockPos
return false;
}

// note: automatically uses durability from recolouring pipes, apart from the last use, as this allows for proper
// animation of the item's use
private boolean traversePipes(EntityPlayer player, World world, EnumHand hand, BlockPos startPos) {
TileEntity connectedTe = world.getTileEntity(startPos);
// I LOVE LAMBDAS
final boolean[] painted = { false };
ItemStack heldItem = player.getHeldItem(hand);
int colour = this.color == null ? -1 : this.color.colorValue;
if (connectedTe instanceof IPipeTile<?, ?>startPipe) {
PipeCollectorWalker.collectPipeNet(world, startPos, startPipe, pipe -> {
if (getUsesLeft(heldItem) == 0) {
return false;
}
if (pipe.getPaintingColor() != colour) {
pipe.setPaintingColor(colour);
pipe.scheduleRenderUpdate();
if (getUsesLeft(heldItem) == 1) {
if (painted[0]) {
useItemDurability(player, hand, heldItem, empty.copy());
}
painted[0] = true;
return false;
}
// Off by one durability as the final use is handled by onItemUse, along with the use animation
if (painted[0]) {
useItemDurability(player, hand, heldItem, empty.copy());
}
painted[0] = true;
}
return true;
});

}
return painted[0];
}

@SuppressWarnings("unchecked, rawtypes")
private static boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block,
EnumFacing side) {
private boolean tryStripBlockColor(EntityPlayer player, World world, BlockPos pos, Block block,
EnumFacing side, EnumHand hand) {
// MC special cases
if (block == Blocks.STAINED_GLASS) {
world.setBlockState(pos, Blocks.GLASS.getDefaultState());
Expand Down Expand Up @@ -136,18 +180,13 @@ private static boolean tryStripBlockColor(EntityPlayer player, World world, Bloc
}

// TileEntityPipeBase special case
if (te instanceof IPipeTile) {
IPipeTile<?, ?> pipe = (IPipeTile<?, ?>) te;
if (pipe.isPainted()) {
pipe.setPaintingColor(-1);
return true;
} else return false;
if (player.isSneaking() && te instanceof IPipeTile<?, ?>) {
return traversePipes(player, world, hand, pos);
}

// AE2 cable special case
if (Mods.AppliedEnergistics2.isModLoaded()) {
if (te instanceof TileCableBus) {
TileCableBus cable = (TileCableBus) te;
if (te instanceof TileCableBus cable) {
// do not try to strip color if it is already colorless
if (cable.getColor() != AEColor.TRANSPARENT) {
cable.recolourBlock(null, AEColor.TRANSPARENT, player);
Expand Down Expand Up @@ -189,6 +228,7 @@ public void addInformation(ItemStack itemStack, List<String> lines) {
}
lines.add(I18n.format("behaviour.paintspray.uses", remainingUses));
lines.add(I18n.format("behaviour.paintspray.offhand"));
lines.add(I18n.format("behaviour.paintspray.crouch"));
}

@Override
Expand Down
66 changes: 66 additions & 0 deletions src/main/java/gregtech/common/pipelike/PipeCollectorWalker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package gregtech.common.pipelike;

import gregtech.api.pipenet.PipeNetWalker;
import gregtech.api.pipenet.tile.IPipeTile;

import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.function.Function;

public class PipeCollectorWalker<T extends IPipeTile<?, ?>> extends PipeNetWalker<T> {

public static void collectPipeNet(World world, BlockPos sourcePipe, IPipeTile<?, ?> pipe,
Function<IPipeTile<?, ?>, Boolean> pipeFunction) {
PipeCollectorWalker<? extends IPipeTile<?, ?>> walker = (PipeCollectorWalker<? extends IPipeTile<?, ?>>) new PipeCollectorWalker<>(
world, sourcePipe, 0, pipe.getClass());
walker.pipeFunction = pipeFunction;
walker.traversePipeNet();
}

// I love type erasure
private final Class<T> basePipeClass;
/**
* Function to run on every pipe
* If false is returned then halt the walker
*/
private Function<IPipeTile<?, ?>, @NotNull Boolean> pipeFunction;

private BlockPos sourcePipe;

protected PipeCollectorWalker(World world, BlockPos sourcePipe, int walkedBlocks, Class<T> basePipeClass) {
super(world, sourcePipe, walkedBlocks);
this.sourcePipe = sourcePipe;
this.basePipeClass = basePipeClass;
}

@Override
protected PipeNetWalker<T> createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos,
int walkedBlocks) {
PipeCollectorWalker<T> walker = new PipeCollectorWalker<>(world, nextPos, walkedBlocks, this.basePipeClass);
walker.pipeFunction = pipeFunction;
walker.sourcePipe = sourcePipe;
return walker;
}

@Override
protected void checkPipe(T pipeTile, BlockPos pos) {
if (this.pipeFunction != null && !this.pipeFunction.apply(pipeTile)) {
this.root.stop();
}
}

@Override
protected void checkNeighbour(T pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour,
@Nullable TileEntity neighbourTile) {}

@Override
protected Class<T> getBasePipeClass() {
return basePipeClass;
}
}
1 change: 1 addition & 0 deletions src/main/resources/assets/gregtech/lang/en_us.lang
Original file line number Diff line number Diff line change
Expand Up @@ -4717,6 +4717,7 @@ behaviour.paintspray.red.tooltip=Can paint things in Red
behaviour.paintspray.black.tooltip=Can paint things in Black
behaviour.paintspray.uses=Remaining Uses: %,d
behaviour.paintspray.offhand=Hold in offhand to color while placing blocks
behaviour.paintspray.crouch=Crouch to spray connected pipes
behaviour.prospecting=Usable for Prospecting

# Multiblock machine controllers
Expand Down