package com.thebrokenrail.sorcerycraft; import com.thebrokenrail.sorcerycraft.block.CastingTableBlock; import com.thebrokenrail.sorcerycraft.block.CastingTableContainer; import com.thebrokenrail.sorcerycraft.client.block.CastingTableScreen; import com.thebrokenrail.sorcerycraft.client.entity.SpellEntityRenderer; import com.thebrokenrail.sorcerycraft.command.SpellCommand; import com.thebrokenrail.sorcerycraft.entity.SpellEntity; import com.thebrokenrail.sorcerycraft.item.SpellItem; import com.thebrokenrail.sorcerycraft.packet.LearnedNewSpellS2CPacket; import com.thebrokenrail.sorcerycraft.packet.SelectSpellC2SPacket; import com.thebrokenrail.sorcerycraft.packet.UpdateKnownSpellsS2CPacket; import com.thebrokenrail.sorcerycraft.spell.RandomSpellLootTableFunction; import com.thebrokenrail.sorcerycraft.spell.SpellRegistry; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; import net.fabricmc.fabric.api.client.screen.ScreenProviderRegistry; import net.fabricmc.fabric.api.container.ContainerProviderRegistry; import net.fabricmc.fabric.api.entity.FabricEntityTypeBuilder; import net.fabricmc.fabric.api.loot.v1.FabricLootPoolBuilder; import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback; import net.fabricmc.fabric.api.registry.CommandRegistry; import net.fabricmc.fabric.impl.networking.ClientSidePacketRegistryImpl; import net.fabricmc.fabric.impl.networking.ServerSidePacketRegistryImpl; import net.minecraft.client.MinecraftClient; import net.minecraft.entity.EntityCategory; import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityType; import net.minecraft.item.*; import net.minecraft.loot.BinomialLootTableRange; import net.minecraft.loot.LootTables; import net.minecraft.loot.entry.ItemEntry; import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; import java.util.Objects; public class SorceryCraft implements ModInitializer, ClientModInitializer { public static final String NAMESPACE = "sorcerycraft"; public static SpellItem SPELL_ITEM; public static CastingTableBlock CASTING_TABLE_BLOCK; public static BlockItem CASTING_TABLE_BLOCK_ITEM; public static ItemGroup ITEM_GROUP; public static EntityType SPELL_ENTITY; public static final Identifier[] LOOT_TABLES = new Identifier[] { LootTables.SIMPLE_DUNGEON_CHEST, LootTables.END_CITY_TREASURE_CHEST, LootTables.NETHER_BRIDGE_CHEST, LootTables.ABANDONED_MINESHAFT_CHEST, LootTables.SHIPWRECK_TREASURE_CHEST, LootTables.DESERT_PYRAMID_CHEST, LootTables.JUNGLE_TEMPLE_CHEST, LootTables.STRONGHOLD_LIBRARY_CHEST }; private boolean isSelectedLootTable(Identifier lootTable) { for (Identifier id : LOOT_TABLES) { if (id.equals(lootTable)) { return true; } } return false; } @Override public void onInitialize() { ITEM_GROUP = FabricItemGroupBuilder.create( new Identifier(NAMESPACE, "spells")) .icon(() -> new ItemStack(SPELL_ITEM)) .build(); CASTING_TABLE_BLOCK = new CastingTableBlock(); CASTING_TABLE_BLOCK_ITEM = new BlockItem(CASTING_TABLE_BLOCK, new Item.Settings().group(ITEM_GROUP)); SPELL_ITEM = new SpellItem(); SPELL_ENTITY = FabricEntityTypeBuilder.create(EntityCategory.MISC, SpellEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build(); Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "spell"), SPELL_ITEM); Registry.register(Registry.BLOCK, new Identifier(NAMESPACE, "casting_table"), CASTING_TABLE_BLOCK); Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "casting_table"), CASTING_TABLE_BLOCK_ITEM); Registry.register(Registry.ENTITY_TYPE, new Identifier(NAMESPACE, "spell"), SPELL_ENTITY); SpellRegistry.init(); ContainerProviderRegistry.INSTANCE.registerFactory(new Identifier(NAMESPACE, "casting_table"), (syncId, identifier, player, buf) -> { final World world = player.world; final BlockPos pos = buf.readBlockPos(); return Objects.requireNonNull(world.getBlockState(pos).createContainerFactory(player.world, pos)).createMenu(syncId, player.inventory, player); }); CommandRegistry.INSTANCE.register(false, SpellCommand::register); ServerSidePacketRegistryImpl.INSTANCE.register(new Identifier(NAMESPACE, "select_spell"), SelectSpellC2SPacket::handle); ClientSidePacketRegistryImpl.INSTANCE.register(new Identifier(NAMESPACE, "update_known_spells"), UpdateKnownSpellsS2CPacket::handle); ClientSidePacketRegistryImpl.INSTANCE.register(new Identifier(NAMESPACE, "learned_new_spell"), LearnedNewSpellS2CPacket::handle); LootTableLoadingCallback.EVENT.register((resourceManager, lootManager, id, supplier, setter) -> { if (isSelectedLootTable(id)) { FabricLootPoolBuilder poolBuilder = FabricLootPoolBuilder.builder() .withRolls(new BinomialLootTableRange(2, 0.5f)) .withEntry(ItemEntry.builder(SPELL_ITEM)) .withFunction(new RandomSpellLootTableFunction.Builder()); supplier.withPool(poolBuilder); } }); } @Override public void onInitializeClient() { EntityRendererRegistry.INSTANCE.register(SPELL_ENTITY, (entityRenderDispatcher, context) -> new SpellEntityRenderer(entityRenderDispatcher)); ScreenProviderRegistry.INSTANCE.registerFactory(new Identifier(NAMESPACE, "casting_table"), (container) -> { assert MinecraftClient.getInstance().player != null; return new CastingTableScreen(container, MinecraftClient.getInstance().player.inventory, new TranslatableText("block.sorcerycraft.casting_table")); }); } }