Skip to content
Merged
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
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@

This mod adds a vending machine, unlocking trades based on questbook data. If you have AE2 installed, it will also add an AE2 vending terminal, which will allow you perform trades directly with items from your ME system.

### Structure

![img.png](img.png)

### Interface
![img_1.png](img_1.png)

## Current Status

WIP
Alpha Testing

## For Non-GTNH Modpacks

This can be used as a standalone mod with several dependencies. The vending machine block and ME Vending terminal do not come with default recipes.
This can be used as a standalone mod with several dependencies. The vending machine block and ME Vending Uplink do not come with default recipes.

### Required Dependencies:
- GT5U
- ModularUI 2
- NotEnoughItems
- Applied Energistics 2

### Optional Dependencies:
- BetterQuesting
Expand Down
Binary file added img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions src/main/java/com/cubefury/vendingmachine/api/enums/Textures.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.cubefury.vendingmachine.api.enums;

import gregtech.api.enums.Textures.BlockIcons.CustomIcon;
import gregtech.api.interfaces.IIconContainer;

public class Textures {

public static final CustomIcon VM_MACHINE_FRONT_OFF = new CustomIcon("vendingmachine:vending_machine_front_off"),
VM_MACHINE_FRONT_ON = new CustomIcon("vendingmachine:vending_machine_front_on"),
VM_MACHINE_FRONT_ON_GLOW = new CustomIcon("vendingmachine:vending_machine_front_on_glow"),

VM_OVERLAY_0 = new CustomIcon("vendingmachine:vending_machine_overlay_0"),
VM_OVERLAY_1 = new CustomIcon("vendingmachine:vending_machine_overlay_1"),
VM_OVERLAY_2 = new CustomIcon("vendingmachine:vending_machine_overlay_2"),
VM_OVERLAY_3 = new CustomIcon("vendingmachine:vending_machine_overlay_3"),
VM_OVERLAY_4 = new CustomIcon("vendingmachine:vending_machine_overlay_4"),

VM_OVERLAY_ACTIVE_0 = new CustomIcon("vendingmachine:vending_machine_overlay_active_0"),
VM_OVERLAY_ACTIVE_1 = new CustomIcon("vendingmachine:vending_machine_overlay_active_1"),
VM_OVERLAY_ACTIVE_2 = new CustomIcon("vendingmachine:vending_machine_overlay_active_2"),
VM_OVERLAY_ACTIVE_3 = new CustomIcon("vendingmachine:vending_machine_overlay_active_3");

public static final IIconContainer[] VM_OVERLAY_ACTIVE = { VM_OVERLAY_ACTIVE_0, VM_OVERLAY_ACTIVE_1,
VM_OVERLAY_ACTIVE_2, VM_OVERLAY_ACTIVE_3, VM_OVERLAY_4 // bottom right not animated
};

public static final IIconContainer[] VM_OVERLAY = { VM_OVERLAY_0, VM_OVERLAY_1, VM_OVERLAY_2, VM_OVERLAY_3,
VM_OVERLAY_4 };

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.cubefury.vendingmachine.blocks;

import static com.cubefury.vendingmachine.api.enums.Textures.VM_MACHINE_FRONT_OFF;
import static com.cubefury.vendingmachine.api.enums.Textures.VM_MACHINE_FRONT_ON;
import static com.cubefury.vendingmachine.api.enums.Textures.VM_MACHINE_FRONT_ON_GLOW;
import static com.cubefury.vendingmachine.api.enums.Textures.VM_OVERLAY;
import static com.cubefury.vendingmachine.api.enums.Textures.VM_OVERLAY_ACTIVE;
import static gregtech.api.util.GTStructureUtility.ofHatchAdderOptional;

import java.util.ArrayList;
Expand Down Expand Up @@ -40,6 +45,7 @@
import com.cubefury.vendingmachine.trade.TradeManager;
import com.cubefury.vendingmachine.trade.TradeRequest;
import com.cubefury.vendingmachine.util.BigItemStack;
import com.cubefury.vendingmachine.util.OverlayHelper;
import com.gtnewhorizon.structurelib.StructureLibAPI;
import com.gtnewhorizon.structurelib.alignment.IAlignment;
import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits;
Expand All @@ -52,11 +58,13 @@
import gregtech.api.GregTechAPI;
import gregtech.api.covers.CoverRegistry;
import gregtech.api.enums.Textures;
import gregtech.api.interfaces.IIconContainer;
import gregtech.api.interfaces.ISecondaryDescribable;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.implementations.MTEMultiBlockBase;
import gregtech.api.render.RenderOverlay;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.GTUtil;
import gregtech.api.util.GTUtility;
Expand All @@ -82,26 +90,26 @@ public class MTEVendingMachine extends MTEMultiBlockBase
private final ArrayList<MTEVendingUplinkHatch> uplinkHatches = new ArrayList<>();

public static final int INPUT_SLOTS = 6;
public static final int OUTPUT_SLOTS = 4;
public static final int OUTPUT_SLOTS = 6;

public static final int MAX_TRADES = 300;

public static final int STRUCTURE_CHECK_TICKS = 20;

private static final ITexture[] FACING_SIDE = {
TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_ITEM_PIPE_TIN) };
private static final ITexture[] FACING_FRONT = {
TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_BRICKEDBLASTFURNACE_INACTIVE) };
private static final ITexture[] FACING_ACTIVE = {
TextureFactory.of(Textures.BlockIcons.MACHINE_CASING_BRICKEDBLASTFURNACE_ACTIVE), TextureFactory.builder()
.addIcon(Textures.BlockIcons.MACHINE_CASING_BRICKEDBLASTFURNACE_ACTIVE_GLOW)
.glow()
.build() };
private static final ITexture[] FACING_FRONT = { TextureFactory.of(VM_MACHINE_FRONT_OFF) };
private static final ITexture[] FACING_ACTIVE = { TextureFactory.of(VM_MACHINE_FRONT_ON), TextureFactory.builder()
.addIcon(VM_MACHINE_FRONT_ON_GLOW)
.glow()
.build() };
protected final List<RenderOverlay.OverlayTicket> overlayTickets = new ArrayList<>();

