mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 21:17:32 +00:00
Implement Phase 2: Trader Enhancements with stock and currency system
- Add EnumStockReset.java for stock reset timing types - NONE, MCDAILY, MCWEEKLY, MCCUSTOM (MC time) - RLDAILY, RLWEEKLY, RLCUSTOM (real time) - Helper methods for interval calculation and display formatting - Add TraderStock.java for stock management - Per-slot stock limits with -1 for unlimited - Per-player vs per-server stock tracking modes - Automatic reset timer with configurable intervals - PlayerTraderStock inner class for per-player tracking - NBT serialization for persistence - Modify RoleTrader.java to support stock and currency - Add TraderStock instance for stock management - Add useCurrency flag and slotPrices array for virtual currency - Auto-check for stock reset on interact() - Helper methods: hasStock(), getAvailableStock(), consumeStock() - Helper methods: getSlotPrice(), setSlotPrice(), hasSlotPrice() - getTimeUntilResetFormatted() for GUI display - Modify ContainerNPCTrader.java for transactions - Check stock availability before purchase - Handle virtual currency purchases via CurrencyController - Fall back to item-based currency when useCurrency disabled - Consume stock after successful purchase
This commit is contained in:
4 files changed
+535
-5
No files matched your search
@@ -0,0 +1,64 @@
|
||||
package noppes.npcs.constants;
|
||||
|
||||
/**
|
||||
* Stock reset types for Trader NPCs.
|
||||
* Mirrors EnumQuestRepeat pattern for consistency.
|
||||
*/
|
||||
public enum EnumStockReset {
|
||||
NONE, // Never resets
|
||||
MCDAILY, // Every 24000 MC ticks (1 MC day)
|
||||
MCWEEKLY, // Every 168000 MC ticks (7 MC days)
|
||||
MCCUSTOM, // Custom MC tick interval
|
||||
RLDAILY, // Every 24 real hours
|
||||
RLWEEKLY, // Every 7 real days
|
||||
RLCUSTOM; // Custom real-time interval
|
||||
|
||||
/**
|
||||
* Get reset interval in milliseconds for real-time types
|
||||
* or ticks for MC-time types
|
||||
*/
|
||||
public long getDefaultInterval() {
|
||||
switch (this) {
|
||||
case MCDAILY:
|
||||
return 24000; // MC ticks
|
||||
case MCWEEKLY:
|
||||
return 168000; // MC ticks (7 days)
|
||||
case RLDAILY:
|
||||
return 86400000L; // 24 hours in ms
|
||||
case RLWEEKLY:
|
||||
return 604800000L; // 7 days in ms
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this reset type uses real-world time
|
||||
*/
|
||||
public boolean isRealTime() {
|
||||
return this == RLDAILY || this == RLWEEKLY || this == RLCUSTOM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this reset type uses Minecraft time
|
||||
*/
|
||||
public boolean isMinecraftTime() {
|
||||
return this == MCDAILY || this == MCWEEKLY || this == MCCUSTOM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get display name for GUI
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
switch (this) {
|
||||
case NONE: return "Never";
|
||||
case MCDAILY: return "MC Daily";
|
||||
case MCWEEKLY: return "MC Weekly";
|
||||
case MCCUSTOM: return "MC Custom";
|
||||
case RLDAILY: return "Real Daily";
|
||||
case RLWEEKLY: return "Real Weekly";
|
||||
case RLCUSTOM: return "Real Custom";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import noppes.npcs.NoppesUtilPlayer;
|
||||
import noppes.npcs.controllers.CurrencyController;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
import noppes.npcs.roles.RoleTrader;
|
||||
|
||||
@@ -61,17 +62,43 @@ public class ContainerNPCTrader extends ContainerNpcInterface {
|
||||
ItemStack item = slot.getStack();
|
||||
if (!canGivePlayer(item, entityplayer))
|
||||
return null;
|
||||
if (!canBuy(i, entityplayer))
|
||||
return null;
|
||||
if (!isSlotEnabled(i, entityplayer))
|
||||
return null;
|
||||
NoppesUtilPlayer.consumeItem(entityplayer, role.inventoryCurrency.getStackInSlot(i), role.ignoreDamage, role.ignoreNBT);
|
||||
NoppesUtilPlayer.consumeItem(entityplayer, role.inventoryCurrency.getStackInSlot(i + 18), role.ignoreDamage, role.ignoreNBT);
|
||||
|
||||
// Check stock availability
|
||||
String playerName = entityplayer.getCommandSenderName();
|
||||
if (!role.hasStock(i, playerName, 1)) {
|
||||
return null; // Out of stock
|
||||
}
|
||||
|
||||
// Handle currency-based purchase
|
||||
if (role.hasSlotPrice(i)) {
|
||||
long price = role.getSlotPrice(i);
|
||||
if (CurrencyController.Instance == null) {
|
||||
return null; // Currency system not available
|
||||
}
|
||||
if (!CurrencyController.Instance.canAfford(entityplayer, price)) {
|
||||
return null; // Can't afford
|
||||
}
|
||||
// Withdraw currency
|
||||
if (!CurrencyController.Instance.withdraw(entityplayer, price)) {
|
||||
return null; // Withdrawal failed
|
||||
}
|
||||
} else {
|
||||
// Item-based currency - existing logic
|
||||
if (!canBuy(i, entityplayer))
|
||||
return null;
|
||||
NoppesUtilPlayer.consumeItem(entityplayer, role.inventoryCurrency.getStackInSlot(i), role.ignoreDamage, role.ignoreNBT);
|
||||
NoppesUtilPlayer.consumeItem(entityplayer, role.inventoryCurrency.getStackInSlot(i + 18), role.ignoreDamage, role.ignoreNBT);
|
||||
}
|
||||
|
||||
// Consume stock
|
||||
role.consumeStock(i, playerName, 1);
|
||||
|
||||
ItemStack soldItem = item.copy();
|
||||
givePlayer(soldItem, entityplayer);
|
||||
role.addPurchase(i, entityplayer.getDisplayName());
|
||||
return soldItem;
|
||||
|
||||
}
|
||||
|
||||
public boolean isSlotEnabled(int slot, EntityPlayer player) {
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
package noppes.npcs.controllers.data;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import noppes.npcs.constants.EnumStockReset;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Manages trader stock system including:
|
||||
* - Per-slot stock limits
|
||||
* - Per-player vs per-server stock tracking
|
||||
* - Automatic stock reset timers
|
||||
*/
|
||||
public class TraderStock {
|
||||
// Stock configuration
|
||||
public boolean enableStock = false;
|
||||
public boolean perPlayer = false; // false = per-server, true = per-player
|
||||
|
||||
// Reset configuration (mirrors Quest cooldown system)
|
||||
public EnumStockReset resetType = EnumStockReset.NONE;
|
||||
public long customResetTime = 0; // For MCCUSTOM/RLCUSTOM types (in ticks or ms)
|
||||
|
||||
// Stock quantities per slot (max stock, -1 = unlimited)
|
||||
public int[] maxStock = new int[18];
|
||||
|
||||
// Current stock (per-server mode)
|
||||
public int[] currentStock = new int[18];
|
||||
public long lastResetTime = 0;
|
||||
|
||||
// Per-player stock tracking
|
||||
public HashMap<String, PlayerTraderStock> playerStock = new HashMap<>();
|
||||
|
||||
public TraderStock() {
|
||||
for (int i = 0; i < 18; i++) {
|
||||
maxStock[i] = -1; // -1 = unlimited
|
||||
currentStock[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available stock for a slot
|
||||
* @param slot The slot index
|
||||
* @param playerName The player name (for per-player mode)
|
||||
* @return Available stock count, or Integer.MAX_VALUE if unlimited
|
||||
*/
|
||||
public int getAvailableStock(int slot, String playerName) {
|
||||
if (!enableStock || slot < 0 || slot >= 18 || maxStock[slot] < 0) {
|
||||
return Integer.MAX_VALUE; // Unlimited
|
||||
}
|
||||
|
||||
if (perPlayer) {
|
||||
PlayerTraderStock pStock = playerStock.get(playerName);
|
||||
if (pStock == null) {
|
||||
return maxStock[slot]; // Not purchased yet
|
||||
}
|
||||
return pStock.getStock(slot, maxStock[slot]);
|
||||
}
|
||||
|
||||
return Math.max(0, currentStock[slot]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if stock is available for purchase
|
||||
*/
|
||||
public boolean hasStock(int slot, String playerName, int amount) {
|
||||
return getAvailableStock(slot, playerName) >= amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume stock when purchase is made
|
||||
* @return true if successful, false if insufficient stock
|
||||
*/
|
||||
public boolean consumeStock(int slot, String playerName, int amount) {
|
||||
if (!enableStock || slot < 0 || slot >= 18 || maxStock[slot] < 0) {
|
||||
return true; // Unlimited, always succeeds
|
||||
}
|
||||
|
||||
if (perPlayer) {
|
||||
PlayerTraderStock pStock = playerStock.computeIfAbsent(
|
||||
playerName, k -> new PlayerTraderStock());
|
||||
return pStock.consumeStock(slot, maxStock[slot], amount);
|
||||
}
|
||||
|
||||
if (currentStock[slot] >= amount) {
|
||||
currentStock[slot] -= amount;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if stock should reset based on current time
|
||||
* @param currentTime Current MC world time (ticks) or real time (ms) depending on reset type
|
||||
*/
|
||||
public boolean shouldReset(long currentTime) {
|
||||
if (resetType == EnumStockReset.NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long elapsed = currentTime - lastResetTime;
|
||||
long resetInterval = getResetInterval();
|
||||
|
||||
return elapsed >= resetInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all stock to max values
|
||||
* @param currentTime Current time to record as reset time
|
||||
*/
|
||||
public void resetStock(long currentTime) {
|
||||
lastResetTime = currentTime;
|
||||
|
||||
// Reset per-server stock
|
||||
for (int i = 0; i < 18; i++) {
|
||||
currentStock[i] = maxStock[i];
|
||||
}
|
||||
|
||||
// Clear per-player stock
|
||||
playerStock.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reset interval based on reset type
|
||||
* @return Interval in ticks (MC time) or milliseconds (real time)
|
||||
*/
|
||||
public long getResetInterval() {
|
||||
switch (resetType) {
|
||||
case MCDAILY:
|
||||
return 24000; // 1 MC day in ticks
|
||||
case MCWEEKLY:
|
||||
return 168000; // 7 MC days in ticks
|
||||
case MCCUSTOM:
|
||||
return customResetTime; // Custom ticks
|
||||
case RLDAILY:
|
||||
return 86400000L; // 24 hours in ms
|
||||
case RLWEEKLY:
|
||||
return 604800000L; // 7 days in ms
|
||||
case RLCUSTOM:
|
||||
return customResetTime; // Custom ms
|
||||
default:
|
||||
return Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time until next reset
|
||||
* @param currentTime Current time
|
||||
* @return Time remaining until reset, or -1 if no reset scheduled
|
||||
*/
|
||||
public long getTimeUntilReset(long currentTime) {
|
||||
if (resetType == EnumStockReset.NONE) {
|
||||
return -1;
|
||||
}
|
||||
long elapsed = currentTime - lastResetTime;
|
||||
long interval = getResetInterval();
|
||||
return Math.max(0, interval - elapsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format time until reset for display
|
||||
* @param currentTime Current time
|
||||
* @return Formatted string like "2 hours" or "1 day, 5 hours"
|
||||
*/
|
||||
public String getTimeUntilResetFormatted(long currentTime) {
|
||||
long remaining = getTimeUntilReset(currentTime);
|
||||
if (remaining < 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (resetType.isRealTime()) {
|
||||
// Convert ms to readable format
|
||||
long hours = remaining / 3600000L;
|
||||
long days = hours / 24;
|
||||
hours = hours % 24;
|
||||
|
||||
if (days > 0) {
|
||||
return days + " day" + (days != 1 ? "s" : "") +
|
||||
(hours > 0 ? ", " + hours + " hour" + (hours != 1 ? "s" : "") : "");
|
||||
} else if (hours > 0) {
|
||||
return hours + " hour" + (hours != 1 ? "s" : "");
|
||||
} else {
|
||||
long minutes = remaining / 60000L;
|
||||
return minutes + " minute" + (minutes != 1 ? "s" : "");
|
||||
}
|
||||
} else {
|
||||
// Convert ticks to MC time format
|
||||
long mcHours = remaining / 1000; // 1000 ticks = 1 MC hour
|
||||
long mcDays = mcHours / 24;
|
||||
mcHours = mcHours % 24;
|
||||
|
||||
if (mcDays > 0) {
|
||||
return mcDays + " MC day" + (mcDays != 1 ? "s" : "") +
|
||||
(mcHours > 0 ? ", " + mcHours + " MC hour" + (mcHours != 1 ? "s" : "") : "");
|
||||
} else {
|
||||
return mcHours + " MC hour" + (mcHours != 1 ? "s" : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set stock for a specific slot
|
||||
*/
|
||||
public void setMaxStock(int slot, int amount) {
|
||||
if (slot >= 0 && slot < 18) {
|
||||
maxStock[slot] = amount;
|
||||
if (currentStock[slot] < 0 || currentStock[slot] > amount) {
|
||||
currentStock[slot] = amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== NBT Serialization ====================
|
||||
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
|
||||
compound.setBoolean("EnableStock", enableStock);
|
||||
compound.setBoolean("PerPlayer", perPlayer);
|
||||
compound.setInteger("ResetType", resetType.ordinal());
|
||||
compound.setLong("CustomResetTime", customResetTime);
|
||||
compound.setIntArray("MaxStock", maxStock);
|
||||
compound.setIntArray("CurrentStock", currentStock);
|
||||
compound.setLong("LastResetTime", lastResetTime);
|
||||
|
||||
// Save per-player stock
|
||||
NBTTagList playerList = new NBTTagList();
|
||||
for (Map.Entry<String, PlayerTraderStock> entry : playerStock.entrySet()) {
|
||||
NBTTagCompound playerTag = new NBTTagCompound();
|
||||
playerTag.setString("Player", entry.getKey());
|
||||
entry.getValue().writeToNBT(playerTag);
|
||||
playerList.appendTag(playerTag);
|
||||
}
|
||||
compound.setTag("PlayerStock", playerList);
|
||||
|
||||
return compound;
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
enableStock = compound.getBoolean("EnableStock");
|
||||
perPlayer = compound.getBoolean("PerPlayer");
|
||||
|
||||
int resetOrdinal = compound.getInteger("ResetType");
|
||||
if (resetOrdinal >= 0 && resetOrdinal < EnumStockReset.values().length) {
|
||||
resetType = EnumStockReset.values()[resetOrdinal];
|
||||
}
|
||||
|
||||
customResetTime = compound.getLong("CustomResetTime");
|
||||
|
||||
int[] loadedMax = compound.getIntArray("MaxStock");
|
||||
int[] loadedCurrent = compound.getIntArray("CurrentStock");
|
||||
|
||||
if (loadedMax != null && loadedMax.length == 18) {
|
||||
maxStock = loadedMax;
|
||||
}
|
||||
if (loadedCurrent != null && loadedCurrent.length == 18) {
|
||||
currentStock = loadedCurrent;
|
||||
}
|
||||
|
||||
lastResetTime = compound.getLong("LastResetTime");
|
||||
|
||||
// Load per-player stock
|
||||
playerStock.clear();
|
||||
NBTTagList playerList = compound.getTagList("PlayerStock", 10);
|
||||
for (int i = 0; i < playerList.tagCount(); i++) {
|
||||
NBTTagCompound playerTag = playerList.getCompoundTagAt(i);
|
||||
String playerName = playerTag.getString("Player");
|
||||
PlayerTraderStock pStock = new PlayerTraderStock();
|
||||
pStock.readFromNBT(playerTag);
|
||||
playerStock.put(playerName, pStock);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Inner Class for Per-Player Stock ====================
|
||||
|
||||
public static class PlayerTraderStock {
|
||||
public int[] purchasedAmounts = new int[18];
|
||||
public long lastPurchaseTime = 0;
|
||||
|
||||
public PlayerTraderStock() {
|
||||
for (int i = 0; i < 18; i++) {
|
||||
purchasedAmounts[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getStock(int slot, int maxStock) {
|
||||
if (slot < 0 || slot >= 18) return 0;
|
||||
return Math.max(0, maxStock - purchasedAmounts[slot]);
|
||||
}
|
||||
|
||||
public boolean consumeStock(int slot, int maxStock, int amount) {
|
||||
if (slot < 0 || slot >= 18) return false;
|
||||
if (getStock(slot, maxStock) >= amount) {
|
||||
purchasedAmounts[slot] += amount;
|
||||
lastPurchaseTime = System.currentTimeMillis();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void writeToNBT(NBTTagCompound compound) {
|
||||
compound.setIntArray("Purchased", purchasedAmounts);
|
||||
compound.setLong("LastPurchase", lastPurchaseTime);
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
int[] loaded = compound.getIntArray("Purchased");
|
||||
if (loaded != null && loaded.length == 18) {
|
||||
purchasedAmounts = loaded;
|
||||
}
|
||||
lastPurchaseTime = compound.getLong("LastPurchase");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,13 @@ import foxz.utils.Market;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import noppes.npcs.NBTTags;
|
||||
import noppes.npcs.NoppesUtilPlayer;
|
||||
import noppes.npcs.NoppesUtilServer;
|
||||
import noppes.npcs.NpcMiscInventory;
|
||||
import noppes.npcs.constants.EnumGuiType;
|
||||
import noppes.npcs.controllers.data.TraderStock;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -30,6 +32,13 @@ public class RoleTrader extends RoleInterface {
|
||||
public HashMap<String, int[]> playerPurchases;
|
||||
public HashMap<String, int[]> playerDisableSlot;
|
||||
|
||||
// Stock system
|
||||
public TraderStock stock = new TraderStock();
|
||||
|
||||
// Currency system
|
||||
public boolean useCurrency = false; // Use virtual currency instead of items
|
||||
public long[] slotPrices = new long[18]; // Currency prices per slot
|
||||
|
||||
public RoleTrader(EntityNPCInterface npc) {
|
||||
super(npc);
|
||||
inventoryCurrency = new NpcMiscInventory(36);
|
||||
@@ -59,6 +68,20 @@ public class RoleTrader extends RoleInterface {
|
||||
nbttagcompound.setIntArray("Purchases", purchases);
|
||||
nbttagcompound.setTag("PlayerPurchases", NBTTags.nbtStringIntegerArrayMap(playerPurchases));
|
||||
}
|
||||
|
||||
// Stock system
|
||||
nbttagcompound.setTag("Stock", stock.writeToNBT(new NBTTagCompound()));
|
||||
|
||||
// Currency system
|
||||
nbttagcompound.setBoolean("UseCurrency", useCurrency);
|
||||
NBTTagList priceList = new NBTTagList();
|
||||
for (long price : slotPrices) {
|
||||
NBTTagCompound priceTag = new NBTTagCompound();
|
||||
priceTag.setLong("Price", price);
|
||||
priceList.appendTag(priceTag);
|
||||
}
|
||||
nbttagcompound.setTag("SlotPrices", priceList);
|
||||
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
@@ -94,10 +117,39 @@ public class RoleTrader extends RoleInterface {
|
||||
disableSlot = new int[18];
|
||||
for (int i = 0; i < disableSlot.length; ++i) disableSlot[i] = 0;
|
||||
}
|
||||
|
||||
// Stock system
|
||||
if (nbttagcompound.hasKey("Stock")) {
|
||||
stock.readFromNBT(nbttagcompound.getCompoundTag("Stock"));
|
||||
}
|
||||
|
||||
// Currency system
|
||||
useCurrency = nbttagcompound.getBoolean("UseCurrency");
|
||||
if (nbttagcompound.hasKey("SlotPrices")) {
|
||||
NBTTagList priceList = nbttagcompound.getTagList("SlotPrices", 10);
|
||||
for (int i = 0; i < priceList.tagCount() && i < 18; i++) {
|
||||
slotPrices[i] = priceList.getCompoundTagAt(i).getLong("Price");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interact(EntityPlayer player) {
|
||||
// Check for stock reset before opening GUI
|
||||
if (stock.enableStock) {
|
||||
long currentTime = stock.resetType.isRealTime()
|
||||
? System.currentTimeMillis()
|
||||
: player.worldObj.getTotalWorldTime();
|
||||
|
||||
if (stock.shouldReset(currentTime)) {
|
||||
stock.resetStock(currentTime);
|
||||
// Save to market if using shared market
|
||||
if (!marketName.isEmpty()) {
|
||||
Market.save(this, marketName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
npc.say(player, npc.advanced.getInteractLine());
|
||||
try {
|
||||
Market.getMarket(this, marketName);
|
||||
@@ -138,4 +190,78 @@ public class RoleTrader extends RoleInterface {
|
||||
return map.get(name);
|
||||
}
|
||||
|
||||
// ==================== Stock System Methods ====================
|
||||
|
||||
/**
|
||||
* Check if there is stock available for a slot
|
||||
*/
|
||||
public boolean hasStock(int slot, String playerName, int amount) {
|
||||
if (!stock.enableStock) {
|
||||
return true; // Stock system disabled, always available
|
||||
}
|
||||
return stock.hasStock(slot, playerName, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available stock for a slot
|
||||
*/
|
||||
public int getAvailableStock(int slot, String playerName) {
|
||||
if (!stock.enableStock) {
|
||||
return Integer.MAX_VALUE; // Unlimited
|
||||
}
|
||||
return stock.getAvailableStock(slot, playerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume stock after purchase
|
||||
*/
|
||||
public boolean consumeStock(int slot, String playerName, int amount) {
|
||||
if (!stock.enableStock) {
|
||||
return true; // Stock system disabled
|
||||
}
|
||||
boolean consumed = stock.consumeStock(slot, playerName, amount);
|
||||
if (consumed && !marketName.isEmpty()) {
|
||||
Market.save(this, marketName);
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time until stock reset formatted for display
|
||||
*/
|
||||
public String getTimeUntilResetFormatted() {
|
||||
if (!stock.enableStock || stock.resetType == noppes.npcs.constants.EnumStockReset.NONE) {
|
||||
return "";
|
||||
}
|
||||
long currentTime = stock.resetType.isRealTime()
|
||||
? System.currentTimeMillis()
|
||||
: (npc != null && npc.worldObj != null ? npc.worldObj.getTotalWorldTime() : 0);
|
||||
return stock.getTimeUntilResetFormatted(currentTime);
|
||||
}
|
||||
|
||||
// ==================== Currency System Methods ====================
|
||||
|
||||
/**
|
||||
* Get the currency price for a slot
|
||||
*/
|
||||
public long getSlotPrice(int slot) {
|
||||
if (slot < 0 || slot >= 18) return 0;
|
||||
return slotPrices[slot];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the currency price for a slot
|
||||
*/
|
||||
public void setSlotPrice(int slot, long price) {
|
||||
if (slot >= 0 && slot < 18) {
|
||||
slotPrices[slot] = Math.max(0, price);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a slot has a currency price set
|
||||
*/
|
||||
public boolean hasSlotPrice(int slot) {
|
||||
return useCurrency && slot >= 0 && slot < 18 && slotPrices[slot] > 0;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user