Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Pipe Swapping functionality #3836

Merged
merged 35 commits into from
Feb 1, 2025
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
116b341
Add Pipe Swapping functionality
mak8427 Jan 20, 2025
46cad99
Merge branch 'master' into pipe-switch
mak8427 Jan 20, 2025
30578f8
Merge branch 'master' into pipe-switch
Dream-Master Jan 21, 2025
0a28bf7
Merge branch 'master' into pipe-switch
mak8427 Jan 21, 2025
4f425b3
Merge branch 'master' into pipe-switch
Dream-Master Jan 22, 2025
4cc7714
Merge branch 'master' into pipe-switch
Dream-Master Jan 22, 2025
eded734
Merge branch 'master' into pipe-switch
Dream-Master Jan 23, 2025
b9c4804
changed CTRL click from Keyboard to KeyboardUtil
mak8427 Jan 23, 2025
f054d1a
StatCollector instead of GTUtility.trans
mak8427 Jan 23, 2025
93e0972
Packet implementation first try
mak8427 Jan 24, 2025
aa2ff70
Merge branch 'master' into pipe-switch
Dream-Master Jan 25, 2025
49e336a
Merge branch 'master' into pipe-switch
Dream-Master Jan 25, 2025
24d91db
Merge branch 'master' into pipe-switch
Dream-Master Jan 25, 2025
cc57e4f
Merge branch 'master' into pipe-switch
mak8427 Jan 25, 2025
5bd80cb
Merge branch 'master' into pipe-switch
Dream-Master Jan 26, 2025
32f79a7
Merge branch 'master' into pipe-switch
Dream-Master Jan 27, 2025
8b07aec
Merge remote-tracking branch 'origin/pipe-switch' into pipe-switch
mak8427 Jan 28, 2025
c40941f
Spotless apply
mak8427 Jan 28, 2025
c8a3de3
Fix conditions
mak8427 Jan 28, 2025
ea171ba
Merge branch 'master' into pipe-switch
Dream-Master Jan 28, 2025
bb8f5f0
Merge branch 'master' into pipe-switch
Dream-Master Jan 30, 2025
26b9cc7
Merge branch 'master' into pipe-switch
Dream-Master Jan 30, 2025
def330a
star import fix
Dream-Master Jan 30, 2025
187205f
Update src/main/java/gregtech/api/metatileentity/implementations/MTEF…
mak8427 Jan 30, 2025
88f956e
Merge remote-tracking branch 'origin/pipe-switch' into pipe-switch
mak8427 Jan 30, 2025
65fcfd0
-fix for multiplayer sever compatibilitity from ctrl + right click t…
mak8427 Jan 30, 2025
c1df479
keep diseble input
mak8427 Jan 30, 2025
ca95f94
Keep fluid inside the pipe
mak8427 Jan 30, 2025
968e4ca
fix fluid handling
mak8427 Jan 30, 2025
85b5c03
Spotless
mak8427 Jan 30, 2025
7c229fa
Merge branch 'master' into pipe-switch
mak8427 Jan 31, 2025
567ca28
Merge branch 'master' into pipe-switch
Dream-Master Jan 31, 2025
ec91878
Remove CTRL var as unused
mak8427 Feb 1, 2025
975f2dc
Merge remote-tracking branch 'origin/pipe-switch' into pipe-switch
mak8427 Feb 1, 2025
1d6980e
Merge branch 'master' into pipe-switch
serenibyss Feb 1, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package gregtech.api.interfaces.tileentity;

import net.minecraft.entity.player.EntityPlayer;

