Files
CustomNPC-Plus/src/main/java/noppes/npcs/containers/ContainerNPCTrader.java
T

193 lines
7.6 KiB
Java
Raw Normal View History

2018-09-13 12:03:28 -04:00
package noppes.npcs.containers;
import net.minecraft.entity.player.EntityPlayer;
2026-01-22 12:38:56 -05:00
import net.minecraft.entity.player.EntityPlayerMP;
2018-09-13 12:03:28 -04:00
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import noppes.npcs.NoppesUtilPlayer;
2026-01-22 12:38:56 -05:00
import noppes.npcs.controllers.data.PlayerData;
2018-09-13 12:03:28 -04:00
import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.roles.RoleTrader;
2025-03-13 17:14:45 -04:00
public class ContainerNPCTrader extends ContainerNpcInterface {
public RoleTrader role;
2026-01-22 12:38:56 -05:00
private final EntityNPCInterface npc;
// Layout constants for 256px wide GUI
public static final int COLUMN_WIDTH = 80;
public static final int COLUMN_START_X = 8;
public static final int ROW_HEIGHT = 22;
public static final int ROW_START_Y = 6;
// Slot offsets within each column (for 18x18 slots, items render centered)
public static final int CURRENCY1_OFFSET = 2; // Primary currency slot
public static final int CURRENCY2_OFFSET = 20; // Secondary currency slot
public static final int OUTPUT_OFFSET = 50; // Output slot
2018-09-13 12:03:28 -04:00
2025-03-13 17:14:45 -04:00
public ContainerNPCTrader(EntityNPCInterface npc, EntityPlayer player) {
super(player);
2026-01-22 12:38:56 -05:00
this.npc = npc;
2018-09-13 12:03:28 -04:00
role = (RoleTrader) npc.roleInterface;
2026-01-22 12:38:56 -05:00
// Register this player as viewing the trader (server-side only)
// Needed for shared stock (not per-player) to sync updates to other viewers
// Works for both linked markets (MarketRegistry) and normal traders (local viewers)
if (player instanceof EntityPlayerMP && !role.stock.perPlayer) {
role.registerViewer((EntityPlayerMP) player);
}
// Trade slots: 3 columns x 6 rows, 80px column width
// Layout per column: [Slot1][Slot2] = [Output]
2025-03-13 17:14:45 -04:00
for (int i = 0; i < 18; i++) {
2026-01-22 12:38:56 -05:00
int col = i % 3;
int row = i / 3;
int x = COLUMN_START_X + col * COLUMN_WIDTH;
int y = ROW_START_Y + row * ROW_HEIGHT;
// Output slot position (slot texture is 18x18, item renders centered at +1)
addSlotToContainer(new Slot(role.inventorySold, i, x + OUTPUT_OFFSET + 1, y + 1));
2018-09-13 12:03:28 -04:00
}
2025-03-13 17:14:45 -04:00
for (int i1 = 0; i1 < 3; i1++) {
for (int l1 = 0; l1 < 9; l1++) {
2026-01-22 12:38:56 -05:00
addSlotToContainer(new Slot(player.inventory, l1 + i1 * 9 + 9, 48 + l1 * 18, 137 + i1 * 18));
2018-09-13 12:03:28 -04:00
}
}
2026-01-22 12:38:56 -05:00
// Player hotbar
2025-03-13 17:14:45 -04:00
for (int j1 = 0; j1 < 9; j1++) {
2026-01-22 12:38:56 -05:00
addSlotToContainer(new Slot(player.inventory, j1, 48 + j1 * 18, 195));
}
}
@Override
public void onContainerClosed(EntityPlayer player) {
super.onContainerClosed(player);
// Unregister this player from viewer tracking (only if registered for shared stock)
if (player instanceof EntityPlayerMP && !role.stock.perPlayer) {
role.unregisterViewer((EntityPlayerMP) player);
2018-09-13 12:03:28 -04:00
}
}
@Override
2025-03-13 17:14:45 -04:00
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int i) {
2018-09-13 12:03:28 -04:00
return null;
}
2025-03-13 17:14:45 -04:00
2018-09-13 12:03:28 -04:00
@Override
2025-03-13 17:14:45 -04:00
public ItemStack slotClick(int i, int j, int par3, EntityPlayer entityplayer) {
if (par3 == 6)
par3 = 0;
if (i < 0 || i >= 18)
return super.slotClick(i, j, par3, entityplayer);
if (j == 1)
return null;
Slot slot = (Slot) inventorySlots.get(i);
if (slot == null || slot.getStack() == null)
return null;
2018-09-13 12:03:28 -04:00
ItemStack item = slot.getStack();
2025-03-13 17:14:45 -04:00
if (!canGivePlayer(item, entityplayer))
return null;
if (!isSlotEnabled(i, entityplayer))
return null;
// Check stock availability
String playerName = entityplayer.getCommandSenderName();
if (!role.hasStock(i, playerName, 1)) {
return null; // Out of stock
}
2026-01-22 12:38:56 -05:00
// Item-based currency
if (!canBuy(i, entityplayer))
return null;
// Currency cost check (additive to item costs)
long currencyCost = role.getCurrencyCost(i);
if (currencyCost > 0) {
PlayerData data = PlayerData.get(entityplayer);
2026-01-24 15:11:50 -05:00
if (data.tradeData.getBalance() < currencyCost) {
2026-01-22 12:38:56 -05:00
return null; // Can't afford currency cost
}
2026-01-22 12:38:56 -05:00
}
// Consume item currency
NoppesUtilPlayer.consumeItem(entityplayer, role.inventoryCurrency.getStackInSlot(i), role.ignoreDamage, role.ignoreNBT);
NoppesUtilPlayer.consumeItem(entityplayer, role.inventoryCurrency.getStackInSlot(i + 18), role.ignoreDamage, role.ignoreNBT);
// Withdraw currency cost (after item consumption to maintain order)
if (currencyCost > 0) {
PlayerData data = PlayerData.get(entityplayer);
2026-01-24 15:11:50 -05:00
data.tradeData.withdraw(currencyCost);
}
// Consume stock
role.consumeStock(i, playerName, 1);
2018-09-13 12:03:28 -04:00
ItemStack soldItem = item.copy();
givePlayer(soldItem, entityplayer);
role.addPurchase(i, entityplayer.getDisplayName());
2026-01-22 12:38:56 -05:00
// Sync updated data after purchase
// For per-player stocks: sync only to the purchasing player
// For shared stocks: consumeStock() handles sync (market-wide or local)
if (entityplayer instanceof EntityPlayerMP) {
if (role.stock.perPlayer) {
// Per-player: only sync to purchasing player (their own stock/balance)
role.syncToPlayer((EntityPlayerMP) entityplayer);
}
// Shared stock sync is already handled in consumeStock()
}
2018-09-13 12:03:28 -04:00
return soldItem;
}
2025-03-13 17:14:45 -04:00
2022-05-26 01:43:17 -05:00
public boolean isSlotEnabled(int slot, EntityPlayer player) {
2025-03-13 17:14:45 -04:00
return role.isSlotEnabled(slot, player.getDisplayName());
2022-05-26 01:43:17 -05:00
}
2025-03-13 17:14:45 -04:00
2018-09-13 12:03:28 -04:00
public boolean canBuy(int slot, EntityPlayer player) {
2025-03-13 17:14:45 -04:00
ItemStack currency = role.inventoryCurrency.getStackInSlot(slot);
ItemStack currency2 = role.inventoryCurrency.getStackInSlot(slot + 18);
if (currency == null && currency2 == null)
return true;
if (currency == null) {
currency = currency2;
currency2 = null;
}
if (NoppesUtilPlayer.compareItems(currency, currency2, role.ignoreDamage, role.ignoreNBT)) {
currency = currency.copy();
currency.stackSize += currency2.stackSize;
currency2 = null;
}
if (currency2 == null)
return NoppesUtilPlayer.compareItems(player, currency, role.ignoreDamage, role.ignoreNBT);
return NoppesUtilPlayer.compareItems(player, currency, role.ignoreDamage, role.ignoreNBT) && NoppesUtilPlayer.compareItems(player, currency2, role.ignoreDamage, role.ignoreNBT);
2018-09-13 12:03:28 -04:00
}
2025-03-13 17:14:45 -04:00
private boolean canGivePlayer(ItemStack item, EntityPlayer entityplayer) {//check Item being held with the mouse
2018-09-13 12:03:28 -04:00
ItemStack itemstack3 = entityplayer.inventory.getItemStack();
2025-03-13 17:14:45 -04:00
if (itemstack3 == null) {
return true;
} else if (NoppesUtilPlayer.compareItems(itemstack3, item, false, false)) {
2018-09-13 12:03:28 -04:00
int k1 = item.stackSize;
2025-03-13 17:14:45 -04:00
if (k1 > 0 && k1 + itemstack3.stackSize <= itemstack3.getMaxStackSize()) {
2018-09-13 12:03:28 -04:00
return true;
}
}
return false;
}
2025-03-13 17:14:45 -04:00
private void givePlayer(ItemStack item, EntityPlayer entityplayer) {//set item bought to the held mouse item
2018-09-13 12:03:28 -04:00
ItemStack itemstack3 = entityplayer.inventory.getItemStack();
2025-03-13 17:14:45 -04:00
if (itemstack3 == null) {
entityplayer.inventory.setItemStack(item);
} else if (NoppesUtilPlayer.compareItems(itemstack3, item, false, false)) {
2018-09-13 12:03:28 -04:00
int k1 = item.stackSize;
2025-03-13 17:14:45 -04:00
if (k1 > 0 && k1 + itemstack3.stackSize <= itemstack3.getMaxStackSize()) {
2018-09-13 12:03:28 -04:00
itemstack3.stackSize += k1;
}
}
}
}