package cz.jzitnik.game.entities.items; import cz.jzitnik.game.annotations.BlockRegistry; import cz.jzitnik.game.annotations.EntityRegistry; import cz.jzitnik.game.annotations.ItemRegistry; import cz.jzitnik.game.entities.Block; import org.reflections.Reflections; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.*; public class ItemBlockSupplier { private static final HashMap> registeredBlocks = new HashMap<>(); private static final HashMap> registeredItems = new HashMap<>(); private static final HashMap> registeredEntities = new HashMap<>(); private static final HashMap dropsList = new HashMap<>(); private static final HashMap blockList = new HashMap<>(); static { registerItems(); registerBlocks(); registerEntities(); } private static void registerBlocks() { Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry"); Set> blockClasses = reflections.getTypesAnnotatedWith(BlockRegistry.class); for (Class clazz : blockClasses) { try { Constructor blockInstance = (Constructor) clazz.getDeclaredConstructor(); BlockRegistry annotation = clazz.getAnnotation(BlockRegistry.class); registeredBlocks.put(annotation.value(), blockInstance); String dropKey = annotation.drops().isEmpty() ? annotation.value() : annotation.drops(); dropsList.put(annotation.value(), dropKey); } catch (Exception e) { e.printStackTrace(); } } } private static void registerEntities() { Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry"); Set> entityClasses = reflections.getTypesAnnotatedWith(EntityRegistry.class); for (Class clazz : entityClasses) { try { Constructor entityInstance = (Constructor) clazz.getDeclaredConstructor(); EntityRegistry annotation = clazz.getAnnotation(EntityRegistry.class); registeredEntities.put(annotation.value(), entityInstance); } catch (Exception e) { e.printStackTrace(); } } } private static void registerItems() { Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry"); Set> itemClasses = reflections.getTypesAnnotatedWith(ItemRegistry.class); for (Class clazz : itemClasses) { try { Constructor itemInstance = (Constructor) clazz.getDeclaredConstructor(); ItemRegistry annotation = clazz.getAnnotation(ItemRegistry.class); registeredItems.put(annotation.value(), itemInstance); blockList.put(annotation.value(), annotation.block().isEmpty() ? annotation.value() : annotation.block()); } catch (Exception e) { e.printStackTrace(); } } } public static Block getBlock(String key, Item item) { try { Block block = registeredBlocks.get(key).newInstance(); if (dropsList.get(key).equals(item.getId())) { block.setDrops(List.of(item)); } else { block.setDrops(List.of(getItem(dropsList.get(key), block))); } return block; } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } public static Block getBlock(String key) { try { Block block = registeredBlocks.get(key).newInstance(); if (registeredItems.containsKey(dropsList.get(key))) { block.setDrops(List.of(getItem(dropsList.get(key), block))); } return block; } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } public static Item getItem(String key) { try { Item item = registeredItems.get(key).newInstance(); if (registeredBlocks.containsKey(blockList.get(key))) { item.setBlock(Optional.of(getBlock(blockList.get(key), item))); } return item; } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); } } public static Item getItem(String key, Block block) { try { Item item = registeredItems.get(key).newInstance(); if (blockList.get(key).equals(block.getBlockId())) { item.setBlock(Optional.of(block)); } else { item.setBlock(Optional.of(getBlock(blockList.get(key), item))); } return item; } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); } } public static Block getEntity(String key) { try { return registeredEntities.get(key).newInstance(); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } }