Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c699dcc77b | |||
| f39205404a | |||
| b3d46931b2 | |||
| 5d0011d4e2 | |||
| c6fb859db8 | |||
| 86d8f3e80d | |||
| 3e1f5c01ed | |||
| 34e24df0b3 | |||
| ce8304d6cb | |||
| 7eb70bfa78 | |||
| add5803191 |
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"default_packs": [
|
||||||
|
"file/Computer Craft Recreated v1.2.zip"
|
||||||
|
],
|
||||||
|
"default_overrides": [
|
||||||
|
{
|
||||||
|
"id": "file/Computer Craft Recreated v1.2.zip",
|
||||||
|
"default_position": "TOP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# Brass & Sigil KubeJS scripts
|
||||||
|
|
||||||
|
All custom server behaviour lives here. Files in this tree ship via the
|
||||||
|
modpack manifest (see `scripts/Build-Pack.ps1` — `kubejs/` is in
|
||||||
|
`managedRoots`), get synced to both server and client installs, and are
|
||||||
|
loaded by KubeJS on startup.
|
||||||
|
|
||||||
|
## File layout
|
||||||
|
|
||||||
|
```
|
||||||
|
kubejs/
|
||||||
|
├── README.md this file
|
||||||
|
│
|
||||||
|
├── server_scripts/ Loaded by the SERVER's KubeJS on world load.
|
||||||
|
│ ├── recipes_<x>.js Crafting-recipe overhauls per mod.
|
||||||
|
│ ├── waystones_policy.js Waystones placement gating (1/player + bans).
|
||||||
|
│ ├── welcome.js First-join grant: waystone + manual book.
|
||||||
|
│ ├── cc_recipes.js Full ComputerCraft recipe overhaul.
|
||||||
|
│ └── bns_admin.js /bns admin <subcommand> for OP diagnostics.
|
||||||
|
│
|
||||||
|
└── client_scripts/ Loaded by the CLIENT's KubeJS on game load.
|
||||||
|
└── jei_hides.js Hide specific items from the JEI ingredient list.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- **Logging prefix**: every console line uses `[bns/<module>]` so server
|
||||||
|
logs can be filtered with `journalctl -u brass-sigil-server.service |
|
||||||
|
grep '\[bns/'`. Keeps our output separate from mod output.
|
||||||
|
- **One concern per file**. Recipe overhauls live in `recipes_<modname>`.
|
||||||
|
Block/item policy goes in a `<thing>_policy.js`. Don't mix recipe
|
||||||
|
removal with event listeners in the same file.
|
||||||
|
- **Persistent player data** keys are prefixed `bns` to avoid clashing
|
||||||
|
with other mods' use of `player.persistentData`. Currently used keys:
|
||||||
|
- `bnsWaystoneCount` (int) — see `waystones_policy.js`
|
||||||
|
- `bnsWelcomeGranted` (bool) — see `welcome.js`
|
||||||
|
- **Performance**: hot-path event handlers (BlockEvents.placed/broken,
|
||||||
|
PlayerEvents.loggedIn) must stay O(1). Use `Set` for ID lookups, never
|
||||||
|
Array.includes inside an event handler. Avoid Modrinth/network calls
|
||||||
|
in event handlers — never. No periodic-tick polling unless absolutely
|
||||||
|
necessary.
|
||||||
|
- **Server commands** are registered under the `/bns` namespace
|
||||||
|
(`/bns admin ...`, future: `/bns plot ...`). See `bns_admin.js` for
|
||||||
|
the registration pattern.
|
||||||
|
|
||||||
|
## Diagnostics
|
||||||
|
|
||||||
|
When something looks wrong in-game, first port of call:
|
||||||
|
|
||||||
|
1. `/bns admin info` — prints active flags + counts for the running player
|
||||||
|
2. `/bns admin waystone-count <player>` — read stored count
|
||||||
|
3. `/bns admin reset-welcome <player>` — re-trigger the first-join grant
|
||||||
|
4. Server log: `journalctl -u brass-sigil-server.service -f | grep '\[bns/'`
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- `pack/overrides/defaultconfigs/` — first-run mod configs (auto-copied
|
||||||
|
to `config/` by NeoForge on first launch only)
|
||||||
|
- `scripts/Check-Deps.ps1` — pre-flight dep check, runs before any
|
||||||
|
Deploy-Brass `-Stage Pack` deploy
|
||||||
|
- The memory file `project-mc-player-economy.md` for the broader plan
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
// Brass & Sigil — admin commands (/bns admin ...)
|
||||||
|
//
|
||||||
|
// Diagnostic + maintenance commands for OPs. Players without OP level
|
||||||
|
// (>= 2) get a permission-denied response from the command framework.
|
||||||
|
//
|
||||||
|
// Subcommand summary:
|
||||||
|
// /bns admin info state of the calling player
|
||||||
|
// /bns admin waystone-count <player> read stored count
|
||||||
|
// /bns admin waystone-set <player> <n> override stored count
|
||||||
|
// /bns admin reset-welcome <player> clear bnsWelcomeGranted flag
|
||||||
|
// so the welcome grant fires again
|
||||||
|
//
|
||||||
|
// Adding new subcommands: follow the same `Commands.literal(...)
|
||||||
|
// .then(...)` pattern below. Keep handlers cheap -- these are only run
|
||||||
|
// on operator action so performance isn't critical, but make them
|
||||||
|
// readable.
|
||||||
|
|
||||||
|
ServerEvents.commandRegistry(event => {
|
||||||
|
const { commands: Commands, arguments: Arguments } = event;
|
||||||
|
|
||||||
|
const bnsAdmin = Commands.literal('bns')
|
||||||
|
.then(Commands.literal('admin')
|
||||||
|
.requires(src => src.hasPermission(2))
|
||||||
|
|
||||||
|
// /bns admin info
|
||||||
|
.then(Commands.literal('info').executes(ctx => {
|
||||||
|
const player = ctx.source.player;
|
||||||
|
if (!player) {
|
||||||
|
ctx.source.sendSystemMessage(Text.red('Run from a player context.'));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const data = player.persistentData;
|
||||||
|
const lines = [
|
||||||
|
`Player: ${player.username} (${player.uuid})`,
|
||||||
|
`bnsWaystoneCount = ${data.getInt('bnsWaystoneCount')}`,
|
||||||
|
`bnsWelcomeGranted = ${data.getBoolean('bnsWelcomeGranted')}`,
|
||||||
|
];
|
||||||
|
lines.forEach(line => ctx.source.sendSystemMessage(Text.aqua(line)));
|
||||||
|
console.info(`[bns/admin] info: ${player.username} -> ${JSON.stringify({
|
||||||
|
waystones: data.getInt('bnsWaystoneCount'),
|
||||||
|
welcomed: data.getBoolean('bnsWelcomeGranted'),
|
||||||
|
})}`);
|
||||||
|
return 1;
|
||||||
|
}))
|
||||||
|
|
||||||
|
// /bns admin waystone-count <player>
|
||||||
|
.then(Commands.literal('waystone-count')
|
||||||
|
.then(Commands.argument('target', Arguments.PLAYER.create(event))
|
||||||
|
.executes(ctx => {
|
||||||
|
const target = Arguments.PLAYER.getResult(ctx, 'target');
|
||||||
|
const count = target.persistentData.getInt('bnsWaystoneCount');
|
||||||
|
ctx.source.sendSystemMessage(Text.aqua(
|
||||||
|
`${target.username} has bnsWaystoneCount = ${count}`
|
||||||
|
));
|
||||||
|
return 1;
|
||||||
|
})))
|
||||||
|
|
||||||
|
// /bns admin waystone-set <player> <n>
|
||||||
|
.then(Commands.literal('waystone-set')
|
||||||
|
.then(Commands.argument('target', Arguments.PLAYER.create(event))
|
||||||
|
.then(Commands.argument('count', Arguments.INTEGER.create(event, 0, 1000))
|
||||||
|
.executes(ctx => {
|
||||||
|
const target = Arguments.PLAYER.getResult(ctx, 'target');
|
||||||
|
const count = Arguments.INTEGER.getResult(ctx, 'count');
|
||||||
|
target.persistentData.putInt('bnsWaystoneCount', count);
|
||||||
|
ctx.source.sendSystemMessage(Text.gold(
|
||||||
|
`Set ${target.username}'s bnsWaystoneCount = ${count}`
|
||||||
|
));
|
||||||
|
console.info(`[bns/admin] waystone-set: ${target.username} -> ${count}`);
|
||||||
|
return 1;
|
||||||
|
}))))
|
||||||
|
|
||||||
|
// /bns admin reset-welcome <player>
|
||||||
|
.then(Commands.literal('reset-welcome')
|
||||||
|
.then(Commands.argument('target', Arguments.PLAYER.create(event))
|
||||||
|
.executes(ctx => {
|
||||||
|
const target = Arguments.PLAYER.getResult(ctx, 'target');
|
||||||
|
target.persistentData.putBoolean('bnsWelcomeGranted', false);
|
||||||
|
ctx.source.sendSystemMessage(Text.gold(
|
||||||
|
`Cleared bnsWelcomeGranted for ${target.username}. ` +
|
||||||
|
`They'll get the welcome packet again on next login.`
|
||||||
|
));
|
||||||
|
console.info(`[bns/admin] reset-welcome: ${target.username}`);
|
||||||
|
return 1;
|
||||||
|
})))
|
||||||
|
);
|
||||||
|
|
||||||
|
event.register(bnsAdmin);
|
||||||
|
});
|
||||||
@@ -1,36 +1,278 @@
|
|||||||
// Brass & Sigil — ComputerCraft recipe overhaul
|
// Brass & Sigil — ComputerCraft recipe overhaul (full coverage, v3)
|
||||||
//
|
//
|
||||||
// Replaces CC: Tweaked's default crafting recipes with ones that require
|
// Two design principles:
|
||||||
// Create + TFMG materials. This gates the tech tier behind progression
|
// 1. Every electronic CC item contains TFMG plastic_sheet -- plastic is
|
||||||
// (you need plastic refining and Create's precision_mechanism chain
|
// the electrical insulator and the gate that forces players to build
|
||||||
// before you can build computers).
|
// out TFMG's full oil-refining chain (crude oil -> naphtha -> molten
|
||||||
|
// plastic -> sheet) before any CC tech.
|
||||||
|
// 2. Advanced versions contain their basic counterpart in the recipe.
|
||||||
|
// Computer Advanced contains Computer Normal; Monitor Advanced
|
||||||
|
// contains Monitor Normal; etc. This makes the upgrade chain
|
||||||
|
// literal -- you can't skip basic tier, you upgrade through it.
|
||||||
//
|
//
|
||||||
// Items rewritten: computer_normal, computer_advanced, monitor_normal,
|
// Tier outline (with both principles applied):
|
||||||
// monitor_advanced, disk_drive, modem (wired), wireless_modem, speaker,
|
// T1 Cable plastic + copper_wire + redstone (cheap commodity)
|
||||||
// printer, disk. Recipes for cables, peripherals, etc. left at default
|
// T2 Basic CC plastic + brass_casing + electron_tube + p_mech +
|
||||||
// for now -- can iterate later if needed.
|
// steel + silicon-or-cogwheel (Create T2 + TFMG oil
|
||||||
|
// + steel chain)
|
||||||
|
// T3 Networking+bots plastic + electromagnetic_coil + mech_arm/bearing
|
||||||
|
// + constantan_wire (TFMG advanced electrical)
|
||||||
|
// T4 Advanced Basic item + silicon + rose_quartz + gold +
|
||||||
|
// industrial_iron_block (or display_link / large_coil)
|
||||||
|
// T5 Mobile Pocket Normal -> Pocket Advanced via same pattern
|
||||||
|
|
||||||
ServerEvents.recipes(event => {
|
ServerEvents.recipes(event => {
|
||||||
// ─── Computer (Basic) ──────────────────────────────────────────────
|
// ─── T1 - CABLING ──────────────────────────────────────────────────
|
||||||
// Plastic shell, electron tubes (Create's retro vacuum tube fits CC
|
// Cable (x8): plastic insulator + copper_wire core + redstone signal.
|
||||||
// aesthetically), steel frame, precision mechanism core.
|
// Outputs 8 so network laying is still viable.
|
||||||
|
event.remove({ output: 'computercraft:cable' });
|
||||||
|
event.shaped(Item.of('computercraft:cable', 8), [
|
||||||
|
'PWP',
|
||||||
|
'WRW',
|
||||||
|
'PWP',
|
||||||
|
], {
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
W: 'tfmg:copper_wire',
|
||||||
|
R: 'minecraft:redstone',
|
||||||
|
});
|
||||||
|
|
||||||
|
// ─── T2 - BASIC COMPUTING ──────────────────────────────────────────
|
||||||
|
|
||||||
|
// Computer (Basic): plastic shell + electron_tube CPU + brass_casing
|
||||||
|
// chassis + steel reinforcement + precision_mechanism core.
|
||||||
event.remove({ output: 'computercraft:computer_normal' });
|
event.remove({ output: 'computercraft:computer_normal' });
|
||||||
event.shaped('computercraft:computer_normal', [
|
event.shaped('computercraft:computer_normal', [
|
||||||
'PEP',
|
'PEP',
|
||||||
'SCS',
|
'SBS',
|
||||||
'PEP',
|
'PMP',
|
||||||
], {
|
], {
|
||||||
P: 'tfmg:plastic_sheet',
|
P: 'tfmg:plastic_sheet',
|
||||||
E: 'create:electron_tube',
|
E: 'create:electron_tube',
|
||||||
S: 'tfmg:steel_ingot',
|
S: 'tfmg:steel_ingot',
|
||||||
C: 'create:precision_mechanism',
|
B: 'create:brass_casing',
|
||||||
|
M: 'create:precision_mechanism',
|
||||||
});
|
});
|
||||||
|
|
||||||
// ─── Computer (Advanced) ───────────────────────────────────────────
|
// Monitor (Basic): plastic frame + nixie_tube (retro CRT) + glass.
|
||||||
// Same architecture but with silicon (proper semiconductor) and rose
|
event.remove({ output: 'computercraft:monitor_normal' });
|
||||||
// quartz (Create's "data" material).
|
event.shaped('computercraft:monitor_normal', [
|
||||||
|
'PNP',
|
||||||
|
'GGG',
|
||||||
|
'PNP',
|
||||||
|
], {
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
N: 'create:nixie_tube',
|
||||||
|
G: 'minecraft:glass_pane',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disk Drive: plastic frame + cogwheel (spinning read head) +
|
||||||
|
// rose_quartz (data medium) + steel + p_mech.
|
||||||
|
event.remove({ output: 'computercraft:disk_drive' });
|
||||||
|
event.shaped('computercraft:disk_drive', [
|
||||||
|
'PCP',
|
||||||
|
'RQR',
|
||||||
|
'SMS',
|
||||||
|
], {
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
C: 'create:cogwheel',
|
||||||
|
R: 'minecraft:redstone',
|
||||||
|
Q: 'create:rose_quartz',
|
||||||
|
S: 'tfmg:steel_ingot',
|
||||||
|
M: 'create:precision_mechanism',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Floppy Disk: 2 plastic + redstone, shapeless.
|
||||||
|
event.remove({ output: 'computercraft:disk' });
|
||||||
|
event.shapeless('computercraft:disk', [
|
||||||
|
'tfmg:plastic_sheet',
|
||||||
|
'tfmg:plastic_sheet',
|
||||||
|
'minecraft:redstone',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Wired Modem: plastic shell + copper_wire signal lines + brass_casing
|
||||||
|
// chassis + electron_tube amplifier.
|
||||||
|
event.remove({ output: 'computercraft:wired_modem' });
|
||||||
|
event.shaped('computercraft:wired_modem', [
|
||||||
|
'PWP',
|
||||||
|
'BEB',
|
||||||
|
'PWP',
|
||||||
|
], {
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
W: 'tfmg:copper_wire',
|
||||||
|
B: 'create:brass_casing',
|
||||||
|
E: 'create:electron_tube',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wired Modem Full: 1 modem -> block form (toggle).
|
||||||
|
event.remove({ output: 'computercraft:wired_modem_full' });
|
||||||
|
event.shapeless('computercraft:wired_modem_full',
|
||||||
|
['computercraft:wired_modem']);
|
||||||
|
|
||||||
|
// Speaker: plastic + electron_tube amplifier + brass_casing + note_block.
|
||||||
|
event.remove({ output: 'computercraft:speaker' });
|
||||||
|
event.shaped('computercraft:speaker', [
|
||||||
|
'PEP',
|
||||||
|
'BMB',
|
||||||
|
'PNP',
|
||||||
|
], {
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
E: 'create:electron_tube',
|
||||||
|
B: 'create:brass_casing',
|
||||||
|
M: 'create:precision_mechanism',
|
||||||
|
N: 'minecraft:note_block',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Printer: plastic + steel + ink_sac + precision_mech + cogwheel.
|
||||||
|
event.remove({ output: 'computercraft:printer' });
|
||||||
|
event.shaped('computercraft:printer', [
|
||||||
|
'PSP',
|
||||||
|
'IMI',
|
||||||
|
'PCP',
|
||||||
|
], {
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
S: 'tfmg:steel_ingot',
|
||||||
|
I: 'minecraft:ink_sac',
|
||||||
|
M: 'create:precision_mechanism',
|
||||||
|
C: 'create:cogwheel',
|
||||||
|
});
|
||||||
|
|
||||||
|
// ─── T3 - NETWORKING + ROBOTICS ────────────────────────────────────
|
||||||
|
|
||||||
|
// Wireless Modem (Basic): plastic + copper/aluminum wire + TFMG
|
||||||
|
// electromagnetic_coil antenna + brass_casing chassis.
|
||||||
|
event.remove({ output: 'computercraft:wireless_modem_normal' });
|
||||||
|
event.shaped('computercraft:wireless_modem_normal', [
|
||||||
|
'WAW',
|
||||||
|
'PLP',
|
||||||
|
'WBW',
|
||||||
|
], {
|
||||||
|
W: 'tfmg:copper_wire',
|
||||||
|
A: 'tfmg:aluminum_wire',
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
L: 'tfmg:electromagnetic_coil',
|
||||||
|
B: 'create:brass_casing',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Redstone Relay: plastic + copper_wire + electron_tube switching +
|
||||||
|
// brass_casing.
|
||||||
|
event.remove({ output: 'computercraft:redstone_relay' });
|
||||||
|
event.shaped('computercraft:redstone_relay', [
|
||||||
|
'PEP',
|
||||||
|
'RBR',
|
||||||
|
'PEP',
|
||||||
|
], {
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
E: 'create:electron_tube',
|
||||||
|
R: 'minecraft:redstone',
|
||||||
|
B: 'create:brass_casing',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Turtle (Basic): steel + mechanical_bearing (movement axis) +
|
||||||
|
// gantry_shaft (arm reach) + computer_normal (the brain) + chest.
|
||||||
|
// Contains the basic computer, so turtle inherits its plastic cost.
|
||||||
|
event.remove({ output: 'computercraft:turtle_normal' });
|
||||||
|
event.shaped('computercraft:turtle_normal', [
|
||||||
|
'SBS',
|
||||||
|
'GCG',
|
||||||
|
'SHS',
|
||||||
|
], {
|
||||||
|
S: 'tfmg:steel_ingot',
|
||||||
|
B: 'create:mechanical_bearing',
|
||||||
|
G: 'create:gantry_shaft',
|
||||||
|
C: 'computercraft:computer_normal',
|
||||||
|
H: 'minecraft:chest',
|
||||||
|
});
|
||||||
|
|
||||||
|
// ─── T4 - ADVANCED ─────────────────────────────────────────────────
|
||||||
|
// All advanced items: contain their basic counterpart + premium
|
||||||
|
// upgrade materials (silicon, rose_quartz, gold, industrial_iron_blk,
|
||||||
|
// constantan).
|
||||||
|
|
||||||
|
// Computer (Advanced): Computer Normal core, silicon + rose_quartz
|
||||||
|
// upgrades, industrial_iron_block premium chassis, gold trim.
|
||||||
event.remove({ output: 'computercraft:computer_advanced' });
|
event.remove({ output: 'computercraft:computer_advanced' });
|
||||||
event.shaped('computercraft:computer_advanced', [
|
event.shaped('computercraft:computer_advanced', [
|
||||||
|
'GQG',
|
||||||
|
'SCS',
|
||||||
|
'GIG',
|
||||||
|
], {
|
||||||
|
G: 'minecraft:gold_ingot',
|
||||||
|
Q: 'create:rose_quartz',
|
||||||
|
S: 'tfmg:silicon_ingot',
|
||||||
|
C: 'computercraft:computer_normal',
|
||||||
|
I: 'create:industrial_iron_block',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Monitor (Advanced): Monitor Normal as the screen, display_link as
|
||||||
|
// the data binding layer, gold trim + nixie_tube accents, plastic
|
||||||
|
// insulation on the sides.
|
||||||
|
event.remove({ output: 'computercraft:monitor_advanced' });
|
||||||
|
event.shaped('computercraft:monitor_advanced', [
|
||||||
|
'GNG',
|
||||||
|
'PMP',
|
||||||
|
'GDG',
|
||||||
|
], {
|
||||||
|
G: 'minecraft:gold_ingot',
|
||||||
|
N: 'create:nixie_tube',
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
M: 'computercraft:monitor_normal',
|
||||||
|
D: 'create:display_link',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wireless Modem (Advanced): contains Wireless Modem Normal,
|
||||||
|
// wrapped in constantan_wire + spool for high-Q tuning, large_coil
|
||||||
|
// for the powerful antenna, gold trim.
|
||||||
|
event.remove({ output: 'computercraft:wireless_modem_advanced' });
|
||||||
|
event.shaped('computercraft:wireless_modem_advanced', [
|
||||||
|
'WCW',
|
||||||
|
'PMP',
|
||||||
|
'GLG',
|
||||||
|
], {
|
||||||
|
W: 'tfmg:constantan_wire',
|
||||||
|
C: 'tfmg:constantan_spool',
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
M: 'computercraft:wireless_modem_normal',
|
||||||
|
G: 'minecraft:gold_ingot',
|
||||||
|
L: 'tfmg:large_coil',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Turtle (Advanced): contains Computer Advanced (so the upgrade
|
||||||
|
// chain forces Basic -> Computer Normal -> Computer Advanced ->
|
||||||
|
// Turtle Advanced). Mechanical_arm for proper robotic manipulation,
|
||||||
|
// gold trim.
|
||||||
|
event.remove({ output: 'computercraft:turtle_advanced' });
|
||||||
|
event.shaped('computercraft:turtle_advanced', [
|
||||||
|
'GAG',
|
||||||
|
'GCG',
|
||||||
|
'GHG',
|
||||||
|
], {
|
||||||
|
G: 'minecraft:gold_ingot',
|
||||||
|
A: 'create:mechanical_arm',
|
||||||
|
C: 'computercraft:computer_advanced',
|
||||||
|
H: 'minecraft:chest',
|
||||||
|
});
|
||||||
|
|
||||||
|
// ─── T5 - MOBILE (POCKET COMPUTERS) ────────────────────────────────
|
||||||
|
|
||||||
|
// Pocket Computer (Basic): miniaturised. Plastic shell, electron_tube,
|
||||||
|
// silicon CPU, precision_mech, glass pane screen.
|
||||||
|
event.remove({ output: 'computercraft:pocket_computer_normal' });
|
||||||
|
event.shaped('computercraft:pocket_computer_normal', [
|
||||||
|
'PEP',
|
||||||
|
'SMS',
|
||||||
|
'PgP',
|
||||||
|
], {
|
||||||
|
P: 'tfmg:plastic_sheet',
|
||||||
|
E: 'create:electron_tube',
|
||||||
|
S: 'tfmg:silicon_ingot',
|
||||||
|
M: 'create:precision_mechanism',
|
||||||
|
g: 'minecraft:glass_pane',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pocket Computer (Advanced): contains Pocket Computer Normal,
|
||||||
|
// upgraded with rose_quartz, gold-trim, silicon doubled.
|
||||||
|
event.remove({ output: 'computercraft:pocket_computer_advanced' });
|
||||||
|
event.shaped('computercraft:pocket_computer_advanced', [
|
||||||
'PQP',
|
'PQP',
|
||||||
'SCS',
|
'SCS',
|
||||||
'PGP',
|
'PGP',
|
||||||
@@ -38,113 +280,7 @@ ServerEvents.recipes(event => {
|
|||||||
P: 'tfmg:plastic_sheet',
|
P: 'tfmg:plastic_sheet',
|
||||||
Q: 'create:rose_quartz',
|
Q: 'create:rose_quartz',
|
||||||
S: 'tfmg:silicon_ingot',
|
S: 'tfmg:silicon_ingot',
|
||||||
C: 'create:precision_mechanism',
|
C: 'computercraft:pocket_computer_normal',
|
||||||
G: 'minecraft:gold_ingot',
|
G: 'minecraft:gold_ingot',
|
||||||
});
|
});
|
||||||
|
|
||||||
// ─── Monitor (Basic) ───────────────────────────────────────────────
|
|
||||||
event.remove({ output: 'computercraft:monitor_normal' });
|
|
||||||
event.shaped('computercraft:monitor_normal', [
|
|
||||||
'PSP',
|
|
||||||
'GGG',
|
|
||||||
'PSP',
|
|
||||||
], {
|
|
||||||
P: 'tfmg:plastic_sheet',
|
|
||||||
S: 'tfmg:steel_ingot',
|
|
||||||
G: 'minecraft:glass_pane',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Monitor (Advanced) ────────────────────────────────────────────
|
|
||||||
event.remove({ output: 'computercraft:monitor_advanced' });
|
|
||||||
event.shaped('computercraft:monitor_advanced', [
|
|
||||||
'PGP',
|
|
||||||
'gGg',
|
|
||||||
'PGP',
|
|
||||||
], {
|
|
||||||
P: 'tfmg:plastic_sheet',
|
|
||||||
G: 'minecraft:gold_ingot',
|
|
||||||
g: 'minecraft:glass_pane',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Disk Drive ────────────────────────────────────────────────────
|
|
||||||
event.remove({ output: 'computercraft:disk_drive' });
|
|
||||||
event.shaped('computercraft:disk_drive', [
|
|
||||||
'SCS',
|
|
||||||
'RrR',
|
|
||||||
'SSS',
|
|
||||||
], {
|
|
||||||
S: 'tfmg:steel_ingot',
|
|
||||||
C: 'create:precision_mechanism',
|
|
||||||
R: 'minecraft:redstone',
|
|
||||||
r: 'create:rose_quartz',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Floppy Disk ───────────────────────────────────────────────────
|
|
||||||
// Cheap consumable: plastic + redstone (you'll print many).
|
|
||||||
event.remove({ output: 'computercraft:disk' });
|
|
||||||
event.shapeless('computercraft:disk', [
|
|
||||||
'tfmg:plastic_sheet',
|
|
||||||
'minecraft:redstone',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// ─── Wired Modem ───────────────────────────────────────────────────
|
|
||||||
event.remove({ output: 'computercraft:wired_modem' });
|
|
||||||
event.shaped('computercraft:wired_modem', [
|
|
||||||
'SSS',
|
|
||||||
'SrS',
|
|
||||||
'SSS',
|
|
||||||
], {
|
|
||||||
S: 'tfmg:steel_ingot',
|
|
||||||
r: 'create:electron_tube',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Wireless Modem (regular tier) ─────────────────────────────────
|
|
||||||
event.remove({ output: 'computercraft:wireless_modem_normal' });
|
|
||||||
event.shaped('computercraft:wireless_modem_normal', [
|
|
||||||
'SSS',
|
|
||||||
'PrP',
|
|
||||||
'SSS',
|
|
||||||
], {
|
|
||||||
S: 'tfmg:steel_ingot',
|
|
||||||
P: 'tfmg:plastic_sheet',
|
|
||||||
r: 'create:electron_tube',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Wireless Modem (advanced tier) ────────────────────────────────
|
|
||||||
event.remove({ output: 'computercraft:wireless_modem_advanced' });
|
|
||||||
event.shaped('computercraft:wireless_modem_advanced', [
|
|
||||||
'GGG',
|
|
||||||
'PCP',
|
|
||||||
'GGG',
|
|
||||||
], {
|
|
||||||
G: 'minecraft:gold_ingot',
|
|
||||||
P: 'tfmg:plastic_sheet',
|
|
||||||
C: 'create:precision_mechanism',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Speaker ───────────────────────────────────────────────────────
|
|
||||||
event.remove({ output: 'computercraft:speaker' });
|
|
||||||
event.shaped('computercraft:speaker', [
|
|
||||||
'SSS',
|
|
||||||
'PrP',
|
|
||||||
'SnS',
|
|
||||||
], {
|
|
||||||
S: 'tfmg:steel_ingot',
|
|
||||||
P: 'tfmg:plastic_sheet',
|
|
||||||
r: 'create:electron_tube',
|
|
||||||
n: 'minecraft:note_block',
|
|
||||||
});
|
|
||||||
|
|
||||||
// ─── Printer ───────────────────────────────────────────────────────
|
|
||||||
event.remove({ output: 'computercraft:printer' });
|
|
||||||
event.shaped('computercraft:printer', [
|
|
||||||
'SSS',
|
|
||||||
'IrI',
|
|
||||||
'SCS',
|
|
||||||
], {
|
|
||||||
S: 'tfmg:steel_ingot',
|
|
||||||
I: 'minecraft:ink_sac',
|
|
||||||
r: 'minecraft:redstone',
|
|
||||||
C: 'create:precision_mechanism',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
// Brass & Sigil — economy policy (recipe removal)
|
|
||||||
//
|
|
||||||
// Players can't craft Waystones items (they're distributed by the welcome
|
|
||||||
// grant -- see welcome.js -- and any replacements come from the bank
|
|
||||||
// vendor in the future). Players also can't manufacture currency: coins
|
|
||||||
// only enter circulation through the bank exchange (item-in / coin-out).
|
|
||||||
//
|
|
||||||
// Other Numismatics blocks (piggy banks, bank tellers, vendor blocks) stay
|
|
||||||
// craftable -- those are infrastructure, not currency.
|
|
||||||
|
|
||||||
ServerEvents.recipes(event => {
|
|
||||||
// Block ALL crafting of Waystones items. The welcome-grant script
|
|
||||||
// gives each new player exactly one regular waystone; any further
|
|
||||||
// recovery happens via OP /give or future bank vendor.
|
|
||||||
event.remove({ mod: 'waystones' });
|
|
||||||
|
|
||||||
// Block coin manufacturing only -- 5 denominations.
|
|
||||||
// Real registry IDs: spur, bevel, cog, crown, sun.
|
|
||||||
[
|
|
||||||
'numismatics:spur',
|
|
||||||
'numismatics:bevel',
|
|
||||||
'numismatics:cog',
|
|
||||||
'numismatics:crown',
|
|
||||||
'numismatics:sun',
|
|
||||||
].forEach(coin => event.remove({ output: coin }));
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// Brass & Sigil — Numismatics coin recipe removal
|
||||||
|
//
|
||||||
|
// The 5 coin denominations cannot be crafted by players. All currency
|
||||||
|
// enters circulation exclusively through the bank exchange (item-in /
|
||||||
|
// coin-out). Initially with fixed rates admin-configured on Numismatics
|
||||||
|
// vendor blocks; future dynamic-rates layer adjusts based on trade
|
||||||
|
// volume (see project-mc-player-economy.md).
|
||||||
|
//
|
||||||
|
// Other Numismatics items (piggy banks, bank tellers, vendor blocks,
|
||||||
|
// depositors, bank cards) stay craftable -- those are infrastructure,
|
||||||
|
// not currency.
|
||||||
|
|
||||||
|
const COIN_IDS = [
|
||||||
|
'numismatics:spur',
|
||||||
|
'numismatics:bevel',
|
||||||
|
'numismatics:cog',
|
||||||
|
'numismatics:crown',
|
||||||
|
'numismatics:sun',
|
||||||
|
];
|
||||||
|
|
||||||
|
ServerEvents.recipes(event => {
|
||||||
|
COIN_IDS.forEach(coin => event.remove({ output: coin }));
|
||||||
|
console.info(`[bns/recipes_numismatics] removed crafting recipes for ${COIN_IDS.length} coin denominations`);
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// Brass & Sigil — Waystones recipe removal
|
||||||
|
//
|
||||||
|
// All Waystones items are uncraftable. Players never see waystones,
|
||||||
|
// sharestones, portstones, warp plates, warp scrolls or warp stones in
|
||||||
|
// the recipe book or JEI search results (see also jei_hides.js on the
|
||||||
|
// client side).
|
||||||
|
//
|
||||||
|
// Regular waystones are distributed exclusively via the first-join grant
|
||||||
|
// (welcome.js). Replacement waystones for players who break theirs will
|
||||||
|
// come from the bank vendor once the economy ships -- until then OPs
|
||||||
|
// hand them out via /give.
|
||||||
|
|
||||||
|
ServerEvents.recipes(event => {
|
||||||
|
event.remove({ mod: 'waystones' });
|
||||||
|
console.info('[bns/recipes_waystones] removed all waystones recipes');
|
||||||
|
});
|
||||||
@@ -62,6 +62,7 @@ BlockEvents.placed(event => {
|
|||||||
'That block is disabled. Use a regular Waystone (1 per player) ' +
|
'That block is disabled. Use a regular Waystone (1 per player) ' +
|
||||||
'and build transport between distant bases.'
|
'and build transport between distant bases.'
|
||||||
));
|
));
|
||||||
|
console.info(`[bns/waystones_policy] denied ${blockId} placement by ${player.username} (banned)`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,9 +75,11 @@ BlockEvents.placed(event => {
|
|||||||
`You already have ${WAYSTONE_CAP} waystone. Break your existing one ` +
|
`You already have ${WAYSTONE_CAP} waystone. Break your existing one ` +
|
||||||
`to relocate, or build infrastructure to reach distant bases.`
|
`to relocate, or build infrastructure to reach distant bases.`
|
||||||
));
|
));
|
||||||
|
console.info(`[bns/waystones_policy] denied ${blockId} placement by ${player.username} (already at cap ${current})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.putInt('bnsWaystoneCount', current + 1);
|
data.putInt('bnsWaystoneCount', current + 1);
|
||||||
|
console.info(`[bns/waystones_policy] +1 waystone for ${player.username} (now ${current + 1})`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -89,5 +92,6 @@ BlockEvents.broken(event => {
|
|||||||
const current = data.getInt('bnsWaystoneCount');
|
const current = data.getInt('bnsWaystoneCount');
|
||||||
if (current > 0) {
|
if (current > 0) {
|
||||||
data.putInt('bnsWaystoneCount', current - 1);
|
data.putInt('bnsWaystoneCount', current - 1);
|
||||||
|
console.info(`[bns/waystones_policy] -1 waystone for ${player.username} (now ${current - 1})`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ PlayerEvents.loggedIn(event => {
|
|||||||
giveManual(player);
|
giveManual(player);
|
||||||
data.putBoolean(WELCOME_FLAG, true);
|
data.putBoolean(WELCOME_FLAG, true);
|
||||||
player.tell(Text.gold('Welcome to Brass & Sigil. Check your inventory for a Waystone and the server manual.'));
|
player.tell(Text.gold('Welcome to Brass & Sigil. Check your inventory for a Waystone and the server manual.'));
|
||||||
|
console.info(`[bns/welcome] granted starter packet to ${player.username}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// If something goes wrong, don't set the flag -- player gets another chance.
|
// If something goes wrong, don't set the flag -- player gets another chance.
|
||||||
console.error(`[bns/welcome] failed for ${player.username}: ${e}`);
|
console.error(`[bns/welcome] failed for ${player.username}: ${e}`);
|
||||||
|
|||||||
+12
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "Brass-and-Sigil pack.lock.json - generated, do not edit by hand unless you know what you are doing",
|
"$schema": "Brass-and-Sigil pack.lock.json - generated, do not edit by hand unless you know what you are doing",
|
||||||
"name": "Brass and Sigil",
|
"name": "Brass and Sigil",
|
||||||
"version": "0.19.0",
|
"version": "0.20.0",
|
||||||
"minecraft": "1.21.1",
|
"minecraft": "1.21.1",
|
||||||
"loader": {
|
"loader": {
|
||||||
"type": "neoforge",
|
"type": "neoforge",
|
||||||
@@ -558,6 +558,17 @@
|
|||||||
"sha1": "18aa40e1684d1e1833ca53b2a8d7f08548bd7b5b",
|
"sha1": "18aa40e1684d1e1833ca53b2a8d7f08548bd7b5b",
|
||||||
"size": 133729,
|
"size": 133729,
|
||||||
"side": "client"
|
"side": "client"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "modrinth",
|
||||||
|
"slug": "resource-pack-overrides",
|
||||||
|
"versionId": "xf3H2eJV",
|
||||||
|
"version": "v21.1.0-1.21.1-NeoForge",
|
||||||
|
"path": "mods/ResourcePackOverrides-v21.1.0-1.21.1-NeoForge.jar",
|
||||||
|
"url": "https://cdn.modrinth.com/data/YsFycamt/versions/xf3H2eJV/ResourcePackOverrides-v21.1.0-1.21.1-NeoForge.jar",
|
||||||
|
"sha1": "42dddb70cc645a864596439ea95bd56e7a5561ed",
|
||||||
|
"size": 83035,
|
||||||
|
"side": "client"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"defaultServer": {
|
"defaultServer": {
|
||||||
|
|||||||
Reference in New Issue
Block a user