Skip to content

Commit caa470f

Browse files
authored
Generate the Base Minerals 1.10 ore models (#38)
Use KiriCattus's overlays on vanilla stone and keep support for full ore textures.
2 parents 44942d2 + 6ffd701 commit caa470f

18 files changed

Lines changed: 241 additions & 48 deletions

File tree

‎CHANGELOG.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Update the Base Metals and OreSpawn dependencies and move the Java packages to z
55
Use OreSpawn 4 for ore generation, with new depths and deposit shapes for the seven minerals. Existing chunks are not regenerated.
66
Fix material and fluid switches, charcoal ownership, disabled-content recipes and achievements, and client models and molten textures.
77
Add restart-required material settings to Forge Mods and OreSpawn Mods, plus automated build, compatibility and world-generation checks.
8+
Use KiriCattus's ore overlays for all seven ores. Generate the models during the build, with support for full ore textures as well.
89

910
Known issues:
1011
- OreSpawn 4.1.2 can add a second lithium rule when an OS1-imported world is moved without its original global import file.

‎README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ materials, ingots, blends and molten forms. Charcoal uses the material supplied
66
by Base Metals. Silicon is made from sand and coal or charcoal dust; it does
77
not generate as ore.
88

9+
The seven ores use KiriCattus's overlays on Minecraft's stone texture.
10+
911
This branch targets Minecraft 1.10.2 and Forge 12.18.3.2511 or later. It requires
1012
Base Metals 2.5.1.110021 and OreSpawn 4.1.2.110021, or compatible versions in the
1113
declared ranges. Mineralogy is optional. Tinkers' Construct adds melting and

‎build.gradle‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ tasks.named('jar', Jar) {
169169
}
170170

171171
ext.baseMineralsBuild = [developmentOutput: developmentOutput].asImmutable()
172+
apply from: 'gradle/ore-models.gradle'
172173
apply from: 'gradle/release/artifacts.gradle'
173174
apply from: 'gradle/release/publishing.gradle'
174175
apply from: 'gradle/verification/runtime.gradle'

‎docs/BUILDING.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ ForgeGradle's `source-sets-not-merged-for-eclipse` diagnostic refers to its own
4444
automatic merge. This project deliberately merges production output itself;
4545
the generated profiles, Buildship model and Java 8 Eclipse compiler are audited.
4646

47+
## Ore models
48+
49+
`generateOreModels` writes the ore block models to `build/generated/ore-models`.
50+
The normal build includes them in the game and sources jars. Blockstates and
51+
inventory models use the existing model names.
52+
53+
The seven ores use KiriCattus's transparent PNGs in
54+
`src/main/resources/assets/baseminerals/textures/blocks/ore_overlays/`. The build
55+
layers each PNG over Minecraft stone for the block and inventory models.
56+
An ore with only a full texture in `textures/blocks/` uses that texture on a
57+
single cube. To switch it to an overlay, put a PNG with the same name in
58+
`ore_overlays/` and rebuild.
59+
4760
## Verification
4861

4962
`test` checks native declarations, configuration latching and namespace compatibility.

‎gradle/ore-models.gradle‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import groovy.json.JsonOutput
2+
3+
// Forge 1.10 predates Minecraft's data generator. Generate models during the build.
4+
def assets = layout.projectDirectory.dir('src/main/resources/assets/baseminerals')
5+
def textures = assets.dir('textures/blocks')
6+
def solidTextures = fileTree(textures) { include '*_ore.png' }
7+
def overlayTextures = fileTree(textures.dir('ore_overlays')) { include '*_ore.png' }
8+
def oreStates = fileTree(assets.dir('blockstates')) {
9+
include '*_ore.json'
10+
// Historical placeholders with no registered ore blocks.
11+
exclude 'charcoal_ore.json', 'silicon_ore.json'
12+
}
13+
def generated = layout.buildDirectory.dir('generated/ore-models')
14+
15+
def generateOreModels = tasks.register('generateOreModels') {
16+
group = 'build'
17+
description = 'Generates ore models from the available overlay or solid textures.'
18+
inputs.files(oreStates, solidTextures, overlayTextures).withPathSensitivity(PathSensitivity.RELATIVE)
19+
outputs.dir(generated)
20+
21+
doLast {
22+
def names = oreStates.files.collect { it.name - '.json' }.sort()
23+
def overlays = overlayTextures.files.collect { it.name - '.png' }.toSet()
24+
def solid = solidTextures.files.collect { it.name - '.png' }.toSet()
25+
def extra = overlays - names
26+
def missing = names.findAll { !overlays.contains(it) && !solid.contains(it) }
27+
if (extra || missing) {
28+
throw new GradleException("Invalid ore textures. Missing textures: ${missing}. Unmatched overlays: ${extra}.")
29+
}
30+
31+
def directory = generated.get().dir('assets/baseminerals/models/block').asFile
32+
directory.mkdirs()
33+
def writeModel = { String name, Map model ->
34+
new File(directory, "${name}.json").setText(JsonOutput.prettyPrint(JsonOutput.toJson(model)) + '\n', 'UTF-8')
35+
}
36+
def cube = { Number from, Number to, String texture ->
37+
def faces = ['down', 'up', 'north', 'south', 'west', 'east'].collectEntries { face ->
38+
[(face): [texture: texture, cullface: face, uv: [0, 0, 16, 16]]]
39+
}
40+
[from: [from, from, from], to: [to, to, to], faces: faces]
41+
}
42+
writeModel('ore_overlay', [
43+
parent: 'minecraft:block/block',
44+
elements: [cube(0, 16, '#base'), cube(-0.05, 16.05, '#overlay')]
45+
])
46+
names.each { name ->
47+
if (overlays.contains(name)) {
48+
writeModel(name, [
49+
parent: 'baseminerals:block/ore_overlay',
50+
textures: [particle: 'minecraft:blocks/stone', base: 'minecraft:blocks/stone',
51+
overlay: "baseminerals:blocks/ore_overlays/${name}"]
52+
])
53+
} else {
54+
writeModel(name, [
55+
parent: 'block/cube_all',
56+
textures: [all: "baseminerals:blocks/${name}"]
57+
])
58+
}
59+
}
60+
directory.listFiles().findAll {
61+
it.isFile() && it.name.endsWith('_ore.json') && !names.contains(it.name - '.json')
62+
}.each {
63+
if (!it.delete()) throw new GradleException("Could not remove stale generated ore model ${it.name}")
64+
}
65+
}
66+
}
67+
68+
tasks.named('processResources', ProcessResources) {
69+
dependsOn generateOreModels
70+
from generated
71+
duplicatesStrategy = DuplicatesStrategy.FAIL
72+
}
73+
74+
tasks.named('sourcesJar', Jar) {
75+
dependsOn generateOreModels
76+
from generated
77+
}

‎gradle/verification/runtime.gradle‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ tasks.named('test', Test) {
4949

5050
tasks.register('verifyProjectResources', Exec) {
5151
group = 'verification'
52-
dependsOn tasks.named('test')
52+
dependsOn tasks.named('test'), tasks.named('processResources')
5353
doFirst {
5454
commandLine providers.gradleProperty('pythonExecutable').getOrElse('python3'),
5555
'tools/validation/legacy110/audit_resources.py', '--mirror',
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package zone.moddev.mc.baseminerals.block;
2+
3+
import com.mcmoddev.lib.block.BlockMMDOre;
4+
import com.mcmoddev.lib.material.MMDMaterial;
5+
import net.minecraft.util.BlockRenderLayer;
6+
import net.minecraftforge.fml.relauncher.Side;
7+
import net.minecraftforge.fml.relauncher.SideOnly;
8+
9+
/** Uses the shared ore behaviour with alpha testing for overlay models. */
10+
public final class OverlayOreBlock extends BlockMMDOre {
11+
public OverlayOreBlock(MMDMaterial material) {
12+
super(material);
13+
}
14+
15+
@Override
16+
@SideOnly(Side.CLIENT)
17+
public BlockRenderLayer getBlockLayer() {
18+
return BlockRenderLayer.CUTOUT_MIPPED;
19+
}
20+
}

‎src/main/java/zone/moddev/mc/baseminerals/init/Blocks.java‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
package zone.moddev.mc.baseminerals.init;
22

3-
import zone.moddev.mc.baseminerals.init.ItemGroups;
4-
53
import java.util.Arrays;
64
import java.util.List;
75

6+
import zone.moddev.mc.baseminerals.block.OverlayOreBlock;
87
import zone.moddev.mc.baseminerals.data.MaterialNames;
98
import com.mcmoddev.lib.data.Names;
109
import com.mcmoddev.lib.data.SharedStrings;
1110
import com.mcmoddev.lib.init.Materials;
1211
import com.mcmoddev.lib.material.MMDMaterial;
12+
import com.mcmoddev.lib.util.Oredicts;
13+
import net.minecraft.block.Block;
1314

1415
/**
1516
* This class initializes all blocks in Base Minerals.
@@ -40,12 +41,22 @@ public static void init() {
4041
final MMDMaterial material = Materials.getMaterialByName(materialName);
4142

4243
create(Names.BLOCK, material);
43-
create(Names.ORE, material);
44+
createOre(material);
4445
});
4546
/*
4647
if (zone.moddev.mc.baseminerals.util.Config.isEnabled(MaterialNames.SILICON) && Materials.hasMaterial(MaterialNames.SILICON)) {
4748
create(Names.BLOCK, Materials.getMaterialByName(MaterialNames.SILICON));
4849
}
4950
*/
5051
}
52+
53+
private static void createOre(MMDMaterial material) {
54+
if (!material.hasOre() || material.hasBlock(Names.ORE) || !isNameEnabled(Names.ORE)) {
55+
return;
56+
}
57+
final Block ore = addBlock(new OverlayOreBlock(material), Names.ORE, material,
58+
ItemGroups.getTab(SharedStrings.TAB_BLOCKS));
59+
material.addNewBlock(Names.ORE.toString(), ore);
60+
Oredicts.registerOre("ore" + material.getCapitalizedName(), ore);
61+
}
5162
}

‎src/main/resources/assets/baseminerals/models/block/lithium_ore.json‎

Lines changed: 0 additions & 6 deletions
This file was deleted.

‎src/main/resources/assets/baseminerals/models/block/niter_ore.json‎

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)