Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
![](/src/main/resources/logo.png?raw=true)

---

## ⚠️ Crash Fix Fork — NeoForge 1.21.1

This is a community fork of ProjectE that fixes a server crash introduced in PE1.1.0 on NeoForge 1.21.1.

**The bug:** Crafting any DM/RM tool or armor (Dark Matter Pickaxe, Red Matter Sword, etc.) causes the server to crash immediately with `IllegalStateException: Value must be positive: 0`. Every player on the server is kicked and the server cannot restart until the item is removed from the player's inventory.

**The fix:** DM/RM tools and armor are now registered with a real `max_damage` data component (required by NeoForge 1.21.1's serialization system). Durability is still never consumed — the items work exactly as intended.

### How to install

1. Go to the [**Releases**](../../releases) tab and download the latest `projecte-1.1.0.jar`
2. Replace the existing `ProjectE-1.21.1-PE1.1.0.jar` in your `mods/` folder with the downloaded jar
3. **Both the server and all clients must use this jar** (NeoForge requires matching mod versions)

> Once an official fix is released by the ProjectE team, switch back to the official jar from [CurseForge](https://www.curseforge.com/minecraft/mc-mods/projecte/files).

---

Repository for ProjectE, a complete rewrite of EE2 (Equivalent Exchange 2) for modern Minecraft versions. Transmutation tables, collectors, condensers, flying rings, and all the other trinkets you love are here.

Discover powerful alchemical tools, items, and devices. Break down unwanted items into EMC (Energy-Matter Covalence) and use that EMC to create new items.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,16 @@ public <ITEM extends Item> ItemRegistryObject<ITEM> registerNoStackFireImmune(St
return register(name, sup, properties -> properties.stacksTo(1).fireResistant());
}

// Use for armor items — sets a real max_damage so the minecraft:max_damage component is present.
// damageItem() in PEArmor always returns 0, so durability is never actually consumed.
public <ITEM extends Item> ItemRegistryObject<ITEM> registerArmor(String name, Function<Item.Properties, ITEM> sup) {
return register(name, sup, properties -> properties.durability(Integer.MAX_VALUE).stacksTo(1).fireResistant());
}

public <ITEM extends Item> ItemRegistryObject<ITEM> registerTool(String name, Function<Item.Properties, ITEM> sup) {
return register(name, () -> sup.apply(new NoDurabilityItemProperties().stacksTo(1).fireResistant()));
// Use real durability so minecraft:max_damage component is present on the ItemStack.
// damageItem() in PETool/PEPickaxe always returns 0 so durability is never actually consumed.
return register(name, () -> sup.apply(new Item.Properties().durability(Integer.MAX_VALUE).stacksTo(1).fireResistant()));
}

public <ITEM extends Item> ItemRegistryObject<ITEM> register(String name, Function<Item.Properties, ITEM> sup, UnaryOperator<Item.Properties> propertyModifier) {
Expand All @@ -104,14 +112,4 @@ public <ITEM extends Item> ItemRegistryObject<ITEM> register(String name, Functi
public <ITEM extends Item> ItemRegistryObject<ITEM> register(@NotNull String name, @NotNull Supplier<? extends ITEM> sup) {
return (ItemRegistryObject<ITEM>) super.register(name, sup);
}

private static class NoDurabilityItemProperties extends Item.Properties {

@NotNull
@Override
public Item.Properties durability(int maxDamage) {
//NO-OP super setting durability components
return this;
}
}
}
28 changes: 14 additions & 14 deletions src/main/java/moze_intel/projecte/gameObjs/registries/PEItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,20 @@ public class PEItems {
public static final ItemRegistryObject<PEKatar> RED_MATTER_KATAR = ITEMS.registerTool("rm_katar", properties -> new PEKatar(EnumMatterType.RED_MATTER, 4, properties));
public static final ItemRegistryObject<PEMorningStar> RED_MATTER_MORNING_STAR = ITEMS.registerTool("rm_morning_star", properties -> new PEMorningStar(EnumMatterType.RED_MATTER, 4, properties));

public static final ItemRegistryObject<DMArmor> DARK_MATTER_HELMET = ITEMS.registerNoStackFireImmune("dm_helmet", properties -> new DMArmor(ArmorItem.Type.HELMET, properties));
public static final ItemRegistryObject<DMArmor> DARK_MATTER_CHESTPLATE = ITEMS.registerNoStackFireImmune("dm_chestplate", properties -> new DMArmor(ArmorItem.Type.CHESTPLATE, properties));
public static final ItemRegistryObject<DMArmor> DARK_MATTER_LEGGINGS = ITEMS.registerNoStackFireImmune("dm_leggings", properties -> new DMArmor(ArmorItem.Type.LEGGINGS, properties));
public static final ItemRegistryObject<DMArmor> DARK_MATTER_BOOTS = ITEMS.registerNoStackFireImmune("dm_boots", properties -> new DMArmor(ArmorItem.Type.BOOTS, properties));

public static final ItemRegistryObject<RMArmor> RED_MATTER_HELMET = ITEMS.registerNoStackFireImmune("rm_helmet", properties -> new RMArmor(ArmorItem.Type.HELMET, properties));
public static final ItemRegistryObject<RMArmor> RED_MATTER_CHESTPLATE = ITEMS.registerNoStackFireImmune("rm_chestplate", properties -> new RMArmor(ArmorItem.Type.CHESTPLATE, properties));
public static final ItemRegistryObject<RMArmor> RED_MATTER_LEGGINGS = ITEMS.registerNoStackFireImmune("rm_leggings", properties -> new RMArmor(ArmorItem.Type.LEGGINGS, properties));
public static final ItemRegistryObject<RMArmor> RED_MATTER_BOOTS = ITEMS.registerNoStackFireImmune("rm_boots", properties -> new RMArmor(ArmorItem.Type.BOOTS, properties));

public static final ItemRegistryObject<GemHelmet> GEM_HELMET = ITEMS.registerNoStackFireImmune("gem_helmet", GemHelmet::new);
public static final ItemRegistryObject<GemChest> GEM_CHESTPLATE = ITEMS.registerNoStackFireImmune("gem_chestplate", GemChest::new);
public static final ItemRegistryObject<GemLegs> GEM_LEGGINGS = ITEMS.registerNoStackFireImmune("gem_leggings", GemLegs::new);
public static final ItemRegistryObject<GemFeet> GEM_BOOTS = ITEMS.registerNoStackFireImmune("gem_boots", GemFeet::new);
public static final ItemRegistryObject<DMArmor> DARK_MATTER_HELMET = ITEMS.registerArmor("dm_helmet", properties -> new DMArmor(ArmorItem.Type.HELMET, properties));
public static final ItemRegistryObject<DMArmor> DARK_MATTER_CHESTPLATE = ITEMS.registerArmor("dm_chestplate", properties -> new DMArmor(ArmorItem.Type.CHESTPLATE, properties));
public static final ItemRegistryObject<DMArmor> DARK_MATTER_LEGGINGS = ITEMS.registerArmor("dm_leggings", properties -> new DMArmor(ArmorItem.Type.LEGGINGS, properties));
public static final ItemRegistryObject<DMArmor> DARK_MATTER_BOOTS = ITEMS.registerArmor("dm_boots", properties -> new DMArmor(ArmorItem.Type.BOOTS, properties));

public static final ItemRegistryObject<RMArmor> RED_MATTER_HELMET = ITEMS.registerArmor("rm_helmet", properties -> new RMArmor(ArmorItem.Type.HELMET, properties));
public static final ItemRegistryObject<RMArmor> RED_MATTER_CHESTPLATE = ITEMS.registerArmor("rm_chestplate", properties -> new RMArmor(ArmorItem.Type.CHESTPLATE, properties));
public static final ItemRegistryObject<RMArmor> RED_MATTER_LEGGINGS = ITEMS.registerArmor("rm_leggings", properties -> new RMArmor(ArmorItem.Type.LEGGINGS, properties));
public static final ItemRegistryObject<RMArmor> RED_MATTER_BOOTS = ITEMS.registerArmor("rm_boots", properties -> new RMArmor(ArmorItem.Type.BOOTS, properties));

public static final ItemRegistryObject<GemHelmet> GEM_HELMET = ITEMS.registerArmor("gem_helmet", GemHelmet::new);
public static final ItemRegistryObject<GemChest> GEM_CHESTPLATE = ITEMS.registerArmor("gem_chestplate", GemChest::new);
public static final ItemRegistryObject<GemLegs> GEM_LEGGINGS = ITEMS.registerArmor("gem_leggings", GemLegs::new);
public static final ItemRegistryObject<GemFeet> GEM_BOOTS = ITEMS.registerArmor("gem_boots", GemFeet::new);

public static final ItemRegistryObject<Item> IRON_BAND = ITEMS.register("iron_band");
public static final ItemRegistryObject<BlackHoleBand> BLACK_HOLE_BAND = ITEMS.registerNoStackFireImmune("black_hole_band", BlackHoleBand::new);
Expand Down