getMixins() {
+ return null;
+ }
+
+ @Override
+ public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
+ }
+
+ @Override
+ public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
+ }
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/VanillaBlocks.java b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/VanillaBlocks.java
new file mode 100644
index 00000000..b5f66e7a
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/VanillaBlocks.java
@@ -0,0 +1,245 @@
+package net.ornithemc.osl.blocks.impl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import net.minecraft.block.Block;
+
+import net.ornithemc.osl.blocks.api.block.Blocks;
+import net.ornithemc.osl.core.api.util.NamespacedIdentifiers;
+
+final class VanillaBlocks {
+
+ /**
+ * Namespaced IDs were introduced in 1.7. Before then, the numerical IDs
+ * were the only unique identifiers for blocks. Here we assign namespaced
+ * IDs to pre-1.7 blocks, matching the 1.7 IDs where possible.
+ *
+ * Note that in 1.7 snapshots the IDs went through several changes.
+ * The IDs used here match those used in Release 1.7.2.
+ */
+ private static final String[] IDENTIFIERS = {
+ // grouped per 10 for easier lookup
+
+ "air",
+ "stone",
+ "grass",
+ "dirt",
+ "cobblestone",
+ "planks",
+ "sapling",
+ "bedrock",
+ "flowing_water",
+ "water",
+
+ "flowing_lava",
+ "lava",
+ "sand",
+ "gravel",
+ "gold_ore",
+ "iron_ore",
+ "coal_ore",
+ "log",
+ "leaves",
+ "sponge",
+
+ "glass",
+ "lapis_ore",
+ "lapis_block",
+ "dispenser",
+ "sandstone",
+ "noteblock",
+ "bed",
+ "golden_rail",
+ "detector_rail",
+ "sticky_piston",
+
+ "web",
+ "tallgrass",
+ "deadbush",
+ "piston",
+ "piston_head",
+ "wool",
+ "piston_extension",
+ "yellow_flower",
+ "red_flower",
+ "brown_mushroom",
+
+ "red_mushroom",
+ "gold_block",
+ "iron_block",
+ "double_stone_slab",
+ "stone_slab",
+ "brick_block",
+ "tnt",
+ "bookshelf",
+ "mossy_cobblestone",
+ "obsidian",
+
+ "torch",
+ "fire",
+ "mob_spawner",
+ "oak_stairs",
+ "chest",
+ "redstone_wire",
+ "diamond_ore",
+ "diamond_block",
+ "crafting_table",
+ "wheat",
+
+ "farmland",
+ "furnace",
+ "lit_furnace",
+ "standing_sign",
+ "wooden_door",
+ "ladder",
+ "rail",
+ "stone_stairs",
+ "wall_sign",
+ "lever",
+
+ "stone_pressure_plate",
+ "iron_door",
+ "wooden_pressure_plate",
+ "redstone_ore",
+ "lit_redstone_ore",
+ "unlit_redstone_torch",
+ "redstone_torch",
+ "stone_button",
+ "snow_layer",
+ "ice",
+
+ "snow",
+ "cactus",
+ "clay",
+ "reeds",
+ "jukebox",
+ "fence",
+ "pumpkin",
+ "netherrack",
+ "soul_sand",
+ "glowstone",
+
+ "portal",
+ "lit_pumpkin",
+ "cake",
+ "unpowered_repeater",
+ "powered_repeater",
+ "april_fools_locked_chest",
+ "trapdoor",
+ "monster_egg",
+ "stonebrick",
+ "brown_mushroom_block",
+
+ "red_mushroom_block",
+ "iron_bars",
+ "glass_pane",
+ "melon_block",
+ "pumpkin_stem",
+ "melon_stem",
+ "vine",
+ "fence_gate",
+ "brick_stairs",
+ "stone_brick_stairs",
+
+ "mycelium",
+ "waterlily",
+ "nether_brick",
+ "nether_brick_fence",
+ "nether_brick_stairs",
+ "nether_wart",
+ "enchanting_table",
+ "brewing_stand",
+ "cauldron",
+ "end_portal",
+
+ "end_portal_frame",
+ "end_stone",
+ "dragon_egg",
+ "redstone_lamp",
+ "lit_redstone_lamp",
+ "double_wooden_slab",
+ "wooden_slab",
+ "cocoa",
+ "sandstone_stairs",
+ "emerald_ore",
+
+ "ender_chest",
+ "tripwire_hook",
+ "tripwire",
+ "emerald_block",
+ "spruce_stairs",
+ "birch_stairs",
+ "jungle_stairs",
+ "command_block",
+ "beacon",
+ "cobblestone_wall",
+
+ "flower_pot",
+ "carrots",
+ "potatoes",
+ "wooden_button",
+ "skull",
+ "anvil",
+ "trapped_chest",
+ "light_weighted_pressure_plate",
+ "heavey_weighted_pressure_plate",
+ "unpowered_comparator",
+
+ "powered_comparator",
+ "daylight_detector",
+ "redstone_block",
+ "quartz_ore",
+ "hopper",
+ "quartz_block",
+ "quartz_stairs",
+ "activator_rail",
+ "dropper",
+ "stained_hardened_clay",
+
+// IDs 160 to 169 were unused
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+
+ "hay",
+ "carpet",
+ "hardened_clay",
+ "coal_block"
+ };
+
+ static void init() {
+ // Air block added by OSL
+ register(Blocks.AIR);
+
+ for (Field f : Block.class.getDeclaredFields()) {
+ if (Modifier.isStatic(f.getModifiers()) && Block.class.isAssignableFrom(f.getType())) {
+ try {
+ Block block = (Block) f.get(null);
+
+ if (block != null) {
+ register(block);
+ }
+ } catch (Throwable t) {
+ }
+ }
+ }
+ }
+
+ private static void register(Block block) {
+ if (block.id >= 0 && block.id < IDENTIFIERS.length) {
+ String identifier = IDENTIFIERS[block.id];
+
+ if (identifier != null) {
+ BlockRegistryImpl.register(block.id, NamespacedIdentifiers.from(identifier), block);
+ }
+ }
+ }
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/block/AirBlock.java b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/block/AirBlock.java
new file mode 100644
index 00000000..1aed2f62
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/block/AirBlock.java
@@ -0,0 +1,38 @@
+package net.ornithemc.osl.blocks.impl.block;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.material.Material;
+import net.minecraft.util.math.Box;
+import net.minecraft.world.World;
+
+public class AirBlock extends Block {
+
+ public AirBlock() {
+ super(0, Material.AIR);
+ }
+
+ @Override
+ public boolean isAir() {
+ return true;
+ }
+
+ @Override
+ public int getRenderType() {
+ return -1;
+ }
+
+ @Override
+ public Box getCollisionShape(World world, int x, int y, int z) {
+ return null;
+ }
+
+ @Override
+ public boolean isSolidRender() {
+ return false;
+ }
+
+ @Override
+ public boolean canRayTrace(int metadata, boolean allowLiquids) {
+ return false;
+ }
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/block/BlockExtensionImpl.java b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/block/BlockExtensionImpl.java
new file mode 100644
index 00000000..a34f0259
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/block/BlockExtensionImpl.java
@@ -0,0 +1,18 @@
+package net.ornithemc.osl.blocks.impl.block;
+
+import net.minecraft.block.Block;
+
+import net.ornithemc.osl.blocks.api.block.BlockExtension;
+
+public interface BlockExtensionImpl extends BlockExtension {
+
+ @Override
+ default boolean isAir() {
+ throw new AbstractMethodError();
+ }
+
+ @Override
+ default boolean is(Block block) {
+ throw new AbstractMethodError();
+ }
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixin.java b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixin.java
new file mode 100644
index 00000000..9a9de523
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixin.java
@@ -0,0 +1,52 @@
+package net.ornithemc.osl.blocks.impl.mixin.common;
+
+import org.objectweb.asm.Opcodes;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.Slice;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import net.minecraft.block.Block;
+
+import net.ornithemc.osl.blocks.impl.BlockRegistryImpl;
+
+@Mixin(Block.class)
+public class BlockMixin {
+
+ @Inject(
+ method = "",
+ at = @At(
+ value = "HEAD"
+ )
+ )
+ private static void osl$blocks$unlockBlockRegistry(CallbackInfo ci) {
+ BlockRegistryImpl.unlock();
+ }
+
+ @Inject(
+ method = "",
+ slice = @Slice(
+ from = @At(
+ value = "FIELD",
+ opcode = Opcodes.PUTSTATIC,
+ target = "Lnet/minecraft/block/Block;STONE:Lnet/minecraft/block/Block;"
+ )
+ ),
+ at = @At(
+ value = "CONSTANT",
+ args = "intValue=256",
+ ordinal = 0
+ )
+ )
+ private static void osl$blocks$initAndLockBlockRegistry(CallbackInfo ci) {
+ BlockRegistryImpl.init();
+ BlockRegistryImpl.lock();
+ }
+
+ @Override
+ public String toString() {
+ return "Block{" + BlockRegistryImpl.getKey((Block) (Object) this) + "}";
+ }
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixinNew.java b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixinNew.java
new file mode 100644
index 00000000..51098abb
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixinNew.java
@@ -0,0 +1,21 @@
+package net.ornithemc.osl.blocks.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+
+import net.minecraft.block.Block;
+
+import net.ornithemc.osl.blocks.api.block.BlockExtension;
+
+@Mixin(Block.class)
+public class BlockMixinNew implements BlockExtension {
+
+ @Override
+ public boolean isAir() {
+ return false;
+ }
+
+ @Override
+ public boolean is(Block block) {
+ return ((Block) (Object) this).is(block.id);
+ }
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixinOld.java b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixinOld.java
new file mode 100644
index 00000000..15a537b7
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/BlockMixinOld.java
@@ -0,0 +1,21 @@
+package net.ornithemc.osl.blocks.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+
+import net.minecraft.block.Block;
+
+import net.ornithemc.osl.blocks.api.block.BlockExtension;
+
+@Mixin(Block.class)
+public class BlockMixinOld implements BlockExtension {
+
+ @Override
+ public boolean isAir() {
+ return false;
+ }
+
+ @Override
+ public boolean is(Block block) {
+ return (Block) (Object) this == block;
+ }
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/RedstoneTorchBlockMixin.java b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/RedstoneTorchBlockMixin.java
new file mode 100644
index 00000000..2339ee23
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/RedstoneTorchBlockMixin.java
@@ -0,0 +1,21 @@
+package net.ornithemc.osl.blocks.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.RedstoneTorchBlock;
+import net.minecraft.block.material.Material;
+
+@Mixin(RedstoneTorchBlock.class)
+public class RedstoneTorchBlockMixin extends Block {
+
+ private RedstoneTorchBlockMixin(int id, Material material) {
+ super(id, material);
+ }
+
+ @Override
+ public boolean is(Block block) {
+ return block == Block.REDSTONE_TORCH || block == Block.UNLIT_REDSTONE_TORCH;
+ }
+
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/RepeaterBlockMixin.java b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/RepeaterBlockMixin.java
new file mode 100644
index 00000000..8ffde7e8
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/blocks/impl/mixin/common/RepeaterBlockMixin.java
@@ -0,0 +1,21 @@
+package net.ornithemc.osl.blocks.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.RepeaterBlock;
+import net.minecraft.block.material.Material;
+
+@Mixin(RepeaterBlock.class)
+public class RepeaterBlockMixin extends Block {
+
+ private RepeaterBlockMixin(int id, Material material) {
+ super(id, material);
+ }
+
+ @Override
+ public boolean is(Block block) {
+ return block == Block.REPEATER || block == Block.POWERED_REPEATER;
+ }
+
+}
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/fabric.mod.json b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/fabric.mod.json
new file mode 100644
index 00000000..beee7d68
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/fabric.mod.json
@@ -0,0 +1,26 @@
+{
+ "schemaVersion": 1,
+ "id": "osl-blocks",
+ "version": "0.1.0-alpha.1+mca1.0.1_01-mc1.6.4",
+ "environment": "*",
+ "mixins": [
+ "osl.blocks.mixins.json"
+ ],
+ "accessWidener": "osl.blocks.classtweaker",
+ "depends": {
+ "fabricloader": "\u003e\u003d0.18.0",
+ "minecraft": "\u003e\u003d1.0.0-alpha.0.1 \u003c\u003d1.6.4",
+ "osl-core": "\u003e\u003d0.7.0"
+ },
+ "name": "OSL Blocks",
+ "description": "Blocks API and events.",
+ "authors": [
+ "OrnitheMC"
+ ],
+ "contact": {
+ "homepage": "https://ornithemc.net/",
+ "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues",
+ "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries"
+ },
+ "license": "Apache-2.0"
+}
\ No newline at end of file
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/osl.blocks.classtweaker b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/osl.blocks.classtweaker
new file mode 100644
index 00000000..d4ae7c59
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/osl.blocks.classtweaker
@@ -0,0 +1,14 @@
+classTweaker v1 named
+
+transitive-accessible method net/minecraft/block/Block setSounds (Lnet/minecraft/block/Block$Sounds;)Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setOpacity (I)Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setLight (F)Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setBlastResistance (F)Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setStrength (F)Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setUnbreakable ()Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setTicksRandomly (Z)Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setKey (Ljava/lang/String;)Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setCreativeModeTab (Lnet/minecraft/item/CreativeModeTab;)Lnet/minecraft/block/Block;
+transitive-accessible method net/minecraft/block/Block setSpriteName (Ljava/lang/String;)Lnet/minecraft/block/Block;
+
+transitive-inject-interface net/minecraft/block/Block net/ornithemc/osl/blocks/impl/block/BlockExtensionImpl
\ No newline at end of file
diff --git a/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/osl.blocks.mixins.json b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/osl.blocks.mixins.json
new file mode 100644
index 00000000..c3640215
--- /dev/null
+++ b/libraries/blocks/blocks-mca1.0.1_01-mc1.6.4/src/main/resources/osl.blocks.mixins.json
@@ -0,0 +1,21 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "net.ornithemc.osl.blocks.impl.mixin",
+ "compatibilityLevel": "JAVA_8",
+ "plugin": "net.ornithemc.osl.blocks.impl.BlocksMixinPlugin",
+ "mixins": [
+ "common.BlockMixin",
+ "common.BlockMixinNew",
+ "common.BlockMixinOld",
+ "common.RedstoneTorchBlockMixin",
+ "common.RepeaterBlockMixin"
+ ],
+ "client": [
+ ],
+ "server": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/libraries/blocks/build.gradle b/libraries/blocks/build.gradle
new file mode 100644
index 00000000..e98ba2c6
--- /dev/null
+++ b/libraries/blocks/build.gradle
@@ -0,0 +1 @@
+setUpLibrary(project)
diff --git a/libraries/blocks/gradle.properties b/libraries/blocks/gradle.properties
new file mode 100644
index 00000000..12b27d8f
--- /dev/null
+++ b/libraries/blocks/gradle.properties
@@ -0,0 +1,6 @@
+library_id = blocks
+library_name = Blocks
+library_description = Blocks API and events.
+library_version = 0.1.0-alpha.1
+
+osl_dependencies = core:>=0.7.0
diff --git a/libraries/core/src/main/java/net/ornithemc/osl/core/api/registry/SimpleIdRegistry.java b/libraries/core/src/main/java/net/ornithemc/osl/core/api/registry/SimpleIdRegistry.java
new file mode 100644
index 00000000..eb42caf8
--- /dev/null
+++ b/libraries/core/src/main/java/net/ornithemc/osl/core/api/registry/SimpleIdRegistry.java
@@ -0,0 +1,84 @@
+package net.ornithemc.osl.core.api.registry;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Reference2IntMap;
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
+
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+
+public final class SimpleIdRegistry {
+
+ private final Int2ReferenceMap values;
+ private final Reference2IntMap ids;
+ private final Map registry;
+ private final Map keys;
+
+ private int nextId = 0;
+
+ public SimpleIdRegistry() {
+ this.values = new Int2ReferenceOpenHashMap<>();
+ this.ids = new Reference2IntOpenHashMap<>();
+ this.registry = new HashMap<>();
+ this.keys = new IdentityHashMap<>();
+
+ this.ids.defaultReturnValue(-1);
+ }
+
+ public T register(NamespacedIdentifier key, T value) {
+ return this.register(this.nextId++, key, value);
+ }
+
+ public T register(int id, NamespacedIdentifier key, T value) {
+ if (id < 0) {
+ throw new IllegalStateException("invalid ID " + id + " (must be >= 0)");
+ }
+ if (this.values.containsKey(id)) {
+ throw new IllegalStateException("duplicate ID " + id + " (" + this.getKey(this.get(id)) + " and " + key + ")");
+ }
+ if (this.registry.containsKey(key)) {
+ throw new IllegalStateException("duplicate Namespaced ID " + key + " (" + this.getId(this.get(key)) + " and " + id + ")");
+ }
+ if (this.ids.containsKey(value) || this.keys.containsKey(value)) {
+ throw new IllegalStateException("value registered twice (" + this.getId(value) + ", " + this.getKey(value) + " and " + id + ", " + key + ")");
+ }
+
+ this.values.put(id, value);
+ this.ids.put(value, id);
+ this.registry.put(key, value);
+ this.keys.put(value, key);
+
+ this.nextId = Math.max(this.nextId, id + 1);
+
+ return value;
+ }
+
+ public T get(int id) {
+ return this.values.get(id);
+ }
+
+ public T get(NamespacedIdentifier key) {
+ return this.registry.get(key);
+ }
+
+ public boolean has(T value) {
+ return this.ids.containsKey(value);
+ }
+
+ public int getId(T value) {
+ return this.ids.getInt(value);
+ }
+
+ public NamespacedIdentifier getKey(T value) {
+ return this.keys.get(value);
+ }
+
+ public Set keySet() {
+ return this.registry.keySet();
+ }
+}
diff --git a/libraries/items/README.md b/libraries/items/README.md
new file mode 100644
index 00000000..0566ce42
--- /dev/null
+++ b/libraries/items/README.md
@@ -0,0 +1,41 @@
+# Items API
+
+The Items API provides events and utilities for registering and working with items.
+
+## Registering Custom Items
+
+Item registration should be done in a listener to the `REGISTER_ITEMS` event. The `ItemRegistry` class provides utility methods for registering items.
+
+An example is shown below.
+
+```java
+package com.example;
+
+import net.ornithemc.osl.entrypoints.api.ModInitializer;
+import net.ornithemc.osl.items.api.ItemEvents;
+
+public class ExampleInitializer implements ModInitializer {
+
+ @Override
+ public void init() {
+ ItemEvents.REGISTER_ITEMS.register(ExampleItems::init);
+ }
+}
+```
+
+```java
+package com.example;
+
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.core.util.NamespacedIdentifiers;
+import net.ornithemc.osl.items.api.ItemRegistry;
+
+public final class ExampleItems {
+
+ public static final CookieItem COOKIE = ItemRegistry.register(NamespacedIdentifiers.from("example", "cookie"), new CookieItem());
+
+ public static void init() {
+ }
+}
+```
diff --git a/libraries/items/build.gradle b/libraries/items/build.gradle
new file mode 100644
index 00000000..e98ba2c6
--- /dev/null
+++ b/libraries/items/build.gradle
@@ -0,0 +1 @@
+setUpLibrary(project)
diff --git a/libraries/items/gradle.properties b/libraries/items/gradle.properties
new file mode 100644
index 00000000..a3ddc062
--- /dev/null
+++ b/libraries/items/gradle.properties
@@ -0,0 +1,6 @@
+library_id = items
+library_name = Items
+library_description = Items API and events.
+library_version = 0.1.0-alpha.1
+
+osl_dependencies = core:>=0.7.0,blocks:>=0.1.0-
diff --git a/libraries/items/items-mc13w36a-mc14w25b/build.gradle b/libraries/items/items-mc13w36a-mc14w25b/build.gradle
new file mode 100644
index 00000000..0a350fdb
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/build.gradle
@@ -0,0 +1 @@
+setUpModule(project)
diff --git a/libraries/items/items-mc13w36a-mc14w25b/gradle.properties b/libraries/items/items-mc13w36a-mc14w25b/gradle.properties
new file mode 100644
index 00000000..fd8d10fb
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/gradle.properties
@@ -0,0 +1,8 @@
+min_mc_version = 13w36a
+max_mc_version = 14w25b
+minecraft_dependency = >=1.7-alpha.13.36.a <=1.8-alpha.14.25.b
+
+minecraft_version = 1.7.2
+raven_build = 1
+sparrow_build = 1
+nests_build = 3
diff --git a/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
new file mode 100644
index 00000000..4d0923b9
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
@@ -0,0 +1,34 @@
+package net.ornithemc.osl.items.api;
+
+import net.ornithemc.osl.core.api.events.Event;
+
+/**
+ * Events related to the items lifecycle.
+ */
+public final class ItemEvents {
+
+ /**
+ * This event is invoked upon game start-up, after Vanilla item registration is finished.
+ *
+ *
+ * Custom item registration should be done in a listener of this event.
+ * Helper methods for registering items can be found in the {@linkplain
+ * ItemRegistry} class.
+ *
+ *
+ * Listeners to this event should be registered in your mod's entrypoint,
+ * and can be done as follows:
+ *
+ *
+ * {@code
+ * ItemEvents.REGISTER_ITEMS.register(() -> {
+ * ItemRegistry.register(999, NamespacedIdentifiers.from("example", "cookie"), new CookieItem());
+ * });
+ * }
+ *
+ *
+ * @see ItemRegistry
+ */
+ public static final Event REGISTER_ITEMS = Event.runnable();
+
+}
diff --git a/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
new file mode 100644
index 00000000..5c9fdcbc
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
@@ -0,0 +1,89 @@
+package net.ornithemc.osl.items.api;
+
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+/**
+ * Public access to the Items registry.
+ */
+public final class ItemRegistry {
+
+ /**
+ * @return the numerical ID assigned to the given item.
+ */
+ public static int getId(Item item) {
+ return ItemRegistryImpl.getId(item);
+ }
+
+ /**
+ * @return the namespaced ID assigned to the given item.
+ */
+ public static NamespacedIdentifier getKey(Item item) {
+ return ItemRegistryImpl.getKey(item);
+ }
+
+ /**
+ * @return the item mapped to the given numerical ID.
+ */
+ public static Item getItem(int id) {
+ return ItemRegistryImpl.getItem(id);
+ }
+
+ /**
+ * @return the item mapped to the given namespaced ID.
+ */
+ public static Item getItem(NamespacedIdentifier key) {
+ return ItemRegistryImpl.getItem(key);
+ }
+
+ /**
+ * @return a set containing all namespaced IDs in the registry.
+ */
+ public static Set keySet() {
+ return ItemRegistryImpl.keySet();
+ }
+
+ /**
+ * @param block the block item to register.
+ * @return the registered block item.
+ */
+ public static BlockItem register(Block block) {
+ return ItemRegistryImpl.register(block);
+ }
+
+ /**
+ * @param the item type.
+ * @param item the item to register.
+ * @return the registered block item.
+ */
+ public static T register(T item) {
+ return ItemRegistryImpl.register(item);
+ }
+
+ /**
+ * @param the item type.
+ * @param block the block placed by the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(Block block, T item) {
+ return ItemRegistryImpl.register(block, item);
+ }
+
+ /**
+ * @param the item type.
+ * @param id the numerical ID of the item.
+ * @param key the namespaced ID of the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(int id, NamespacedIdentifier key, T item) {
+ return ItemRegistryImpl.register(id, key, item);
+ }
+}
diff --git a/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
new file mode 100644
index 00000000..9b00a45b
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
@@ -0,0 +1,88 @@
+package net.ornithemc.osl.items.impl;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.blocks.api.BlockRegistry;
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.core.api.util.NamespacedIdentifiers;
+import net.ornithemc.osl.items.api.ItemEvents;
+import net.ornithemc.osl.items.impl.mixin.common.BlockItemAccess;
+
+public final class ItemRegistryImpl {
+
+ private static boolean locked = true;
+ private static boolean initialized = false;
+
+ public static int getId(Item item) {
+ return Item.REGISTRY.getId(item);
+ }
+
+ public static NamespacedIdentifier getKey(Item item) {
+ String key = Item.REGISTRY.getKey(item);
+ return key == null ? null : NamespacedIdentifiers.parse(key);
+ }
+
+ public static Item getItem(int id) {
+ return Item.REGISTRY.get(id);
+ }
+
+ public static Item getItem(NamespacedIdentifier key) {
+ return Item.REGISTRY.get(key.toString());
+ }
+
+ public static Set keySet() {
+ return Item.REGISTRY.keySet().stream().map(NamespacedIdentifiers::parse).collect(Collectors.toSet());
+ }
+
+ public static BlockItem register(Block block) {
+ return register(block, new BlockItem(block));
+ }
+
+ public static T register(T item) {
+ return register(((BlockItemAccess) item).accessBlock(), item);
+ }
+
+ public static T register(Block block, T item) {
+ return register(BlockRegistry.getId(block), BlockRegistry.getKey(block), item);
+ }
+
+ public static T register(int id, NamespacedIdentifier key, T item) {
+ if (locked) {
+ throw new IllegalStateException("register called too " + (initialized ? "late" : "early") + ": registry locked!");
+ } else {
+ Item.REGISTRY.register(id, key.toString(), item);
+ }
+
+ return item;
+ }
+
+ public static void lock() {
+ if (!initialized) {
+ throw new IllegalStateException("cannot lock item registry unless it's been initialized!");
+ }
+
+ locked = true;
+ }
+
+ public static void unlock() {
+ if (initialized) {
+ throw new IllegalStateException("cannot unlock item registry once it's been initialized!");
+ }
+
+ locked = false;
+ }
+
+ public static void init() {
+ if (locked) {
+ throw new IllegalStateException("cannot initialize item registry when it's locked!");
+ }
+
+ ItemEvents.REGISTER_ITEMS.invoker().run();
+ initialized = true;
+ }
+}
diff --git a/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/mixin/common/BlockItemAccess.java b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/mixin/common/BlockItemAccess.java
new file mode 100644
index 00000000..001592ad
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/mixin/common/BlockItemAccess.java
@@ -0,0 +1,15 @@
+package net.ornithemc.osl.items.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+
+@Mixin(BlockItem.class)
+public interface BlockItemAccess {
+
+ @Accessor("block")
+ Block accessBlock();
+
+}
diff --git a/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
new file mode 100644
index 00000000..07185e86
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
@@ -0,0 +1,60 @@
+package net.ornithemc.osl.items.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.Slice;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+
+import net.minecraft.item.Item;
+import net.minecraft.util.registry.IdRegistry;
+
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+@Mixin(Item.class)
+public class ItemMixin {
+
+ @Inject(
+ method = "init",
+ at = @At(
+ value = "HEAD"
+ )
+ )
+ private static void osl$items$unlockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.unlock();
+ }
+
+ @Inject(
+ method = "init",
+ at = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/util/registry/IdRegistry;keySet()Ljava/util/Set;"
+ )
+ )
+ private static void osl$items$initAndLockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.init();
+ ItemRegistryImpl.lock();
+ }
+
+ @WrapOperation(
+ method = "init",
+ slice = @Slice(
+ from = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/util/registry/IdRegistry;keySet()Ljava/util/Set;"
+ )
+ ),
+ at = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/util/registry/IdRegistry;register(ILjava/lang/String;Ljava/lang/Object;)V"
+ )
+ )
+ private static void osl$items$registerBlockItems(IdRegistry- registry, int id, String key, Object item, Operation operation) {
+ if (ItemRegistryImpl.getItem(id) == null) {
+ operation.call(registry, id, key, item);
+ }
+ }
+}
diff --git a/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/fabric.mod.json b/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/fabric.mod.json
new file mode 100644
index 00000000..e8acd0b2
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/fabric.mod.json
@@ -0,0 +1,27 @@
+{
+ "schemaVersion": 1,
+ "id": "osl-items",
+ "version": "0.1.0-alpha.1+mc13w36a-mc14w25b",
+ "environment": "*",
+ "mixins": [
+ "osl.items.mixins.json"
+ ],
+ "accessWidener": "osl.items.classtweaker",
+ "depends": {
+ "fabricloader": "\u003e\u003d0.18.0",
+ "minecraft": "\u003e\u003d1.7-alpha.13.36.a \u003c\u003d1.8-alpha.14.25.b",
+ "osl-core": "\u003e\u003d0.7.0",
+ "osl-blocks": "\u003e\u003d0.1.0-"
+ },
+ "name": "OSL Items",
+ "description": "Items API and events.",
+ "authors": [
+ "OrnitheMC"
+ ],
+ "contact": {
+ "homepage": "https://ornithemc.net/",
+ "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues",
+ "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries"
+ },
+ "license": "Apache-2.0"
+}
\ No newline at end of file
diff --git a/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/osl.items.classtweaker b/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/osl.items.classtweaker
new file mode 100644
index 00000000..68957c43
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/osl.items.classtweaker
@@ -0,0 +1,11 @@
+classTweaker v1 named
+
+transitive-accessible method net/minecraft/item/Item setMaxStackSize (I)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setHasCustomData (Z)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setMaxDamage (I)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setHandheld ()Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setKey (Ljava/lang/String;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setRecipeRemainder (Lnet/minecraft/item/Item;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setPotionIngredient (Ljava/lang/String;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setCreativeModeTab (Lnet/minecraft/item/CreativeModeTab;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setSpriteName (Ljava/lang/String;)Lnet/minecraft/item/Item;
\ No newline at end of file
diff --git a/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/osl.items.mixins.json b/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/osl.items.mixins.json
new file mode 100644
index 00000000..9b15896a
--- /dev/null
+++ b/libraries/items/items-mc13w36a-mc14w25b/src/main/resources/osl.items.mixins.json
@@ -0,0 +1,17 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "net.ornithemc.osl.items.impl.mixin",
+ "compatibilityLevel": "JAVA_8",
+ "mixins": [
+ "common.BlockItemAccess",
+ "common.ItemMixin"
+ ],
+ "client": [
+ ],
+ "server": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/libraries/items/items-mc14w26a-mc17w46a/build.gradle b/libraries/items/items-mc14w26a-mc17w46a/build.gradle
new file mode 100644
index 00000000..0a350fdb
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/build.gradle
@@ -0,0 +1 @@
+setUpModule(project)
diff --git a/libraries/items/items-mc14w26a-mc17w46a/gradle.properties b/libraries/items/items-mc14w26a-mc17w46a/gradle.properties
new file mode 100644
index 00000000..abd5c757
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/gradle.properties
@@ -0,0 +1,5 @@
+min_mc_version = 14w26a
+max_mc_version = 17w46a
+minecraft_dependency = >=1.8-alpha.14.26.a <=1.13-alpha.17.46.a
+
+minecraft_version = 1.12.2
diff --git a/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java b/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
new file mode 100644
index 00000000..4d0923b9
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
@@ -0,0 +1,34 @@
+package net.ornithemc.osl.items.api;
+
+import net.ornithemc.osl.core.api.events.Event;
+
+/**
+ * Events related to the items lifecycle.
+ */
+public final class ItemEvents {
+
+ /**
+ * This event is invoked upon game start-up, after Vanilla item registration is finished.
+ *
+ *
+ * Custom item registration should be done in a listener of this event.
+ * Helper methods for registering items can be found in the {@linkplain
+ * ItemRegistry} class.
+ *
+ *
+ * Listeners to this event should be registered in your mod's entrypoint,
+ * and can be done as follows:
+ *
+ *
+ * {@code
+ * ItemEvents.REGISTER_ITEMS.register(() -> {
+ * ItemRegistry.register(999, NamespacedIdentifiers.from("example", "cookie"), new CookieItem());
+ * });
+ * }
+ *
+ *
+ * @see ItemRegistry
+ */
+ public static final Event REGISTER_ITEMS = Event.runnable();
+
+}
diff --git a/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java b/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
new file mode 100644
index 00000000..5c9fdcbc
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
@@ -0,0 +1,89 @@
+package net.ornithemc.osl.items.api;
+
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+/**
+ * Public access to the Items registry.
+ */
+public final class ItemRegistry {
+
+ /**
+ * @return the numerical ID assigned to the given item.
+ */
+ public static int getId(Item item) {
+ return ItemRegistryImpl.getId(item);
+ }
+
+ /**
+ * @return the namespaced ID assigned to the given item.
+ */
+ public static NamespacedIdentifier getKey(Item item) {
+ return ItemRegistryImpl.getKey(item);
+ }
+
+ /**
+ * @return the item mapped to the given numerical ID.
+ */
+ public static Item getItem(int id) {
+ return ItemRegistryImpl.getItem(id);
+ }
+
+ /**
+ * @return the item mapped to the given namespaced ID.
+ */
+ public static Item getItem(NamespacedIdentifier key) {
+ return ItemRegistryImpl.getItem(key);
+ }
+
+ /**
+ * @return a set containing all namespaced IDs in the registry.
+ */
+ public static Set keySet() {
+ return ItemRegistryImpl.keySet();
+ }
+
+ /**
+ * @param block the block item to register.
+ * @return the registered block item.
+ */
+ public static BlockItem register(Block block) {
+ return ItemRegistryImpl.register(block);
+ }
+
+ /**
+ * @param the item type.
+ * @param item the item to register.
+ * @return the registered block item.
+ */
+ public static T register(T item) {
+ return ItemRegistryImpl.register(item);
+ }
+
+ /**
+ * @param the item type.
+ * @param block the block placed by the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(Block block, T item) {
+ return ItemRegistryImpl.register(block, item);
+ }
+
+ /**
+ * @param the item type.
+ * @param id the numerical ID of the item.
+ * @param key the namespaced ID of the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(int id, NamespacedIdentifier key, T item) {
+ return ItemRegistryImpl.register(id, key, item);
+ }
+}
diff --git a/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java b/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
new file mode 100644
index 00000000..1e116539
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
@@ -0,0 +1,94 @@
+package net.ornithemc.osl.items.impl;
+
+import java.util.Collections;
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+import net.minecraft.resource.Identifier;
+
+import net.ornithemc.osl.blocks.api.BlockRegistry;
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.api.ItemEvents;
+
+public final class ItemRegistryImpl {
+
+ private static boolean locked = true;
+ private static boolean initialized = false;
+
+ public static int getId(Item item) {
+ return Item.REGISTRY.getId(item);
+ }
+
+ public static NamespacedIdentifier getKey(Item item) {
+ return Item.REGISTRY.getKey(item);
+ }
+
+ public static Item getItem(int id) {
+ return Item.REGISTRY.get(id);
+ }
+
+ public static Item getItem(NamespacedIdentifier key) {
+ return Item.REGISTRY.get(identifier(key));
+ }
+
+ public static Set keySet() {
+ return Collections.unmodifiableSet(Item.REGISTRY.keySet());
+ }
+
+ public static BlockItem register(Block block) {
+ return register(block, new BlockItem(block));
+ }
+
+ public static T register(T item) {
+ return register(item.getBlock(), item);
+ }
+
+ public static T register(Block block, T item) {
+ return register(BlockRegistry.getId(block), BlockRegistry.getKey(block), item);
+ }
+
+ public static T register(int id, NamespacedIdentifier key, T item) {
+ if (locked) {
+ throw new IllegalStateException("register called too " + (initialized ? "late" : "early") + ": registry locked!");
+ } else {
+ if (item instanceof BlockItem) {
+ Item.BLOCK_ITEMS.put(((BlockItem) item).getBlock(), item);
+ }
+
+ Item.REGISTRY.register(id, identifier(key), item);
+ }
+
+ return item;
+ }
+
+ private static Identifier identifier(NamespacedIdentifier id) {
+ return id instanceof Identifier ? (Identifier) id : new Identifier(id.namespace(), id.identifier());
+ }
+
+ public static void lock() {
+ if (!initialized) {
+ throw new IllegalStateException("cannot lock item registry unless it's been initialized!");
+ }
+
+ locked = true;
+ }
+
+ public static void unlock() {
+ if (initialized) {
+ throw new IllegalStateException("cannot unlock item registry once it's been initialized!");
+ }
+
+ locked = false;
+ }
+
+ public static void init() {
+ if (locked) {
+ throw new IllegalStateException("cannot initialize item registry when it's locked!");
+ }
+
+ ItemEvents.REGISTER_ITEMS.invoker().run();
+ initialized = true;
+ }
+}
diff --git a/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java b/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
new file mode 100644
index 00000000..d50463e1
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
@@ -0,0 +1,35 @@
+package net.ornithemc.osl.items.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+@Mixin(Item.class)
+public class ItemMixin {
+
+ @Inject(
+ method = "init",
+ at = @At(
+ value = "HEAD"
+ )
+ )
+ private static void osl$items$unlockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.unlock();
+ }
+
+ @Inject(
+ method = "init",
+ at = @At(
+ value = "TAIL"
+ )
+ )
+ private static void osl$items$initAndLockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.init();
+ ItemRegistryImpl.lock();
+ }
+}
diff --git a/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/fabric.mod.json b/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/fabric.mod.json
new file mode 100644
index 00000000..db78343f
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/fabric.mod.json
@@ -0,0 +1,27 @@
+{
+ "schemaVersion": 1,
+ "id": "osl-items",
+ "version": "0.1.0-alpha.1+mc14w26a-mc17w46a",
+ "environment": "*",
+ "mixins": [
+ "osl.items.mixins.json"
+ ],
+ "accessWidener": "osl.items.classtweaker",
+ "depends": {
+ "fabricloader": "\u003e\u003d0.18.0",
+ "minecraft": "\u003e\u003d1.8-alpha.14.26.a \u003c\u003d1.13-alpha.17.46.a",
+ "osl-core": "\u003e\u003d0.7.0",
+ "osl-blocks": "\u003e\u003d0.1.0-"
+ },
+ "name": "OSL Items",
+ "description": "Items API and events.",
+ "authors": [
+ "OrnitheMC"
+ ],
+ "contact": {
+ "homepage": "https://ornithemc.net/",
+ "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues",
+ "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries"
+ },
+ "license": "Apache-2.0"
+}
\ No newline at end of file
diff --git a/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/osl.items.classtweaker b/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/osl.items.classtweaker
new file mode 100644
index 00000000..2a595cb6
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/osl.items.classtweaker
@@ -0,0 +1,11 @@
+classTweaker v1 named
+
+accessible field net/minecraft/item/Item BLOCK_ITEMS Ljava/util/Map;
+
+transitive-accessible method net/minecraft/item/Item setMaxStackSize (I)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setHasCustomData (Z)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setMaxDamage (I)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setHandheld ()Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setKey (Ljava/lang/String;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setRecipeRemainder (Lnet/minecraft/item/Item;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setCreativeModeTab (Lnet/minecraft/item/CreativeModeTab;)Lnet/minecraft/item/Item;
\ No newline at end of file
diff --git a/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/osl.items.mixins.json b/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/osl.items.mixins.json
new file mode 100644
index 00000000..eba99f92
--- /dev/null
+++ b/libraries/items/items-mc14w26a-mc17w46a/src/main/resources/osl.items.mixins.json
@@ -0,0 +1,16 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "net.ornithemc.osl.items.impl.mixin",
+ "compatibilityLevel": "JAVA_8",
+ "mixins": [
+ "common.ItemMixin"
+ ],
+ "client": [
+ ],
+ "server": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/libraries/items/items-mc17w47a-mc18w31a/build.gradle b/libraries/items/items-mc17w47a-mc18w31a/build.gradle
new file mode 100644
index 00000000..0a350fdb
--- /dev/null
+++ b/libraries/items/items-mc17w47a-mc18w31a/build.gradle
@@ -0,0 +1 @@
+setUpModule(project)
diff --git a/libraries/items/items-mc17w47a-mc18w31a/gradle.properties b/libraries/items/items-mc17w47a-mc18w31a/gradle.properties
new file mode 100644
index 00000000..214f5d68
--- /dev/null
+++ b/libraries/items/items-mc17w47a-mc18w31a/gradle.properties
@@ -0,0 +1,5 @@
+min_mc_version = 17w47a
+max_mc_version = 18w31a
+minecraft_dependency = >=1.13-alpha.17.47.a <=1.13.1-alpha.18.31.a
+
+minecraft_version = 1.13
diff --git a/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java b/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
new file mode 100644
index 00000000..e4b60f8b
--- /dev/null
+++ b/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
@@ -0,0 +1,34 @@
+package net.ornithemc.osl.items.api;
+
+import net.ornithemc.osl.core.api.events.Event;
+
+/**
+ * Events related to the items lifecycle.
+ */
+public final class ItemEvents {
+
+ /**
+ * This event is invoked upon game start-up, after Vanilla item registration is finished.
+ *
+ *
+ * Custom item registration should be done in a listener of this event.
+ * Helper methods for registering items can be found in the {@linkplain
+ * ItemRegistry} class.
+ *
+ *
+ * Listeners to this event should be registered in your mod's entrypoint,
+ * and can be done as follows:
+ *
+ *
+ * {@code
+ * ItemEvents.REGISTER_ITEMS.register(() -> {
+ * ItemRegistry.register(NamespacedIdentifiers.from("example", "cookie"), new CookieItem());
+ * });
+ * }
+ *
+ *
+ * @see ItemRegistry
+ */
+ public static final Event REGISTER_ITEMS = Event.runnable();
+
+}
diff --git a/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java b/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
new file mode 100644
index 00000000..fc2acc8b
--- /dev/null
+++ b/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
@@ -0,0 +1,88 @@
+package net.ornithemc.osl.items.api;
+
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+/**
+ * Public access to the Items registry.
+ */
+public final class ItemRegistry {
+
+ /**
+ * @return the numerical ID assigned to the given item.
+ */
+ public static int getId(Item item) {
+ return ItemRegistryImpl.getId(item);
+ }
+
+ /**
+ * @return the namespaced ID assigned to the given item.
+ */
+ public static NamespacedIdentifier getKey(Item item) {
+ return ItemRegistryImpl.getKey(item);
+ }
+
+ /**
+ * @return the item mapped to the given numerical ID.
+ */
+ public static Item getItem(int id) {
+ return ItemRegistryImpl.getItem(id);
+ }
+
+ /**
+ * @return the item mapped to the given namespaced ID.
+ */
+ public static Item getItem(NamespacedIdentifier key) {
+ return ItemRegistryImpl.getItem(key);
+ }
+
+ /**
+ * @return a set containing all namespaced IDs in the registry.
+ */
+ public static Set keySet() {
+ return ItemRegistryImpl.keySet();
+ }
+
+ /**
+ * @param block the block item to register.
+ * @return the registered block item.
+ */
+ public static BlockItem register(Block block) {
+ return ItemRegistryImpl.register(block);
+ }
+
+ /**
+ * @param the item type.
+ * @param item the item to register.
+ * @return the registered block item.
+ */
+ public static T register(T item) {
+ return ItemRegistryImpl.register(item);
+ }
+
+ /**
+ * @param the item type.
+ * @param block the block placed by the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(Block block, T item) {
+ return ItemRegistryImpl.register(block, item);
+ }
+
+ /**
+ * @param the item type.
+ * @param key the namespaced ID of the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(NamespacedIdentifier key, T item) {
+ return ItemRegistryImpl.register(key, item);
+ }
+}
diff --git a/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java b/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
new file mode 100644
index 00000000..484c47ce
--- /dev/null
+++ b/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
@@ -0,0 +1,94 @@
+package net.ornithemc.osl.items.impl;
+
+import java.util.Collections;
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+import net.minecraft.resource.Identifier;
+
+import net.ornithemc.osl.blocks.api.BlockRegistry;
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.api.ItemEvents;
+
+public final class ItemRegistryImpl {
+
+ private static boolean locked = true;
+ private static boolean initialized = false;
+
+ public static int getId(Item item) {
+ return Item.REGISTRY.getId(item);
+ }
+
+ public static NamespacedIdentifier getKey(Item item) {
+ return Item.REGISTRY.getKey(item);
+ }
+
+ public static Item getItem(int id) {
+ return Item.REGISTRY.get(id);
+ }
+
+ public static Item getItem(NamespacedIdentifier key) {
+ return Item.REGISTRY.get(identifier(key));
+ }
+
+ public static Set keySet() {
+ return Collections.unmodifiableSet(Item.REGISTRY.entrySet());
+ }
+
+ public static BlockItem register(Block block) {
+ return register(block, new BlockItem(block, new Item.Properties()));
+ }
+
+ public static T register(T item) {
+ return register(item.getBlock(), item);
+ }
+
+ public static T register(Block block, T item) {
+ return register(BlockRegistry.getKey(block), item);
+ }
+
+ public static T register(NamespacedIdentifier key, T item) {
+ if (locked) {
+ throw new IllegalStateException("register called too " + (initialized ? "late" : "early") + ": registry locked!");
+ } else {
+ if (item instanceof BlockItem) {
+ ((BlockItem) item).register(Item.BLOCK_ITEMS, item);
+ }
+
+ Item.REGISTRY.put(identifier(key), item);
+ }
+
+ return item;
+ }
+
+ private static Identifier identifier(NamespacedIdentifier id) {
+ return id instanceof Identifier ? (Identifier) id : new Identifier(id.namespace(), id.identifier());
+ }
+
+ public static void lock() {
+ if (!initialized) {
+ throw new IllegalStateException("cannot lock item registry unless it's been initialized!");
+ }
+
+ locked = true;
+ }
+
+ public static void unlock() {
+ if (initialized) {
+ throw new IllegalStateException("cannot unlock item registry once it's been initialized!");
+ }
+
+ locked = false;
+ }
+
+ public static void init() {
+ if (locked) {
+ throw new IllegalStateException("cannot initialize item registry when it's locked!");
+ }
+
+ ItemEvents.REGISTER_ITEMS.invoker().run();
+ initialized = true;
+ }
+}
diff --git a/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java b/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
new file mode 100644
index 00000000..d50463e1
--- /dev/null
+++ b/libraries/items/items-mc17w47a-mc18w31a/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
@@ -0,0 +1,35 @@
+package net.ornithemc.osl.items.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+@Mixin(Item.class)
+public class ItemMixin {
+
+ @Inject(
+ method = "init",
+ at = @At(
+ value = "HEAD"
+ )
+ )
+ private static void osl$items$unlockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.unlock();
+ }
+
+ @Inject(
+ method = "init",
+ at = @At(
+ value = "TAIL"
+ )
+ )
+ private static void osl$items$initAndLockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.init();
+ ItemRegistryImpl.lock();
+ }
+}
diff --git a/libraries/items/items-mc17w47a-mc18w31a/src/main/resources/fabric.mod.json b/libraries/items/items-mc17w47a-mc18w31a/src/main/resources/fabric.mod.json
new file mode 100644
index 00000000..032ee1b8
--- /dev/null
+++ b/libraries/items/items-mc17w47a-mc18w31a/src/main/resources/fabric.mod.json
@@ -0,0 +1,26 @@
+{
+ "schemaVersion": 1,
+ "id": "osl-items",
+ "version": "0.1.0-alpha.1+mc17w47a-mc18w31a",
+ "environment": "*",
+ "mixins": [
+ "osl.items.mixins.json"
+ ],
+ "depends": {
+ "fabricloader": "\u003e\u003d0.18.0",
+ "minecraft": "\u003e\u003d1.13-alpha.17.47.a \u003c\u003d1.13.1-alpha.18.31.a",
+ "osl-core": "\u003e\u003d0.7.0",
+ "osl-blocks": "\u003e\u003d0.1.0-"
+ },
+ "name": "OSL Items",
+ "description": "Items API and events.",
+ "authors": [
+ "OrnitheMC"
+ ],
+ "contact": {
+ "homepage": "https://ornithemc.net/",
+ "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues",
+ "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries"
+ },
+ "license": "Apache-2.0"
+}
\ No newline at end of file
diff --git a/libraries/items/items-mc17w47a-mc18w31a/src/main/resources/osl.items.mixins.json b/libraries/items/items-mc17w47a-mc18w31a/src/main/resources/osl.items.mixins.json
new file mode 100644
index 00000000..eba99f92
--- /dev/null
+++ b/libraries/items/items-mc17w47a-mc18w31a/src/main/resources/osl.items.mixins.json
@@ -0,0 +1,16 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "net.ornithemc.osl.items.impl.mixin",
+ "compatibilityLevel": "JAVA_8",
+ "mixins": [
+ "common.ItemMixin"
+ ],
+ "client": [
+ ],
+ "server": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/libraries/items/items-mc18w32a-mc1.13.2/build.gradle b/libraries/items/items-mc18w32a-mc1.13.2/build.gradle
new file mode 100644
index 00000000..0a350fdb
--- /dev/null
+++ b/libraries/items/items-mc18w32a-mc1.13.2/build.gradle
@@ -0,0 +1 @@
+setUpModule(project)
diff --git a/libraries/items/items-mc18w32a-mc1.13.2/gradle.properties b/libraries/items/items-mc18w32a-mc1.13.2/gradle.properties
new file mode 100644
index 00000000..4c9c2619
--- /dev/null
+++ b/libraries/items/items-mc18w32a-mc1.13.2/gradle.properties
@@ -0,0 +1,5 @@
+min_mc_version = 18w32a
+max_mc_version = 1.13.2
+minecraft_dependency = >=1.13.1-alpha.18.32.a <=1.13.2
+
+minecraft_version = 1.13.2
diff --git a/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java b/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
new file mode 100644
index 00000000..e4b60f8b
--- /dev/null
+++ b/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
@@ -0,0 +1,34 @@
+package net.ornithemc.osl.items.api;
+
+import net.ornithemc.osl.core.api.events.Event;
+
+/**
+ * Events related to the items lifecycle.
+ */
+public final class ItemEvents {
+
+ /**
+ * This event is invoked upon game start-up, after Vanilla item registration is finished.
+ *
+ *
+ * Custom item registration should be done in a listener of this event.
+ * Helper methods for registering items can be found in the {@linkplain
+ * ItemRegistry} class.
+ *
+ *
+ * Listeners to this event should be registered in your mod's entrypoint,
+ * and can be done as follows:
+ *
+ *
+ * {@code
+ * ItemEvents.REGISTER_ITEMS.register(() -> {
+ * ItemRegistry.register(NamespacedIdentifiers.from("example", "cookie"), new CookieItem());
+ * });
+ * }
+ *
+ *
+ * @see ItemRegistry
+ */
+ public static final Event REGISTER_ITEMS = Event.runnable();
+
+}
diff --git a/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java b/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
new file mode 100644
index 00000000..fc2acc8b
--- /dev/null
+++ b/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
@@ -0,0 +1,88 @@
+package net.ornithemc.osl.items.api;
+
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+/**
+ * Public access to the Items registry.
+ */
+public final class ItemRegistry {
+
+ /**
+ * @return the numerical ID assigned to the given item.
+ */
+ public static int getId(Item item) {
+ return ItemRegistryImpl.getId(item);
+ }
+
+ /**
+ * @return the namespaced ID assigned to the given item.
+ */
+ public static NamespacedIdentifier getKey(Item item) {
+ return ItemRegistryImpl.getKey(item);
+ }
+
+ /**
+ * @return the item mapped to the given numerical ID.
+ */
+ public static Item getItem(int id) {
+ return ItemRegistryImpl.getItem(id);
+ }
+
+ /**
+ * @return the item mapped to the given namespaced ID.
+ */
+ public static Item getItem(NamespacedIdentifier key) {
+ return ItemRegistryImpl.getItem(key);
+ }
+
+ /**
+ * @return a set containing all namespaced IDs in the registry.
+ */
+ public static Set keySet() {
+ return ItemRegistryImpl.keySet();
+ }
+
+ /**
+ * @param block the block item to register.
+ * @return the registered block item.
+ */
+ public static BlockItem register(Block block) {
+ return ItemRegistryImpl.register(block);
+ }
+
+ /**
+ * @param the item type.
+ * @param item the item to register.
+ * @return the registered block item.
+ */
+ public static T register(T item) {
+ return ItemRegistryImpl.register(item);
+ }
+
+ /**
+ * @param the item type.
+ * @param block the block placed by the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(Block block, T item) {
+ return ItemRegistryImpl.register(block, item);
+ }
+
+ /**
+ * @param the item type.
+ * @param key the namespaced ID of the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(NamespacedIdentifier key, T item) {
+ return ItemRegistryImpl.register(key, item);
+ }
+}
diff --git a/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java b/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
new file mode 100644
index 00000000..99878100
--- /dev/null
+++ b/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
@@ -0,0 +1,95 @@
+package net.ornithemc.osl.items.impl;
+
+import java.util.Collections;
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+import net.minecraft.resource.Identifier;
+import net.minecraft.util.registry.Registry;
+
+import net.ornithemc.osl.blocks.api.BlockRegistry;
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.api.ItemEvents;
+
+public final class ItemRegistryImpl {
+
+ private static boolean locked = true;
+ private static boolean initialized = false;
+
+ public static int getId(Item item) {
+ return Registry.ITEM.getId(item);
+ }
+
+ public static NamespacedIdentifier getKey(Item item) {
+ return Registry.ITEM.getKey(item);
+ }
+
+ public static Item getItem(int id) {
+ return Registry.ITEM.get(id);
+ }
+
+ public static Item getItem(NamespacedIdentifier key) {
+ return Registry.ITEM.get(identifier(key));
+ }
+
+ public static Set keySet() {
+ return Collections.unmodifiableSet(Registry.ITEM.keySet());
+ }
+
+ public static BlockItem register(Block block) {
+ return register(block, new BlockItem(block, new Item.Properties()));
+ }
+
+ public static T register(T item) {
+ return register(item.getBlock(), item);
+ }
+
+ public static T register(Block block, T item) {
+ return register(BlockRegistry.getKey(block), item);
+ }
+
+ public static T register(NamespacedIdentifier key, T item) {
+ if (locked) {
+ throw new IllegalStateException("register called too " + (initialized ? "late" : "early") + ": registry locked!");
+ } else {
+ if (item instanceof BlockItem) {
+ ((BlockItem) item).register(Item.BLOCK_ITEMS, item);
+ }
+
+ Registry.ITEM.register(identifier(key), item);
+ }
+
+ return item;
+ }
+
+ private static Identifier identifier(NamespacedIdentifier id) {
+ return id instanceof Identifier ? (Identifier) id : new Identifier(id.namespace(), id.identifier());
+ }
+
+ public static void lock() {
+ if (!initialized) {
+ throw new IllegalStateException("cannot lock item registry unless it's been initialized!");
+ }
+
+ locked = true;
+ }
+
+ public static void unlock() {
+ if (initialized) {
+ throw new IllegalStateException("cannot unlock item registry once it's been initialized!");
+ }
+
+ locked = false;
+ }
+
+ public static void init() {
+ if (locked) {
+ throw new IllegalStateException("cannot initialize item registry when it's locked!");
+ }
+
+ ItemEvents.REGISTER_ITEMS.invoker().run();
+ initialized = true;
+ }
+}
diff --git a/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java b/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
new file mode 100644
index 00000000..d50463e1
--- /dev/null
+++ b/libraries/items/items-mc18w32a-mc1.13.2/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
@@ -0,0 +1,35 @@
+package net.ornithemc.osl.items.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+@Mixin(Item.class)
+public class ItemMixin {
+
+ @Inject(
+ method = "init",
+ at = @At(
+ value = "HEAD"
+ )
+ )
+ private static void osl$items$unlockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.unlock();
+ }
+
+ @Inject(
+ method = "init",
+ at = @At(
+ value = "TAIL"
+ )
+ )
+ private static void osl$items$initAndLockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.init();
+ ItemRegistryImpl.lock();
+ }
+}
diff --git a/libraries/items/items-mc18w32a-mc1.13.2/src/main/resources/fabric.mod.json b/libraries/items/items-mc18w32a-mc1.13.2/src/main/resources/fabric.mod.json
new file mode 100644
index 00000000..6fb7a32b
--- /dev/null
+++ b/libraries/items/items-mc18w32a-mc1.13.2/src/main/resources/fabric.mod.json
@@ -0,0 +1,26 @@
+{
+ "schemaVersion": 1,
+ "id": "osl-items",
+ "version": "0.1.0-alpha.1+mc18w32a-mc1.13.2",
+ "environment": "*",
+ "mixins": [
+ "osl.items.mixins.json"
+ ],
+ "depends": {
+ "fabricloader": "\u003e\u003d0.18.0",
+ "minecraft": "\u003e\u003d1.13.1-alpha.18.32.a \u003c\u003d1.13.2",
+ "osl-core": "\u003e\u003d0.7.0",
+ "osl-blocks": "\u003e\u003d0.1.0-"
+ },
+ "name": "OSL Items",
+ "description": "Items API and events.",
+ "authors": [
+ "OrnitheMC"
+ ],
+ "contact": {
+ "homepage": "https://ornithemc.net/",
+ "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues",
+ "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries"
+ },
+ "license": "Apache-2.0"
+}
\ No newline at end of file
diff --git a/libraries/items/items-mc18w32a-mc1.13.2/src/main/resources/osl.items.mixins.json b/libraries/items/items-mc18w32a-mc1.13.2/src/main/resources/osl.items.mixins.json
new file mode 100644
index 00000000..eba99f92
--- /dev/null
+++ b/libraries/items/items-mc18w32a-mc1.13.2/src/main/resources/osl.items.mixins.json
@@ -0,0 +1,16 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "net.ornithemc.osl.items.impl.mixin",
+ "compatibilityLevel": "JAVA_8",
+ "mixins": [
+ "common.ItemMixin"
+ ],
+ "client": [
+ ],
+ "server": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/libraries/items/items-mc18w43a-mc1.14.4/build.gradle b/libraries/items/items-mc18w43a-mc1.14.4/build.gradle
new file mode 100644
index 00000000..0a350fdb
--- /dev/null
+++ b/libraries/items/items-mc18w43a-mc1.14.4/build.gradle
@@ -0,0 +1 @@
+setUpModule(project)
diff --git a/libraries/items/items-mc18w43a-mc1.14.4/gradle.properties b/libraries/items/items-mc18w43a-mc1.14.4/gradle.properties
new file mode 100644
index 00000000..071d210e
--- /dev/null
+++ b/libraries/items/items-mc18w43a-mc1.14.4/gradle.properties
@@ -0,0 +1,5 @@
+min_mc_version = 18w43a
+max_mc_version = 1.14.4
+minecraft_dependency = >=1.14-alpha.18.43.a <=1.14.4
+
+minecraft_version = 1.14.4
diff --git a/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java b/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
new file mode 100644
index 00000000..e4b60f8b
--- /dev/null
+++ b/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
@@ -0,0 +1,34 @@
+package net.ornithemc.osl.items.api;
+
+import net.ornithemc.osl.core.api.events.Event;
+
+/**
+ * Events related to the items lifecycle.
+ */
+public final class ItemEvents {
+
+ /**
+ * This event is invoked upon game start-up, after Vanilla item registration is finished.
+ *
+ *
+ * Custom item registration should be done in a listener of this event.
+ * Helper methods for registering items can be found in the {@linkplain
+ * ItemRegistry} class.
+ *
+ *
+ * Listeners to this event should be registered in your mod's entrypoint,
+ * and can be done as follows:
+ *
+ *
+ * {@code
+ * ItemEvents.REGISTER_ITEMS.register(() -> {
+ * ItemRegistry.register(NamespacedIdentifiers.from("example", "cookie"), new CookieItem());
+ * });
+ * }
+ *
+ *
+ * @see ItemRegistry
+ */
+ public static final Event REGISTER_ITEMS = Event.runnable();
+
+}
diff --git a/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java b/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
new file mode 100644
index 00000000..fc2acc8b
--- /dev/null
+++ b/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
@@ -0,0 +1,88 @@
+package net.ornithemc.osl.items.api;
+
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+/**
+ * Public access to the Items registry.
+ */
+public final class ItemRegistry {
+
+ /**
+ * @return the numerical ID assigned to the given item.
+ */
+ public static int getId(Item item) {
+ return ItemRegistryImpl.getId(item);
+ }
+
+ /**
+ * @return the namespaced ID assigned to the given item.
+ */
+ public static NamespacedIdentifier getKey(Item item) {
+ return ItemRegistryImpl.getKey(item);
+ }
+
+ /**
+ * @return the item mapped to the given numerical ID.
+ */
+ public static Item getItem(int id) {
+ return ItemRegistryImpl.getItem(id);
+ }
+
+ /**
+ * @return the item mapped to the given namespaced ID.
+ */
+ public static Item getItem(NamespacedIdentifier key) {
+ return ItemRegistryImpl.getItem(key);
+ }
+
+ /**
+ * @return a set containing all namespaced IDs in the registry.
+ */
+ public static Set keySet() {
+ return ItemRegistryImpl.keySet();
+ }
+
+ /**
+ * @param block the block item to register.
+ * @return the registered block item.
+ */
+ public static BlockItem register(Block block) {
+ return ItemRegistryImpl.register(block);
+ }
+
+ /**
+ * @param the item type.
+ * @param item the item to register.
+ * @return the registered block item.
+ */
+ public static T register(T item) {
+ return ItemRegistryImpl.register(item);
+ }
+
+ /**
+ * @param the item type.
+ * @param block the block placed by the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(Block block, T item) {
+ return ItemRegistryImpl.register(block, item);
+ }
+
+ /**
+ * @param the item type.
+ * @param key the namespaced ID of the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(NamespacedIdentifier key, T item) {
+ return ItemRegistryImpl.register(key, item);
+ }
+}
diff --git a/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java b/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
new file mode 100644
index 00000000..8bc9e720
--- /dev/null
+++ b/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
@@ -0,0 +1,93 @@
+package net.ornithemc.osl.items.impl;
+
+import java.util.Collections;
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+import net.minecraft.resource.Identifier;
+import net.minecraft.util.registry.Registry;
+
+import net.ornithemc.osl.blocks.api.BlockRegistry;
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.api.ItemEvents;
+
+public final class ItemRegistryImpl {
+
+ private static boolean locked = true;
+ private static boolean initialized = false;
+
+ public static int getId(Item item) {
+ return Registry.ITEM.getId(item);
+ }
+
+ public static NamespacedIdentifier getKey(Item item) {
+ return Registry.ITEM.getKey(item);
+ }
+
+ public static Item getItem(int id) {
+ return Registry.ITEM.get(id);
+ }
+
+ public static Item getItem(NamespacedIdentifier key) {
+ return Registry.ITEM.getOrDefault(identifier(key));
+ }
+
+ public static Set keySet() {
+ return Collections.unmodifiableSet(Registry.ITEM.keySet());
+ }
+
+ public static BlockItem register(Block block) {
+ return register(block, new BlockItem(block, new Item.Properties()));
+ }
+
+ public static T register(T item) {
+ return register(item.getBlock(), item);
+ }
+
+ public static T register(Block block, T item) {
+ return register(BlockRegistry.getKey(block), item);
+ }
+
+ public static T register(NamespacedIdentifier key, T item) {
+ if (locked) {
+ throw new IllegalStateException("register called too " + (initialized ? "late" : "early") + ": registry locked!");
+ } else {
+ if (item instanceof BlockItem) {
+ ((BlockItem) item).register(Item.BLOCK_ITEMS, item);
+ }
+
+ return Registry.ITEM.m_30368144(identifier(key), item);
+ }
+ }
+
+ private static Identifier identifier(NamespacedIdentifier id) {
+ return id instanceof Identifier ? (Identifier) id : new Identifier(id.namespace(), id.identifier());
+ }
+
+ public static void lock() {
+ if (!initialized) {
+ throw new IllegalStateException("cannot lock item registry unless it's been initialized!");
+ }
+
+ locked = true;
+ }
+
+ public static void unlock() {
+ if (initialized) {
+ throw new IllegalStateException("cannot unlock item registry once it's been initialized!");
+ }
+
+ locked = false;
+ }
+
+ public static void init() {
+ if (locked) {
+ throw new IllegalStateException("cannot initialize item registry when it's locked!");
+ }
+
+ ItemEvents.REGISTER_ITEMS.invoker().run();
+ initialized = true;
+ }
+}
diff --git a/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemsMixin.java b/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemsMixin.java
new file mode 100644
index 00000000..44264b2e
--- /dev/null
+++ b/libraries/items/items-mc18w43a-mc1.14.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemsMixin.java
@@ -0,0 +1,35 @@
+package net.ornithemc.osl.items.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import net.minecraft.item.Items;
+
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+@Mixin(Items.class)
+public class ItemsMixin {
+
+ @Inject(
+ method = "",
+ at = @At(
+ value = "HEAD"
+ )
+ )
+ private static void osl$items$unlockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.unlock();
+ }
+
+ @Inject(
+ method = "",
+ at = @At(
+ value = "TAIL"
+ )
+ )
+ private static void osl$items$initAndLockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.init();
+ ItemRegistryImpl.lock();
+ }
+}
diff --git a/libraries/items/items-mc18w43a-mc1.14.4/src/main/resources/fabric.mod.json b/libraries/items/items-mc18w43a-mc1.14.4/src/main/resources/fabric.mod.json
new file mode 100644
index 00000000..3e43e575
--- /dev/null
+++ b/libraries/items/items-mc18w43a-mc1.14.4/src/main/resources/fabric.mod.json
@@ -0,0 +1,26 @@
+{
+ "schemaVersion": 1,
+ "id": "osl-items",
+ "version": "0.1.0-alpha.1+mc18w43a-mc1.14.4",
+ "environment": "*",
+ "mixins": [
+ "osl.items.mixins.json"
+ ],
+ "depends": {
+ "fabricloader": "\u003e\u003d0.18.0",
+ "minecraft": "\u003e\u003d1.14-alpha.18.43.a \u003c\u003d1.14.4",
+ "osl-core": "\u003e\u003d0.7.0",
+ "osl-blocks": "\u003e\u003d0.1.0-"
+ },
+ "name": "OSL Items",
+ "description": "Items API and events.",
+ "authors": [
+ "OrnitheMC"
+ ],
+ "contact": {
+ "homepage": "https://ornithemc.net/",
+ "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues",
+ "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries"
+ },
+ "license": "Apache-2.0"
+}
\ No newline at end of file
diff --git a/libraries/items/items-mc18w43a-mc1.14.4/src/main/resources/osl.items.mixins.json b/libraries/items/items-mc18w43a-mc1.14.4/src/main/resources/osl.items.mixins.json
new file mode 100644
index 00000000..a0d26288
--- /dev/null
+++ b/libraries/items/items-mc18w43a-mc1.14.4/src/main/resources/osl.items.mixins.json
@@ -0,0 +1,16 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "net.ornithemc.osl.items.impl.mixin",
+ "compatibilityLevel": "JAVA_8",
+ "mixins": [
+ "common.ItemsMixin"
+ ],
+ "client": [
+ ],
+ "server": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/build.gradle b/libraries/items/items-mca1.0.1_01-mc1.6.4/build.gradle
new file mode 100644
index 00000000..0a350fdb
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/build.gradle
@@ -0,0 +1 @@
+setUpModule(project)
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/gradle.properties b/libraries/items/items-mca1.0.1_01-mc1.6.4/gradle.properties
new file mode 100644
index 00000000..48fac24e
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/gradle.properties
@@ -0,0 +1,8 @@
+min_mc_version = a1.0.1_01
+max_mc_version = 1.6.4
+minecraft_dependency = >=1.0.0-alpha.0.1 <=1.6.4
+
+minecraft_version = 1.6.4
+raven_build = 1
+sparrow_build = 1
+nests_build = 3
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
new file mode 100644
index 00000000..7cd360c3
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/api/ItemEvents.java
@@ -0,0 +1,34 @@
+package net.ornithemc.osl.items.api;
+
+import net.ornithemc.osl.core.api.events.Event;
+
+/**
+ * Events related to the items lifecycle.
+ */
+public final class ItemEvents {
+
+ /**
+ * This event is invoked upon game start-up, after Vanilla item registration is finished.
+ *
+ *
+ * Custom item registration should be done in a listener of this event.
+ * Helper methods for registering items can be found in the {@linkplain
+ * ItemRegistry} class.
+ *
+ *
+ * Listeners to this event should be registered in your mod's entrypoint,
+ * and can be done as follows:
+ *
+ *
+ * {@code
+ * ItemEvents.REGISTER_ITEMS.register(() -> {
+ * ItemRegistry.register(999, NamespacedIdentifiers.from("example", "cookie"), new CookieItem(999));
+ * });
+ * }
+ *
+ *
+ * @see ItemRegistry
+ */
+ public static final Event REGISTER_ITEMS = Event.runnable();
+
+}
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
new file mode 100644
index 00000000..5c9fdcbc
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/api/ItemRegistry.java
@@ -0,0 +1,89 @@
+package net.ornithemc.osl.items.api;
+
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+/**
+ * Public access to the Items registry.
+ */
+public final class ItemRegistry {
+
+ /**
+ * @return the numerical ID assigned to the given item.
+ */
+ public static int getId(Item item) {
+ return ItemRegistryImpl.getId(item);
+ }
+
+ /**
+ * @return the namespaced ID assigned to the given item.
+ */
+ public static NamespacedIdentifier getKey(Item item) {
+ return ItemRegistryImpl.getKey(item);
+ }
+
+ /**
+ * @return the item mapped to the given numerical ID.
+ */
+ public static Item getItem(int id) {
+ return ItemRegistryImpl.getItem(id);
+ }
+
+ /**
+ * @return the item mapped to the given namespaced ID.
+ */
+ public static Item getItem(NamespacedIdentifier key) {
+ return ItemRegistryImpl.getItem(key);
+ }
+
+ /**
+ * @return a set containing all namespaced IDs in the registry.
+ */
+ public static Set keySet() {
+ return ItemRegistryImpl.keySet();
+ }
+
+ /**
+ * @param block the block item to register.
+ * @return the registered block item.
+ */
+ public static BlockItem register(Block block) {
+ return ItemRegistryImpl.register(block);
+ }
+
+ /**
+ * @param the item type.
+ * @param item the item to register.
+ * @return the registered block item.
+ */
+ public static T register(T item) {
+ return ItemRegistryImpl.register(item);
+ }
+
+ /**
+ * @param the item type.
+ * @param block the block placed by the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(Block block, T item) {
+ return ItemRegistryImpl.register(block, item);
+ }
+
+ /**
+ * @param the item type.
+ * @param id the numerical ID of the item.
+ * @param key the namespaced ID of the item.
+ * @param item the item to register.
+ * @return the registered item.
+ */
+ public static T register(int id, NamespacedIdentifier key, T item) {
+ return ItemRegistryImpl.register(id, key, item);
+ }
+}
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
new file mode 100644
index 00000000..9821a308
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/ItemRegistryImpl.java
@@ -0,0 +1,90 @@
+package net.ornithemc.osl.items.impl;
+
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.blocks.api.BlockRegistry;
+import net.ornithemc.osl.core.api.registry.SimpleIdRegistry;
+import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
+import net.ornithemc.osl.items.api.ItemEvents;
+import net.ornithemc.osl.items.impl.mixin.common.BlockItemAccess;
+
+public final class ItemRegistryImpl {
+
+ private static final SimpleIdRegistry- REGISTRY = new SimpleIdRegistry<>();
+
+ private static boolean locked = true;
+ private static boolean initialized = false;
+
+ public static int getId(Item item) {
+ return REGISTRY.getId(item);
+ }
+
+ public static NamespacedIdentifier getKey(Item item) {
+ return REGISTRY.getKey(item);
+ }
+
+ public static Item getItem(int id) {
+ return REGISTRY.get(id);
+ }
+
+ public static Item getItem(NamespacedIdentifier key) {
+ return REGISTRY.get(key);
+ }
+
+ public static Set keySet() {
+ return REGISTRY.keySet();
+ }
+
+ public static BlockItem register(Block block) {
+ return register(block, new BlockItem(BlockRegistry.getId(block)));
+ }
+
+ public static T register(T item) {
+ return register(BlockRegistry.getBlock(((BlockItemAccess) item).accessBlock()), item);
+ }
+
+ public static T register(Block block, T item) {
+ return register(BlockRegistry.getId(block), BlockRegistry.getKey(block), item);
+ }
+
+ public static T register(int id, NamespacedIdentifier key, T item) {
+ if (locked) {
+ throw new IllegalStateException("register called too " + (initialized ? "late" : "early") + ": registry locked!");
+ } else {
+ REGISTRY.register(id, key, item);
+ }
+
+ return item;
+ }
+
+ public static void lock() {
+ if (!initialized) {
+ throw new IllegalStateException("cannot lock item registry unless it's been initialized!");
+ }
+
+ locked = true;
+ }
+
+ public static void unlock() {
+ if (initialized) {
+ throw new IllegalStateException("cannot unlock item registry once it's been initialized!");
+ }
+
+ locked = false;
+ }
+
+ public static void init() {
+ if (locked) {
+ throw new IllegalStateException("cannot initialize item registry when it's locked!");
+ }
+
+ VanillaItems.init();
+ VanillaBlockItems.init();
+ ItemEvents.REGISTER_ITEMS.invoker().run();
+ initialized = true;
+ }
+}
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/VanillaBlockItems.java b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/VanillaBlockItems.java
new file mode 100644
index 00000000..b9d43d1e
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/VanillaBlockItems.java
@@ -0,0 +1,22 @@
+package net.ornithemc.osl.items.impl;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+
+final class VanillaBlockItems {
+
+ static void init() {
+ for (int id = 0; id < Block.BY_ID.length; id++) {
+ Block block = Block.BY_ID[id];
+ Item item = Item.BY_ID[id];
+
+ if (item != null) {
+ if (ItemRegistryImpl.getItem(id) == null) {
+ ItemRegistryImpl.register(block, item);
+ } else {
+ // what the fuck?
+ }
+ }
+ }
+ }
+}
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/VanillaItems.java b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/VanillaItems.java
new file mode 100644
index 00000000..feb8640d
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/VanillaItems.java
@@ -0,0 +1,258 @@
+package net.ornithemc.osl.items.impl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.core.api.util.NamespacedIdentifiers;
+
+final class VanillaItems {
+
+ /**
+ * Namespaced IDs were introduced in 1.7. Before then, the numerical IDs
+ * were the only unique identifiers for items. Here we assign namespaced
+ * IDs to pre-1.7 items, matching the 1.7 IDs where possible.
+ *
+ * Note that in 1.7 snapshots the IDs went through several changes.
+ * The IDs used here match those used in Release 1.7.2.
+ */
+ private static final String[] IDENTIFIERS = {
+ // grouped per 10 for easier lookup
+
+ "iron_shovel",
+ "iron_pickaxe",
+ "iron_axe",
+ "flint_and_steel",
+ "apple",
+ "bow",
+ "arrow",
+ "coal",
+ "diamond",
+ "iron_ingot",
+
+ "gold_ingot",
+ "iron_sword",
+ "wooden_sword",
+ "wooden_shovel",
+ "wooden_pickaxe",
+ "wooden_axe",
+ "stone_sword",
+ "stone_shovel",
+ "stone_pickaxe",
+ "stone_axe",
+
+ "diamond_sword",
+ "diamond_shovel",
+ "diamond_pickaxe",
+ "diamond_axe",
+ "stick",
+ "bowl",
+ "mushroom_stew",
+ "golden_sword",
+ "golden_shovel",
+ "golden_pickaxe",
+
+ "golden_axe",
+ "string",
+ "feather",
+ "gunpowder",
+ "wooden_hoe",
+ "stone_hoe",
+ "iron_hoe",
+ "diamond_hoe",
+ "golden_hoe",
+ "wheat_seeds",
+
+ "wheat",
+ "bread",
+ "leather_helmet",
+ "leather_chestplate",
+ "leather_leggings",
+ "leather_boots",
+ "chainmail_helmet",
+ "chainmail_chestplate",
+ "chainmail_leggings",
+ "chainmail_boots",
+
+ "iron_helmet",
+ "iron_chestplate",
+ "iron_leggings",
+ "iron_boots",
+ "diamond_helmet",
+ "diamond_chestplate",
+ "diamond_leggings",
+ "diamond_boots",
+ "golden_helmet",
+ "golden_chestplate",
+
+ "golden_leggings",
+ "golden_boots",
+ "flint",
+ "porkchop",
+ "cooked_porkchop",
+ "painting",
+ "golden_apple",
+ "sign",
+ "wooden_door",
+ "bucket",
+
+ "water_bucket",
+ "lava_bucket",
+ "minecart",
+ "saddle",
+ "iron_door",
+ "redstone",
+ "snowball",
+ "boat",
+ "leather",
+ "milk_bucket",
+
+ "brick",
+ "clay_ball",
+ "reeds",
+ "paper",
+ "book",
+ "slime_ball",
+ "chest_minecart",
+ "furnace_minecart",
+ "egg",
+ "compass",
+
+ "fishing_rod",
+ "clock",
+ "glowstone_dust",
+ "fish",
+ "cooked_fished",
+ "dye",
+ "bone",
+ "sugar",
+ "cake",
+ "bed",
+
+ "repeater",
+ "cookie",
+ "filled_map",
+ "shears",
+ "melon",
+ "pumpkin_seeds",
+ "melon_seeds",
+ "beef",
+ "cooked_beef",
+ "chicken",
+
+ "cooked_chicken",
+ "rotten_flesh",
+ "ender_pearl",
+ "blaze_rod",
+ "ghast_tear",
+ "gold_nugget",
+ "nether_wart",
+ "potion",
+ "glass_bottle",
+ "spider_eye",
+
+ "fermented_spider_eye",
+ "blaze_powder",
+ "magma_cream",
+ "brewing_stand",
+ "cauldron",
+ "ender_eye",
+ "speckled_melon",
+ "spawn_egg",
+ "experience_bottle",
+ "fire_charge",
+
+ "writable_book",
+ "written_book",
+ "emerald",
+ "item_frame",
+ "flower_pot",
+ "carrot",
+ "potato",
+ "baked_potato",
+ "poisonous_potato",
+ "map",
+
+ "golden_carrot",
+ "skull",
+ "carrot_on_a_stick",
+ "nether_star",
+ "pumpkin_pie",
+ "fireworks",
+ "firework_charge",
+ "enchanted_book",
+ "comparator",
+ "netherbrick",
+
+ "quartz",
+ "tnt_minecart",
+ "hopper_minecart",
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+
+ null,
+ "iron_horse_armor",
+ "golden_horse_armor",
+ "diamond_horse_armor",
+ "lead",
+ "name_tag",
+ "command_block_minecart"
+ };
+ private static final String[] DISC_IDENTIFIERS = {
+ "record_13",
+ "record_cat",
+ "record_blocks",
+ "record_chirp",
+ "record_far",
+ "record_mall",
+ "record_mellohi",
+ "record_stal",
+ "record_strad",
+ "record_ward",
+
+ "record_11",
+ "record_wait"
+ };
+
+ private static final int ITEM_ID_OFFSET = 256;
+ private static final int DISC_ITEM_ID_OFFSET = 2000 + ITEM_ID_OFFSET;
+
+ static void init() {
+ for (Field f : Item.class.getDeclaredFields()) {
+ if (Modifier.isStatic(f.getModifiers()) && Item.class.isAssignableFrom(f.getType())) {
+ try {
+ Item item = (Item) f.get(null);
+
+ if (item != null) {
+ String identifier = null;
+
+ if (item.id >= DISC_ITEM_ID_OFFSET) {
+ int id = item.id - DISC_ITEM_ID_OFFSET;
+
+ if (id >= 0 && id < DISC_IDENTIFIERS.length) {
+ identifier = DISC_IDENTIFIERS[id];
+ }
+ } else if (item.id >= ITEM_ID_OFFSET) {
+ int id = item.id - ITEM_ID_OFFSET;
+
+ if (id >= 0 && id < IDENTIFIERS.length) {
+ identifier = IDENTIFIERS[id];
+ }
+ }
+
+ if (identifier != null) {
+ ItemRegistryImpl.register(item.id, NamespacedIdentifiers.from(identifier), item);
+ }
+ }
+ } catch (Throwable t) {
+ }
+ }
+ }
+ }
+}
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/BlockItemAccess.java b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/BlockItemAccess.java
new file mode 100644
index 00000000..4d2224a9
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/BlockItemAccess.java
@@ -0,0 +1,14 @@
+package net.ornithemc.osl.items.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import net.minecraft.item.BlockItem;
+
+@Mixin(BlockItem.class)
+public interface BlockItemAccess {
+
+ @Accessor("block")
+ int accessBlock();
+
+}
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
new file mode 100644
index 00000000..ca77f0e3
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/java/net/ornithemc/osl/items/impl/mixin/common/ItemMixin.java
@@ -0,0 +1,35 @@
+package net.ornithemc.osl.items.impl.mixin.common;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import net.minecraft.item.Item;
+
+import net.ornithemc.osl.items.impl.ItemRegistryImpl;
+
+@Mixin(Item.class)
+public class ItemMixin {
+
+ @Inject(
+ method = "",
+ at = @At(
+ value = "HEAD"
+ )
+ )
+ private static void osl$items$unlockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.unlock();
+ }
+
+ @Inject(
+ method = "",
+ at = @At(
+ value = "TAIL"
+ )
+ )
+ private static void osl$items$initAndLockItemRegistry(CallbackInfo ci) {
+ ItemRegistryImpl.init();
+ ItemRegistryImpl.lock();
+ }
+}
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/fabric.mod.json b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/fabric.mod.json
new file mode 100644
index 00000000..1c738f86
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/fabric.mod.json
@@ -0,0 +1,27 @@
+{
+ "schemaVersion": 1,
+ "id": "osl-items",
+ "version": "0.1.0-alpha.1+mca1.0.1_01-mc1.6.4",
+ "environment": "*",
+ "mixins": [
+ "osl.items.mixins.json"
+ ],
+ "accessWidener": "osl.items.classtweaker",
+ "depends": {
+ "fabricloader": "\u003e\u003d0.18.0",
+ "minecraft": "\u003e\u003d1.0.0-alpha.0.1 \u003c\u003d1.6.4",
+ "osl-core": "\u003e\u003d0.7.0",
+ "osl-blocks": "\u003e\u003d0.1.0-"
+ },
+ "name": "OSL Items",
+ "description": "Items API and events.",
+ "authors": [
+ "OrnitheMC"
+ ],
+ "contact": {
+ "homepage": "https://ornithemc.net/",
+ "issues": "https://github.com/OrnitheMC/ornithe-standard-libraries/issues",
+ "sources": "https://github.com/OrnitheMC/ornithe-standard-libraries"
+ },
+ "license": "Apache-2.0"
+}
\ No newline at end of file
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/osl.items.classtweaker b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/osl.items.classtweaker
new file mode 100644
index 00000000..68957c43
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/osl.items.classtweaker
@@ -0,0 +1,11 @@
+classTweaker v1 named
+
+transitive-accessible method net/minecraft/item/Item setMaxStackSize (I)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setHasCustomData (Z)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setMaxDamage (I)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setHandheld ()Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setKey (Ljava/lang/String;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setRecipeRemainder (Lnet/minecraft/item/Item;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setPotionIngredient (Ljava/lang/String;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setCreativeModeTab (Lnet/minecraft/item/CreativeModeTab;)Lnet/minecraft/item/Item;
+transitive-accessible method net/minecraft/item/Item setSpriteName (Ljava/lang/String;)Lnet/minecraft/item/Item;
\ No newline at end of file
diff --git a/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/osl.items.mixins.json b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/osl.items.mixins.json
new file mode 100644
index 00000000..9b15896a
--- /dev/null
+++ b/libraries/items/items-mca1.0.1_01-mc1.6.4/src/main/resources/osl.items.mixins.json
@@ -0,0 +1,17 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "net.ornithemc.osl.items.impl.mixin",
+ "compatibilityLevel": "JAVA_8",
+ "mixins": [
+ "common.BlockItemAccess",
+ "common.ItemMixin"
+ ],
+ "client": [
+ ],
+ "server": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index 3fcddc03..cd4bbf94 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -22,6 +22,14 @@ include ':libraries:core'
include ':libraries:core:core-mca1.0.1_01-mc14w26c'
include ':libraries:core:core-mc14w27a-mc1.14.4'
+include ':libraries:blocks'
+include ':libraries:blocks:blocks-mca1.0.1_01-mc1.6.4'
+include ':libraries:blocks:blocks-mc13w36a-mc14w26c'
+include ':libraries:blocks:blocks-mc14w27a-mc17w46a'
+include ':libraries:blocks:blocks-mc17w47a-mc18w31a'
+include ':libraries:blocks:blocks-mc18w32a-mc1.13.2'
+include ':libraries:blocks:blocks-mc18w43a-mc1.14.4'
+
include ':libraries:branding'
include ':libraries:branding:branding-mcin-20100206-2103-mca1.2.1_01'
include ':libraries:branding:branding-mca1.2.2-mc14w29b'
@@ -51,6 +59,14 @@ include ':libraries:executors:executors-mc14w07a-mc14w20b'
include ':libraries:executors:executors-mc14w21a-mc1.13.2'
include ':libraries:executors:executors-mc18w43a-mc1.14.4'
+include ':libraries:items'
+include ':libraries:items:items-mca1.0.1_01-mc1.6.4'
+include ':libraries:items:items-mc13w36a-mc14w25b'
+include ':libraries:items:items-mc14w26a-mc17w46a'
+include ':libraries:items:items-mc17w47a-mc18w31a'
+include ':libraries:items:items-mc18w32a-mc1.13.2'
+include ':libraries:items:items-mc18w43a-mc1.14.4'
+
include ':libraries:keybinds'
include ':libraries:keybinds:keybinds-mcc0.0.23a_01-mcb1.7.3'
include ':libraries:keybinds:keybinds-mcb1.8-pre1-mc1.6.4'