private MultiblockTooltipBuilder tooltipBuilder;

public int mUpdate = 0;
public boolean mMachine = false;
private boolean mIsAnimated;

public ItemStackHandler inputItems = new ItemStackHandler(INPUT_SLOTS);
public ItemStackHandler outputItems = new ItemStackHandler(OUTPUT_SLOTS);
Expand All @@ -118,17 +126,24 @@ public class MTEVendingMachine extends MTEMultiBlockBase

public MTEVendingMachine(final int aID, final String aName, final String aNameRegional) {
super(aID, aName, aNameRegional);
this.mIsAnimated = true;
}

protected MTEVendingMachine(String aName) {
super(aName);
this.mIsAnimated = true;
}

@Override
public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
return new MTEVendingMachine(this.mName);
}

public boolean usingAnimations() {
// Logger.INFO("Is animated? "+this.mIsAnimated);
return this.mIsAnimated;
}

public void sendTradeRequest(TradeItemDisplay trade) {
IGregTechTileEntity baseTile = getBaseMetaTileEntity();
if (baseTile == null) {
Expand Down Expand Up @@ -374,11 +389,32 @@ public boolean isFacingValid(ForgeDirection facing) {
public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection side, ForgeDirection facing,
int colorIndex, boolean active, boolean redstoneLevel) {
if (side == facing) {
if (baseMetaTileEntity == null) {
return FACING_FRONT;
}
return active ? FACING_ACTIVE : FACING_FRONT;
}
return FACING_SIDE;
}

protected void setTextureOverlay() {
IGregTechTileEntity tile = getBaseMetaTileEntity();
if (tile == null || tile.isServerSide()) return;

IIconContainer[] vmTextures;
if (getBaseMetaTileEntity().isActive() && usingAnimations()) vmTextures = VM_OVERLAY_ACTIVE;
else vmTextures = VM_OVERLAY;

OverlayHelper.setVMOverlay(
tile.getWorld(),
tile.getXCoord(),
tile.getYCoord(),
tile.getZCoord(),
getExtendedFacing(),
vmTextures,
overlayTickets);
}

@Override
public String[] getDescription() {
return getCurrentDescription();
Expand Down Expand Up @@ -460,7 +496,16 @@ public ExtendedFacing getExtendedFacing() {

@Override
public void setExtendedFacing(ExtendedFacing alignment) {
boolean extendedFacingChanged = alignment != getExtendedFacing();
getBaseMetaTileEntity().setFrontFacing(alignment.getDirection());
if (extendedFacingChanged) {
setTextureOverlay();
}
}

@Override
public void onTextureUpdate() {
setTextureOverlay();
}

@Override
Expand Down Expand Up @@ -491,8 +536,8 @@ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack a

@Override
public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) {
if ((aBaseMetaTileEntity.isClientSide()) && (aBaseMetaTileEntity.isActive())) {
// spawn something maybe
if (aBaseMetaTileEntity.isClientSide() && !aBaseMetaTileEntity.isActive()) {
OverlayHelper.clearVMOverlay(overlayTickets);
}
if (aBaseMetaTileEntity.isServerSide()) {
dispenseItems();
Expand Down Expand Up @@ -537,7 +582,8 @@ public boolean inputItemsSatisfied(List<BigItemStack> fromItems) {
ItemStack aeStackSearch = base.getBaseStack();
aeStackSearch.stackSize = bis.stackSize;
if (this.inputSlotCache.get(base) != null) {
aeStackSearch.stackSize = Math.max(aeStackSearch.stackSize - this.inputSlotCache.get(base), 0);
aeStackSearch.stackSize = Math
.max(aeStackSearch.stackSize - this.inputSlotCache.getOrDefault(base, 0), 0);
}
if (aeStackSearch.stackSize == 0) {
continue;
Expand Down Expand Up @@ -570,8 +616,10 @@ public boolean getActive() {
@Override
public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
super.onFirstTick(aBaseMetaTileEntity);
if (aBaseMetaTileEntity.isClientSide())
if (aBaseMetaTileEntity.isClientSide()) {
StructureLibAPI.queryAlignment((IAlignmentProvider) aBaseMetaTileEntity);
setTextureOverlay();
}
}

@Override
Expand Down Expand Up @@ -611,6 +659,12 @@ public void construct(ItemStack stackSize, boolean hintsOnly) {
hintsOnly);
}

@Override
public void onRemoval() {
super.onRemoval();
if (getBaseMetaTileEntity().isClientSide()) OverlayHelper.clearVMOverlay(overlayTickets);
}

@Override
public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
if (GTUtil.hasMultiblockInputConfiguration(aPlayer.getHeldItem())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public ModularPanel build(PosGuiData guiData, PanelSyncManager syncManager, UISe
.child(createTradeUI((TradeMainPanel) panel, this.tabController));
mainColumn.child(createCoinInventoryRow((TradeMainPanel) panel));
}
mainColumn.child(createInventoryRow(panel, syncManager));
mainColumn.child(createInventoryRow());
panel.child(mainColumn);
panel.child(
new Column().size(20)
Expand Down Expand Up @@ -256,7 +256,7 @@ private void doEjectItems() {
private IWidget createIOColumn(PanelSyncManager syncManager) {
return new ParentWidget<>().excludeAreaInNEI()
.width(50)
.height(160)
.height(178)
.right(-48)
.top(40)
.widgetTheme(WidgetThemes.BACKGROUND_SIDEPANEL)
Expand All @@ -268,7 +268,7 @@ private IWidget createIOColumn(PanelSyncManager syncManager) {
.width(30)
.height(20))
.child(
new Row().child(createInputRow(syncManager).center())
new Row().child(createInputRow().center())
.top(20)
.height(18 * 3))
.child(
Expand All @@ -289,17 +289,17 @@ private IWidget createIOColumn(PanelSyncManager syncManager) {
.child(
GuiTextures.OUTPUT_SPRITE.asWidget()
.leftRel(0.5f)
.bottom(34)
.bottom(52)
.width(30)
.height(20))
.child(
new Row().child(createOutputSlots().center())
.bottom(6)
.height(18 * 2))
.height(18 * 3))
.right(1));
}

private SlotGroupWidget createInputRow(PanelSyncManager syncManager) {
private SlotGroupWidget createInputRow() {
return SlotGroupWidget.builder()
.matrix("II", "II", "II")
.key('I', index -> {
Expand Down Expand Up @@ -334,7 +334,7 @@ private SlotGroupWidget createInputRow(PanelSyncManager syncManager) {

private SlotGroupWidget createOutputSlots() {
return SlotGroupWidget.builder()
.matrix("II", "II")
.matrix("II", "II", "II")
.key('I', index -> {
ModularSlot ms = new ModularSlot(base.outputItems, index).accessibility(false, true)
.slotGroup("outputSlotGroup");
Expand Down Expand Up @@ -474,7 +474,7 @@ private IWidget createCoinInventoryRow(TradeMainPanel panel) {
}

// why is the original method private lmao
private IWidget createInventoryRow(ModularPanel panel, PanelSyncManager syncManager) {
private IWidget createInventoryRow() {
return new Row().widthRel(1)
.height(76)
.alignX(0)
Expand Down
72 changes: 72 additions & 0 deletions src/main/java/com/cubefury/vendingmachine/util/OverlayHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.cubefury.vendingmachine.util;

import java.util.List;

import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;

import gregtech.api.interfaces.IIconContainer;
import gregtech.api.render.RenderOverlay;
import gregtech.api.render.TextureFactory;

public class OverlayHelper {

private static final int[] vmX = new int[] { -1, 0, -1, -1, 0 };
private static final int[] vmY = new int[] { -1, -1, 0, 1, 1 };

public static void clearVMOverlay(List<RenderOverlay.OverlayTicket> overlayTickets) {
overlayTickets.forEach(RenderOverlay.OverlayTicket::remove);
overlayTickets.clear();
}

/**
* Texture Display Front View
* -----
* 0 | 1
* 2 | ~
* 3 | 4
* -----
* Only 0-3 are animated
* 4 is a static texture without glow
*/
public static void setVMOverlay(World world, int x, short y, int z, ExtendedFacing facing,
IIconContainer[] vmTextures, List<RenderOverlay.OverlayTicket> overlayTickets) {
clearVMOverlay(overlayTickets);

int[] tXYZOffset = new int[3];
final ForgeDirection tDirection = facing.getDirection();
facing = ExtendedFacing.of(tDirection);

RenderOverlay overlay = RenderOverlay.getOrCreate(world);

for (int i = 0; i < 5; i++) {
int[] tABCCoord = new int[] { vmX[i], vmY[i], 0 };

facing.getWorldOffset(tABCCoord, tXYZOffset);
int tX = tXYZOffset[0] + x;
int tY = tXYZOffset[1] + y;
int tZ = tXYZOffset[2] + z;

if (i == 4) { // bottom right
overlayTickets.add(overlay.set(x, y, z, tX, tY, tZ, tDirection, TextureFactory.of(vmTextures[i]), 0));
} else {
overlayTickets.add(
overlay.set(
x,
y,
z,
tX,
tY,
tZ,
tDirection,
TextureFactory.builder()
.addIcon(vmTextures[i])
.glow()
.build(),
0));
}
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"animation": {
"frametime": 45,
"width": 16,
"height": 16,
"interpolate": false
}
}

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading