From 0d7b30a5cfc3f851b51276c7dfc2978cae25f223 Mon Sep 17 00:00:00 2001 From: Aryxst Date: Wed, 16 Apr 2025 19:12:21 +0200 Subject: [PATCH] feat: add custom ore registration scripts and Akite ore Add dynamic ore/dust/nugget/block/ingot generation with recipes Implement loot table auto-generation with silk touch/fortune support Add `HarvestLevel` enum and use it across global scripts Blacklist Akite ore from AA's vertical digger Co-authored-by: Phantom <33400200+WhitePhant0m@users.noreply.github.com> --- config/actuallyadditions-common.toml | 2 +- .../craftoria/textures/block/akite_block.png | Bin 0 -> 440 bytes .../textures/block/deepslate_akite_ore.png | Bin 0 -> 749 bytes .../craftoria/textures/item/akite_dust.png | Bin 0 -> 439 bytes .../craftoria/textures/item/akite_ingot.png | Bin 0 -> 298 bytes .../craftoria/textures/item/raw_akite.png | Bin 0 -> 274 bytes .../biome_modifier/ore_deepslate_akite.json | 6 ++ .../ore_deepslate_akite.json | 18 ++++ .../placed_feature/ore_deepslate_akite.json | 48 +++++++++ .../Mods/Craftoria/CustomOres.js | 28 ++++++ .../Mods/Craftoria/OreProcessing.js | 21 ++++ .../server_scripts/Mods/Craftoria/recipes.js | 8 ++ kubejs/server_scripts/init.js | 18 ++++ kubejs/startup_scripts/Globals.js | 27 +++++ kubejs/startup_scripts/Ores.js | 95 ++++++++++++++++++ kubejs/startup_scripts/blocks.js | 26 ++--- 16 files changed, 283 insertions(+), 14 deletions(-) create mode 100644 kubejs/assets/craftoria/textures/block/akite_block.png create mode 100644 kubejs/assets/craftoria/textures/block/deepslate_akite_ore.png create mode 100644 kubejs/assets/craftoria/textures/item/akite_dust.png create mode 100644 kubejs/assets/craftoria/textures/item/akite_ingot.png create mode 100644 kubejs/assets/craftoria/textures/item/raw_akite.png create mode 100644 kubejs/data/craftoria/neoforge/biome_modifier/ore_deepslate_akite.json create mode 100644 kubejs/data/craftoria/worldgen/configured_feature/ore_deepslate_akite.json create mode 100644 kubejs/data/craftoria/worldgen/placed_feature/ore_deepslate_akite.json create mode 100644 kubejs/server_scripts/Mods/Craftoria/CustomOres.js create mode 100644 kubejs/server_scripts/Mods/Craftoria/OreProcessing.js create mode 100644 kubejs/startup_scripts/Ores.js diff --git a/config/actuallyadditions-common.toml b/config/actuallyadditions-common.toml index cf2d1d49b..742ae6a12 100644 --- a/config/actuallyadditions-common.toml +++ b/config/actuallyadditions-common.toml @@ -80,7 +80,7 @@ #By default, the Vertical Digger mines everything that is in the 'forge:ores' block/item tags. If there is one that it can't mine, but should be able to, put its REGISTRY NAME here. These are the actual registered Item Names, the ones you use, for example, when using the /give Command. This Config Option only applies if the miner is in Ores Only Mode. verticalDiggerExtraWhitelist = [] #By default, the Vertical Digger mines everything that is in the 'forge:ores' block/item tags. If there is one that it can mine, but shouldn't be able to, put its REGISTRY NAME here. These are the actual registered Item Names, the ones you use, for example, when using the /give Command. This Config Option will apply in both modes. - verticalDiggerBlacklist = [] + verticalDiggerBlacklist = ["craftoria:deepslate_akite_ore"] #Worldgen Settings [worldgenSettings] diff --git a/kubejs/assets/craftoria/textures/block/akite_block.png b/kubejs/assets/craftoria/textures/block/akite_block.png new file mode 100644 index 0000000000000000000000000000000000000000..fdfdb17800111a35db70308475a18765961c5142 GIT binary patch literal 440 zcmV;p0Z0CcP)Px$a!Eu%R5*=g)4i_RKoExE2jfT-hZ9glgXGe26p=c8aznX7ZXy&xE-lfx2!T@& z@t4B8YZJDywX-w(z2D4^zI%WF;uBcdf>vc=t5v1_R^?=4V&!B5)+R{H zniLF!jkC3h!mo6w402=9natiz=^}q*KC9)vIhk0c0=<$NnW=+)@F#1W9la*mrAxXg zx*aj64yF#Na4nZjtStS0U@p~KRoaWPV;7=d=n#f73-8p*2cu>|_W!Gq%T6|S<{|m* zX^3KSymfecQqZyW!B`}=uN$bFWk`yxW*iG#?aWgvOSNSfuBmHEjAvSvA|NIYVxVKs z(quNFXt$mRDXZnlgWm1lu$e5Ow5sGyr{W@OPx%r%6OXR5*=QlV3?` z-=k$RnVOUmr4)_FwjBUEJ0o7ry<^)Bp^y%MzgR3{+YY&Jn*elK7JA%7*IT_NAp}Y( zZ)l^4UkHH^g045O0hkU3N$x1vsjDR%;Wg&IZ8Fi@OFm!lh8$>VIebsks{A>qbJG4! zroDZiN}=Zh^B+HOwDgJF$0BTP{Xo}S>FkW4X;u7=^BaI@v<+KtWn^uIXB{1MSr((| zG!L^`x-1KT^&Q1Xxm-sJ>Dab|mdRvl0J+>NOf!yB3d1mPYr5Xb*FC&bJ|D~f{_(u2 ziTQy6gb?@uq?DLuoR@QR7>0p4GsC;7DV#!{P)O%^&sC;_K>)7%{UpO-Y}-L8h0nFH zRN7!PokmK@!}FK;T&)7|s8Apj(#fY%j0Xaoot$K(T*gJ$hKGl1u8l6M9yf_b+qk*3 z#O&@a%|k<;mG2i9J)H4C0H147qD3$r46+`LvbtyC{J;R?fdH1ZMX9s_unz~|K!1PV zJx!|;i*<14=TC3g_VzEfw|{Z}ke?IfFRX7`Jo)>Vo8NA^T+DaGT# fL6W%~6H@XYkoG#AJ4pVi00000NkvXXu0mjfj6qzK literal 0 HcmV?d00001 diff --git a/kubejs/assets/craftoria/textures/item/akite_dust.png b/kubejs/assets/craftoria/textures/item/akite_dust.png new file mode 100644 index 0000000000000000000000000000000000000000..472beae74b2c8195e0c095e230a299f5a7306ee3 GIT binary patch literal 439 zcmV;o0Z9IdP)Px$aY;l$R5*>*kUdLdQ4ofob8?S~Xhc|owV)7C{HRl?jpY`yD)`Y}BK`tPVbwn% zB9|LmI}5?u57KC{8WFJ;1x3_GiQ+wHEH++@*Yvwn4a~gHyzjt&U+SZ&7K@4De5oY6 z)^hIq>g%j|eH{SZh&&aBGHwi&Y?gcwNTa=P0TW>;i|I54V_2zHnKg#q29N~cR~X7t zI!%jGs9cVpp2tus#hB;O_YI^DFjp$coH2Bbj?&TD$@1kTPr#!Hw;~K^orn`ZXT}(r zHimYf#~4;$Ug*=BkwSsr2M7Fdj!bR$&{}RpRGot#O3@DNTT80HpDwK#&ga=Em$`5b zfVE79Td7YGJLuM0CXHcXaFCr!1%M0ZIJB0mQrwHs3S5hDWNoaC9h~~U+I)Ls<@lJb zC}KN`*oz{XfGg*C7U8ZYt`>{&Vehk@Gv8OeK_CvuDTM|eL}&xbf3Mbw6Mzp0Kt2fM hwU+lpBq98F>Kz`llB~rP;@bcK002ovPDHLkV1k|?z^niO literal 0 HcmV?d00001 diff --git a/kubejs/assets/craftoria/textures/item/akite_ingot.png b/kubejs/assets/craftoria/textures/item/akite_ingot.png new file mode 100644 index 0000000000000000000000000000000000000000..5b670f7342f6ae84fd6c0fa78f5751f35d87f26f GIT binary patch literal 298 zcmV+_0oDGAP)Px#*lCcegFc3w*EhC1Yh!_SbP@=4WXy`Hr10?K0h%!XFv_L_V1t>5$ zMPg$k0+h+GPA9*wf9C`KMlPkorBqD&WDSyaYTE#SQ`h0jx#HLw-jnXgxOYP)Px#%t=H+R5*>rl0gcCFcd_e8bL~q(K`fsnr?d{x8B2j!8-_ELQ0{vzl$_YOtiY| zz>t_^=Kntk|3lDr})Ip$&xH2#he4J{O~*8xa=%A*q#ZFK#&;Ycqpr|25r{!5WsT?a}SS Y8wE;kL#Og}xc~qF07*qoM6N<$g3OU}E&u=k literal 0 HcmV?d00001 diff --git a/kubejs/data/craftoria/neoforge/biome_modifier/ore_deepslate_akite.json b/kubejs/data/craftoria/neoforge/biome_modifier/ore_deepslate_akite.json new file mode 100644 index 000000000..4f2685022 --- /dev/null +++ b/kubejs/data/craftoria/neoforge/biome_modifier/ore_deepslate_akite.json @@ -0,0 +1,6 @@ +{ + "type": "neoforge:add_features", + "features": "craftoria:ore_deepslate_akite", + "biomes": "#minecraft:has_structure/ancient_city", + "step": "underground_ores" +} diff --git a/kubejs/data/craftoria/worldgen/configured_feature/ore_deepslate_akite.json b/kubejs/data/craftoria/worldgen/configured_feature/ore_deepslate_akite.json new file mode 100644 index 000000000..719e926f2 --- /dev/null +++ b/kubejs/data/craftoria/worldgen/configured_feature/ore_deepslate_akite.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:ore", + "config": { + "targets": [ + { + "target": { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:deepslate_ore_replaceables" + }, + "state": { + "Name": "craftoria:deepslate_akite_ore" + } + } + ], + "size": 3, + "discard_chance_on_air_exposure": 0.1 + } +} diff --git a/kubejs/data/craftoria/worldgen/placed_feature/ore_deepslate_akite.json b/kubejs/data/craftoria/worldgen/placed_feature/ore_deepslate_akite.json new file mode 100644 index 000000000..d7bd3f83a --- /dev/null +++ b/kubejs/data/craftoria/worldgen/placed_feature/ore_deepslate_akite.json @@ -0,0 +1,48 @@ +{ + "feature": "craftoria:ore_deepslate_akite", + "placement": [ + { + "type": "minecraft:count", + "count": 3 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:rarity_filter", + "chance": 3 + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:trapezoid", + "max_inclusive": { + "absolute": -35 + }, + "min_inclusive": { + "absolute": -53 + } + } + }, + { + "direction_of_search": "down", + "target_condition": { + "type": "minecraft:solid" + }, + "allowed_search_condition": { + "blocks": "minecraft:air", + "type": "minecraft:matching_blocks" + }, + "max_steps": 12, + "type": "minecraft:environment_scan" + }, + { + "xz_spread": 0, + "y_spread": 1, + "type": "minecraft:random_offset" + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/kubejs/server_scripts/Mods/Craftoria/CustomOres.js b/kubejs/server_scripts/Mods/Craftoria/CustomOres.js new file mode 100644 index 000000000..2f406e7b4 --- /dev/null +++ b/kubejs/server_scripts/Mods/Craftoria/CustomOres.js @@ -0,0 +1,28 @@ +LootJS.lootTables(event => { + for (let entry in global.customOres) { + for (let oreId of Object.values(getCustomOreVariants(entry))) { + createLootTable(oreId, `raw_${entry}`); + } + } + + /** + * Creates a loot table for the specified ore type. + * @param {string} oreId + * @param {string} rawOre + */ + function createLootTable(oreId, rawOre) { + event + .getBlockTable(oreId) + .clear() + .firstPool(pool => { + pool.rolls(1); + pool.addEntry(LootEntry.of(oreId).matchTool(ItemFilter.hasEnchantment('minecraft:silk_touch'))); + pool.addEntry( + LootEntry.of(`craftoria:${rawOre}`) + .applyOreBonus('minecraft:fortune') + .matchTool(ItemFilter.hasEnchantment('minecraft:silk_touch').negate()) + .survivesExplosion() + ); + }); + } +}); diff --git a/kubejs/server_scripts/Mods/Craftoria/OreProcessing.js b/kubejs/server_scripts/Mods/Craftoria/OreProcessing.js new file mode 100644 index 000000000..1156ae960 --- /dev/null +++ b/kubejs/server_scripts/Mods/Craftoria/OreProcessing.js @@ -0,0 +1,21 @@ +ServerEvents.recipes(event => { + const { occultism } = event.recipes; + const mekanism = MekanismHelper(event); + + for (let entry in global.customOres) { + for (let oreId of Object.values(getCustomOreVariants(entry))) { + occultism.crushing(RecipeResult.of(`craftoria:${entry}_dust`, 4), oreId); + + mekanism.enriching(`2x craftoria:${entry}_dust`, oreId); + + event.smelting(`craftoria:${entry}_ingot`, oreId); + } + occultism.crushing(RecipeResult.of(`craftoria:${entry}_dust`, 2), `craftoria:raw_${entry}`); + + mekanism.crushing(`craftoria:${entry}_dust`, `craftoria:raw_${entry}`); + mekanism.enriching(`4x craftoria:${entry}_dust`, `3x craftoria:raw_${entry}`); + + event.smelting('craftoria:akite_ingot', 'craftoria:akite_dust'); + event.smelting('craftoria:akite_ingot', 'craftoria:raw_akite'); + } +}); diff --git a/kubejs/server_scripts/Mods/Craftoria/recipes.js b/kubejs/server_scripts/Mods/Craftoria/recipes.js index 6b48328e1..e169ada10 100644 --- a/kubejs/server_scripts/Mods/Craftoria/recipes.js +++ b/kubejs/server_scripts/Mods/Craftoria/recipes.js @@ -1,4 +1,12 @@ ServerEvents.recipes(e => { + for (let [entry, ore] of Object.entries(global.customOres)) { + const { block } = ore.registry; + if (block) + e.shaped(`craftoria:${entry}_block`, ['AAA', 'AAA', 'AAA'], { + A: `craftoria:${entry}_ingot`, + }); + } + e.shaped('craftoria:blaze_block', ['AAA', 'AAA', 'AAA'], { A: 'minecraft:blaze_rod', }); diff --git a/kubejs/server_scripts/init.js b/kubejs/server_scripts/init.js index 21414b184..572a6dfa1 100644 --- a/kubejs/server_scripts/init.js +++ b/kubejs/server_scripts/init.js @@ -56,6 +56,24 @@ const getServerLevel = levelAccessor => { return null; }; +/** @param {string} entry A key inside`global.customOres` */ +const getCustomOreVariants = entry => { + const oreVariants = { + stone: `craftoria:${entry}_ore`, + deepslate: `craftoria:deepslate_${entry}_ore`, + nether: `craftoria:nether_${entry}_ore`, + end: `craftoria:end_${entry}_ore`, + }; + + for (const variant in oreVariants) { + if (!global.customOres[entry].worldGen[variant]) { + delete oreVariants[variant]; + } + } + + return oreVariants; +}; + /** * Used for recipe IDs * @param {Special.Mod} mod The mod name diff --git a/kubejs/startup_scripts/Globals.js b/kubejs/startup_scripts/Globals.js index aadadd724..ed0538df9 100644 --- a/kubejs/startup_scripts/Globals.js +++ b/kubejs/startup_scripts/Globals.js @@ -52,4 +52,31 @@ global.customMIMachines = [ // }, ]; +const HarvestLevel = { + WOOD: 'neoforge:needs_wood_tool', + STONE: 'minecraft:needs_stone_tool', + IRON: 'minecraft:needs_iron_tool', + DIAMOND: 'minecraft:needs_diamond_tool', + NETHERITE: 'neoforge:needs_netherite_tool', +}; + +global.HarvestLevel = HarvestLevel; + +global.customOres = { + akite: { + name: 'Akite', + worldGen: { + stone: false, + deepslate: true, + nether: false, + end: false, + harvestLevel: HarvestLevel.NETHERITE, + }, + registry: { + nugget: false, + block: true, + }, + }, +}; + Platform.setModName('craftoria', 'Craftoria'); diff --git a/kubejs/startup_scripts/Ores.js b/kubejs/startup_scripts/Ores.js new file mode 100644 index 000000000..c033c5488 --- /dev/null +++ b/kubejs/startup_scripts/Ores.js @@ -0,0 +1,95 @@ +StartupEvents.registry('block', event => { + for (let [entry, ore] of Object.entries(global.customOres)) { + const { stone, deepslate, nether, end, harvestLevel } = ore.worldGen; + const { block } = ore.registry; + + if (stone) + event + .create(`craftoria:${entry}_ore`) + .displayName(`${ore.name} Ore`) + .soundType(SoundType.STONE) + .hardness(20.0) + .resistance(10.0) + .tagBlock('minecraft:mineable/pickaxe') + .tagBlock('minecraft:mineable/paxel') + .tagBlock('minecraft:mineable/mattock') + .tagBlock(harvestLevel) + .tagBoth('c:ores') + .tagBoth(`c:ores/${entry}`) + .tagBoth('c:ores_in_ground/stone') + .tagBoth('mekanism:miner_blacklist') + .requiresTool(true); + if (deepslate) + event + .create(`craftoria:deepslate_${entry}_ore`) + .displayName(`Deepslate ${ore.name} Ore`) + .soundType(SoundType.DEEPSLATE) + .hardness(25.0) + .resistance(10.0) + .tagBlock('minecraft:mineable/pickaxe') + .tagBlock('minecraft:mineable/paxel') + .tagBlock('minecraft:mineable/mattock') + .tagBlock(harvestLevel) + .tagBoth('c:ores') + .tagBoth(`c:ores/${entry}`) + .tagBoth('c:ores_in_ground/deepslate') + .tagBoth('mekanism:miner_blacklist') + .requiresTool(true); + if (nether) + event + .create(`craftoria:nether_${entry}_ore`) + .displayName(`Nether ${ore.name} Ore`) + .soundType(SoundType.NETHERRACK) + .hardness(15.0) + .resistance(10.0) + .tagBlock('minecraft:mineable/pickaxe') + .tagBlock('minecraft:mineable/paxel') + .tagBlock('minecraft:mineable/mattock') + .tagBlock(harvestLevel) + .tagBoth('c:ores') + .tagBoth(`c:ores/${entry}`) + .tagBoth('c:ores_in_ground/netherrack') + .tagBoth('mekanism:miner_blacklist') + .requiresTool(true); + if (end) + event + .create(`craftoria:end_${entry}_ore`) + .displayName(`End ${ore.name} Ore`) + .soundType(SoundType.STONE) + .hardness(20.0) + .resistance(10.0) + .tagBlock('minecraft:mineable/pickaxe') + .tagBlock('minecraft:mineable/paxel') + .tagBlock('minecraft:mineable/mattock') + .tagBlock(harvestLevel) + .tagBoth('c:ores') + .tagBoth(`c:ores/${entry}`) + .tagBoth('c:ores_in_ground/end_stone') + .tagBoth('mekanism:miner_blacklist') + .requiresTool(true); + + if (block) + event + .create(`craftoria:${entry}_block`) + .displayName(`${ore.name} Block`) + .tagBlock('minecraft:mineable/pickaxe') + .tagBlock('minecraft:mineable/paxel') + .tagBlock('minecraft:mineable/mattock') + .tagBlock(harvestLevel) + .tagBoth('c:storage_blocks') + .tagBoth(`c:storage_blocks/${entry}`) + .requiresTool(true); + } +}); + +StartupEvents.registry('item', event => { + for (let [entry, ore] of Object.entries(global.customOres)) { + if (!Object.values(ore.worldGen).includes(true)) return; + const { nugget } = ore.registry; + + event.create(`craftoria:raw_${entry}`).displayName(`Raw ${ore.name}`).tag('c:raw_materials').tag(`c:raw_materials/${entry}`); + event.create(`craftoria:${entry}_dust`).displayName(`${ore.name} Dust`).tag('c:dusts').tag(`c:dusts/${entry}`); + event.create(`craftoria:${entry}_ingot`).displayName(`${ore.name} Ingot`).tag('c:ingots').tag(`c:ingots/${entry}`); + if (nugget) event.create(`craftoria:${entry}_nugget`).displayName(`${ore.name} Nugget`).tag('c:nuggets').tag(`c:nuggets/${entry}`); + } +}); diff --git a/kubejs/startup_scripts/blocks.js b/kubejs/startup_scripts/blocks.js index 7c5297b71..69184ccaf 100644 --- a/kubejs/startup_scripts/blocks.js +++ b/kubejs/startup_scripts/blocks.js @@ -2,61 +2,61 @@ StartupEvents.registry('block', event => { event .create('craftoria:blaze_block') .displayName('Blaze Block') - .soundType('deepslate_bricks') + .soundType(SoundType.DEEPSLATE_BRICKS) .hardness(3) .resistance(2) .tagBlock('minecraft:mineable/pickaxe') - .tagBlock('minecraft:needs_iron_tool') + .tagBlock(HarvestLevel.IRON) .requiresTool(true); event .create('craftoria:smokey_bricks') .displayName('Smokey Brick') - .soundType('deepslate_bricks') + .soundType(SoundType.DEEPSLATE_BRICKS) .hardness(3) .resistance(2) .tagBlock('minecraft:mineable/pickaxe') - .tagBlock('minecraft:needs_stone_tool') + .tagBlock(HarvestLevel.STONE) .requiresTool(true); event .create('craftoria:smokey_bricks_slab', 'slab') .displayName('Smokey Brick Slab') - .soundType('deepslate_bricks') + .soundType(SoundType.DEEPSLATE_BRICKS) .hardness(3) .resistance(2) .tagBlock('minecraft:mineable/pickaxe') - .tagBlock('minecraft:needs_stone_tool') + .tagBlock(HarvestLevel.STONE) .requiresTool(true); event .create('craftoria:smokey_bricks_stairs', 'stairs') .displayName('Smokey Brick Stairs') - .soundType('deepslate_bricks') + .soundType(SoundType.DEEPSLATE_BRICKS) .hardness(3) .resistance(2) .tagBlock('minecraft:mineable/pickaxe') - .tagBlock('minecraft:needs_stone_tool') + .tagBlock(HarvestLevel.STONE) .requiresTool(true); event .create('craftoria:smokey_bricks_wall', 'wall') .displayName('Smokey Brick Wall') - .soundType('deepslate_bricks') + .soundType(SoundType.DEEPSLATE_BRICKS) .hardness(3) .resistance(2) .tagBlock('minecraft:mineable/pickaxe') - .tagBlock('minecraft:needs_stone_tool') + .tagBlock(HarvestLevel.STONE) .requiresTool(true); event .create('craftoria:smokey_bricks_button', 'button') .displayName('Smokey Brick Button') - .soundType('deepslate_bricks') + .soundType(SoundType.DEEPSLATE_BRICKS) .hardness(3) .resistance(2) .tagBlock('minecraft:mineable/pickaxe') - .tagBlock('minecraft:needs_stone_tool') + .tagBlock(HarvestLevel.STONE) .requiresTool(true); event @@ -72,7 +72,7 @@ StartupEvents.registry('block', event => { .box(13, 8, 7, 16, 10, 9, true) .box(0, 8, 7, 3, 10, 9, true) .box(0, 10, 7, 2, 14, 9, true) - .soundType('metal') + .soundType(SoundType.METAL) .property(BlockProperties.WATERLOGGED) .tagBlock('minecraft:mineable/pickaxe') .tagItem('modern_industrialization:replicator_blacklist')