public interface IKeyHandlerTile {

/**
* Called when a key interaction occurs
*
* @param aKey The key identifier (e.g. KEY_CTRL = 1)
* @param aPressed True if key was pressed, false if released
* @param aPlayer The player who triggered the key event
* @return True if the key event was handled
*/
boolean onKeyInteraction(byte aKey, boolean aPressed, EntityPlayer aPlayer);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,21 @@

import org.apache.commons.lang3.tuple.MutableTriple;

import com.gtnewhorizons.modularui.api.KeyboardUtil;

import cpw.mods.fml.common.Optional;
import gregtech.GTMod;
import gregtech.api.enums.Dyes;
import gregtech.api.enums.Materials;
import gregtech.api.enums.Mods;
import gregtech.api.enums.OrePrefixes;
import gregtech.api.enums.ParticleFX;
import gregtech.api.enums.SoundResource;
import gregtech.api.enums.Textures;
import gregtech.api.enums.ToolModes;
import gregtech.api.enums.*;
mak8427 marked this conversation as resolved.
Show resolved Hide resolved
import gregtech.api.interfaces.IIconContainer;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.ICoverable;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.interfaces.tileentity.IKeyHandlerTile;
import gregtech.api.items.MetaGeneratedTool;
import gregtech.api.metatileentity.BaseMetaPipeEntity;
import gregtech.api.metatileentity.MetaPipeEntity;
import gregtech.api.net.GTPacketKeyEvent;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.CoverBehavior;
import gregtech.api.util.CoverBehaviorBase;
Expand All @@ -64,14 +61,15 @@
import gregtech.api.util.ISerializableObject;
import gregtech.api.util.WorldSpawnedEventBuilder.ParticleEventBuilder;
import gregtech.common.GTClient;
import gregtech.common.blocks.ItemMachines;
import gregtech.common.config.Other;
import gregtech.common.covers.CoverDrain;
import gregtech.common.covers.CoverFluidRegulator;
import gregtech.common.covers.CoverInfo;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;

public class MTEFluid extends MetaPipeEntity {
public class MTEFluid extends MetaPipeEntity implements IKeyHandlerTile {

protected static final EnumMap<ForgeDirection, EnumMap<Border, ForgeDirection>> FACE_BORDER_MAP = new EnumMap<>(
ForgeDirection.class);
Expand Down Expand Up @@ -111,6 +109,7 @@ public class MTEFluid extends MetaPipeEntity {
public final boolean mGasProof;
public final FluidStack[] mFluids;
public byte mLastReceivedFrom = 0, oLastReceivedFrom = 0;
public static final byte KEY_CTRL = 1;
/**
* Bitmask for whether disable fluid input form each side.
*/
Expand Down Expand Up @@ -473,6 +472,163 @@ public void blockPipeOnSide(ForgeDirection side, EntityPlayer entityPlayer, byte
}
}

@Override
public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer, ForgeDirection side,
float aX, float aY, float aZ) {
if (aBaseMetaTileEntity.isClientSide()) {
if (KeyboardUtil.isCtrlKeyDown()) {
GTUtility.sendChatToPlayer(aPlayer, "Ctrl+Rightclick");
// Send key event packet with player name
GTValues.NW.sendToServer(
new GTPacketKeyEvent(
aBaseMetaTileEntity.getXCoord(),
(short) aBaseMetaTileEntity.getYCoord(),
aBaseMetaTileEntity.getZCoord(),
KEY_CTRL,
(byte) 1,
aPlayer.getCommandSenderName()));
return true;
}
return false;
}
return super.onRightclick(aBaseMetaTileEntity, aPlayer, side, aX, aY, aZ);
}

// Implement the IKeyHandlerTile interface
@Override
public boolean onKeyInteraction(byte aKey, boolean aPressed, EntityPlayer aPlayer) {
if (aKey == KEY_CTRL && aPressed) {
IGregTechTileEntity te = getBaseMetaTileEntity();
if (te == null || aPlayer == null) return false;

// Now we use the exact player who triggered the event
final ItemStack handItem = aPlayer.inventory.getCurrentItem();
IMetaTileEntity meta = ItemMachines.getMetaTileEntity(handItem);
if (!(meta instanceof MTEFluid handFluid)) return false;

if (aPlayer == null) return false;

// Store old state before any changes
byte oldConnections = this.mConnections;
short oldMetaID = (short) te.getMetaTileID();

// Create new pipe using newMetaEntity to ensure proper initialization
MTEFluid newPipe = (MTEFluid) handFluid.newMetaEntity(te);
if (newPipe == null) return false;

// Preserve connections
newPipe.mConnections = oldConnections;
mak8427 marked this conversation as resolved.
Show resolved Hide resolved

// Store values for comparison
long oldCapacity = this.mCapacity;
boolean oldGasProof = this.mGasProof;
int oldHeatResistance = this.mHeatResistance;

// Update the pipe
te.setMetaTileID((short) handItem.getItemDamage());
te.setMetaTileEntity(newPipe);

// Build status change message
StringBuilder message = new StringBuilder();

// Capacity change
if (oldCapacity != newPipe.mCapacity) {
message.append(oldCapacity * 20)
.append("L/s → ");
if (newPipe.mCapacity > oldCapacity) {
message.append(EnumChatFormatting.GREEN);
} else {
message.append(EnumChatFormatting.RED);
}
message.append(newPipe.mCapacity * 20)
.append("L/s");
message.append(EnumChatFormatting.RESET);
}

// Heat resistance change
if (oldHeatResistance != newPipe.mHeatResistance) {
if (message.length() > 0) message.append(" | ");
message.append(oldHeatResistance)
.append("K → ");
if (newPipe.mHeatResistance > oldHeatResistance) {
message.append(EnumChatFormatting.GREEN);
} else {
message.append(EnumChatFormatting.RED);
}
message.append(newPipe.mHeatResistance)
.append("K");
message.append(EnumChatFormatting.RESET);
}

// Gas handling change
if (oldGasProof != newPipe.mGasProof) {
if (message.length() > 0) message.append(" | ");
if (newPipe.mGasProof) {
message.append(EnumChatFormatting.GREEN)
.append("Now Gas-Proof");
} else {
message.append(EnumChatFormatting.RED)
.append("No Longer Gas-Proof");
}
message.append(EnumChatFormatting.RESET);
}

// Send message if there were any changes
if (message.length() > 0) {
GTUtility.sendChatToPlayer(
aPlayer,
StatCollector.translateToLocal("GT5U.item.pipe.swap") + message.toString());
mak8427 marked this conversation as resolved.
Show resolved Hide resolved
}

// Force updates
te.markDirty();
te.issueTextureUpdate();
te.issueBlockUpdate();
te.issueClientUpdate();

// Handle inventory swapping
if (!aPlayer.capabilities.isCreativeMode) {
// Create ItemStack for the removed pipe
ItemStack oldPipe = new ItemStack(handItem.getItem(), 1, oldMetaID);

// Try to give the old pipe to the player
boolean addedToInventory = false;
if (oldPipe != null) {
// First try to stack with existing pipes
for (int i = 0; i < aPlayer.inventory.mainInventory.length; i++) {
ItemStack slot = aPlayer.inventory.mainInventory[i];
if (slot != null && slot.getItem() == oldPipe.getItem()
&& slot.getItemDamage() == oldPipe.getItemDamage()
&& slot.stackSize < slot.getMaxStackSize()) {
slot.stackSize++;
addedToInventory = true;
break;
}
}

// If couldn't stack, try to find empty slot
if (!addedToInventory) {
addedToInventory = aPlayer.inventory.addItemStackToInventory(oldPipe);
}

// If still couldn't add, drop in world
if (!addedToInventory) {
aPlayer.dropPlayerItemWithRandomChoice(oldPipe, false);
}
}

// Use one pipe from player's hand
handItem.stackSize--;
if (handItem.stackSize <= 0) {
aPlayer.inventory.setInventorySlotContents(aPlayer.inventory.currentItem, null);
}
}

return true;
}
return false;
}

@Override
public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer,
float aX, float aY, float aZ, ItemStack aTool) {
Expand Down
112 changes: 112 additions & 0 deletions src/main/java/gregtech/api/net/GTPacketKeyEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package gregtech.api.net;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;

import com.google.common.io.ByteArrayDataInput;

import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.interfaces.tileentity.IKeyHandlerTile;
import gregtech.api.util.GTUtility;
import io.netty.buffer.ByteBuf;

public class GTPacketKeyEvent extends GTPacket {

private int mX, mZ;
private short mY;
private byte mKey;
private byte mAction;
private String mPlayerName; // Add player name

public GTPacketKeyEvent() {
super();
}

public GTPacketKeyEvent(int aX, short aY, int aZ, byte aKey, byte aAction, String aPlayerName) {
super();
mX = aX;
mY = aY;
mZ = aZ;
mKey = aKey;
mAction = aAction;
mPlayerName = aPlayerName;
}

@Override
public byte getPacketID() {
return GTPacketTypes.KEY_EVENT.id;
}

@Override
public void encode(ByteBuf aOut) {
aOut.writeInt(mX);
aOut.writeShort(mY);
aOut.writeInt(mZ);
aOut.writeByte(mKey);
aOut.writeByte(mAction);
writeString(aOut, mPlayerName);
}

@Override
public GTPacket decode(ByteArrayDataInput aData) {
return new GTPacketKeyEvent(
aData.readInt(),
aData.readShort(),
aData.readInt(),
aData.readByte(),
aData.readByte(),
readString(aData));
}

private void writeString(ByteBuf buf, String str) {
byte[] bytes = str.getBytes(java.nio.charset.StandardCharsets.UTF_8);
buf.writeInt(bytes.length);
buf.writeBytes(bytes);
}

private String readString(ByteArrayDataInput data) {
int length = data.readInt();
byte[] bytes = new byte[length];
data.readFully(bytes);
return new String(bytes, java.nio.charset.StandardCharsets.UTF_8);
}

@Override
public void process(IBlockAccess aWorld) {
if (!(aWorld instanceof World) || ((World) aWorld).isRemote) return;

World world = (World) aWorld;
TileEntity tTileEntity = world.getTileEntity(mX, mY, mZ);

// Find the player
EntityPlayer player = null;
for (Object obj : world.playerEntities) {
if (obj instanceof EntityPlayer && ((EntityPlayer) obj).getCommandSenderName()
.equals(mPlayerName)) {
player = (EntityPlayer) obj;
break;
}
}

if (player == null) {
// Can't send chat if we don't have a player
return;
}

GTUtility.sendChatToPlayer(player, "Processing packet at: " + mX + ", " + mY + ", " + mZ);

if (tTileEntity instanceof IGregTechTileEntity) {
IMetaTileEntity mte = ((IGregTechTileEntity) tTileEntity).getMetaTileEntity();
if (mte instanceof IKeyHandlerTile) {
((IKeyHandlerTile) mte).onKeyInteraction(mKey, mAction == 1, player);
} else {
GTUtility.sendChatToPlayer(player, "Error: TileEntity does not handle key events");
}
} else {
GTUtility.sendChatToPlayer(player, "Error: Invalid TileEntity type");
}
}
}
1 change: 1 addition & 0 deletions src/main/java/gregtech/api/net/GTPacketTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public enum GTPacketTypes {
EIC(27, new PacketEIC()),
CREATE_TILE_ENTITY(28, new GTPacketCreateTE()),
NODE_INFO(29, new GTPacketNodeInfo()),
KEY_EVENT(30, new GTPacketKeyEvent()),
// merge conflict prevention comment, keep a trailing comma above
;

Expand Down
1 change: 1 addition & 0 deletions src/main/java/gregtech/api/util/GTLanguageManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ public static void writePlaceholderStrings() {
addStringLocalization("Interaction_DESCRIPTION_Index_213", "Input disabled");
addStringLocalization("Interaction_DESCRIPTION_Index_214", "Connected");
addStringLocalization("Interaction_DESCRIPTION_Index_215", "Disconnected");
addStringLocalization("Interaction_DESCRIPTION_Index_215.2", "Pipe Changed: ");
addStringLocalization("Interaction_DESCRIPTION_Index_216", "Deprecated Recipe");
addStringLocalization("Interaction_DESCRIPTION_Index_219", "Extended Facing: ");
addStringLocalization("Interaction_DESCRIPTION_Index_220", "Single recipe locking disabled.");
Expand Down
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 @@ -688,6 +688,7 @@ GT5U.item.pipe.gas_proof.yes=Yes
GT5U.item.pipe.gas_proof.no=No
GT5U.item.pipe.amount=Pipe Amount
GT5U.item.pipe.empty=Empty
GT5U.item.pipe.swap=Pipe Swapped:

gt.behaviour.paintspray.infinite.gui.header=Select a Color
gt.behaviour.paintspray.infinite.gui.lock_error=§eSpray can is §clocked§e! §bSneak middle-click to unlock.
Expand Down
Loading