mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 00:17:27 +00:00
Add auction configuration, timing rules, and finalize design decisions
Design Decisions Added: - Modify Bid feature: auto-reclaim and re-bid from claims - Default 5 auction slots per player (configurable) - 30-day claim expiration (configurable) - Percentage-based minimum bid increment (configurable) - Snipe protection: extend TO 5 minutes when bid near end (configurable) - Auction durations: 2h, 12h, 24h, 48h (configurable) Item Restrictions Updated: - Reuse existing ProfileSlotRequirement (cnpc_profile_slot NBT tag) - Reuse existing SoulbindRequirement (cnpc_soulbind NBT tag) - Add new CNPC_Untradeable attribute Configuration Reference Added: - Full auction.cfg with all settings - Currency configuration - Trader stock configuration - Complete permission nodes table Updated conclusion with all finalized decisions.
This commit is contained in:
1 file changed
+173
-29
@@ -17,12 +17,14 @@ This document outlines the implementation plan for the CustomNPC+ 1.11 update, f
|
||||
- Players can manage their bids from claims
|
||||
- If auction ends while player is offline, they can claim their money later
|
||||
- This keeps the flow consistent with item claims
|
||||
- **Modify Bid Feature**: Players can use a "Modify Bid" button that auto-reclaims their money and applies it to a higher bid amount
|
||||
|
||||
### 2. Permission System
|
||||
**Decision:** Use the **existing CustomNPC+ permission system** used for Profiles.
|
||||
- Pattern: `customnpcs.auction.slots.X` where X is the max slot count
|
||||
- Implementation mirrors `ProfileController.allowSlotPermission()` approach
|
||||
- Uses `CustomNpcsPermissions.hasCustomPermission(player, permissionString)`
|
||||
- **Default**: 5 auction slots per player (configurable)
|
||||
|
||||
### 3. Virtual Currency Storage
|
||||
**Decision:** Currency is **NOT profile slot bound** - all profile slots share the same currency pool per player.
|
||||
@@ -43,9 +45,9 @@ This document outlines the implementation plan for the CustomNPC+ 1.11 update, f
|
||||
|
||||
### 6. Item Trading Restrictions
|
||||
**Decision:** Implement the following restrictions for auction listings:
|
||||
- **Untradeable Attribute**: New item attribute that prevents auction listing
|
||||
- **SlotBound Items**: Cannot be listed (needs to be implemented)
|
||||
- **SoulBound Items**: Cannot be listed (needs to be implemented)
|
||||
- **Untradeable Attribute**: New item attribute (`CNPC_Untradeable`) that prevents auction listing
|
||||
- **ProfileSlot Bound Items**: Use existing `cnpc_profile_slot` NBT tag (from `ProfileSlotRequirement.java`)
|
||||
- **Soulbound Items**: Use existing `cnpc_soulbind` NBT tag (from `SoulbindRequirement.java`)
|
||||
- **Auction House Blacklist**: Configurable list of items that cannot be auctioned
|
||||
|
||||
### 7. Admin Auction Management
|
||||
@@ -54,6 +56,15 @@ This document outlines the implementation plan for the CustomNPC+ 1.11 update, f
|
||||
- Accessible via special admin GUI
|
||||
- Permission-gated for server operators
|
||||
|
||||
### 8. Auction Timing & Bidding Rules
|
||||
**Decision:** Configurable auction timing with snipe protection.
|
||||
- **Claim Expiration**: 30 days by default (configurable) - claims auto-expire after this period
|
||||
- **Bid Increment**: Percentage-based minimum increment (configurable, e.g., 5%)
|
||||
- **Snipe Protection**: When a bid is placed near auction end, extend time TO 5 minutes remaining (never higher)
|
||||
- Extension amount is configurable
|
||||
- Example: If 2 minutes left and bid placed, extend to 5 minutes. If 10 minutes left, no extension.
|
||||
- **Auction Durations**: Configurable default options (2h, 12h, 24h, 48h)
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
@@ -65,9 +76,10 @@ This document outlines the implementation plan for the CustomNPC+ 1.11 update, f
|
||||
5. [Feature 3: Auction House](#feature-3-auction-house)
|
||||
6. [Feature 4: Item Attributes & Restrictions](#feature-4-item-attributes--restrictions)
|
||||
7. [Feature 5: Admin Auction Management](#feature-5-admin-auction-management)
|
||||
8. [Implementation Order](#implementation-order)
|
||||
9. [File Summary](#file-summary)
|
||||
10. [Testing Strategy](#testing-strategy)
|
||||
8. [Configuration Reference](#configuration-reference)
|
||||
9. [Implementation Order](#implementation-order)
|
||||
10. [File Summary](#file-summary)
|
||||
11. [Testing Strategy](#testing-strategy)
|
||||
|
||||
---
|
||||
|
||||
@@ -1775,9 +1787,16 @@ public void onServerTick(TickEvent.ServerTickEvent event) {
|
||||
|
||||
Implement item attribute system to control which items can be traded/auctioned. Items with certain attributes will be blocked from the auction house.
|
||||
|
||||
### 4.2 New Item Attributes
|
||||
### 4.2 Existing Item Requirements (Reuse)
|
||||
|
||||
#### 4.2.1 Untradeable Attribute
|
||||
The codebase already has requirement types that we can leverage:
|
||||
|
||||
| Requirement | NBT Key | File | Purpose |
|
||||
|-------------|---------|------|---------|
|
||||
| ProfileSlot Bound | `cnpc_profile_slot` | `ProfileSlotRequirement.java` | Item bound to specific profile slot |
|
||||
| Soulbound | `cnpc_soulbind` | `SoulbindRequirement.java` | Item bound to specific player UUID |
|
||||
|
||||
### 4.3 New Untradeable Attribute
|
||||
|
||||
A new NBT-based item attribute that marks items as untradeable.
|
||||
|
||||
@@ -1786,27 +1805,35 @@ A new NBT-based item attribute that marks items as untradeable.
|
||||
```java
|
||||
package kamkeel.npcs.controllers.data.attribute;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class ItemTradeAttribute {
|
||||
// New untradeable attribute
|
||||
public static final String TAG_UNTRADEABLE = "CNPC_Untradeable";
|
||||
public static final String TAG_SLOT_BOUND = "CNPC_SlotBound";
|
||||
public static final String TAG_SOUL_BOUND = "CNPC_SoulBound";
|
||||
|
||||
// Existing requirement keys (from ProfileSlotRequirement and SoulbindRequirement)
|
||||
public static final String TAG_PROFILE_SLOT = "cnpc_profile_slot";
|
||||
public static final String TAG_SOULBIND = "cnpc_soulbind";
|
||||
|
||||
/**
|
||||
* Check if item can be traded/auctioned
|
||||
*/
|
||||
public static boolean canTrade(ItemStack item) {
|
||||
public static boolean canTrade(ItemStack item, EntityPlayer player) {
|
||||
if (item == null || !item.hasTagCompound()) {
|
||||
return true;
|
||||
}
|
||||
NBTTagCompound tag = item.getTagCompound();
|
||||
|
||||
// Check all trade-blocking attributes
|
||||
// Check untradeable flag
|
||||
if (tag.getBoolean(TAG_UNTRADEABLE)) return false;
|
||||
if (tag.getBoolean(TAG_SLOT_BOUND)) return false;
|
||||
if (tag.getBoolean(TAG_SOUL_BOUND)) return false;
|
||||
|
||||
// Check profile slot bound (item tied to specific profile slot)
|
||||
if (tag.hasKey(TAG_PROFILE_SLOT)) return false;
|
||||
|
||||
// Check soulbound (item tied to specific player)
|
||||
if (tag.hasKey(TAG_SOULBIND)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1819,7 +1846,11 @@ public class ItemTradeAttribute {
|
||||
if (!item.hasTagCompound()) {
|
||||
item.setTagCompound(new NBTTagCompound());
|
||||
}
|
||||
item.getTagCompound().setBoolean(TAG_UNTRADEABLE, untradeable);
|
||||
if (untradeable) {
|
||||
item.getTagCompound().setBoolean(TAG_UNTRADEABLE, true);
|
||||
} else {
|
||||
item.getTagCompound().removeTag(TAG_UNTRADEABLE);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isUntradeable(ItemStack item) {
|
||||
@@ -1827,14 +1858,14 @@ public class ItemTradeAttribute {
|
||||
return item.getTagCompound().getBoolean(TAG_UNTRADEABLE);
|
||||
}
|
||||
|
||||
public static boolean isSlotBound(ItemStack item) {
|
||||
public static boolean isProfileSlotBound(ItemStack item) {
|
||||
if (item == null || !item.hasTagCompound()) return false;
|
||||
return item.getTagCompound().getBoolean(TAG_SLOT_BOUND);
|
||||
return item.getTagCompound().hasKey(TAG_PROFILE_SLOT);
|
||||
}
|
||||
|
||||
public static boolean isSoulBound(ItemStack item) {
|
||||
public static boolean isSoulbound(ItemStack item) {
|
||||
if (item == null || !item.hasTagCompound()) return false;
|
||||
return item.getTagCompound().getBoolean(TAG_SOUL_BOUND);
|
||||
return item.getTagCompound().hasKey(TAG_SOULBIND);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1845,15 +1876,15 @@ public class ItemTradeAttribute {
|
||||
NBTTagCompound tag = item.getTagCompound();
|
||||
|
||||
if (tag.getBoolean(TAG_UNTRADEABLE)) return "gui.auction.untradeable";
|
||||
if (tag.getBoolean(TAG_SLOT_BOUND)) return "gui.auction.slotbound";
|
||||
if (tag.getBoolean(TAG_SOUL_BOUND)) return "gui.auction.soulbound";
|
||||
if (tag.hasKey(TAG_PROFILE_SLOT)) return "gui.auction.profileslotbound";
|
||||
if (tag.hasKey(TAG_SOULBIND)) return "gui.auction.soulbound";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 Auction House Item Blacklist
|
||||
### 4.4 Auction House Item Blacklist
|
||||
|
||||
A configurable system to blacklist specific items from being auctioned.
|
||||
|
||||
@@ -1980,7 +2011,7 @@ public class AuctionBlacklist {
|
||||
}
|
||||
```
|
||||
|
||||
### 4.4 Integration with Auction Listing
|
||||
### 4.5 Integration with Auction Listing
|
||||
|
||||
Modify `AuctionController.createListing()` to check restrictions:
|
||||
|
||||
@@ -2196,6 +2227,115 @@ The Admin GUI can be accessed via:
|
||||
|
||||
---
|
||||
|
||||
## Configuration Reference
|
||||
|
||||
All auction and market settings will be added to the configuration system.
|
||||
|
||||
### Auction Configuration
|
||||
|
||||
**File: `config/customnpcs/auction.cfg`** (or section in existing config)
|
||||
|
||||
```properties
|
||||
# ===========================================
|
||||
# Auction House Configuration
|
||||
# ===========================================
|
||||
|
||||
# General Settings
|
||||
# ----------------
|
||||
# Enable/disable the auction house system
|
||||
B:AuctionEnabled=true
|
||||
|
||||
# Default maximum auction listings per player (without permission override)
|
||||
I:DefaultMaxListings=5
|
||||
|
||||
# Listing fee as percentage of starting price (0.0 = no fee)
|
||||
D:ListingFeePercent=0.0
|
||||
|
||||
# Sales tax as percentage taken from final sale price (0.05 = 5%)
|
||||
D:SalesTaxPercent=0.05
|
||||
|
||||
# Require an Auctioneer NPC to access auction house
|
||||
B:RequireAuctioneerNPC=true
|
||||
|
||||
# Timing Settings
|
||||
# ---------------
|
||||
# Available auction durations in hours (comma-separated)
|
||||
S:AvailableDurations=2,12,24,48
|
||||
|
||||
# Default auction duration in hours
|
||||
I:DefaultDurationHours=24
|
||||
|
||||
# Claim expiration in days (claims auto-expire after this period, 0 = never)
|
||||
I:ClaimExpirationDays=30
|
||||
|
||||
# Bidding Rules
|
||||
# -------------
|
||||
# Minimum bid increment as percentage (0.05 = 5% minimum increase)
|
||||
D:MinBidIncrementPercent=0.05
|
||||
|
||||
# Snipe protection: extend auction TO this many minutes when bid placed near end
|
||||
# Set to 0 to disable snipe protection
|
||||
I:SnipeProtectionMinutes=5
|
||||
|
||||
# How many minutes before end triggers snipe protection
|
||||
# (bids placed with less than this remaining will extend the auction)
|
||||
I:SnipeProtectionThreshold=5
|
||||
|
||||
# Permissions
|
||||
# -----------
|
||||
# Permission pattern for auction slot limits: customnpcs.auction.slots.X
|
||||
# Players without any permission get DefaultMaxListings
|
||||
# Example: Player with customnpcs.auction.slots.10 can have 10 listings
|
||||
```
|
||||
|
||||
### Currency Configuration
|
||||
|
||||
```properties
|
||||
# ===========================================
|
||||
# Currency System Configuration
|
||||
# ===========================================
|
||||
|
||||
# Use VaultAPI if available on Bukkit hybrid servers
|
||||
B:UseVaultIfAvailable=true
|
||||
|
||||
# Fallback currency item (registry name) when Vault unavailable
|
||||
# Leave empty to disable fallback currency
|
||||
S:FallbackCurrencyItem=customnpcs:npcCoinGold
|
||||
|
||||
# Conversion ratio: 1 fallback item = X virtual currency
|
||||
D:FallbackItemRatio=1.0
|
||||
```
|
||||
|
||||
### Trader Stock Configuration
|
||||
|
||||
```properties
|
||||
# ===========================================
|
||||
# Trader Stock Configuration
|
||||
# ===========================================
|
||||
|
||||
# Enable stock system by default for new traders
|
||||
B:EnableStockByDefault=false
|
||||
|
||||
# Default stock reset type (NONE, MCDAILY, MCWEEKLY, RLDAILY, RLWEEKLY)
|
||||
S:DefaultResetType=NONE
|
||||
```
|
||||
|
||||
### Permission Nodes
|
||||
|
||||
| Permission | Description | Default |
|
||||
|------------|-------------|---------|
|
||||
| `customnpcs.auction.use` | Access auction house | true |
|
||||
| `customnpcs.auction.sell` | Create auction listings | true |
|
||||
| `customnpcs.auction.buy` | Bid and buyout auctions | true |
|
||||
| `customnpcs.auction.slots.X` | Have X maximum listings | - |
|
||||
| `customnpcs.auction.admin` | Access admin management | op |
|
||||
| `customnpcs.auction.manage` | Modify/cancel any listing | op |
|
||||
| `customnpcs.auction.blacklist` | Manage item blacklist | op |
|
||||
| `customnpcs.auction.bypass.fee` | Bypass listing fees | op |
|
||||
| `customnpcs.auction.bypass.tax` | Bypass sales tax | op |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Order
|
||||
|
||||
The features should be implemented in this order due to dependencies:
|
||||
@@ -2400,17 +2540,21 @@ This implementation plan provides a comprehensive roadmap for the CustomNPC+ 1.1
|
||||
|
||||
1. **Currency System** provides the foundation for monetary transactions (shared across profile slots)
|
||||
2. **Trader Enhancements** modernize the existing trader with stock, currency support, and reset timer banners
|
||||
3. **Item Attributes & Restrictions** control which items can be traded via Untradeable, SlotBound, SoulBound attributes and blacklists
|
||||
4. **Auction House** creates a global marketplace with claims-based refunds and permission-based slot limits
|
||||
3. **Item Attributes & Restrictions** control which items can be traded via Untradeable, ProfileSlot Bound, and Soulbound attributes plus blacklists
|
||||
4. **Auction House** creates a global marketplace with claims-based refunds, bid modification, and permission-based slot limits
|
||||
5. **Admin Management** provides comprehensive tools for server operators to manage the auction house in real-time
|
||||
|
||||
The implementation follows existing codebase patterns (permission system from Profiles, gold coin from CustomItems) and can be developed incrementally, with each phase building on the previous one.
|
||||
The implementation follows existing codebase patterns (permission system from Profiles, gold coin from CustomItems, existing requirement types) and can be developed incrementally, with each phase building on the previous one.
|
||||
|
||||
### Key Design Decisions Summary
|
||||
- Outbid refunds → Claims (not direct to balance)
|
||||
- Outbid refunds → Claims (not direct to balance) with **Modify Bid** feature
|
||||
- Currency → Shared across all profile slots per player
|
||||
- Permissions → Uses existing CustomNPC+ permission pattern
|
||||
- Permissions → Uses existing CustomNPC+ permission pattern (default: 5 slots)
|
||||
- Display icon → Existing `CustomItems.coinGold`
|
||||
- Stock reset timer → Banner displayed ABOVE the trader GUI
|
||||
- Trade restrictions → Untradeable attribute + SlotBound/SoulBound + Blacklist system
|
||||
- Trade restrictions → New Untradeable + existing ProfileSlotRequirement/SoulbindRequirement + Blacklist
|
||||
- Claim expiration → 30 days default (configurable)
|
||||
- Bid increment → Percentage-based minimum (configurable, e.g., 5%)
|
||||
- Snipe protection → Extend TO 5 minutes when bid placed near end (configurable)
|
||||
- Auction durations → 2h, 12h, 24h, 48h (configurable)
|
||||
- Admin tools → Full management GUI with audit logging
|
||||
Reference in new issue
Block a user