diff --git a/gradle.properties b/gradle.properties index 16958198935..3ef01c00ac9 100755 --- a/gradle.properties +++ b/gradle.properties @@ -31,7 +31,7 @@ mappingsVersion=1.20.1 dataGeneratorsVersion=1.19.3-0.1.54-ALPHA blockUI_version=1.20.1-1.0.139-BETA -structurize_version=1.20.1-1.0.740-BETA +structurize_version=1.20.1-1.0.759-snapshot domumOrnamentumVersion=1.20.1-1.0.184-BETA multiPistonVersion=1.20-1.2.30-ALPHA diff --git a/src/main/java/com/minecolonies/api/crafting/GenericRecipe.java b/src/main/java/com/minecolonies/api/crafting/GenericRecipe.java index f58374b5a42..069ad0a3169 100644 --- a/src/main/java/com/minecolonies/api/crafting/GenericRecipe.java +++ b/src/main/java/com/minecolonies/api/crafting/GenericRecipe.java @@ -8,7 +8,7 @@ import com.minecolonies.api.util.OptionalPredicate; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.CraftingContainer; @@ -93,7 +93,7 @@ public static IGenericRecipe of(@Nullable final IToken recipeToken) private final Block intermediate; private final ResourceLocation lootTable; private final EquipmentTypeEntry requiredTool; - private final LivingEntity requiredEntity; + private final EntityType requiredEntity; private final List restrictions; private final int levelSort; @@ -129,7 +129,7 @@ public GenericRecipe(@Nullable final ResourceLocation id, final int gridSize, @NotNull final Block intermediate, @Nullable final ResourceLocation lootTable, @NotNull final EquipmentTypeEntry requiredTool, - @Nullable final LivingEntity requiredEntity, + @Nullable final EntityType requiredEntity, @NotNull final List restrictions, final int levelSort) { @@ -246,8 +246,9 @@ public EquipmentTypeEntry getRequiredTool() return this.requiredTool; } + @Nullable @Override - public @Nullable LivingEntity getRequiredEntity() + public EntityType getRequiredEntity() { return this.requiredEntity; } diff --git a/src/main/java/com/minecolonies/api/crafting/IGenericRecipe.java b/src/main/java/com/minecolonies/api/crafting/IGenericRecipe.java index 12493d4e3f6..6f28bd979c1 100644 --- a/src/main/java/com/minecolonies/api/crafting/IGenericRecipe.java +++ b/src/main/java/com/minecolonies/api/crafting/IGenericRecipe.java @@ -4,7 +4,7 @@ import com.minecolonies.api.util.OptionalPredicate; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import org.jetbrains.annotations.NotNull; @@ -134,7 +134,7 @@ public interface IGenericRecipe * @return The required creature. */ @Nullable - LivingEntity getRequiredEntity(); + EntityType getRequiredEntity(); /** * Gets some human-readable restrictions on when this recipe is valid. diff --git a/src/main/java/com/minecolonies/core/colony/buildings/modules/AnimalHerdingModule.java b/src/main/java/com/minecolonies/core/colony/buildings/modules/AnimalHerdingModule.java index e6492e2458c..720f5b57519 100644 --- a/src/main/java/com/minecolonies/core/colony/buildings/modules/AnimalHerdingModule.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/modules/AnimalHerdingModule.java @@ -103,7 +103,7 @@ public List getRecipesForDisplayPurposesOnly(@NotNull final Anim Blocks.AIR, animal.getLootTable(), ModEquipmentTypes.axe.get(), - animal, + animal.getType(), Collections.emptyList(), 0)); } diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingBeekeeper.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingBeekeeper.java index fc918a6c1dc..7aae580df09 100644 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingBeekeeper.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingBeekeeper.java @@ -265,12 +265,12 @@ public List getRecipesForDisplayPurposesOnly(@NotNull Animal ani recipes.add(new GenericRecipe(null, new ItemStack(Items.HONEYCOMB), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), - 0, Blocks.AIR, null, ModEquipmentTypes.shears.get(), animal, Collections.emptyList(), 0)); + 0, Blocks.AIR, null, ModEquipmentTypes.shears.get(), animal.getType(), Collections.emptyList(), 0)); recipes.add(new GenericRecipe(null, new ItemStack(Items.HONEY_BOTTLE), Collections.emptyList(), Collections.emptyList(), Collections.singletonList(Collections.singletonList(new ItemStack(Items.GLASS_BOTTLE))), - 0, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal, Collections.emptyList(), 0)); + 0, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal.getType(), Collections.emptyList(), 0)); return recipes; } diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingChickenHerder.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingChickenHerder.java index b42534e0643..60e6022d65c 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingChickenHerder.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingChickenHerder.java @@ -74,7 +74,7 @@ public List getRecipesForDisplayPurposesOnly(@NotNull Animal ani final List recipes = new ArrayList<>(super.getRecipesForDisplayPurposesOnly(animal)); recipes.add(new GenericRecipe(null, new ItemStack(Items.EGG), Collections.emptyList(), Collections.emptyList(), - Collections.emptyList(), 0, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal, Collections.emptyList(), 0)); + Collections.emptyList(), 0, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal.getType(), Collections.emptyList(), 0)); return recipes; } diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingCowboy.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingCowboy.java index f12bbe90fd0..6dc8a079f8a 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingCowboy.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingCowboy.java @@ -189,7 +189,7 @@ public List getRecipesForDisplayPurposesOnly(@NotNull Animal ani Collections.singletonList(new ItemStack(Items.SUSPICIOUS_STEW)), // alt output Collections.emptyList(), // extra output Collections.singletonList(Collections.singletonList(new ItemStack(Items.BOWL))), // input - 1, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal, Collections.emptyList(), 0)); + 1, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal.getType(), Collections.emptyList(), 0)); } else if (animal instanceof Cow) { @@ -198,13 +198,13 @@ else if (animal instanceof Cow) Collections.emptyList(), // alt output Collections.emptyList(), // extra output Collections.singletonList(Collections.singletonList(new ItemStack(Items.BUCKET))), // input - 1, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal, Collections.emptyList(), 0)); + 1, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal.getType(), Collections.emptyList(), 0)); recipes.add(new GenericRecipe(null, new ItemStack(ModItems.large_milk_bottle), // output Collections.emptyList(), // alt output Collections.emptyList(), // extra output Collections.singletonList(Collections.singletonList(new ItemStack(ModItems.large_empty_bottle))), // input - 1, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal, Collections.emptyList(), 0)); + 1, Blocks.AIR, null, ModEquipmentTypes.none.get(), animal.getType(), Collections.emptyList(), 0)); } return recipes; diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingShepherd.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingShepherd.java index b84bc4cadca..2670321c189 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingShepherd.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingShepherd.java @@ -108,7 +108,7 @@ public List getRecipesForDisplayPurposesOnly(@NotNull Animal ani recipes.add(new GenericRecipe(null, ItemStack.EMPTY, ForgeRegistries.ITEMS.tags().getTag(ItemTags.WOOL).stream().map(ItemStack::new).toList(), Collections.emptyList(), Collections.emptyList(), - 0, Blocks.AIR, null, ModEquipmentTypes.shears.get(), animal, Collections.emptyList(), 0)); + 0, Blocks.AIR, null, ModEquipmentTypes.shears.get(), animal.getType(), Collections.emptyList(), 0)); return recipes; } diff --git a/src/main/java/com/minecolonies/core/compatibility/jei/GenericRecipeCategory.java b/src/main/java/com/minecolonies/core/compatibility/jei/GenericRecipeCategory.java index d67de30dde4..47cee3325a2 100644 --- a/src/main/java/com/minecolonies/core/compatibility/jei/GenericRecipeCategory.java +++ b/src/main/java/com/minecolonies/core/compatibility/jei/GenericRecipeCategory.java @@ -1,11 +1,14 @@ package com.minecolonies.core.compatibility.jei; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.ldtteam.blockui.UiRenderMacros; import com.minecolonies.api.colony.buildings.modules.ICraftingBuildingModule; import com.minecolonies.api.colony.buildings.registry.BuildingEntry; import com.minecolonies.api.colony.jobs.IJob; import com.minecolonies.api.crafting.IGenericRecipe; import com.minecolonies.api.crafting.registry.CraftingType; +import com.minecolonies.api.util.Log; import com.minecolonies.api.util.constant.TranslationConstants; import com.minecolonies.core.colony.buildings.modules.AnimalHerdingModule; import com.minecolonies.core.colony.crafting.CustomRecipeManager; @@ -22,11 +25,13 @@ import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeType; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.Rect2i; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; @@ -37,6 +42,7 @@ import net.minecraftforge.registries.ForgeRegistries; import org.jetbrains.annotations.NotNull; +import java.time.Duration; import java.util.*; import java.util.stream.Collectors; @@ -67,6 +73,10 @@ public GenericRecipeCategory(@NotNull final BuildingEntry building, @NotNull private final IModIdHelper modIdHelper; @NotNull private final ITickTimer animalTimer; + private static final Cache, Entity> entityCache = CacheBuilder.newBuilder() + .expireAfterAccess(Duration.ofMinutes(2)) + .build(); + private static final int ANIMAL_W = (WIDTH - CITIZEN_W) / 2; private static final int ANIMAL_H = CITIZEN_H - 10; private static final int ANIMAL_X = CITIZEN_X + CITIZEN_W + (WIDTH - CITIZEN_X - CITIZEN_W - ANIMAL_W) / 2; @@ -279,20 +289,29 @@ public void draw(@NotNull final IGenericRecipe recipe, RenderHelper.renderBlock(stack.pose(), block, outputSlotX + 8, CITIZEN_Y + 6, 100, -30F, 30F, 16F); } - final LivingEntity animal = recipe.getRequiredEntity(); - if (animal != null) + final EntityType entityType = recipe.getRequiredEntity(); + if (entityType != null) { - final float scale = ANIMAL_H / 2.4f; - final int animal_cx = ANIMAL_X + (ANIMAL_W / 2); - final int animal_cy = ANIMAL_Y + (ANIMAL_H / 2); - final int animal_by = ANIMAL_Y + ANIMAL_H; - final int offsetY = 16; - final float yaw = animalTimer.getValue(); - final float headYaw = (float) Math.atan((animal_cx - mouseX) / 40.0F) * 40.0F + yaw; - final float pitch = (float) Math.atan((animal_cy - offsetY - mouseY) / 40.0F) * 20.0F; - Lighting.setupForFlatItems(); - UiRenderMacros.drawEntity(stack.pose(), animal_cx, animal_by - offsetY, scale, headYaw, yaw, pitch, animal); - Lighting.setupFor3DItems(); + try + { + final Entity entity = entityCache.get(entityType, () -> entityType.create(Minecraft.getInstance().level)); + + final float scale = ANIMAL_H / 2.4f; + final int animal_cx = ANIMAL_X + (ANIMAL_W / 2); + final int animal_cy = ANIMAL_Y + (ANIMAL_H / 2); + final int animal_by = ANIMAL_Y + ANIMAL_H; + final int offsetY = 16; + final float yaw = animalTimer.getValue(); + final float headYaw = (float) Math.atan((animal_cx - mouseX) / 40.0F) * 40.0F + yaw; + final float pitch = (float) Math.atan((animal_cy - offsetY - mouseY) / 40.0F) * 20.0F; + Lighting.setupForFlatItems(); + UiRenderMacros.drawEntity(stack.pose(), animal_cx, animal_by - offsetY, scale, headYaw, yaw, pitch, entity); + Lighting.setupFor3DItems(); + } + catch (final Throwable e) + { + Log.getLogger().error("Error drawing {}", entityType.getDescriptionId(), e); + } } } diff --git a/src/main/java/com/minecolonies/core/compatibility/jei/JeiFakeLevel.java b/src/main/java/com/minecolonies/core/compatibility/jei/JeiFakeLevel.java new file mode 100644 index 00000000000..93729c8d8a6 --- /dev/null +++ b/src/main/java/com/minecolonies/core/compatibility/jei/JeiFakeLevel.java @@ -0,0 +1,24 @@ +package com.minecolonies.core.compatibility.jei; + +import com.ldtteam.structurize.client.fakelevel.SingleBlockFakeLevel; +import net.minecraft.client.Minecraft; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +public class JeiFakeLevel extends SingleBlockFakeLevel +{ + public JeiFakeLevel() + { + super(null); + prepare(Blocks.AIR.defaultBlockState(), null, null); + } + + @Override + public Level realLevel() + { + return Minecraft.getInstance().level; + } +} diff --git a/src/main/java/com/minecolonies/core/compatibility/jei/JobBasedRecipeCategory.java b/src/main/java/com/minecolonies/core/compatibility/jei/JobBasedRecipeCategory.java index 12466a25455..5f9a1af38f9 100644 --- a/src/main/java/com/minecolonies/core/compatibility/jei/JobBasedRecipeCategory.java +++ b/src/main/java/com/minecolonies/core/compatibility/jei/JobBasedRecipeCategory.java @@ -58,6 +58,7 @@ */ public abstract class JobBasedRecipeCategory implements IRecipeCategory { + protected static final JeiFakeLevel FAKE_LEVEL = new JeiFakeLevel(); protected static final ResourceLocation TEXTURE = new ResourceLocation(Constants.MOD_ID, "textures/gui/jei_recipe.png"); @NotNull protected final IJob job; @NotNull private final RecipeType type; @@ -300,7 +301,7 @@ public InfoBlock(final String text, final String tip, final Rect2i bounds) @NotNull private static EntityCitizen createCitizenWithJob(@NotNull final IJob job) { - final EntityCitizen citizen = new EntityCitizen(ModEntities.CITIZEN, Minecraft.getInstance().level); + final EntityCitizen citizen = new EntityCitizen(ModEntities.CITIZEN, FAKE_LEVEL); citizen.setFemale(citizen.getRandom().nextBoolean()); citizen.setTextureId(citizen.getRandom().nextInt(255)); citizen.getEntityData().set(EntityCitizen.DATA_TEXTURE_SUFFIX, CitizenData.SUFFIXES.get(citizen.getRandom().nextInt(CitizenData.SUFFIXES.size())));