diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cecde6d..38bf34b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,9 +108,9 @@ jobs: if-no-files-found: error retention-days: 30 path: | - build/libs/ElectricAdvantage-2.2.4.110021.jar - build/libs/ElectricAdvantage-2.2.4.110021-sources.jar - build/libs/ElectricAdvantage-2.2.4.110021-javadoc.jar + build/libs/ElectricAdvantage-2.2.5.110021.jar + build/libs/ElectricAdvantage-2.2.5.110021-sources.jar + build/libs/ElectricAdvantage-2.2.5.110021-javadoc.jar build/release/SHA256SUMS CHANGELOG.txt diff --git a/.gitignore b/.gitignore index 4502811..4933367 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,25 @@ /replay_pid*.log /secret.json +# Nested local tooling and generated output +AGENTS.md +AGENT.md +CLAUDE.md +GEMINI.md +ARCHITECT.md +agent-notes/ +.codex/ +.agent/ +.agents/ +.claude/ +.gemini/ +.cursor/ +agent-*.md +codex-*.md +*.log +*.class +__pycache__/ +*.pyc /.DS_Store /README.txt /forge-*-changelog.txt diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 31d28ea..b37c3d7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,9 @@ +Electric Advantage 2.2.5.110021 + +- Retain unfinished drill progress when rebuilding the mining target after a world or chunk reload. +- Clear stale deferred target data when loading an untargeted tile; clamp restored progress to current target hardness. +- Preserve registry identities, saved target coordinates, inventories, energy and the existing progress NBT key. + Electric Advantage 2.2.4.110021 - Move the implementation namespace to zone.moddev.mc.electricadvantage while preserving runtime identities. diff --git a/README.md b/README.md index 2b9fbbb..32da75f 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ registry, tile/entity, asset, configuration, and saved-world identities are unch The cross-mod [Advantage Works 1.10.2 Handbook](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.10.2/docs/1.10/README.md) includes the Electrician's Handbook, rated figures, commissioning layouts, and persistence tests. The [MMD material and fluid compatibility specification](https://github.com/MinecraftModDevelopmentMods/PowerAdvantage/blob/master-1.10.2/docs/1.10/mmd-material-fluid-compatibility.md) defines sulfur/lithium ownership, migration, and Ore Dictionary aliases. +## Drill Reload Fix + +Version `2.2.5.110021` keeps unfinished drill work when a chunk or world reloads. +Existing inventories, energy, orientation and saved-world names are unchanged. +The regression tests cover resumed progress and full server restarts. + ## Building Minecraft 1.10.2 The `master-1.10.2` build uses ForgeGradle 7.0.34 and Gradle 9.6.1. Run Gradle with Java 17; Gradle resolves the Java 8 toolchain used for compilation. diff --git a/build.gradle b/build.gradle index 5737f35..f7e9b44 100644 --- a/build.gradle +++ b/build.gradle @@ -182,6 +182,7 @@ dependencies { compileOnly files(oreSpawnDeobfJar) runtimeOnly files(oreSpawnDeobfJar) testImplementation files(oreSpawnDeobfJar) + testImplementation files(powerAdvantageDeobfJar) testImplementation 'junit:junit:4.13.2' } @@ -310,7 +311,7 @@ tasks.register('verifyReleaseConfiguration') { group = 'verification' description = 'Validates release identity, target metadata, and dependency policy.' doLast { - if (project.mod_version != '2.2.4.110021') { + if (project.mod_version != '2.2.5.110021') { throw new GradleException("Unexpected ElectricAdvantage release version: ${project.mod_version}") } if (project.minecraft_version != '1.10.2' @@ -361,7 +362,7 @@ tasks.register('verifyReleaseConfiguration') { String mainSource = file( 'src/main/java/zone/moddev/mc/electricadvantage/ElectricAdvantage.java').getText('UTF-8') if (!mainSource.contains('MODID = "electricadvantage"') - || !mainSource.contains('VERSION = "2.2.4.110021"') + || !mainSource.contains('VERSION = "2.2.5.110021"') || !mainSource.contains('required-after:orespawn@[4.0.6,5.0.0);required-after:poweradvantage@[2.4.3.110021,);after:basemetals')) { throw new GradleException('ElectricAdvantage source identity or dependency policy changed') } diff --git a/gradle.properties b/gradle.properties index 09f896d..a54237e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,7 +24,7 @@ curseforge_project_id=240985 mod_id=electricadvantage mod_name=Electric Advantage mod_license=GPL-3.0-only -mod_version=2.2.4.110021 +mod_version=2.2.5.110021 mod_group=zone.moddev.mc.electricadvantage mod_authors=DrCyano mod_description=Electrical generation, storage, and machines for the Power Advantage platform. diff --git a/src/main/java/zone/moddev/mc/electricadvantage/ElectricAdvantage.java b/src/main/java/zone/moddev/mc/electricadvantage/ElectricAdvantage.java index 74df04c..ea42d05 100644 --- a/src/main/java/zone/moddev/mc/electricadvantage/ElectricAdvantage.java +++ b/src/main/java/zone/moddev/mc/electricadvantage/ElectricAdvantage.java @@ -25,7 +25,7 @@ public class ElectricAdvantage /** The display name for this mod */ public static final String NAME = "Electric Advantage"; /** The version of this mod, in the format major.minor.update */ - public static final String VERSION = "2.2.4.110021"; + public static final String VERSION = "2.2.5.110021"; public static ElectricAdvantage INSTANCE = null; diff --git a/src/main/java/zone/moddev/mc/electricadvantage/machines/ElectricDrillTileEntity.java b/src/main/java/zone/moddev/mc/electricadvantage/machines/ElectricDrillTileEntity.java index d529df3..6fc4ff8 100644 --- a/src/main/java/zone/moddev/mc/electricadvantage/machines/ElectricDrillTileEntity.java +++ b/src/main/java/zone/moddev/mc/electricadvantage/machines/ElectricDrillTileEntity.java @@ -69,7 +69,7 @@ public float[] getProgress() { public void tickUpdate(boolean isServerWorld) { if(isServerWorld){ if(deferred){ - targetBlock(targetBlockCoord); + restoreTargetBlock(); } updateFacing(); @@ -192,7 +192,7 @@ public void onDataFieldUpdate() { private int oldLength = 0; @Override public void powerUpdate(){ if(deferred){ - targetBlock(targetBlockCoord); + restoreTargetBlock(); } super.powerUpdate(); boolean flagSync = progress != oldProgress || oldEnergy != getEnergy(); @@ -362,12 +362,20 @@ private BlockPos[] getArea(BlockPos center){ return a; } + private void restoreTargetBlock(){ + int savedProgress = progress; + // Rebuild transient drops and hardness without discarding saved work. + targetBlock(targetBlockCoord); + progress = Math.max(0, Math.min(savedProgress, progressGoal)); + } + private void deferredTargetBlock (BlockPos n){ targetBlockCoord = n; deferred = true; } private void untargetBlock(){ + deferred = false; progress = 0; progressGoal = 0; targetBlockCoord = null; @@ -467,6 +475,7 @@ protected void saveTo(NBTTagCompound tagRoot) { @Override protected void loadFrom(NBTTagCompound tagRoot) { + untargetBlock(); if(tagRoot.hasKey("progress")){ progress = tagRoot.getShort("progress"); } @@ -478,7 +487,8 @@ protected void loadFrom(NBTTagCompound tagRoot) { if(getWorld() == null){ this.deferredTargetBlock(new BlockPos(x,y,z)); } else { - this.targetBlock(new BlockPos(x,y,z)); + this.deferredTargetBlock(new BlockPos(x,y,z)); + this.restoreTargetBlock(); } } } diff --git a/src/test/java/zone/moddev/mc/electricadvantage/machines/ElectricDrillPersistenceTest.java b/src/test/java/zone/moddev/mc/electricadvantage/machines/ElectricDrillPersistenceTest.java new file mode 100644 index 0000000..03f6bf5 --- /dev/null +++ b/src/test/java/zone/moddev/mc/electricadvantage/machines/ElectricDrillPersistenceTest.java @@ -0,0 +1,46 @@ +package zone.moddev.mc.electricadvantage.machines; + +import net.minecraft.nbt.NBTTagCompound; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ElectricDrillPersistenceTest { + @Test public void retainsLegacyProgressBeforeWorldAttachment() { + ElectricDrillTileEntity drill = new ElectricDrillTileEntity(); + drill.loadFrom(target(512)); + drill.prepareDataFieldsForSync(); + assertEquals(512, drill.getDataFieldArray()[1]); + } + + @Test public void preservesPendingTargetThroughRepeatedSerialization() { + NBTTagCompound source = target(512); + for (int i = 0; i < 3; i++) { + ElectricDrillTileEntity drill = new ElectricDrillTileEntity(); + drill.loadFrom(source); + source = new NBTTagCompound(); + drill.saveTo(source); + assertEquals(512, source.getShort("progress")); + assertEquals(2049, source.getInteger("targetZ")); + } + } + + @Test public void untargetedDataClearsPendingWork() { + ElectricDrillTileEntity drill = new ElectricDrillTileEntity(); + drill.loadFrom(target(512)); + drill.loadFrom(new NBTTagCompound()); + NBTTagCompound saved = new NBTTagCompound(); + drill.saveTo(saved); + assertEquals(0, saved.getShort("progress")); + assertFalse(saved.hasKey("targetX")); + } + + private static NBTTagCompound target(int progress) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setShort("progress", (short) progress); + tag.setInteger("targetX", 2048); + tag.setInteger("targetY", 80); + tag.setInteger("targetZ", 2049); + return tag; + } +}