// Brass and Sigil -- player-facing economy commands // // /bns help overview of every /bns subcommand // /bns me quick economic status (tier, balance, plots, bounties) // /bns tier upgrade pay spurs to advance to the next tier // // Player-facing tier upgrade pays spurs, increments the NBT tier, and // runs `ftbranks add ` so FTB Ranks applies the rank's // permission nodes (ftbchunks.max_claimed_chunks etc.). // FTB Ranks rank ID per tier number (must match // pack/overrides/world/serverconfig/ftbranks/ranks.snbt) const TIER_RANK_ID = [ null, // 0 unused 'peasant', 'farmer', 'citizen', 'merchant', 'knight', 'baron', 'viscount', 'earl', 'marquess', 'duke', 'archduke', 'grand_duke', 'sovereign', ]; ServerEvents.commandRegistry(event => { const { commands: Commands } = event; const playerCmds = Commands.literal('bns') // /bns help .then(Commands.literal('help').executes(ctx => { const lines = [ '§6═══ Brass and Sigil — economy commands ═══', '§eGeneral:', '§7 /bns help this list', '§7 /bns me your economy status', '§eCivic tier:', '§7 /bns tier upgrade pay spurs to advance to next tier', '§eSpawn plots:', '§7 /bns plot list browse available plots', '§7 /bns plot info details for one plot', '§7 /bns plot buy purchase a plot (uses a tier slot)', '§7 /bns plot release release a plot (50% refund)', '§7 /bns plot mine list plots you own', '§eBazaar (sell raw commodities):', '§7 /bns sell list prices for items you can sell', '§7 /bns sell [count] sell items from your inventory', '§eBounties:', '§7 /bns bounty list today\'s available bounties', '§7 /bns bounty active your accepted bounties', '§7 /bns bounty accept accept a bounty', '§7 /bns bounty cancel drop a bounty (cooldown applies)', '§7 /bns bounty turnin claim reward for a completed bounty', '§7 /bns bounty completed bounties on cooldown', '§eAdmin (op level 2):', '§7 /bns admin info your raw NBT state', '§7 /bns admin tier get|set|list', '§7 /bns admin waystone-count|waystone-set|reset-welcome', ]; for (const l of lines) ctx.source.sendSystemMessage(Text.of(l)); return 1; })) // /bns me — quick status .then(Commands.literal('me').executes(ctx => { const player = ctx.source.player; if (!player) { ctx.source.sendSystemMessage(Text.red('Run from a player context.')); return 0; } const tier = bnsTier.get(player); const cfg = bnsTier.config(tier); const balance = countCoins(player); // shared helper from plots.js const ownedPlots = plotsOwnedBy(player.uuid.toString()); const plotCap = playerPlotSlotCap(player); const activeBounties = getActiveMap(player); const bountyCap = playerBountySlotCap(player); const feePct = bnsTier.effectiveShopFeePct(player); const lines = [ '§6═══ ' + player.username + ' — economy status ═══', '§eCivic tier: §f' + tier + '. ' + cfg.name, '§eSpur balance: §f' + balance, '§ePlots owned: §f' + ownedPlots.length + ' / ' + plotCap, '§eActive bounties: §f' + activeBounties.getAllKeys().size() + ' / ' + bountyCap, '§eBazaar fee: §f' + feePct + '%', '§eWilderness cap: §f' + cfg.wildernessChunks + ' chunks', ]; if (tier < 13) { const next = bnsTier.config(tier + 1); lines.push('§eNext tier: §f' + next.name + ' (' + next.cost + ' spurs to upgrade)'); } else { lines.push('§eNext tier: §f— you are Sovereign, the peak of the realm.'); } for (const l of lines) player.tell(Text.of(l)); return 1; })) // /bns tier upgrade .then(Commands.literal('tier').then(Commands.literal('upgrade').executes(ctx => { const player = ctx.source.player; if (!player) { ctx.source.sendSystemMessage(Text.red('Run from a player context.')); return 0; } const cur = bnsTier.get(player); if (cur >= bnsTier.MAX) { player.tell(Text.gold('You\'re already Sovereign. There is no higher rank.')); return 0; } const nextTier = cur + 1; const nextCfg = bnsTier.config(nextTier); const balance = countCoins(player); if (balance < nextCfg.cost) { player.tell(Text.red( 'Upgrade to ' + nextCfg.name + ' costs ' + nextCfg.cost + ' spurs. You have ' + balance + '.' )); return 0; } const took = takeCoins(player, nextCfg.cost); if (took < nextCfg.cost) { giveCoins(player, took); player.tell(Text.red('Coin removal failed — refunded. Try again.')); return 0; } // Promote via FTB Ranks const rankId = TIER_RANK_ID[nextTier]; Utils.server.runCommandSilent('ftbranks add ' + player.username + ' ' + rankId); // Mirror to NBT bnsTier.set(player, nextTier); player.tell(Text.gold( '╔══ You have been elevated to ' + nextCfg.name + '! ══╗' )); player.tell(Text.gold( ' ' + nextCfg.wildernessChunks + ' wilderness chunks · ' + nextCfg.plotSlots + ' plot slots · ' + nextCfg.dailyBountySlots + ' bounty slots · ' + (Math.max(0, 25 + nextCfg.shopFeeDiscount)) + '% Bazaar fee' )); console.info('[bns/tier] ' + player.username + ' upgraded to tier ' + nextTier + ' (' + nextCfg.name + ') for ' + nextCfg.cost + ' spurs'); return 1; }))); event.register(playerCmds); }); console.info('[bns/player_commands] loaded — /bns help, /bns me, /bns tier upgrade');