From bcf78ba2045da80f4786cc6c1da7834c9e0168e1 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Sun, 24 Nov 2024 13:15:10 +0100 Subject: [PATCH 01/33] Concrete mixer can do multiple things before going back to the hut (#10331) Concrete mixer can do multiple things before going back to the hut --- .../ai/statemachine/states/AIWorkerState.java | 16 +- .../com/minecolonies/api/items/ModTags.java | 1 - .../BuildingConcreteMixer.java | 38 ++-- .../crafting/EntityAIConcreteMixer.java | 214 ++++++++++-------- 4 files changed, 156 insertions(+), 113 deletions(-) diff --git a/src/main/java/com/minecolonies/api/entity/ai/statemachine/states/AIWorkerState.java b/src/main/java/com/minecolonies/api/entity/ai/statemachine/states/AIWorkerState.java index 024fcf0af4f..24fedaa20a1 100755 --- a/src/main/java/com/minecolonies/api/entity/ai/statemachine/states/AIWorkerState.java +++ b/src/main/java/com/minecolonies/api/entity/ai/statemachine/states/AIWorkerState.java @@ -653,7 +653,21 @@ public enum AIWorkerState implements IAIState /** * Harvest the netherwart. */ - HARVEST_NETHERWART(true); + HARVEST_NETHERWART(true), + + /* +###Concrete mixers### + */ + + /** + * Continues placing blocks until can't place anymore. + */ + CONCRETE_MIXER_PLACING(true), + + /** + * Harvest all blocks placed in the water. + */ + CONCRETE_MIXER_HARVESTING(true); /** * Is it okay to eat. diff --git a/src/main/java/com/minecolonies/api/items/ModTags.java b/src/main/java/com/minecolonies/api/items/ModTags.java index 7a6cac22cf4..d9f1611cbb8 100644 --- a/src/main/java/com/minecolonies/api/items/ModTags.java +++ b/src/main/java/com/minecolonies/api/items/ModTags.java @@ -3,7 +3,6 @@ import com.minecolonies.api.util.constant.TagConstants; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.BiomeTags; import net.minecraft.tags.BlockTags; import net.minecraft.tags.ItemTags; import net.minecraft.tags.TagKey; diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingConcreteMixer.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingConcreteMixer.java index 0b04683ec1c..9d2c4403722 100644 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingConcreteMixer.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingConcreteMixer.java @@ -3,7 +3,6 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.jobs.registry.JobEntry; import com.minecolonies.api.colony.requestsystem.token.IToken; -import com.minecolonies.api.items.ModTags; import com.minecolonies.api.equipment.ModEquipmentTypes; import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.core.colony.buildings.AbstractBuilding; @@ -51,11 +50,6 @@ public class BuildingConcreteMixer extends AbstractBuilding */ private final Map> waterPos = new HashMap<>(); - /** - * The minimum found water level - */ - private int minWaterLevel = WATER_DEPTH_SUPPORT; - /** * Instantiates a new concrete mason building. * @@ -81,7 +75,6 @@ public void registerBlockPosition(@NotNull final BlockState blockState, @NotNull fluidPos.add(pos); } waterPos.put(blockState.getFluidState().getAmount(), fluidPos); - minWaterLevel = Math.min(minWaterLevel, blockState.getFluidState().getAmount()); } } @@ -123,7 +116,6 @@ public void deserializeNBT(final CompoundTag compound) { final CompoundTag waterCompound = waterMapList.getCompound(i); final int level = waterCompound.getInt(TAG_LEVEL); - minWaterLevel = Math.min(minWaterLevel, level); final ListTag waterTagList = waterCompound.getList(TAG_WATER, Tag.TAG_COMPOUND); final List water = new ArrayList<>(); @@ -154,6 +146,21 @@ public int getMaxBuildingLevel() return CONST_DEFAULT_MAX_BUILDING_LEVEL; } + /** + * Get the max amount of concrete placed at once. + * + * @return the number of concrete. + */ + public int getMaxConcretePlaced() + { + int size = 0; + for (List positions : waterPos.values()) + { + size += positions.size(); + } + return size; + } + /** * Check if there are open positions to mine. * @@ -162,17 +169,18 @@ public int getMaxBuildingLevel() @Nullable public BlockPos getBlockToMine() { - for (int i = 1; i <= minWaterLevel; i++) + for (int i = 1; i <= WATER_DEPTH_SUPPORT; i++) { for (final BlockPos pos : waterPos.getOrDefault(i, Collections.emptyList())) { - if (colony.getWorld().getBlockState(pos).is(ModTags.concreteBlocks)) + final BlockState state = colony.getWorld().getBlockState(pos); + if (!state.isAir() && !state.is(Blocks.WATER)) { return pos; } } } - + return null; } @@ -184,18 +192,18 @@ public BlockPos getBlockToMine() @Nullable public BlockPos getBlockToPlace() { - for (int i = 1; i <= minWaterLevel; i++) + for (int i = 1; i <= WATER_DEPTH_SUPPORT; i++) { for (final BlockPos pos : waterPos.getOrDefault(i, Collections.emptyList())) { final BlockState state = colony.getWorld().getBlockState(pos); - if (!state.getFluidState().isEmpty() && state.getBlock() == Blocks.WATER) + if (state.is(Blocks.WATER)) { return pos; } } } - + return null; } @@ -210,7 +218,7 @@ public int outputBlockCountInWorld(final ItemStack primaryOutput) int count = 0; if (primaryOutput.getItem() instanceof BlockItem) { - for (int i = 1; i <= minWaterLevel; i++) + for (int i = 1; i <= WATER_DEPTH_SUPPORT; i++) { for (final BlockPos pos : waterPos.getOrDefault(i, Collections.emptyList())) { diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java index 4f32fe4b812..65a0268aec7 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java @@ -1,6 +1,7 @@ package com.minecolonies.core.entity.ai.workers.crafting; import com.minecolonies.api.colony.requestsystem.request.RequestState; +import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.api.util.ItemStackUtils; @@ -13,16 +14,17 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.core.Direction; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.common.capabilities.ForgeCapabilities; import org.jetbrains.annotations.NotNull; import java.util.function.Predicate; import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; -import static com.minecolonies.api.util.constant.Constants.STACKSIZE; +import static com.minecolonies.api.util.constant.Constants.*; /** - * Concrete mason AI class. + * Concrete mixer AI class. */ public class EntityAIConcreteMixer extends AbstractEntityAICrafting { @@ -42,6 +44,10 @@ public class EntityAIConcreteMixer extends AbstractEntityAICrafting getExpectedBuildingClass() return BuildingConcreteMixer.class; } - @Override - protected IAIState decide() + /** + * Place concrete powder down into the water stream. + * + * @return the next AI state. + */ + private IAIState placePowder() { - // This needs to only run on concrete powder that isn't earmarked for delivery. - // We need an 'output' inventory to protect those from processing here. - /* - if (job.getTaskQueue().isEmpty()) + final BlockPos posToPlace = building.getBlockToPlace(); + if (posToPlace == null) + { + return START_WORKING; + } + + final int slot = getSlotWithPowder(); + if (slot == -1) { - final IAIState state = mixConcrete(); - if (state != CRAFT) + if (InventoryUtils.hasItemInItemHandler(building.getCapability(ForgeCapabilities.ITEM_HANDLER).orElseGet(null), CONCRETE)) { - return state; + needsCurrently = new Tuple<>(CONCRETE, STACKSIZE); + return GATHERING_REQUIRED_MATERIALS; } + return START_WORKING; } - */ - if (job.getCurrentTask() == null) + if (walkToBlock(posToPlace)) { - return START_WORKING; + return getState(); } - if (walkTo == null && walkToBuilding()) + final ItemStack stack = worker.getInventoryCitizen().getStackInSlot(slot); + final Block block = ((BlockItem) stack.getItem()).getBlock(); + if (InventoryUtils.attemptReduceStackInItemHandler(worker.getInventoryCitizen(), stack, 1)) + { + world.setBlock(posToPlace, block.defaultBlockState().updateShape(Direction.DOWN, block.defaultBlockState(), world, posToPlace, posToPlace), UPDATE_FLAG); + } + + return getState(); + } + + /** + * Harvest concrete from the water stream. + * + * @return the next AI state. + */ + private IAIState harvestConcrete() + { + final BlockPos posToMine = building.getBlockToMine(); + if (posToMine == null) { + this.resetActionsDone(); return START_WORKING; } - if (job.getActionsDone() > 0) + if (walkToBlock(posToMine)) { - // Wait to dump before continuing. return getState(); } - if (currentRequest != null && currentRecipeStorage != null) + final BlockState blockToMine = world.getBlockState(posToMine); + if (mineBlock(posToMine)) { - return QUERY_ITEMS; - } + incrementActionsDoneAndDecSaturation(); - return GET_RECIPE; - } + if (currentRequest != null && currentRecipeStorage != null && blockToMine.getBlock().asItem().equals(currentRecipeStorage.getPrimaryOutput().getItem())) + { + currentRequest.addDelivery(new ItemStack(blockToMine.getBlock(), 1)); + job.setCraftCounter(job.getCraftCounter() + 1); + if (job.getCraftCounter() >= job.getMaxCraftingCount()) + { + job.finishRequest(true); + worker.getCitizenExperienceHandler().addExperience(currentRequest.getRequest().getCount() / 2.0); + currentRequest = null; + currentRecipeStorage = null; + resetValues(); - @Override - protected int getExtendedCount(final ItemStack primaryOutput) - { - return building.outputBlockCountInWorld(primaryOutput); + return START_WORKING; + } + } + } + + return getState(); } /** - * Mix the concrete and mine it. + * Get the first slow in the inventory that contains concrete powder. + * We attempt to find powder tied to the current request first, if we can't find any, we look for any possible powder. * - * @return next state. + * @return the slot number containing powder, or -1 if no slot contains any. */ - private IAIState mixConcrete() + private int getSlotWithPowder() { - int slot = -1; - if (currentRequest != null && currentRecipeStorage != null) { - ItemStack inputStack = currentRecipeStorage.getCleanedInput().get(0).getItemStack(); + final ItemStack inputStack = currentRecipeStorage.getCleanedInput().get(0).getItemStack(); if (CONCRETE.test(inputStack)) { - slot = InventoryUtils.findFirstSlotInItemHandlerWith(worker.getInventoryCitizen(), s -> ItemStackUtils.compareItemStacksIgnoreStackSize(s, inputStack)); - } - else - { - return START_WORKING; + return InventoryUtils.findFirstSlotInItemHandlerWith(worker.getInventoryCitizen(), s -> ItemStackUtils.compareItemStacksIgnoreStackSize(s, inputStack)); } + return -1; } else { - slot = InventoryUtils.findFirstSlotInItemHandlerWith(worker.getInventoryCitizen(), CONCRETE); + return InventoryUtils.findFirstSlotInItemHandlerWith(worker.getInventoryCitizen(), CONCRETE); } + } - if (slot != -1) + @Override + protected IAIState decide() + { + if (job.getCurrentTask() == null) { - final ItemStack stack = worker.getInventoryCitizen().getStackInSlot(slot); - final Block block = ((BlockItem) stack.getItem()).getBlock(); - final BlockPos posToPlace = building.getBlockToPlace(); - if (posToPlace != null) - { - if (walkToBlock(posToPlace)) - { - walkTo = posToPlace; - return START_WORKING; - } - walkTo = null; - if (InventoryUtils.attemptReduceStackInItemHandler(worker.getInventoryCitizen(), stack, 1)) - { - world.setBlock(posToPlace, block.defaultBlockState().updateShape(Direction.DOWN, block.defaultBlockState(), world, posToPlace, posToPlace), 0x03); - } - return START_WORKING; - } + return performMixingWork(); } - final BlockPos pos = building.getBlockToMine(); - if (pos != null) + if (walkTo == null && walkToBuilding()) { - if (walkToBlock(pos)) - { - walkTo = pos; - return START_WORKING; - } - walkTo = null; - if (mineBlock(pos)) - { - this.resetActionsDone(); - return CRAFT; - } return START_WORKING; } - if (InventoryUtils.hasItemInItemHandler(building.getCapability(ForgeCapabilities.ITEM_HANDLER).orElseGet(null), CONCRETE)) + if (job.getActionsDone() > 0) { - needsCurrently = new Tuple<>(CONCRETE, STACKSIZE); - return GATHERING_REQUIRED_MATERIALS; + // Wait to dump before continuing. + return getState(); } - else + + if (currentRequest != null && currentRecipeStorage != null) { - incrementActionsDone(); + return QUERY_ITEMS; } - return START_WORKING; + return GET_RECIPE; + } + + @Override + protected int getExtendedCount(final ItemStack primaryOutput) + { + return building.outputBlockCountInWorld(primaryOutput); } @Override @@ -196,8 +218,8 @@ protected IAIState craft() if (currentRequest != null && (currentRequest.getState() == RequestState.CANCELLED || currentRequest.getState() == RequestState.FAILED)) { - currentRequest = null; incrementActionsDone(getActionRewardForCraftingSuccess()); + currentRequest = null; currentRecipeStorage = null; return START_WORKING; } @@ -208,28 +230,28 @@ protected IAIState craft() return super.craft(); } - final IAIState mixState = mixConcrete(); - if (mixState == getState()) - { - currentRequest.addDelivery(new ItemStack(concrete.getItem(), 1)); - job.setCraftCounter(job.getCraftCounter() + 1); - if (job.getCraftCounter() >= job.getMaxCraftingCount()) - { - incrementActionsDone(getActionRewardForCraftingSuccess()); - currentRecipeStorage = null; - resetValues(); + return performMixingWork(); + } - if (inventoryNeedsDump()) - { - if (job.getMaxCraftingCount() == 0 && job.getCraftCounter() == 0 && currentRequest != null) - { - job.finishRequest(true); - worker.getCitizenExperienceHandler().addExperience(currentRequest.getRequest().getCount() / 2.0); - } - } - } + @Override + protected int getActionsDoneUntilDumping() + { + return getState().equals(CONCRETE_MIXER_HARVESTING) ? building.getMaxConcretePlaced() : super.getActionsDoneUntilDumping(); + } + + /** + * Harvest and placement logic for concrete. + * + * @return the next AI state. + */ + private IAIState performMixingWork() + { + final BlockPos blockToMine = building.getBlockToMine(); + if (blockToMine != null) + { + return CONCRETE_MIXER_HARVESTING; } - return mixState; + return CONCRETE_MIXER_PLACING; } } From cbe6e3e488878db922f152f3e91b934ae3b4df03 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Sun, 24 Nov 2024 13:15:23 +0100 Subject: [PATCH 02/33] Overhaul study items (#10338) Converted study items to a datapack in favor of configuration Changed the AI so that they're able to request several study items at once --- .../configuration/ServerConfiguration.java | 17 +-- .../api/entity/ai/workers/util/StudyItem.java | 66 --------- .../workerbuildings/BuildingLibrary.java | 87 ++---------- .../workerbuildings/BuildingUniversity.java | 8 +- .../core/datalistener/StudyItemListener.java | 132 ++++++++++++++++++ .../ai/workers/education/EntityAIStudy.java | 80 +++++------ .../core/event/FMLEventHandler.java | 1 + .../data/minecolonies/study_items/book.json | 5 + .../data/minecolonies/study_items/paper.json | 5 + 9 files changed, 203 insertions(+), 198 deletions(-) delete mode 100755 src/main/java/com/minecolonies/api/entity/ai/workers/util/StudyItem.java create mode 100644 src/main/java/com/minecolonies/core/datalistener/StudyItemListener.java create mode 100644 src/main/resources/data/minecolonies/study_items/book.json create mode 100644 src/main/resources/data/minecolonies/study_items/paper.json diff --git a/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java b/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java index 03c46f07bfe..f4dc578a01d 100755 --- a/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java +++ b/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java @@ -63,11 +63,11 @@ public class ServerConfiguration extends AbstractConfiguration * ------------------- ######## Claim settings ######## ------------------- * * --------------------------------------------------------------------------- */ - public final ForgeConfigSpec.IntValue maxColonySize; - public final ForgeConfigSpec.IntValue minColonyDistance; - public final ForgeConfigSpec.IntValue initialColonySize; - public final ForgeConfigSpec.IntValue maxDistanceFromWorldSpawn; - public final ForgeConfigSpec.IntValue minDistanceFromWorldSpawn; + public final ForgeConfigSpec.IntValue maxColonySize; + public final ForgeConfigSpec.IntValue minColonyDistance; + public final ForgeConfigSpec.IntValue initialColonySize; + public final ForgeConfigSpec.IntValue maxDistanceFromWorldSpawn; + public final ForgeConfigSpec.IntValue minDistanceFromWorldSpawn; /* ------------------------------------------------------------------------- * * ------------------- ######## Combat Settings ######## ------------------- * @@ -96,7 +96,6 @@ public class ServerConfiguration extends AbstractConfiguration * ------------------- ######## Compatibility Settings ######## ------------------- * * -------------------------------------------------------------------------------- */ - public final ForgeConfigSpec.ConfigValue> configListStudyItems; public final ForgeConfigSpec.ConfigValue> configListRecruitmentItems; public final ForgeConfigSpec.ConfigValue> diseases; public final ForgeConfigSpec.BooleanValue auditCraftingTags; @@ -117,7 +116,6 @@ public class ServerConfiguration extends AbstractConfiguration public final ForgeConfigSpec.BooleanValue creativeResolve; - /** * Builds server configuration. * @@ -193,11 +191,6 @@ protected ServerConfiguration(final ForgeConfigSpec.Builder builder) swapToCategory(builder, "compatibility"); - configListStudyItems = defineList(builder, "configliststudyitems", - Arrays.asList - ("minecraft:paper;400;100", "minecraft:book;600;10"), - s -> s instanceof String); - configListRecruitmentItems = defineList(builder, "configlistrecruitmentitems", Arrays.asList ("minecraft:hay_block;3", diff --git a/src/main/java/com/minecolonies/api/entity/ai/workers/util/StudyItem.java b/src/main/java/com/minecolonies/api/entity/ai/workers/util/StudyItem.java deleted file mode 100755 index 624da4f72a5..00000000000 --- a/src/main/java/com/minecolonies/api/entity/ai/workers/util/StudyItem.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.minecolonies.api.entity.ai.workers.util; - -import net.minecraft.world.item.Item; -import org.jetbrains.annotations.NotNull; - -public class StudyItem -{ - /** - * The actual item to use for studies - */ - private final Item item; - - /** - * The percent chance increase for skillups [100-1000] - */ - private final int skillIncrease; - - /** - * The percent chance to break upon skillup-try [0-100] - */ - private final int breakChance; - - /** - * Inventory slot the item is found in, set for specific use - */ - private int slot = -1; - - /** - * Initializing Study item, making sure the rates are valid. - * - * @param breakChance the break chance. - * @param item the item. - * @param skillIncrease the skill increase factor. - */ - public StudyItem(@NotNull final Item item, final int skillIncrease, final int breakChance) - { - this.item = item; - this.skillIncrease = skillIncrease > 0 ? skillIncrease : 100; - this.breakChance = breakChance < 0 ? 0 : breakChance; - } - - public int getSkillIncreasePct() - { - return skillIncrease; - } - - public Item getItem() - { - return item; - } - - public int getBreakPct() - { - return breakChance; - } - - public int getSlot() - { - return slot; - } - - public void setSlot(final int slot) - { - this.slot = slot; - } -} diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingLibrary.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingLibrary.java index 4bff7854b18..a1d608d3cdb 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingLibrary.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingLibrary.java @@ -1,27 +1,22 @@ package com.minecolonies.core.colony.buildings.workerbuildings; import com.minecolonies.api.colony.IColony; -import com.minecolonies.api.entity.ai.workers.util.StudyItem; -import com.minecolonies.api.util.Log; -import com.minecolonies.core.MineColonies; +import com.minecolonies.api.util.MathUtils; import com.minecolonies.core.colony.buildings.AbstractBuilding; +import com.minecolonies.core.datalistener.StudyItemListener; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; -import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Tuple; -import net.minecraft.world.item.Item; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraftforge.common.Tags; -import net.minecraftforge.registries.ForgeRegistries; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import java.util.Random; import static com.minecolonies.api.util.constant.NbtTagConstants.TAG_BOOKCASES; import static com.minecolonies.api.util.constant.NbtTagConstants.TAG_POS; @@ -36,25 +31,15 @@ public class BuildingLibrary extends AbstractBuilding */ private static final String LIBRARY_HUT_NAME = "library"; - /** - * List of registered barrels. - */ - private final List bookCases = new ArrayList<>(); - /** * Max building level of the hut. */ private static final int MAX_BUILDING_LEVEL = 5; /** - * Random obj for random calc. - */ - private final Random random = new Random(); - - /** - * Study Item list, loaded from config, Typle First is the study chance increase,second is the breakchance + * List of registered barrels. */ - private final List studyItems; + private final List bookCases = new ArrayList<>(); /** * Instantiates the building. @@ -65,50 +50,7 @@ public class BuildingLibrary extends AbstractBuilding public BuildingLibrary(final IColony c, final BlockPos l) { super(c, l); - - studyItems = parseFromConfig(); - } - - /** - * Parses Study Items from the Config and adds them on the keepX list - * - * @return the list of study items - */ - private List parseFromConfig() - { - final List studyItemList = new ArrayList<>(); - - for (final String entry : MineColonies.getConfig().getServer().configListStudyItems.get()) - { - - try - { - final String[] entries = entry.split(";"); - if (entries.length < 3) - { - Log.getLogger().info("Minecolonies: Parsing config for study items for Library failed for entry:" + entry); - continue; - } - final Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(entries[0])); - final int skillChance = Integer.parseInt(entries[1]); - final int breakChance = Integer.parseInt(entries[2]); - - if (item == null || skillChance < 100 || skillChance > 1000 || breakChance > 100 || breakChance < 0) - { - Log.getLogger().info("Minecolonies: Parsing config for study items for Library failed for entry:" + entry); - continue; - } - - studyItemList.add(new StudyItem(item, skillChance, breakChance)); - // Keep a certain part of the items in the Chest - keepX.put(itemStack -> itemStack.getItem() == item, new Tuple<>(breakChance < 5 ? 5 : breakChance, true)); - } - catch (NumberFormatException | ClassCastException e) - { - Log.getLogger().info("Minecolonies: Parsing config for study items for Library failed for entry:" + entry + " Exception:" + e.getMessage()); - } - } - return studyItemList; + keepX.put(StudyItemListener::isStudyItem, new Tuple<>(64, true)); } @NotNull @@ -118,12 +60,6 @@ public String getSchematicName() return LIBRARY_HUT_NAME; } - @Override - public int getMaxBuildingLevel() - { - return MAX_BUILDING_LEVEL; - } - @Override public void deserializeNBT(final CompoundTag compound) { @@ -151,6 +87,12 @@ public CompoundTag serializeNBT() return compound; } + @Override + public int getMaxBuildingLevel() + { + return MAX_BUILDING_LEVEL; + } + @Override public void registerBlockPosition(@NotNull final Block block, @NotNull final BlockPos pos, @NotNull final Level world) { @@ -172,7 +114,7 @@ public BlockPos getRandomBookShelf() { return getPosition(); } - final BlockPos returnPos = bookCases.get(random.nextInt(bookCases.size())); + final BlockPos returnPos = bookCases.get(MathUtils.RANDOM.nextInt(bookCases.size())); if (colony.getWorld().getBlockState(returnPos).is(Tags.Blocks.BOOKSHELVES)) { return returnPos; @@ -180,9 +122,4 @@ public BlockPos getRandomBookShelf() bookCases.remove(returnPos); return getPosition(); } - - public List getStudyItems() - { - return studyItems; - } } diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingUniversity.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingUniversity.java index 65f45c250e3..50ce10cbcf0 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingUniversity.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingUniversity.java @@ -5,6 +5,7 @@ import com.minecolonies.api.colony.jobs.ModJobs; import com.minecolonies.api.research.IGlobalResearchTree; import com.minecolonies.api.research.ILocalResearch; +import com.minecolonies.api.util.MathUtils; import com.minecolonies.api.util.MessageUtils; import com.minecolonies.core.colony.buildings.AbstractBuilding; import com.minecolonies.core.colony.buildings.modules.WorkerBuildingModule; @@ -50,11 +51,6 @@ public class BuildingUniversity extends AbstractBuilding */ private final List bookCases = new ArrayList<>(); - /** - * Random obj for random calc. - */ - private final Random random = new Random(); - /** * Instantiates the building. * @@ -121,7 +117,7 @@ public BlockPos getRandomBookShelf() { return getPosition(); } - final BlockPos returnPos = bookCases.get(random.nextInt(bookCases.size())); + final BlockPos returnPos = bookCases.get(MathUtils.RANDOM.nextInt(bookCases.size())); if (colony.getWorld().getBlockState(returnPos).is(Tags.Blocks.BOOKSHELVES)) { return returnPos; diff --git a/src/main/java/com/minecolonies/core/datalistener/StudyItemListener.java b/src/main/java/com/minecolonies/core/datalistener/StudyItemListener.java new file mode 100644 index 00000000000..4c77366563c --- /dev/null +++ b/src/main/java/com/minecolonies/core/datalistener/StudyItemListener.java @@ -0,0 +1,132 @@ +package com.minecolonies.core.datalistener; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.minecolonies.api.util.Log; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; +import net.minecraft.util.GsonHelper; +import net.minecraft.util.Mth; +import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Loads and listens to study items for the {@link com.minecolonies.core.colony.buildings.workerbuildings.BuildingLibrary}. + */ +public class StudyItemListener extends SimpleJsonResourceReloadListener +{ + /** + * Gson instance + */ + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); + + /** + * Json constants + */ + private static final String KEY_ITEM = "item"; + private static final String KEY_SKILL_INCREASE_CHANCE = "skill_increase_chance"; + private static final String KEY_BREAK_CHANCE = "break_chance"; + + /** + * The current list of study items. + */ + private static Map ACTIVE_LIST = new HashMap<>(); + + /** + * Container class for any study item. + * + * @param item the item to use. + * @param skillIncreaseChance chance for skill to increase after using the item. + * @param breakChance chance for the item to be used up after using it. + */ + public record StudyItem(Item item, int skillIncreaseChance, int breakChance) + { + } + + /** + * Default constructor. + */ + public StudyItemListener() + { + super(GSON, "study_items"); + } + + /** + * Get the current map of study items. + * + * @return the map of study items. + */ + public static Map getAllStudyItems() + { + return ACTIVE_LIST; + } + + /** + * Check if the given item is a valid study item. + * + * @param stack the item stack to check. + * @return true if so. + */ + public static boolean isStudyItem(final ItemStack stack) + { + return ACTIVE_LIST.containsKey(BuiltInRegistries.ITEM.getKey(stack.getItem())); + } + + @Override + protected void apply( + final @NotNull Map jsonElementMap, + final @NotNull ResourceManager resourceManager, + final @NotNull ProfilerFiller profiler) + { + final Map newItems = new HashMap<>(); + for (final Map.Entry entry : jsonElementMap.entrySet()) + { + if (!entry.getValue().isJsonObject()) + { + return; + } + + final JsonObject object = entry.getValue().getAsJsonObject(); + + final Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(GsonHelper.getAsString(object, KEY_ITEM))); + final int skillIncreaseChance = percentage(object, KEY_SKILL_INCREASE_CHANCE); + final int breakChance = percentage(object, KEY_BREAK_CHANCE); + + newItems.put(entry.getKey(), new StudyItem(item, skillIncreaseChance, breakChance)); + } + ACTIVE_LIST = Collections.unmodifiableMap(newItems); + } + + /** + * Parse a json field as a percentage. + * + * @param object the input json object. + * @param field the field name to parse. + * @return the percentage. + */ + private int percentage(final JsonObject object, final String field) + { + final int raw = GsonHelper.getAsInt(object, field, 0); + final int clamped = Mth.clamp(raw, 0, 100); + if (raw != clamped) + { + Log.getLogger() + .warn( + "Parsing study item for Library contains a problem. Expected value for {} exceeded the range of [0,100], actual values was {}. Value was automatically clamped to {}.", + field, + raw, + clamped); + } + return clamped; + } +} diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java index 3b389599029..dee2f982caa 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java @@ -1,14 +1,16 @@ package com.minecolonies.core.entity.ai.workers.education; import com.minecolonies.api.colony.ICitizenData; +import com.minecolonies.api.colony.requestsystem.requestable.StackList; import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; -import com.minecolonies.api.entity.ai.workers.util.StudyItem; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.api.util.Tuple; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingLibrary; import com.minecolonies.core.colony.jobs.JobStudent; +import com.minecolonies.core.datalistener.StudyItemListener; +import com.minecolonies.core.datalistener.StudyItemListener.StudyItem; import com.minecolonies.core.entity.ai.workers.AbstractEntityAISkill; import com.minecolonies.core.entity.pathfinding.navigation.PathfindingAIHelper; import net.minecraft.core.BlockPos; @@ -18,8 +20,7 @@ import net.minecraft.world.item.Items; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; +import java.util.*; import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND; @@ -41,22 +42,19 @@ public class EntityAIStudy extends AbstractEntityAISkill getExpectedBuildingClass() + { + return BuildingLibrary.class; + } + @Override protected void updateRenderMetaData() { @@ -89,12 +93,6 @@ protected void updateRenderMetaData() worker.setRenderMetadata(renderMeta); } - @Override - public Class getExpectedBuildingClass() - { - return BuildingLibrary.class; - } - /** * The AI task for the student to study. For this he should walk between the different bookcase hit them once and then stand around for a while. * @@ -115,37 +113,40 @@ private IAIState study() return getState(); } + final Collection studyItems = StudyItemListener.getAllStudyItems().values(); + // Search for Items to use to study - final List currentItems = new ArrayList<>(); - for (final StudyItem curItem : building.getStudyItems()) + final List availableItemKeys = new ArrayList<>(); + final Map availableItems = new HashMap<>(); + for (final StudyItem curItem : studyItems) { - final int slot = InventoryUtils.findFirstSlotInProviderNotEmptyWith(worker, - itemStack -> !ItemStackUtils.isEmpty(itemStack) && itemStack.getItem() == curItem.getItem()); - + final int slot = InventoryUtils.findFirstSlotInProviderNotEmptyWith(worker, (item) -> item.is(curItem.item())); if (slot != -1) { - curItem.setSlot(slot); - currentItems.add(curItem); + availableItemKeys.add(curItem); + availableItems.put(curItem, slot); } } // Create a new Request for items - if (currentItems.isEmpty()) + if (availableItems.isEmpty()) { - for (final StudyItem studyItem : building.getStudyItems()) + final List itemsToRequest = new ArrayList<>(); + for (final StudyItem studyItem : studyItems) { - final int bSlot = InventoryUtils.findFirstSlotInProviderWith(building, studyItem.getItem()); + final int bSlot = InventoryUtils.findFirstSlotInProviderWith(building, studyItem.item()); if (bSlot > -1) { - needsCurrently = new Tuple<>(itemStack -> studyItem.getItem() == itemStack.getItem(), 10); + needsCurrently = new Tuple<>(itemStack -> studyItem.item() == itemStack.getItem(), 10); return GATHERING_REQUIRED_MATERIALS; } - else - { - checkIfRequestForItemExistOrCreateAsync(new ItemStack(studyItem.getItem(), studyItem.getBreakPct() / 10 > 0 ? studyItem.getBreakPct() / 10 : 1)); - } + + final ItemStack itemStack = new ItemStack(studyItem.item(), studyItem.item().getDefaultInstance().getMaxStackSize()); + itemsToRequest.add(itemStack); } + checkIfRequestForItemExistOrCreate(new StackList(itemsToRequest, "Study Items", 64)); + // Default levelup data.getCitizenSkillHandler().tryLevelUpIntelligence(data.getRandom(), ONE_IN_X_CHANCE, data); worker.setItemInHand(InteractionHand.MAIN_HAND, ItemStackUtils.EMPTY); @@ -153,18 +154,19 @@ private IAIState study() // Use random item else { - final StudyItem chosenItem = currentItems.get(world.random.nextInt(currentItems.size())); + final StudyItem chosenItem = availableItemKeys.get(world.random.nextInt(availableItems.size())); + final int chosenSlot = availableItems.get(chosenItem); - worker.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(chosenItem.getItem(), 1)); - if (data.getCitizenSkillHandler().tryLevelUpIntelligence(data.getRandom(), ONE_IN_X_CHANCE * (100D / chosenItem.getSkillIncreasePct()), data)) + worker.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(chosenItem.item(), 1)); + if (data.getCitizenSkillHandler().tryLevelUpIntelligence(data.getRandom(), ONE_IN_X_CHANCE * (10D / chosenItem.skillIncreaseChance()), data)) { building.getModule(STATS_MODULE).increment(INT_LEVELED); } // Break item rand - if (world.random.nextInt(100) <= chosenItem.getBreakPct()) + if (world.random.nextInt(100) <= chosenItem.breakChance()) { - data.getInventory().extractItem(chosenItem.getSlot(), 1, false); - building.getModule(STATS_MODULE).increment(ITEM_USED + ";" + chosenItem.getItem().getDescriptionId()); + data.getInventory().extractItem(chosenSlot, 1, false); + building.getModule(STATS_MODULE).increment(ITEM_USED + ";" + chosenItem.item().getDescriptionId()); } } diff --git a/src/main/java/com/minecolonies/core/event/FMLEventHandler.java b/src/main/java/com/minecolonies/core/event/FMLEventHandler.java index ecc742de3e1..d8b690cc43c 100755 --- a/src/main/java/com/minecolonies/core/event/FMLEventHandler.java +++ b/src/main/java/com/minecolonies/core/event/FMLEventHandler.java @@ -51,6 +51,7 @@ public static void onAddReloadListenerEvent(@NotNull final AddReloadListenerEven event.addListener(new CitizenNameListener()); event.addListener(new QuestJsonListener()); event.addListener(new ItemNbtListener()); + event.addListener(new StudyItemListener()); } @SubscribeEvent diff --git a/src/main/resources/data/minecolonies/study_items/book.json b/src/main/resources/data/minecolonies/study_items/book.json new file mode 100644 index 00000000000..7491121fb42 --- /dev/null +++ b/src/main/resources/data/minecolonies/study_items/book.json @@ -0,0 +1,5 @@ +{ + "item": "minecraft:book", + "skill_increase_chance": 60, + "break_chance": 10 +} \ No newline at end of file diff --git a/src/main/resources/data/minecolonies/study_items/paper.json b/src/main/resources/data/minecolonies/study_items/paper.json new file mode 100644 index 00000000000..fe4e858d86b --- /dev/null +++ b/src/main/resources/data/minecolonies/study_items/paper.json @@ -0,0 +1,5 @@ +{ + "item": "minecraft:paper", + "skill_increase_chance": 40, + "break_chance": 100 +} \ No newline at end of file From d9948ab87758b732fc2480e6fae77a9b5e0ae3c6 Mon Sep 17 00:00:00 2001 From: Gavin Lambert Date: Mon, 25 Nov 2024 01:15:36 +1300 Subject: [PATCH 03/33] Use fake level for JEI (#10304) Use fake level for JEI --- gradle.properties | 2 +- .../api/crafting/GenericRecipe.java | 9 ++-- .../api/crafting/IGenericRecipe.java | 4 +- .../modules/AnimalHerdingModule.java | 2 +- .../workerbuildings/BuildingBeekeeper.java | 4 +- .../BuildingChickenHerder.java | 2 +- .../workerbuildings/BuildingCowboy.java | 6 +-- .../workerbuildings/BuildingShepherd.java | 2 +- .../jei/GenericRecipeCategory.java | 47 +++++++++++++------ .../core/compatibility/jei/JeiFakeLevel.java | 24 ++++++++++ .../jei/JobBasedRecipeCategory.java | 3 +- 11 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/minecolonies/core/compatibility/jei/JeiFakeLevel.java 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()))); From 438e6533be622270ac0b2db49ddc282b801f745b Mon Sep 17 00:00:00 2001 From: Gavin Lambert Date: Mon, 25 Nov 2024 01:15:46 +1300 Subject: [PATCH 04/33] Compat for waystones and productive bees (#10473) Compat for waystones and productive bees --- .../minecolonies/tags/blocks/protectionexception.json | 10 +--------- .../data/minecolonies/tags/blocks/tree.json | 6 +++++- .../generation/defaults/DefaultBlockTagsProvider.java | 7 +++---- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/datagen/generated/minecolonies/data/minecolonies/tags/blocks/protectionexception.json b/src/datagen/generated/minecolonies/data/minecolonies/tags/blocks/protectionexception.json index abb68029ff6..808dd4f76ca 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/tags/blocks/protectionexception.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/tags/blocks/protectionexception.json @@ -1,15 +1,7 @@ { "values": [ { - "id": "waystones:waystone", - "required": false - }, - { - "id": "waystones:sandy_waystone", - "required": false - }, - { - "id": "waystones:mossy_waystone", + "id": "#waystones:waystones", "required": false } ] diff --git a/src/datagen/generated/minecolonies/data/minecolonies/tags/blocks/tree.json b/src/datagen/generated/minecolonies/data/minecolonies/tags/blocks/tree.json index 65f442f3f5a..208fc51f615 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/tags/blocks/tree.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/tags/blocks/tree.json @@ -2,6 +2,10 @@ "values": [ "#minecraft:logs", "#minecolonies:mangrove_tree", - "minecraft:mushroom_stem" + "minecraft:mushroom_stem", + { + "id": "#productivebees:nests/wood_nests", + "required": false + } ] } \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/generation/defaults/DefaultBlockTagsProvider.java b/src/main/java/com/minecolonies/core/generation/defaults/DefaultBlockTagsProvider.java index 07fbddd5d39..ab0fb59976f 100644 --- a/src/main/java/com/minecolonies/core/generation/defaults/DefaultBlockTagsProvider.java +++ b/src/main/java/com/minecolonies/core/generation/defaults/DefaultBlockTagsProvider.java @@ -186,12 +186,11 @@ protected void addTags(final HolderLookup.Provider holder) tag(ModTags.tree) .addTag(BlockTags.LOGS) .addTag(ModTags.mangroveTree) - .add(Blocks.MUSHROOM_STEM); + .add(Blocks.MUSHROOM_STEM) + .addOptionalTag(new ResourceLocation("productivebees", "nests/wood_nests")); tag(ModTags.colonyProtectionException) - .addOptional(new ResourceLocation("waystones:waystone")) - .addOptional(new ResourceLocation("waystones:sandy_waystone")) - .addOptional(new ResourceLocation("waystones:mossy_waystone")); + .addOptionalTag(new ResourceLocation("waystones", "waystones")); tag(ModTags.indestructible).add(Blocks.BEDROCK); tag(ModTags.oreChanceBlocks) From 14b05187fd15e43994c5d0f3bf9c44782f7b000e Mon Sep 17 00:00:00 2001 From: Raycoms Date: Mon, 25 Nov 2024 12:45:28 +0100 Subject: [PATCH 05/33] hotfix netherminer food request --- .../core/colony/buildings/modules/BuildingModules.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/minecolonies/core/colony/buildings/modules/BuildingModules.java b/src/main/java/com/minecolonies/core/colony/buildings/modules/BuildingModules.java index 1e7812544d0..7984ffc613a 100644 --- a/src/main/java/com/minecolonies/core/colony/buildings/modules/BuildingModules.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/modules/BuildingModules.java @@ -73,7 +73,7 @@ public class BuildingModules new BuildingEntry.ModuleProducer<>("restaurant_menu", () -> new RestaurantMenuModule(true, ISchematicProvider::getBuildingLevel), () -> RestaurantMenuModuleView::new); public static final BuildingEntry.ModuleProducer NETHERMINER_MENU = - new BuildingEntry.ModuleProducer<>("netherminer_menu", () -> new RestaurantMenuModule(false, building -> 16), () -> RestaurantMenuModuleView::new); + new BuildingEntry.ModuleProducer<>("netherminer_menu", () -> new RestaurantMenuModule(false, building -> 1), () -> RestaurantMenuModuleView::new); public static final BuildingEntry.ModuleProducer ITEMLIST_SAPLING = new BuildingEntry.ModuleProducer<>("itemlist_sapling", () -> new ItemListModule(SAPLINGS_LIST), From c9aa1b8f4cd92186ce94757ce390b9f7dbc1b56b Mon Sep 17 00:00:00 2001 From: Raycoms Date: Wed, 27 Nov 2024 12:14:40 +0100 Subject: [PATCH 06/33] Some sickness improvements (#10482) Give citizens always some immunity time after healed. Fix wrong min-max Always increment cured citizen stat even if not in bed Increase immunity time very slightly --- .../citizenhandlers/CitizenDiseaseHandler.java | 15 +++++++++------ .../citizenhandlers/CitizenFoodHandler.java | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java index b1ca192afa4..69c54003512 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java @@ -36,9 +36,9 @@ public class CitizenDiseaseHandler implements ICitizenDiseaseHandler private static final int DISEASE_FACTOR = 100000; /** - * Number of seconds after recovering a citizen is immune against any illness. + * Number of seconds after recovering a citizen is immune against any illness. 90 Minutes currently. */ - private static final int IMMUNITY_TIME = 60 * 10 * 7; + private static final int IMMUNITY_TIME = 60 * 90; /** * Additional immunity time through vaccines. @@ -65,6 +65,7 @@ public class CitizenDiseaseHandler implements ICitizenDiseaseHandler */ private boolean sleepsAtHospital = false; + /** * The initial citizen count */ @@ -93,8 +94,6 @@ public void tick() final double citizenModifier = citizen.getCitizenData().getDiseaseModifier(); final int configModifier = MineColonies.getConfig().getServer().diseaseModifier.get(); - // normally it's one in 5 x 10.000 - if (!IColonyManager.getInstance().getCompatibilityManager().getDiseases().isEmpty() && citizen.getRandom().nextInt(configModifier * DISEASE_FACTOR) < citizenModifier * 10) { @@ -203,10 +202,14 @@ public void cure() { immunityTicks = IMMUNITY_TIME; } - - citizen.getCitizenColonyHandler().getColonyOrRegister().getStatisticsManager().increment(CITIZENS_HEALED, citizen.getCitizenColonyHandler().getColonyOrRegister().getDay()); + } + else + { + // Less immunity time if not cored in bed, but still have immunity time. + immunityTicks = IMMUNITY_TIME / 2; } + citizen.getCitizenColonyHandler().getColonyOrRegister().getStatisticsManager().increment(CITIZENS_HEALED, citizen.getCitizenColonyHandler().getColonyOrRegister().getDay()); citizen.markDirty(0); } diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenFoodHandler.java b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenFoodHandler.java index cc55f6ca0bb..89837d610bc 100644 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenFoodHandler.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenFoodHandler.java @@ -158,6 +158,6 @@ public double getDiseaseModifier(final double baseModifier) { return baseModifier; } - return baseModifier * 0.5 * Math.max(2.5, 5.0/getFoodHappinessStats().diversity()); + return baseModifier * 0.5 * Math.min(2.5, 5.0/getFoodHappinessStats().diversity()); } } From 61d5f1a168085ea5af3b7a87d9c2c5b74604eb78 Mon Sep 17 00:00:00 2001 From: someaddons <38401808+someaddons@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:06:42 +0100 Subject: [PATCH 07/33] Move sickness handler to citizendata (#10483) Move sickness handler to citizendata Child buildings no longer claim Add torchflower to tier6 --- .../minecolonies/api/colony/ICitizenData.java | 12 +-- .../api/colony/ICivilianData.java | 2 +- .../managers/interfaces/ICitizenManager.java | 2 +- .../entity/citizen/AbstractEntityCitizen.java | 11 --- .../ICitizenDiseaseHandler.java | 7 +- .../com/minecolonies/api/util/SoundUtils.java | 2 +- .../InteractionValidatorInitializer.java | 6 +- .../ModHappinessFactorTypeInitializer.java | 3 +- .../minecolonies/core/colony/CitizenData.java | 24 ++++-- .../com/minecolonies/core/colony/Colony.java | 6 +- .../colony/buildings/AbstractBuilding.java | 7 +- .../BuildingBarracksTower.java | 2 - .../workerbuildings/BuildingHospital.java | 10 ++- .../core/colony/managers/CitizenManager.java | 4 +- .../managers/RegisteredStructureManager.java | 4 +- .../entity/ai/minimal/EntityAISickTask.java | 28 +++---- .../core/entity/ai/workers/CitizenAI.java | 10 +-- .../workers/service/EntityAIWorkHealer.java | 22 +++--- .../core/entity/citizen/EntityCitizen.java | 54 +++----------- .../CitizenDiseaseHandler.java | 73 ++++++++++--------- .../CitizenHappinessHandler.java | 2 +- .../core/entity/visitor/VisitorCitizen.java | 18 ----- .../core/items/ItemScrollGuardHelp.java | 28 ++++--- .../minecolonies/tags/blocks/tier6blocks.json | 3 +- 24 files changed, 153 insertions(+), 187 deletions(-) diff --git a/src/main/java/com/minecolonies/api/colony/ICitizenData.java b/src/main/java/com/minecolonies/api/colony/ICitizenData.java index daa12a4f17f..90bc80a2530 100644 --- a/src/main/java/com/minecolonies/api/colony/ICitizenData.java +++ b/src/main/java/com/minecolonies/api/colony/ICitizenData.java @@ -4,10 +4,7 @@ import com.minecolonies.api.colony.jobs.IJob; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; -import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenFoodHandler; -import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenHappinessHandler; -import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenMournHandler; -import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenSkillHandler; +import com.minecolonies.api.entity.citizen.citizenhandlers.*; import com.minecolonies.api.quests.IQuestGiver; import com.minecolonies.api.quests.IQuestParticipant; import com.minecolonies.api.util.Tuple; @@ -18,7 +15,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.UUID; public interface ICitizenData extends ICivilianData, IQuestGiver, IQuestParticipant { @@ -151,6 +151,8 @@ public interface ICitizenData extends ICivilianData, IQuestGiver, IQuestParticip */ ICitizenSkillHandler getCitizenSkillHandler(); + ICitizenDiseaseHandler getCitizenDiseaseHandler(); + /** * Schedule restart and cleanup. * diff --git a/src/main/java/com/minecolonies/api/colony/ICivilianData.java b/src/main/java/com/minecolonies/api/colony/ICivilianData.java index ee2198113fb..cb3d055e881 100644 --- a/src/main/java/com/minecolonies/api/colony/ICivilianData.java +++ b/src/main/java/com/minecolonies/api/colony/ICivilianData.java @@ -159,7 +159,7 @@ public interface ICivilianData extends ICitizen, INBTSerializable /** * Tick the data to update values. */ - void update(); + void update(final int tickRate); /** * Trigger a possible interaction. diff --git a/src/main/java/com/minecolonies/api/colony/managers/interfaces/ICitizenManager.java b/src/main/java/com/minecolonies/api/colony/managers/interfaces/ICitizenManager.java index 810bcc5f4c2..f91502da6dc 100644 --- a/src/main/java/com/minecolonies/api/colony/managers/interfaces/ICitizenManager.java +++ b/src/main/java/com/minecolonies/api/colony/managers/interfaces/ICitizenManager.java @@ -130,7 +130,7 @@ default ICitizenData spawnOrCreateCitizen(final ICitizenData data, @NotNull fina /** * Tick the citizen data of all active citizens. */ - boolean tickCitizenData(); + boolean tickCitizenData(int tickRate); /** * Call this to set all the citizens in the colony to mourn or not. diff --git a/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java b/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java index f1a8fd4338a..1fa971fdb0b 100755 --- a/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java +++ b/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java @@ -25,7 +25,6 @@ import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.navigation.PathingStuckHandler; import com.mojang.datafixers.util.Pair; -import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -51,7 +50,6 @@ import net.minecraft.world.phys.Vec3; import net.minecraftforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.List; @@ -658,15 +656,6 @@ public boolean checkCanDropLoot() */ public abstract ICitizenSleepHandler getCitizenSleepHandler(); - /** - * The Handler to check if the citizen is sick. - * - * @return the instance of the handler. - */ - public abstract ICitizenDiseaseHandler getCitizenDiseaseHandler(); - - public abstract void setCitizenDiseaseHandler(ICitizenDiseaseHandler citizenDiseaseHandler); - public abstract float getRotationYaw(); public abstract float getRotationPitch(); diff --git a/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenDiseaseHandler.java b/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenDiseaseHandler.java index 56209ad2a4f..20a2815e97f 100755 --- a/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenDiseaseHandler.java +++ b/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenDiseaseHandler.java @@ -1,8 +1,7 @@ package com.minecolonies.api.entity.citizen.citizenhandlers; -import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; +import com.minecolonies.api.colony.ICitizenData; import net.minecraft.nbt.CompoundTag; -import org.jetbrains.annotations.NotNull; /** * Citizen disease handler interface. @@ -12,7 +11,7 @@ public interface ICitizenDiseaseHandler /** * To tick the handler. */ - void tick(); + void update(final int tickRate); /** * Check if the citizen is sick and must be healed.. @@ -50,7 +49,7 @@ public interface ICitizenDiseaseHandler /** * Called when two citizens collide. */ - void onCollission(@NotNull final AbstractEntityCitizen citizen); + void onCollission(final ICitizenData citizen); /** * True when the citizen needs to go to a hospital because its hurt diff --git a/src/main/java/com/minecolonies/api/util/SoundUtils.java b/src/main/java/com/minecolonies/api/util/SoundUtils.java index 86acc67415a..ea45feae048 100755 --- a/src/main/java/com/minecolonies/api/util/SoundUtils.java +++ b/src/main/java/com/minecolonies/api/util/SoundUtils.java @@ -145,7 +145,7 @@ else if (v <= 0.3) { playSoundAtCitizenWith(worldIn, pos, EventType.GENERAL, citizen); } - else if (v <= 0.4 && citizen.getEntity().isPresent() && citizen.getEntity().get().getCitizenDiseaseHandler().isSick()) + else if (v <= 0.4 && citizen.getEntity().isPresent() && citizen.getCitizenDiseaseHandler().isSick()) { playSoundAtCitizenWith(worldIn, pos, EventType.SICKNESS, citizen); } diff --git a/src/main/java/com/minecolonies/apiimp/initializer/InteractionValidatorInitializer.java b/src/main/java/com/minecolonies/apiimp/initializer/InteractionValidatorInitializer.java index 92549896a41..7900d7f2072 100755 --- a/src/main/java/com/minecolonies/apiimp/initializer/InteractionValidatorInitializer.java +++ b/src/main/java/com/minecolonies/apiimp/initializer/InteractionValidatorInitializer.java @@ -68,10 +68,10 @@ public static void init() && citizen.getColony().getBuildingManager().getBestBuilding(citizen.getEntity().get(), BuildingCook.class) == null && InventoryUtils.findFirstSlotInItemHandlerNotEmptyWith(citizen.getInventory(), ISFOOD) == -1); InteractionValidatorRegistry.registerStandardPredicate(Component.translatable(NO_HOSPITAL), - citizen -> citizen.getColony() != null && citizen.getEntity().isPresent() && citizen.getEntity().get().getCitizenDiseaseHandler().isSick() + citizen -> citizen.getColony() != null && citizen.getEntity().isPresent() && citizen.getCitizenDiseaseHandler().isSick() && citizen.getColony().getBuildingManager().getBestBuilding(citizen.getEntity().get(), BuildingHospital.class) == null); InteractionValidatorRegistry.registerStandardPredicate(Component.translatable(WAITING_FOR_CURE), - citizen -> citizen.getColony() != null && citizen.getEntity().isPresent() && !citizen.getEntity().get().getCitizenDiseaseHandler().getDisease().isEmpty()); + citizen -> citizen.getColony() != null && citizen.getEntity().isPresent() && !citizen.getCitizenDiseaseHandler().getDisease().isEmpty()); InteractionValidatorRegistry.registerPosBasedPredicate(Component.translatable(COM_MINECOLONIES_COREMOD_JOB_DELIVERYMAN_CHESTFULL), (citizen, pos) -> @@ -158,7 +158,7 @@ public static void init() }); InteractionValidatorRegistry.registerStandardPredicate(Component.translatable(PATIENT_FULL_INVENTORY), - citizen -> citizen.getEntity().isPresent() && citizen.getEntity().get().getCitizenDiseaseHandler().isSick() + citizen -> citizen.getEntity().isPresent() && citizen.getCitizenDiseaseHandler().isSick() && InventoryUtils.isItemHandlerFull(citizen.getEntity().get().getInventoryCitizen())); InteractionValidatorRegistry.registerStandardPredicate(Component.translatable(PUPIL_NO_CARPET), diff --git a/src/main/java/com/minecolonies/apiimp/initializer/ModHappinessFactorTypeInitializer.java b/src/main/java/com/minecolonies/apiimp/initializer/ModHappinessFactorTypeInitializer.java index 01b7f07acca..33caf17730c 100755 --- a/src/main/java/com/minecolonies/apiimp/initializer/ModHappinessFactorTypeInitializer.java +++ b/src/main/java/com/minecolonies/apiimp/initializer/ModHappinessFactorTypeInitializer.java @@ -43,7 +43,8 @@ private ModHappinessFactorTypeInitializer() HappinessRegistry.housingFunction = DEFERRED_REGISTER_HAPPINESS_FUNCTION.register(HOUSING_FUNCTION.getPath(), () -> new HappinessFunctionEntry(data -> data.getHomeBuilding() == null ? 0.0 : data.getHomeBuilding().getBuildingLevel() / 3.0)); HappinessRegistry.unemploymentFunction = DEFERRED_REGISTER_HAPPINESS_FUNCTION.register(UNEMPLOYMENT_FUNCTION.getPath(), () -> new HappinessFunctionEntry(data -> data.isChild() ? 1.0 : (data.getWorkBuilding() == null ? 0.5 : data.getWorkBuilding().getBuildingLevel() > 3 ? 2.0 : 1.0))); - HappinessRegistry.healthFunction = DEFERRED_REGISTER_HAPPINESS_FUNCTION.register(HEALTH_FUNCTION.getPath(), () -> new HappinessFunctionEntry(data -> data.getEntity().isPresent() ? (data.getEntity().get().getCitizenDiseaseHandler().isSick() ? 0.5 : 1.0) : 1.0)); + HappinessRegistry.healthFunction = DEFERRED_REGISTER_HAPPINESS_FUNCTION.register(HEALTH_FUNCTION.getPath(), + () -> new HappinessFunctionEntry(data -> data.getEntity().isPresent() ? (data.getCitizenDiseaseHandler().isSick() ? 0.5 : 1.0) : 1.0)); HappinessRegistry.idleatjobFunction = DEFERRED_REGISTER_HAPPINESS_FUNCTION.register(IDLEATJOB_FUNCTION.getPath(), () -> new HappinessFunctionEntry(data -> data.isIdleAtJob() ? 0.5 : 1.0)); HappinessRegistry.sleptTonightFunction = DEFERRED_REGISTER_HAPPINESS_FUNCTION.register(SLEPTTONIGHT_FUNCTION.getPath(), () -> new HappinessFunctionEntry(data -> data.getJob() instanceof AbstractJobGuard ? 1 : 0.5)); diff --git a/src/main/java/com/minecolonies/core/colony/CitizenData.java b/src/main/java/com/minecolonies/core/colony/CitizenData.java index 8dd9919a677..6b41abd58f5 100755 --- a/src/main/java/com/minecolonies/core/colony/CitizenData.java +++ b/src/main/java/com/minecolonies/core/colony/CitizenData.java @@ -18,6 +18,7 @@ import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.entity.citizen.Skill; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; +import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenDiseaseHandler; import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenFoodHandler; import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenSkillHandler; import com.minecolonies.api.inventory.InventoryCitizen; @@ -34,10 +35,7 @@ import com.minecolonies.core.colony.interactionhandling.ServerCitizenInteraction; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.entity.citizen.EntityCitizen; -import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenFoodHandler; -import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenHappinessHandler; -import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenMournHandler; -import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenSkillHandler; +import com.minecolonies.core.entity.citizen.citizenhandlers.*; import com.minecolonies.core.network.messages.client.colony.ColonyViewCitizenViewMessage; import com.minecolonies.core.util.AttributeModifierUtils; import net.minecraft.core.BlockPos; @@ -224,6 +222,11 @@ public class CitizenData implements ICitizenData */ private final ICitizenFoodHandler citizenFoodHandler; + /** + * Disease handler + */ + private final CitizenDiseaseHandler citizenDiseaseHandler; + /** * The citizen chat options on the server side. */ @@ -349,6 +352,7 @@ public CitizenData(final int id, final IColony colony) this.citizenMournHandler = new CitizenMournHandler(this); this.citizenSkillHandler = new CitizenSkillHandler(); this.citizenFoodHandler = new CitizenFoodHandler(this); + citizenDiseaseHandler = new CitizenDiseaseHandler(this); } @Override @@ -1174,6 +1178,12 @@ public ICitizenFoodHandler getCitizenFoodHandler() return citizenFoodHandler; } + @Override + public ICitizenDiseaseHandler getCitizenDiseaseHandler() + { + return citizenDiseaseHandler; + } + @Override public void scheduleRestart(final ServerPlayer player) { @@ -1257,6 +1267,7 @@ public CompoundTag serializeNBT() citizenHappinessHandler.write(nbtTagCompound, true); citizenMournHandler.write(nbtTagCompound); citizenFoodHandler.write(nbtTagCompound); + citizenDiseaseHandler.write(nbtTagCompound); inventory.write(nbtTagCompound); nbtTagCompound.putInt(TAG_HELD_ITEM_SLOT, inventory.getHeldItemSlot(InteractionHand.MAIN_HAND)); @@ -1422,6 +1433,7 @@ public void deserializeNBT(final CompoundTag nbtTagCompound) this.citizenHappinessHandler.read(nbtTagCompound, true); this.citizenMournHandler.read(nbtTagCompound); this.citizenFoodHandler.read(nbtTagCompound); + citizenDiseaseHandler.read(nbtTagCompound); if (nbtTagCompound.contains(TAG_LEVEL_MAP) && !nbtTagCompound.contains(TAG_NEW_SKILLS)) { @@ -1541,7 +1553,7 @@ public void setInteractedRecently(final UUID player) } @Override - public void update() + public void update(final int tickRate) { if (!getEntity().isPresent() || !getEntity().get().isAlive()) { @@ -1597,6 +1609,8 @@ public void update() } } } + + citizenDiseaseHandler.update(tickRate); } @Override diff --git a/src/main/java/com/minecolonies/core/colony/Colony.java b/src/main/java/com/minecolonies/core/colony/Colony.java index b73baca9a75..1400e409339 100644 --- a/src/main/java/com/minecolonies/core/colony/Colony.java +++ b/src/main/java/com/minecolonies/core/colony/Colony.java @@ -45,7 +45,6 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.*; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerChunkCache; @@ -373,7 +372,10 @@ protected Colony(final int id, @Nullable final Level world) colonyStateMachine.addTransition(new TickingTransition<>(INACTIVE, () -> true, this::updateState, UPDATE_STATE_INTERVAL)); colonyStateMachine.addTransition(new TickingTransition<>(UNLOADED, () -> true, this::updateState, UPDATE_STATE_INTERVAL)); colonyStateMachine.addTransition(new TickingTransition<>(ACTIVE, () -> true, this::updateState, UPDATE_STATE_INTERVAL)); - colonyStateMachine.addTransition(new TickingTransition<>(ACTIVE, citizenManager::tickCitizenData, () -> ACTIVE, TICKS_SECOND * 3)); + colonyStateMachine.addTransition(new TickingTransition<>(ACTIVE, () -> { + citizenManager.tickCitizenData(TICKS_SECOND * 3); + return false; + }, () -> ACTIVE, TICKS_SECOND * 3)); colonyStateMachine.addTransition(new TickingTransition<>(ACTIVE, this::updateSubscribers, () -> ACTIVE, UPDATE_SUBSCRIBERS_INTERVAL)); colonyStateMachine.addTransition(new TickingTransition<>(ACTIVE, this::tickRequests, () -> ACTIVE, UPDATE_RS_INTERVAL)); diff --git a/src/main/java/com/minecolonies/core/colony/buildings/AbstractBuilding.java b/src/main/java/com/minecolonies/core/colony/buildings/AbstractBuilding.java index d0433533c16..f8f0345de2d 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/AbstractBuilding.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/AbstractBuilding.java @@ -331,7 +331,7 @@ public void onPlayerEnterNearby(final Player player) @Override public void onPlacement() { - if (getBuildingLevel() == 0) + if (getBuildingLevel() == 0 && !hasParent()) { ChunkDataHelper.claimBuildingChunks(colony, true, getPosition(), getClaimRadius(getBuildingLevel()), getCorners()); } @@ -961,7 +961,10 @@ && getPosition() != null public void onUpgradeComplete(final int newLevel) { cachedRotation = -1; - ChunkDataHelper.claimBuildingChunks(colony, true, this.getID(), this.getClaimRadius(newLevel), getCorners()); + if (!hasParent()) + { + ChunkDataHelper.claimBuildingChunks(colony, true, this.getID(), this.getClaimRadius(newLevel), getCorners()); + } recheckGuardBuildingNear = true; ConstructionTapeHelper.removeConstructionTape(getCorners(), colony.getWorld()); diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingBarracksTower.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingBarracksTower.java index 23849cad160..af0b595ce06 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingBarracksTower.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingBarracksTower.java @@ -7,7 +7,6 @@ import com.minecolonies.api.util.MessageUtils; import com.minecolonies.core.colony.buildings.AbstractBuildingGuards; import com.minecolonies.core.util.AdvancementUtils; -import com.minecolonies.core.util.ChunkDataHelper; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; @@ -105,7 +104,6 @@ public void onUpgradeComplete(final int newLevel) { return; } - ChunkDataHelper.claimBuildingChunks(colony, true, barracks, barrack.getClaimRadius(newLevel), barrack.getCorners()); if (newLevel == barrack.getMaxBuildingLevel()) { diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingHospital.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingHospital.java index 96056c78ee6..5996fd631eb 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingHospital.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingHospital.java @@ -20,10 +20,12 @@ import net.minecraft.world.level.block.BedBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BedPart; - import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.function.Predicate; import static com.minecolonies.api.util.constant.NbtTagConstants.*; @@ -209,9 +211,9 @@ private boolean doesAnyPatientRequireStack(final ItemStack stack) for (final Patient patient : patients.values()) { final ICitizenData data = colony.getCitizenManager().getCivilian(patient.getId()); - if (data != null && data.getEntity().isPresent() && data.getEntity().get().getCitizenDiseaseHandler().isSick()) + if (data != null && data.getEntity().isPresent() && data.getCitizenDiseaseHandler().isSick()) { - final String diseaseName = data.getEntity().get().getCitizenDiseaseHandler().getDisease(); + final String diseaseName = data.getCitizenDiseaseHandler().getDisease(); if (!diseaseName.isEmpty()) { final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName); diff --git a/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java b/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java index 034851a156c..0ac81368971 100755 --- a/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java +++ b/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java @@ -567,11 +567,11 @@ public void checkCitizensForHappiness() } @Override - public boolean tickCitizenData() + public boolean tickCitizenData(final int tickRate) { for (ICitizenData iCitizenData : this.getCitizens()) { - iCitizenData.update(); + iCitizenData.update(tickRate); } return false; } diff --git a/src/main/java/com/minecolonies/core/colony/managers/RegisteredStructureManager.java b/src/main/java/com/minecolonies/core/colony/managers/RegisteredStructureManager.java index 0c620811f37..2fcda075993 100644 --- a/src/main/java/com/minecolonies/core/colony/managers/RegisteredStructureManager.java +++ b/src/main/java/com/minecolonies/core/colony/managers/RegisteredStructureManager.java @@ -675,7 +675,7 @@ public BlockPos getBestBuilding(final BlockPos citizen, final Class 0) + if (clazz.isInstance(building) && building.getBuildingLevel() > 0 && WorldUtil.isBlockLoaded(colony.getWorld(), building.getPosition())) { final double localDistance = building.getPosition().distSqr(citizen); if (localDistance < distance) @@ -724,7 +724,7 @@ public boolean hasGuardBuildingNear(final IBuilding building) for (final IBuilding colonyBuilding : getBuildings().values()) { - if (colonyBuilding instanceof IGuardBuilding || colonyBuilding instanceof BuildingBarracks) + if (colonyBuilding.getBuildingLevel() > 0 && (colonyBuilding instanceof IGuardBuilding || colonyBuilding instanceof BuildingBarracks)) { final BoundingBox guardedRegion = BlockPosUtil.getChunkAlignedBB(colonyBuilding.getPosition(), colonyBuilding.getClaimRadius(colonyBuilding.getBuildingLevel())); if (guardedRegion.isInside(building.getPosition())) diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java index 5331c365dc6..581ea8ff195 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java @@ -140,8 +140,8 @@ public EntityAISickTask(final EntityCitizen citizen) private boolean isSick() { - if (citizen.getCitizenDiseaseHandler().isSick() - || citizen.getCitizenDiseaseHandler().isHurt()) + if (citizen.getCitizenData().getCitizenDiseaseHandler().isSick() + || citizen.getCitizenData().getCitizenDiseaseHandler().isHurt()) { reset(); return true; @@ -200,7 +200,7 @@ private DiseaseState findEmptyBed() && state.getValue(BedBlock.PART).equals(BedPart.HEAD) && world.isEmptyBlock(pos.above())) { - citizen.getCitizenDiseaseHandler().setSleepsAtHospital(true); + citizen.getCitizenData().getCitizenDiseaseHandler().setSleepsAtHospital(true); usedBed = pos; ((BuildingHospital) hospital).registerPatient(usedBed, citizen.getCivilianID()); return FIND_EMPTY_BED; @@ -245,7 +245,7 @@ private IState applyCure() return CHECK_FOR_CURE; } - final List list = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenDiseaseHandler().getDisease()).getCure(); + final List list = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenData().getCitizenDiseaseHandler().getDisease()).getCure(); if (!list.isEmpty()) { citizen.setItemInHand(InteractionHand.MAIN_HAND, list.get(citizen.getRandom().nextInt(list.size()))); @@ -275,7 +275,7 @@ private IState applyCure() */ private void cure() { - final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenDiseaseHandler().getDisease()); + final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenData().getCitizenDiseaseHandler().getDisease()); if (disease != null) { for (final ItemStack cure : disease.getCure()) @@ -298,7 +298,7 @@ private void cure() citizen.getCitizenData().setBedPos(BlockPos.ZERO); } citizen.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); - citizen.getCitizenDiseaseHandler().cure(); + citizen.getCitizenData().getCitizenDiseaseHandler().cure(); citizen.setHealth(citizen.getMaxHealth()); reset(); } @@ -369,7 +369,7 @@ else if (state == CitizenAIState.IDLE) private IState goToHut() { final IBuilding buildingWorker = citizenData.getWorkBuilding(); - citizen.getCitizenDiseaseHandler().setSleepsAtHospital(false); + citizen.getCitizenData().getCitizenDiseaseHandler().setSleepsAtHospital(false); if (buildingWorker == null) { @@ -390,7 +390,7 @@ private IState goToHut() */ private IState goToHospital() { - citizen.getCitizenDiseaseHandler().setSleepsAtHospital(false); + citizen.getCitizenData().getCitizenDiseaseHandler().setSleepsAtHospital(false); if (placeToPath == null) { return SEARCH_HOSPITAL; @@ -415,7 +415,7 @@ private IState searchHospital() if (placeToPath == null) { - final String id = citizen.getCitizenDiseaseHandler().getDisease(); + final String id = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); if (id.isEmpty()) { return CitizenAIState.IDLE; @@ -426,9 +426,9 @@ private IState searchHospital() ChatPriority.BLOCKING)); return WANDER; } - else if (!citizen.getCitizenDiseaseHandler().getDisease().isEmpty()) + else if (!citizen.getCitizenData().getCitizenDiseaseHandler().getDisease().isEmpty()) { - final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenDiseaseHandler().getDisease()); + final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenData().getCitizenDiseaseHandler().getDisease()); citizenData.triggerInteraction(new StandardInteraction(Component.translatable(WAITING_FOR_CURE, disease.getName(), disease.getCureString()), Component.translatable(WAITING_FOR_CURE), ChatPriority.BLOCKING)); @@ -444,7 +444,7 @@ else if (!citizen.getCitizenDiseaseHandler().getDisease().isEmpty()) */ private IState checkForCure() { - final String id = citizen.getCitizenDiseaseHandler().getDisease(); + final String id = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); if (id.isEmpty()) { if (citizen.getHealth() > SEEK_DOCTOR_HEALTH) @@ -460,7 +460,7 @@ private IState checkForCure() final int slot = InventoryUtils.findFirstSlotInProviderNotEmptyWith(citizen, stack -> ItemStack.isSameItem(cure, stack)); if (slot == -1) { - if (citizen.getCitizenDiseaseHandler().isSick()) + if (citizen.getCitizenData().getCitizenDiseaseHandler().isSick()) { return GO_TO_HUT; } @@ -482,7 +482,7 @@ private void reset() citizen.stopUsingItem(); citizen.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); placeToPath = null; - citizen.getCitizenDiseaseHandler().setSleepsAtHospital(false); + citizen.getCitizenData().getCitizenDiseaseHandler().setSleepsAtHospital(false); } // TODO: Citizen AI should set status icons diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/CitizenAI.java b/src/main/java/com/minecolonies/core/entity/ai/workers/CitizenAI.java index 78bdacc45fd..c1b5b0850e0 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/CitizenAI.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/CitizenAI.java @@ -137,7 +137,7 @@ private IState calculateNextState() } // Sick - if (citizen.getCitizenDiseaseHandler().isSick() && guardJob.canAIBeInterrupted()) + if (citizen.getCitizenData().getCitizenDiseaseHandler().isSick() && guardJob.canAIBeInterrupted()) { citizen.getCitizenData().setVisibleStatus(VisibleCitizenStatus.SICK); return CitizenAIState.SICK; @@ -147,7 +147,7 @@ private IState calculateNextState() } // Sick at hospital - if (citizen.getCitizenDiseaseHandler().isSick() && citizen.getCitizenDiseaseHandler().sleepsAtHospital()) + if (citizen.getCitizenData().getCitizenDiseaseHandler().isSick() && citizen.getCitizenData().getCitizenDiseaseHandler().sleepsAtHospital()) { citizen.getCitizenData().setVisibleStatus(VisibleCitizenStatus.SICK); return CitizenAIState.SICK; @@ -181,7 +181,7 @@ private IState calculateNextState() { if (citizen.getCitizenSleepHandler().isAsleep()) { - if (citizen.getCitizenDiseaseHandler().isSick()) + if (citizen.getCitizenData().getCitizenDiseaseHandler().isSick()) { final BlockPos bedPos = citizen.getCitizenSleepHandler().getBedLocation(); if (bedPos == null || bedPos.distSqr(citizen.blockPosition()) > 5) @@ -197,7 +197,7 @@ private IState calculateNextState() } // Sick - if (citizen.getCitizenDiseaseHandler().isSick() || citizen.getCitizenDiseaseHandler().isHurt()) + if (citizen.getCitizenData().getCitizenDiseaseHandler().isSick() || citizen.getCitizenData().getCitizenDiseaseHandler().isHurt()) { citizen.getCitizenData().setVisibleStatus(VisibleCitizenStatus.SICK); return CitizenAIState.SICK; @@ -279,7 +279,7 @@ public boolean shouldEat() return false; } - if (citizen.getCitizenDiseaseHandler().isSick() && citizen.getCitizenSleepHandler().isAsleep()) + if (citizen.getCitizenData().getCitizenDiseaseHandler().isSick() && citizen.getCitizenSleepHandler().isAsleep()) { return false; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java index 86185e36c26..50ed8f1f2e0 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java @@ -20,10 +20,10 @@ import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.network.messages.client.CircleParticleEffectMessage; import com.minecolonies.core.network.messages.client.StreamParticleEffectMessage; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; @@ -110,7 +110,7 @@ private IAIState decide() for (final AbstractEntityCitizen citizen : WorldUtil.getEntitiesWithinBuilding(world, AbstractEntityCitizen.class, building, - cit -> cit.getCitizenDiseaseHandler().isSick())) + cit -> cit.getCitizenData().getCitizenDiseaseHandler().isSick())) { hospital.checkOrCreatePatientFile(citizen.getCivilianID()); } @@ -118,13 +118,13 @@ private IAIState decide() for (final Patient patient : hospital.getPatients()) { final ICitizenData data = hospital.getColony().getCitizenManager().getCivilian(patient.getId()); - if (data == null || !data.getEntity().isPresent() || (data.getEntity().isPresent() && !data.getEntity().get().getCitizenDiseaseHandler().isSick())) + if (data == null || !data.getEntity().isPresent() || (data.getEntity().isPresent() && !data.getEntity().get().getCitizenData().getCitizenDiseaseHandler().isSick())) { hospital.removePatientFile(patient); continue; } final EntityCitizen citizen = (EntityCitizen) data.getEntity().get(); - final String diseaseName = citizen.getCitizenDiseaseHandler().getDisease(); + final String diseaseName = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); @Nullable final Disease disease = diseaseName.isEmpty() ? null : IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName); if (patient.getState() == Patient.PatientState.NEW) @@ -247,7 +247,7 @@ private IAIState requestCure() } final ICitizenData data = building.getColony().getCitizenManager().getCivilian(currentPatient.getId()); - if (data == null || !data.getEntity().isPresent() || !data.getEntity().get().getCitizenDiseaseHandler().isSick()) + if (data == null || !data.getEntity().isPresent() || !data.getEntity().get().getCitizenData().getCitizenDiseaseHandler().isSick()) { currentPatient = null; return DECIDE; @@ -259,7 +259,7 @@ private IAIState requestCure() return REQUEST_CURE; } - final String diseaseName = citizen.getCitizenDiseaseHandler().getDisease(); + final String diseaseName = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); if (diseaseName.isEmpty()) { currentPatient.setState(Patient.PatientState.REQUESTED); @@ -317,7 +317,7 @@ private IAIState cure() } final ICitizenData data = building.getColony().getCitizenManager().getCivilian(currentPatient.getId()); - if (data == null || !data.getEntity().isPresent() || !data.getEntity().get().getCitizenDiseaseHandler().isSick()) + if (data == null || !data.getEntity().isPresent() || !data.getEntity().get().getCitizenData().getCitizenDiseaseHandler().isSick()) { currentPatient = null; return DECIDE; @@ -329,7 +329,7 @@ private IAIState cure() return CURE; } - final String diseaseName = citizen.getCitizenDiseaseHandler().getDisease(); + final String diseaseName = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName); if (diseaseName.isEmpty()) { @@ -396,7 +396,7 @@ private IAIState freeCure() } final ICitizenData data = building.getColony().getCitizenManager().getCivilian(currentPatient.getId()); - if (data == null || !data.getEntity().isPresent() || !data.getEntity().get().getCitizenDiseaseHandler().isSick()) + if (data == null || !data.getEntity().isPresent() || !data.getEntity().get().getCitizenData().getCitizenDiseaseHandler().isSick()) { currentPatient = null; return DECIDE; @@ -431,7 +431,7 @@ private IAIState freeCure() progressTicks = 0; worker.getCitizenExperienceHandler().addExperience(BASE_XP_GAIN); - citizen.getCitizenDiseaseHandler().cure(); + citizen.getCitizenData().getCitizenDiseaseHandler().cure(); currentPatient.setState(Patient.PatientState.TREATED); currentPatient = null; return DECIDE; diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index 11de28a8eb8..dd744f09782 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -75,8 +75,6 @@ import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.tags.DamageTypeTags; -import net.minecraft.tags.FluidTags; -import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.CombatRules; @@ -86,10 +84,8 @@ import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.*; -import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.animal.FlyingAnimal; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; @@ -98,10 +94,8 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.ShieldItem; -import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; -import net.minecraft.world.level.material.FluidState; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.Shapes; @@ -197,11 +191,6 @@ public class EntityCitizen extends AbstractEntityCitizen implements IThreatTable */ private ICitizenSleepHandler citizenSleepHandler; - /** - * The citizen sleep handler. - */ - private ICitizenDiseaseHandler citizenDiseaseHandler; - /** * Our custom combat tracker. */ @@ -280,7 +269,6 @@ public EntityCitizen(final EntityType type, final Level this.citizenColonyHandler = new CitizenColonyHandler(this); this.citizenJobHandler = new CitizenJobHandler(this); this.citizenSleepHandler = new CitizenSleepHandler(this); - this.citizenDiseaseHandler = new CitizenDiseaseHandler(this); this.combatTracker = new CitizenCombatTracker(this); this.moveControl = new MovementHandler(this); @@ -421,7 +409,7 @@ public InteractionResult checkAndHandleImportantInteractions(final Player player if (!level.isClientSide && getCitizenData() != null) { - citizenData.update(); + citizenData.update(TICKS_SECOND * 3); citizenData.setInteractedRecently(player.getUUID()); final ColonyViewCitizenViewMessage message = new ColonyViewCitizenViewMessage((Colony) getCitizenData().getColony(), getCitizenData()); Network.getNetwork().sendToPlayer(message, (ServerPlayer) player); @@ -476,10 +464,12 @@ private InteractionResult directPlayerInteraction(final Player player, final Int .withPriority(MessagePriority.DANGER) .sendTo(player); } - return null; + return InteractionResult.PASS; } - if (usedStack.getItem() == Items.GOLDEN_APPLE && getCitizenDiseaseHandler().isSick()) + final boolean isSick = (getCitizenData() != null && getCitizenData().getCitizenDiseaseHandler().isSick()) || (citizenDataView != null + && citizenDataView.getVisibleStatus() == VisibleCitizenStatus.SICK); + if (usedStack.getItem() == Items.GOLDEN_APPLE && isSick) { usedStack.shrink(1); player.setItemInHand(hand, usedStack); @@ -488,7 +478,7 @@ private InteractionResult directPlayerInteraction(final Player player, final Int { if (getRandom().nextInt(3) == 0) { - getCitizenDiseaseHandler().cure(); + getCitizenData().getCitizenDiseaseHandler().cure(); playSound(SoundEvents.PLAYER_LEVELUP, 1.0f, (float) SoundUtils.getRandomPitch(getRandom())); Network.getNetwork().sendToTrackingEntity(new VanillaParticleMessage(getX(), getY(), getZ(), ParticleTypes.HAPPY_VILLAGER), this); } @@ -505,7 +495,7 @@ private InteractionResult directPlayerInteraction(final Player player, final Int if (!level.isClientSide()) { - getCitizenDiseaseHandler().setDisease(IColonyManager.getInstance().getCompatibilityManager().getRandomDisease()); + getCitizenData().getCitizenDiseaseHandler().setDisease(IColonyManager.getInstance().getCompatibilityManager().getRandomDisease()); playSound(SoundEvents.VILLAGER_HURT, 1.0f, (float) SoundUtils.getRandomPitch(getRandom())); getCitizenData().markDirty(20); @@ -514,11 +504,11 @@ private InteractionResult directPlayerInteraction(final Player player, final Int .sendTo(player); } - interactionCooldown = 20 * 60 * 5; + interactionCooldown = 20 * 20; return InteractionResult.CONSUME; } - if (getCitizenDiseaseHandler().isSick()) + if (isSick) { return null; } @@ -701,7 +691,6 @@ public void addAdditionalSaveData(final CompoundTag compound) { compound.putInt(TAG_CITIZEN, citizenData.getId()); } - citizenDiseaseHandler.write(compound); } @Override @@ -717,7 +706,6 @@ public void readAdditionalSaveData(final CompoundTag compound) citizenId = compound.getInt(TAG_CITIZEN); } } - citizenDiseaseHandler.read(compound); setPose(Pose.STANDING); } @@ -776,7 +764,6 @@ private boolean onServerUpdateHandlers() citizenExperienceHandler.gatherXp(); citizenItemHandler.pickupItems(); citizenData.setLastPosition(blockPosition()); - citizenDiseaseHandler.tick(); onLivingSoundUpdate(); final ChunkPos currentChunk = chunkPosition(); @@ -912,7 +899,7 @@ private void decreaseWalkingSaturation() */ private void checkHeal() { - if (getHealth() < (citizenDiseaseHandler.isSick() ? getMaxHealth() / 3 : getMaxHealth()) && getLastHurtByMob() == null) + if (getCitizenData() != null && getHealth() < (getCitizenData().getCitizenDiseaseHandler().isSick() ? getMaxHealth() / 3 : getMaxHealth()) && getLastHurtByMob() == null) { final double limitDecrease = getCitizenColonyHandler().getColonyOrRegister().getResearchManager().getResearchEffects().getEffectStrength(SATLIMIT); @@ -1253,23 +1240,6 @@ public ICitizenSleepHandler getCitizenSleepHandler() return citizenSleepHandler; } - /** - * The Handler to check if a citizen is sick. - * - * @return the instance of the handler. - */ - @Override - public ICitizenDiseaseHandler getCitizenDiseaseHandler() - { - return citizenDiseaseHandler; - } - - @Override - public void setCitizenDiseaseHandler(final ICitizenDiseaseHandler citizenDiseaseHandler) - { - this.citizenDiseaseHandler = citizenDiseaseHandler; - } - /** * Sets the visible status if there is none * @@ -1598,9 +1568,9 @@ protected void doPush(final Entity entity) super.doPush(entity); } - if (!level.isClientSide && entity instanceof AbstractEntityCitizen) + if (!level.isClientSide && getCitizenData() != null && entity instanceof AbstractEntityCitizen otherCitizen && otherCitizen.getCitizenData() != null) { - getCitizenDiseaseHandler().onCollission((AbstractEntityCitizen) entity); + getCitizenData().getCitizenDiseaseHandler().onCollission(otherCitizen.getCitizenData()); } } diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java index 69c54003512..f94bef8184b 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java @@ -1,10 +1,10 @@ package com.minecolonies.core.entity.citizen.citizenhandlers; import com.minecolonies.api.IMinecoloniesAPI; +import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.IColonyManager; import com.minecolonies.api.colony.buildings.IBuilding; -import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenDiseaseHandler; import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingCook; @@ -12,7 +12,6 @@ import com.minecolonies.core.colony.jobs.JobHealer; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; -import org.jetbrains.annotations.NotNull; import static com.minecolonies.api.research.util.ResearchConstants.MASKS; import static com.minecolonies.api.research.util.ResearchConstants.VACCINES; @@ -33,12 +32,12 @@ public class CitizenDiseaseHandler implements ICitizenDiseaseHandler /** * Base likelihood of a citizen getting a disease. */ - private static final int DISEASE_FACTOR = 100000; + private static final int DISEASE_FACTOR = 100000 / 3; /** - * Number of seconds after recovering a citizen is immune against any illness. 90 Minutes currently. + * Number of ticks after recovering a citizen is immune against any illness. 90 Minutes currently. */ - private static final int IMMUNITY_TIME = 60 * 90; + private static final int IMMUNITY_TIME = 20 * 60 * 90; /** * Additional immunity time through vaccines. @@ -48,7 +47,7 @@ public class CitizenDiseaseHandler implements ICitizenDiseaseHandler /** * The citizen assigned to this manager. */ - private final AbstractEntityCitizen citizen; + private final ICitizenData citizenData; /** * The disease the citizen has, empty if none. @@ -78,24 +77,24 @@ public class CitizenDiseaseHandler implements ICitizenDiseaseHandler * * @param citizen the citizen owning the handler. */ - public CitizenDiseaseHandler(final AbstractEntityCitizen citizen) + public CitizenDiseaseHandler(final ICitizenData citizen) { - this.citizen = citizen; + this.citizenData = citizen; } /** - * Called in the citizen every few ticks to check for illness. + * Called in the citizen every few ticks to check for illness. Called every 60 ticks */ @Override - public void tick() + public void update(final int tickRate) { if (canBecomeSick()) { - final double citizenModifier = citizen.getCitizenData().getDiseaseModifier(); + final double citizenModifier = citizenData.getDiseaseModifier(); final int configModifier = MineColonies.getConfig().getServer().diseaseModifier.get(); if (!IColonyManager.getInstance().getCompatibilityManager().getDiseases().isEmpty() && - citizen.getRandom().nextInt(configModifier * DISEASE_FACTOR) < citizenModifier * 10) + citizenData.getRandom().nextInt(configModifier * DISEASE_FACTOR) < citizenModifier * 10) { this.disease = IColonyManager.getInstance().getCompatibilityManager().getRandomDisease(); } @@ -103,7 +102,7 @@ public void tick() if (immunityTicks > 0) { - immunityTicks--; + immunityTicks -= tickRate; } } @@ -120,22 +119,21 @@ public void setDisease(final String disease) private boolean canBecomeSick() { return !isSick() - && citizen.getCitizenColonyHandler().getColonyOrRegister() != null - && citizen.getCitizenColonyHandler().getColonyOrRegister().isActive() - && !(citizen.getCitizenJobHandler().getColonyJob() instanceof JobHealer) + && citizenData.getEntity().isPresent() + && citizenData.getColony().isActive() + && !(citizenData.getJob() instanceof JobHealer) && immunityTicks <= 0 - && citizen.getCitizenColonyHandler().getColonyOrRegister().getCitizenManager().getCurrentCitizenCount() > initialCitizenCount; + && citizenData.getColony().getCitizenManager().getCurrentCitizenCount() > initialCitizenCount; } @Override - public void onCollission(@NotNull final AbstractEntityCitizen citizen) + public void onCollission(final ICitizenData citizen) { if (citizen.getCitizenDiseaseHandler().isSick() && canBecomeSick() && citizen.getRandom().nextInt(ONE_HUNDRED_PERCENT) < 1) { - if (citizen.getCitizenColonyHandler().getColonyOrRegister() != null - && (citizen.getCitizenColonyHandler().getColonyOrRegister().getResearchManager().getResearchEffects().getEffectStrength(MASKS) <= 0 || citizen.getRandom().nextBoolean())) + if (citizen.getColony().getResearchManager().getResearchEffects().getEffectStrength(MASKS) <= 0 || citizen.getRandom().nextBoolean()) { this.disease = citizen.getCitizenDiseaseHandler().getDisease(); } @@ -145,7 +143,8 @@ && canBecomeSick() @Override public boolean isHurt() { - return !(citizen.getCitizenJobHandler() instanceof AbstractJobGuard) && citizen.getHealth() < SEEK_DOCTOR_HEALTH && citizen.getCitizenData().getSaturation() > LOW_SATURATION; + return citizenData.getEntity().isPresent() && !(citizenData.getJob() instanceof AbstractJobGuard) && citizenData.getEntity().get().getHealth() < SEEK_DOCTOR_HEALTH + && citizenData.getSaturation() > LOW_SATURATION; } @Override @@ -157,19 +156,25 @@ public boolean isSick() @Override public void write(final CompoundTag compound) { - compound.putString(TAG_DISEASE, disease); - compound.putInt(TAG_IMMUNITY, immunityTicks); + CompoundTag diseaseTag = new CompoundTag(); + diseaseTag.putString(TAG_DISEASE, disease); + diseaseTag.putInt(TAG_IMMUNITY, immunityTicks); + compound.put(TAG_DISEASE, diseaseTag); } @Override public void read(final CompoundTag compound) { - // cure diseases that have been removed from the configuration file. - if (IColonyManager.getInstance().getCompatibilityManager().getDisease(compound.getString(TAG_DISEASE)) != null) + if (compound.contains(TAG_DISEASE)) { - this.disease = compound.getString(TAG_DISEASE); + CompoundTag diseaseTag = compound.getCompound(TAG_DISEASE); + // cure diseases that have been removed from the configuration file. + if (IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseTag.getString(TAG_DISEASE)) != null) + { + this.disease = diseaseTag.getString(TAG_DISEASE); + } + this.immunityTicks = diseaseTag.getInt(TAG_IMMUNITY); } - this.immunityTicks = compound.getInt(TAG_IMMUNITY); } @Override @@ -183,18 +188,18 @@ public void cure() { this.disease = ""; sleepsAtHospital = false; - if (citizen.getCitizenSleepHandler().isAsleep()) + if (citizenData.isAsleep() && citizenData.getEntity().isPresent()) { - citizen.stopSleeping(); - final BlockPos hospitalPos = citizen.getCitizenColonyHandler().getColonyOrRegister().getBuildingManager().getBestBuilding(citizen, BuildingCook.class); - final IColony colony = citizen.getCitizenColonyHandler().getColonyOrRegister(); + citizenData.getEntity().get().stopSleeping(); + final BlockPos hospitalPos = citizenData.getColony().getBuildingManager().getBestBuilding(citizenData.getEntity().get(), BuildingCook.class); + final IColony colony = citizenData.getColony(); final IBuilding hospital = colony.getBuildingManager().getBuilding(hospitalPos); if (hospital != null) { hospital.onWakeUp(); } - if (citizen.getCitizenColonyHandler().getColonyOrRegister() != null && citizen.getCitizenColonyHandler().getColonyOrRegister().getResearchManager().getResearchEffects().getEffectStrength(VACCINES) > 0) + if (citizenData.getColony().getResearchManager().getResearchEffects().getEffectStrength(VACCINES) > 0) { immunityTicks = IMMUNITY_TIME * VACCINE_MODIFIER; } @@ -209,8 +214,8 @@ public void cure() immunityTicks = IMMUNITY_TIME / 2; } - citizen.getCitizenColonyHandler().getColonyOrRegister().getStatisticsManager().increment(CITIZENS_HEALED, citizen.getCitizenColonyHandler().getColonyOrRegister().getDay()); - citizen.markDirty(0); + citizenData.getColony().getStatisticsManager().increment(CITIZENS_HEALED, citizenData.getColony().getDay()); + citizenData.markDirty(0); } @Override diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenHappinessHandler.java b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenHappinessHandler.java index 47c1af59080..bdf45d5352f 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenHappinessHandler.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenHappinessHandler.java @@ -231,7 +231,7 @@ public static double getSocialModifier(final IColony colony) homelessness++; } - if (citizen.getEntity().isPresent() && citizen.getEntity().get().getCitizenDiseaseHandler().isSick()) + if (citizen.getEntity().isPresent() && citizen.getCitizenDiseaseHandler().isSick()) { sickPeople++; } diff --git a/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java b/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java index eb59eca7778..6005cb8d9c6 100644 --- a/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java @@ -119,7 +119,6 @@ public class VisitorCitizen extends AbstractEntityCitizen * The location used for requests */ private ILocation location = null; - private ICitizenDiseaseHandler citizenDiseaseHandler; /** * Constructor for a new citizen typed entity. @@ -138,7 +137,6 @@ public VisitorCitizen(final EntityType type, final Leve this.citizenJobHandler = new CitizenJobHandler(this); this.citizenSleepHandler = new CitizenSleepHandler(this); this.citizenExperienceHandler = new CitizenExperienceHandler(this); - this.citizenDiseaseHandler = new CitizenDiseaseHandler(this); this.moveControl = new MovementHandler(this); this.setPersistenceRequired(); @@ -390,18 +388,6 @@ public ICitizenSleepHandler getCitizenSleepHandler() return citizenSleepHandler; } - @Override - public ICitizenDiseaseHandler getCitizenDiseaseHandler() - { - return citizenDiseaseHandler; - } - - @Override - public void setCitizenDiseaseHandler(final ICitizenDiseaseHandler citizenDiseaseHandler) - { - this.citizenDiseaseHandler = citizenDiseaseHandler; - } - @Override public float getRotationYaw() { @@ -600,8 +586,6 @@ public void addAdditionalSaveData(final CompoundTag compound) { compound.putInt(TAG_CITIZEN, citizenData.getId()); } - - citizenDiseaseHandler.write(compound); } @Override @@ -617,8 +601,6 @@ public void readAdditionalSaveData(final CompoundTag compound) citizenId = compound.getInt(TAG_CITIZEN); } } - - citizenDiseaseHandler.read(compound); } @Override diff --git a/src/main/java/com/minecolonies/core/items/ItemScrollGuardHelp.java b/src/main/java/com/minecolonies/core/items/ItemScrollGuardHelp.java index c913da5147e..15e2465d1dd 100644 --- a/src/main/java/com/minecolonies/core/items/ItemScrollGuardHelp.java +++ b/src/main/java/com/minecolonies/core/items/ItemScrollGuardHelp.java @@ -5,7 +5,6 @@ import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.entity.ai.statemachine.AIOneTimeEventTarget; import com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState; -import com.minecolonies.core.tileentities.TileEntityColonyBuilding; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.MessageUtils; import com.minecolonies.api.util.SoundUtils; @@ -16,21 +15,25 @@ import com.minecolonies.core.colony.jobs.AbstractJobGuard; import com.minecolonies.core.entity.ai.workers.guard.AbstractEntityAIGuard; import com.minecolonies.core.network.messages.client.VanillaParticleMessage; -import net.minecraft.world.item.TooltipFlag; +import com.minecolonies.core.tileentities.TileEntityColonyBuilding; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.Style; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.animal.horse.Llama; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.InteractionResult; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.core.BlockPos; - import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -40,11 +43,6 @@ import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND; import static com.minecolonies.api.util.constant.translation.ToolTranslationConstants.TOOL_GUARD_SCROLL_NO_GUARD_BUILDING; -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.Style; - /** * Magic scroll which summons guards to the users aid, with a limited duration. Only works within the same world as the colony. */ @@ -101,7 +99,7 @@ protected ItemStack onItemUseSuccess( if (citizenData.getEntity().isPresent()) { - if (citizenData.getEntity().get().getCitizenDiseaseHandler().isSick()) + if (citizenData.getCitizenDiseaseHandler().isSick()) { continue; } diff --git a/src/main/resources/data/minecolonies/tags/blocks/tier6blocks.json b/src/main/resources/data/minecolonies/tags/blocks/tier6blocks.json index b4d42d3944b..4d8de4a78fb 100644 --- a/src/main/resources/data/minecolonies/tags/blocks/tier6blocks.json +++ b/src/main/resources/data/minecolonies/tags/blocks/tier6blocks.json @@ -3,6 +3,7 @@ "minecraft:wither_rose", "minecraft:dragon_head", "minecraft:beacon", - "minecraft:conduit" + "minecraft:conduit", + "minecraft:torchflower" ] } \ No newline at end of file From 8a5def598e0de79445c6cd318ef535cbf88ab790 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Wed, 27 Nov 2024 22:30:54 +0100 Subject: [PATCH 08/33] Stateless citizen item utils (#10484) --- .../entity/citizen/AbstractEntityCitizen.java | 9 -- .../citizenhandlers/ICitizenItemHandler.java | 102 ------------------ .../core/colony/jobs/JobKnight.java | 3 +- .../ai/workers/AbstractEntityAIBasic.java | 7 +- .../ai/workers/AbstractEntityAIInteract.java | 3 +- .../crafting/AbstractEntityAICrafting.java | 3 +- .../AbstractEntityAIRequestSmelter.java | 3 +- .../crafting/EntityAIWorkAlchemist.java | 9 +- .../workers/crafting/EntityAIWorkCrusher.java | 4 +- .../workers/guard/AbstractEntityAIFight.java | 3 +- .../ai/workers/guard/KnightCombatAI.java | 7 +- .../ai/workers/guard/RangerCombatAI.java | 15 ++- .../training/EntityAIArcherTraining.java | 5 +- .../training/EntityAICombatTraining.java | 11 +- .../production/EntityAIWorkLumberjack.java | 3 +- .../production/EntityAIWorkNether.java | 5 +- .../agriculture/EntityAIWorkBeekeeper.java | 11 +- .../agriculture/EntityAIWorkComposter.java | 5 +- .../agriculture/EntityAIWorkFarmer.java | 5 +- .../agriculture/EntityAIWorkFisherman.java | 7 +- .../agriculture/EntityAIWorkPlanter.java | 9 +- .../herders/AbstractEntityAIHerder.java | 19 ++-- .../herders/EntityAIWorkChickenHerder.java | 3 +- .../herders/EntityAIWorkCowboy.java | 5 +- .../herders/EntityAIWorkRabbitHerder.java | 3 +- .../herders/EntityAIWorkShepherd.java | 3 +- .../service/EntityAIWorkDeliveryman.java | 9 +- .../service/EntityAIWorkUndertaker.java | 7 +- .../core/entity/citizen/EntityCitizen.java | 37 ++----- .../CitizenExperienceHandler.java | 5 +- .../citizenhandlers/CitizenSleepHandler.java | 3 +- .../core/entity/visitor/VisitorCitizen.java | 22 +--- .../citizenutils/CitizenItemUtils.java} | 65 ++++------- 33 files changed, 126 insertions(+), 284 deletions(-) delete mode 100755 src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenItemHandler.java rename src/main/java/com/minecolonies/core/{entity/citizen/citizenhandlers/CitizenItemHandler.java => util/citizenutils/CitizenItemUtils.java} (88%) diff --git a/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java b/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java index 1fa971fdb0b..21b8b75c468 100755 --- a/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java +++ b/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java @@ -617,13 +617,6 @@ public boolean checkCanDropLoot() */ public abstract ICitizenExperienceHandler getCitizenExperienceHandler(); - /** - * The Handler for all item related methods. - * - * @return the instance of the handler. - */ - public abstract ICitizenItemHandler getCitizenItemHandler(); - /** * The Handler for all inventory related methods. * @@ -666,8 +659,6 @@ public boolean checkCanDropLoot() public abstract void setCitizenJobHandler(ICitizenJobHandler citizenJobHandler); - public abstract void setCitizenItemHandler(ICitizenItemHandler citizenItemHandler); - public abstract void setCitizenExperienceHandler(ICitizenExperienceHandler citizenExperienceHandler); /** diff --git a/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenItemHandler.java b/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenItemHandler.java deleted file mode 100755 index c39aeb9dd05..00000000000 --- a/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenItemHandler.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.minecolonies.api.entity.citizen.citizenhandlers; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public interface ICitizenItemHandler -{ - /** - * Citizen will try to pick up a certain item. - * - * @param ItemEntity the item he wants to pickup. - */ - void tryPickupItemEntity(@NotNull ItemEntity ItemEntity); - - /** - * Removes the currently held item. - */ - void removeHeldItem(); - - /** - * Sets the currently held item. - * - * @param hand what hand we're setting - * @param slot from the inventory slot. - */ - void setHeldItem(InteractionHand hand, int slot); - - /** - * Sets the currently held for mainHand item. - * - * @param slot from the inventory slot. - */ - void setMainHeldItem(int slot); - - /** - * Swing entity arm, create sound and particle effects. - *

- * Will not break the block. - * - * @param blockPos Block position. - */ - void hitBlockWithToolInHand(@Nullable BlockPos blockPos); - - /** - * Swing entity arm, create sound and particle effects. - *

- * If breakBlock is true then it will break the block (different sound and particles), and damage the tool in the citizens hand. - * - * @param blockPos Block position. - * @param breakBlock if we want to break this block. - */ - void hitBlockWithToolInHand(@Nullable BlockPos blockPos, boolean breakBlock); - - /** - * Damage the current held item. - * - * @param hand hand the item is in. - * @param damage amount of damage. - */ - void damageItemInHand(InteractionHand hand, int damage); - - /** - * Pick up all items in a range around the citizen. - */ - void pickupItems(); - - /** - * Swing entity arm, create sound and particle effects. - *

- * This will break the block (different sound and particles), and damage the tool in the citizens hand. - * - * @param blockPos Block position. - */ - void breakBlockWithToolInHand(@Nullable BlockPos blockPos); - - /** - * Handles the dropping of items from the entity. - * - * @param itemstack to drop. - * @return the dropped item. - */ - ItemEntity entityDropItem(@NotNull ItemStack itemstack); - - /** - * Updates the armour damage after being hit. - * - * @param damage damage dealt. - */ - void updateArmorDamage(double damage); - - /** - * Apply mending to the armour. - * - * @param localXp the xp to add. - * @return the remaining xp. - */ - double applyMending(final double localXp); -} diff --git a/src/main/java/com/minecolonies/core/colony/jobs/JobKnight.java b/src/main/java/com/minecolonies/core/colony/jobs/JobKnight.java index d92e3fb7b12..45fffe3fb04 100755 --- a/src/main/java/com/minecolonies/core/colony/jobs/JobKnight.java +++ b/src/main/java/com/minecolonies/core/colony/jobs/JobKnight.java @@ -1,5 +1,6 @@ package com.minecolonies.core.colony.jobs; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.resources.ResourceLocation; import com.minecolonies.api.client.render.modeltype.ModModelTypes; import com.minecolonies.api.colony.ICitizenData; @@ -84,7 +85,7 @@ public boolean ignoresDamage(@NotNull final DamageSource damageSource) return true; } final AbstractEntityCitizen worker = this.getCitizen().getEntity().get(); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.OFF_HAND, InventoryUtils.findFirstSlotInItemHandlerWith(this.getCitizen().getInventory(), Items.SHIELD)); + CitizenItemUtils.setHeldItem(worker, InteractionHand.OFF_HAND, InventoryUtils.findFirstSlotInItemHandlerWith(this.getCitizen().getInventory(), Items.SHIELD)); worker.startUsingItem(InteractionHand.OFF_HAND); // Apply the colony Flag to the shield diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIBasic.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIBasic.java index 9f7157c1a88..3339c47103a 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIBasic.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIBasic.java @@ -35,6 +35,7 @@ import com.minecolonies.core.colony.jobs.AbstractJob; import com.minecolonies.core.colony.jobs.JobDeliveryman; import com.minecolonies.core.colony.requestsystem.resolvers.StationRequestResolver; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.entity.pathfinding.proxy.EntityCitizenWalkToProxy; import com.minecolonies.core.tileentities.TileEntityRack; import com.minecolonies.core.util.WorkerUtil; @@ -522,7 +523,7 @@ private boolean waitingForSomething() currentWorkingLocation.getZ(), DEFAULT_RANGE_FOR_DELAY)) { - worker.getCitizenItemHandler().hitBlockWithToolInHand(currentWorkingLocation); + CitizenItemUtils.hitBlockWithToolInHand(worker, currentWorkingLocation); } delay -= getTickRate(); if (delay <= 0) @@ -1280,13 +1281,13 @@ public final boolean holdEfficientTool(@NotNull final BlockState target, final B if (bestSlot >= 0) { worker.getCitizenData().setIdleAtJob(false); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, bestSlot); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, bestSlot); return true; } else if (bestSlot == NO_TOOL) { worker.getCitizenData().setIdleAtJob(false); - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); return true; } requestTool(target, pos); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java index 182ce1aecd7..957ed54662c 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java @@ -8,6 +8,7 @@ import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.buildings.AbstractBuilding; import com.minecolonies.core.colony.jobs.AbstractJob; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.item.ItemEntity; @@ -220,7 +221,7 @@ protected final boolean mineBlock( if (blockBreakAction == null) { //Break the block - worker.getCitizenItemHandler().breakBlockWithToolInHand(blockToMine); + CitizenItemUtils.breakBlockWithToolInHand(worker, blockToMine); } else { diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAICrafting.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAICrafting.java index 85d6e3d617a..106f0a28b63 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAICrafting.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAICrafting.java @@ -24,6 +24,7 @@ import com.minecolonies.core.colony.jobs.AbstractJobCrafter; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.network.messages.client.BlockParticleEffectMessage; import com.minecolonies.core.network.messages.client.LocalizedParticleEffectMessage; import net.minecraft.core.BlockPos; @@ -450,7 +451,7 @@ protected IAIState craft() job.setCraftCounter(job.getCraftCounter() + 1); if (toolSlot != -1) { - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); } if (job.getCraftCounter() >= job.getMaxCraftingCount()) diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAIRequestSmelter.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAIRequestSmelter.java index 64e6fee1768..8763a043d8c 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAIRequestSmelter.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAIRequestSmelter.java @@ -24,6 +24,7 @@ import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.AbstractJobCrafter; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIBasic; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.world.InteractionHand; @@ -740,7 +741,7 @@ private IAIState fillUpFurnace() { return getState(); } - worker.getCitizenItemHandler().hitBlockWithToolInHand(walkTo); + CitizenItemUtils.hitBlockWithToolInHand(worker, walkTo); InventoryUtils.transferXInItemHandlerIntoSlotInItemHandler( worker.getInventoryCitizen(), smeltable, diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkAlchemist.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkAlchemist.java index cbdfbba5225..918dc28a7bf 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkAlchemist.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkAlchemist.java @@ -20,6 +20,7 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingAlchemist; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobAlchemist; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.network.messages.client.BlockParticleEffectMessage; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; @@ -248,7 +249,7 @@ private IAIState harvestMistleToe() final int slot = InventoryUtils.getFirstSlotOfItemHandlerContainingEquipment(worker.getInventoryCitizen(), ModEquipmentTypes.shears.get(), TOOL_LEVEL_WOOD_OR_GOLD, building.getMaxEquipmentLevel()); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, slot); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, slot); worker.swing(InteractionHand.MAIN_HAND); world.playSound(null, @@ -263,7 +264,7 @@ private IAIState harvestMistleToe() worker.decreaseSaturationForContinuousAction(); InventoryUtils.addItemStackToItemHandler(worker.getInventoryCitizen(), new ItemStack(ModItems.mistletoe, 1)); walkTo = null; - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); return INVENTORY_FULL; } } @@ -930,7 +931,7 @@ private IAIState fillUpBrewingStand() { return getState(); } - worker.getCitizenItemHandler().hitBlockWithToolInHand(walkTo); + CitizenItemUtils.hitBlockWithToolInHand(worker, walkTo); InventoryUtils.transferXInItemHandlerIntoSlotInItemHandler( worker.getInventoryCitizen(), potion, @@ -989,7 +990,7 @@ else if (isEmpty(((BrewingStandBlockEntity) entity).getItem(INGREDIENT_SLOT))) { return getState(); } - worker.getCitizenItemHandler().hitBlockWithToolInHand(walkTo); + CitizenItemUtils.hitBlockWithToolInHand(worker, walkTo); InventoryUtils.transferXInItemHandlerIntoSlotInItemHandler( worker.getInventoryCitizen(), ingredient, diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkCrusher.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkCrusher.java index db13826457c..6b27a8711f7 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkCrusher.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkCrusher.java @@ -6,7 +6,7 @@ import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; -import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.Network; @@ -221,7 +221,7 @@ protected IAIState craft() worker.setItemInHand(InteractionHand.MAIN_HAND, currentRecipeStorage.getCleanedInput().get(worker.getRandom().nextInt(currentRecipeStorage.getCleanedInput().size())).getItemStack().copy()); worker.setItemInHand(InteractionHand.OFF_HAND, currentRecipeStorage.getPrimaryOutput().copy()); - worker.getCitizenItemHandler().hitBlockWithToolInHand(building.getPosition()); + CitizenItemUtils.hitBlockWithToolInHand(worker, building.getPosition()); currentRequest = job.getCurrentTask(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIFight.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIFight.java index a6864ea4838..b14f9d68051 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIFight.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIFight.java @@ -12,6 +12,7 @@ import com.minecolonies.core.colony.buildings.AbstractBuildingGuards; import com.minecolonies.core.colony.jobs.AbstractJobGuard; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ArmorItem; @@ -125,7 +126,7 @@ private IAIState prepare() stack -> !ItemStackUtils.isEmpty(stack) && ItemStackUtils.doesItemServeAsWeapon(stack) && ItemStackUtils.hasEquipmentLevel(stack, tool, 0, building.getMaxEquipmentLevel()), - itemStack -> worker.getCitizenItemHandler().setMainHeldItem(itemStack)); + itemStack -> CitizenItemUtils.setMainHeldItem(worker, itemStack)); } equipInventoryArmor(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/KnightCombatAI.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/KnightCombatAI.java index 240ace960d4..d0e720a0187 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/KnightCombatAI.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/KnightCombatAI.java @@ -14,6 +14,7 @@ import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.api.util.constant.ColonyConstants; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.jobs.AbstractJobGuard; @@ -111,7 +112,7 @@ protected IAIState attackProtect() if (shieldSlot != -1 && target != null && target.isAlive() && nextAttackTime - user.level.getGameTime() >= MIN_TIME_TO_ATTACK && user.getCitizenColonyHandler().getColonyOrRegister().getResearchManager().getResearchEffects().getEffectStrength(SHIELD_USAGE) > 0) { - user.getCitizenItemHandler().setHeldItem(InteractionHand.OFF_HAND, shieldSlot); + CitizenItemUtils.setHeldItem(user, InteractionHand.OFF_HAND, shieldSlot); user.startUsingItem(InteractionHand.OFF_HAND); // Apply the colony Flag to the shield @@ -137,7 +138,7 @@ public boolean canAttack() if (weaponSlot != -1) { - user.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, weaponSlot); + CitizenItemUtils.setHeldItem(user, InteractionHand.MAIN_HAND, weaponSlot); return true; } @@ -188,7 +189,7 @@ protected void doAttack(final LivingEntity target) user.stopUsingItem(); user.decreaseSaturationForContinuousAction(); user.getCitizenData().setVisibleStatus(KNIGHT_COMBAT); - user.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(user, InteractionHand.MAIN_HAND, 1); } /** diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java index 12f043df468..811ceb86a82 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java @@ -9,6 +9,10 @@ import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.api.util.constant.ColonyConstants; +import com.minecolonies.core.entity.pathfinding.PathfindingUtils; +import com.minecolonies.core.entity.pathfinding.PathingOptions; +import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.buildings.AbstractBuildingGuards; @@ -18,13 +22,8 @@ import com.minecolonies.core.entity.ai.combat.CombatUtils; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.entity.other.CustomArrowEntity; -import com.minecolonies.core.entity.pathfinding.PathfindingUtils; -import com.minecolonies.core.entity.pathfinding.PathingOptions; import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; -import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobCanSee; -import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveAwayFromLocation; -import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveToLocation; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; +import com.minecolonies.core.entity.pathfinding.pathjobs.*; import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; @@ -110,7 +109,7 @@ public boolean canAttack() if (weaponSlot != -1) { - user.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, weaponSlot); + CitizenItemUtils.setHeldItem(user, InteractionHand.MAIN_HAND, weaponSlot); if (nextAttackTime - BOW_HOLDING_DELAY >= user.level.getGameTime() && !user.isUsingItem()) { user.startUsingItem(InteractionHand.MAIN_HAND); @@ -196,7 +195,7 @@ protected void doAttack(final LivingEntity target) } target.setLastHurtByMob(user); - user.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(user, InteractionHand.MAIN_HAND, 1); user.stopUsingItem(); user.decreaseSaturationForContinuousAction(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAIArcherTraining.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAIArcherTraining.java index e5038dc5da5..a3cfc08fa5a 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAIArcherTraining.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAIArcherTraining.java @@ -11,6 +11,7 @@ import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingArchery; import com.minecolonies.core.colony.jobs.JobArcherTraining; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.util.WorkerUtil; import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.projectile.Arrow; @@ -187,7 +188,7 @@ protected IAIState shoot() if (worker.getRandom().nextBoolean()) { - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); } worker.stopUsingItem(); this.incrementActionsDoneAndDecSaturation(); @@ -232,7 +233,7 @@ protected boolean isSetup() } final int bowSlot = InventoryUtils.getFirstSlotOfItemHandlerContainingEquipment(getInventory(), ModEquipmentTypes.bow.get(), 0, building.getMaxEquipmentLevel()); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, bowSlot); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, bowSlot); return true; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAICombatTraining.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAICombatTraining.java index b93382dee90..4e98efbe600 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAICombatTraining.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAICombatTraining.java @@ -10,6 +10,7 @@ import com.minecolonies.api.util.SoundUtils; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingCombatAcademy; import com.minecolonies.core.colony.jobs.JobCombatTraining; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.util.WorkerUtil; import net.minecraft.world.item.Items; import net.minecraft.world.InteractionHand; @@ -185,7 +186,7 @@ private IAIState attack() if (shieldSlot != -1) { worker.playSound(SoundEvents.SHIELD_BLOCK, (float) BASIC_VOLUME, (float) SoundUtils.getRandomPitch(worker.getRandom())); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.OFF_HAND, shieldSlot); + CitizenItemUtils.setHeldItem(worker, InteractionHand.OFF_HAND, shieldSlot); worker.startUsingItem(InteractionHand.OFF_HAND); worker.getLookControl().setLookAt(trainingPartner, (float) TURN_AROUND, (float) TURN_AROUND); } @@ -195,7 +196,7 @@ private IAIState attack() worker.swing(InteractionHand.MAIN_HAND); worker.playSound(SoundEvents.PLAYER_ATTACK_SWEEP, (float) BASIC_VOLUME, (float) SoundUtils.getRandomPitch(worker.getRandom())); trainingPartner.hurt(world.damageSources().source(DamageSourceKeys.TRAINING, worker), 0.0F); - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); } worker.getNavigation().moveAwayFromXYZ(trainingPartner.blockPosition(), 4.0, 1.0, true); targetCounter++; @@ -278,7 +279,7 @@ private IAIState attackDummy() if (shieldSlot != -1) { worker.playSound(SoundEvents.SHIELD_BLOCK, (float) BASIC_VOLUME, (float) SoundUtils.getRandomPitch(worker.getRandom())); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.OFF_HAND, shieldSlot); + CitizenItemUtils.setHeldItem(worker, InteractionHand.OFF_HAND, shieldSlot); worker.startUsingItem(InteractionHand.OFF_HAND); } } @@ -286,7 +287,7 @@ private IAIState attackDummy() { worker.swing(InteractionHand.MAIN_HAND); worker.playSound(SoundEvents.PLAYER_ATTACK_SWEEP, (float) BASIC_VOLUME, (float) SoundUtils.getRandomPitch(worker.getRandom())); - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); } currentAttackDelay = RANGED_ATTACK_DELAY_BASE; @@ -316,7 +317,7 @@ protected boolean isSetup() final int weaponSlot = InventoryUtils.getFirstSlotOfItemHandlerContainingEquipment(getInventory(), ModEquipmentTypes.sword.get(), 0, building.getMaxEquipmentLevel()); if (weaponSlot != -1) { - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, weaponSlot); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, weaponSlot); } return true; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkLumberjack.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkLumberjack.java index 6125db4afc5..4ec4498d1b1 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkLumberjack.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkLumberjack.java @@ -17,6 +17,7 @@ import com.minecolonies.core.colony.jobs.JobLumberjack; import com.minecolonies.core.entity.ai.workers.crafting.AbstractEntityAICrafting; import com.minecolonies.core.entity.ai.workers.util.Tree; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveToWithPassable; @@ -823,7 +824,7 @@ private boolean plantSapling(@NotNull final BlockPos location) if (saplingSlot != -1) { final ItemStack stack = getInventory().getStackInSlot(saplingSlot); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, saplingSlot); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, saplingSlot); if (job.getTree().isDynamicTree() && Compatibility.isDynamicTreeSapling(stack)) { diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java index 92b04690989..fed20177bb5 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java @@ -22,6 +22,7 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingNetherWorker; import com.minecolonies.core.colony.jobs.JobNetherWorker; import com.minecolonies.core.entity.ai.workers.crafting.AbstractEntityAICrafting; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.items.ItemAdventureToken; import com.minecolonies.core.util.TeleportHelper; import net.minecraft.core.BlockPos; @@ -557,7 +558,7 @@ protected IAIState stayInNether() if (currStack.getTag().contains(TAG_XP_DROPPED)) { - worker.getCitizenExperienceHandler().addExperience(worker.getCitizenItemHandler().applyMending(currStack.getTag().getInt(TAG_XP_DROPPED))); + worker.getCitizenExperienceHandler().addExperience(CitizenItemUtils.applyMending(worker, currStack.getTag().getInt(TAG_XP_DROPPED))); } } } @@ -589,7 +590,7 @@ else if (!currStack.isEmpty()) tool = findTool(block.defaultBlockState(), worker.blockPosition()); worker.setItemSlot(EquipmentSlot.MAINHAND, tool); } - worker.getCitizenExperienceHandler().addExperience(worker.getCitizenItemHandler().applyMending(xpOnDrop(block))); + worker.getCitizenExperienceHandler().addExperience(CitizenItemUtils.applyMending(worker, xpOnDrop(block))); itemDelay += TICK_DELAY; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkBeekeeper.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkBeekeeper.java index 31dc00ebb19..03ea995a813 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkBeekeeper.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkBeekeeper.java @@ -16,6 +16,7 @@ import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobBeekeeper; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.tags.BlockTags; @@ -357,7 +358,7 @@ private IAIState harvestHoney() final ItemStack itemStack = worker.getMainHandItem(); if (!building.getHarvestTypes().equals(BuildingBeekeeper.HONEY) && ModEquipmentTypes.shears.get().checkIsEquipment(itemStack)) { - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); for (ItemStack stackItem : Compatibility.getCombsFromHive(hive, world, getHoneycombsPerHarvest())) { @@ -492,7 +493,7 @@ public boolean equipTool(final InteractionHand hand, final EquipmentTypeEntry to { if (getToolSlot(toolType) != -1) { - worker.getCitizenItemHandler().setHeldItem(hand, getToolSlot(toolType)); + CitizenItemUtils.setHeldItem(worker, hand, getToolSlot(toolType)); return true; } return false; @@ -527,7 +528,7 @@ public boolean equipItem(final InteractionHand hand, final ItemStack itemStack) { if (checkIfRequestForItemExistOrCreateAsync(itemStack)) { - worker.getCitizenItemHandler().setHeldItem(hand, getItemSlot(itemStack.getItem())); + CitizenItemUtils.setHeldItem(worker, hand, getItemSlot(itemStack.getItem())); return true; } return false; @@ -544,8 +545,8 @@ public boolean equipBreedItem(final InteractionHand hand) if (checkIfRequestForTagExistOrCreateAsync(ItemTags.FLOWERS, NUM_OF_FLOWERS_TO_BREED)) { ItemListModule flowersModule = building.getModuleMatching(ItemListModule.class, m -> m.getId().equals(BUILDING_FLOWER_LIST)); - worker.getCitizenItemHandler() - .setHeldItem(hand, InventoryUtils.findFirstSlotInItemHandlerWith(getInventory(), stack -> flowersModule.isItemInList(new ItemStorage(stack)))); + CitizenItemUtils + .setHeldItem(worker, hand, InventoryUtils.findFirstSlotInItemHandlerWith(getInventory(), stack -> flowersModule.isItemInList(new ItemStorage(stack)))); return true; } return false; diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkComposter.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkComposter.java index b1f0554c3ec..a682e335406 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkComposter.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkComposter.java @@ -17,6 +17,7 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingComposter; import com.minecolonies.core.colony.jobs.JobComposter; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.tileentities.TileEntityBarrel; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; @@ -274,7 +275,7 @@ private IAIState fillBarrels() final TileEntityBarrel barrel = (TileEntityBarrel) world.getBlockEntity(currentTarget); - worker.getCitizenItemHandler().hitBlockWithToolInHand(currentTarget); + CitizenItemUtils.hitBlockWithToolInHand(worker, currentTarget); barrel.addItem(worker.getItemInHand(InteractionHand.MAIN_HAND)); worker.getCitizenExperienceHandler().addExperience(BASE_XP_GAIN); this.incrementActionsDoneAndDecSaturation(); @@ -302,7 +303,7 @@ private IAIState harvestBarrels() if (world.getBlockEntity(currentTarget) instanceof TileEntityBarrel) { - worker.getCitizenItemHandler().hitBlockWithToolInHand(currentTarget); + CitizenItemUtils.hitBlockWithToolInHand(worker, currentTarget); final TileEntityBarrel te = (TileEntityBarrel) world.getBlockEntity(currentTarget); final ItemStack compost = te.retrieveCompost(getLootMultiplier(worker.getRandom())); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFarmer.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFarmer.java index abd9db32586..87629b7ed48 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFarmer.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFarmer.java @@ -29,6 +29,7 @@ import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobFarmer; import com.minecolonies.core.entity.ai.workers.crafting.AbstractEntityAICrafting; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.items.ItemCrop; import com.minecolonies.core.network.messages.client.CompostParticleMessage; import com.minecolonies.core.util.AdvancementUtils; @@ -589,7 +590,7 @@ private boolean hoeIfAble(BlockPos position, final FarmField farmField) equipHoe(); worker.swing(worker.getUsedItemHand()); createCorrectFarmlandForSeed(farmField.getSeed(), position); - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); worker.decreaseSaturationForContinuousAction(); worker.getCitizenColonyHandler().getColonyOrRegister().getStatisticsManager().increment(LAND_TILLED, worker.getCitizenColonyHandler().getColonyOrRegister().getDay()); @@ -701,7 +702,7 @@ private boolean tryToPlant(final FarmField farmField, BlockPos position) */ private void equipHoe() { - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, getHoeSlot()); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, getHoeSlot()); } /** diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFisherman.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFisherman.java index b505adb3f04..a0583a3e8b0 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFisherman.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFisherman.java @@ -15,6 +15,7 @@ import com.minecolonies.core.colony.jobs.JobFisherman; import com.minecolonies.core.entity.ai.workers.AbstractEntityAISkill; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.entity.other.NewBobberEntity; import com.minecolonies.core.entity.pathfinding.Pathfinding; import com.minecolonies.core.entity.pathfinding.PathfindingUtils; @@ -29,7 +30,6 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.tags.ItemTags; import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ExperienceOrb; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; @@ -607,7 +607,7 @@ private IAIState isReadyToFish() */ private void equipRod() { - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, getRodSlot()); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, getRodSlot()); } /** @@ -658,8 +658,7 @@ private void retrieveRod() worker.swing(worker.getUsedItemHand()); final int i = entityFishHook.getDamage(); generateBonusLoot(); - entityFishHook.remove(Entity.RemovalReason.DISCARDED); - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, i); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, i); entityFishHook = null; } } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkPlanter.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkPlanter.java index da022aacbc4..b82f2a25693 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkPlanter.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkPlanter.java @@ -23,6 +23,7 @@ import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobPlanter; import com.minecolonies.core.entity.ai.workers.crafting.AbstractEntityAICrafting; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; @@ -223,7 +224,7 @@ private IAIState workField() if (handlerResult.equals(ActionHandlerResult.FINISHED)) { - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); if (activeModuleResult.getAction().increasesActionCount()) { @@ -311,13 +312,13 @@ private ActionHandlerResult handlePlantingAction() } final int slot = InventoryUtils.findFirstSlotInItemHandlerWith(worker.getItemHandlerCitizen(), currentStack.getItem()); - worker.getCitizenItemHandler().setMainHeldItem(slot); + CitizenItemUtils.setMainHeldItem(worker, slot); BlockState blockState = planterModule.getPlantingBlockState(world, activeModuleResult.getWorkingPosition(), BlockUtils.getBlockStateFromStack(currentStack)); if (world.setBlockAndUpdate(activeModuleResult.getActionPosition(), blockState)) { InventoryUtils.reduceStackInItemHandler(worker.getItemHandlerCitizen(), currentStack); - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); return ActionHandlerResult.FINISHED; } @@ -371,7 +372,7 @@ private ActionHandlerResult handleMiningAction(boolean isHarvest) boolean mineResult = mineBlock(activeModuleResult.getActionPosition()); if (mineResult) { - worker.getCitizenItemHandler().pickupItems(); + CitizenItemUtils.pickupItems(worker); if (isHarvest) { diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/AbstractEntityAIHerder.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/AbstractEntityAIHerder.java index 0ae47f1dbc1..081e0c32970 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/AbstractEntityAIHerder.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/AbstractEntityAIHerder.java @@ -13,6 +13,7 @@ import com.minecolonies.core.colony.buildings.modules.AnimalHerdingModule; import com.minecolonies.core.colony.jobs.AbstractJob; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.InteractionHand; @@ -410,7 +411,7 @@ protected IAIState breedAnimals() { if (current_module == null) { - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); return DECIDE; } @@ -424,7 +425,7 @@ protected IAIState breedAnimals() if (breedables.size() < 2) { - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); breedTimeOut = TICKS_SECOND * 60; return DECIDE; } @@ -448,14 +449,14 @@ protected IAIState breedAnimals() if (animalTwo == null) { - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); breedTimeOut = TICKS_SECOND * 20; return DECIDE; } if (!equipItem(InteractionHand.MAIN_HAND, current_module.getBreedingItems())) { - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); return START_WORKING; } @@ -469,7 +470,7 @@ protected IAIState breedAnimals() } breedTimeOut = TICKS_SECOND * 60; - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); return IDLE; } @@ -547,7 +548,7 @@ protected IAIState feedAnimal() worker.getCitizenExperienceHandler().addExperience(XP_PER_ACTION); worker.level.broadcastEntityEvent(toFeed, (byte) 18); toFeed.playSound(SoundEvents.GENERIC_EAT, 1.0F, 1.0F); - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); fedRecently.put(toFeed.getUUID(), worker.level.getGameTime()); return DECIDE; @@ -694,7 +695,7 @@ public boolean equipTool(final InteractionHand hand, final EquipmentTypeEntry to { if (getToolSlot(toolType) != -1) { - worker.getCitizenItemHandler().setHeldItem(hand, getToolSlot(toolType)); + CitizenItemUtils.setHeldItem(worker, hand, getToolSlot(toolType)); return true; } return false; @@ -731,7 +732,7 @@ public boolean equipItem(final InteractionHand hand, final List itemS { if (checkIfRequestForItemExistOrCreateAsync(itemStack)) { - worker.getCitizenItemHandler().setHeldItem(hand, getItemSlot(itemStack.getItem())); + CitizenItemUtils.setHeldItem(worker, hand, getItemSlot(itemStack.getItem())); return true; } } @@ -762,7 +763,7 @@ protected void butcherAnimal(@Nullable final Animal animal) worker.swing(InteractionHand.MAIN_HAND); final DamageSource ds = animal.level.damageSources().playerAttack(getFakePlayer()); animal.hurt(ds, (float) getButcheringAttackDamage()); - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); } } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkChickenHerder.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkChickenHerder.java index e0f58079308..38c40fe456c 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkChickenHerder.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkChickenHerder.java @@ -7,6 +7,7 @@ import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingChickenHerder; import com.minecolonies.core.colony.jobs.JobChickenHerder; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.animal.Animal; @@ -66,7 +67,7 @@ protected void butcherAnimal(@Nullable final Animal animal) if (worker.getRandom().nextInt(1 + (ONE_HUNDRED_PERCENT - getSecondarySkillLevel()) / 5) <= 1) { animal.hurt(world.damageSources().source(DamageSourceKeys.DEFAULT, worker), (float) getButcheringAttackDamage()); - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); } } } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkCowboy.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkCowboy.java index 3a014a959a4..72350cf0f3b 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkCowboy.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkCowboy.java @@ -9,6 +9,7 @@ import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingCowboy; import com.minecolonies.core.colony.jobs.JobCowboy; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionHand; @@ -170,7 +171,7 @@ private IAIState milkCows() if (InventoryUtils.addItemStackToItemHandler(worker.getInventoryCitizen(), building.getMilkOutputItem())) { building.getFirstModuleOccurance(BuildingCowboy.HerdingModule.class).onMilked(); - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); equipItem(InteractionHand.MAIN_HAND, Collections.singletonList(building.getMilkOutputItem())); InventoryUtils.tryRemoveStackFromItemHandler(worker.getInventoryCitizen(), building.getMilkInputItem()); } @@ -224,7 +225,7 @@ private IAIState milkMooshrooms() if (InventoryUtils.addItemStackToItemHandler(worker.getInventoryCitizen(), fakePlayer.getMainHandItem())) { building.getFirstModuleOccurance(BuildingCowboy.HerdingModule.class).onStewed(); - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); equipItem(InteractionHand.MAIN_HAND, Collections.singletonList(fakePlayer.getMainHandItem())); InventoryUtils.tryRemoveStackFromItemHandler(worker.getInventoryCitizen(), new ItemStack(Items.BOWL)); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkRabbitHerder.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkRabbitHerder.java index e7397b289fe..2125199c9e4 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkRabbitHerder.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkRabbitHerder.java @@ -3,6 +3,7 @@ import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingRabbitHutch; import com.minecolonies.core.colony.jobs.JobRabbitHerder; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.world.InteractionHand; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.animal.Animal; @@ -61,7 +62,7 @@ protected void butcherAnimal(@Nullable final Animal animal) { final DamageSource ds = animal.level.damageSources().playerAttack(getFakePlayer()); animal.hurt(ds, (float) getButcheringAttackDamage()); - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); } } } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkShepherd.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkShepherd.java index 439eba3cae8..c1b738f5957 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkShepherd.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkShepherd.java @@ -8,6 +8,7 @@ import com.minecolonies.core.Network; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingShepherd; import com.minecolonies.core.colony.jobs.JobShepherd; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.network.messages.client.LocalizedParticleEffectMessage; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.InteractionHand; @@ -149,7 +150,7 @@ private IAIState shearSheep() Network.getNetwork().sendToTrackingEntity(new LocalizedParticleEffectMessage(new ItemStack(ITEM_BY_DYE.get(sheep.getColor())), sheep.getOnPos().above()), worker); dyeSheepChance(sheep); - worker.getCitizenItemHandler().damageItemInHand(InteractionHand.MAIN_HAND, 1); + CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); worker.getCitizenExperienceHandler().addExperience(XP_PER_ACTION); incrementActionsDoneAndDecSaturation(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkDeliveryman.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkDeliveryman.java index 09fbf366b2a..7305fba6c78 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkDeliveryman.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkDeliveryman.java @@ -13,6 +13,7 @@ import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; import com.minecolonies.api.tileentities.AbstractTileEntityColonyBuilding; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.tileentities.TileEntityColonyBuilding; import com.minecolonies.core.tileentities.TileEntityRack; import com.minecolonies.api.util.InventoryUtils; @@ -253,7 +254,7 @@ private boolean pickupFromBuilding(@NotNull final IBuilding building) // The worker gets a little bit of exp for every itemstack he grabs. worker.getCitizenExperienceHandler().addExperience(0.01D); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, SLOT_HAND); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, SLOT_HAND); return false; } @@ -304,7 +305,7 @@ private IAIState dump() } warehouse.getTileEntity().dumpInventoryIntoWareHouse(worker.getInventoryCitizen()); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, SLOT_HAND); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, SLOT_HAND); return START_WORKING; } @@ -450,7 +451,7 @@ private IAIState deliver() // This can only happen if the dman's inventory was completely empty. // Let the retry-system handle this case. worker.decreaseSaturationForContinuousAction(); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, SLOT_HAND); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, SLOT_HAND); job.finishRequest(false); // No need to go dumping in this case. @@ -459,7 +460,7 @@ private IAIState deliver() worker.getCitizenExperienceHandler().addExperience(1.5D); worker.decreaseSaturationForContinuousAction(); - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, SLOT_HAND); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, SLOT_HAND); job.finishRequest(true); return success ? START_WORKING : DUMPING; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkUndertaker.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkUndertaker.java index 3869a78df89..0fa07fab0fc 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkUndertaker.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkUndertaker.java @@ -9,6 +9,7 @@ import com.minecolonies.api.entity.citizen.Skill; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; import com.minecolonies.api.equipment.ModEquipmentTypes; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.tileentities.TileEntityGrave; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.api.util.MessageUtils; @@ -451,7 +452,7 @@ private IAIState buryCitizen() if (effortCounter < EFFORT_BURY) { equipShovel(); - worker.getCitizenItemHandler().hitBlockWithToolInHand(burialPos.getA(), false); + CitizenItemUtils.hitBlockWithToolInHand(worker, burialPos.getA(), false); effortCounter += getPrimarySkillLevel(); return getState(); } @@ -490,7 +491,7 @@ protected boolean wantInventoryDumped() */ private void equipShovel() { - worker.getCitizenItemHandler().setHeldItem(InteractionHand.MAIN_HAND, getShovelSlot()); + CitizenItemUtils.setHeldItem(worker, InteractionHand.MAIN_HAND, getShovelSlot()); } /** @@ -498,7 +499,7 @@ private void equipShovel() */ private void unequip() { - worker.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(worker); } /** diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index dd744f09782..d470d5d877e 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -64,6 +64,7 @@ import com.minecolonies.core.network.messages.client.colony.ColonyViewCitizenViewMessage; import com.minecolonies.core.network.messages.client.colony.PlaySoundForCitizenMessage; import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.util.TeleportHelper; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -84,7 +85,6 @@ import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.*; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Inventory; @@ -133,10 +133,6 @@ @SuppressWarnings({"PMD.ExcessiveImports", "PMD.CouplingBetweenObjects", "PMD.ExcessiveClassLength"}) public class EntityCitizen extends AbstractEntityCitizen implements IThreatTableEntity { - private static final UUID SLOW_FALLING_ID = UUID.fromString("A5B6CF2A-2F7C-31EF-9022-7C3E7D5E6ABA"); - private static final AttributeModifier SLOW_FALLING = new AttributeModifier(SLOW_FALLING_ID, "Slow falling acceleration reduction", -0.07, AttributeModifier.Operation.ADDITION); // Add -0.07 to 0.08 so we get the vanilla default of 0.01 - - /** * Cooldown for calling help, in ticks. */ @@ -167,10 +163,7 @@ public class EntityCitizen extends AbstractEntityCitizen implements IThreatTable * The citizen experience handler. */ private ICitizenExperienceHandler citizenExperienceHandler; - /** - * The citizen item handler. - */ - private ICitizenItemHandler citizenItemHandler; + /** * The citizen inv handler. */ @@ -264,7 +257,6 @@ public EntityCitizen(final EntityType type, final Level this.goalSelector = new CustomGoalSelector(this.goalSelector); this.targetSelector = new CustomGoalSelector(this.targetSelector); this.citizenExperienceHandler = new CitizenExperienceHandler(this); - this.citizenItemHandler = new CitizenItemHandler(this); this.citizenInventoryHandler = new CitizenInventoryHandler(this); this.citizenColonyHandler = new CitizenColonyHandler(this); this.citizenJobHandler = new CitizenJobHandler(this); @@ -762,7 +754,7 @@ private boolean onServerUpdateHandlers() { // Every 20 ticks citizenExperienceHandler.gatherXp(); - citizenItemHandler.pickupItems(); + CitizenItemUtils.pickupItems(this); citizenData.setLastPosition(blockPosition()); onLivingSoundUpdate(); @@ -1173,17 +1165,6 @@ public ICitizenExperienceHandler getCitizenExperienceHandler() return citizenExperienceHandler; } - /** - * The Handler for all item related methods. - * - * @return the instance of the handler. - */ - @Override - public ICitizenItemHandler getCitizenItemHandler() - { - return citizenItemHandler; - } - /** * The Handler for all inventory related methods. * @@ -1283,12 +1264,6 @@ public void setCitizenJobHandler(final ICitizenJobHandler citizenJobHandler) this.citizenJobHandler = citizenJobHandler; } - @Override - public void setCitizenItemHandler(final ICitizenItemHandler citizenItemHandler) - { - this.citizenItemHandler = citizenItemHandler; - } - @Override public void setCitizenExperienceHandler(final ICitizenExperienceHandler citizenExperienceHandler) { @@ -1473,7 +1448,7 @@ && getHealth() < ((int) getMaxHealth() * 0.2D)) if (!level.isClientSide) { - citizenItemHandler.updateArmorDamage(damageInc); + CitizenItemUtils.updateArmorDamage(this, damageInc); if (citizenData != null) { getCitizenData().getCitizenHappinessHandler().addModifier(new ExpirationBasedHappinessModifier(DAMAGE, 2.0, new StaticHappinessSupplier(0.0), 1)); @@ -1686,7 +1661,7 @@ protected void dropEquipment() final ItemStack itemstack = getCitizenData().getInventory().getStackInSlot(i); if (ItemStackUtils.getSize(itemstack) > 0) { - citizenItemHandler.entityDropItem(itemstack); + CitizenItemUtils.entityDropItem(this, itemstack); } } } @@ -1755,7 +1730,7 @@ protected void hurtCurrentlyUsedShield(final float damage) (float) this.getAttribute(Attributes.ARMOR_TOUGHNESS).getValue()); setHealth(getHealth() - Math.max(GUARD_BLOCK_DAMAGE, blockDamage)); } - citizenItemHandler.damageItemInHand(this.getUsedItemHand(), (int) (damage * GUARD_BLOCK_DAMAGE)); + CitizenItemUtils.damageItemInHand(this, this.getUsedItemHand(), (int) (damage * GUARD_BLOCK_DAMAGE)); } super.hurtCurrentlyUsedShield(damage); } diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenExperienceHandler.java b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenExperienceHandler.java index 54913b566de..5cb553f4569 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenExperienceHandler.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenExperienceHandler.java @@ -8,6 +8,7 @@ import com.minecolonies.api.util.CompatibilityUtils; import com.minecolonies.api.util.WorldUtil; import com.minecolonies.core.colony.buildings.modules.WorkerBuildingModule; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ExperienceOrb; @@ -190,7 +191,7 @@ public void gatherXp() if (d1 < 1.0D) { double localXp = orb.getValue(); - localXp = citizen.getCitizenItemHandler().applyMending(localXp); + localXp = CitizenItemUtils.applyMending(citizen, localXp); addExperience(localXp); orb.remove(Entity.RemovalReason.DISCARDED); counterMovedXp = 0; @@ -198,7 +199,7 @@ public void gatherXp() else if (counterMovedXp > MAX_XP_PICKUP_ATTEMPTS) { double localXp = orb.getValue(); - localXp = citizen.getCitizenItemHandler().applyMending(localXp); + localXp = CitizenItemUtils.applyMending(citizen, localXp); addExperience(localXp); orb.remove(Entity.RemovalReason.DISCARDED); counterMovedXp = 0; diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenSleepHandler.java b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenSleepHandler.java index 0fe0fa4b38f..60d54b1a081 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenSleepHandler.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenSleepHandler.java @@ -10,6 +10,7 @@ import com.minecolonies.core.colony.interactionhandling.SimpleNotificationInteraction; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobMiner; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; @@ -120,7 +121,7 @@ public boolean trySleep(final BlockPos bedLocation) citizen.hasImpulse = true; //Remove item while citizen is asleep. - citizen.getCitizenItemHandler().removeHeldItem(); + CitizenItemUtils.removeHeldItem(citizen); setIsAsleep(true); diff --git a/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java b/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java index 6005cb8d9c6..7b5745b1487 100644 --- a/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java @@ -29,6 +29,7 @@ import com.minecolonies.core.entity.pathfinding.proxy.EntityCitizenWalkToProxy; import com.minecolonies.core.network.messages.client.ItemParticleEffectMessage; import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -87,10 +88,6 @@ public class VisitorCitizen extends AbstractEntityCitizen @Nullable private ICitizenData citizenData; - /** - * The citizen item handler. - */ - private ICitizenItemHandler citizenItemHandler; /** * The citizen inv handler. */ @@ -129,9 +126,6 @@ public class VisitorCitizen extends AbstractEntityCitizen public VisitorCitizen(final EntityType type, final Level world) { super(type, world); - this.goalSelector = new CustomGoalSelector(this.goalSelector); - this.targetSelector = new CustomGoalSelector(this.targetSelector); - this.citizenItemHandler = new CitizenItemHandler(this); this.citizenInventoryHandler = new CitizenInventoryHandler(this); this.citizenColonyHandler = new VisitorColonyHandler(this); this.citizenJobHandler = new CitizenJobHandler(this); @@ -346,12 +340,6 @@ public ICitizenExperienceHandler getCitizenExperienceHandler() return citizenExperienceHandler; } - @Override - public ICitizenItemHandler getCitizenItemHandler() - { - return citizenItemHandler; - } - @Override public ICitizenInventoryHandler getCitizenInventoryHandler() { @@ -418,12 +406,6 @@ public void setCitizenJobHandler(final ICitizenJobHandler citizenJobHandler) this.citizenJobHandler = citizenJobHandler; } - @Override - public void setCitizenItemHandler(final ICitizenItemHandler citizenItemHandler) - { - this.citizenItemHandler = citizenItemHandler; - } - @Override public void setCitizenExperienceHandler(final ICitizenExperienceHandler citizenExperienceHandler) { @@ -638,7 +620,7 @@ protected void dropEquipment() final ItemStack itemstack = getCitizenData().getInventory().getStackInSlot(i); if (ItemStackUtils.getSize(itemstack) > 0) { - citizenItemHandler.entityDropItem(itemstack); + CitizenItemUtils.entityDropItem(this, itemstack); } } } diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenItemHandler.java b/src/main/java/com/minecolonies/core/util/citizenutils/CitizenItemUtils.java similarity index 88% rename from src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenItemHandler.java rename to src/main/java/com/minecolonies/core/util/citizenutils/CitizenItemUtils.java index 0e33726b673..bbb7d584573 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenItemHandler.java +++ b/src/main/java/com/minecolonies/core/util/citizenutils/CitizenItemUtils.java @@ -1,7 +1,6 @@ -package com.minecolonies.core.entity.citizen.citizenhandlers; +package com.minecolonies.core.util.citizenutils; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenItemHandler; import com.minecolonies.api.util.*; import com.minecolonies.core.Network; import com.minecolonies.core.network.messages.client.BlockParticleEffectMessage; @@ -33,30 +32,14 @@ * Handles the citizens interaction with an item with the world. */ @SuppressWarnings("PMD.ExcessiveImports") -public class CitizenItemHandler implements ICitizenItemHandler +public class CitizenItemUtils { - /** - * The citizen assigned to this manager. - */ - private final AbstractEntityCitizen citizen; - - /** - * Constructor for the experience handler. - * - * @param citizen the citizen owning the handler. - */ - public CitizenItemHandler(final AbstractEntityCitizen citizen) - { - this.citizen = citizen; - } - /** * Citizen will try to pick up a certain item. * * @param itemEntity the item he wants to pickup. */ - @Override - public void tryPickupItemEntity(@NotNull final ItemEntity itemEntity) + public static void tryPickupItemEntity(@NotNull final AbstractEntityCitizen citizen, @NotNull final ItemEntity itemEntity) { if (!CompatibilityUtils.getWorldFromCitizen(citizen).isClientSide) { @@ -107,8 +90,7 @@ public void tryPickupItemEntity(@NotNull final ItemEntity itemEntity) /** * Removes the currently held item. */ - @Override - public void removeHeldItem() + public static void removeHeldItem(AbstractEntityCitizen citizen) { citizen.setItemSlot(EquipmentSlot.MAINHAND, ItemStackUtils.EMPTY); } @@ -119,8 +101,7 @@ public void removeHeldItem() * @param hand what hand we're setting * @param slot from the inventory slot. */ - @Override - public void setHeldItem(final InteractionHand hand, final int slot) + public static void setHeldItem(@NotNull final AbstractEntityCitizen citizen, final InteractionHand hand, final int slot) { citizen.getCitizenData().getInventory().setHeldItem(hand, slot); if (hand.equals(InteractionHand.MAIN_HAND)) @@ -138,8 +119,7 @@ else if (hand.equals(InteractionHand.OFF_HAND)) * * @param slot from the inventory slot. */ - @Override - public void setMainHeldItem(final int slot) + public static void setMainHeldItem(@NotNull final AbstractEntityCitizen citizen, final int slot) { citizen.getCitizenData().getInventory().setHeldItem(InteractionHand.MAIN_HAND, slot); citizen.setItemSlot(EquipmentSlot.MAINHAND, citizen.getCitizenData().getInventory().getStackInSlot(slot)); @@ -152,14 +132,13 @@ public void setMainHeldItem(final int slot) * * @param blockPos Block position. */ - @Override - public void hitBlockWithToolInHand(@Nullable final BlockPos blockPos) + public static void hitBlockWithToolInHand(@NotNull final AbstractEntityCitizen citizen, @Nullable final BlockPos blockPos) { if (blockPos == null) { return; } - hitBlockWithToolInHand(blockPos, false); + hitBlockWithToolInHand(citizen, blockPos, false); } /** @@ -170,8 +149,8 @@ public void hitBlockWithToolInHand(@Nullable final BlockPos blockPos) * @param blockPos Block position. * @param breakBlock if we want to break this block. */ - @Override - public void hitBlockWithToolInHand(@Nullable final BlockPos blockPos, final boolean breakBlock) + + public static void hitBlockWithToolInHand(@NotNull final AbstractEntityCitizen citizen, @Nullable final BlockPos blockPos, final boolean breakBlock) { if (blockPos == null) { @@ -201,7 +180,7 @@ public void hitBlockWithToolInHand(@Nullable final BlockPos blockPos, final bool block.getSoundType(blockState, CompatibilityUtils.getWorldFromCitizen(citizen), blockPos, citizen).getPitch() * 0.8F); WorldUtil.removeBlock(CompatibilityUtils.getWorldFromCitizen(citizen), blockPos, false); - damageItemInHand(citizen.getUsedItemHand(), 1); + damageItemInHand(citizen, citizen.getUsedItemHand(), 1); } else { @@ -229,8 +208,7 @@ public void hitBlockWithToolInHand(@Nullable final BlockPos blockPos, final bool * * @param damage amount of damage. */ - @Override - public void damageItemInHand(final InteractionHand hand, final int damage) + public static void damageItemInHand(@NotNull final AbstractEntityCitizen citizen, final InteractionHand hand, final int damage) { final ItemStack heldItem = citizen.getCitizenData().getInventory().getHeldItem(hand); //If we hit with bare hands, ignore @@ -271,8 +249,7 @@ public void damageItemInHand(final InteractionHand hand, final int damage) /** * Pick up all items in a range around the citizen. */ - @Override - public void pickupItems() + public static void pickupItems(AbstractEntityCitizen citizen) { for (final ItemEntity item : CompatibilityUtils.getWorldFromCitizen(citizen).getEntitiesOfClass(ItemEntity.class, new AABB(citizen.blockPosition()) @@ -281,7 +258,7 @@ public void pickupItems() { if (item != null && item.isAlive()) { - tryPickupItemEntity(item); + tryPickupItemEntity(citizen, item); } } } @@ -293,14 +270,13 @@ public void pickupItems() * * @param blockPos Block position. */ - @Override - public void breakBlockWithToolInHand(@Nullable final BlockPos blockPos) + public static void breakBlockWithToolInHand(@NotNull final AbstractEntityCitizen citizen, @Nullable final BlockPos blockPos) { if (blockPos == null) { return; } - hitBlockWithToolInHand(blockPos, true); + hitBlockWithToolInHand(citizen, blockPos, true); } /** @@ -309,8 +285,7 @@ public void breakBlockWithToolInHand(@Nullable final BlockPos blockPos) * @param itemstack to drop. * @return the dropped item. */ - @Override - public ItemEntity entityDropItem(@NotNull final ItemStack itemstack) + public static ItemEntity entityDropItem(@NotNull final AbstractEntityCitizen citizen, @NotNull final ItemStack itemstack) { return citizen.spawnAtLocation(itemstack, 0.0F); } @@ -320,8 +295,7 @@ public ItemEntity entityDropItem(@NotNull final ItemStack itemstack) * * @param damage damage dealt. */ - @Override - public void updateArmorDamage(final double damage) + public static void updateArmorDamage(@NotNull final AbstractEntityCitizen citizen, final double damage) { if (citizen.getCitizenColonyHandler().getColonyOrRegister().getResearchManager().getResearchEffects().getEffectStrength(ARMOR_DURABILITY) > 0) { @@ -348,8 +322,7 @@ public void updateArmorDamage(final double damage) } } - @Override - public double applyMending(final double xp) + public static double applyMending(@NotNull final AbstractEntityCitizen citizen, final double xp) { double localXp = xp; From 3f76f9651627fc98793a180456c7df0366ca3940 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Sun, 1 Dec 2024 13:36:26 +0100 Subject: [PATCH 09/33] Rework diseases to become datapacks (#10361) Diseases use datapacks in favor of configuration values Upgraded the RandomCollection introduced in Rework lucky ores to become datapacks #10343 to allow for key based values Improved code regarding diseases by using more up-to-date code --- .../compatibility/CompatibilityManager.java | 82 +------- .../compatibility/ICompatibilityManager.java | 23 --- .../configuration/ServerConfiguration.java | 7 - .../ICitizenDiseaseHandler.java | 13 +- .../container/ContainerCrafting.java | 2 +- .../com/minecolonies/api/util/Disease.java | 88 --------- .../InteractionValidatorInitializer.java | 2 +- .../workerbuildings/BuildingHospital.java | 42 ++-- .../core/datalistener/DiseasesListener.java | 187 ++++++++++++++++++ .../core/datalistener/model/Disease.java | 75 +++++++ .../entity/ai/minimal/EntityAISickTask.java | 42 ++-- .../workers/service/EntityAIWorkHealer.java | 61 +++--- .../core/entity/citizen/EntityCitizen.java | 14 +- .../CitizenDiseaseHandler.java | 51 +++-- .../core/event/DataPackSyncEventHandler.java | 2 + .../core/event/FMLEventHandler.java | 1 + .../core/network/NetworkChannel.java | 1 + .../colony/GlobalDiseaseSyncMessage.java | 72 +++++++ .../minecolonies/lang/manual_en_us.json | 6 +- .../colony/diseases/influenza.json | 14 ++ .../minecolonies/colony/diseases/measles.json | 18 ++ .../colony/diseases/smallpox.json | 14 ++ 22 files changed, 506 insertions(+), 311 deletions(-) delete mode 100755 src/main/java/com/minecolonies/api/util/Disease.java create mode 100644 src/main/java/com/minecolonies/core/datalistener/DiseasesListener.java create mode 100644 src/main/java/com/minecolonies/core/datalistener/model/Disease.java create mode 100644 src/main/java/com/minecolonies/core/network/messages/client/colony/GlobalDiseaseSyncMessage.java create mode 100644 src/main/resources/data/minecolonies/colony/diseases/influenza.json create mode 100644 src/main/resources/data/minecolonies/colony/diseases/measles.json create mode 100644 src/main/resources/data/minecolonies/colony/diseases/smallpox.json diff --git a/src/main/java/com/minecolonies/api/compatibility/CompatibilityManager.java b/src/main/java/com/minecolonies/api/compatibility/CompatibilityManager.java index 8b7d31ba345..568468247c8 100755 --- a/src/main/java/com/minecolonies/api/compatibility/CompatibilityManager.java +++ b/src/main/java/com/minecolonies/api/compatibility/CompatibilityManager.java @@ -112,14 +112,9 @@ public class CompatibilityManager implements ICompatibilityManager private ImmutableSet beekeeperflowers = ImmutableSet.of(); /** - * Set of all possible diseases. + * List of lucky oreBlocks which get dropped by the miner. */ - private final Map diseases = new HashMap<>(); - - /** - * List of diseases including the random factor. - */ - private final List diseaseList = new ArrayList<>(); + private final Map> luckyOres = new HashMap<>(); /** * The items and weights of the recruitment. @@ -170,8 +165,6 @@ private void clear() compostRecipes.clear(); recruitmentCostsWeights.clear(); - diseases.clear(); - diseaseList.clear(); monsters = ImmutableSet.of(); creativeModeTabMap.clear(); } @@ -188,7 +181,6 @@ public void discover(@NotNull final RecipeManager recipeManager, final Level lev discoverAllItems(level); discoverRecruitCosts(); - discoverDiseases(); discoverModCompat(); discoverCompostRecipes(recipeManager); @@ -243,7 +235,6 @@ public void deserialize(@NotNull final FriendlyByteBuf buf, final ClientLevel le // the below are loaded from config files, which have been synched already by this point discoverRecruitCosts(); - discoverDiseases(); discoverModCompat(); } @@ -460,24 +451,6 @@ public Set getImmutableFlowers() return beekeeperflowers; } - @Override - public String getRandomDisease() - { - return diseaseList.get(random.nextInt(diseaseList.size())); - } - - @Override - public Disease getDisease(final String disease) - { - return diseases.get(disease); - } - - @Override - public List getDiseases() - { - return new ArrayList<>(diseases.values()); - } - @Override public List> getRecruitmentCostsWeights() { @@ -802,57 +775,6 @@ private void discoverRecruitCosts() Log.getLogger().info("Finished discovering recruitment costs"); } - /** - * Go through the disease config and setup all possible diseases. - */ - private void discoverDiseases() - { - if (diseases.isEmpty()) - { - for (final String disease : MinecoloniesAPIProxy.getInstance().getConfig().getServer().diseases.get()) - { - final String[] split = disease.split(","); - if (split.length < 3) - { - Log.getLogger().warn("Wrongly configured disease: " + disease); - continue; - } - - try - { - final String name = split[0]; - final int rarity = Integer.parseInt(split[1]); - - final List cure = new ArrayList<>(); - - for (int i = 2; i < split.length; i++) - { - final String[] theItem = split[i].split(":"); - final Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(theItem[0], theItem[1])); - if (item == null || item == Items.AIR) - { - Log.getLogger().warn("Invalid cure item: " + disease); - continue; - } - - final ItemStack stack = new ItemStack(item, 1); - cure.add(stack); - } - diseases.put(name, new Disease(name, rarity, cure)); - for (int i = 0; i < rarity; i++) - { - diseaseList.add(name); - } - } - catch (final NumberFormatException e) - { - Log.getLogger().warn("Wrongly configured disease: " + disease); - } - } - } - Log.getLogger().info("Finished discovering diseases"); - } - private static CompoundTag writeLeafSaplingEntryToNBT(final BlockState state, final ItemStorage storage) { final CompoundTag compound = NbtUtils.writeBlockState(state); diff --git a/src/main/java/com/minecolonies/api/compatibility/ICompatibilityManager.java b/src/main/java/com/minecolonies/api/compatibility/ICompatibilityManager.java index 1f3604acdc3..2fcf7009685 100755 --- a/src/main/java/com/minecolonies/api/compatibility/ICompatibilityManager.java +++ b/src/main/java/com/minecolonies/api/compatibility/ICompatibilityManager.java @@ -3,7 +3,6 @@ import com.google.common.collect.ImmutableSet; import com.minecolonies.api.crafting.CompostRecipe; import com.minecolonies.api.crafting.ItemStorage; -import com.minecolonies.api.util.Disease; import com.minecolonies.api.util.Tuple; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.nbt.CompoundTag; @@ -139,28 +138,6 @@ public interface ICompatibilityManager */ ImmutableSet getAllMonsters(); - /** - * Get a random disease of the compat manager. - * - * @return a randomly chosen disease. - */ - String getRandomDisease(); - - /** - * Get a disease by the ID. - * - * @param disease the id. - * @return the disease. - */ - Disease getDisease(String disease); - - /** - * Get the list of diseases. - * - * @return a copy of the list. - */ - List getDiseases(); - /** * Gets the list of recruitment costs with weights * diff --git a/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java b/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java index f4dc578a01d..3d33f5ee439 100755 --- a/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java +++ b/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java @@ -97,7 +97,6 @@ public class ServerConfiguration extends AbstractConfiguration * -------------------------------------------------------------------------------- */ public final ForgeConfigSpec.ConfigValue> configListRecruitmentItems; - public final ForgeConfigSpec.ConfigValue> diseases; public final ForgeConfigSpec.BooleanValue auditCraftingTags; public final ForgeConfigSpec.BooleanValue debugInventories; public final ForgeConfigSpec.BooleanValue blueprintBuildMode; @@ -208,12 +207,6 @@ protected ServerConfiguration(final ForgeConfigSpec.Builder builder) "minecraft:quartz;3"), s -> s instanceof String); - diseases = defineList(builder, "diseases", - Arrays.asList("Influenza,100,minecraft:carrot,minecraft:potato", - "Measles,10,minecraft:dandelion,minecraft:kelp,minecraft:poppy", - "Smallpox,1,minecraft:honey_bottle,minecraft:golden_apple"), - s -> s instanceof String); - auditCraftingTags = defineBoolean(builder, "auditcraftingtags", false); debugInventories = defineBoolean(builder, "debuginventories", false); blueprintBuildMode = defineBoolean(builder, "blueprintbuildmode", false); diff --git a/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenDiseaseHandler.java b/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenDiseaseHandler.java index 20a2815e97f..d8811f35aae 100755 --- a/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenDiseaseHandler.java +++ b/src/main/java/com/minecolonies/api/entity/citizen/citizenhandlers/ICitizenDiseaseHandler.java @@ -1,7 +1,9 @@ package com.minecolonies.api.entity.citizen.citizenhandlers; +import com.minecolonies.core.datalistener.model.Disease; import com.minecolonies.api.colony.ICitizenData; import net.minecraft.nbt.CompoundTag; +import org.jetbrains.annotations.Nullable; /** * Citizen disease handler interface. @@ -35,11 +37,12 @@ public interface ICitizenDiseaseHandler void read(final CompoundTag compound); /** - * get the disease identifier. + * Get the current disease, if any. * - * @return the disease identifier. + * @return the disease instance. */ - String getDisease(); + @Nullable + Disease getDisease(); /** * Cure the citizen. @@ -70,7 +73,9 @@ public interface ICitizenDiseaseHandler /** * Set a disease on the citizen. + * * @param disease to set. + * @return true if they actually became sick. */ - void setDisease(String disease); + boolean setDisease(Disease disease); } diff --git a/src/main/java/com/minecolonies/api/inventory/container/ContainerCrafting.java b/src/main/java/com/minecolonies/api/inventory/container/ContainerCrafting.java index 2a67a2d5baa..60b42cffe10 100755 --- a/src/main/java/com/minecolonies/api/inventory/container/ContainerCrafting.java +++ b/src/main/java/com/minecolonies/api/inventory/container/ContainerCrafting.java @@ -416,7 +416,7 @@ public BlockPos getPos() } /** - * Get for the remaining items. + * Get for the remaining items. * @return */ public List getRemainingItems() diff --git a/src/main/java/com/minecolonies/api/util/Disease.java b/src/main/java/com/minecolonies/api/util/Disease.java deleted file mode 100755 index 19a6d5436f8..00000000000 --- a/src/main/java/com/minecolonies/api/util/Disease.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.minecolonies.api.util; - -import com.google.common.collect.ImmutableList; -import net.minecraft.world.item.ItemStack; - -import java.util.List; - -/** - * Disease storage class. - */ -public class Disease -{ - /** - * The name string. - */ - private final String name; - - /** - * The rarity modifier. - */ - private final int rarity; - - /** - * The cure. - */ - private final List cure; - - /** - * Create a disease. - * - * @param name the name of it. - * @param rarity its rarity. - * @param cure the cure. - */ - public Disease(final String name, final int rarity, final List cure) - { - this.name = name; - this.rarity = rarity; - this.cure = cure; - } - - /** - * Get the name of the disease. - * - * @return the name. - */ - public String getName() - { - return name; - } - - /** - * Get the rarity modifier of the disease. - * - * @return the rarity. - */ - public int getRarity() - { - return rarity; - } - - /** - * Get the cure list. - * - * @return the cure. - */ - public List getCure() - { - return ImmutableList.copyOf(cure); - } - - /** - * The Cure String. - * - * @return the cure string. - */ - public String getCureString() - { - StringBuilder cureString = new StringBuilder(); - for (final ItemStack cureStack : cure) - { - cureString.append(cureStack.getHoverName().getString()); - cureString.append("+"); - } - cureString.deleteCharAt(cureString.length() - 1); - return cureString.toString(); - } -} diff --git a/src/main/java/com/minecolonies/apiimp/initializer/InteractionValidatorInitializer.java b/src/main/java/com/minecolonies/apiimp/initializer/InteractionValidatorInitializer.java index 7900d7f2072..61b4d86329c 100755 --- a/src/main/java/com/minecolonies/apiimp/initializer/InteractionValidatorInitializer.java +++ b/src/main/java/com/minecolonies/apiimp/initializer/InteractionValidatorInitializer.java @@ -71,7 +71,7 @@ public static void init() citizen -> citizen.getColony() != null && citizen.getEntity().isPresent() && citizen.getCitizenDiseaseHandler().isSick() && citizen.getColony().getBuildingManager().getBestBuilding(citizen.getEntity().get(), BuildingHospital.class) == null); InteractionValidatorRegistry.registerStandardPredicate(Component.translatable(WAITING_FOR_CURE), - citizen -> citizen.getColony() != null && citizen.getEntity().isPresent() && !citizen.getCitizenDiseaseHandler().getDisease().isEmpty()); + citizen -> citizen.getColony() != null && citizen.getEntity().isPresent() && citizen.getCitizenDiseaseHandler().getDisease() != null); InteractionValidatorRegistry.registerPosBasedPredicate(Component.translatable(COM_MINECOLONIES_COREMOD_JOB_DELIVERYMAN_CHESTFULL), (citizen, pos) -> diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingHospital.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingHospital.java index 5996fd631eb..37b6ca4f4f2 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingHospital.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingHospital.java @@ -3,11 +3,12 @@ import com.google.common.collect.ImmutableList; import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.IColony; -import com.minecolonies.api.colony.IColonyManager; +import com.minecolonies.api.crafting.ItemStorage; import com.minecolonies.api.util.BlockPosUtil; -import com.minecolonies.api.util.Disease; import com.minecolonies.api.util.constant.NbtTagConstants; import com.minecolonies.core.colony.buildings.AbstractBuilding; +import com.minecolonies.core.datalistener.model.Disease; +import com.minecolonies.core.datalistener.DiseasesListener; import com.minecolonies.core.entity.ai.workers.util.Patient; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -196,35 +197,23 @@ public void removePatientFile(final Patient patient) public Map, Tuple> getRequiredItemsAndAmount() { final Map, Tuple> map = super.getRequiredItemsAndAmount(); - map.put(this::doesAnyPatientRequireStack, new Tuple<>(10, false)); + map.put(BuildingHospital::isCureItem, new Tuple<>(10, false)); return map; } /** - * Check if any patient requires this. + * Check if the given itemstack is a cure item. * * @param stack the stack to test. * @return true if so. */ - private boolean doesAnyPatientRequireStack(final ItemStack stack) + private static boolean isCureItem(final ItemStack stack) { - for (final Patient patient : patients.values()) + for (final Disease disease : DiseasesListener.getDiseases()) { - final ICitizenData data = colony.getCitizenManager().getCivilian(patient.getId()); - if (data != null && data.getEntity().isPresent() && data.getCitizenDiseaseHandler().isSick()) + for (final ItemStorage cureItem : disease.cureItems()) { - final String diseaseName = data.getCitizenDiseaseHandler().getDisease(); - if (!diseaseName.isEmpty()) - { - final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName); - for (final ItemStack cure : disease.getCure()) - { - if (ItemStack.isSameItem(cure, stack)) - { - return true; - } - } - } + return Disease.isCureItem(stack, cureItem); } } return false; @@ -297,8 +286,7 @@ else if (entry.getValue() != 0) { if (state.getValue(BedBlock.OCCUPIED)) { - if (!citizen.isAsleep() || !citizen.getEntity().isPresent() - || citizen.getEntity().get().blockPosition().distSqr(entry.getKey()) > 2.0) + if (!citizen.isAsleep() || citizen.getEntity().isEmpty() || citizen.getEntity().get().blockPosition().distSqr(entry.getKey()) > 2.0) { setBedOccupation(entry.getKey(), false); bedMap.put(entry.getKey(), 0); @@ -328,15 +316,9 @@ else if (entry.getValue() != 0) @Override public boolean canEat(final ItemStack stack) { - for (final Disease disease : IColonyManager.getInstance().getCompatibilityManager().getDiseases()) + if (isCureItem(stack)) { - for (final ItemStack cure : disease.getCure()) - { - if (ItemStack.isSameItem(cure, stack)) - { - return false; - } - } + return false; } return super.canEat(stack); diff --git a/src/main/java/com/minecolonies/core/datalistener/DiseasesListener.java b/src/main/java/com/minecolonies/core/datalistener/DiseasesListener.java new file mode 100644 index 00000000000..1610eef22ea --- /dev/null +++ b/src/main/java/com/minecolonies/core/datalistener/DiseasesListener.java @@ -0,0 +1,187 @@ +package com.minecolonies.core.datalistener; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.minecolonies.api.colony.requestsystem.StandardFactoryController; +import com.minecolonies.api.crafting.ItemStorage; +import com.minecolonies.core.Network; +import com.minecolonies.core.datalistener.model.Disease; +import com.minecolonies.core.network.messages.client.colony.GlobalDiseaseSyncMessage; +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; +import net.minecraft.util.GsonHelper; +import net.minecraft.util.RandomSource; +import net.minecraft.util.profiling.ProfilerFiller; +import net.minecraft.util.random.WeightedRandomList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Loads and listens to diseases data. + */ +public class DiseasesListener extends SimpleJsonResourceReloadListener +{ + /** + * Gson instance + */ + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); + + /** + * Json constants + */ + private static final String KEY_NAME = "name"; + private static final String KEY_RARITY = "rarity"; + private static final String KEY_ITEMS = "items"; + + /** + * The map of diseases. + */ + private static WeightedRandomList DISEASES = WeightedRandomList.create(); + + /** + * Default constructor. + */ + public DiseasesListener() + { + super(GSON, "colony/diseases"); + } + + /** + * Sync to client. + * + * @param player to send it to. + */ + public static void sendGlobalDiseasesPackets(final ServerPlayer player) + { + final FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer()); + byteBuf.writeInt(DISEASES.unwrap().size()); + for (final Disease disease : DISEASES.unwrap()) + { + byteBuf.writeResourceLocation(disease.id()); + byteBuf.writeComponent(disease.name()); + byteBuf.writeInt(disease.rarity()); + for (final ItemStorage cureItem : disease.cureItems()) + { + StandardFactoryController.getInstance().serialize(byteBuf, cureItem); + } + } + Network.getNetwork().sendToPlayer(new GlobalDiseaseSyncMessage(byteBuf), player); + } + + /** + * Read the data from the packet and parse it. + * + * @param byteBuf pck. + */ + public static void readGlobalDiseasesPackets(final FriendlyByteBuf byteBuf) + { + final List newDiseases = new ArrayList<>(); + final int size = byteBuf.readInt(); + for (int i = 0; i < size; i++) + { + final ResourceLocation id = byteBuf.readResourceLocation(); + final Component name = byteBuf.readComponent(); + final int rarity = byteBuf.readInt(); + + final List cureItems = new ArrayList<>(); + final int itemCount = byteBuf.readInt(); + for (int j = 0; j < itemCount; j++) + { + cureItems.add(StandardFactoryController.getInstance().deserialize(byteBuf)); + } + + newDiseases.add(new Disease(id, name, rarity, cureItems)); + } + DISEASES = WeightedRandomList.create(newDiseases); + } + + /** + * Get a collection of all possible diseases. + * + * @return the collection of diseases. + */ + @NotNull + public static List getDiseases() + { + return DISEASES.unwrap(); + } + + /** + * Get a specific disease by id. + * + * @param id the disease id. + * @return the disease instance or null if it does not exist. + */ + @Nullable + public static Disease getDisease(final ResourceLocation id) + { + for (final Disease disease : DISEASES.unwrap()) + { + if (disease.id().equals(id)) + { + return disease; + } + } + return null; + } + + /** + * Get a random disease from the list of diseases. + * + * @param random the input random source. + * @return the random disease instance or null if no diseases exist. + */ + @Nullable + public static Disease getRandomDisease(final RandomSource random) + { + return DISEASES.getRandom(random).orElse(null); + } + + @Override + protected void apply( + final @NotNull Map jsonElementMap, + final @NotNull ResourceManager resourceManager, + final @NotNull ProfilerFiller profiler) + { + final List diseases = new ArrayList<>(); + for (final Map.Entry entry : jsonElementMap.entrySet()) + { + if (!entry.getValue().isJsonObject()) + { + return; + } + + final JsonObject object = entry.getValue().getAsJsonObject(); + final Component name = Component.translatable(GsonHelper.getAsString(object, KEY_NAME)); + final int rarity = GsonHelper.getAsInt(object, KEY_RARITY); + final List cureItems = new ArrayList<>(); + for (final JsonElement jsonElement : object.getAsJsonArray(KEY_ITEMS)) + { + if (!jsonElement.isJsonObject()) + { + continue; + } + + final ItemStorage cureItem = new ItemStorage(jsonElement.getAsJsonObject()); + // TODO: Apparently the healing doesn't fully work yet with multi-count cure items + // for the sake of compatibility for now, revert the count to 1 despite what's in the JSON. + cureItem.setAmount(1); + cureItems.add(cureItem); + } + + diseases.add(new Disease(entry.getKey(), name, rarity, cureItems)); + } + DISEASES = WeightedRandomList.create(diseases); + } +} diff --git a/src/main/java/com/minecolonies/core/datalistener/model/Disease.java b/src/main/java/com/minecolonies/core/datalistener/model/Disease.java new file mode 100644 index 00000000000..6a9868bf9b7 --- /dev/null +++ b/src/main/java/com/minecolonies/core/datalistener/model/Disease.java @@ -0,0 +1,75 @@ +package com.minecolonies.core.datalistener.model; + +import com.minecolonies.api.crafting.ItemStorage; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.random.Weight; +import net.minecraft.util.random.WeightedEntry; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * A possible disease. + * + * @param id the id of the disease. + * @param name the name of the disease. + * @param rarity the rarity of the disease. + * @param cureItems the list of items needed to heal. + */ +public record Disease(ResourceLocation id, Component name, int rarity, List cureItems) implements WeightedEntry +{ + /** + * Predicate for the different usages to check if inventory contains a cure. + * + * @param cure the expected cure item. + * @return the predicate for checking if the cure exists. + */ + public static Predicate hasCureItem(final ItemStorage cure) + { + return stack -> isCureItem(stack, cure); + } + + /** + * Check if the given item is a cure item. + * + * @param stack the input stack. + * @param cure the cure item. + * @return true if so. + */ + public static boolean isCureItem(final ItemStack stack, final ItemStorage cure) + { + return Objects.equals(new ItemStorage(stack), cure); + } + + /** + * Get the cure string containing all items required for the cure. + * + * @return the cure string. + */ + public Component getCureString() + { + final MutableComponent cureString = Component.literal(""); + for (int i = 0; i < cureItems.size(); i++) + { + final ItemStorage cureStack = cureItems.get(i); + cureString.append(String.valueOf(cureStack.getItemStack().getCount())).append(" ").append(cureStack.getItemStack().getHoverName()); + if (i != cureItems.size() - 1) + { + cureString.append(" + "); + } + } + return cureString; + } + + @Override + @NotNull + public Weight getWeight() + { + return Weight.of(rarity); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java index 581ea8ff195..842246b6eed 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java @@ -2,21 +2,22 @@ import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.IColony; -import com.minecolonies.api.colony.IColonyManager; import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.colony.interactionhandling.ChatPriority; +import com.minecolonies.api.crafting.ItemStorage; import com.minecolonies.api.entity.ai.IStateAI; import com.minecolonies.api.entity.ai.statemachine.states.CitizenAIState; import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; import com.minecolonies.api.util.BlockPosUtil; -import com.minecolonies.api.util.Disease; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.core.Network; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingHospital; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; +import com.minecolonies.core.datalistener.DiseasesListener; +import com.minecolonies.core.datalistener.model.Disease; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.network.messages.client.CircleParticleEffectMessage; import net.minecraft.core.BlockPos; @@ -245,10 +246,16 @@ private IState applyCure() return CHECK_FOR_CURE; } - final List list = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenData().getCitizenDiseaseHandler().getDisease()).getCure(); + final Disease disease = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); + if (disease == null) + { + return CitizenAIState.IDLE; + } + + final List list = disease.cureItems(); if (!list.isEmpty()) { - citizen.setItemInHand(InteractionHand.MAIN_HAND, list.get(citizen.getRandom().nextInt(list.size()))); + citizen.setItemInHand(InteractionHand.MAIN_HAND, list.get(citizen.getRandom().nextInt(list.size())).getItemStack()); } citizen.swing(InteractionHand.MAIN_HAND); @@ -275,12 +282,12 @@ private IState applyCure() */ private void cure() { - final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenData().getCitizenDiseaseHandler().getDisease()); + final Disease disease = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); if (disease != null) { - for (final ItemStack cure : disease.getCure()) + for (final ItemStorage cure : disease.cureItems()) { - final int slot = InventoryUtils.findFirstSlotInProviderNotEmptyWith(citizen, stack -> ItemStack.isSameItem(cure, stack)); + final int slot = InventoryUtils.findFirstSlotInProviderNotEmptyWith(citizen, Disease.hasCureItem(cure)); if (slot != -1) { citizenData.getInventory().extractItem(slot, 1, false); @@ -411,25 +418,23 @@ private IState goToHospital() private IState searchHospital() { final IColony colony = citizenData.getColony(); + final Disease disease = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); placeToPath = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class); if (placeToPath == null) { - final String id = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); - if (id.isEmpty()) + if (disease == null) { return CitizenAIState.IDLE; } - final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(id); - citizenData.triggerInteraction(new StandardInteraction(Component.translatable(NO_HOSPITAL, disease.getName(), disease.getCureString()), + citizenData.triggerInteraction(new StandardInteraction(Component.translatable(NO_HOSPITAL, disease.name(), disease.getCureString()), Component.translatable(NO_HOSPITAL), ChatPriority.BLOCKING)); return WANDER; } - else if (!citizen.getCitizenData().getCitizenDiseaseHandler().getDisease().isEmpty()) + else if (disease != null) { - final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(citizen.getCitizenData().getCitizenDiseaseHandler().getDisease()); - citizenData.triggerInteraction(new StandardInteraction(Component.translatable(WAITING_FOR_CURE, disease.getName(), disease.getCureString()), + citizenData.triggerInteraction(new StandardInteraction(Component.translatable(WAITING_FOR_CURE, disease.name(), disease.getCureString()), Component.translatable(WAITING_FOR_CURE), ChatPriority.BLOCKING)); } @@ -444,8 +449,8 @@ else if (!citizen.getCitizenData().getCitizenDiseaseHandler().getDisease().isEmp */ private IState checkForCure() { - final String id = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); - if (id.isEmpty()) + final Disease disease = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); + if (disease == null) { if (citizen.getHealth() > SEEK_DOCTOR_HEALTH) { @@ -454,10 +459,9 @@ private IState checkForCure() } return GO_TO_HUT; } - final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(id); - for (final ItemStack cure : disease.getCure()) + for (final ItemStorage cure : disease.cureItems()) { - final int slot = InventoryUtils.findFirstSlotInProviderNotEmptyWith(citizen, stack -> ItemStack.isSameItem(cure, stack)); + final int slot = InventoryUtils.findFirstSlotInProviderNotEmptyWith(citizen, Disease.hasCureItem(cure)); if (slot == -1) { if (citizen.getCitizenData().getCitizenDiseaseHandler().isSick()) diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java index 50ed8f1f2e0..0528966f01b 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java @@ -3,10 +3,10 @@ import com.google.common.collect.ImmutableList; import com.google.common.reflect.TypeToken; import com.minecolonies.api.colony.ICitizenData; -import com.minecolonies.api.colony.IColonyManager; import com.minecolonies.api.colony.interactionhandling.ChatPriority; import com.minecolonies.api.colony.requestsystem.request.IRequest; import com.minecolonies.api.colony.requestsystem.requestable.Stack; +import com.minecolonies.api.crafting.ItemStorage; import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; @@ -15,19 +15,18 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingHospital; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobHealer; +import com.minecolonies.core.datalistener.model.Disease; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; import com.minecolonies.core.entity.ai.workers.util.Patient; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.network.messages.client.CircleParticleEffectMessage; import com.minecolonies.core.network.messages.client.StreamParticleEffectMessage; +import net.minecraft.world.entity.player.Player; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; import static com.minecolonies.api.util.constant.TranslationConstants.PATIENT_FULL_INVENTORY; @@ -124,8 +123,7 @@ private IAIState decide() continue; } final EntityCitizen citizen = (EntityCitizen) data.getEntity().get(); - final String diseaseName = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); - @Nullable final Disease disease = diseaseName.isEmpty() ? null : IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName); + final Disease disease = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); if (patient.getState() == Patient.PatientState.NEW) { @@ -158,20 +156,20 @@ private IAIState decide() final ImmutableList> list = building.getOpenRequestsOfType(worker.getCitizenData().getId(), TypeToken.of(Stack.class)); final ImmutableList> completed = building.getCompletedRequestsOfType(worker.getCitizenData(), TypeToken.of(Stack.class)); - for (final ItemStack cure : IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName).getCure()) + for (final ItemStorage cure : disease.cureItems()) { - if (!InventoryUtils.hasItemInItemHandler(worker.getInventoryCitizen(), stack -> ItemStack.isSameItem(cure, stack))) + if (!InventoryUtils.hasItemInItemHandler(worker.getInventoryCitizen(), Disease.hasCureItem(cure))) { if (InventoryUtils.getItemCountInItemHandler(building.getCapability(ForgeCapabilities.ITEM_HANDLER).orElseGet(null), - stack -> ItemStack.isSameItem(stack, cure)) >= cure.getCount()) + Disease.hasCureItem(cure)) >= cure.getAmount()) { - needsCurrently = new Tuple<>(stack -> ItemStack.isSameItem(stack, cure), cure.getCount()); + needsCurrently = new Tuple<>(Disease.hasCureItem(cure), cure.getAmount()); return GATHERING_REQUIRED_MATERIALS; } boolean hasCureRequested = false; for (final IRequest request : list) { - if (ItemStack.isSameItem(request.getRequest().getStack(), cure)) + if (Disease.isCureItem(request.getRequest().getStack(), cure)) { hasCureRequested = true; break; @@ -179,7 +177,7 @@ private IAIState decide() } for (final IRequest request : completed) { - if (ItemStack.isSameItem(request.getRequest().getStack(), cure)) + if (Disease.isCureItem(request.getRequest().getStack(), cure)) { hasCureRequested = true; break; @@ -259,8 +257,8 @@ private IAIState requestCure() return REQUEST_CURE; } - final String diseaseName = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); - if (diseaseName.isEmpty()) + final Disease disease = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); + if (disease == null) { currentPatient.setState(Patient.PatientState.REQUESTED); currentPatient = null; @@ -270,15 +268,15 @@ private IAIState requestCure() final ImmutableList> list = building.getOpenRequestsOfType(worker.getCitizenData().getId(), TypeToken.of(Stack.class)); final ImmutableList> completed = building.getCompletedRequestsOfType(worker.getCitizenData(), TypeToken.of(Stack.class)); - for (final ItemStack cure : IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName).getCure()) + for (final ItemStorage cure : disease.cureItems()) { - if (!InventoryUtils.hasItemInItemHandler(worker.getInventoryCitizen(), stack -> ItemStack.isSameItem(cure, stack)) - && !InventoryUtils.hasItemInItemHandler(building.getCapability(ForgeCapabilities.ITEM_HANDLER).orElseGet(null), stack -> ItemStack.isSameItem(cure, stack))) + if (!InventoryUtils.hasItemInItemHandler(worker.getInventoryCitizen(), Disease.hasCureItem(cure)) + && !InventoryUtils.hasItemInItemHandler(building.getCapability(ForgeCapabilities.ITEM_HANDLER).orElseGet(null), Disease.hasCureItem(cure))) { boolean hasRequest = false; for (final IRequest request : list) { - if (ItemStack.isSameItem(request.getRequest().getStack(), cure)) + if (Disease.isCureItem(request.getRequest().getStack(), cure)) { hasRequest = true; break; @@ -286,7 +284,7 @@ private IAIState requestCure() } for (final IRequest request : completed) { - if (ItemStack.isSameItem(request.getRequest().getStack(), cure)) + if (Disease.isCureItem(request.getRequest().getStack(), cure)) { hasRequest = true; break; @@ -294,7 +292,7 @@ private IAIState requestCure() } if (!hasRequest) { - worker.getCitizenData().createRequestAsync(new Stack(cure, REQUEST_COUNT, 1)); + worker.getCitizenData().createRequestAsync(new Stack(cure)); } } } @@ -329,9 +327,8 @@ private IAIState cure() return CURE; } - final String diseaseName = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); - final Disease disease = IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseName); - if (diseaseName.isEmpty()) + final Disease disease = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); + if (disease == null) { currentPatient = null; citizen.heal(10); @@ -343,11 +340,11 @@ private IAIState cure() { if (hasCureInInventory(disease, building.getCapability(ForgeCapabilities.ITEM_HANDLER).orElseGet(null))) { - for (final ItemStack cure : disease.getCure()) + for (final ItemStorage cure : disease.cureItems()) { - if (InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), stack -> ItemStack.isSameItem(stack, cure)) < cure.getCount()) + if (InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), Disease.hasCureItem(cure)) < cure.getAmount()) { - needsCurrently = new Tuple<>(stack -> ItemStack.isSameItem(stack, cure), 1); + needsCurrently = new Tuple<>(Disease.hasCureItem(cure), 1); return GATHERING_REQUIRED_MATERIALS; } } @@ -358,9 +355,9 @@ private IAIState cure() if (!hasCureInInventory(disease, citizen.getInventoryCitizen())) { - for (final ItemStack cure : disease.getCure()) + for (final ItemStorage cure : disease.cureItems()) { - if (InventoryUtils.getItemCountInItemHandler(citizen.getInventoryCitizen(), stack -> ItemStack.isSameItem(stack, cure)) < cure.getCount()) + if (InventoryUtils.getItemCountInItemHandler(citizen.getInventoryCitizen(), Disease.hasCureItem(cure)) < cure.getAmount()) { if (InventoryUtils.isItemHandlerFull(citizen.getInventoryCitizen())) { @@ -370,8 +367,8 @@ private IAIState cure() } InventoryUtils.transferXOfFirstSlotInItemHandlerWithIntoNextFreeSlotInItemHandler( worker.getInventoryCitizen(), - stack -> ItemStack.isSameItem(cure, stack), - cure.getCount(), citizen.getInventoryCitizen() + Disease.hasCureItem(cure), + cure.getAmount(), citizen.getInventoryCitizen() ); } } @@ -518,9 +515,9 @@ private boolean testRandomCureChance() */ private boolean hasCureInInventory(final Disease disease, final IItemHandler handler) { - for (final ItemStack cure : disease.getCure()) + for (final ItemStorage cure : disease.cureItems()) { - if (InventoryUtils.getItemCountInItemHandler(handler, stack -> ItemStack.isSameItem(cure, stack)) < cure.getCount()) + if (InventoryUtils.getItemCountInItemHandler(handler, Disease.hasCureItem(cure)) < cure.getAmount()) { return false; } diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index d470d5d877e..a7525185e56 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -49,6 +49,7 @@ import com.minecolonies.core.colony.jobs.JobKnight; import com.minecolonies.core.colony.jobs.JobNetherWorker; import com.minecolonies.core.colony.jobs.JobRanger; +import com.minecolonies.core.datalistener.DiseasesListener; import com.minecolonies.core.entity.ai.minimal.*; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIBasic; import com.minecolonies.core.entity.ai.workers.CitizenAI; @@ -487,13 +488,14 @@ private InteractionResult directPlayerInteraction(final Player player, final Int if (!level.isClientSide()) { - getCitizenData().getCitizenDiseaseHandler().setDisease(IColonyManager.getInstance().getCompatibilityManager().getRandomDisease()); - playSound(SoundEvents.VILLAGER_HURT, 1.0f, (float) SoundUtils.getRandomPitch(getRandom())); - getCitizenData().markDirty(20); + if (getCitizenData().getCitizenDiseaseHandler().setDisease(DiseasesListener.getRandomDisease(getRandom()))) { + playSound(SoundEvents.VILLAGER_HURT, 1.0f, (float) SoundUtils.getRandomPitch(getRandom())); + getCitizenData().markDirty(20); - MessageUtils.format(MESSAGE_INTERACTION_POISON, this.getCitizenData().getName()) - .withPriority(MessagePriority.DANGER) - .sendTo(player); + MessageUtils.format(MESSAGE_INTERACTION_POISON, this.getCitizenData().getName()) + .withPriority(MessagePriority.DANGER) + .sendTo(player); + } } interactionCooldown = 20 * 20; diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java index f94bef8184b..bf054786668 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java @@ -3,15 +3,20 @@ import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.IColony; -import com.minecolonies.api.colony.IColonyManager; import com.minecolonies.api.colony.buildings.IBuilding; +import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenDiseaseHandler; import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingCook; import com.minecolonies.core.colony.jobs.AbstractJobGuard; import com.minecolonies.core.colony.jobs.JobHealer; +import com.minecolonies.core.datalistener.model.Disease; +import com.minecolonies.core.datalistener.DiseasesListener; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import org.jetbrains.annotations.Nullable; import static com.minecolonies.api.research.util.ResearchConstants.MASKS; import static com.minecolonies.api.research.util.ResearchConstants.VACCINES; @@ -52,7 +57,8 @@ public class CitizenDiseaseHandler implements ICitizenDiseaseHandler /** * The disease the citizen has, empty if none. */ - private String disease = ""; + @Nullable + private Disease disease; /** * Special immunity time after being cured. @@ -93,10 +99,11 @@ public void update(final int tickRate) final double citizenModifier = citizenData.getDiseaseModifier(); final int configModifier = MineColonies.getConfig().getServer().diseaseModifier.get(); - if (!IColonyManager.getInstance().getCompatibilityManager().getDiseases().isEmpty() && - citizenData.getRandom().nextInt(configModifier * DISEASE_FACTOR) < citizenModifier * 10) + // normally it's one in 5 x 10.000 + + if (citizenData.getRandom().nextInt(configModifier * DISEASE_FACTOR) < citizenModifier * 10) { - this.disease = IColonyManager.getInstance().getCompatibilityManager().getRandomDisease(); + this.disease = DiseasesListener.getRandomDisease(citizenData.getEntity().map(AbstractEntityCitizen::getRandom).orElse(RandomSource.create())); } } @@ -106,9 +113,15 @@ public void update(final int tickRate) } } - public void setDisease(final String disease) + @Override + public boolean setDisease(final @Nullable Disease disease) { - this.disease = disease; + if (canBecomeSick()) + { + this.disease = disease; + return true; + } + return false; } /** @@ -150,14 +163,17 @@ public boolean isHurt() @Override public boolean isSick() { - return !disease.isEmpty(); + return disease != null; } @Override public void write(final CompoundTag compound) { CompoundTag diseaseTag = new CompoundTag(); - diseaseTag.putString(TAG_DISEASE, disease); + if (disease != null) + { + diseaseTag.putString(TAG_DISEASE, disease.id().toString()); + } diseaseTag.putInt(TAG_IMMUNITY, immunityTicks); compound.put(TAG_DISEASE, diseaseTag); } @@ -165,20 +181,17 @@ public void write(final CompoundTag compound) @Override public void read(final CompoundTag compound) { - if (compound.contains(TAG_DISEASE)) + CompoundTag diseaseTag = compound.getCompound(TAG_DISEASE); + if (diseaseTag.contains(TAG_DISEASE)) { - CompoundTag diseaseTag = compound.getCompound(TAG_DISEASE); - // cure diseases that have been removed from the configuration file. - if (IColonyManager.getInstance().getCompatibilityManager().getDisease(diseaseTag.getString(TAG_DISEASE)) != null) - { - this.disease = diseaseTag.getString(TAG_DISEASE); - } - this.immunityTicks = diseaseTag.getInt(TAG_IMMUNITY); + this.disease = DiseasesListener.getDisease(new ResourceLocation(diseaseTag.getString(TAG_DISEASE))); } + this.immunityTicks = diseaseTag.getInt(TAG_IMMUNITY); } @Override - public String getDisease() + @Nullable + public Disease getDisease() { return this.disease; } @@ -186,7 +199,7 @@ public String getDisease() @Override public void cure() { - this.disease = ""; + this.disease = null; sleepsAtHospital = false; if (citizenData.isAsleep() && citizenData.getEntity().isPresent()) { diff --git a/src/main/java/com/minecolonies/core/event/DataPackSyncEventHandler.java b/src/main/java/com/minecolonies/core/event/DataPackSyncEventHandler.java index 6342a6085fd..d89f476aad8 100644 --- a/src/main/java/com/minecolonies/core/event/DataPackSyncEventHandler.java +++ b/src/main/java/com/minecolonies/core/event/DataPackSyncEventHandler.java @@ -6,6 +6,7 @@ import com.minecolonies.core.Network; import com.minecolonies.core.colony.crafting.CustomRecipeManager; import com.minecolonies.core.compatibility.CraftingTagAuditor; +import com.minecolonies.core.datalistener.DiseasesListener; import com.minecolonies.core.datalistener.QuestJsonListener; import com.minecolonies.core.network.messages.client.UpdateClientWithCompatibilityMessage; import com.minecolonies.core.util.FurnaceRecipes; @@ -69,6 +70,7 @@ private static void sendPackets(@NotNull final ServerPlayer player, CustomRecipeManager.getInstance().sendCustomRecipeManagerPackets(player); IGlobalResearchTree.getInstance().sendGlobalResearchTreePackets(player); QuestJsonListener.sendGlobalQuestPackets(player); + DiseasesListener.sendGlobalDiseasesPackets(player); } /** diff --git a/src/main/java/com/minecolonies/core/event/FMLEventHandler.java b/src/main/java/com/minecolonies/core/event/FMLEventHandler.java index d8b690cc43c..465511f88d5 100755 --- a/src/main/java/com/minecolonies/core/event/FMLEventHandler.java +++ b/src/main/java/com/minecolonies/core/event/FMLEventHandler.java @@ -52,6 +52,7 @@ public static void onAddReloadListenerEvent(@NotNull final AddReloadListenerEven event.addListener(new QuestJsonListener()); event.addListener(new ItemNbtListener()); event.addListener(new StudyItemListener()); + event.addListener(new DiseasesListener()); } @SubscribeEvent diff --git a/src/main/java/com/minecolonies/core/network/NetworkChannel.java b/src/main/java/com/minecolonies/core/network/NetworkChannel.java index 8290ad9700f..76759c65569 100755 --- a/src/main/java/com/minecolonies/core/network/NetworkChannel.java +++ b/src/main/java/com/minecolonies/core/network/NetworkChannel.java @@ -229,6 +229,7 @@ public void registerCommonMessages() registerMessage(++idx, OpenPlantationFieldBuildWindowMessage.class, OpenPlantationFieldBuildWindowMessage::new); registerMessage(++idx, SaveStructureNBTMessage.class, SaveStructureNBTMessage::new); registerMessage(++idx, GlobalQuestSyncMessage.class, GlobalQuestSyncMessage::new); + registerMessage(++idx, GlobalDiseaseSyncMessage.class, GlobalDiseaseSyncMessage::new); registerMessage(++idx, OpenColonyFoundingCovenantMessage.class, OpenColonyFoundingCovenantMessage::new); registerMessage(++idx, OpenBuildingUIMessage.class, OpenBuildingUIMessage::new); registerMessage(++idx, OpenCantFoundColonyWarningMessage.class, OpenCantFoundColonyWarningMessage::new); diff --git a/src/main/java/com/minecolonies/core/network/messages/client/colony/GlobalDiseaseSyncMessage.java b/src/main/java/com/minecolonies/core/network/messages/client/colony/GlobalDiseaseSyncMessage.java new file mode 100644 index 00000000000..760488c3e89 --- /dev/null +++ b/src/main/java/com/minecolonies/core/network/messages/client/colony/GlobalDiseaseSyncMessage.java @@ -0,0 +1,72 @@ +package com.minecolonies.core.network.messages.client.colony; + +import com.minecolonies.api.network.IMessage; +import com.minecolonies.core.datalistener.DiseasesListener; +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.network.NetworkEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * The message used to synchronize global disease data from a server to a remote client. + */ +public class GlobalDiseaseSyncMessage implements IMessage +{ + /** + * The buffer with the data. + */ + private FriendlyByteBuf buffer; + + /** + * Empty constructor used when registering the message + */ + public GlobalDiseaseSyncMessage() + { + super(); + } + + /** + * Add or Update expedition type data on the client. + * + * @param buf the bytebuffer. + */ + public GlobalDiseaseSyncMessage(final FriendlyByteBuf buf) + { + this.buffer = new FriendlyByteBuf(buf.copy()); + } + + @Override + public void toBytes(@NotNull final FriendlyByteBuf buf) + { + buffer.resetReaderIndex(); + buf.writeBytes(buffer); + } + + @Override + public void fromBytes(@NotNull final FriendlyByteBuf buf) + { + buffer = new FriendlyByteBuf(buf.retain()); + } + + @Nullable + @Override + public LogicalSide getExecutionSide() + { + return LogicalSide.CLIENT; + } + + @OnlyIn(Dist.CLIENT) + @Override + public void onExecute(final NetworkEvent.Context ctxIn, final boolean isLogicalServer) + { + if (Minecraft.getInstance().level != null) + { + DiseasesListener.readGlobalDiseasesPackets(buffer); + } + buffer.release(); + } +} diff --git a/src/main/resources/assets/minecolonies/lang/manual_en_us.json b/src/main/resources/assets/minecolonies/lang/manual_en_us.json index 368cf13ea8b..5f2e375f588 100644 --- a/src/main/resources/assets/minecolonies/lang/manual_en_us.json +++ b/src/main/resources/assets/minecolonies/lang/manual_en_us.json @@ -2734,5 +2734,9 @@ "com.minecolonies.coremod.setting.minecolonies:milk_item": "Milk Item:", "com.minecolonies.core.menu.title": "Menu", "com.minecolonies.core.food_list.title": "Food Options", - "com.minecolonies.core.menu.warning": "Select the Food Citizens will eat at this Restaurant" + "com.minecolonies.core.menu.warning": "Select the Food Citizens will eat at this Restaurant", + + "com.minecolonies.coremod.diseases.influenza": "Influenza", + "com.minecolonies.coremod.diseases.measles": "Measles", + "com.minecolonies.coremod.diseases.smallpox": "Smallpox" } diff --git a/src/main/resources/data/minecolonies/colony/diseases/influenza.json b/src/main/resources/data/minecolonies/colony/diseases/influenza.json new file mode 100644 index 00000000000..29b3fdfdd16 --- /dev/null +++ b/src/main/resources/data/minecolonies/colony/diseases/influenza.json @@ -0,0 +1,14 @@ +{ + "name": "com.minecolonies.coremod.diseases.influenza", + "rarity": 100, + "items": [ + { + "item": "minecraft:carrot", + "count": 1 + }, + { + "item": "minecraft:potato", + "count": 1 + } + ] +} diff --git a/src/main/resources/data/minecolonies/colony/diseases/measles.json b/src/main/resources/data/minecolonies/colony/diseases/measles.json new file mode 100644 index 00000000000..bccd625c97b --- /dev/null +++ b/src/main/resources/data/minecolonies/colony/diseases/measles.json @@ -0,0 +1,18 @@ +{ + "name": "com.minecolonies.coremod.diseases.measles", + "rarity": 10, + "items": [ + { + "item": "minecraft:poppy", + "count": 1 + }, + { + "item": "minecraft:dandelion", + "count": 1 + }, + { + "item": "minecraft:kelp", + "count": 1 + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/minecolonies/colony/diseases/smallpox.json b/src/main/resources/data/minecolonies/colony/diseases/smallpox.json new file mode 100644 index 00000000000..952048a1e15 --- /dev/null +++ b/src/main/resources/data/minecolonies/colony/diseases/smallpox.json @@ -0,0 +1,14 @@ +{ + "name": "com.minecolonies.coremod.diseases.smallpox", + "rarity": 1, + "items": [ + { + "item": "minecraft:honey_bottle", + "count": 1 + }, + { + "item": "minecraft:golden_apple", + "count": 1 + } + ] +} \ No newline at end of file From bb4ba6e5acda3ad2ed0d02856a92259be42e5be6 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Sun, 1 Dec 2024 22:43:37 +0100 Subject: [PATCH 10/33] Fix a possible crash upon loading old disease data (#10495) Fix a possible crash upon loading old disease data --- .../api/util/constant/CitizenConstants.java | 5 +++++ .../citizenhandlers/CitizenDiseaseHandler.java | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minecolonies/api/util/constant/CitizenConstants.java b/src/main/java/com/minecolonies/api/util/constant/CitizenConstants.java index eedc5230d21..2f88035a6ee 100755 --- a/src/main/java/com/minecolonies/api/util/constant/CitizenConstants.java +++ b/src/main/java/com/minecolonies/api/util/constant/CitizenConstants.java @@ -213,6 +213,11 @@ public final class CitizenConstants */ public static final String TAG_DISEASE = "disease"; + /** + * Disease iod tag. + */ + public static final String TAG_DISEASE_ID = "disease_id"; + /** * Disease immunity tag, */ diff --git a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java index bf054786668..1736b5cf00c 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/citizenhandlers/CitizenDiseaseHandler.java @@ -14,6 +14,7 @@ import com.minecolonies.core.datalistener.DiseasesListener; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import org.jetbrains.annotations.Nullable; @@ -172,7 +173,7 @@ public void write(final CompoundTag compound) CompoundTag diseaseTag = new CompoundTag(); if (disease != null) { - diseaseTag.putString(TAG_DISEASE, disease.id().toString()); + diseaseTag.putString(TAG_DISEASE_ID, disease.id().toString()); } diseaseTag.putInt(TAG_IMMUNITY, immunityTicks); compound.put(TAG_DISEASE, diseaseTag); @@ -181,10 +182,15 @@ public void write(final CompoundTag compound) @Override public void read(final CompoundTag compound) { + if (!compound.contains(TAG_DISEASE, Tag.TAG_COMPOUND)) + { + return; + } + CompoundTag diseaseTag = compound.getCompound(TAG_DISEASE); - if (diseaseTag.contains(TAG_DISEASE)) + if (diseaseTag.contains(TAG_DISEASE_ID)) { - this.disease = DiseasesListener.getDisease(new ResourceLocation(diseaseTag.getString(TAG_DISEASE))); + this.disease = DiseasesListener.getDisease(new ResourceLocation(diseaseTag.getString(TAG_DISEASE_ID))); } this.immunityTicks = diseaseTag.getInt(TAG_IMMUNITY); } From a8346fd5ea0973a21c8c1844f038d8064f8d4625 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Mon, 2 Dec 2024 13:55:55 +0100 Subject: [PATCH 11/33] hotfix 10498 --- .../workers/guard/AbstractEntityAIGuard.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIGuard.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIGuard.java index c7f21ad1d43..3f201d91e46 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIGuard.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIGuard.java @@ -521,7 +521,7 @@ public IAIState patrol() if (currentPatrolPoint != null) { - setNextPatrolTargetAndMove(currentPatrolPoint); + setNextPatrolTarget(currentPatrolPoint); } } } @@ -562,11 +562,11 @@ public IAIState patrolMine() final MinerLevel level = buildingMiner.getFirstModuleOccurance(MinerLevelManagementModule.class).getCurrentLevel(); if (level == null) { - setNextPatrolTargetAndMove(buildingMiner.getPosition()); + setNextPatrolTarget(buildingMiner.getPosition()); } else { - setNextPatrolTargetAndMove(level.getRandomCompletedNode(buildingMiner)); + setNextPatrolTarget(level.getRandomCompletedNode(buildingMiner)); } } else @@ -589,7 +589,7 @@ public IAIState patrolMine() */ public void setNextPatrolTargetAndMove(final BlockPos target) { - currentPatrolPoint = target; + setNextPatrolTarget(target); registerTarget(new AIOneTimeEventTarget(() -> { if (getState() == CombatAIStates.NO_TARGET) @@ -600,6 +600,16 @@ public void setNextPatrolTargetAndMove(final BlockPos target) })); } + /** + * Sets the next patrol target. + * + * @param target the next patrol target. + */ + private void setNextPatrolTarget(final BlockPos target) + { + currentPatrolPoint = target; + } + /** * Check if the worker has the required tool to fight. * From f2b2311a727613f1f06fe08be6f63aa908b67201 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Wed, 4 Dec 2024 18:08:33 +0100 Subject: [PATCH 12/33] fix #10490 (#10502) Mark min stock requests as passive to avoid interfering with worker operation. Fix food request equality --- .../core/colony/buildings/modules/MinimumStockModule.java | 2 +- .../core/colony/buildings/modules/RestaurantMenuModule.java | 2 +- .../core/entity/ai/workers/production/EntityAIWorkNether.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minecolonies/core/colony/buildings/modules/MinimumStockModule.java b/src/main/java/com/minecolonies/core/colony/buildings/modules/MinimumStockModule.java index e97e566bed6..5304872058f 100644 --- a/src/main/java/com/minecolonies/core/colony/buildings/modules/MinimumStockModule.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/modules/MinimumStockModule.java @@ -132,7 +132,7 @@ public void onColonyTick(@NotNull final IColony colony) itemStack.setCount(Math.min(itemStack.getMaxStackSize(), delta)); final MinimumStack stack = new MinimumStack(itemStack, false); stack.setCanBeResolvedByBuilding(false); - building.createRequest(stack, false); + building.createRequest(stack, true); } } else if (request != null && delta <= 0) diff --git a/src/main/java/com/minecolonies/core/colony/buildings/modules/RestaurantMenuModule.java b/src/main/java/com/minecolonies/core/colony/buildings/modules/RestaurantMenuModule.java index b9aa5f5b7fa..33cf6643f14 100644 --- a/src/main/java/com/minecolonies/core/colony/buildings/modules/RestaurantMenuModule.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/modules/RestaurantMenuModule.java @@ -144,7 +144,7 @@ public void onColonyTick(@NotNull final IColony colony) requestStack.setCount(Math.min(16, Math.min(requestStack.getMaxStackSize(), delta))); final MinimumStack stack = new MinimumStack(requestStack, false); stack.setCanBeResolvedByBuilding(false); - building.createRequest(stack, false); + building.createRequest(stack, true); } } else if (request != null && delta <= 0) diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java index fed20177bb5..66880efd086 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java @@ -985,7 +985,7 @@ protected void checkAndRequestArmor() protected IAIState checkAndRequestFood() { - if (InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), stack -> building.getModule(NETHERMINER_MENU).getMenu().contains(new ItemStorage(stack))) > 16) + if (InventoryUtils.getItemCountInItemHandler(worker.getInventoryCitizen(), stack -> building.getModule(NETHERMINER_MENU).getMenu().contains(new ItemStorage(stack))) >= 16) { // We have enough food. return getState(); From 53ccec723f3a6ccedc6408abb431bb69208be085 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Thu, 5 Dec 2024 21:09:41 +0100 Subject: [PATCH 13/33] Mark item costs to actually be a singular item, not an item list, give building requirements explicit types (for the wiki) (#10507) Changed the generation from item costs lists to simple items (unintentional reuse of functions inside the research provider) Make sure that building requirements have a type This is quick and dirty generation code which has no effect on runtime, I need this to better generate data for the wiki --- .../researches/civilian/academic.json | 10 +++---- .../researches/civilian/agile.json | 9 +++---- .../minecolonies/researches/civilian/air.json | 10 +++---- .../researches/civilian/ambition.json | 10 +++---- .../researches/civilian/athlete.json | 10 +++---- .../researches/civilian/bachelor.json | 9 +++---- .../researches/civilian/bandages.json | 9 +++---- .../researches/civilian/bandaid.json | 9 +++---- .../researches/civilian/beanstalk.json | 10 +++---- .../researches/civilian/bookworm.json | 9 +++---- .../researches/civilian/cast.json | 10 +++---- .../researches/civilian/circus.json | 9 +++---- .../researches/civilian/city.json | 9 +++---- .../researches/civilian/compress.json | 9 +++---- .../researches/civilian/diligent.json | 9 +++---- .../researches/civilian/epicure.json | 9 +++---- .../researches/civilian/festival.json | 9 +++---- .../researches/civilian/firstaid.json | 9 +++---- .../researches/civilian/firstaid2.json | 9 +++---- .../researches/civilian/fortitude.json | 9 +++---- .../researches/civilian/glutton.json | 10 +++---- .../researches/civilian/gorger.json | 9 +++---- .../researches/civilian/gourmand.json | 9 +++---- .../researches/civilian/gravedecaybonus1.json | 9 +++---- .../researches/civilian/gravedecaybonus2.json | 9 +++---- .../researches/civilian/growth.json | 9 +++---- .../researches/civilian/guardianangel.json | 9 +++---- .../researches/civilian/guardianangel2.json | 10 +++---- .../researches/civilian/hamlet.json | 9 +++---- .../researches/civilian/healingcream.json | 9 +++---- .../researches/civilian/higherlearning.json | 9 +++---- .../researches/civilian/hormones.json | 9 +++---- .../researches/civilian/indefatigability.json | 10 +++---- .../researches/civilian/keen.json | 9 +++---- .../researches/civilian/lifesaver.json | 9 +++---- .../researches/civilian/lifesaver2.json | 9 +++---- .../researches/civilian/masks.json | 9 +++---- .../researches/civilian/master.json | 9 +++---- .../minecolonies/researches/civilian/moq.json | 17 ++++-------- .../researches/civilian/morebooks.json | 9 +++---- .../researches/civilian/nightowl.json | 9 +++---- .../researches/civilian/nightowl2.json | 9 +++---- .../researches/civilian/nimble.json | 9 +++---- .../researches/civilian/nurture.json | 9 +++---- .../researches/civilian/opera.json | 9 +++---- .../researches/civilian/outpost.json | 9 +++---- .../minecolonies/researches/civilian/phd.json | 10 +++---- .../researches/civilian/puberty.json | 9 +++---- .../researches/civilian/rails.json | 9 +++---- .../researches/civilian/raisingthedead.json | 9 +++---- .../researches/civilian/reflective.json | 9 +++---- .../researches/civilian/remembrance.json | 9 +++---- .../researches/civilian/resilience.json | 9 +++---- .../researches/civilian/resistance.json | 9 +++---- .../researches/civilian/resurrectchance1.json | 9 +++---- .../researches/civilian/resurrectchance2.json | 9 +++---- .../researches/civilian/scholarly.json | 9 +++---- .../researches/civilian/spectacle.json | 9 +++---- .../researches/civilian/stamina.json | 10 +++---- .../researches/civilian/studious.json | 9 +++---- .../researches/civilian/stuffer.json | 9 +++---- .../researches/civilian/swift.json | 9 +++---- .../researches/civilian/theater.json | 10 +++---- .../civilian/undertakeremergency.json | 9 +++---- .../researches/civilian/vaccines.json | 9 +++---- .../researches/civilian/village.json | 9 +++---- .../researches/civilian/vines.json | 9 +++---- .../researches/civilian/vitality.json | 9 +++---- .../researches/combat/accuracy.json | 9 +++---- .../researches/combat/agilearcher.json | 10 +++---- .../researches/combat/arrowpierce.json | 17 ++++-------- .../researches/combat/arrowuse.json | 9 +++---- .../minecolonies/researches/combat/avoid.json | 9 +++---- .../researches/combat/avoidance.json | 9 +++---- .../researches/combat/boiledleather.json | 9 +++---- .../researches/combat/captainoftheguard.json | 10 +++---- .../researches/combat/captaintraining.json | 9 +++---- .../researches/combat/cleave.json | 9 +++---- .../researches/combat/coffee.json | 10 +++---- .../researches/combat/deadlyaim.json | 10 +++---- .../researches/combat/diamondskin.json | 10 +++---- .../minecolonies/researches/combat/dodge.json | 9 +++---- .../researches/combat/druidpotion.json | 9 +++---- .../researches/combat/duelist.json | 9 +++---- .../minecolonies/researches/combat/evade.json | 9 +++---- .../researches/combat/evasion.json | 9 +++---- .../minecolonies/researches/combat/fear.json | 9 +++---- .../minecolonies/researches/combat/feint.json | 9 +++---- .../minecolonies/researches/combat/flee.json | 9 +++---- .../researches/combat/fullretreat.json | 10 +++---- .../researches/combat/hotfoot.json | 10 +++---- .../researches/combat/improvedbows.json | 9 +++---- .../researches/combat/improveddodge.json | 9 +++---- .../researches/combat/improvedevasion.json | 9 +++---- .../researches/combat/improvedleather.json | 9 +++---- .../researches/combat/improvedswords.json | 9 +++---- .../researches/combat/ironarmor.json | 9 +++---- .../researches/combat/ironskin.json | 9 +++---- .../researches/combat/knighttraining.json | 9 +++---- .../researches/combat/masterbowman.json | 10 +++---- .../researches/combat/masterswordsman.json | 10 +++---- .../researches/combat/mightycleave.json | 9 +++---- .../researches/combat/multishot.json | 9 +++---- .../minecolonies/researches/combat/parry.json | 9 +++---- .../researches/combat/penetratingshot.json | 9 +++---- .../researches/combat/piercingshot.json | 9 +++---- .../researches/combat/platearmor.json | 9 +++---- .../researches/combat/powerattack.json | 9 +++---- .../researches/combat/preciseshot.json | 9 +++---- .../researches/combat/provost.json | 9 +++---- .../researches/combat/quickdraw.json | 9 +++---- .../researches/combat/rapidshot.json | 9 +++---- .../researches/combat/regeneration.json | 9 +++---- .../researches/combat/retreat.json | 9 +++---- .../researches/combat/riposte.json | 9 +++---- .../researches/combat/savagestrike.json | 10 +++---- .../researches/combat/squiretraining.json | 9 +++---- .../researches/combat/standard.json | 9 +++---- .../researches/combat/steelarmor.json | 9 +++---- .../researches/combat/tactictraining.json | 9 +++---- .../minecolonies/researches/combat/taunt.json | 25 +++++------------- .../researches/combat/telescope.json | 9 +++---- .../researches/combat/trickshot.json | 9 +++---- .../researches/combat/whirlwind.json | 25 +++++------------- .../researches/combat/woundingshot.json | 9 +++---- .../researches/technology/ability.json | 9 +++---- .../researches/technology/alchemist.json | 10 +++---- .../researches/technology/amazingveins.json | 1 + .../researches/technology/biodegradable.json | 9 +++---- .../researches/technology/bonemeal.json | 9 +++---- .../researches/technology/buildermodes.json | 9 +++---- .../researches/technology/capacity.json | 9 +++---- .../researches/technology/cheatsheet.json | 9 +++---- .../researches/technology/compost.json | 9 +++---- .../researches/technology/croprotation.json | 17 ++++-------- .../researches/technology/deeppockets.json | 9 +++---- .../researches/technology/depthknowledge.json | 9 +++---- .../researches/technology/diamondcoated.json | 10 +++---- .../researches/technology/dung.json | 9 +++---- .../technology/enhanced_gates1.json | 26 +++++-------------- .../technology/enhanced_gates2.json | 26 +++++-------------- .../researches/technology/exoticfruits.json | 9 +++---- .../researches/technology/fertilizer.json | 9 +++---- .../researches/technology/flowerpower.json | 9 +++---- .../researches/technology/fullstock.json | 9 +++---- .../researches/technology/gargamel.json | 18 +++++-------- .../researches/technology/gildedhammer.json | 25 +++++------------- .../researches/technology/goodveins.json | 1 + .../researches/technology/hardened.json | 9 +++---- .../researches/technology/heavilyloaded.json | 10 +++---- .../researches/technology/heavymachinery.json | 10 +++---- .../researches/technology/hittingiron.json | 9 +++---- .../researches/technology/honeypot.json | 9 +++---- .../researches/technology/hot.json | 9 +++---- .../researches/technology/hotboots.json | 17 ++++-------- .../researches/technology/isthisredstone.json | 10 +++---- .../researches/technology/junglemaster.json | 25 +++++------------- .../researches/technology/knowtheend.json | 9 +++---- .../researches/technology/letitgrow.json | 9 +++---- .../researches/technology/lightning.json | 10 +++---- .../researches/technology/loaded.json | 9 +++---- .../researches/technology/madness.json | 10 +++---- .../researches/technology/magiccompost.json | 10 +++---- .../researches/technology/memoryaid.json | 9 +++---- .../researches/technology/morescrolls.json | 25 +++++------------- .../researches/technology/netherlog.json | 17 ++++-------- .../researches/technology/oceanheart.json | 9 +++---- .../researches/technology/opennether.json | 10 +++---- .../researches/technology/pavetheroad.json | 1 + .../researches/technology/podzolchance.json | 9 +++---- .../researches/technology/podzolchance2.json | 9 +++---- .../researches/technology/rainbowheaven.json | 9 +++---- .../researches/technology/rainman.json | 10 +++---- .../researches/technology/recipebook.json | 9 +++---- .../technology/redstonepowered.json | 10 +++---- .../researches/technology/reinforced.json | 9 +++---- .../researches/technology/richveins.json | 1 + .../researches/technology/rockingroll.json | 9 +++---- .../researches/technology/rtm.json | 9 +++---- .../researches/technology/seemsautomatic.json | 9 +++---- .../researches/technology/sieving.json | 9 +++---- .../researches/technology/skills.json | 9 +++---- .../researches/technology/softshoes.json | 18 ++++--------- .../researches/technology/space.json | 9 +++---- .../researches/technology/steelbracing.json | 9 +++---- .../researches/technology/stonecake.json | 9 +++---- .../researches/technology/stringwork.json | 9 +++---- .../researches/technology/strong.json | 9 +++---- .../technology/takingdivinglessons.json | 25 +++++------------- .../researches/technology/theflintstones.json | 9 +++---- .../researches/technology/thoselungs.json | 9 +++---- .../researches/technology/tools.json | 9 +++---- .../researches/technology/veinminer.json | 1 + .../technology/warehousemaster.json | 9 +++---- .../technology/whatisthisspeed.json | 10 +++---- .../researches/technology/whatyaneed.json | 9 +++---- .../researches/technology/woodwork.json | 1 + .../researches/unlockable/diamondmesh.json | 1 + .../researches/unlockable/flintmesh.json | 1 + .../researches/unlockable/ironmesh.json | 1 + .../researches/unlockable/stringmesh.json | 1 + .../research/AbstractResearchProvider.java | 15 ++++++++--- 202 files changed, 642 insertions(+), 1324 deletions(-) diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/academic.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/academic.json index 4e9390e2501..3bd1ecaa83b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/academic.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/academic.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:civilian/reflective", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 128 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.civilian.academic.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/agile.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/agile.json index 27810aeec31..b0379580af7 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/agile.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/agile.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/nimble", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:rabbit_foot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:rabbit_foot", "quantity": 10 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/air.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/air.json index 25864ef7daf..2b8bd2a9c3e 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/air.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/air.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:civilian/ambition", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:heart_of_the_sea" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:heart_of_the_sea", "quantity": 1 } ], "researchLevel": 2, "sortOrder": 1 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/ambition.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/ambition.json index da2e16e1f16..88dccc92b9c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/ambition.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/ambition.json @@ -8,15 +8,11 @@ "icon": "minecolonies:blockhutmysticalsite", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 1 } ], "researchLevel": 1, "sortOrder": 5 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/athlete.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/athlete.json index f018816305e..b0cb1e263e9 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/athlete.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/athlete.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:civilian/swift", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:rabbit_foot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:rabbit_foot", "quantity": 64 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.civilian.athlete.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bachelor.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bachelor.json index e7838f1a017..00053ff215d 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bachelor.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bachelor.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/bookworm", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bookshelf" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bookshelf", "quantity": 12 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bandages.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bandages.json index 6cae5266874..0950d54e6db 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bandages.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bandages.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/healingcream", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_carrot", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bandaid.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bandaid.json index 05c17f47d85..4333712fe40 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bandaid.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bandaid.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/stamina", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_carrot", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/beanstalk.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/beanstalk.json index 91be7d2844b..409674e2843 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/beanstalk.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/beanstalk.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:civilian/growth", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_chicken" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_chicken", "quantity": 512 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.civilian.beanstalk.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bookworm.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bookworm.json index a30eae0e66d..77487a1d53d 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bookworm.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/bookworm.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/morebooks", "requirements": [ { + "type": "minecolonies:building", "building": "school", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bookshelf" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bookshelf", "quantity": 6 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/cast.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/cast.json index 030b7978d1f..d0c2fe39663 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/cast.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/cast.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:civilian/compress", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_carrot", "quantity": 64 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/circus.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/circus.json index 03ab7ea5955..6fee42fa8e1 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/circus.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/circus.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/firstaid", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cake" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cake", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/city.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/city.json index 8a20dc2d506..86b80fc0410 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/city.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/city.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/village", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_beef" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_beef", "quantity": 512 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/compress.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/compress.json index aba4d7fe9ae..df94476504c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/compress.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/compress.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/bandages", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_carrot", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/diligent.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/diligent.json index 26e4154eeaa..1a3f04efd74 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/diligent.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/diligent.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/keen", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 6 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/epicure.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/epicure.json index 97208609809..8a6a98e5b70 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/epicure.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/epicure.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/stuffer", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cookie" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cookie", "quantity": 256 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/festival.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/festival.json index 06dc04a21ae..91b77cbc58a 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/festival.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/festival.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/circus", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cake" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cake", "quantity": 9 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/firstaid.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/firstaid.json index b2307930526..aefc58e93ef 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/firstaid.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/firstaid.json @@ -8,16 +8,13 @@ "icon": "minecolonies:textures/icons/research/hp1.png", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:hay_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:hay_block", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/firstaid2.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/firstaid2.json index 87963c43cc4..a7fa246fa18 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/firstaid2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/firstaid2.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/firstaid", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:hay_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:hay_block", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/fortitude.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/fortitude.json index b4f338bca03..1b0fb958894 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/fortitude.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/fortitude.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/vitality", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_apple" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_apple", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/glutton.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/glutton.json index d510c5131b0..11dbdef90bb 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/glutton.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/glutton.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:civilian/epicure", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cookie" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cookie", "quantity": 512 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.civilian.glutton.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gorger.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gorger.json index de793a0df00..79f89c65373 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gorger.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gorger.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/gourmand", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cookie" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cookie", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gourmand.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gourmand.json index f5b2f4dbde8..deccb694622 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gourmand.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gourmand.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/firstaid", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cookie" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cookie", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gravedecaybonus1.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gravedecaybonus1.json index 6870a0d0c51..ca4992ee745 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gravedecaybonus1.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gravedecaybonus1.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/remembrance", "requirements": [ { + "type": "minecolonies:building", "building": "graveyard", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:rotten_flesh" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:rotten_flesh", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gravedecaybonus2.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gravedecaybonus2.json index 12c8fbc8b26..8638af20259 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gravedecaybonus2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/gravedecaybonus2.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/gravedecaybonus1", "requirements": [ { + "type": "minecolonies:building", "building": "graveyard", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:nether_wart_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:nether_wart_block", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/growth.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/growth.json index 9d0288d5677..17239caab61 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/growth.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/growth.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/puberty", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_chicken" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_chicken", "quantity": 256 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/guardianangel.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/guardianangel.json index ca11483d3bf..c337c0ff2cb 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/guardianangel.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/guardianangel.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/lifesaver2", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:hay_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:hay_block", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/guardianangel2.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/guardianangel2.json index f868c472744..5a977d66dca 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/guardianangel2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/guardianangel2.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:civilian/guardianangel", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:hay_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:hay_block", "quantity": 256 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/hamlet.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/hamlet.json index d3e673ffd9f..6f4fff38591 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/hamlet.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/hamlet.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/outpost", "requirements": [ { + "type": "minecolonies:building", "building": "residence", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_beef" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_beef", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/healingcream.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/healingcream.json index 2656c128321..ed4a151a249 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/healingcream.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/healingcream.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/bandaid", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_carrot", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/higherlearning.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/higherlearning.json index 8892cd90659..57031300757 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/higherlearning.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/higherlearning.json @@ -9,16 +9,13 @@ "icon": "minecolonies:blockhutschool", "requirements": [ { + "type": "minecolonies:building", "building": "residence", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 3 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/hormones.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/hormones.json index 64e53192633..574595d2b9f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/hormones.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/hormones.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/nurture", "requirements": [ { + "type": "minecolonies:building", "building": "school", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_chicken" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_chicken", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/indefatigability.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/indefatigability.json index bac460f4583..936877d8e0f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/indefatigability.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/indefatigability.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:civilian/fortitude", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_apple" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_apple", "quantity": 64 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/keen.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/keen.json index e34a51f3505..0fc12f34df7 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/keen.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/keen.json @@ -8,16 +8,13 @@ "icon": "minecolonies:blockhutlibrary", "requirements": [ { + "type": "minecolonies:building", "building": "residence", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 3 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/lifesaver.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/lifesaver.json index ea5e916abd3..d336d943acf 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/lifesaver.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/lifesaver.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/firstaid2", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:hay_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:hay_block", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/lifesaver2.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/lifesaver2.json index 8f2b0951ecf..3d96a909298 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/lifesaver2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/lifesaver2.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/lifesaver", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:hay_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:hay_block", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/masks.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/masks.json index ead4f9eba0d..f918f0b19d4 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/masks.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/masks.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/firstaid2", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:white_wool" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:white_wool", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/master.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/master.json index 8e57cb2661f..f75bba62bc8 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/master.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/master.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/bachelor", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bookshelf" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bookshelf", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/moq.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/moq.json index 0a2fdfa594e..1619a8696fd 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/moq.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/moq.json @@ -9,25 +9,18 @@ "parentResearch": "minecolonies:civilian/rails", "requirements": [ { + "type": "minecolonies:building", "building": "deliveryman", "level": 9 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:clipboard" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:clipboard", "quantity": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/morebooks.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/morebooks.json index 144bff9784a..4feebceb8f0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/morebooks.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/morebooks.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/higherlearning", "requirements": [ { + "type": "minecolonies:building", "building": "school", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 6 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nightowl.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nightowl.json index 993922c4f9a..76f40509529 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nightowl.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nightowl.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/circus", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_carrot", "quantity": 25 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nightowl2.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nightowl2.json index fd89d0a7260..e442568ebaa 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nightowl2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nightowl2.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/nightowl", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_carrot", "quantity": 75 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nimble.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nimble.json index 05f3b9e3cc8..c366cb82a80 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nimble.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nimble.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/rails", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:rabbit_foot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:rabbit_foot", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nurture.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nurture.json index 473849fcb79..703a71d0b24 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nurture.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/nurture.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/higherlearning", "requirements": [ { + "type": "minecolonies:building", "building": "school", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_chicken" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_chicken", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/opera.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/opera.json index 84f7aafc04c..88d12079622 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/opera.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/opera.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/spectacle", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cake" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cake", "quantity": 27 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/outpost.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/outpost.json index a756cf644f7..62eb1a5e7b3 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/outpost.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/outpost.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/keen", "requirements": [ { + "type": "minecolonies:building", "building": "residence", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_beef" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_beef", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/phd.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/phd.json index fb35a1178d7..ca21f8f7b44 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/phd.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/phd.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:civilian/master", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bookshelf" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bookshelf", "quantity": 64 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.civilian.phd.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/puberty.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/puberty.json index 18b9174d600..5a84474589b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/puberty.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/puberty.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/hormones", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_chicken" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_chicken", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/rails.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/rails.json index e2b72e89f7d..30990a65f88 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/rails.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/rails.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/keen", "requirements": [ { + "type": "minecolonies:building", "building": "deliveryman", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:rail" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:rail", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/raisingthedead.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/raisingthedead.json index 230c0494670..c3d6eb9d9fe 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/raisingthedead.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/raisingthedead.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/resurrectchance2", "requirements": [ { + "type": "minecolonies:building", "building": "graveyard", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:totem_of_undying" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:totem_of_undying", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/reflective.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/reflective.json index f66ce20bf6a..d53f17374b1 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/reflective.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/reflective.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/scholarly", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 48 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/remembrance.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/remembrance.json index 20167ebd78c..5440d8eed3b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/remembrance.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/remembrance.json @@ -8,16 +8,13 @@ "icon": "minecolonies:blockhutgraveyard", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bone", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resilience.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resilience.json index de940a0bf7a..e4c29f437c0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resilience.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resilience.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/resistance", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_apple" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_apple", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resistance.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resistance.json index 62fae31ab20..513a43b6d51 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resistance.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resistance.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/stamina", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_apple" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_apple", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resurrectchance1.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resurrectchance1.json index 438ff8d1495..1654f1f893c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resurrectchance1.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resurrectchance1.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/remembrance", "requirements": [ { + "type": "minecolonies:building", "building": "graveyard", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:ghast_tear" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:ghast_tear", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resurrectchance2.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resurrectchance2.json index ee115727d31..37602d6d0b3 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resurrectchance2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/resurrectchance2.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/resurrectchance1", "requirements": [ { + "type": "minecolonies:building", "building": "graveyard", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:chorus_fruit" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:chorus_fruit", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/scholarly.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/scholarly.json index a1e8af1feb3..cf1eecea01a 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/scholarly.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/scholarly.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/studious", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 24 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/spectacle.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/spectacle.json index 7c59e372e95..c8121b30572 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/spectacle.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/spectacle.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/festival", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cake" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cake", "quantity": 18 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/stamina.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/stamina.json index 33e5669d9d4..5fdf6f57e6c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/stamina.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/stamina.json @@ -9,14 +9,10 @@ "icon": "minecolonies:blockhuthospital", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:carrot", "quantity": 1 } ], "researchLevel": 1 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/studious.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/studious.json index e761bd3977d..260cc47991c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/studious.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/studious.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/diligent", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:book" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:book", "quantity": 12 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/stuffer.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/stuffer.json index 966b8f21feb..984b1d6c8f3 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/stuffer.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/stuffer.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/gorger", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cookie" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cookie", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/swift.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/swift.json index 51f9ecaafbe..75fb27a681e 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/swift.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/swift.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/agile", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:rabbit_foot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:rabbit_foot", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/theater.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/theater.json index d3abf98497a..8caecfbb025 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/theater.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/theater.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:civilian/opera", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:enchanted_golden_apple" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:enchanted_golden_apple", "quantity": 16 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.civilian.theater.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/undertakeremergency.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/undertakeremergency.json index 99ad526256b..9f4c84fa933 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/undertakeremergency.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/undertakeremergency.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/remembrance", "requirements": [ { + "type": "minecolonies:building", "building": "graveyard", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_boots" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_boots", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vaccines.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vaccines.json index c1adf3c6572..30eb59b0c54 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vaccines.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vaccines.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/masks", "requirements": [ { + "type": "minecolonies:building", "building": "hospital", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:egg" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:egg", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/village.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/village.json index d44088854d6..60a1ef03f9f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/village.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/village.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/hamlet", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cooked_beef" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cooked_beef", "quantity": 256 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vines.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vines.json index 593155d4651..a671866ea39 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vines.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vines.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/keen", "requirements": [ { + "type": "minecolonies:building", "building": "residence", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:vine" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:vine", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vitality.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vitality.json index 6de9e9945c2..ee418d8101c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vitality.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/civilian/vitality.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:civilian/resilience", "requirements": [ { + "type": "minecolonies:building", "building": "cook", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_apple" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_apple", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/accuracy.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/accuracy.json index dc1004e3e78..5bcc88e53eb 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/accuracy.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/accuracy.json @@ -9,16 +9,13 @@ "icon": "minecraft:iron_sword", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/agilearcher.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/agilearcher.json index 2c2379c3745..ae341835075 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/agilearcher.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/agilearcher.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:combat/improvedevasion", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 64 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.combat.agilearcher.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/arrowpierce.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/arrowpierce.json index bc138a3d25a..c12c32a7653 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/arrowpierce.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/arrowpierce.json @@ -9,25 +9,18 @@ "parentResearch": "minecolonies:combat/arrowuse", "requirements": [ { + "type": "minecolonies:building", "building": "archery", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:arrow" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:arrow", "quantity": 64 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:redstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:redstone", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/arrowuse.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/arrowuse.json index b63666b5cf8..08cb1a3c90e 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/arrowuse.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/arrowuse.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/taunt", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:arrow" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:arrow", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/avoid.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/avoid.json index 3e013e62c1b..5b4bfc6923b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/avoid.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/avoid.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/regeneration", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/avoidance.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/avoidance.json index c06a3e3bca5..403cb6c9f37 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/avoidance.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/avoidance.json @@ -9,16 +9,13 @@ "icon": "minecraft:shield", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 3 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/boiledleather.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/boiledleather.json index 83aae4e412b..e8f76e2b227 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/boiledleather.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/boiledleather.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/improvedleather", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:leather" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:leather", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/captainoftheguard.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/captainoftheguard.json index e00fad6efe3..6a63c6d09ad 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/captainoftheguard.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/captainoftheguard.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:combat/captaintraining", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:shield" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:shield", "quantity": 27 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/captaintraining.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/captaintraining.json index 5d6c0a5d276..2579ab9bf15 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/captaintraining.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/captaintraining.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/knighttraining", "requirements": [ { + "type": "minecolonies:building", "building": "combatacademy", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:shield" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:shield", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/cleave.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/cleave.json index c3e83066289..55f64be0364 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/cleave.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/cleave.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/powerattack", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 10 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/coffee.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/coffee.json index edad25312a1..a0ce62ee88a 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/coffee.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/coffee.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:combat/tactictraining", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:golden_carrot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:golden_carrot", "quantity": 4 } ], "researchLevel": 2, "subtitle": "com.minecolonies.research.combat.coffee.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/deadlyaim.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/deadlyaim.json index d81c0875cca..fc6dd61c61a 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/deadlyaim.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/deadlyaim.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:combat/woundingshot", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:flint" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:flint", "quantity": 256 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.combat.deadlyaim.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/diamondskin.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/diamondskin.json index a1dd6649b5b..23fb7caf532 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/diamondskin.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/diamondskin.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:combat/steelarmor", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 64 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/dodge.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/dodge.json index 11dbbca1f9d..aee6c90ea21 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/dodge.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/dodge.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/avoidance", "requirements": [ { + "type": "minecolonies:building", "building": "smeltery", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:leather" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:leather", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/druidpotion.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/druidpotion.json index 0e08e8f61e3..bcdb9d63e3f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/druidpotion.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/druidpotion.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/arrowuse", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:mistletoe" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:mistletoe", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/duelist.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/duelist.json index 6cf0d906844..7efe924f226 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/duelist.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/duelist.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/riposte", "requirements": [ { + "type": "minecolonies:building", "building": "smeltery", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/evade.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/evade.json index ea92cddea2e..36072260bf4 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/evade.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/evade.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/avoid", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 8 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/evasion.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/evasion.json index 1408c94b051..d61116a1f29 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/evasion.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/evasion.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/improveddodge", "requirements": [ { + "type": "minecolonies:building", "building": "smeltery", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:leather" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:leather", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/fear.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/fear.json index 46230207f94..1fbec21bda0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/fear.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/fear.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/feint", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 8 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/feint.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/feint.json index be14138ea57..d42585a0385 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/feint.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/feint.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/regeneration", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/flee.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/flee.json index 4ef6955c1fb..d131ca6ec9b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/flee.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/flee.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/evade", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 12 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/fullretreat.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/fullretreat.json index 43e8a9b55c5..d0ab09697f0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/fullretreat.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/fullretreat.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:combat/retreat", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 64 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/hotfoot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/hotfoot.json index eaa84d4fe60..a3fd9eb72da 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/hotfoot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/hotfoot.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:combat/flee", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 64 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedbows.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedbows.json index bdd5a973522..652f4c2d326 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedbows.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedbows.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/tactictraining", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 6 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improveddodge.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improveddodge.json index df39f68ab53..28c093017ac 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improveddodge.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improveddodge.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/dodge", "requirements": [ { + "type": "minecolonies:building", "building": "archery", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:leather" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:leather", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedevasion.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedevasion.json index b63bf42dec4..f8a9d03e1a7 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedevasion.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedevasion.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/evasion", "requirements": [ { + "type": "minecolonies:building", "building": "archery", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedleather.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedleather.json index 46f084683d8..d544f942b70 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedleather.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedleather.json @@ -8,16 +8,13 @@ "icon": "minecraft:leather_helmet", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:leather" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:leather", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedswords.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedswords.json index d273b646836..a51be27b4f4 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedswords.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/improvedswords.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/tactictraining", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 6 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/ironarmor.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/ironarmor.json index a3a602da586..c0e9c9f9db3 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/ironarmor.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/ironarmor.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/ironskin", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/ironskin.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/ironskin.json index 9c632809b50..4d2e3028cf9 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/ironskin.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/ironskin.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/boiledleather", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/knighttraining.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/knighttraining.json index 93b6de1142f..86ab5d206af 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/knighttraining.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/knighttraining.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/squiretraining", "requirements": [ { + "type": "minecolonies:building", "building": "combatacademy", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:shield" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:shield", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/masterbowman.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/masterbowman.json index 9aac957c029..d7cf9b9bf68 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/masterbowman.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/masterbowman.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:combat/rapidshot", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bow" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bow", "quantity": 27 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/masterswordsman.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/masterswordsman.json index 58e061c6b3a..de8a6038c4d 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/masterswordsman.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/masterswordsman.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:combat/provost", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 64 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/mightycleave.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/mightycleave.json index f5ec993aa79..c777e4c61eb 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/mightycleave.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/mightycleave.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/cleave", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/multishot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/multishot.json index c6efa19bc5a..578e9dc9f72 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/multishot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/multishot.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/trickshot", "requirements": [ { + "type": "minecolonies:building", "building": "archery", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bow" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bow", "quantity": 9 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/parry.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/parry.json index 5ea5c8b7169..fad00333131 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/parry.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/parry.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/avoidance", "requirements": [ { + "type": "minecolonies:building", "building": "smeltery", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/penetratingshot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/penetratingshot.json index 9c7b0a1b17e..6fedd091c62 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/penetratingshot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/penetratingshot.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/preciseshot", "requirements": [ { + "type": "minecolonies:building", "building": "archery", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:flint" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:flint", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/piercingshot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/piercingshot.json index f24d93fe98b..7dd48f65696 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/piercingshot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/piercingshot.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/penetratingshot", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 10 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:flint" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:flint", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/platearmor.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/platearmor.json index 81698d80d15..8b48488e9ab 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/platearmor.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/platearmor.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/ironarmor", "requirements": [ { + "type": "minecolonies:mandatory-building", "level": 4, "mandatory-building": "blacksmith" }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/powerattack.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/powerattack.json index 4406fb5f1c1..bfb2f0ff337 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/powerattack.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/powerattack.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/quickdraw", "requirements": [ { + "type": "minecolonies:building", "building": "combatacademy", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 4 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/preciseshot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/preciseshot.json index 7617e88c3e3..ebacc3cafea 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/preciseshot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/preciseshot.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/accuracy", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:flint" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:flint", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/provost.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/provost.json index 6df88e211a3..13b64599d3a 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/provost.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/provost.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/duelist", "requirements": [ { + "type": "minecolonies:building", "building": "combatacademy", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/quickdraw.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/quickdraw.json index abdf810d207..f2553fd6fc0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/quickdraw.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/quickdraw.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/accuracy", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 2 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/rapidshot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/rapidshot.json index a4bf7c3b17f..6e32f8bbeaf 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/rapidshot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/rapidshot.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/multishot", "requirements": [ { + "type": "minecolonies:building", "building": "archery", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bow" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bow", "quantity": 18 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/regeneration.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/regeneration.json index 20ad7b2b0ae..a2682bc3bf2 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/regeneration.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/regeneration.json @@ -10,16 +10,13 @@ "parentResearch": "minecolonies:combat/improvedleather", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/retreat.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/retreat.json index 3bd690afdef..408cc0330da 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/retreat.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/retreat.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/fear", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 12 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/riposte.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/riposte.json index d3a7167240b..a90d63546e5 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/riposte.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/riposte.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/parry", "requirements": [ { + "type": "minecolonies:building", "building": "combatacademy", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/savagestrike.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/savagestrike.json index de53a219999..12be05ab730 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/savagestrike.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/savagestrike.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:combat/mightycleave", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 32 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/squiretraining.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/squiretraining.json index d20b12e5d0d..2d435d1c30c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/squiretraining.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/squiretraining.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/improvedswords", "requirements": [ { + "type": "minecolonies:building", "building": "combatacademy", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:shield" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:shield", "quantity": 4 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/standard.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/standard.json index 0fb1852a985..6e141d956ab 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/standard.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/standard.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/telescope", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/steelarmor.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/steelarmor.json index c1a8519c456..eb1fce2b89c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/steelarmor.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/steelarmor.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/ironarmor", "requirements": [ { + "type": "minecolonies:building", "building": "townhall", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/tactictraining.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/tactictraining.json index 25fb460b37f..faca3e1bd61 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/tactictraining.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/tactictraining.json @@ -8,16 +8,13 @@ "icon": "minecolonies:blockhutbarrackstower", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 3 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/taunt.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/taunt.json index 920e2c62354..917bfed2e6d 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/taunt.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/taunt.json @@ -8,34 +8,23 @@ "icon": "minecraft:chain", "requirements": [ { + "type": "minecolonies:building", "building": "guardtower", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:rotten_flesh" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:rotten_flesh", "quantity": 8 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bone", "quantity": 8 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:spider_eye" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:spider_eye", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/telescope.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/telescope.json index f7b5e5423da..4d6b186e677 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/telescope.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/telescope.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/ironskin", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/trickshot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/trickshot.json index ebf85167b2b..085c68a76e1 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/trickshot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/trickshot.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/improvedbows", "requirements": [ { + "type": "minecolonies:building", "building": "archery", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bow" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bow", "quantity": 5 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/whirlwind.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/whirlwind.json index 5383bde89ee..e2d962b7d93 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/whirlwind.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/whirlwind.json @@ -9,34 +9,23 @@ "parentResearch": "minecolonies:combat/arrowpierce", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:redstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:redstone", "quantity": 64 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:gold_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:gold_ingot", "quantity": 64 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:lapis_lazuli" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:lapis_lazuli", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/woundingshot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/woundingshot.json index e35c5cd52e0..044c4ff1ed2 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/woundingshot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/combat/woundingshot.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:combat/piercingshot", "requirements": [ { + "type": "minecolonies:building", "building": "barracks", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:flint" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:flint", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/ability.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/ability.json index 796a4b8cd46..63b6a1d4df1 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/ability.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/ability.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/hittingiron", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/alchemist.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/alchemist.json index 9163e3cb2ed..426017869fd 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/alchemist.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/alchemist.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:technology/opennether", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:nether_wart" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:nether_wart", "quantity": 16 } ], "researchLevel": 3, "subtitle": "com.minecolonies.research.technology.alchemist.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/amazingveins.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/amazingveins.json index 8b75b1840f1..f61d52e19f8 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/amazingveins.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/amazingveins.json @@ -9,6 +9,7 @@ "parentResearch": "minecolonies:technology/richveins", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 5 }, diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/biodegradable.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/biodegradable.json index 8a9c3dd1bee..8a5484a873f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/biodegradable.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/biodegradable.json @@ -8,16 +8,13 @@ "icon": "minecolonies:blockhutcomposter", "requirements": [ { + "type": "minecolonies:building", "building": "farmer", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bone_meal" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bone_meal", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/bonemeal.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/bonemeal.json index 5d9b62ed9a5..b55ed967b6d 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/bonemeal.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/bonemeal.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/biodegradable", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:wheat_seeds" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:wheat_seeds", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/buildermodes.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/buildermodes.json index 46619590f5a..037fd232a78 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/buildermodes.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/buildermodes.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/memoryaid", "requirements": [ { + "type": "minecolonies:building", "building": "builder", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond_axe" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond_axe", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/capacity.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/capacity.json index f1b97642314..84ac5b07f30 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/capacity.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/capacity.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/space", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:blockminecoloniesrack" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:blockminecoloniesrack", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/cheatsheet.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/cheatsheet.json index bad9c44b7d2..110a6dc6ce5 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/cheatsheet.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/cheatsheet.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/memoryaid", "requirements": [ { + "type": "minecolonies:building", "building": "sawmill", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:paper" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:paper", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/compost.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/compost.json index 9dd2fa6b1a7..00acd661371 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/compost.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/compost.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/dung", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:wheat_seeds" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:wheat_seeds", "quantity": 256 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/croprotation.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/croprotation.json index d5d30e71708..79779607202 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/croprotation.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/croprotation.json @@ -9,25 +9,18 @@ "parentResearch": "minecolonies:technology/letitgrow", "requirements": [ { + "type": "minecolonies:building", "building": "plantation", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:sugar_cane" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:sugar_cane", "quantity": 32 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cactus" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cactus", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/deeppockets.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/deeppockets.json index 3db64ba5e2e..130dbb2b4f5 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/deeppockets.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/deeppockets.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/cheatsheet", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/depthknowledge.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/depthknowledge.json index b7b5fc1ac7d..21c62034a70 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/depthknowledge.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/depthknowledge.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/rockingroll", "requirements": [ { + "type": "minecolonies:building", "building": "crusher", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:deepslate" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:deepslate", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/diamondcoated.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/diamondcoated.json index 8c629a4e852..ac49bf3f313 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/diamondcoated.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/diamondcoated.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:technology/steelbracing", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 128 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/dung.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/dung.json index 428e5a51d53..b6a5acfca53 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/dung.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/dung.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/bonemeal", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:wheat_seeds" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:wheat_seeds", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/enhanced_gates1.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/enhanced_gates1.json index 7b864221201..b289840cf28 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/enhanced_gates1.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/enhanced_gates1.json @@ -9,32 +9,20 @@ "parentResearch": "minecolonies:technology/whatyaneed", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:gate_wood" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:gate_wood", "quantity": 64 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:ancienttome" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:ancienttome", "quantity": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_block" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_block", "quantity": 5 } ], "researchLevel": 3 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/enhanced_gates2.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/enhanced_gates2.json index 600f606a94f..b2fb592bd00 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/enhanced_gates2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/enhanced_gates2.json @@ -9,32 +9,20 @@ "parentResearch": "minecolonies:technology/enhanced_gates1", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:gate_iron" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:gate_iron", "quantity": 64 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:ancienttome" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:ancienttome", "quantity": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:obsidian" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:obsidian", "quantity": 32 } ], "researchLevel": 4 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/exoticfruits.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/exoticfruits.json index 00f62e2ef47..9026a0a5941 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/exoticfruits.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/exoticfruits.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/letitgrow", "requirements": [ { + "type": "minecolonies:building", "building": "plantation", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:glow_berries" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:glow_berries", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/fertilizer.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/fertilizer.json index 55fb3019084..8f2abfd6c92 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/fertilizer.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/fertilizer.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/compost", "requirements": [ { + "type": "minecolonies:building", "building": "smeltery", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:wheat_seeds" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:wheat_seeds", "quantity": 512 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/flowerpower.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/flowerpower.json index dc17c7a54da..7f80bd89ce7 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/flowerpower.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/flowerpower.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/biodegradable", "requirements": [ { + "type": "minecolonies:building", "building": "composter", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:compost" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:compost", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/fullstock.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/fullstock.json index 460b91bf194..bcadeb6d5b3 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/fullstock.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/fullstock.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/capacity", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:blockminecoloniesrack" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:blockminecoloniesrack", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/gargamel.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/gargamel.json index cef12af5f3b..80a1233d25c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/gargamel.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/gargamel.json @@ -9,29 +9,23 @@ "parentResearch": "minecolonies:technology/croprotation", "requirements": [ { + "type": "minecolonies:building", "building": "plantation", "level": 3 }, { + "type": "minecolonies:building", "building": "netherworker", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:crimson_fungus" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:crimson_fungus", "quantity": 16 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:warped_fungus" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:warped_fungus", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/gildedhammer.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/gildedhammer.json index 8a5cf6f0476..aa01492b283 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/gildedhammer.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/gildedhammer.json @@ -9,34 +9,23 @@ "parentResearch": "minecolonies:technology/rockingroll", "requirements": [ { + "type": "minecolonies:building", "building": "crusher", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:gravel" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:gravel", "quantity": 64 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:sand" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:sand", "quantity": 64 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:clay" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:clay", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/goodveins.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/goodveins.json index 5e369290031..7ef773441b0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/goodveins.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/goodveins.json @@ -9,6 +9,7 @@ "parentResearch": "minecolonies:technology/veinminer", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 2 }, diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hardened.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hardened.json index 794e7f23e66..278714b8e61 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hardened.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hardened.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/strong", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/heavilyloaded.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/heavilyloaded.json index 76fc03f6dd4..74ecb384ec3 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/heavilyloaded.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/heavilyloaded.json @@ -10,14 +10,10 @@ "parentResearch": "minecolonies:technology/loaded", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 256 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/heavymachinery.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/heavymachinery.json index 2c662502449..9975b7200d1 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/heavymachinery.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/heavymachinery.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:technology/redstonepowered", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:redstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:redstone", "quantity": 512 } ], "researchLevel": 4 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hittingiron.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hittingiron.json index b858aeaa87c..981e5d51ca5 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hittingiron.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hittingiron.json @@ -8,16 +8,13 @@ "icon": "minecolonies:blockhutblacksmith", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:anvil" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:anvil", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/honeypot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/honeypot.json index 03560674fe7..b4b1036110f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/honeypot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/honeypot.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/rainbowheaven", "requirements": [ { + "type": "minecolonies:building", "building": "beekeeper", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:beehive" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:beehive", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hot.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hot.json index 42a25df4ebd..e55620f0323 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hot.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hot.json @@ -8,16 +8,13 @@ "icon": "minecolonies:blockhutsmeltery", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:lava_bucket" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:lava_bucket", "quantity": 4 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hotboots.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hotboots.json index f39cf38861d..ee396f82df0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hotboots.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/hotboots.json @@ -9,25 +9,18 @@ "parentResearch": "minecolonies:technology/stringwork", "requirements": [ { + "type": "minecolonies:building", "building": "fletcher", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:leather" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:leather", "quantity": 32 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/isthisredstone.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/isthisredstone.json index 82057e59fc7..a3befb9a697 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/isthisredstone.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/isthisredstone.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:technology/hot", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:redstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:redstone", "quantity": 128 } ], "researchLevel": 2 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/junglemaster.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/junglemaster.json index 8be8504823e..79c8eab007b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/junglemaster.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/junglemaster.json @@ -9,34 +9,23 @@ "parentResearch": "minecolonies:technology/letitgrow", "requirements": [ { + "type": "minecolonies:building", "building": "plantation", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:bamboo" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:bamboo", "quantity": 16 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:cocoa_beans" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:cocoa_beans", "quantity": 16 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:vine" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:vine", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/knowtheend.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/knowtheend.json index f5e93bff6ee..1967ac9f7db 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/knowtheend.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/knowtheend.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/theflintstones", "requirements": [ { + "type": "minecolonies:building", "building": "baker", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:chorus_fruit" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:chorus_fruit", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/letitgrow.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/letitgrow.json index 64778f31103..94820e59613 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/letitgrow.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/letitgrow.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/biodegradable", "requirements": [ { + "type": "minecolonies:building", "building": "farmer", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:compost" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:compost", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/lightning.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/lightning.json index fbacffdbab6..3533dfe758f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/lightning.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/lightning.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:technology/whatisthisspeed", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:redstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:redstone", "quantity": 2048 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.technology.lightning.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/loaded.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/loaded.json index b9a204e6022..9216da14380 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/loaded.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/loaded.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/deeppockets", "requirements": [ { + "type": "minecolonies:building", "building": "library", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:emerald" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:emerald", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/madness.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/madness.json index 7b4e8ceb9e8..41591cea4ec 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/madness.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/madness.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:technology/seemsautomatic", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 1024 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/magiccompost.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/magiccompost.json index f4593a8b1b6..e1d3721578e 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/magiccompost.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/magiccompost.json @@ -9,14 +9,10 @@ "parentResearch": "minecolonies:technology/fertilizer", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:wheat_seeds" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:wheat_seeds", "quantity": 2048 } ], "researchLevel": 6 -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/memoryaid.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/memoryaid.json index 8dcf6628c65..c789f7f59a4 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/memoryaid.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/memoryaid.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/woodwork", "requirements": [ { + "type": "minecolonies:building", "building": "sawmill", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:paper" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:paper", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/morescrolls.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/morescrolls.json index e9922130d7a..52871e9dbea 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/morescrolls.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/morescrolls.json @@ -8,34 +8,23 @@ "icon": "minecolonies:scroll_highlight", "requirements": [ { + "type": "minecolonies:building", "building": "enchanter", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:paper" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:paper", "quantity": 64 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:ancienttome" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:ancienttome", "quantity": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:lapis_lazuli" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:lapis_lazuli", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/netherlog.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/netherlog.json index b650888e1bd..91865915bc9 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/netherlog.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/netherlog.json @@ -9,24 +9,17 @@ "parentResearch": "minecolonies:technology/opennether", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:ender_eye" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:ender_eye", "quantity": 16 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:ancienttome" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:ancienttome", "quantity": 1 }, { + "type": "minecolonies:building", "building": "netherworker", "level": 1 } diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/oceanheart.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/oceanheart.json index df56f7d34cb..05842f2b97b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/oceanheart.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/oceanheart.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/alchemist", "requirements": [ { + "type": "minecolonies:building", "building": "fisherman", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:heart_of_the_sea" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:heart_of_the_sea", "quantity": 1 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/opennether.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/opennether.json index a631a8984c5..de551f72786 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/opennether.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/opennether.json @@ -9,16 +9,12 @@ "parentResearch": "minecolonies:technology/morescrolls", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:gilded_blackstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:gilded_blackstone", "quantity": 3 } ], "researchLevel": 2, "sortOrder": 1, "subtitle": "com.minecolonies.research.technology.opennether.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/pavetheroad.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/pavetheroad.json index 4c7502da6cd..3c5bd407f5b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/pavetheroad.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/pavetheroad.json @@ -9,6 +9,7 @@ "parentResearch": "minecolonies:technology/rockingroll", "requirements": [ { + "type": "minecolonies:building", "building": "crusher", "level": 1 }, diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/podzolchance.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/podzolchance.json index f6f889b3df9..72081c49551 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/podzolchance.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/podzolchance.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/biodegradable", "requirements": [ { + "type": "minecolonies:building", "building": "composter", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:podzol" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:podzol", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/podzolchance2.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/podzolchance2.json index 4043647fd43..ef1cab46510 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/podzolchance2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/podzolchance2.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/podzolchance", "requirements": [ { + "type": "minecolonies:building", "building": "composter", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:podzol" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:podzol", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rainbowheaven.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rainbowheaven.json index 27ab9ab3ff2..c9b61780be7 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rainbowheaven.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rainbowheaven.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/biodegradable", "requirements": [ { + "type": "minecolonies:building", "building": "composter", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:poppy" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:poppy", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rainman.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rainman.json index 0f7208c3efb..e70f1224e84 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rainman.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rainman.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:technology/rtm", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:salmon_bucket" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:salmon_bucket", "quantity": 27 } ], "researchLevel": 6, "subtitle": "com.minecolonies.research.technology.rainman.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/recipebook.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/recipebook.json index df11179bbf3..133e8786610 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/recipebook.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/recipebook.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/cheatsheet", "requirements": [ { + "type": "minecolonies:building", "building": "sawmill", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:paper" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:paper", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/redstonepowered.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/redstonepowered.json index 6deefbf7fd5..efb7529d73f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/redstonepowered.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/redstonepowered.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:technology/isthisredstone", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:redstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:redstone", "quantity": 256 } ], "researchLevel": 3, "subtitle": "com.minecolonies.research.technology.redstonepowered.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/reinforced.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/reinforced.json index cb9ae9d5436..42c42017f8b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/reinforced.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/reinforced.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/hardened", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 32 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/richveins.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/richveins.json index f077c7458a7..2dda42ef77d 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/richveins.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/richveins.json @@ -9,6 +9,7 @@ "parentResearch": "minecolonies:technology/goodveins", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 4 }, diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rockingroll.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rockingroll.json index 25189458f94..ddb76762257 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rockingroll.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rockingroll.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/stonecake", "requirements": [ { + "type": "minecolonies:building", "building": "stonemason", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:stone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:stone", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rtm.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rtm.json index c798fb72e27..f420b3f63a0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rtm.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/rtm.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/recipebook", "requirements": [ { + "type": "minecolonies:building", "building": "sawmill", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:paper" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:paper", "quantity": 256 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/seemsautomatic.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/seemsautomatic.json index 34273080f87..6b561db9195 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/seemsautomatic.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/seemsautomatic.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/tools", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 512 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/sieving.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/sieving.json index 61e8f1c5f45..cc92c53c642 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/sieving.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/sieving.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/woodwork", "requirements": [ { + "type": "minecolonies:building", "building": "fisherman", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:string" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:string", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/skills.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/skills.json index 07c253e1e45..859b1792a38 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/skills.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/skills.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/ability", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 128 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/softshoes.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/softshoes.json index b79035d2591..d56fbc69f11 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/softshoes.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/softshoes.json @@ -8,25 +8,17 @@ "icon": "minecraft:leather_boots", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:white_wool" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:white_wool", "quantity": 16 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:feather" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:feather", "quantity": 16 } ], "researchLevel": 1, "sortOrder": 2, "subtitle": "com.minecolonies.research.technology.softshoes.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/space.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/space.json index b45dff12003..40da571cfde 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/space.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/space.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/sieving", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:blockminecoloniesrack" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:blockminecoloniesrack", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/steelbracing.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/steelbracing.json index e7c33968b6b..7236487667b 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/steelbracing.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/steelbracing.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/reinforced", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 5 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/stonecake.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/stonecake.json index 6c735bed0db..fe4e8ac5907 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/stonecake.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/stonecake.json @@ -8,16 +8,13 @@ "icon": "minecolonies:blockhutstonemason", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:chiseled_stone_bricks" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:chiseled_stone_bricks", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/stringwork.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/stringwork.json index a547bd229db..b1dd07fac01 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/stringwork.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/stringwork.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/woodwork", "requirements": [ { + "type": "minecolonies:building", "building": "sawmill", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:string" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:string", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/strong.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/strong.json index 906efa4cc36..6f82e01b547 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/strong.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/strong.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/hittingiron", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:diamond" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:diamond", "quantity": 8 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/takingdivinglessons.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/takingdivinglessons.json index 2c3033daa98..0e7ab06ef26 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/takingdivinglessons.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/takingdivinglessons.json @@ -9,34 +9,23 @@ "parentResearch": "minecolonies:technology/letitgrow", "requirements": [ { + "type": "minecolonies:building", "building": "plantation", "level": 2 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:kelp" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:kelp", "quantity": 16 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:seagrass" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:seagrass", "quantity": 16 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:sea_pickle" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:sea_pickle", "quantity": 16 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/theflintstones.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/theflintstones.json index 97116c20b9a..3fd579e5c16 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/theflintstones.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/theflintstones.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/stonecake", "requirements": [ { + "type": "minecolonies:building", "building": "stonemason", "level": 1 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:brick" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:brick", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/thoselungs.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/thoselungs.json index aa5a62ed9fa..0a6228d9918 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/thoselungs.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/thoselungs.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/hot", "requirements": [ { + "type": "minecolonies:building", "building": "smeltery", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:glass" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:glass", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/tools.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/tools.json index 855599721ae..29a05f89414 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/tools.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/tools.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/skills", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 4 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:iron_ingot" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:iron_ingot", "quantity": 256 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/veinminer.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/veinminer.json index 4dd50757b8b..e73d77fb0e4 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/veinminer.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/veinminer.json @@ -9,6 +9,7 @@ "parentResearch": "minecolonies:technology/hittingiron", "requirements": [ { + "type": "minecolonies:building", "building": "miner", "level": 1 }, diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/warehousemaster.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/warehousemaster.json index 65138e70191..1dce586c244 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/warehousemaster.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/warehousemaster.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/memoryaid", "requirements": [ { + "type": "minecolonies:building", "building": "sawmill", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecolonies:blockminecoloniesrack" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecolonies:blockminecoloniesrack", "quantity": 3 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/whatisthisspeed.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/whatisthisspeed.json index 0c3823e8c6f..ca294a4f804 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/whatisthisspeed.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/whatisthisspeed.json @@ -9,15 +9,11 @@ "parentResearch": "minecolonies:technology/heavymachinery", "requirements": [ { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:redstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:redstone", "quantity": 1024 } ], "researchLevel": 5, "subtitle": "com.minecolonies.research.technology.whatisthisspeed.subtitle" -} \ No newline at end of file +} diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/whatyaneed.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/whatyaneed.json index 194879eeca6..f35e1236e9e 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/whatyaneed.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/whatyaneed.json @@ -9,16 +9,13 @@ "parentResearch": "minecolonies:technology/hittingiron", "requirements": [ { + "type": "minecolonies:building", "building": "blacksmith", "level": 3 }, { - "type": "minecolonies:item_list", - "item": { - "items": [ - "minecraft:redstone" - ] - }, + "type": "minecolonies:item_simple", + "item": "minecraft:redstone", "quantity": 64 } ], diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/woodwork.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/woodwork.json index ef48ff414f1..15ec43316ce 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/woodwork.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/technology/woodwork.json @@ -8,6 +8,7 @@ "icon": "minecolonies:blockhutsawmill", "requirements": [ { + "type": "minecolonies:building", "building": "lumberjack", "level": 3 }, diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/diamondmesh.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/diamondmesh.json index 29b8b8b36dc..a3a4ec0a422 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/diamondmesh.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/diamondmesh.json @@ -12,6 +12,7 @@ "parentResearch": "minecolonies:unlockable/ironmesh", "requirements": [ { + "type": "minecolonies:mandatory-building", "level": 5, "mandatory-building": "sifter" } diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/flintmesh.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/flintmesh.json index 5cb4133fa47..93ff978af6c 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/flintmesh.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/flintmesh.json @@ -12,6 +12,7 @@ "parentResearch": "minecolonies:unlockable/stringmesh", "requirements": [ { + "type": "minecolonies:mandatory-building", "level": 3, "mandatory-building": "sifter" } diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/ironmesh.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/ironmesh.json index 743bf05b696..0c56b5de479 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/ironmesh.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/ironmesh.json @@ -12,6 +12,7 @@ "parentResearch": "minecolonies:unlockable/flintmesh", "requirements": [ { + "type": "minecolonies:mandatory-building", "level": 4, "mandatory-building": "sifter" } diff --git a/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/stringmesh.json b/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/stringmesh.json index f19ef24f6f4..52e1f6485d3 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/stringmesh.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/researches/unlockable/stringmesh.json @@ -11,6 +11,7 @@ "instant": true, "requirements": [ { + "type": "minecolonies:mandatory-building", "level": 1, "mandatory-building": "sifter" } diff --git a/src/main/java/com/minecolonies/api/research/AbstractResearchProvider.java b/src/main/java/com/minecolonies/api/research/AbstractResearchProvider.java index 63673b2dd78..13ea028fe29 100644 --- a/src/main/java/com/minecolonies/api/research/AbstractResearchProvider.java +++ b/src/main/java/com/minecolonies/api/research/AbstractResearchProvider.java @@ -22,8 +22,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import static com.minecolonies.api.research.ModResearchCostTypes.LIST_ITEM_COST_ID; -import static com.minecolonies.api.research.ModResearchCostTypes.TAG_ITEM_COST_ID; +import static com.minecolonies.api.research.ModResearchCostTypes.*; /** * A class for creating the Research-related JSONs, including Research, ResearchEffects, and (optional) Branches. @@ -393,6 +392,7 @@ public Research setIcon(final ResourceLocation texture) private JsonObject makeSafeBuildingProperty(final String propertyType, final String buildingName, final int level) { JsonObject req = new JsonObject(); + req.addProperty("type", new ResourceLocation(Constants.MOD_ID, propertyType).toString()); req.addProperty(propertyType, buildingName); req.addProperty("level", level); return req; @@ -545,7 +545,16 @@ public Research addResearchRequirement(final ResourceLocation researchReq, final */ public Research addItemCost(final Item item, final int count) { - return addItemCost(List.of(item), count); + final JsonArray reqArray = getRequirementsArray(); + + JsonObject req = new JsonObject(); + req.addProperty("type", SIMPLE_ITEM_COST_ID.toString()); + req.addProperty("item", ForgeRegistries.ITEMS.getKey(item).toString()); + req.addProperty("quantity", count); + + reqArray.add(req); + this.json.add("requirements", reqArray); + return this; } /** From 130f64b395e2c5f8f1d0bb0c2753ec41a4d57c91 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Sun, 8 Dec 2024 16:02:26 +0100 Subject: [PATCH 14/33] Pathfixesandhealingchanges (#10330) Fix citizens not stepping up correctly make citizens heal at low saturation still, but at much lower rate --- .../minecolonies/core/entity/citizen/EntityCitizen.java | 8 ++++---- .../core/entity/pathfinding/pathjobs/AbstractPathJob.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index a7525185e56..be1a8ff21d5 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -896,15 +896,15 @@ private void checkHeal() if (getCitizenData() != null && getHealth() < (getCitizenData().getCitizenDiseaseHandler().isSick() ? getMaxHealth() / 3 : getMaxHealth()) && getLastHurtByMob() == null) { final double limitDecrease = getCitizenColonyHandler().getColonyOrRegister().getResearchManager().getResearchEffects().getEffectStrength(SATLIMIT); - + final double citizenSaturation = citizenData.getSaturation(); final double healAmount; - if (citizenData.getSaturation() >= FULL_SATURATION + limitDecrease) + if (citizenSaturation >= FULL_SATURATION + limitDecrease) { healAmount = 2 * (1.0 + getCitizenColonyHandler().getColonyOrRegister().getResearchManager().getResearchEffects().getEffectStrength(REGENERATION)); } - else if (citizenData.getSaturation() < LOW_SATURATION) + else if (citizenSaturation < LOW_SATURATION) { - return; + healAmount = 1 * (citizenSaturation / FULL_SATURATION) / 2.0; } else { diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java index 2e96d3cbfe3..dc0ec86760a 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java @@ -1404,7 +1404,7 @@ private int handleTargetNotPassable(@Nullable final MNode parent, final int x, f } // Check for headroom in the target space - if (!isPassable(x, y + 2, z, false, parent)) + if (!isPassable(x, y + 2, z, true, parent)) { final VoxelShape bb1 = cachedBlockLookup.getBlockState(x, y, z).getCollisionShape(world, tempWorldPos.set(x, y, z)); final VoxelShape bb2 = cachedBlockLookup.getBlockState(x, y + 2, z).getCollisionShape(world, tempWorldPos.set(x, y + 2, z)); @@ -1420,7 +1420,7 @@ private int handleTargetNotPassable(@Nullable final MNode parent, final int x, f } // Check for jump room from the origin space - if (!isPassable(parent.x, parent.y + 2, parent.z, false, parent)) + if (!isPassable(parent.x, parent.y + 2, parent.z, true, parent)) { final VoxelShape bb1 = cachedBlockLookup.getBlockState(x, y, z).getCollisionShape(world, tempWorldPos.set(x, y, z)); final VoxelShape bb2 = cachedBlockLookup.getBlockState(parent.x, parent.y + 2, parent.z).getCollisionShape(world, tempWorldPos.set(parent.x, parent.y + 2, parent.z)); From eb4fd959132d09185149a79052e28297575facca Mon Sep 17 00:00:00 2001 From: Raycoms Date: Sun, 8 Dec 2024 17:37:37 +0100 Subject: [PATCH 15/33] Somefixes (#10513) Fix concrete mixer infinite loop Fix concrete mixer achievement descriptions Cache colony name in the tp scroll & calculate a non in air position --- .../workerbuildings/BuildingSmeltery.java | 20 ------------------- .../crafting/EntityAIConcreteMixer.java | 10 +++++----- .../core/items/AbstractItemScroll.java | 15 ++++++++------ .../core/items/ItemScrollColonyTP.java | 7 ++++++- .../minecolonies/lang/manual_en_us.json | 4 ++-- 5 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingSmeltery.java b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingSmeltery.java index 9fad5a3af52..f1f66498873 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingSmeltery.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/workerbuildings/BuildingSmeltery.java @@ -83,26 +83,6 @@ public int getMaxBuildingLevel() return MAX_BUILDING_LEVEL; } - @SuppressWarnings(MAGIC_NUMBERS_SHOULD_NOT_BE_USED) - public int ingotMultiplier(final int skillLevel, final Random random) - { - switch (getBuildingLevel()) - { - case 1: - return random.nextInt(ONE_HUNDRED_PERCENT - skillLevel / 2) == 0 ? DOUBLE : 1; - case 2: - return random.nextInt(ONE_HUNDRED_PERCENT - skillLevel) == 0 ? DOUBLE : 1; - case 3: - return 2; - case 4: - return random.nextInt(ONE_HUNDRED_PERCENT - skillLevel / 2) == 0 ? TRIPLE : DOUBLE; - case 5: - return random.nextInt(ONE_HUNDRED_PERCENT - skillLevel) == 0 ? TRIPLE : DOUBLE; - default: - return 1; - } - } - public static class SmeltingModule extends AbstractCraftingBuildingModule.Smelting { /** diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java index 65a0268aec7..0917133d94b 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java @@ -118,20 +118,20 @@ private IAIState harvestConcrete() final BlockState blockToMine = world.getBlockState(posToMine); if (mineBlock(posToMine)) { - incrementActionsDoneAndDecSaturation(); - if (currentRequest != null && currentRecipeStorage != null && blockToMine.getBlock().asItem().equals(currentRecipeStorage.getPrimaryOutput().getItem())) { currentRequest.addDelivery(new ItemStack(blockToMine.getBlock(), 1)); job.setCraftCounter(job.getCraftCounter() + 1); if (job.getCraftCounter() >= job.getMaxCraftingCount()) { - job.finishRequest(true); - worker.getCitizenExperienceHandler().addExperience(currentRequest.getRequest().getCount() / 2.0); - currentRequest = null; currentRecipeStorage = null; resetValues(); + if (inventoryNeedsDump() && job.getMaxCraftingCount() == 0 && job.getProgress() == 0 && job.getCraftCounter() == 0 && currentRequest != null) + { + worker.getCitizenExperienceHandler().addExperience(currentRequest.getRequest().getCount() / 2.0); + } + return START_WORKING; } } diff --git a/src/main/java/com/minecolonies/core/items/AbstractItemScroll.java b/src/main/java/com/minecolonies/core/items/AbstractItemScroll.java index 84dce8d63dd..d438ce49fc7 100644 --- a/src/main/java/com/minecolonies/core/items/AbstractItemScroll.java +++ b/src/main/java/com/minecolonies/core/items/AbstractItemScroll.java @@ -34,8 +34,10 @@ */ public abstract class AbstractItemScroll extends AbstractItemMinecolonies { - public static final String TAG_COLONY_DIM = "colony_dim"; - public static final String TAG_BUILDING_POS = "building_pos"; + public static final String TAG_COLONY_DIM = "colony_dim"; + public static final String TAG_BUILDING_POS = "building_pos"; + public static final String TAG_CACHED_COLONY_NAME = "cached_colony_name"; + public static final int FAIL_RESPONSES_TOTAL = 10; /** @@ -125,12 +127,13 @@ public InteractionResult useOn(UseOnContext ctx) final BlockEntity te = ctx.getLevel().getBlockEntity(ctx.getClickedPos()); final ItemStack scroll = ctx.getPlayer().getItemInHand(ctx.getHand()); final CompoundTag compound = checkForCompound(scroll); - if (te instanceof TileEntityColonyBuilding) + if (te instanceof TileEntityColonyBuilding buildingTe) { - compound.putInt(TAG_COLONY_ID, ((AbstractTileEntityColonyBuilding) te).getColonyId()); - compound.putString(TAG_COLONY_DIM, ((AbstractTileEntityColonyBuilding) te).getColony().getWorld().dimension().location().toString()); + compound.putInt(TAG_COLONY_ID, buildingTe.getColonyId()); + compound.putString(TAG_COLONY_DIM, buildingTe.getColony().getWorld().dimension().location().toString()); BlockPosUtil.write(compound, TAG_BUILDING_POS, ctx.getClickedPos()); - MessageUtils.format(MESSAGE_SCROLL_REGISTERED, ((AbstractTileEntityColonyBuilding) te).getColony().getName()).sendTo(ctx.getPlayer()); + MessageUtils.format(MESSAGE_SCROLL_REGISTERED, buildingTe.getColony().getName()).sendTo(ctx.getPlayer()); + compound.putString(TAG_CACHED_COLONY_NAME, buildingTe.getColony().getName()); } return InteractionResult.SUCCESS; diff --git a/src/main/java/com/minecolonies/core/items/ItemScrollColonyTP.java b/src/main/java/com/minecolonies/core/items/ItemScrollColonyTP.java index 53d3296ec2d..df769e50c66 100644 --- a/src/main/java/com/minecolonies/core/items/ItemScrollColonyTP.java +++ b/src/main/java/com/minecolonies/core/items/ItemScrollColonyTP.java @@ -1,5 +1,6 @@ package com.minecolonies.core.items; +import com.ldtteam.structurize.util.BlockUtils; import com.minecolonies.api.colony.IColony; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.SoundUtils; @@ -61,7 +62,7 @@ protected ItemStack onItemUseSuccess(final ItemStack itemStack, final Level worl player.blockPosition().relative(dir, 10), 5, 5, - (predWorld, predPos) -> predWorld.getBlockState(predPos).isAir() && predWorld.getBlockState(predPos.above()).isAir()); + (predWorld, predPos) -> BlockUtils.isAnySolid(predWorld.getBlockState(predPos.below())) && predWorld.getBlockState(predPos).isAir() && predWorld.getBlockState(predPos.above()).isAir()); if (pos != null) { break; @@ -133,6 +134,10 @@ public void appendHoverText( { colonyDesc = Component.literal(colony.getName()); } + else if (stack.getOrCreateTag().contains(TAG_CACHED_COLONY_NAME)) + { + colonyDesc = Component.literal(stack.getOrCreateTag().getString(TAG_CACHED_COLONY_NAME)); + } final MutableComponent guiHint2 = Component.translatable(TOOL_COLONY_TELEPORT_SCROLL_COLONY_NAME, colonyDesc); guiHint2.setStyle(Style.EMPTY.withColor(ChatFormatting.GOLD)); diff --git a/src/main/resources/assets/minecolonies/lang/manual_en_us.json b/src/main/resources/assets/minecolonies/lang/manual_en_us.json index 5f2e375f588..c2b20000dd0 100644 --- a/src/main/resources/assets/minecolonies/lang/manual_en_us.json +++ b/src/main/resources/assets/minecolonies/lang/manual_en_us.json @@ -1305,9 +1305,9 @@ "advancements.minecolonies.colony_population_75.title": "Town", "advancements.minecolonies.colony_population_75.description": "You settled. You survived. You thrived.", "advancements.minecolonies.build.smeltery_3.title": "Double Trouble!", - "advancements.minecolonies.build.smeltery_3.description": "A level 3 Smeltery has a 100% chance of doubling ore output, nice!", + "advancements.minecolonies.build.smeltery_3.description": "A level 3 Smeltery applies fortune 2 when processing ore blocks, nice!", "advancements.minecolonies.build.smeltery_5.title": "That's Oresome!", - "advancements.minecolonies.build.smeltery_5.description": "A level 5 Smeltery has a chance of tripling every ore output, the chance is equal to the worker's Strength level!", + "advancements.minecolonies.build.smeltery_5.description": "A level 5 Smeltery applies fortune 4 when processing ore blocks, can't do better than that!", "advancements.minecolonies.complete_build_request_5_town_hall.title": "The Masterpiece Centerpiece", "advancements.minecolonies.complete_build_request_5_town_hall.description": "While there's little benefit to having a level 5 Town Hall, it sure does look pretty!", "advancements.minecolonies.build.archery.title": "Bullseye", From 0896b9dedae28af7d267582d006e8281d99dca3f Mon Sep 17 00:00:00 2001 From: someaddons <38401808+someaddons@users.noreply.github.com> Date: Sun, 8 Dec 2024 18:59:54 +0100 Subject: [PATCH 16/33] Raid fixes (#10509) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework raid messages for raid ending, they now got an individual finished message followed by a general victory message for the whole raid Fix campfires getting spawned incorrectly, due to not loading a chunk when required to Reworked North/South directions util, it is now split into 8 sections a 45° to give proper ranges for North/Northeast etc Fix door break speed, research no longer strengthens normal doors and doors break slightly faster with more raiders hitting it. Improved despawn of few remaining raiders to not stall raids for longer than needed Full raid end is now handled by the raid manager Added more message variants to raid end messages Removed attackspeed scaling from archers, as those already scale in attack damage --- .../colony/colonyEvents/IColonyRaidEvent.java | 5 -- .../managers/interfaces/IRaiderManager.java | 5 +- .../minecolonies/api/util/BlockPosUtil.java | 79 +++++++++++++------ .../util/constant/TranslationConstants.java | 13 ++- .../initializer/ModBlocksInitializer.java | 4 +- .../events/raid/AbstractShipRaidEvent.java | 46 +++++------ .../colony/events/raid/HordeRaidEvent.java | 53 ++++--------- .../core/colony/events/raid/RaidManager.java | 46 ++++++++++- .../pirateEvent/DrownedPirateRaidEvent.java | 18 +---- .../pirateEvent/PirateGroundRaidEvent.java | 6 -- .../ai/workers/guard/RangerCombatAI.java | 16 ++-- .../mobs/aitasks/EntityAIBreakDoor.java | 8 +- .../minecolonies/lang/manual_en_us.json | 33 ++++++-- 13 files changed, 191 insertions(+), 141 deletions(-) diff --git a/src/main/java/com/minecolonies/api/colony/colonyEvents/IColonyRaidEvent.java b/src/main/java/com/minecolonies/api/colony/colonyEvents/IColonyRaidEvent.java index 511bc895343..6da3f3be0d9 100755 --- a/src/main/java/com/minecolonies/api/colony/colonyEvents/IColonyRaidEvent.java +++ b/src/main/java/com/minecolonies/api/colony/colonyEvents/IColonyRaidEvent.java @@ -51,9 +51,4 @@ default boolean isRaidActive() { return getStatus() == EventStatus.PROGRESSING ||getStatus() == EventStatus.PREPARING; } - - /** - * Set the raid event to mercy. - */ - void setMercyEnd(); } diff --git a/src/main/java/com/minecolonies/api/colony/managers/interfaces/IRaiderManager.java b/src/main/java/com/minecolonies/api/colony/managers/interfaces/IRaiderManager.java index 69eb2daa687..8d30c447b61 100755 --- a/src/main/java/com/minecolonies/api/colony/managers/interfaces/IRaiderManager.java +++ b/src/main/java/com/minecolonies/api/colony/managers/interfaces/IRaiderManager.java @@ -1,6 +1,7 @@ package com.minecolonies.api.colony.managers.interfaces; import com.minecolonies.api.colony.ICitizenData; +import com.minecolonies.api.colony.colonyEvents.IColonyRaidEvent; import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -206,7 +207,7 @@ default RaidSpawnResult raiderEvent(String raidType, final boolean overrideConfi /** * Gets the amount of citizens lost in a raid. * - * @return weighted amount of list citizen + * @return amount */ int getLostCitizen(); @@ -217,6 +218,8 @@ default RaidSpawnResult raiderEvent(String raidType, final boolean overrideConfi */ void onRaiderDeath(AbstractEntityRaiderMob entity); + void onRaidEventFinished(IColonyRaidEvent event); + /** * Notify raid manager of a passing through raid. */ diff --git a/src/main/java/com/minecolonies/api/util/BlockPosUtil.java b/src/main/java/com/minecolonies/api/util/BlockPosUtil.java index 494a4bb1ee2..6ec59aa69a1 100755 --- a/src/main/java/com/minecolonies/api/util/BlockPosUtil.java +++ b/src/main/java/com/minecolonies/api/util/BlockPosUtil.java @@ -140,11 +140,27 @@ public static BlockPos getRandomPosAround(final BlockPos center, final int dista * @return the BlockPos. */ public static BlockPos getRandomPosition(final Level world, final BlockPos currentPosition, final BlockPos def, final int minDist, final int maxDist) + { + return getRandomPosition(world, currentPosition, def, minDist, maxDist, false); + } + + /** + * Gets a random position within a certain range for wandering around. + * + * @param world the world. + * @param currentPosition the current position. + * @param def the default position if none was found. + * @param minDist the minimum distance of the pos. + * @param maxDist the maximum distance. + * @param load whether chunks should get loaded if needed + * @return the BlockPos. + */ + public static BlockPos getRandomPosition(final Level world, final BlockPos currentPosition, final BlockPos def, final int minDist, final int maxDist, final boolean load) { int tries = 0; BlockPos pos = null; while (pos == null - || !WorldUtil.isEntityBlockLoaded(world, pos) + || !load && !WorldUtil.isEntityBlockLoaded(world, pos) || world.getBlockState(pos).liquid() || !BlockUtils.isAnySolid(world.getBlockState(pos.below())) || (!world.isEmptyBlock(pos) || !world.isEmptyBlock(pos.above()))) @@ -889,46 +905,59 @@ public static DirectionResult calcDirection(@NotNull final BlockPos building, @N { if (pos.getY() > building.getY()) { - direction = DirectionResult.UP; + return DirectionResult.UP; } else if (pos.getY() < building.getY()) { - direction = DirectionResult.DOWN; + return DirectionResult.DOWN; + } + else + { + return DirectionResult.SAME; } } - // If a building is greater or smaller in the Z direction, either return north or south - if (pos.getZ() > building.getZ()) + final int xDiff = building.getX() - pos.getX(); + final int zDiff = building.getZ() - pos.getZ(); + int degree = (int) (Math.atan2(xDiff, zDiff) * 180 / Math.PI); + if (degree < 0) { - direction = DirectionResult.SOUTH; + degree += 360; } - else if (pos.getZ() < building.getZ()) + + if (degree <= 22 || degree >= 338) { direction = DirectionResult.NORTH; } - - // If a building is greater or smaller in the X direction, either return west or east - // If previously already north or south was selected, create a compound direction (north/east etc) - if (pos.getX() > building.getX()) + else if (degree > 22 && degree < 67) + { + direction = DirectionResult.NORTH_WEST; + } + else if (degree >= 67 && degree <= 112) + { + direction = DirectionResult.WEST; + } + else if (degree > 112 && degree < 157) { - direction = switch (direction) - { - case NORTH -> DirectionResult.NORTH_EAST; - case SOUTH -> DirectionResult.SOUTH_EAST; - default -> DirectionResult.EAST; - }; + direction = DirectionResult.SOUTH_WEST; } - else if (pos.getX() < building.getX()) + else if (degree >= 157 && degree <= 202) + { + direction = DirectionResult.SOUTH; + } + else if (degree > 202 && degree < 247) + { + direction = DirectionResult.SOUTH_EAST; + } + else if (degree >= 247 && degree <= 292) + { + direction = DirectionResult.EAST; + } + else { - direction = switch (direction) - { - case NORTH -> DirectionResult.NORTH_WEST; - case SOUTH -> DirectionResult.SOUTH_WEST; - default -> DirectionResult.WEST; - }; + direction = DirectionResult.NORTH_EAST; } - // In case that none of the checks pass (XYZ fully identical to the building), return a component saying the positions are identical return direction; } diff --git a/src/main/java/com/minecolonies/api/util/constant/TranslationConstants.java b/src/main/java/com/minecolonies/api/util/constant/TranslationConstants.java index a9409737970..5a3ddb95359 100755 --- a/src/main/java/com/minecolonies/api/util/constant/TranslationConstants.java +++ b/src/main/java/com/minecolonies/api/util/constant/TranslationConstants.java @@ -206,13 +206,14 @@ public final class TranslationConstants @NonNls public static final String RAID_NORSEMEN = "com.minecolonies.coremod.raid.norsemen.name"; @NonNls - public static final String ONLY_X_BARBARIANS_LEFT_MESSAGE = "com.minecolonies.coremod.barbarians.left"; + public static final String ONLY_X_BARBARIANS_LEFT_MESSAGE = "com.minecolonies.coremod.barbarians.left"; @NonNls - public static final String ALL_BARBARIANS_KILLED_MESSAGE = "com.minecolonies.coremod.barbarians.killed"; + public static final String INDIVIDUAL_RAID_FINISH = "com.minecolonies.coremod.raid.end"; @NonNls - public static final String ALL_BARBARIANS_MERCY_MESSAGE = "com.minecolonies.core.barbarians.mercy"; + public static final String RAID_END_MERCY = "com.minecolonies.core.barbarians.mercy"; + public static final String RAID_END = "com.minecolonies.coremod.barbarians.killed"; @NonNls - public static final String CANT_PLACE_COLONY_TOO_CLOSE_TO_SPAWN = "com.minecolonies.core.founding.tooclosetospawn"; + public static final String CANT_PLACE_COLONY_TOO_CLOSE_TO_SPAWN = "com.minecolonies.core.founding.tooclosetospawn"; @NonNls public static final String CANT_PLACE_COLONY_TOO_FAR_FROM_SPAWN = "com.minecolonies.core.founding.toofarfromspawn"; @NonNls @@ -262,9 +263,7 @@ public final class TranslationConstants @NonNls public static final String CMC_GUI_TOWNHALL_BUILDING_LEVEL = "com.minecolonies.coremod.gui.townhall.buildinglevel"; @NonNls - public static final String PIRATES_SAILING_OFF_MESSAGE = "com.minecolonies.coremod.pirates.sailing.away"; - @NonNls - public static final String DROWNED_PIRATES_SAILING_OFF_MESSAGE = "com.minecolonies.core.drowned_pirates.sailing.away"; + public static final String PIRATES_SAILING_OFF_MESSAGE = "com.minecolonies.coremod.raid.sailing.away"; @NonNls public static final String STRUCTURE_SPAWNER_BREAKS = "com.minecolonies.core.raidevent.spawnerbreaks"; @NonNls diff --git a/src/main/java/com/minecolonies/apiimp/initializer/ModBlocksInitializer.java b/src/main/java/com/minecolonies/apiimp/initializer/ModBlocksInitializer.java index 5bdf889cfcd..acd8971dc7c 100755 --- a/src/main/java/com/minecolonies/apiimp/initializer/ModBlocksInitializer.java +++ b/src/main/java/com/minecolonies/apiimp/initializer/ModBlocksInitializer.java @@ -119,8 +119,8 @@ public static void init(final IForgeRegistry registry) ModBlocks.blockCompostedDirt = new BlockCompostedDirt().registerBlock(registry); ModBlocks.blockColonyBanner = new BlockColonyFlagBanner().registerBlock(registry); ModBlocks.blockColonyWallBanner = new BlockColonyFlagWallBanner().registerBlock(registry); - ModBlocks.blockIronGate = new BlockGate(IRON_GATE, 5f, 6, 8).registerBlock(registry); - ModBlocks.blockWoodenGate = new BlockGate(WOODEN_GATE, 4f, 6, 5).registerBlock(registry); + ModBlocks.blockIronGate = new BlockGate(IRON_GATE, 10f, 6, 8).registerBlock(registry); + ModBlocks.blockWoodenGate = new BlockGate(WOODEN_GATE, 7f, 6, 5).registerBlock(registry); ModBlocks.farmland = new MinecoloniesFarmland(FARMLAND, false, 15.0).registerBlock(registry); ModBlocks.floodedFarmland = new MinecoloniesFarmland(FLOODED_FARMLAND, true, 13.0).registerBlock(registry); diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/AbstractShipRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/AbstractShipRaidEvent.java index 12fa7545e49..4484b84527c 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/AbstractShipRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/AbstractShipRaidEvent.java @@ -14,6 +14,7 @@ import com.minecolonies.api.util.MessageUtils.MessagePriority; import com.minecolonies.api.util.Tuple; import com.minecolonies.api.util.WorldUtil; +import com.minecolonies.api.util.constant.ColonyConstants; import com.minecolonies.core.colony.events.raid.pirateEvent.ShipBasedRaiderUtils; import com.minecolonies.core.colony.events.raid.pirateEvent.ShipSize; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; @@ -311,16 +312,10 @@ public boolean isUnderWater() return false; } - @Override - public void setMercyEnd() - { - // Noop, the sailing away message is fine. - } - @Override public void onFinish() { - MessageUtils.format(PIRATES_SAILING_OFF_MESSAGE, BlockPosUtil.calcDirection(colony.getCenter(), spawnPoint).getLongText(), colony.getName()) + MessageUtils.format(PIRATES_SAILING_OFF_MESSAGE, BlockPosUtil.calcDirection(colony.getCenter(), spawnPoint).getLongText()) .sendTo(colony).forManagers(); for (final Entity entity : raiders.keySet()) { @@ -339,12 +334,22 @@ public void onTileEntityBreak(final BlockEntity te) spawners.remove(te.getBlockPos()); raidBar.setProgress((float) spawners.size() / maxSpawners); - // remove at nightfall after spawners are killed. - if (spawners.isEmpty()) - { - daysToGo = 2; - MessageUtils.format(ALL_PIRATE_SPAWNERS_DESTROYED_MESSAGE, colony.getName()).sendTo(colony).forManagers(); - } + checkRaidEnd(); + } + } + + /** + * Checks if the raid got defeated, announces it and sets the remaining days for the ship + */ + private void checkRaidEnd() + { + if (raiders.isEmpty() && spawners.isEmpty()) + { + status = EventStatus.WAITING; + colony.getRaiderManager().onRaidEventFinished(this); + daysToGo = 1; + MessageUtils.format(INDIVIDUAL_RAID_FINISH + "." + this.getEventTypeID().getPath() + ColonyConstants.rand.nextInt(3), + BlockPosUtil.calcDirection(colony.getCenter(), spawnPoint).getLongText()).sendTo(colony, true).forManagers(); } } @@ -361,26 +366,17 @@ public void onNightFall() @Override public void onEntityDeath(final LivingEntity entity) { - raiders.remove(entity); - if (raiders.isEmpty() && spawners.isEmpty()) - { - status = EventStatus.WAITING; - MessageUtils.format(ALL_PIRATES_KILLED_MESSAGE, colony.getName()).sendTo(colony).forManagers(); - } spawnerThresholdKillTracker++; if (!spawners.isEmpty() && spawnerThresholdKillTracker > maxRaiderCount/maxSpawners) { - MessageUtils.format(STRUCTURE_SPAWNER_BREAKS, colony.getName()).sendTo(colony).forManagers(); colony.getWorld().removeBlock(spawners.remove(0), false); raidBar.setProgress((float) spawners.size() / maxSpawners); spawnerThresholdKillTracker = 0; - if (spawners.isEmpty()) - { - daysToGo = 1; - MessageUtils.format(ALL_PIRATE_SPAWNERS_DESTROYED_MESSAGE, colony.getName()).sendTo(colony).forManagers(); - } } + + raiders.remove(entity); + checkRaidEnd(); } @Override diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/HordeRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/HordeRaidEvent.java index 2f015b9ec41..8e6aae93b66 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/HordeRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/HordeRaidEvent.java @@ -6,13 +6,12 @@ import com.minecolonies.api.colony.colonyEvents.IColonyCampFireRaidEvent; import com.minecolonies.api.colony.colonyEvents.IColonyEvent; import com.minecolonies.api.colony.colonyEvents.IColonyRaidEvent; -import com.minecolonies.api.entity.citizen.happiness.ExpirationBasedHappinessModifier; -import com.minecolonies.api.entity.citizen.happiness.StaticHappinessSupplier; import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; import com.minecolonies.api.entity.mobs.RaiderMobUtils; import com.minecolonies.api.sounds.RaidSounds; import com.minecolonies.api.util.*; import com.minecolonies.api.util.MessageUtils.MessagePriority; +import com.minecolonies.api.util.constant.ColonyConstants; import com.minecolonies.api.util.constant.NbtTagConstants; import com.minecolonies.core.colony.events.raid.barbarianEvent.Horde; import com.minecolonies.core.colony.events.raid.pirateEvent.ShipBasedRaiderUtils; @@ -42,7 +41,6 @@ import static com.minecolonies.api.util.constant.ColonyConstants.SMALL_HORDE_SIZE; import static com.minecolonies.api.util.constant.Constants.TAG_COMPOUND; -import static com.minecolonies.api.util.constant.HappinessConstants.RAIDWITHOUTDEATH; import static com.minecolonies.api.util.constant.NbtTagConstants.*; import static com.minecolonies.api.util.constant.TranslationConstants.*; import static com.minecolonies.core.colony.events.raid.pirateEvent.PirateRaidEvent.TAG_DAYS_LEFT; @@ -134,11 +132,6 @@ public abstract class HordeRaidEvent implements IColonyRaidEvent, IColonyCampFir */ private PathResult spawnPathResult; - /** - * If this was a mercy end. - */ - private boolean mercyEnd = false; - /** * Waypoints helping raiders travel */ @@ -244,12 +237,6 @@ protected void spawnHorde(final BlockPos spawnPos, final IColony colony, final i RaiderMobUtils.spawn(getArcherRaiderType(), numberOfArchers, spawnPos, colony.getWorld(), colony, id); } - @Override - public void setMercyEnd() - { - this.mercyEnd = true; - } - /** * Prepares the horde event, makes them wait at campfires for a while,deciding on their plans. */ @@ -274,7 +261,7 @@ private void spawnCampFires(final BlockPos pos) { for (int tries = 0; tries < 3; tries++) { - BlockPos spawn = BlockPosUtil.getRandomPosition(colony.getWorld(), pos, BlockPos.ZERO, 3, 7); + BlockPos spawn = BlockPosUtil.getRandomPosition(colony.getWorld(), pos, BlockPos.ZERO, 3, 7, true); if (spawn != BlockPos.ZERO) { colony.getWorld().setBlockAndUpdate(spawn, Blocks.CAMPFIRE.defaultBlockState()); @@ -288,6 +275,7 @@ private void spawnCampFires(final BlockPos pos) @Override public void onFinish() { + colony.getRaiderManager().onRaidEventFinished(this); for (final Entity entity : getEntities()) { entity.remove(Entity.RemovalReason.DISCARDED); @@ -300,18 +288,6 @@ public void onFinish() raidBar.setVisible(false); raidBar.removeAllPlayers(); - - if (horde.hordeSize > 0) - { - if (mercyEnd) - { - MessageUtils.format(ALL_BARBARIANS_MERCY_MESSAGE, colony.getName()).sendTo(colony).forManagers(); - } - else - { - MessageUtils.format(ALL_BARBARIANS_KILLED_MESSAGE, colony.getName()).sendTo(colony).forManagers(); - } - } } @Override @@ -435,6 +411,7 @@ public void onUpdate() if (horde.hordeSize <= 0) { status = EventStatus.DONE; + return; } if (!respawns.isEmpty()) @@ -460,8 +437,9 @@ public void onUpdate() } } - if (horde.numberOfBosses + horde.numberOfRaiders + horde.numberOfArchers < Math.round(horde.initialSize * 0.05)) + if (horde.numberOfBosses + horde.numberOfRaiders + horde.numberOfArchers < Math.floor(horde.initialSize * 0.1)) { + announceWin(); status = EventStatus.DONE; } @@ -481,6 +459,15 @@ public void onUpdate() } } + /** + * Sends the winning message + */ + private void announceWin() + { + MessageUtils.format(INDIVIDUAL_RAID_FINISH + "." + this.getEventTypeID().getPath() + ColonyConstants.rand.nextInt(3), + BlockPosUtil.calcDirection(colony.getCenter(), spawnPoint).getLongText()).sendTo(colony, true).forManagers(); + } + /** * Sends the right horde message. */ @@ -499,15 +486,7 @@ protected void sendHordeMessage() if (total == 0) { - MessageUtils.format(ALL_BARBARIANS_KILLED_MESSAGE, colony.getName()).sendTo(colony).forManagers(); - - PlayAudioMessage audio = new PlayAudioMessage(horde.initialSize <= SMALL_HORDE_SIZE ? RaidSounds.VICTORY_EARLY : RaidSounds.VICTORY, SoundSource.RECORDS); - PlayAudioMessage.sendToAll(getColony(), false, true, audio); - - if (colony.getRaiderManager().getLostCitizen() == 0) - { - colony.getCitizenManager().injectModifier(new ExpirationBasedHappinessModifier(RAIDWITHOUTDEATH, 1.0, new StaticHappinessSupplier(2.0), 3)); - } + announceWin(); } else if (total > 0 && total <= SMALL_HORDE_SIZE) { diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/RaidManager.java b/src/main/java/com/minecolonies/core/colony/events/raid/RaidManager.java index 49bda098270..aabbc3a7c18 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/RaidManager.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/RaidManager.java @@ -9,7 +9,10 @@ import com.minecolonies.api.colony.colonyEvents.IColonyRaidEvent; import com.minecolonies.api.colony.managers.interfaces.IRaiderManager; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; +import com.minecolonies.api.entity.citizen.happiness.ExpirationBasedHappinessModifier; +import com.minecolonies.api.entity.citizen.happiness.StaticHappinessSupplier; import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.sounds.RaidSounds; import com.minecolonies.api.util.*; import com.minecolonies.api.util.constant.ColonyConstants; import com.minecolonies.core.MineColonies; @@ -31,6 +34,7 @@ import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobRaiderPathing; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; +import com.minecolonies.core.network.messages.client.PlayAudioMessage; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.nbt.CompoundTag; @@ -38,6 +42,7 @@ import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundSource; import net.minecraft.tags.BiomeTags; import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Player; @@ -54,10 +59,14 @@ import static com.minecolonies.api.util.BlockPosUtil.DOUBLE_AIR_POS_SELECTOR; import static com.minecolonies.api.util.BlockPosUtil.SOLID_AIR_POS_SELECTOR; import static com.minecolonies.api.util.constant.ColonyConstants.BIG_HORDE_SIZE; +import static com.minecolonies.api.util.constant.ColonyConstants.SMALL_HORDE_SIZE; import static com.minecolonies.api.util.constant.ColonyManagerConstants.NO_COLONY_ID; import static com.minecolonies.api.util.constant.Constants.DEFAULT_BARBARIAN_DIFFICULTY; import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND; +import static com.minecolonies.api.util.constant.HappinessConstants.RAIDWITHOUTDEATH; import static com.minecolonies.api.util.constant.NbtTagConstants.*; +import static com.minecolonies.api.util.constant.TranslationConstants.RAID_END; +import static com.minecolonies.api.util.constant.TranslationConstants.RAID_END_MERCY; /** * Handles spawning hostile raid events. @@ -947,7 +956,6 @@ public void onLostCitizen(final ICitizenData citizen) if (event instanceof IColonyRaidEvent raidEvent) { raidEvent.setStatus(EventStatus.DONE); - raidEvent.setMercyEnd(); } } } @@ -1019,6 +1027,42 @@ public void onRaiderDeath(final AbstractEntityRaiderMob entity) } } + @Override + public void onRaidEventFinished(final IColonyRaidEvent finishedRaid) + { + for (final IColonyEvent event : colony.getEventManager().getEvents().values()) + { + if (event instanceof IColonyRaidEvent raidEvent && raidEvent.getStatus() == EventStatus.PROGRESSING) + { + return; + } + } + + if (((double) raidHistories.get(0).lostCitizens / colony.getCitizenManager().getMaxCitizens()) > 0.5) + { + MessageUtils.format(RAID_END_MERCY, colony.getName()).sendTo(colony).forManagers(); + } + else + { + String msgID = RAID_END; + int rng = ColonyConstants.rand.nextInt(3); + if (rng > 0) + { + msgID += rng; + } + + MessageUtils.format(msgID, colony.getName()).sendTo(colony).forManagers(); + } + + PlayAudioMessage audio = new PlayAudioMessage(raidHistories.get(0).raiderAmount <= SMALL_HORDE_SIZE ? RaidSounds.VICTORY_EARLY : RaidSounds.VICTORY, SoundSource.RECORDS); + PlayAudioMessage.sendToAll(colony, false, true, audio); + + if (colony.getRaiderManager().getLostCitizen() == 0) + { + colony.getCitizenManager().injectModifier(new ExpirationBasedHappinessModifier(RAIDWITHOUTDEATH, 1.0, new StaticHappinessSupplier(2.0), 3)); + } + } + /** * List of raid histories * diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/DrownedPirateRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/DrownedPirateRaidEvent.java index c40c61f821c..b5b49130ab7 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/DrownedPirateRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/DrownedPirateRaidEvent.java @@ -16,14 +16,14 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.pathfinder.Path; import org.jetbrains.annotations.NotNull; import static com.minecolonies.api.util.constant.Constants.STORAGE_STYLE; -import static com.minecolonies.api.util.constant.TranslationConstants.*; +import static com.minecolonies.api.util.constant.TranslationConstants.RAID_EVENT_MESSAGE_U_PIRATE; +import static com.minecolonies.api.util.constant.TranslationConstants.RAID_PIRATE; /** * The Pirate raid event, spawns a ship with pirate spawners onboard. @@ -166,18 +166,4 @@ protected void updateRaidBar() super.updateRaidBar(); raidBar.setDarkenScreen(true); } - - @Override - public void onFinish() - { - MessageUtils.format(DROWNED_PIRATES_SAILING_OFF_MESSAGE, BlockPosUtil.calcDirection(colony.getCenter(), spawnPoint).getLongText(), colony.getName()) - .sendTo(colony).forManagers(); - for (final Entity entity : raiders.keySet()) - { - entity.remove(Entity.RemovalReason.DISCARDED); - } - - raidBar.setVisible(false); - raidBar.removeAllPlayers(); - } } diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/PirateGroundRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/PirateGroundRaidEvent.java index a8dc1ec0dd9..5bc1eabf9f6 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/PirateGroundRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/PirateGroundRaidEvent.java @@ -59,12 +59,6 @@ public void onUpdate() super.onUpdate(); } - @Override - public void onFinish() - { - super.onFinish(); - } - @Override public void registerEntity(final Entity entity) { diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java index 811ceb86a82..a409be80f4a 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java @@ -9,10 +9,6 @@ import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.api.util.constant.ColonyConstants; -import com.minecolonies.core.entity.pathfinding.PathfindingUtils; -import com.minecolonies.core.entity.pathfinding.PathingOptions; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.buildings.AbstractBuildingGuards; @@ -22,8 +18,14 @@ import com.minecolonies.core.entity.ai.combat.CombatUtils; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.entity.other.CustomArrowEntity; +import com.minecolonies.core.entity.pathfinding.PathfindingUtils; +import com.minecolonies.core.entity.pathfinding.PathingOptions; import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; -import com.minecolonies.core.entity.pathfinding.pathjobs.*; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobCanSee; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveAwayFromLocation; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveToLocation; +import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; @@ -233,9 +235,7 @@ protected double getAttackDistance() @Override protected int getAttackDelay() { - // TODO: Maybe better for balancing to not increase damage and speed, looks odd and drains arrows/bow durability - final int attackDelay = RANGED_ATTACK_DELAY_BASE - (user.getCitizenData().getCitizenSkillHandler().getLevel(Skill.Adaptability)); - return Math.max(attackDelay, PHYSICAL_ATTACK_DELAY_MIN * 2); + return RANGED_ATTACK_DELAY_BASE; } /** diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/EntityAIBreakDoor.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/EntityAIBreakDoor.java index f37d5dacf69..0de00d2356f 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/EntityAIBreakDoor.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/EntityAIBreakDoor.java @@ -90,15 +90,17 @@ public void tick() } else { - int fasterBreakPerXNearby = 5; + double fasterBreakPerXNearby = 5; - if (mob instanceof AbstractEntityRaiderMob && !mob.level.isClientSide()) + if (mob instanceof AbstractEntityRaiderMob && !mob.level.isClientSide() && mob.level.getBlockState(doorPos).getBlock() instanceof AbstractBlockGate) { final IColony colony = ((AbstractEntityRaiderMob) mob).getColony(); fasterBreakPerXNearby += colony.getResearchManager().getResearchEffects().getEffectStrength(MECHANIC_ENHANCED_GATES); } - breakChance = Math.max(1, + + fasterBreakPerXNearby /= 2; + breakChance = (int) Math.max(1, hardness / (1 + (mob.level.getEntitiesOfClass(AbstractEntityRaiderMob.class, mob.getBoundingBox().inflate(5)).size() / fasterBreakPerXNearby))); } diff --git a/src/main/resources/assets/minecolonies/lang/manual_en_us.json b/src/main/resources/assets/minecolonies/lang/manual_en_us.json index c2b20000dd0..b9da4b5408a 100644 --- a/src/main/resources/assets/minecolonies/lang/manual_en_us.json +++ b/src/main/resources/assets/minecolonies/lang/manual_en_us.json @@ -1005,9 +1005,36 @@ "com.minecolonies.coremod.gui.workerhuts.barbpoints": "Last Barbarian Spawns", "com.minecolonies.coremod.gui.workerhuts.barbpoints.current": "Current Barbarian Position", "com.minecolonies.coremod.barbarians.left": "Only %d raiders left!", - "com.minecolonies.coremod.barbarians.killed": "§2Victory! %s successfully defended against the intruders!", + "com.minecolonies.coremod.barbarians.killed": "§2Victory! %s successfully defended against the invaders!", + "com.minecolonies.coremod.barbarians.killed1": "§2You successfully defended %s against an invasion of raiders, they were a poor match for your defences!", + "com.minecolonies.coremod.barbarians.killed2": "§2Together, the brave defenders of %s stood tall and drove the invaders into the shadows!", + "com.minecolonies.coremod.raid.end.amazon_raid0": "The Amazon Warriors from the %s have been pushed back into the forest.", + "com.minecolonies.coremod.raid.end.barbarian_raid0": "The Barbarians from the %s met their match and were defeated.", + "com.minecolonies.coremod.raid.end.egyptian_raid0": "The Ancient Mummies from the %s have returned to dust.", + "com.minecolonies.coremod.raid.end.norsemen_raid0": "The Norsemen from the %s have departed for Valhalla.", + "com.minecolonies.coremod.raid.end.norsemen_ship_raid0": "The Norsemen's ship from the %s got broken, and its crew now sails for Valhalla.", + "com.minecolonies.coremod.raid.end.pirate_raid0": "The Pirate ship from the %s was sent to Davy Jones' locker!", + "com.minecolonies.coremod.raid.end.drowned_pirate_raid0": "The Drowned Pirates from the %s slinked back into the depths.", + "com.minecolonies.coremod.raid.end.pirate_ground_raid0": "The Pirates from the %s decided that without a ship, a pirate’s life is just a poor career choice.", + "com.minecolonies.coremod.raid.end.amazon_raid1": "The Amazon Warriors from the %s were driven back into the shadows of the forest.", + "com.minecolonies.coremod.raid.end.barbarian_raid1": "The Barbarians from the %s were no match for your defenses and met their end.", + "com.minecolonies.coremod.raid.end.egyptian_raid1": "The Ancient Mummies from the %s fell apart, their plans crumbling like dry parchment.", + "com.minecolonies.coremod.raid.end.norsemen_raid1": "The Norsemen from the %s battled fiercely but were sent to the halls of their gods.", + "com.minecolonies.coremod.raid.end.norsemen_ship_raid1": "The Norsemen’s ship from the %s met the sea’s wrath and will sail no more.", + "com.minecolonies.coremod.raid.end.pirate_raid1": "The Pirate ship from the %s remains adrift, its crew routed and scattered.", + "com.minecolonies.coremod.raid.end.drowned_pirate_raid1": "The Drowned Pirates from the %s returned to their watery graves, their attack in vain.", + "com.minecolonies.coremod.raid.end.pirate_ground_raid1": "The Pirates from the %s fled, swearing to never leave the safety of the sea again.", + "com.minecolonies.coremod.raid.end.amazon_raid2": "The Amazon Warriors from the %s fled, vanishing into the mists of the forest.", + "com.minecolonies.coremod.raid.end.barbarian_raid2": "The Barbarians from the %s retreated, their dreams of conquest shattered.", + "com.minecolonies.coremod.raid.end.egyptian_raid2": "The Ancient Mummies from the %s returned to their tombs, defeated and buried.", + "com.minecolonies.coremod.raid.end.norsemen_raid2": "The Norsemen from the %s faced their reckoning and joined their ancestors in Valhalla.", + "com.minecolonies.coremod.raid.end.norsemen_ship_raid2": "The Norsemen’s ship from the %s lies abandoned, its crew defeated and bound for Valhalla.", + "com.minecolonies.coremod.raid.end.pirate_raid2": "The Pirate ship from the %s is deserted, its plundering days ended in shame.", + "com.minecolonies.coremod.raid.end.drowned_pirate_raid2": "The Drowned Pirates from the %s sank back into the ocean’s depths, forgotten and forlorn.", + "com.minecolonies.coremod.raid.end.pirate_ground_raid2": "The Pirates from the %s decided the land wasn’t for them and retreated to the coast.", "com.minecolonies.coremod.pirates.spawners.destroyed": "%s successfully destroyed all the pirate spawners!", "com.minecolonies.coremod.pirates.killed": "§2Victory! %s rid the seas of the intruders!", + "com.minecolonies.coremod.raid.sailing.away": "The defeated ship in %s disappeared into the depths of the ocean.", "com.minecolonies.coremod.gui.workerhuts.deconstruct": "Deconstruct", "com.minecolonies.coremod.gui.workerhuts.pickup": "Pick Up", "com.minecolonies.coremod.gui.workerhuts.pickup.denied": "You cannot pickup this building.", @@ -1094,9 +1121,6 @@ "item.minecolonies.piratecaptainegg": "Pirate Captain Spawn Egg", "item.minecolonies.mercegg": "Mercenary Spawn Egg", - "com.minecolonies.coremod.pirates.sailing.away": "A pirate ship %s of %s just sailed away to search for another victim.", - "com.minecolonies.core.drowned_pirates.sailing.away": "The sunk shipwreck %s of %s mysteriously disappears back into the depths of the ocean.", - "com.minecolonies.coremod.cook.serve.player": "%s: Here Governor, take this food!", "item.minecolonies.santa_hat": "Santa Hat", @@ -2609,7 +2633,6 @@ "entity.minecolonies.drownedchiefpirate": "Drowned Pirate Chief", "death.attack.entity.minecolonies.drownedchiefpirate": "%s was put to a watery grave by a drowned Pirate Chief", "com.minecolonies.core.exit_interactions": "Exit Interactions", - "com.minecolonies.core.raidevent.spawnerbreaks": "One of the spawners of the raid misteriously broke, it seems you hit some sort of limit", "com.minecolonies.core.crop.cantplant": "You do not possess the necessary knowledge to plant this crop. You should ask a Farmer to plant this for you!", "com.minecolonies.core.item.crop.tooltip": "Ask a Farmer to plant this for you", "com.minecolonies.core.item.crop.tooltip.biome.coldbiomes": "Only suitable for Cold Biomes", From bca16ad8acf7334317c1e78cacba02973500e70a Mon Sep 17 00:00:00 2001 From: MotionlessTrain Date: Sun, 8 Dec 2024 19:00:24 +0100 Subject: [PATCH 17/33] Fix: rotation of pillarwalk4 (#10514) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the rotation of the pillarwalk4. It was 180º rotated compared to the levels 1-3 --- .../infrastructure/roads/pillarwalk4.blueprint | Bin 895 -> 942 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/main/resources/blueprints/minecolonies/jungle/infrastructure/roads/pillarwalk4.blueprint b/src/main/resources/blueprints/minecolonies/jungle/infrastructure/roads/pillarwalk4.blueprint index 2787b804d68467e45f692aea71493cd414423f2e..94de2db9cd873666c7a282f640c5ca8e6fa7c06a 100644 GIT binary patch literal 942 zcmV;f15x}RiwFP!00000|J7GpbJIEy-Z+;!E-BY?puht>G0c<#r3~paPiN*ZXU_2M zk!?BFRJM#H)29D`U(6e@lI_H4n;x130@94v@~&2&_GZZgaGTFNpS3NA86RUcgZ$~3+Lz*OHDwl<*`a1kCEMh-1x zIryAM+t7h7KHD&Wtr@xvcP;I~hNaixhNZXRj-~fu$5I!2yP>C^SAL&1!#BB9`i^Mg!j6qHNn(9y zqi9c%BR}UP!+5$oIafxoVjrS?4%JF$5sTk8*>sVM9SGH(Pm=^+-U%J{t)0U zbaJ8-c*e3=5~XDk8W4L@kVx(2jB_H72|s%MJm3Y*CCju2+mm+#_FpMJv4~0!HbUGe zl`q?9jc?eHj*)ypdW!TbOhjH85fczb1Zl^JAZ;xI$c2Fl6N;8);d`_*Y&OI&TXLa3 zkkLORw=rlJ2#?_T+ZR#v=FM<__w6vCyRQ!pUhM|^`|&Or5^@j>gJ3wMe~TphkFtbH zgw{)$ltP+fAce-&L}s>t3bV7THUhcdjEBd~s&^RStF(GTk!dM7r*ctvHHs_Ptq&VH z;Z$pClJ6mEu+|$)LxnJ_*nWOe>%;^u!%GRyB2@$mGq|wUsAcCw=!F01ysoAi4?GO2 zoJvy|a1O=&Ku2TJxUhL_5{Qe@h(^$j30KsGt`Y^tOeNCIgfycJSH{`L)XXjiPLZRO zEa(Kv&V^8YG!>tNqtvu0j*_(k9Bs_)%VCrfYq!RH7$xUwC~BGOQyDE}n4E)`5FSHY zi+nD+gygs;h9WVw(1l)1LY9qc-1SNiFGiy@W`|nTH%F+4@$PA8^6_6|2qx8hu%`pRGeb!jMtWOHexkF-1vT*E|N3=!J&X(P^h4LjZ zeyQ(f3(Wd5`w|?#i#=9=qdqFvt6m6Y&j0rR&&aF!+pVvh&4sawf87%2o)XZHoqJla z@rg=>erdI#pN7={VDQ<4fyj-=2=^nrAmZJ&ao+b}3vVAOkz-%Pv7)-V3bv}NV86Nw QI_9$W9asOWYFrWk0CZoeId~c>oSH6dO~247Cj;xNkcypp>n~n z4?_{9kuPLSA{y&7g1v~vG!R_GjH(v6ILb7B0>Dh)2=?31=yDNU8b$&YWI6a=MypVR zI=-vWf&Dpp49_fWK-1C#IJERB99en-rT2ZJcPvsbBcrGxN}e*HFRt z2wZ%Rq2hwWLU^+nJ{J+uR5HT($d^>pYn@8c|JA#kSz-1$#{yHHDr9>7}` z_asqTrhx%*E(HnIdBQj+a!B~)r*~bR(nPXYdvG-UHekO=am7L^J!l5FQ7S)F(HfJ< ztUa)ui04m&e<5+5b`@q>YWG*jE{UQk|K&|xWi=jn z==g+6le{>G;(nl}F|b`|4^5DB(eKj`>OI00b)l|Aihj*S>amcf7vst}dq~aftmC8! zO39Q?p`6|d)kjnDB{(uoo8rh=cYvdc`L`NICb4sCEQgVC)S`u8E;YOucfU(IWwi`vvY|rL)`7D2>^nHuX(zhx>KTRxoDH$>!W|#{3PA zZ9{eK0+RK1UqI$?+*tux+a8%Gc5aS27`wB^_GNuqU~U}bdL#};es+vnKwBIu3T)G& zm7ywh{`u&zu^Hy;`Ob1=1&jv`iuua5yOOa2$G>8a2R!@C!`NNrS_LX4CnpadRtR8r!YDGcb0oZ%*K}RH}t`P2rcwfV-X6b0}!9HFzA|gk===BuU`OVD9 VZ)UChW>zs5qu(-cg7oVV004IXuz3Ig From 9700ea5dd3cc78614252a7c727a3e0632f9077bb Mon Sep 17 00:00:00 2001 From: Charbonnier Cylian Date: Sun, 8 Dec 2024 19:18:37 +0100 Subject: [PATCH 18/33] Fix banner crashing client when copying blank vanilia banner and desync in multiplayer (#10500) Fix banner crashing client on banner that didn't have tags (aka blank patterns) Fix server not copying but client did, causing a desync add a explanation on how to copy banner's patterns --- .../render/TileEntityColonyFlagRenderer.java | 2 +- .../core/items/ItemColonyFlagBanner.java | 54 +++++++++---------- .../tileentities/TileEntityColonyFlag.java | 23 ++++---- .../minecolonies/lang/manual_en_us.json | 1 + 4 files changed, 37 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/minecolonies/core/client/render/TileEntityColonyFlagRenderer.java b/src/main/java/com/minecolonies/core/client/render/TileEntityColonyFlagRenderer.java index 64a67ddf7b8..b44078c68cb 100644 --- a/src/main/java/com/minecolonies/core/client/render/TileEntityColonyFlagRenderer.java +++ b/src/main/java/com/minecolonies/core/client/render/TileEntityColonyFlagRenderer.java @@ -53,7 +53,7 @@ public TileEntityColonyFlagRenderer(final BlockEntityRendererProvider.Context co @Override public void render(TileEntityColonyFlag flagIn, float partialTicks, PoseStack transform, MultiBufferSource bufferIn, int combinedLightIn, int combinedOverlayIn) { - List, DyeColor>> list = flagIn.getPatternList(); + List, DyeColor>> list = flagIn.getPatterns(); boolean noWorld = flagIn.getLevel() == null; transform.pushPose(); diff --git a/src/main/java/com/minecolonies/core/items/ItemColonyFlagBanner.java b/src/main/java/com/minecolonies/core/items/ItemColonyFlagBanner.java index cc862589ddd..4f5aa15ba6c 100644 --- a/src/main/java/com/minecolonies/core/items/ItemColonyFlagBanner.java +++ b/src/main/java/com/minecolonies/core/items/ItemColonyFlagBanner.java @@ -2,17 +2,19 @@ import com.minecolonies.api.blocks.ModBlocks; import com.minecolonies.core.tileentities.TileEntityColonyFlag; -import net.minecraft.world.level.block.AbstractBannerBlock; +import com.mojang.datafixers.util.Pair; + import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BannerPatterns; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.BannerItem; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.core.Holder; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; import net.minecraft.world.level.block.entity.BannerBlockEntity; +import net.minecraft.world.level.block.entity.BannerPattern; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.InteractionResult; import net.minecraft.network.chat.Component; @@ -46,38 +48,27 @@ public InteractionResult useOn(UseOnContext context) { // Duplicate the patterns of the banner that was clicked on BlockEntity te = context.getLevel().getBlockEntity(context.getClickedPos()); - BlockState state = context.getLevel().getBlockState(context.getClickedPos()); - ItemStack stack = context.getPlayer().getMainHandItem(); + ItemStack stack = context.getItemInHand(); if (te instanceof BannerBlockEntity || te instanceof TileEntityColonyFlag) { - CompoundTag source; + BannerPattern.Builder patternsBuilder = new BannerPattern.Builder(); + List, DyeColor>> source; + if (te instanceof BannerBlockEntity) { - source = ((BannerBlockEntity) te).getItem() - .getTag().getCompound("BlockEntityTag"); + source = ((BannerBlockEntity) te).getPatterns(); } else { - source = (context.getLevel().isClientSide ? ((TileEntityColonyFlag) te).getItemClient() : ((TileEntityColonyFlag) te).getItemServer()) - .getTag().getCompound("BlockEntityTag"); - } - - ListTag patternList = source.getList(TAG_BANNER_PATTERNS, 10); - - // Set the base pattern, if there wasn't one set. - // This saves us attempting to alter the item itself to change the base color. - if (!patternList.getCompound(0).getString(TAG_SINGLE_PATTERN).equals(BannerPatterns.BASE.location().toString())) - { - CompoundTag nbt = new CompoundTag(); - nbt.putString(TAG_SINGLE_PATTERN, BannerPatterns.BASE.location().toString()); - nbt.putInt(TAG_PATTERN_COLOR, ((AbstractBannerBlock) state.getBlock()).getColor().getId()); - patternList.add(0, nbt); + source = ((TileEntityColonyFlag) te).getPatterns(); } - CompoundTag tag = stack.getOrCreateTagElement("BlockEntityTag"); - tag.put(TAG_BANNER_PATTERNS, patternList); + CompoundTag bannerPattern = new CompoundTag(); + source.forEach((pattern) -> patternsBuilder.addPattern(pattern.getFirst(), pattern.getSecond())); + bannerPattern.put(TAG_BANNER_PATTERNS, patternsBuilder.toListTag()); + stack.addTagElement("BlockEntityTag", bannerPattern); return InteractionResult.SUCCESS; } return super.useOn(context); @@ -86,9 +77,14 @@ public InteractionResult useOn(UseOnContext context) @Override public void appendHoverText(ItemStack stack, @Nullable Level worldIn, List tooltip, TooltipFlag flagIn) { - super.appendHoverText(stack, worldIn, tooltip, flagIn); - - // Remove the base, as they have no translations (Mojang were lazy. Or maybe saving space?) - if (tooltip.size() > 1) tooltip.remove(1); + CompoundTag tag = BlockItem.getBlockEntityData(stack); + if (tag != null && tag.contains(TAG_BANNER_PATTERNS)) + { + super.appendHoverText(stack, worldIn, tooltip, flagIn); + } + else + { + tooltip.add(Component.translatable("com.minecolonies.coremod.item.colony_banner.tooltipempty")); + } } } diff --git a/src/main/java/com/minecolonies/core/tileentities/TileEntityColonyFlag.java b/src/main/java/com/minecolonies/core/tileentities/TileEntityColonyFlag.java index e57afd8b5dc..e3c92d49f67 100644 --- a/src/main/java/com/minecolonies/core/tileentities/TileEntityColonyFlag.java +++ b/src/main/java/com/minecolonies/core/tileentities/TileEntityColonyFlag.java @@ -28,9 +28,6 @@ public class TileEntityColonyFlag extends BlockEntity { - /** The last known flag. Required for when the colony is not available. */ - private ListTag flag = new ListTag(); - /** A list of the default banner patterns, for colonies that have not chosen a flag */ private ListTag patterns = new ListTag(); @@ -44,7 +41,6 @@ public void saveAdditional(CompoundTag compound) { super.saveAdditional(compound); - compound.put(TAG_FLAG_PATTERNS, this.flag); compound.put(TAG_BANNER_PATTERNS, this.patterns); compound.putInt(TAG_COLONY_ID, colonyId); @@ -55,7 +51,6 @@ public void load(CompoundTag compound) { super.load(compound); - this.flag = compound.getList(TAG_FLAG_PATTERNS, 10); this.patterns = compound.getList(TAG_BANNER_PATTERNS, 10); this.colonyId = compound.getInt(TAG_COLONY_ID); @@ -87,27 +82,29 @@ public void onDataPacket(final Connection net, final ClientboundBlockEntityDataP } /** - * Retrieves the patterns for the renderer + * Retrieves the patterns, similar to {@link BannerBlockEntity#getPatterns()} * @return the list of pattern-color pairs */ - @OnlyIn(Dist.CLIENT) - public List, DyeColor>> getPatternList() + public List, DyeColor>> getPatterns() { // Structurize will cause the second condition to be false if (level != null && level.dimension() != null) { IColonyView colony = IColonyManager.getInstance().getColonyView(this.colonyId, level.dimension()); - if (colony != null && this.flag != colony.getColonyFlag()) + if (colony != null && this.patterns != colony.getColonyFlag()) { - this.flag = colony.getColonyFlag(); + this.patterns = colony.getColonyFlag(); setChanged(); } } - return BannerBlockEntity.createPatterns( + List, DyeColor>> pattern = BannerBlockEntity.createPatterns( DyeColor.WHITE, - this.flag.size() > 1 ? this.flag : this.patterns + this.patterns ); + //remove the first base layer + pattern.remove(0); + return pattern; } /** @@ -118,7 +115,7 @@ public List, DyeColor>> getPatternList() public ItemStack getItemClient() { ItemStack itemstack = new ItemStack(ModBlocks.blockColonyBanner); - List, DyeColor>> list = getPatternList(); + List, DyeColor>> list = getPatterns(); ListTag nbt = new ListTag(); for (Pair, DyeColor> pair : list) diff --git a/src/main/resources/assets/minecolonies/lang/manual_en_us.json b/src/main/resources/assets/minecolonies/lang/manual_en_us.json index b9da4b5408a..20f4fc361d8 100644 --- a/src/main/resources/assets/minecolonies/lang/manual_en_us.json +++ b/src/main/resources/assets/minecolonies/lang/manual_en_us.json @@ -1945,6 +1945,7 @@ "com.minecolonies.coremod.gui.flag.base_layer": "Base", "com.minecolonies.coremod.gui.townhall.edit_flag": "Edit Colony Flag", "block.minecolonies.colony_banner": "Colony Flag Banner", + "com.minecolonies.coremod.item.colony_banner.tooltipempty": "Right click to copy pattern on the item", "com.minecolonies.coremod.gui.locate": "Locate", "com.minecolonies.coremod.locating": "Successfully located rack with respective item(s).", From 30d6fd5e32643bab6af6b9107d4a7e69ef611d38 Mon Sep 17 00:00:00 2001 From: someaddons <38401808+someaddons@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:52:46 +0100 Subject: [PATCH 19/33] Cornerfixes (#10520) Adjust pathfinding to advance rather than creating a corner when it already exists --- .../pathfinding/pathjobs/AbstractPathJob.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java index dc0ec86760a..4b76b8066f4 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java @@ -728,13 +728,9 @@ protected final void exploreInDirection(final MNode node, int dX, int dY, int dZ node.y + newY - nextY, node.z))) { - dX = 0; - dY = newY - nextY; - dZ = 0; - - nextX = node.x + dX; - nextY = node.y + dY; - nextZ = node.z + dZ; + nextX = node.x; + nextY = node.y + (newY - nextY); + nextZ = node.z; corner = true; } // If we're going down, take the air-corner before going to the lower node @@ -742,10 +738,8 @@ else if (!node.isCornerNode() && newY - node.y < 0 && (dX != 0 || dZ != 0) && (node.parent == null || (node.x != node.parent.x || node.y - 1 != node.parent.y || node.z != node.parent.z))) { - dY = 0; - nextX = node.x + dX; - nextY = node.y + dY; + nextY = node.y; nextZ = node.z + dZ; corner = true; @@ -772,7 +766,19 @@ else if (!node.isCornerNode() && newY - node.y < 0 && (dX != 0 || dZ != 0) && return; } - corner = true; + if (corner && nextNode.parent != null && (nextNode.parent.x != nextX || nextNode.parent.z != nextZ)) + { + // Corner node from different direction already created, skip to using the actual next pos + nextX = node.x + dX; + nextY = newY; + nextZ = node.z + dZ; + nextNode = nodes.get(MNode.computeNodeKey(nextX, nextY, nextZ)); + corner = false; + } + else + { + corner = true; + } } // Current node is already visited, only update nearby costs do not create new nodes @@ -989,7 +995,7 @@ else if (pathingOptions.dropCost != 0) { cost += pathingOptions.traverseToggleAbleCost; } - else if (!onPath && !ShapeUtil.hasCollision(cachedBlockLookup, tempWorldPos.set(x, y, z), state)) + else if (!onPath && ShapeUtil.hasCollision(cachedBlockLookup, tempWorldPos.set(x, y, z), state)) { cost += pathingOptions.walkInShapesCost; } From e187d0c4a2f907cc0f35d1d2adf533c5c94da98f Mon Sep 17 00:00:00 2001 From: Raycoms Date: Mon, 9 Dec 2024 18:13:01 +0100 Subject: [PATCH 20/33] fix 10517 (#10521) Fix clearing trying to reach unreachable places --- .../core/entity/ai/workers/AbstractEntityAIInteract.java | 8 ++++---- .../core/entity/ai/workers/AbstractEntityAIStructure.java | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java index 957ed54662c..b41d475743e 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java @@ -140,7 +140,7 @@ protected final boolean mineBlock(@NotNull final BlockPos blockToMine) * @param safeStand the block we want to stand on to do that * @return true once we're done */ - protected boolean mineBlock(@NotNull final BlockPos blockToMine, @NotNull final BlockPos safeStand) + protected boolean mineBlock(@NotNull final BlockPos blockToMine, @Nullable final BlockPos safeStand) { return mineBlock(blockToMine, safeStand, true, true, null); } @@ -158,7 +158,7 @@ protected boolean mineBlock(@NotNull final BlockPos blockToMine, @NotNull final */ protected final boolean mineBlock( @NotNull final BlockPos blockToMine, - @NotNull final BlockPos safeStand, + @Nullable final BlockPos safeStand, final boolean damageTool, final boolean getDrops, final Runnable blockBreakAction) @@ -287,7 +287,7 @@ protected void triggerMinedBlock(@NotNull final BlockPos position, @NotNull fina * @param safeStand a safe stand to mine from (empty Block!) * @return true if you should wait */ - private boolean checkMiningLocation(@NotNull final BlockPos blockToMine, @NotNull final BlockPos safeStand) + private boolean checkMiningLocation(@NotNull final BlockPos blockToMine, @Nullable final BlockPos safeStand) { final BlockState curBlock = world.getBlockState(blockToMine); @@ -297,7 +297,7 @@ private boolean checkMiningLocation(@NotNull final BlockPos blockToMine, @NotNul return true; } - if (walkToBlock(safeStand) && MathUtils.twoDimDistance(worker.blockPosition(), safeStand) > MIN_WORKING_RANGE) + if (safeStand != null && walkToBlock(safeStand) && MathUtils.twoDimDistance(worker.blockPosition(), safeStand) > MIN_WORKING_RANGE) { return true; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructure.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructure.java index aba1aed1ea4..e7655f8f098 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructure.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructure.java @@ -460,7 +460,6 @@ protected IAIState structureStep() if (result.getBlockResult().getResult() == BlockPlacementResult.Result.FINISHED) { - building.nextStage(); if (!goToNextStage(result)) { @@ -671,7 +670,7 @@ public IAIState doMining() return getState(); } - if (!mineBlock(blockToMine, getCurrentWorkingPosition())) + if (!mineBlock(blockToMine, null)) { worker.swing(InteractionHand.MAIN_HAND); return getState(); From 102dc511c03df589c80fcf68e8b8ec4352fb0261 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Wed, 11 Dec 2024 20:03:43 +0100 Subject: [PATCH 21/33] Dontcrash (#10525) Dont crash with empty stack, but log error so we can find origin more easily. Better log spam than exceptions --- .../colony/requestsystem/requestable/Stack.java | 14 +++++++++++++- .../requestable/crafting/AbstractCrafting.java | 11 +++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/minecolonies/api/colony/requestsystem/requestable/Stack.java b/src/main/java/com/minecolonies/api/colony/requestsystem/requestable/Stack.java index 6f86b2df4bd..e1a6e5dfc00 100755 --- a/src/main/java/com/minecolonies/api/colony/requestsystem/requestable/Stack.java +++ b/src/main/java/com/minecolonies/api/colony/requestsystem/requestable/Stack.java @@ -5,6 +5,7 @@ import com.minecolonies.api.colony.requestsystem.factory.IFactoryController; import com.minecolonies.api.crafting.ItemStorage; import com.minecolonies.api.util.ItemStackUtils; +import com.minecolonies.api.util.Log; import com.minecolonies.api.util.ReflectionUtils; import com.minecolonies.api.util.constant.TypeConstants; import net.minecraft.nbt.CompoundTag; @@ -160,7 +161,7 @@ public Stack(final ItemStack stack, final boolean matchDamage, final boolean mat { if (ItemStackUtils.isEmpty(stack)) { - throw new IllegalArgumentException("Cannot deliver Empty Stack."); + Log.getLogger().error("Created Empty Stack", new Exception()); } this.theStack = stack.copy(); @@ -221,6 +222,11 @@ public static Stack deserialize(final IFactoryController controller, final Compo minCount = compound.getInt(NBT_MINCOUNT); } + if (stack.isEmpty()) + { + Log.getLogger().error("Deserialized bad stack", compound.toString()); + } + return new Stack(stack, matchMeta, matchNBT, result, count, minCount, canBeResolved); } @@ -265,6 +271,12 @@ public static Stack deserialize(final IFactoryController controller, final Frien int count = buffer.readInt(); int minCount = buffer.readInt(); + + if (stack.isEmpty()) + { + Log.getLogger().error("Deserialized bad stack", stack.toString()); + } + return new Stack(stack, matchMeta, matchNBT, result, count, minCount, canBeResolved); } diff --git a/src/main/java/com/minecolonies/api/colony/requestsystem/requestable/crafting/AbstractCrafting.java b/src/main/java/com/minecolonies/api/colony/requestsystem/requestable/crafting/AbstractCrafting.java index 8a54da4f2f0..2bbb89bcd3b 100755 --- a/src/main/java/com/minecolonies/api/colony/requestsystem/requestable/crafting/AbstractCrafting.java +++ b/src/main/java/com/minecolonies/api/colony/requestsystem/requestable/crafting/AbstractCrafting.java @@ -3,6 +3,7 @@ import com.minecolonies.api.colony.requestsystem.requestable.IRequestable; import com.minecolonies.api.colony.requestsystem.token.IToken; import com.minecolonies.api.util.ItemStackUtils; +import com.minecolonies.api.util.Log; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; @@ -57,12 +58,14 @@ public AbstractCrafting(@NotNull final ItemStack stack, final int count, final i this.minCount = minCount; this.recipeToken = recipeToken; - if (ItemStackUtils.isEmpty(stack)) + if (stack.isEmpty()) { - throw new IllegalArgumentException("Cannot deliver Empty Stack."); + Log.getLogger().error("Created Empty Stack", new Exception()); + } + else + { + this.theStack.setCount(Math.min(this.theStack.getCount(), this.theStack.getMaxStackSize())); } - - this.theStack.setCount(Math.min(this.theStack.getCount(), this.theStack.getMaxStackSize())); } @NotNull From 47408b451da18073ab3a6430bd14276bc7968b56 Mon Sep 17 00:00:00 2001 From: Gavin Lambert Date: Thu, 12 Dec 2024 22:51:43 +1300 Subject: [PATCH 22/33] Fix bad loot table path (#10529) Fixes bad loot table path --- .../loot_tables/{loot_tables => }/miner/lucky_ore1.json | 2 +- .../loot_tables/{loot_tables => }/miner/lucky_ore2.json | 2 +- .../loot_tables/{loot_tables => }/miner/lucky_ore3.json | 2 +- .../loot_tables/{loot_tables => }/miner/lucky_ore4.json | 2 +- .../loot_tables/{loot_tables => }/miner/lucky_ore5.json | 2 +- .../entity/ai/workers/production/EntityAIStructureMiner.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename src/datagen/generated/minecolonies/data/minecolonies/loot_tables/{loot_tables => }/miner/lucky_ore1.json (84%) rename src/datagen/generated/minecolonies/data/minecolonies/loot_tables/{loot_tables => }/miner/lucky_ore2.json (90%) rename src/datagen/generated/minecolonies/data/minecolonies/loot_tables/{loot_tables => }/miner/lucky_ore3.json (92%) rename src/datagen/generated/minecolonies/data/minecolonies/loot_tables/{loot_tables => }/miner/lucky_ore4.json (94%) rename src/datagen/generated/minecolonies/data/minecolonies/loot_tables/{loot_tables => }/miner/lucky_ore5.json (94%) diff --git a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore1.json b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore1.json similarity index 84% rename from src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore1.json rename to src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore1.json index 68e1519c018..860997572e0 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore1.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore1.json @@ -17,5 +17,5 @@ "rolls": 1.0 } ], - "random_sequence": "minecolonies:loot_tables/miner/lucky_ore1" + "random_sequence": "minecolonies:miner/lucky_ore1" } \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore2.json b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore2.json similarity index 90% rename from src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore2.json rename to src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore2.json index 2158112901d..aea019e675d 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore2.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore2.json @@ -27,5 +27,5 @@ "rolls": 1.0 } ], - "random_sequence": "minecolonies:loot_tables/miner/lucky_ore2" + "random_sequence": "minecolonies:miner/lucky_ore2" } \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore3.json b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore3.json similarity index 92% rename from src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore3.json rename to src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore3.json index fb6521139a0..c963cd9789e 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore3.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore3.json @@ -37,5 +37,5 @@ "rolls": 1.0 } ], - "random_sequence": "minecolonies:loot_tables/miner/lucky_ore3" + "random_sequence": "minecolonies:miner/lucky_ore3" } \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore4.json b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore4.json similarity index 94% rename from src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore4.json rename to src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore4.json index 63c9fb3f3cd..67afdd3a432 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore4.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore4.json @@ -46,5 +46,5 @@ "rolls": 1.0 } ], - "random_sequence": "minecolonies:loot_tables/miner/lucky_ore4" + "random_sequence": "minecolonies:miner/lucky_ore4" } \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore5.json b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore5.json similarity index 94% rename from src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore5.json rename to src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore5.json index 1577bb6e16b..dcbee353a5f 100644 --- a/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/loot_tables/miner/lucky_ore5.json +++ b/src/datagen/generated/minecolonies/data/minecolonies/loot_tables/miner/lucky_ore5.json @@ -46,5 +46,5 @@ "rolls": 1.0 } ], - "random_sequence": "minecolonies:loot_tables/miner/lucky_ore5" + "random_sequence": "minecolonies:miner/lucky_ore5" } \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIStructureMiner.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIStructureMiner.java index 56dabefd2c9..ee298b7b719 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIStructureMiner.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIStructureMiner.java @@ -72,7 +72,7 @@ public class EntityAIStructureMiner extends AbstractEntityAIStructureWithWorkOrd /** * Lucky ore loot table */ - public static final ResourceLocation LUCKY_ORE_LOOT_TABLE = new ResourceLocation(Constants.MOD_ID, "loot_tables/miner/lucky_ore"); + public static final ResourceLocation LUCKY_ORE_LOOT_TABLE = new ResourceLocation(Constants.MOD_ID, "miner/lucky_ore"); /** * Lead the miner to the other side of the shaft. From d98b6cf224749cd2d304e4c0e62e503dc07e90e5 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Thu, 12 Dec 2024 17:11:05 +0100 Subject: [PATCH 23/33] Write collection size, otherwise results in deserialization failure (#10530) Missing size int to the serialization --- .../com/minecolonies/core/datalistener/DiseasesListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/minecolonies/core/datalistener/DiseasesListener.java b/src/main/java/com/minecolonies/core/datalistener/DiseasesListener.java index 1610eef22ea..388d02331db 100644 --- a/src/main/java/com/minecolonies/core/datalistener/DiseasesListener.java +++ b/src/main/java/com/minecolonies/core/datalistener/DiseasesListener.java @@ -71,6 +71,7 @@ public static void sendGlobalDiseasesPackets(final ServerPlayer player) byteBuf.writeResourceLocation(disease.id()); byteBuf.writeComponent(disease.name()); byteBuf.writeInt(disease.rarity()); + byteBuf.writeInt(disease.cureItems().size()); for (final ItemStorage cureItem : disease.cureItems()) { StandardFactoryController.getInstance().serialize(byteBuf, cureItem); From 8bf39c1a03fd96491b0120d5c4a58538a9bd4cef Mon Sep 17 00:00:00 2001 From: someaddons <38401808+someaddons@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:31:57 +0100 Subject: [PATCH 24/33] Fix citizens not always using toggleables the pathfollow node already advanced (#10532) Fix citizens not always using toggleables when the pathfollow node already advanced Fix citizens not able to pass doors/gates at the end of stairs --- .../entity/ai/minimal/EntityAIInteractToggleAble.java | 7 ++++--- .../core/entity/pathfinding/SurfaceType.java | 9 ++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIInteractToggleAble.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIInteractToggleAble.java index f7d1883d432..1e5a2e433a3 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIInteractToggleAble.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIInteractToggleAble.java @@ -166,7 +166,7 @@ private void checkPathBlocksCollided(final Path path) } final int maxLengthToCheck = Math.min(path.getNextNodeIndex() + LENGTH_TO_CHECK, path.getNodeCount()); - for (int i = Math.max(0, path.getNextNodeIndex() - 1); i < maxLengthToCheck; i++) + for (int i = Math.max(0, path.getNextNodeIndex() - 2); i < maxLengthToCheck; i++) { if (i == path.getNodeCount() - 1) { @@ -249,7 +249,7 @@ private boolean checkPathBlocksBelow() } final int maxLengthToCheck = Math.min(path.getNextNodeIndex() + LENGTH_TO_CHECK, path.getNodeCount()); - for (int i = Math.max(0, path.getNextNodeIndex() - 1); i < maxLengthToCheck; ++i) + for (int i = Math.max(0, path.getNextNodeIndex() - 2); i < maxLengthToCheck; ++i) { final Node pathpoint = path.getNode(i); @@ -275,7 +275,8 @@ else if (i < path.getNodeCount() - 1) { // Check if the next pathing node is below final Node nextPoint = path.getNode(i + 1); - if (pos.getX() == nextPoint.x && pos.getY() > nextPoint.y && pos.getZ() == nextPoint.z) + if ((pos.getX() == nextPoint.x && pos.getY() > nextPoint.y && pos.getZ() == nextPoint.z) || + entity.getY() - pos.getY() > 1) { toggleAblePositions.put(pos, entity.level.getBlockState(pos).getValue(BlockStateProperties.OPEN)); } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/SurfaceType.java b/src/main/java/com/minecolonies/core/entity/pathfinding/SurfaceType.java index f7a80f98ce1..6ff23a51c62 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/SurfaceType.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/SurfaceType.java @@ -67,16 +67,19 @@ public static SurfaceType getSurfaceType(final BlockGetter world, final BlockSta } if (block instanceof FenceBlock - || block instanceof FenceGateBlock || block instanceof WallBlock || block instanceof AbstractBlockMinecoloniesDefault || block instanceof BambooStalkBlock - || block instanceof BambooSaplingBlock - || block instanceof DoorBlock) + || block instanceof BambooSaplingBlock) { return SurfaceType.NOT_PASSABLE; } + if (block instanceof FenceGateBlock || block instanceof DoorBlock) + { + return SurfaceType.DROPABLE; + } + final VoxelShape shape = blockState.getCollisionShape(world, pos); final double maxShapeY = ShapeUtil.max(shape, Direction.Axis.Y); if (maxShapeY < 0.5 && PathfindingUtils.isDangerous(world.getBlockState(pos.below()))) From dd62ae57030a635ac674e767b194ee02b741aefb Mon Sep 17 00:00:00 2001 From: Raycoms Date: Tue, 17 Dec 2024 20:22:48 +0100 Subject: [PATCH 25/33] Feature/camp based mobs (#10533) Add Camp Raiders that can be spawned with spawn eggs and added to spawners Did some refactoring to reduce code duplication. They are their own entities. --- .../minecolonies/damage_type/campamazon.json | 5 + .../damage_type/campamazonchief.json | 5 + .../damage_type/campamazonspearman.json | 5 + .../damage_type/camparcherbarbarian.json | 5 + .../damage_type/camparchermummy.json | 5 + .../damage_type/camparcherpirate.json | 5 + .../damage_type/campbarbarian.json | 5 + .../damage_type/campchiefpirate.json | 5 + .../minecolonies/damage_type/campmummy.json | 5 + .../damage_type/campnorsemenarcher.json | 5 + .../damage_type/campnorsemenchief.json | 5 + .../minecolonies/damage_type/camppharao.json | 5 + .../minecolonies/damage_type/camppirate.json | 5 + .../damage_type/campshieldmaiden.json | 5 + .../damage_type/ccamphiefbarbarian.json | 5 + .../client/render/modeltype/AmazonModel.java | 6 +- .../render/modeltype/EgyptianModel.java | 4 +- .../render/modeltype/NorsemenModel.java | 4 +- .../managers/interfaces/IRaiderManager.java | 4 +- .../api/creativetab/ModCreativeTabs.java | 27 ++ .../minecolonies/api/entity/ModEntities.java | 84 +++- .../entity/ai/combat/threat/ThreatTable.java | 2 +- .../AbstractEntityMinecoloniesMonster.java | 413 ++++++++++++++++++ ... => AbstractEntityMinecoloniesRaider.java} | 279 +----------- .../api/entity/mobs/RaiderMobUtils.java | 10 +- .../mobs/amazons/AbstractEntityAmazon.java | 8 +- .../amazons/AbstractEntityAmazonRaider.java | 63 +++ .../barbarians/AbstractEntityBarbarian.java | 4 +- .../AbstractEntityBarbarianRaider.java | 55 +++ .../AbstractDrownedEntityPirate.java | 25 +- .../AbstractDrownedEntityPirateRaider.java | 118 +++++ .../egyptians/AbstractEntityEgyptian.java | 5 +- .../AbstractEntityEgyptianRaider.java | 63 +++ .../mobs/pirates/AbstractEntityPirate.java | 24 +- .../pirates/AbstractEntityPirateRaider.java | 97 ++++ .../entity/mobs/registry/IMobAIRegistry.java | 24 +- .../mobs/vikings/AbstractEntityNorsemen.java | 24 +- .../vikings/AbstractEntityNorsemenRaider.java | 85 ++++ .../api/sounds/ModSoundEvents.java | 20 +- .../api/util/DamageSourceKeys.java | 16 + .../apiimp/initializer/EntityInitializer.java | 200 +++++++-- .../initializer/ModItemsInitializer.java | 140 +++--- .../com/minecolonies/core/MineColonies.java | 57 ++- .../client/model/raiders/ModelAmazon.java | 4 +- .../model/raiders/ModelAmazonChief.java | 4 +- .../model/raiders/ModelAmazonSpearman.java | 4 +- .../model/raiders/ModelArcherMummy.java | 7 +- .../core/client/model/raiders/ModelMummy.java | 6 +- .../client/model/raiders/ModelPharaoh.java | 26 +- .../mobs/amazon/AbstractRendererAmazon.java | 4 +- .../render/mobs/amazon/RendererAmazon.java | 6 +- .../mobs/amazon/RendererAmazonSpearman.java | 6 +- .../mobs/amazon/RendererChiefAmazon.java | 6 +- .../barbarians/AbstractRendererBarbarian.java | 4 +- .../mobs/barbarians/RendererBarbarian.java | 6 +- .../barbarians/RendererChiefBarbarian.java | 6 +- .../AbstractRendererDrownedPirate.java | 4 +- .../RendererDrownedArcherPirate.java | 6 +- .../RendererDrownedChiefPirate.java | 6 +- .../drownedpirates/RendererDrownedPirate.java | 6 +- .../egyptians/AbstractRendererEgyptian.java | 4 +- .../mobs/egyptians/RendererArcherMummy.java | 6 +- .../render/mobs/egyptians/RendererMummy.java | 6 +- .../render/mobs/egyptians/RendererPharao.java | 6 +- .../norsemen/AbstractRendererNorsemen.java | 4 +- .../mobs/norsemen/RendererArcherNorsemen.java | 6 +- .../mobs/norsemen/RendererChiefNorsemen.java | 6 +- .../RendererShieldmaidenNorsemen.java | 6 +- .../mobs/pirates/AbstractRendererPirate.java | 4 +- .../mobs/pirates/RendererArcherPirate.java | 6 +- .../mobs/pirates/RendererChiefPirate.java | 6 +- .../render/mobs/pirates/RendererPirate.java | 6 +- .../events/raid/AbstractShipRaidEvent.java | 4 +- .../colony/events/raid/HordeRaidEvent.java | 6 +- .../core/colony/events/raid/RaidManager.java | 4 +- .../raid/amazonevent/AmazonRaidEvent.java | 24 +- .../barbarianEvent/BarbarianRaidEvent.java | 24 +- .../raid/egyptianevent/EgyptianRaidEvent.java | 24 +- .../raid/norsemenevent/NorsemenRaidEvent.java | 24 +- .../pirateEvent/PirateGroundRaidEvent.java | 24 +- .../killcommands/CommandKillRaider.java | 6 +- .../journeymap/EventListener.java | 4 +- .../core/entity/ai/combat/CombatUtils.java | 4 +- .../core/entity/mobs/aitasks/CampWalkAI.java | 102 +++++ .../mobs/aitasks/EntityAIBreakDoor.java | 16 +- .../entity/mobs/aitasks/RaiderMeleeAI.java | 7 +- .../entity/mobs/aitasks/RaiderRangedAI.java | 5 +- .../entity/mobs/aitasks/RaiderWalkAI.java | 12 +- .../entity/mobs/amazons/package-info.java | 4 - .../entity/mobs/barbarians/package-info.java | 4 - .../{ => camp}/amazons/EntityAmazonChief.java | 5 +- .../amazons/EntityAmazonSpearman.java | 3 +- .../amazons/EntityArcherAmazon.java | 2 +- .../barbarians/EntityArcherBarbarian.java | 2 +- .../barbarians/EntityBarbarian.java | 2 +- .../barbarians/EntityChiefBarbarian.java | 5 +- .../mobs/camp/barbarians/package-info.java | 4 + .../EntityDrownedArcherPirate.java | 2 +- .../EntityDrownedCaptainPirate.java | 4 +- .../drownedpirates/EntityDrownedPirate.java | 2 +- .../egyptians/EntityArcherMummy.java | 3 +- .../{ => camp}/egyptians/EntityMummy.java | 2 +- .../{ => camp}/egyptians/EntityPharao.java | 4 +- .../mobs/camp/egyptians/package-info.java | 4 + .../norsemen/EntityNorsemenArcher.java | 3 +- .../norsemen/EntityNorsemenChief.java | 4 +- .../norsemen/EntityShieldmaiden.java | 3 +- .../mobs/camp/norsemen/package-info.java | 4 + .../pirates/EntityArcherPirate.java | 3 +- .../pirates/EntityCaptainPirate.java | 4 +- .../mobs/{ => camp}/pirates/EntityPirate.java | 2 +- .../mobs/camp/pirates/package-info.java | 4 + .../entity/mobs/egyptians/package-info.java | 4 - .../entity/mobs/norsemen/package-info.java | 4 - .../entity/mobs/pirates/package-info.java | 4 - .../amazons/EntityAmazonChiefRaider.java | 41 ++ .../amazons/EntityAmazonSpearmanRaider.java | 23 + .../amazons/EntityArcherAmazonRaider.java | 29 ++ .../EntityArcherBarbarianRaider.java | 24 + .../barbarians/EntityBarbarianRaider.java | 24 + .../EntityChiefBarbarianRaider.java | 41 ++ .../mobs/raider/barbarians/package-info.java | 4 + .../EntityDrownedArcherPirateRaider.java | 39 ++ .../EntityDrownedCaptainPirateRaider.java | 44 ++ .../EntityDrownedPirateRaider.java | 36 ++ .../egyptians/EntityArcherMummyRaider.java | 23 + .../raider/egyptians/EntityMummyRaider.java | 26 ++ .../raider/egyptians/EntityPharaoRaider.java | 41 ++ .../mobs/raider/egyptians/package-info.java | 4 + .../norsemen/EntityNorsemenArcherRaider.java | 24 + .../norsemen/EntityNorsemenChiefRaider.java | 40 ++ .../norsemen/EntityShieldmaidenRaider.java | 24 + .../mobs/raider/norsemen/package-info.java | 4 + .../pirates/EntityArcherPirateRaider.java | 23 + .../pirates/EntityCaptainPirateRaider.java | 39 ++ .../raider/pirates/EntityPirateRaider.java | 26 ++ .../mobs/raider/pirates/package-info.java | 4 + .../entity/mobs/registry/MobAIRegistry.java | 49 +-- .../entity/pathfinding/PathfindingUtils.java | 4 +- .../core/event/ClientRegistryHandler.java | 30 ++ .../defaults/DefaultDamageTypeProvider.java | 22 +- .../core/items/ItemChiefSword.java | 4 +- .../minecolonies/lang/manual_en_us.json | 8 + .../models/item/drownedpiratearcheregg.json | 3 + .../models/item/drownedpiratecaptainegg.json | 3 + .../models/item/drownedpirateegg.json | 3 + 146 files changed, 2442 insertions(+), 761 deletions(-) create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazon.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazonchief.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazonspearman.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparcherbarbarian.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparchermummy.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparcherpirate.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campbarbarian.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campchiefpirate.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campmummy.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campnorsemenarcher.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campnorsemenchief.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/camppharao.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/camppirate.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/campshieldmaiden.json create mode 100644 src/datagen/generated/minecolonies/data/minecolonies/damage_type/ccamphiefbarbarian.json create mode 100644 src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesMonster.java rename src/main/java/com/minecolonies/api/entity/mobs/{AbstractEntityRaiderMob.java => AbstractEntityMinecoloniesRaider.java} (64%) create mode 100755 src/main/java/com/minecolonies/api/entity/mobs/amazons/AbstractEntityAmazonRaider.java create mode 100755 src/main/java/com/minecolonies/api/entity/mobs/barbarians/AbstractEntityBarbarianRaider.java create mode 100755 src/main/java/com/minecolonies/api/entity/mobs/drownedpirate/AbstractDrownedEntityPirateRaider.java create mode 100755 src/main/java/com/minecolonies/api/entity/mobs/egyptians/AbstractEntityEgyptianRaider.java create mode 100755 src/main/java/com/minecolonies/api/entity/mobs/pirates/AbstractEntityPirateRaider.java create mode 100755 src/main/java/com/minecolonies/api/entity/mobs/vikings/AbstractEntityNorsemenRaider.java create mode 100644 src/main/java/com/minecolonies/core/entity/mobs/aitasks/CampWalkAI.java delete mode 100755 src/main/java/com/minecolonies/core/entity/mobs/amazons/package-info.java delete mode 100755 src/main/java/com/minecolonies/core/entity/mobs/barbarians/package-info.java rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/amazons/EntityAmazonChief.java (86%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/amazons/EntityAmazonSpearman.java (83%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/amazons/EntityArcherAmazon.java (92%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/barbarians/EntityArcherBarbarian.java (92%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/barbarians/EntityBarbarian.java (91%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/barbarians/EntityChiefBarbarian.java (86%) create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/package-info.java rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/drownedpirates/EntityDrownedArcherPirate.java (95%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/drownedpirates/EntityDrownedCaptainPirate.java (91%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/drownedpirates/EntityDrownedPirate.java (95%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/egyptians/EntityArcherMummy.java (82%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/egyptians/EntityMummy.java (92%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/egyptians/EntityPharao.java (91%) create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/package-info.java rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/norsemen/EntityNorsemenArcher.java (83%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/norsemen/EntityNorsemenChief.java (91%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/norsemen/EntityShieldmaiden.java (83%) create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/package-info.java rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/pirates/EntityArcherPirate.java (83%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/pirates/EntityCaptainPirate.java (90%) rename src/main/java/com/minecolonies/core/entity/mobs/{ => camp}/pirates/EntityPirate.java (93%) create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/package-info.java delete mode 100755 src/main/java/com/minecolonies/core/entity/mobs/egyptians/package-info.java delete mode 100755 src/main/java/com/minecolonies/core/entity/mobs/norsemen/package-info.java delete mode 100755 src/main/java/com/minecolonies/core/entity/mobs/pirates/package-info.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityAmazonChiefRaider.java create mode 100644 src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityAmazonSpearmanRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityArcherAmazonRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityArcherBarbarianRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityBarbarianRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityChiefBarbarianRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/package-info.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedArcherPirateRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedCaptainPirateRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedPirateRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityArcherMummyRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityMummyRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityPharaoRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/package-info.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityNorsemenArcherRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityNorsemenChiefRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityShieldmaidenRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/package-info.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityArcherPirateRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityCaptainPirateRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityPirateRaider.java create mode 100755 src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/package-info.java create mode 100755 src/main/resources/assets/minecolonies/models/item/drownedpiratearcheregg.json create mode 100755 src/main/resources/assets/minecolonies/models/item/drownedpiratecaptainegg.json create mode 100755 src/main/resources/assets/minecolonies/models/item/drownedpirateegg.json diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazon.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazon.json new file mode 100644 index 00000000000..102a971bb4c --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazon.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campamazon", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazonchief.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazonchief.json new file mode 100644 index 00000000000..fac09f1910a --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazonchief.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campamazonchief", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazonspearman.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazonspearman.json new file mode 100644 index 00000000000..a8912fd2f01 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campamazonspearman.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campamazonspearman", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparcherbarbarian.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparcherbarbarian.json new file mode 100644 index 00000000000..fc574fbfbf0 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparcherbarbarian.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.camparcherbarbarian", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparchermummy.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparchermummy.json new file mode 100644 index 00000000000..be9c938ea23 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparchermummy.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.camparchermummy", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparcherpirate.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparcherpirate.json new file mode 100644 index 00000000000..878f74ed22a --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camparcherpirate.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.camparcherpirate", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campbarbarian.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campbarbarian.json new file mode 100644 index 00000000000..6627e84d2ad --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campbarbarian.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campbarbarian", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campchiefpirate.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campchiefpirate.json new file mode 100644 index 00000000000..3c7d0dad1ef --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campchiefpirate.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campchiefpirate", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campmummy.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campmummy.json new file mode 100644 index 00000000000..fee9f1fb7b8 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campmummy.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campmummy", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campnorsemenarcher.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campnorsemenarcher.json new file mode 100644 index 00000000000..6f020583534 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campnorsemenarcher.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campnorsemenarcher", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campnorsemenchief.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campnorsemenchief.json new file mode 100644 index 00000000000..5951fd78c8b --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campnorsemenchief.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campnorsemenchief", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camppharao.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camppharao.json new file mode 100644 index 00000000000..97dcbfc4d10 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camppharao.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.camppharao", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camppirate.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camppirate.json new file mode 100644 index 00000000000..9988292eb28 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/camppirate.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.camppirate", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campshieldmaiden.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campshieldmaiden.json new file mode 100644 index 00000000000..f86d4f84bb3 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/campshieldmaiden.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campshieldmaiden", + "scaling": "always" +} \ No newline at end of file diff --git a/src/datagen/generated/minecolonies/data/minecolonies/damage_type/ccamphiefbarbarian.json b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/ccamphiefbarbarian.json new file mode 100644 index 00000000000..f398aa988d4 --- /dev/null +++ b/src/datagen/generated/minecolonies/data/minecolonies/damage_type/ccamphiefbarbarian.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "entity.minecolonies.campchiefbarbarian", + "scaling": "always" +} \ No newline at end of file diff --git a/src/main/java/com/minecolonies/api/client/render/modeltype/AmazonModel.java b/src/main/java/com/minecolonies/api/client/render/modeltype/AmazonModel.java index 1c8ad91e14b..1487df9e457 100755 --- a/src/main/java/com/minecolonies/api/client/render/modeltype/AmazonModel.java +++ b/src/main/java/com/minecolonies/api/client/render/modeltype/AmazonModel.java @@ -1,6 +1,6 @@ package com.minecolonies.api.client.render.modeltype; -import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelPart; import org.jetbrains.annotations.NotNull; @@ -8,7 +8,7 @@ /** * Amazon model. */ -public class AmazonModel extends HumanoidModel +public class AmazonModel extends HumanoidModel { public AmazonModel(final ModelPart part) { @@ -16,7 +16,7 @@ public AmazonModel(final ModelPart part) } @Override - public void setupAnim(@NotNull final AbstractEntityAmazon entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) + public void setupAnim(@NotNull final AbstractEntityMinecoloniesMonster entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { super.setupAnim(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); head.y -= 3; diff --git a/src/main/java/com/minecolonies/api/client/render/modeltype/EgyptianModel.java b/src/main/java/com/minecolonies/api/client/render/modeltype/EgyptianModel.java index a56f15f0140..57be5d56e03 100755 --- a/src/main/java/com/minecolonies/api/client/render/modeltype/EgyptianModel.java +++ b/src/main/java/com/minecolonies/api/client/render/modeltype/EgyptianModel.java @@ -1,13 +1,13 @@ package com.minecolonies.api.client.render.modeltype; -import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelPart; /** * Egyptian model. */ -public class EgyptianModel extends HumanoidModel +public class EgyptianModel extends HumanoidModel { /** * Create a model of a specific size. diff --git a/src/main/java/com/minecolonies/api/client/render/modeltype/NorsemenModel.java b/src/main/java/com/minecolonies/api/client/render/modeltype/NorsemenModel.java index 3b416d98f3d..2b5d90649dc 100755 --- a/src/main/java/com/minecolonies/api/client/render/modeltype/NorsemenModel.java +++ b/src/main/java/com/minecolonies/api/client/render/modeltype/NorsemenModel.java @@ -1,13 +1,13 @@ package com.minecolonies.api.client.render.modeltype; -import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelPart; /** * Norsemen model. */ -public class NorsemenModel extends HumanoidModel +public class NorsemenModel extends HumanoidModel { /** * Create a model of a specific size. diff --git a/src/main/java/com/minecolonies/api/colony/managers/interfaces/IRaiderManager.java b/src/main/java/com/minecolonies/api/colony/managers/interfaces/IRaiderManager.java index 8d30c447b61..7779794863f 100755 --- a/src/main/java/com/minecolonies/api/colony/managers/interfaces/IRaiderManager.java +++ b/src/main/java/com/minecolonies/api/colony/managers/interfaces/IRaiderManager.java @@ -2,7 +2,7 @@ import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.colonyEvents.IColonyRaidEvent; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -216,7 +216,7 @@ default RaidSpawnResult raiderEvent(String raidType, final boolean overrideConfi * * @param entity */ - void onRaiderDeath(AbstractEntityRaiderMob entity); + void onRaiderDeath(AbstractEntityMinecoloniesRaider entity); void onRaidEventFinished(IColonyRaidEvent event); diff --git a/src/main/java/com/minecolonies/api/creativetab/ModCreativeTabs.java b/src/main/java/com/minecolonies/api/creativetab/ModCreativeTabs.java index a769c8b672f..e92a2585c6c 100755 --- a/src/main/java/com/minecolonies/api/creativetab/ModCreativeTabs.java +++ b/src/main/java/com/minecolonies/api/creativetab/ModCreativeTabs.java @@ -2,6 +2,7 @@ import com.minecolonies.api.blocks.AbstractBlockHut; import com.minecolonies.api.blocks.ModBlocks; +import com.minecolonies.api.entity.ModEntities; import com.minecolonies.api.items.ModItems; import com.minecolonies.api.util.constant.Constants; import net.minecraft.core.Registry; @@ -12,6 +13,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; +import net.minecraftforge.common.ForgeSpawnEggItem; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.RegistryObject; @@ -114,6 +116,31 @@ public final class ModCreativeTabs output.accept(ModItems.sugaryBread); output.accept(ModItems.goldenBread); output.accept(ModItems.chorusBread); + + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_BARBARIAN)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_ARCHERBARBARIAN)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_CHIEFBARBARIAN)); + + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_PIRATE)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_ARCHERPIRATE)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_CHIEFPIRATE)); + + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_MUMMY)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_ARCHERMUMMY)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_PHARAO)); + + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_SHIELDMAIDEN)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_NORSEMEN_ARCHER)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_NORSEMEN_CHIEF)); + + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_AMAZON)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_AMAZONSPEARMAN)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_AMAZONCHIEF)); + + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_DROWNED_PIRATE)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_DROWNED_ARCHERPIRATE)); + output.accept(ForgeSpawnEggItem.fromEntityType(ModEntities.CAMP_DROWNED_CHIEFPIRATE)); + }).build()); public static final RegistryObject FOOD = TAB_REG.register("mcfood", () -> new CreativeModeTab.Builder(CreativeModeTab.Row.TOP, 1) diff --git a/src/main/java/com/minecolonies/api/entity/ModEntities.java b/src/main/java/com/minecolonies/api/entity/ModEntities.java index fec751955b4..52f1d822359 100755 --- a/src/main/java/com/minecolonies/api/entity/ModEntities.java +++ b/src/main/java/com/minecolonies/api/entity/ModEntities.java @@ -1,13 +1,19 @@ package com.minecolonies.api.entity; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazonRaider; import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarian; +import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarianRaider; import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; +import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirateRaider; import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptianRaider; import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirate; +import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirateRaider; import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemenRaider; import com.minecolonies.api.entity.other.MinecoloniesMinecart; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -26,37 +32,37 @@ public class ModEntities public static EntityType MERCENARY; - public static EntityType BARBARIAN; + public static EntityType BARBARIAN; - public static EntityType ARCHERBARBARIAN; + public static EntityType ARCHERBARBARIAN; - public static EntityType CHIEFBARBARIAN; + public static EntityType CHIEFBARBARIAN; - public static EntityType PIRATE; + public static EntityType PIRATE; - public static EntityType CHIEFPIRATE; + public static EntityType CHIEFPIRATE; - public static EntityType ARCHERPIRATE; + public static EntityType ARCHERPIRATE; public static EntityType SITTINGENTITY; - public static EntityType MUMMY; + public static EntityType MUMMY; - public static EntityType PHARAO; + public static EntityType PHARAO; - public static EntityType ARCHERMUMMY; + public static EntityType ARCHERMUMMY; - public static EntityType NORSEMEN_ARCHER; + public static EntityType NORSEMEN_ARCHER; - public static EntityType SHIELDMAIDEN; + public static EntityType SHIELDMAIDEN; - public static EntityType NORSEMEN_CHIEF; + public static EntityType NORSEMEN_CHIEF; - public static EntityType AMAZON; + public static EntityType AMAZON; - public static EntityType AMAZONSPEARMAN; + public static EntityType AMAZONSPEARMAN; - public static EntityType AMAZONCHIEF; + public static EntityType AMAZONCHIEF; public static EntityType MINECART; @@ -68,13 +74,51 @@ public class ModEntities public static EntityType SPEAR; - public static EntityType DROWNED_PIRATE; + public static EntityType DROWNED_PIRATE; - public static EntityType DROWNED_CHIEFPIRATE; + public static EntityType DROWNED_CHIEFPIRATE; - public static EntityType DROWNED_ARCHERPIRATE; + public static EntityType DROWNED_ARCHERPIRATE; - public static List> getRaiders() + // Camp Raiders + + public static EntityType CAMP_BARBARIAN; + + public static EntityType CAMP_ARCHERBARBARIAN; + + public static EntityType CAMP_CHIEFBARBARIAN; + + public static EntityType CAMP_PIRATE; + + public static EntityType CAMP_CHIEFPIRATE; + + public static EntityType CAMP_ARCHERPIRATE; + + public static EntityType CAMP_AMAZON; + + public static EntityType CAMP_AMAZONSPEARMAN; + + public static EntityType CAMP_AMAZONCHIEF; + + public static EntityType CAMP_MUMMY; + + public static EntityType CAMP_PHARAO; + + public static EntityType CAMP_ARCHERMUMMY; + + public static EntityType CAMP_NORSEMEN_ARCHER; + + public static EntityType CAMP_SHIELDMAIDEN; + + public static EntityType CAMP_NORSEMEN_CHIEF; + + public static EntityType CAMP_DROWNED_PIRATE; + + public static EntityType CAMP_DROWNED_CHIEFPIRATE; + + public static EntityType CAMP_DROWNED_ARCHERPIRATE; + + public static List> getRaiders() { return List.of( BARBARIAN, diff --git a/src/main/java/com/minecolonies/api/entity/ai/combat/threat/ThreatTable.java b/src/main/java/com/minecolonies/api/entity/ai/combat/threat/ThreatTable.java index 10572a444dc..5fcac00f55d 100644 --- a/src/main/java/com/minecolonies/api/entity/ai/combat/threat/ThreatTable.java +++ b/src/main/java/com/minecolonies/api/entity/ai/combat/threat/ThreatTable.java @@ -106,7 +106,7 @@ public int getThreatFor(final LivingEntity attacker) } } - return 0; + return -1; } /** diff --git a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesMonster.java b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesMonster.java new file mode 100644 index 00000000000..26b80dfcf8c --- /dev/null +++ b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesMonster.java @@ -0,0 +1,413 @@ +package com.minecolonies.api.entity.mobs; + +import com.minecolonies.api.IMinecoloniesAPI; +import com.minecolonies.api.MinecoloniesAPIProxy; +import com.minecolonies.api.entity.CustomGoalSelector; +import com.minecolonies.api.entity.ai.combat.CombatAIStates; +import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity; +import com.minecolonies.api.entity.ai.combat.threat.ThreatTable; +import com.minecolonies.api.entity.ai.statemachine.states.IState; +import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; +import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickRateStateMachine; +import com.minecolonies.api.entity.other.AbstractFastMinecoloniesEntity; +import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; +import com.minecolonies.api.sounds.RaiderSounds; +import com.minecolonies.api.util.Log; +import com.minecolonies.api.util.MathUtils; +import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; +import com.minecolonies.core.entity.pathfinding.navigation.PathingStuckHandler; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.util.Tuple; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.DamageTypes; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.monster.Enemy; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import net.minecraftforge.common.util.ITeleporter; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; + +import static com.minecolonies.api.entity.citizen.AbstractEntityCitizen.ENTITY_AI_TICKRATE; +import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; +import static com.minecolonies.api.util.constant.NbtTagConstants.*; +import static com.minecolonies.api.util.constant.RaiderConstants.*; + +/** + * Abstract for all villain entities. + */ +public abstract class AbstractEntityMinecoloniesMonster extends AbstractFastMinecoloniesEntity implements IThreatTableEntity, Enemy +{ + /** + * The New PathNavigate navigator. + */ + protected AbstractAdvancedPathNavigate newNavigator; + + /** + * The invulnerability timer for spawning, to prevent suffocate/grouping damage. + */ + private int invulTime = 2 * 20; + + /** + * Texture id of the pirates. + */ + private int textureId; + + /** + * Counts entity collisions + */ + private int collisionCounter = 0; + + /** + * The collision threshold + */ + private final static int COLL_THRESHOLD = 50; + + /** + * The threattable of the mob + */ + private ThreatTable threatTable = new ThreatTable<>(this); + + /** + * Raiders AI statemachine + */ + private ITickRateStateMachine ai = new TickRateStateMachine<>(CombatAIStates.NO_TARGET, e -> Log.getLogger().warn(e), ENTITY_AI_TICKRATE); + + /** + * Initial spawn pos of the entity. + */ + private BlockPos spawnPos = null; + + /** + * Constructor method for Abstract minecolonies mobs. + * + * @param world the world. + * @param type the entity type. + */ + public AbstractEntityMinecoloniesMonster(final EntityType type, final Level world) + { + super(type, world); + this.setPersistenceRequired(); + this.goalSelector = new CustomGoalSelector(this.goalSelector); + this.targetSelector = new CustomGoalSelector(this.targetSelector); + this.xpReward = BARBARIAN_EXP_DROP; + IMinecoloniesAPI.getInstance().getMobAIRegistry().applyToMob(this); + RaiderMobUtils.setEquipment(this); + } + + /** + * Constructor method for Abstract minecolonies mobs. + * + * @param world the world. + * @param type the entity type. + * @param textureCount the texture count. + */ + public AbstractEntityMinecoloniesMonster(final EntityType type, final Level world, final int textureCount) + { + this(type, world); + this.textureId = MathUtils.RANDOM.nextInt(textureCount); + } + + /** + * Ignores cramming + */ + @Override + public void pushEntities() + { + if (collisionCounter > COLL_THRESHOLD) + { + return; + } + + super.pushEntities(); + } + + @Override + public void push(@NotNull final Entity entityIn) + { + if (invulTime > 0) + { + return; + } + + if ((collisionCounter += 3) > COLL_THRESHOLD) + { + if (collisionCounter > (COLL_THRESHOLD * 3)) + { + collisionCounter = 0; + } + + return; + } + + super.push(entityIn); + } + + @Override + public void playAmbientSound() + { + super.playAmbientSound(); + final SoundEvent soundevent = this.getAmbientSound(); + if (soundevent != null && level().random.nextInt(OUT_OF_ONE_HUNDRED) <= ONE) + { + this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch()); + } + } + + + /** + * Get the specific raider type of this raider. + * + * @return the type enum. + */ + public abstract RaiderType getRaiderType(); + + @NotNull + @Override + public AbstractAdvancedPathNavigate getNavigation() + { + if (this.newNavigator == null) + { + this.newNavigator = IPathNavigateRegistry.getInstance().getNavigateFor(this); + this.navigation = newNavigator; + this.newNavigator.setCanFloat(true); + newNavigator.setSwimSpeedFactor(getSwimSpeedFactor()); + this.newNavigator.getPathingOptions().setEnterDoors(true); + newNavigator.getPathingOptions().withDropCost(1D); + newNavigator.getPathingOptions().withJumpCost(1D); + newNavigator.getPathingOptions().setPassDanger(true); + PathingStuckHandler stuckHandler = PathingStuckHandler.createStuckHandler() + .withTakeDamageOnStuck(0.4f) + .withBuildLeafBridges() + .withChanceToByPassMovingAway(0.20) + .withPlaceLadders(); + + if (MinecoloniesAPIProxy.getInstance().getConfig().getServer().raidersbreakblocks.get()) + { + stuckHandler.withBlockBreaks(); + stuckHandler.withCompleteStuckBlockBreak(6); + } + + newNavigator.setStuckHandler(stuckHandler); + } + return newNavigator; + } + + /** + * Get the swim speed factor + * + * @return speed factor + */ + public abstract double getSwimSpeedFactor(); + + @Override + protected SoundEvent getHurtSound(final DamageSource damageSourceIn) + { + return RaiderSounds.raiderSounds.get(getRaiderType()).get(RaiderSounds.RaiderSoundTypes.HURT); + } + + @Override + protected SoundEvent getDeathSound() + { + return RaiderSounds.raiderSounds.get(getRaiderType()).get(RaiderSounds.RaiderSoundTypes.DEATH); + } + + @Nullable + @Override + protected SoundEvent getAmbientSound() + { + return RaiderSounds.raiderSounds.get(getRaiderType()).get(RaiderSounds.RaiderSoundTypes.SAY); + } + + /** + * Prevent raiders from travelling to other dimensions through portals. + */ + @Nullable + @Override + public Entity changeDimension(@NotNull final ServerLevel serverWorld, @NotNull final ITeleporter teleporter) + { + return null; + } + + /** + * Initializes entity stats for a given raidlevel and difficulty + * + * @param baseHealth basehealth for this raid/difficulty + * @param difficulty difficulty + * @param baseDamage basedamage for this raid/difficulty + */ + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage); + + final double armor = difficulty * ARMOR; + this.getAttribute(Attributes.ARMOR).setBaseValue(armor); + + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth); + this.setHealth(this.getMaxHealth()); + } + + @Override + public void aiStep() + { + if (!this.isAlive()) + { + return; + } + + if (this.spawnPos == null && this.blockPosition() != BlockPos.ZERO) + { + this.spawnPos = this.blockPosition(); + } + + updateSwingTime(); + if (collisionCounter > 0) + { + collisionCounter--; + } + + if (level().isClientSide) + { + super.aiStep(); + return; + } + + if (tickCount % ENTITY_AI_TICKRATE == 0) + { + ai.tick(); + } + + super.aiStep(); + } + + @Override + public boolean hurt(@NotNull final DamageSource damageSource, final float damage) + { + if (damageSource.getEntity() instanceof AbstractEntityMinecoloniesMonster) + { + return false; + } + + if (damageSource.getEntity() instanceof LivingEntity attacker) + { + if (threatTable.getThreatFor(attacker) == -1) + { + for (final AbstractEntityMinecoloniesMonster monster : level.getEntitiesOfClass(AbstractEntityMinecoloniesMonster.class, AABB.ofSize(position(), 20,5,20))) + { + monster.threatTable.addThreat(attacker, 0); + } + } + threatTable.addThreat(attacker, (int) damage); + } + + if (damageSource.typeHolder().is(DamageTypes.FELL_OUT_OF_WORLD)) + { + return super.hurt(damageSource, damage); + } + + return super.hurt(damageSource, damage); + } + + /** + * Get the default attributes with their values. + * @return the attribute modifier map. + */ + public static AttributeSupplier.Builder getDefaultAttributes() + { + return LivingEntity.createLivingAttributes() + .add(MOB_ATTACK_DAMAGE.get()) + .add(Attributes.MAX_HEALTH) + .add(Attributes.ARMOR) + .add(Attributes.MOVEMENT_SPEED, MOVEMENT_SPEED) + .add(Attributes.FOLLOW_RANGE, FOLLOW_RANGE * 2) + .add(Attributes.ATTACK_DAMAGE, Attributes.ATTACK_DAMAGE.getDefaultValue()); + } + + @Override + public void addAdditionalSaveData(final CompoundTag compound) + { + if (spawnPos != null) + { + compound.putLong(TAG_SPAWN_POS, spawnPos.asLong()); + } + super.addAdditionalSaveData(compound); + } + + @Override + public void readAdditionalSaveData(final CompoundTag compound) + { + if (compound.contains(TAG_SPAWN_POS)) + { + this.spawnPos = BlockPos.of(compound.getLong(TAG_SPAWN_POS)); + } + super.readAdditionalSaveData(compound); + } + + /** + * Disallow pushing from fluids to prevent stuck + * + * @return + */ + @Override + public boolean isPushedByFluid() + { + return false; + } + + @Override + public ThreatTable getThreatTable() + { + return threatTable; + } + + /** + * Get the AI machine + * + * @return ai statemachine + */ + public ITickRateStateMachine getAI() + { + return ai; + } + + @Override + public int getTeamId() + { + // All raiders are in the same team. You're doomed! + return -1; + } + + /** + * Texture id of the mob. + * @return the texture id. + */ + public int getTextureId() + { + return textureId; + } + + /** + * Getter for the initial spawn pos of the entity. + * @return the pos. + */ + public BlockPos getSpawnPos() + { + return this.spawnPos; + } + + /** + * Get the mobs difficulty + * + * @return difficulty + */ + public double getDifficulty() + { + return 1; + } +} diff --git a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesRaider.java similarity index 64% rename from src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java rename to src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesRaider.java index 6e8df051538..8b50e8825b4 100644 --- a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesRaider.java @@ -8,32 +8,18 @@ import com.minecolonies.api.colony.colonyEvents.IColonyEvent; import com.minecolonies.api.enchants.ModEnchants; import com.minecolonies.api.entity.CustomGoalSelector; -import com.minecolonies.api.entity.ai.combat.CombatAIStates; import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity; -import com.minecolonies.api.entity.ai.combat.threat.ThreatTable; -import com.minecolonies.api.entity.ai.statemachine.states.IState; -import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; -import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickRateStateMachine; -import com.minecolonies.api.entity.other.AbstractFastMinecoloniesEntity; -import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; import com.minecolonies.api.items.IChiefSwordItem; -import com.minecolonies.api.sounds.RaiderSounds; import com.minecolonies.api.util.ColonyUtils; import com.minecolonies.api.util.DamageSourceKeys; -import com.minecolonies.api.util.Log; import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; -import com.minecolonies.core.entity.pathfinding.navigation.PathingStuckHandler; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvent; import net.minecraft.world.DifficultyInstance; import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.*; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; -import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.monster.Enemy; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.enchantment.EnchantmentHelper; @@ -46,8 +32,6 @@ import javax.annotation.Nullable; -import static com.minecolonies.api.entity.citizen.AbstractEntityCitizen.ENTITY_AI_TICKRATE; -import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; import static com.minecolonies.api.util.constant.ColonyManagerConstants.NO_COLONY_ID; import static com.minecolonies.api.util.constant.NbtTagConstants.*; import static com.minecolonies.api.util.constant.RaiderConstants.*; @@ -55,7 +39,7 @@ /** * Abstract for all raider entities. */ -public abstract class AbstractEntityRaiderMob extends AbstractFastMinecoloniesEntity implements IThreatTableEntity, Enemy +public abstract class AbstractEntityMinecoloniesRaider extends AbstractEntityMinecoloniesMonster implements IThreatTableEntity, Enemy { /** * The percent of life taken per damage modifier @@ -107,16 +91,6 @@ public abstract class AbstractEntityRaiderMob extends AbstractFastMinecoloniesEn */ private int currentTick = 0; - /** - * Amount of time the barb got stuck. - */ - private int stuckCounter = 1; - - /** - * Amount of time the barb got stuck. - */ - private int ladderCounter = 0; - /** * The raids event id. */ @@ -157,42 +131,37 @@ public abstract class AbstractEntityRaiderMob extends AbstractFastMinecoloniesEn */ private int collisionCounter = 0; - /** - * The collision threshold - */ - private final static int COLL_THRESHOLD = 50; - private final static String RAID_TEAM = "RAIDERS_TEAM"; - /** * Mob difficulty */ private double difficulty = 1.0d; - /** - * The threattable of the mob - */ - private ThreatTable threatTable = new ThreatTable<>(this); - /** * Last chunk pos. */ private ChunkPos lastChunkPos = null; /** - * Raiders AI statemachine + * Constructor method for Abstract Barbarians. + * + * @param world the world. + * @param type the entity type. */ - private ITickRateStateMachine ai = new TickRateStateMachine<>(CombatAIStates.NO_TARGET, e -> Log.getLogger().warn(e), ENTITY_AI_TICKRATE); + public AbstractEntityMinecoloniesRaider(final EntityType type, final Level world) + { + this(type, world, 1); + } /** * Constructor method for Abstract Barbarians. * * @param world the world. * @param type the entity type. + * @param textureCount texture count. */ - public AbstractEntityRaiderMob(final EntityType type, final Level world) + public AbstractEntityMinecoloniesRaider(final EntityType type, final Level world, final int textureCount) { - super(type, world); - worldTimeAtSpawn = world.getGameTime(); + super(type, world, textureCount); this.setPersistenceRequired(); this.goalSelector = new CustomGoalSelector(this.goalSelector); this.targetSelector = new CustomGoalSelector(this.targetSelector); @@ -202,52 +171,6 @@ public AbstractEntityRaiderMob(final EntityType COLL_THRESHOLD) - { - return; - } - - super.pushEntities(); - } - - @Override - public void push(@NotNull final Entity entityIn) - { - if (invulTime > 0) - { - return; - } - - if ((collisionCounter += 3) > COLL_THRESHOLD) - { - if (collisionCounter > (COLL_THRESHOLD * 3)) - { - collisionCounter = 0; - } - - return; - } - - super.push(entityIn); - } - - @Override - public void playAmbientSound() - { - super.playAmbientSound(); - final SoundEvent soundevent = this.getAmbientSound(); - if (soundevent != null && level().random.nextInt(OUT_OF_ONE_HUNDRED) <= ONE) - { - this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch()); - } - } - @Override public boolean removeWhenFarAway(final double distanceToClosestPlayer) { @@ -271,115 +194,15 @@ private boolean shouldDespawn() return worldTimeAtSpawn != 0 && (level().getGameTime() - worldTimeAtSpawn) >= TICKS_TO_DESPAWN; } - @NotNull - @Override - public AbstractAdvancedPathNavigate getNavigation() - { - if (this.newNavigator == null) - { - this.newNavigator = IPathNavigateRegistry.getInstance().getNavigateFor(this); - this.navigation = newNavigator; - this.newNavigator.setCanFloat(true); - newNavigator.setSwimSpeedFactor(getSwimSpeedFactor()); - this.newNavigator.getPathingOptions().setEnterDoors(true); - newNavigator.getPathingOptions().withDropCost(1D); - newNavigator.getPathingOptions().withJumpCost(1D); - newNavigator.getPathingOptions().setPassDanger(true); - PathingStuckHandler stuckHandler = PathingStuckHandler.createStuckHandler() - .withTakeDamageOnStuck(0.4f) - .withBuildLeafBridges() - .withChanceToByPassMovingAway(0.20) - .withPlaceLadders(); - - if (MinecoloniesAPIProxy.getInstance().getConfig().getServer().raidersbreakblocks.get()) - { - stuckHandler.withBlockBreaks(); - stuckHandler.withCompleteStuckBlockBreak(6); - } - - newNavigator.setStuckHandler(stuckHandler); - } - return newNavigator; - } - - /** - * Get the swim speed factor - * - * @return speed factor - */ - public abstract double getSwimSpeedFactor(); - - /** - * Get the stack counter. - * - * @return the amount it got stuck already. - */ - public int getStuckCounter() - { - return stuckCounter; - } - - /** - * Set the stack counter. - * - * @param stuckCounter the amount. - */ - public void setStuckCounter(final int stuckCounter) - { - this.stuckCounter = stuckCounter; - } - - /** - * Get the ladder counter. - * - * @return the amount it got stuck and placed a ladder already. - */ - public int getLadderCounter() - { - return ladderCounter; - } - - /** - * Set the ladder counter. - * - * @param ladderCounter the amount. - */ - public void setLadderCounter(final int ladderCounter) - { - this.ladderCounter = ladderCounter; - } - - @Override - protected SoundEvent getHurtSound(final DamageSource damageSourceIn) - { - return RaiderSounds.raiderSounds.get(getRaiderType()).get(RaiderSounds.RaiderSoundTypes.HURT); - } - - @Override - protected SoundEvent getDeathSound() - { - return RaiderSounds.raiderSounds.get(getRaiderType()).get(RaiderSounds.RaiderSoundTypes.DEATH); - } - - @Nullable - @Override - protected SoundEvent getAmbientSound() - { - return RaiderSounds.raiderSounds.get(getRaiderType()).get(RaiderSounds.RaiderSoundTypes.SAY); - } - @Override public void addAdditionalSaveData(final CompoundTag compound) { compound.putLong(TAG_TIME, worldTimeAtSpawn); - compound.putInt(TAG_STUCK_COUNTER, stuckCounter); - compound.putInt(TAG_LADDER_COUNTER, ladderCounter); compound.putInt(TAG_COLONY_ID, this.colony == null ? 0 : colony.getID()); compound.putInt(TAG_EVENT_ID, eventID); super.addAdditionalSaveData(compound); } - /** * Prevent raiders from travelling to other dimensions through portals. */ @@ -394,8 +217,6 @@ public Entity changeDimension(@NotNull final ServerLevel serverWorld, @NotNull f public void readAdditionalSaveData(final CompoundTag compound) { worldTimeAtSpawn = compound.getLong(TAG_TIME); - stuckCounter = compound.getInt(TAG_STUCK_COUNTER); - ladderCounter = compound.getInt(TAG_LADDER_COUNTER); eventID = compound.getInt(TAG_EVENT_ID); if (compound.contains(TAG_COLONY_ID)) { @@ -492,12 +313,10 @@ public void aiStep() } currentTick++; - if (isRegistered && tickCount % ENTITY_AI_TICKRATE == 0) + if (isRegistered) { - ai.tick(); + super.aiStep(); } - - super.aiStep(); } /** @@ -576,21 +395,6 @@ public void die(@NotNull final DamageSource cause) @Override public boolean hurt(@NotNull final DamageSource damageSource, final float damage) { - if (damageSource.getEntity() instanceof AbstractEntityRaiderMob) - { - return false; - } - - if (damageSource.getEntity() instanceof LivingEntity) - { - threatTable.addThreat((LivingEntity) damageSource.getEntity(), (int) damage); - } - - if (damageSource.typeHolder().is(DamageTypes.FELL_OUT_OF_WORLD)) - { - return super.hurt(damageSource, damage); - } - if (damageSource.getDirectEntity() == null) { if (envDamageImmunity || tempEnvDamageImmunity) @@ -636,21 +440,6 @@ else if (!level().isClientSide()) return super.hurt(damageSource, damage); } - /** - * Get the default attributes with their values. - * @return the attribute modifier map. - */ - public static AttributeSupplier.Builder getDefaultAttributes() - { - return LivingEntity.createLivingAttributes() - .add(MOB_ATTACK_DAMAGE.get()) - .add(Attributes.MAX_HEALTH) - .add(Attributes.ARMOR) - .add(Attributes.MOVEMENT_SPEED, MOVEMENT_SPEED) - .add(Attributes.FOLLOW_RANGE, FOLLOW_RANGE * 2) - .add(Attributes.ATTACK_DAMAGE, Attributes.ATTACK_DAMAGE.getDefaultValue()); - } - /** * Set the colony to raid. * @@ -712,60 +501,26 @@ public void setTempEnvDamageImmunity(final boolean immunity) * @param difficulty difficulty * @param baseDamage basedamage for this raid/difficulty */ + @Override public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) { - this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage); + super.initStatsFor(baseHealth, difficulty, baseDamage); this.difficulty = difficulty; - final double armor = difficulty * ARMOR; - this.getAttribute(Attributes.ARMOR).setBaseValue(armor); this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * difficulty)); if (difficulty >= 1.4d) { this.setEnvDamageImmunity(true); } - - this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth); - this.setHealth(this.getMaxHealth()); } - /** - * Get the mobs difficulty - * - * @return difficulty - */ + @Override public double getDifficulty() { return difficulty; } - /** - * Disallow pushing from fluids to prevent stuck - * - * @return - */ - public boolean isPushedByFluid() - { - return false; - } - - @Override - public ThreatTable getThreatTable() - { - return threatTable; - } - - /** - * Get the AI machine - * - * @return ai statemachine - */ - public ITickRateStateMachine getAI() - { - return ai; - } - @Override public int getTeamId() { diff --git a/src/main/java/com/minecolonies/api/entity/mobs/RaiderMobUtils.java b/src/main/java/com/minecolonies/api/entity/mobs/RaiderMobUtils.java index 50819813db3..790e9fed15f 100755 --- a/src/main/java/com/minecolonies/api/entity/mobs/RaiderMobUtils.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/RaiderMobUtils.java @@ -65,7 +65,7 @@ private RaiderMobUtils() * @param mob The mob to set the attributes on. * @param colony The colony that the mob is attacking. */ - public static void setMobAttributes(final AbstractEntityRaiderMob mob, final IColony colony) + public static void setMobAttributes(final AbstractEntityMinecoloniesRaider mob, final IColony colony) { final double difficultyModifier = colony.getRaiderManager().getRaidDifficultyModifier(); mob.getAttribute(Attributes.FOLLOW_RANGE).setBaseValue(FOLLOW_RANGE * 2); @@ -120,7 +120,7 @@ public static void spawn( for (int i = 0; i < numberOfSpawns; i++) { - final AbstractEntityRaiderMob entity = (AbstractEntityRaiderMob) entityToSpawn.create(world); + final AbstractEntityMinecoloniesRaider entity = (AbstractEntityMinecoloniesRaider) entityToSpawn.create(world); if (entity != null) { @@ -152,7 +152,7 @@ public static void spawn( * * @param mob the equipment to set up. */ - public static void setEquipment(final AbstractEntityRaiderMob mob) + public static void setEquipment(final AbstractEntityMinecoloniesMonster mob) { if (mob instanceof IMeleeBarbarianEntity || mob instanceof IMeleeNorsemenEntity || mob instanceof INorsemenChiefEntity) { @@ -208,10 +208,10 @@ else if (mob instanceof IPirateEntity) * @param distanceFromEntity The distance to check for * @return the barbarians (if any) that is nearest */ - public static List getBarbariansCloseToEntity(final Entity entity, final double distanceFromEntity) + public static List getBarbariansCloseToEntity(final Entity entity, final double distanceFromEntity) { return CompatibilityUtils.getWorldFromEntity(entity).getEntitiesOfClass( - AbstractEntityRaiderMob.class, + AbstractEntityMinecoloniesRaider.class, entity.getBoundingBox().expandTowards( distanceFromEntity, 3.0D, diff --git a/src/main/java/com/minecolonies/api/entity/mobs/amazons/AbstractEntityAmazon.java b/src/main/java/com/minecolonies/api/entity/mobs/amazons/AbstractEntityAmazon.java index e4009db7201..9b7cdcf136d 100755 --- a/src/main/java/com/minecolonies/api/entity/mobs/amazons/AbstractEntityAmazon.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/amazons/AbstractEntityAmazon.java @@ -1,6 +1,6 @@ package com.minecolonies.api.entity.mobs.amazons; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.api.entity.mobs.RaiderType; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.EntityType; @@ -12,9 +12,9 @@ import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; /** - * Abstract for all egyptian entities. + * Abstract for all amazon entities. */ -public abstract class AbstractEntityAmazon extends AbstractEntityRaiderMob +public abstract class AbstractEntityAmazon extends AbstractEntityMinecoloniesMonster { /** * Swim speed for amazons @@ -22,7 +22,7 @@ public abstract class AbstractEntityAmazon extends AbstractEntityRaiderMob private static final double AMAZON_SWIM_BONUS = 1.9; /** - * Constructor method for Abstract egyptian. + * Constructor method for Abstract amazon. * * @param type the type. * @param world the world. diff --git a/src/main/java/com/minecolonies/api/entity/mobs/amazons/AbstractEntityAmazonRaider.java b/src/main/java/com/minecolonies/api/entity/mobs/amazons/AbstractEntityAmazonRaider.java new file mode 100755 index 00000000000..75f8f6d7fef --- /dev/null +++ b/src/main/java/com/minecolonies/api/entity/mobs/amazons/AbstractEntityAmazonRaider.java @@ -0,0 +1,63 @@ +package com.minecolonies.api.entity.mobs.amazons; + +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; +import com.minecolonies.api.entity.mobs.RaiderType; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; + +import static com.minecolonies.api.util.constant.RaiderConstants.ONE; +import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; + +/** + * Abstract for all amazon entities. + */ +public abstract class AbstractEntityAmazonRaider extends AbstractEntityMinecoloniesRaider +{ + /** + * Swim speed for amazons + */ + private static final double AMAZON_SWIM_BONUS = 1.9; + + /** + * Constructor method for Abstract amazon. + * + * @param type the type. + * @param world the world. + */ + public AbstractEntityAmazonRaider(final EntityType type, final Level world) + { + super(type, world); + } + + @Override + public void playAmbientSound() + { + final SoundEvent soundevent = this.getAmbientSound(); + + if (soundevent != null && level().random.nextInt(OUT_OF_ONE_HUNDRED) <= ONE) + { + this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch()); + } + } + + @Override + public boolean checkSpawnRules(final LevelAccessor worldIn, final MobSpawnType spawnReasonIn) + { + return true; + } + + @Override + public RaiderType getRaiderType() + { + return RaiderType.AMAZON; + } + + @Override + public double getSwimSpeedFactor() + { + return AMAZON_SWIM_BONUS; + } +} diff --git a/src/main/java/com/minecolonies/api/entity/mobs/barbarians/AbstractEntityBarbarian.java b/src/main/java/com/minecolonies/api/entity/mobs/barbarians/AbstractEntityBarbarian.java index 4de1767a1be..5dceae238f6 100755 --- a/src/main/java/com/minecolonies/api/entity/mobs/barbarians/AbstractEntityBarbarian.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/barbarians/AbstractEntityBarbarian.java @@ -1,6 +1,6 @@ package com.minecolonies.api.entity.mobs.barbarians; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.api.entity.mobs.RaiderType; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.EntityType; @@ -12,7 +12,7 @@ /** * Abstract for all Barbarian entities. */ -public abstract class AbstractEntityBarbarian extends AbstractEntityRaiderMob +public abstract class AbstractEntityBarbarian extends AbstractEntityMinecoloniesMonster { /** * Swim speed for barbarians diff --git a/src/main/java/com/minecolonies/api/entity/mobs/barbarians/AbstractEntityBarbarianRaider.java b/src/main/java/com/minecolonies/api/entity/mobs/barbarians/AbstractEntityBarbarianRaider.java new file mode 100755 index 00000000000..bc9108e9e77 --- /dev/null +++ b/src/main/java/com/minecolonies/api/entity/mobs/barbarians/AbstractEntityBarbarianRaider.java @@ -0,0 +1,55 @@ +package com.minecolonies.api.entity.mobs.barbarians; + +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; +import com.minecolonies.api.entity.mobs.RaiderType; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +import static com.minecolonies.api.util.constant.RaiderConstants.ONE; +import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; + +/** + * Abstract for all Barbarian entities. + */ +public abstract class AbstractEntityBarbarianRaider extends AbstractEntityMinecoloniesRaider +{ + /** + * Swim speed for barbarians + */ + private static final double BARBARIAN_SWIM_BONUS = 2.0; + + /** + * Constructor method for Abstract Barbarians. + * + * @param type the type. + * @param world the world. + */ + public AbstractEntityBarbarianRaider(final EntityType type, final Level world) + { + super(type, world); + } + + @Override + public void playAmbientSound() + { + final SoundEvent soundevent = this.getAmbientSound(); + + if (soundevent != null && level().random.nextInt(OUT_OF_ONE_HUNDRED) <= ONE) + { + this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch()); + } + } + + @Override + public RaiderType getRaiderType() + { + return RaiderType.BARBARIAN; + } + + @Override + public double getSwimSpeedFactor() + { + return BARBARIAN_SWIM_BONUS; + } +} diff --git a/src/main/java/com/minecolonies/api/entity/mobs/drownedpirate/AbstractDrownedEntityPirate.java b/src/main/java/com/minecolonies/api/entity/mobs/drownedpirate/AbstractDrownedEntityPirate.java index f726d91018f..dd5d0f7706a 100755 --- a/src/main/java/com/minecolonies/api/entity/mobs/drownedpirate/AbstractDrownedEntityPirate.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/drownedpirate/AbstractDrownedEntityPirate.java @@ -1,12 +1,11 @@ package com.minecolonies.api.entity.mobs.drownedpirate; import com.minecolonies.api.MinecoloniesAPIProxy; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.api.entity.mobs.RaiderType; import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.navigation.PathingStuckHandler; -import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobSpawnType; @@ -15,15 +14,13 @@ import net.minecraft.world.level.LevelReader; import org.jetbrains.annotations.NotNull; -import java.util.Random; - import static com.minecolonies.api.util.constant.RaiderConstants.ONE; import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; /** * Abstract for all drowned pirate entities. */ -public abstract class AbstractDrownedEntityPirate extends AbstractEntityRaiderMob +public abstract class AbstractDrownedEntityPirate extends AbstractEntityMinecoloniesMonster { /** * Swim speed for pirates @@ -35,11 +32,6 @@ public abstract class AbstractDrownedEntityPirate extends AbstractEntityRaiderMo */ private static final int PIRATE_TEXTURES = 4; - /** - * Texture id of the pirates. - */ - private int textureId; - /** * Constructor method for Abstract Barbarians. * @@ -48,8 +40,7 @@ public abstract class AbstractDrownedEntityPirate extends AbstractEntityRaiderMo */ public AbstractDrownedEntityPirate(final EntityType type, final Level world) { - super(type, world); - this.textureId = new Random().nextInt(PIRATE_TEXTURES); + super(type, world, PIRATE_TEXTURES); } @Override @@ -73,16 +64,6 @@ public boolean checkSpawnRules(final LevelAccessor worldIn, final MobSpawnType s return true; } - /** - * Get the unique texture id. - * - * @return the texture id. - */ - public int getTextureId() - { - return this.textureId; - } - @NotNull @Override public AbstractAdvancedPathNavigate getNavigation() diff --git a/src/main/java/com/minecolonies/api/entity/mobs/drownedpirate/AbstractDrownedEntityPirateRaider.java b/src/main/java/com/minecolonies/api/entity/mobs/drownedpirate/AbstractDrownedEntityPirateRaider.java new file mode 100755 index 00000000000..6e9673f0d0b --- /dev/null +++ b/src/main/java/com/minecolonies/api/entity/mobs/drownedpirate/AbstractDrownedEntityPirateRaider.java @@ -0,0 +1,118 @@ +package com.minecolonies.api.entity.mobs.drownedpirate; + +import com.minecolonies.api.MinecoloniesAPIProxy; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; +import com.minecolonies.api.entity.mobs.RaiderType; +import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; +import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; +import com.minecolonies.core.entity.pathfinding.navigation.PathingStuckHandler; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import org.jetbrains.annotations.NotNull; + +import static com.minecolonies.api.util.constant.RaiderConstants.ONE; +import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; + +/** + * Abstract for all drowned pirate entities. + */ +public abstract class AbstractDrownedEntityPirateRaider extends AbstractEntityMinecoloniesRaider +{ + /** + * Swim speed for pirates + */ + private static final double PIRATE_SWIM_BONUS = 3.0; + + /** + * Amount of unique pirate textures. + */ + private static final int PIRATE_TEXTURES = 4; + + /** + * Texture id of the pirates. + */ + private int textureId; + + /** + * Constructor method for Abstract Barbarians. + * + * @param type the type. + * @param world the world. + */ + public AbstractDrownedEntityPirateRaider(final EntityType type, final Level world) + { + super(type, world, PIRATE_TEXTURES); + } + + @Override + public void playAmbientSound() + { + if (level().random.nextInt(OUT_OF_ONE_HUNDRED) <= ONE) + { + this.playSound(this.isInWater() ? SoundEvents.DROWNED_AMBIENT_WATER : SoundEvents.DROWNED_AMBIENT, this.getSoundVolume(), this.getVoicePitch()); + } + } + + @Override + public boolean checkSpawnObstruction(final LevelReader level) + { + return level.isUnobstructed(this); + } + + @Override + public boolean checkSpawnRules(final LevelAccessor worldIn, final MobSpawnType spawnReasonIn) + { + return true; + } + + @NotNull + @Override + public AbstractAdvancedPathNavigate getNavigation() + { + if (this.newNavigator == null) + { + this.newNavigator = IPathNavigateRegistry.getInstance().getNavigateFor(this); + this.navigation = newNavigator; + newNavigator.setSwimSpeedFactor(getSwimSpeedFactor()); + newNavigator.setSpeedModifier(0.5); + newNavigator.getPathingOptions().withStartSwimCost(0.0D).withSwimCost(0.0D).withDivingCost(0.0D).withCanEnterDoors(true).withDropCost(0.0D).withJumpCost(0.0D).withWalkUnderWater(true).withNonLadderClimbableCost(0.0D).setPassDanger(true); + PathingStuckHandler stuckHandler = PathingStuckHandler.createStuckHandler() + .withTakeDamageOnStuck(0.4f) + .withBuildLeafBridges() + .withChanceToByPassMovingAway(0.20) + .withPlaceLadders(); + + if (MinecoloniesAPIProxy.getInstance().getConfig().getServer().raidersbreakblocks.get()) + { + stuckHandler.withBlockBreaks(); + stuckHandler.withCompleteStuckBlockBreak(6); + } + + newNavigator.setStuckHandler(stuckHandler); + this.newNavigator.setCanFloat(true); + } + return newNavigator; + } + + @Override + protected int decreaseAirSupply(final int supply) + { + return supply; + } + + @Override + public RaiderType getRaiderType() + { + return RaiderType.PIRATE; + } + + @Override + public double getSwimSpeedFactor() + { + return PIRATE_SWIM_BONUS; + } +} diff --git a/src/main/java/com/minecolonies/api/entity/mobs/egyptians/AbstractEntityEgyptian.java b/src/main/java/com/minecolonies/api/entity/mobs/egyptians/AbstractEntityEgyptian.java index eb5ef6c8631..1f79fde0112 100755 --- a/src/main/java/com/minecolonies/api/entity/mobs/egyptians/AbstractEntityEgyptian.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/egyptians/AbstractEntityEgyptian.java @@ -1,6 +1,6 @@ package com.minecolonies.api.entity.mobs.egyptians; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.api.entity.mobs.RaiderType; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.EntityType; @@ -14,14 +14,13 @@ /** * Abstract for all egyptian entities. */ -public abstract class AbstractEntityEgyptian extends AbstractEntityRaiderMob +public abstract class AbstractEntityEgyptian extends AbstractEntityMinecoloniesMonster { /** * Swim speed for mummies */ private static final double MUMMY_SWIM_SPEED = 1.7; - /** * Constructor method for Abstract egyptian.. * diff --git a/src/main/java/com/minecolonies/api/entity/mobs/egyptians/AbstractEntityEgyptianRaider.java b/src/main/java/com/minecolonies/api/entity/mobs/egyptians/AbstractEntityEgyptianRaider.java new file mode 100755 index 00000000000..948cac3807b --- /dev/null +++ b/src/main/java/com/minecolonies/api/entity/mobs/egyptians/AbstractEntityEgyptianRaider.java @@ -0,0 +1,63 @@ +package com.minecolonies.api.entity.mobs.egyptians; + +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; +import com.minecolonies.api.entity.mobs.RaiderType; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; + +import static com.minecolonies.api.util.constant.RaiderConstants.ONE; +import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; + +/** + * Abstract for all egyptian entities. + */ +public abstract class AbstractEntityEgyptianRaider extends AbstractEntityMinecoloniesRaider +{ + /** + * Swim speed for mummies + */ + private static final double MUMMY_SWIM_SPEED = 1.7; + + /** + * Constructor method for Abstract egyptian.. + * + * @param type the type. + * @param world the world. + */ + public AbstractEntityEgyptianRaider(final EntityType type, final Level world) + { + super(type, world); + } + + @Override + public void playAmbientSound() + { + final SoundEvent soundevent = this.getAmbientSound(); + + if (soundevent != null && level().random.nextInt(OUT_OF_ONE_HUNDRED) <= ONE) + { + this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch()); + } + } + + @Override + public boolean checkSpawnRules(final LevelAccessor worldIn, final MobSpawnType spawnReasonIn) + { + return true; + } + + @Override + public RaiderType getRaiderType() + { + return RaiderType.EGYPTIAN; + } + + @Override + public double getSwimSpeedFactor() + { + return MUMMY_SWIM_SPEED; + } +} diff --git a/src/main/java/com/minecolonies/api/entity/mobs/pirates/AbstractEntityPirate.java b/src/main/java/com/minecolonies/api/entity/mobs/pirates/AbstractEntityPirate.java index 33fffab8279..a6b973cf3a0 100755 --- a/src/main/java/com/minecolonies/api/entity/mobs/pirates/AbstractEntityPirate.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/pirates/AbstractEntityPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.api.entity.mobs.pirates; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.api.entity.mobs.RaiderType; import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; import net.minecraft.sounds.SoundEvent; @@ -10,15 +10,13 @@ import net.minecraft.world.level.LevelAccessor; import org.jetbrains.annotations.NotNull; -import java.util.Random; - import static com.minecolonies.api.util.constant.RaiderConstants.ONE; import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; /** * Abstract for all pirate entities. */ -public abstract class AbstractEntityPirate extends AbstractEntityRaiderMob +public abstract class AbstractEntityPirate extends AbstractEntityMinecoloniesMonster { /** * Swim speed for pirates @@ -30,11 +28,6 @@ public abstract class AbstractEntityPirate extends AbstractEntityRaiderMob */ private static final int PIRATE_TEXTURES = 4; - /** - * Texture id of the pirates. - */ - private int textureId; - /** * Constructor method for Abstract Barbarians. * @@ -43,8 +36,7 @@ public abstract class AbstractEntityPirate extends AbstractEntityRaiderMob */ public AbstractEntityPirate(final EntityType type, final Level world) { - super(type, world); - this.textureId = new Random().nextInt(PIRATE_TEXTURES); + super(type, world, PIRATE_TEXTURES); } @Override @@ -64,16 +56,6 @@ public boolean checkSpawnRules(final LevelAccessor worldIn, final MobSpawnType s return true; } - /** - * Get the unique texture id. - * - * @return the texture id. - */ - public int getTextureId() - { - return this.textureId; - } - @NotNull @Override public AbstractAdvancedPathNavigate getNavigation() diff --git a/src/main/java/com/minecolonies/api/entity/mobs/pirates/AbstractEntityPirateRaider.java b/src/main/java/com/minecolonies/api/entity/mobs/pirates/AbstractEntityPirateRaider.java new file mode 100755 index 00000000000..8fa9fd86087 --- /dev/null +++ b/src/main/java/com/minecolonies/api/entity/mobs/pirates/AbstractEntityPirateRaider.java @@ -0,0 +1,97 @@ +package com.minecolonies.api.entity.mobs.pirates; + +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; +import com.minecolonies.api.entity.mobs.RaiderType; +import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import org.jetbrains.annotations.NotNull; + +import java.util.Random; + +import static com.minecolonies.api.util.constant.RaiderConstants.ONE; +import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; + +/** + * Abstract for all pirate entities. + */ +public abstract class AbstractEntityPirateRaider extends AbstractEntityMinecoloniesRaider +{ + /** + * Swim speed for pirates + */ + private static final double PIRATE_SWIM_BONUS = 2.3; + + /** + * Amount of unique pirate textures. + */ + private static final int PIRATE_TEXTURES = 4; + + /** + * Texture id of the pirates. + */ + private int textureId; + + /** + * Constructor method for Abstract Barbarians. + * + * @param type the type. + * @param world the world. + */ + public AbstractEntityPirateRaider(final EntityType type, final Level world) + { + super(type, world); + this.textureId = new Random().nextInt(PIRATE_TEXTURES); + } + + @Override + public void playAmbientSound() + { + final SoundEvent soundevent = this.getAmbientSound(); + + if (soundevent != null && level().random.nextInt(OUT_OF_ONE_HUNDRED) <= ONE) + { + this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch()); + } + } + + @Override + public boolean checkSpawnRules(final LevelAccessor worldIn, final MobSpawnType spawnReasonIn) + { + return true; + } + + /** + * Get the unique texture id. + * + * @return the texture id. + */ + public int getTextureId() + { + return this.textureId; + } + + @NotNull + @Override + public AbstractAdvancedPathNavigate getNavigation() + { + AbstractAdvancedPathNavigate navigator = super.getNavigation(); + navigator.getPathingOptions().withStartSwimCost(2.5D).withSwimCost(1.1D); + return navigator; + } + + @Override + public RaiderType getRaiderType() + { + return RaiderType.PIRATE; + } + + @Override + public double getSwimSpeedFactor() + { + return PIRATE_SWIM_BONUS; + } +} diff --git a/src/main/java/com/minecolonies/api/entity/mobs/registry/IMobAIRegistry.java b/src/main/java/com/minecolonies/api/entity/mobs/registry/IMobAIRegistry.java index 65562f3b643..43051f61627 100755 --- a/src/main/java/com/minecolonies/api/entity/mobs/registry/IMobAIRegistry.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/registry/IMobAIRegistry.java @@ -3,7 +3,7 @@ import com.google.common.collect.Multimap; import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.entity.ai.IStateAI; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.world.entity.ai.goal.Goal; import org.jetbrains.annotations.NotNull; @@ -21,7 +21,7 @@ public interface IMobAIRegistry * @return The map with the entity AI tasks that are needed for the given mob, with their priorities. */ @NotNull - Multimap getEntityAiTasksForMobs(final AbstractEntityRaiderMob mob); + Multimap getEntityAiTasksForMobs(final AbstractEntityMinecoloniesMonster mob); /** * Method used to register a entity AI task for a mob that matches the predicate. @@ -31,7 +31,7 @@ public interface IMobAIRegistry * @return The registry. */ @NotNull - default IMobAIRegistry registerNewAiTaskForMobs(final int priority, final Function aiTaskProducer) + default IMobAIRegistry registerNewAiTaskForMobs(final int priority, final Function aiTaskProducer) { return this.registerNewAiTaskForMobs(priority, aiTaskProducer, mob -> true); } @@ -47,8 +47,8 @@ default IMobAIRegistry registerNewAiTaskForMobs(final int priority, final Functi @NotNull IMobAIRegistry registerNewAiTaskForMobs( final int priority, - final Function aiTaskProducer, - Predicate applyPredicate); + final Function aiTaskProducer, + Predicate applyPredicate); /** * Method used to register a entity AI task for a mob that matches the predicate. @@ -59,14 +59,14 @@ IMobAIRegistry registerNewAiTaskForMobs( */ @NotNull IMobAIRegistry registerNewStateAI( - final Function aiTaskProducer, - Predicate applyPredicate); + final Function aiTaskProducer, + Predicate applyPredicate); /** * Applies the registered AI's to the given mob */ @NotNull - void applyToMob(AbstractEntityRaiderMob mob); + void applyToMob(AbstractEntityMinecoloniesMonster mob); /** * Method to get the AI target tasks registered for a given mob. Used by minecolonies to get the AIs that are required for a given mob. @@ -75,7 +75,7 @@ IMobAIRegistry registerNewStateAI( * @return The map with the entity AI tasks that are needed for the given mob, with their priorities. */ @NotNull - Multimap getEntityAiTargetTasksForMobs(final AbstractEntityRaiderMob mob); + Multimap getEntityAiTargetTasksForMobs(final AbstractEntityMinecoloniesMonster mob); /** * Method used to register a entity AI target task for a mob that matches the predicate. @@ -85,7 +85,7 @@ IMobAIRegistry registerNewStateAI( * @return The registry. */ @NotNull - default IMobAIRegistry registerNewAiTargetTaskForMobs(final int priority, final Function aiTaskProducer) + default IMobAIRegistry registerNewAiTargetTaskForMobs(final int priority, final Function aiTaskProducer) { return this.registerNewAiTargetTaskForMobs(priority, aiTaskProducer, mob -> true); } @@ -101,6 +101,6 @@ default IMobAIRegistry registerNewAiTargetTaskForMobs(final int priority, final @NotNull IMobAIRegistry registerNewAiTargetTaskForMobs( final int priority, - final Function aiTaskProducer, - Predicate applyPredicate); + final Function aiTaskProducer, + Predicate applyPredicate); } diff --git a/src/main/java/com/minecolonies/api/entity/mobs/vikings/AbstractEntityNorsemen.java b/src/main/java/com/minecolonies/api/entity/mobs/vikings/AbstractEntityNorsemen.java index e73f91b0df9..36f6ca13eb5 100755 --- a/src/main/java/com/minecolonies/api/entity/mobs/vikings/AbstractEntityNorsemen.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/vikings/AbstractEntityNorsemen.java @@ -1,6 +1,6 @@ package com.minecolonies.api.entity.mobs.vikings; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.api.entity.mobs.RaiderType; import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; import net.minecraft.sounds.SoundEvent; @@ -10,15 +10,13 @@ import net.minecraft.world.level.LevelAccessor; import org.jetbrains.annotations.NotNull; -import java.util.Random; - import static com.minecolonies.api.util.constant.RaiderConstants.ONE; import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; /** * Abstract for all norsemen entities. */ -public abstract class AbstractEntityNorsemen extends AbstractEntityRaiderMob +public abstract class AbstractEntityNorsemen extends AbstractEntityMinecoloniesMonster { /** * Swim speed for pirates @@ -30,11 +28,6 @@ public abstract class AbstractEntityNorsemen extends AbstractEntityRaiderMob */ private static final int NORSEMEN_TEXTURES = 3; - /** - * Texture id of the norsemen. - */ - private int textureId; - /** * Constructor method for Abstract norsemen.. * @@ -43,8 +36,7 @@ public abstract class AbstractEntityNorsemen extends AbstractEntityRaiderMob */ public AbstractEntityNorsemen(final EntityType type, final Level world) { - super(type, world); - this.textureId = new Random().nextInt(NORSEMEN_TEXTURES); + super(type, world, NORSEMEN_TEXTURES); } @Override @@ -70,16 +62,6 @@ public boolean checkSpawnRules(final LevelAccessor worldIn, final MobSpawnType s return true; } - /** - * Get the unique texture id. - * - * @return the texture id. - */ - public int getTextureId() - { - return this.textureId; - } - @NotNull @Override public AbstractAdvancedPathNavigate getNavigation() diff --git a/src/main/java/com/minecolonies/api/entity/mobs/vikings/AbstractEntityNorsemenRaider.java b/src/main/java/com/minecolonies/api/entity/mobs/vikings/AbstractEntityNorsemenRaider.java new file mode 100755 index 00000000000..771541fa9c9 --- /dev/null +++ b/src/main/java/com/minecolonies/api/entity/mobs/vikings/AbstractEntityNorsemenRaider.java @@ -0,0 +1,85 @@ +package com.minecolonies.api.entity.mobs.vikings; + +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; +import com.minecolonies.api.entity.mobs.RaiderType; +import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import org.jetbrains.annotations.NotNull; + +import static com.minecolonies.api.util.constant.RaiderConstants.ONE; +import static com.minecolonies.api.util.constant.RaiderConstants.OUT_OF_ONE_HUNDRED; + +/** + * Abstract for all norsemen entities. + */ +public abstract class AbstractEntityNorsemenRaider extends AbstractEntityMinecoloniesRaider +{ + /** + * Swim speed for norsemen + */ + private static final double PIRATE_SWIM_BONUS = 2.3; + + /** + * Amount of unique norsemen textures. + */ + private static final int NORSEMEN_TEXTURES = 3; + + /** + * Constructor method for Abstract norsemen. + * + * @param type the type. + * @param world the world. + */ + public AbstractEntityNorsemenRaider(final EntityType type, final Level world) + { + super(type, world, NORSEMEN_TEXTURES); + } + + @Override + public void playAmbientSound() + { + final SoundEvent soundevent = this.getAmbientSound(); + + if (soundevent != null && level().random.nextInt(OUT_OF_ONE_HUNDRED) <= ONE) + { + this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch()); + } + } + + @Override + public float getVoicePitch() + { + return (this.random.nextFloat() - this.random.nextFloat()) * 0.1F + 1.0F; + } + + @Override + public boolean checkSpawnRules(final LevelAccessor worldIn, final MobSpawnType spawnReasonIn) + { + return true; + } + + @NotNull + @Override + public AbstractAdvancedPathNavigate getNavigation() + { + AbstractAdvancedPathNavigate navigator = super.getNavigation(); + navigator.getPathingOptions().withStartSwimCost(2.5D).withSwimCost(1.1D); + return navigator; + } + + @Override + public RaiderType getRaiderType() + { + return RaiderType.NORSEMAN; + } + + @Override + public double getSwimSpeedFactor() + { + return PIRATE_SWIM_BONUS; + } +} diff --git a/src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java b/src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java index 0cf314b93fe..6f52bf95772 100755 --- a/src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java +++ b/src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java @@ -11,6 +11,8 @@ import java.util.*; +import static com.minecolonies.core.generation.SoundsJson.createSoundJson; + /** * Registering of sound events for our colony. */ @@ -54,7 +56,6 @@ private ModSoundEvents() mainTypes.remove(ModJobs.placeHolder.getId()); mainTypes.add(new ResourceLocation(Constants.MOD_ID, "unemployed")); mainTypes.add(new ResourceLocation(Constants.MOD_ID, "visitor")); - mainTypes.add(new ResourceLocation(Constants.MOD_ID, "child")); for (final ResourceLocation job : mainTypes) { @@ -78,6 +79,23 @@ private ModSoundEvents() CITIZEN_SOUND_EVENTS.put(job.getPath(), map); } + final Map>> map = new HashMap<>(); + for (final EventType event : EventType.values()) + { + final List> individualSounds = new ArrayList<>(); + for (int i = 1; i <= 2; i++) + { + final SoundEvent maleSoundEvent = + ModSoundEvents.getSoundID(CITIZEN_SOUND_EVENT_PREFIX + "child.male" + i + "." + event.getId()); + final SoundEvent femaleSoundEvent = + ModSoundEvents.getSoundID(CITIZEN_SOUND_EVENT_PREFIX + "child.female" + i + "." + event.getId()); + + individualSounds.add(new Tuple<>(maleSoundEvent, femaleSoundEvent)); + individualSounds.add(new Tuple<>(maleSoundEvent, femaleSoundEvent)); + } + } + CITIZEN_SOUND_EVENTS.put("child", map); + SOUND_EVENTS.register(TavernSounds.tavernTheme.getLocation().getPath(), () -> TavernSounds.tavernTheme); for (final RaiderType raiderType : RaiderType.values()) diff --git a/src/main/java/com/minecolonies/api/util/DamageSourceKeys.java b/src/main/java/com/minecolonies/api/util/DamageSourceKeys.java index 09a10a831d0..18390707d33 100644 --- a/src/main/java/com/minecolonies/api/util/DamageSourceKeys.java +++ b/src/main/java/com/minecolonies/api/util/DamageSourceKeys.java @@ -40,4 +40,20 @@ public class DamageSourceKeys public static ResourceKey DROWNED_CHIEFPIRATE = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "drownedchiefpirate")); public static ResourceKey DROWNED_ARCHERPIRATE = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "drownedarcherpirate")); + public static ResourceKey CAMP_AMAZON = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campamazon")); + public static ResourceKey CAMP_AMAZONSPEARMAN = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campamazonspearman")); + public static ResourceKey CAMP_AMAZONCHIEF = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campamazonchief")); + public static ResourceKey CAMP_MUMMY = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campmummy")); + public static ResourceKey CAMP_PHARAO = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "camppharao")); + public static ResourceKey CAMP_ARCHERMUMMY = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "camparchermummy")); + public static ResourceKey CAMP_NORSEMENCHIEF = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campnorsemenchief")); + public static ResourceKey CAMP_NORSEMENARCHER = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campnorsemenarcher")); + public static ResourceKey CAMP_SHIELDMAIDEN = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campshieldmaiden")); + public static ResourceKey CAMP_BARBARIAN = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campbarbarian")); + public static ResourceKey CAMP_CHIEFBARBARIAN = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "ccamphiefbarbarian")); + public static ResourceKey CAMP_ARCHERBARBARIAN = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "camparcherbarbarian")); + public static ResourceKey CAMP_PIRATE = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "camppirate")); + public static ResourceKey CAMP_CHIEFPIRATE = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "campchiefpirate")); + public static ResourceKey CAMP_ARCHERPIRATE = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(Constants.MOD_ID, "camparcherpirate")); + } diff --git a/src/main/java/com/minecolonies/apiimp/initializer/EntityInitializer.java b/src/main/java/com/minecolonies/apiimp/initializer/EntityInitializer.java index 373e54b1bea..99e50b802b9 100644 --- a/src/main/java/com/minecolonies/apiimp/initializer/EntityInitializer.java +++ b/src/main/java/com/minecolonies/apiimp/initializer/EntityInitializer.java @@ -4,26 +4,44 @@ import com.minecolonies.api.entity.ModEntities; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.entity.citizen.EntityCitizen; -import com.minecolonies.core.entity.mobs.drownedpirates.EntityDrownedArcherPirate; -import com.minecolonies.core.entity.mobs.drownedpirates.EntityDrownedCaptainPirate; -import com.minecolonies.core.entity.mobs.drownedpirates.EntityDrownedPirate; +import com.minecolonies.core.entity.mobs.camp.amazons.EntityAmazonChief; +import com.minecolonies.core.entity.mobs.camp.amazons.EntityAmazonSpearman; +import com.minecolonies.core.entity.mobs.camp.amazons.EntityArcherAmazon; +import com.minecolonies.core.entity.mobs.camp.barbarians.EntityArcherBarbarian; +import com.minecolonies.core.entity.mobs.camp.barbarians.EntityBarbarian; +import com.minecolonies.core.entity.mobs.camp.barbarians.EntityChiefBarbarian; +import com.minecolonies.core.entity.mobs.camp.drownedpirates.EntityDrownedArcherPirate; +import com.minecolonies.core.entity.mobs.camp.drownedpirates.EntityDrownedCaptainPirate; +import com.minecolonies.core.entity.mobs.camp.drownedpirates.EntityDrownedPirate; +import com.minecolonies.core.entity.mobs.camp.egyptians.EntityArcherMummy; +import com.minecolonies.core.entity.mobs.camp.egyptians.EntityMummy; +import com.minecolonies.core.entity.mobs.camp.egyptians.EntityPharao; +import com.minecolonies.core.entity.mobs.camp.norsemen.EntityNorsemenArcher; +import com.minecolonies.core.entity.mobs.camp.norsemen.EntityNorsemenChief; +import com.minecolonies.core.entity.mobs.camp.norsemen.EntityShieldmaiden; +import com.minecolonies.core.entity.mobs.camp.pirates.EntityArcherPirate; +import com.minecolonies.core.entity.mobs.camp.pirates.EntityCaptainPirate; +import com.minecolonies.core.entity.mobs.camp.pirates.EntityPirate; +import com.minecolonies.core.entity.mobs.raider.drownedpirates.EntityDrownedArcherPirateRaider; +import com.minecolonies.core.entity.mobs.raider.drownedpirates.EntityDrownedCaptainPirateRaider; +import com.minecolonies.core.entity.mobs.raider.drownedpirates.EntityDrownedPirateRaider; import com.minecolonies.core.entity.visitor.VisitorCitizen; import com.minecolonies.core.entity.mobs.EntityMercenary; -import com.minecolonies.core.entity.mobs.amazons.EntityAmazonChief; -import com.minecolonies.core.entity.mobs.amazons.EntityAmazonSpearman; -import com.minecolonies.core.entity.mobs.amazons.EntityArcherAmazon; -import com.minecolonies.core.entity.mobs.barbarians.EntityArcherBarbarian; -import com.minecolonies.core.entity.mobs.barbarians.EntityBarbarian; -import com.minecolonies.core.entity.mobs.barbarians.EntityChiefBarbarian; -import com.minecolonies.core.entity.mobs.egyptians.EntityArcherMummy; -import com.minecolonies.core.entity.mobs.egyptians.EntityMummy; -import com.minecolonies.core.entity.mobs.egyptians.EntityPharao; -import com.minecolonies.core.entity.mobs.norsemen.EntityNorsemenArcher; -import com.minecolonies.core.entity.mobs.norsemen.EntityNorsemenChief; -import com.minecolonies.core.entity.mobs.norsemen.EntityShieldmaiden; -import com.minecolonies.core.entity.mobs.pirates.EntityArcherPirate; -import com.minecolonies.core.entity.mobs.pirates.EntityCaptainPirate; -import com.minecolonies.core.entity.mobs.pirates.EntityPirate; +import com.minecolonies.core.entity.mobs.raider.amazons.EntityAmazonChiefRaider; +import com.minecolonies.core.entity.mobs.raider.amazons.EntityAmazonSpearmanRaider; +import com.minecolonies.core.entity.mobs.raider.amazons.EntityArcherAmazonRaider; +import com.minecolonies.core.entity.mobs.raider.barbarians.EntityArcherBarbarianRaider; +import com.minecolonies.core.entity.mobs.raider.barbarians.EntityBarbarianRaider; +import com.minecolonies.core.entity.mobs.raider.barbarians.EntityChiefBarbarianRaider; +import com.minecolonies.core.entity.mobs.raider.egyptians.EntityArcherMummyRaider; +import com.minecolonies.core.entity.mobs.raider.egyptians.EntityMummyRaider; +import com.minecolonies.core.entity.mobs.raider.egyptians.EntityPharaoRaider; +import com.minecolonies.core.entity.mobs.raider.norsemen.EntityNorsemenArcherRaider; +import com.minecolonies.core.entity.mobs.raider.norsemen.EntityNorsemenChiefRaider; +import com.minecolonies.core.entity.mobs.raider.norsemen.EntityShieldmaidenRaider; +import com.minecolonies.core.entity.mobs.raider.pirates.EntityArcherPirateRaider; +import com.minecolonies.core.entity.mobs.raider.pirates.EntityCaptainPirateRaider; +import com.minecolonies.core.entity.mobs.raider.pirates.EntityPirateRaider; import com.minecolonies.core.entity.other.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; @@ -77,37 +95,37 @@ public static void setupEntities(RegisterEvent event) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.BARBARIAN = build(registry, "barbarian", - EntityType.Builder.of(EntityBarbarian::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityBarbarianRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.ARCHERBARBARIAN = build(registry, "archerbarbarian", - EntityType.Builder.of(EntityArcherBarbarian::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityArcherBarbarianRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.CHIEFBARBARIAN = build(registry, "chiefbarbarian", - EntityType.Builder.of(EntityChiefBarbarian::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityChiefBarbarianRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.PIRATE = build(registry, "pirate", - EntityType.Builder.of(EntityPirate::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityPirateRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.ARCHERPIRATE = build(registry, "archerpirate", - EntityType.Builder.of(EntityArcherPirate::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityArcherPirateRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.CHIEFPIRATE = build(registry, "chiefpirate", - EntityType.Builder.of(EntityCaptainPirate::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityCaptainPirateRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); @@ -125,37 +143,37 @@ public static void setupEntities(RegisterEvent event) .sized(0.98F, 0.7F)); ModEntities.MUMMY = build(registry, "mummy", - EntityType.Builder.of(EntityMummy::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityMummyRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.ARCHERMUMMY = build(registry, "archermummy", - EntityType.Builder.of(EntityArcherMummy::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityArcherMummyRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.PHARAO = build(registry, "pharao", - EntityType.Builder.of(EntityPharao::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityPharaoRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.AMAZON = build(registry, "amazon", - EntityType.Builder.of(EntityArcherAmazon::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityArcherAmazonRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.AMAZONSPEARMAN = build(registry, "amazonspearman", - EntityType.Builder.of(EntityAmazonSpearman::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityAmazonSpearmanRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.AMAZONCHIEF = build(registry, "amazonchief", - EntityType.Builder.of(EntityAmazonChief::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityAmazonChiefRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); @@ -182,19 +200,19 @@ public static void setupEntities(RegisterEvent event) .setShouldReceiveVelocityUpdates(true)); ModEntities.SHIELDMAIDEN = build(registry, "shieldmaiden", - EntityType.Builder.of(EntityShieldmaiden::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityShieldmaidenRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.NORSEMEN_ARCHER = build(registry, "norsemenarcher", - EntityType.Builder.of(EntityNorsemenArcher::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityNorsemenArcherRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.NORSEMEN_CHIEF = build(registry, "norsemenchief", - EntityType.Builder.of(EntityNorsemenChief::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityNorsemenChiefRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); @@ -207,22 +225,132 @@ public static void setupEntities(RegisterEvent event) .setShouldReceiveVelocityUpdates(true)); ModEntities.DROWNED_PIRATE = build(registry, "drownedpirate", - EntityType.Builder.of(EntityDrownedPirate::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityDrownedPirateRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.DROWNED_ARCHERPIRATE = build(registry, "drownedarcherpirate", - EntityType.Builder.of(EntityDrownedArcherPirate::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityDrownedArcherPirateRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); ModEntities.DROWNED_CHIEFPIRATE = build(registry, "drownedchiefpirate", - EntityType.Builder.of(EntityDrownedCaptainPirate::new, MobCategory.MONSTER) + EntityType.Builder.of(EntityDrownedCaptainPirateRaider::new, MobCategory.MONSTER) .setTrackingRange(ENTITY_TRACKING_RANGE) .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + // Camp Raiders + + ModEntities.CAMP_BARBARIAN = build(registry, "campbarbarian", + EntityType.Builder.of(EntityBarbarian::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_ARCHERBARBARIAN = build(registry, "camparcherbarbarian", + EntityType.Builder.of(EntityArcherBarbarian::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_CHIEFBARBARIAN = build(registry, "campchiefbarbarian", + EntityType.Builder.of(EntityChiefBarbarian::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_PIRATE = build(registry, "camppirate", + EntityType.Builder.of(EntityPirate::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_ARCHERPIRATE = build(registry, "camparcherpirate", + EntityType.Builder.of(EntityArcherPirate::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_CHIEFPIRATE = build(registry, "campchiefpirate", + EntityType.Builder.of(EntityCaptainPirate::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_AMAZON = build(registry, "campamazon", + EntityType.Builder.of(EntityArcherAmazon::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_AMAZONSPEARMAN = build(registry, "campamazonspearman", + EntityType.Builder.of(EntityAmazonSpearman::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_AMAZONCHIEF = build(registry, "campamazonchief", + EntityType.Builder.of(EntityAmazonChief::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_MUMMY = build(registry, "campmummy", + EntityType.Builder.of(EntityMummy::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_ARCHERMUMMY = build(registry, "camparchermummy", + EntityType.Builder.of(EntityArcherMummy::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_PHARAO = build(registry, "camppharao", + EntityType.Builder.of(EntityPharao::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_SHIELDMAIDEN = build(registry, "campshieldmaiden", + EntityType.Builder.of(EntityShieldmaiden::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_NORSEMEN_ARCHER = build(registry, "campnorsemenarcher", + EntityType.Builder.of(EntityNorsemenArcher::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_NORSEMEN_CHIEF = build(registry, "campnorsemenchief", + EntityType.Builder.of(EntityNorsemenChief::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_DROWNED_PIRATE = build(registry, "campdrownedpirate", + EntityType.Builder.of(EntityDrownedPirate::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_DROWNED_ARCHERPIRATE = build(registry, "campdrownedarcherpirate", + EntityType.Builder.of(EntityDrownedArcherPirate::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); + + ModEntities.CAMP_DROWNED_CHIEFPIRATE = build(registry, "campdrownedchiefpirate", + EntityType.Builder.of(EntityDrownedCaptainPirate::new, MobCategory.MONSTER) + .setTrackingRange(ENTITY_TRACKING_RANGE) + .setUpdateInterval(ENTITY_UPDATE_FREQUENCY) + .sized((float) CITIZEN_WIDTH, (float) CITIZEN_HEIGHT)); } } diff --git a/src/main/java/com/minecolonies/apiimp/initializer/ModItemsInitializer.java b/src/main/java/com/minecolonies/apiimp/initializer/ModItemsInitializer.java index bd3c64a992e..1cb0c4b678e 100755 --- a/src/main/java/com/minecolonies/apiimp/initializer/ModItemsInitializer.java +++ b/src/main/java/com/minecolonies/apiimp/initializer/ModItemsInitializer.java @@ -1,5 +1,6 @@ package com.minecolonies.apiimp.initializer; +import com.ldtteam.blockui.Color; import com.minecolonies.api.blocks.ModBlocks; import com.minecolonies.api.entity.ModEntities; import com.minecolonies.api.items.ModItems; @@ -31,8 +32,6 @@ public final class ModItemsInitializer private static final int SECONDARY_COLOR_BARBARIAN = 700; private static final int PRIMARY_COLOR_PIRATE = 7; private static final int SECONDARY_COLOR_PIRATE = 600; - private static final int PRIMARY_COLOR_MERC = 8; - private static final int SECONDARY_COLOR_MERC = 300; private static final int PRIMARY_COLOR_EG = 10; private static final int SECONDARY_COLOR_EG = 400; @@ -378,65 +377,82 @@ public static void init(final IForgeRegistry registry) registry.register(new ResourceLocation(Constants.MOD_ID, "large_milk_bottle"), ModItems.large_milk_bottle); registry.register(new ResourceLocation(Constants.MOD_ID, "large_soy_milk_bottle"), ModItems.large_soy_milk_bottle); - registry.register(new ResourceLocation(Constants.MOD_ID, "barbarianegg"), new ForgeSpawnEggItem(() -> ModEntities.BARBARIAN, - PRIMARY_COLOR_BARBARIAN, - SECONDARY_COLOR_BARBARIAN, - (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "barbarcheregg"), new ForgeSpawnEggItem(() -> ModEntities.ARCHERBARBARIAN, - PRIMARY_COLOR_BARBARIAN, - SECONDARY_COLOR_BARBARIAN, - (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "barbchiefegg"), new ForgeSpawnEggItem(() -> ModEntities.CHIEFBARBARIAN, - PRIMARY_COLOR_BARBARIAN, - SECONDARY_COLOR_BARBARIAN, - (new Item.Properties()))); - - registry.register(new ResourceLocation(Constants.MOD_ID, "pirateegg"), new ForgeSpawnEggItem(() -> ModEntities.PIRATE, - PRIMARY_COLOR_PIRATE, - SECONDARY_COLOR_PIRATE, - (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "piratearcheregg"), new ForgeSpawnEggItem(() -> ModEntities.ARCHERPIRATE, - PRIMARY_COLOR_PIRATE, - SECONDARY_COLOR_PIRATE, - (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "piratecaptainegg"), new ForgeSpawnEggItem(() -> ModEntities.CHIEFPIRATE, - PRIMARY_COLOR_PIRATE, - SECONDARY_COLOR_PIRATE, - (new Item.Properties()))); - - registry.register(new ResourceLocation(Constants.MOD_ID, "mummyegg"), new ForgeSpawnEggItem(() -> ModEntities.MUMMY, PRIMARY_COLOR_EG, SECONDARY_COLOR_EG, (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "mummyarcheregg"), new ForgeSpawnEggItem(() -> ModEntities.ARCHERMUMMY, - PRIMARY_COLOR_EG, - SECONDARY_COLOR_EG, - (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "pharaoegg"), new ForgeSpawnEggItem(() -> ModEntities.PHARAO, PRIMARY_COLOR_EG, SECONDARY_COLOR_EG, (new Item.Properties()))); - - registry.register(new ResourceLocation(Constants.MOD_ID, "shieldmaidenegg"), new ForgeSpawnEggItem(() -> ModEntities.SHIELDMAIDEN, - PRIMARY_COLOR_EG, - SECONDARY_COLOR_EG, - (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "norsemenarcheregg"), new ForgeSpawnEggItem(() -> ModEntities.NORSEMEN_ARCHER, - PRIMARY_COLOR_EG, - SECONDARY_COLOR_EG, - (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "norsemenchiefegg"), new ForgeSpawnEggItem(() -> ModEntities.NORSEMEN_CHIEF, - PRIMARY_COLOR_EG, - SECONDARY_COLOR_EG, - (new Item.Properties()))); - - registry.register(new ResourceLocation(Constants.MOD_ID, "amazonegg"), new ForgeSpawnEggItem(() -> ModEntities.AMAZON, PRIMARY_COLOR_EG, SECONDARY_COLOR_EG, (new Item.Properties()))); - registry.register(new ResourceLocation(Constants.MOD_ID, "amazonspearmanegg"), new ForgeSpawnEggItem(() -> ModEntities.AMAZONSPEARMAN, - PRIMARY_COLOR_EG, - SECONDARY_COLOR_EG, - new Item.Properties())); - registry.register(new ResourceLocation(Constants.MOD_ID, "amazonchiefegg"), new ForgeSpawnEggItem(() -> ModEntities.AMAZONCHIEF, - PRIMARY_COLOR_EG, - SECONDARY_COLOR_EG, - (new Item.Properties()))); - - registry.register(new ResourceLocation(Constants.MOD_ID, "mercegg"), new ForgeSpawnEggItem(() -> ModEntities.MERCENARY, - PRIMARY_COLOR_MERC, - SECONDARY_COLOR_MERC, - (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "barbarianegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_BARBARIAN, + Color.getByName("orange"), + Color.getByName("black"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "barbarcheregg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_ARCHERBARBARIAN, + Color.getByName("orange"), + Color.getByName("green"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "barbchiefegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_CHIEFBARBARIAN, + Color.getByName("orange"), + Color.getByName("yellow"), + (new Item.Properties()))); + + registry.register(new ResourceLocation(Constants.MOD_ID, "pirateegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_PIRATE, + Color.getByName("red"), + Color.getByName("white"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "piratearcheregg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_ARCHERPIRATE, + Color.getByName("red"), + Color.getByName("green"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "piratecaptainegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_CHIEFPIRATE, + Color.getByName("red"), + Color.getByName("yellow"), + (new Item.Properties()))); + + registry.register(new ResourceLocation(Constants.MOD_ID, "mummyegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_MUMMY, + Color.getByName("yellow"), + Color.getByName("white"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "mummyarcheregg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_ARCHERMUMMY, + Color.getByName("yellow"), + Color.getByName("green"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "pharaoegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_PHARAO, + Color.getByName("yellow"), + Color.getByName("yellow"), + (new Item.Properties()))); + + registry.register(new ResourceLocation(Constants.MOD_ID, "shieldmaidenegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_SHIELDMAIDEN, + Color.getByName("black"), + Color.getByName("white"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "norsemenarcheregg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_NORSEMEN_ARCHER, + Color.getByName("black"), + Color.getByName("green"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "norsemenchiefegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_NORSEMEN_CHIEF, + Color.getByName("black"), + Color.getByName("yellow"), + (new Item.Properties()))); + + registry.register(new ResourceLocation(Constants.MOD_ID, "amazonegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_AMAZON, + Color.getByName("green"), + Color.getByName("white"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "amazonspearmanegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_AMAZONSPEARMAN, + Color.getByName("green"), + Color.getByName("green"), + new Item.Properties())); + registry.register(new ResourceLocation(Constants.MOD_ID, "amazonchiefegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_AMAZONCHIEF, + Color.getByName("green"), + Color.getByName("yellow"), + (new Item.Properties()))); + + registry.register(new ResourceLocation(Constants.MOD_ID, "drownedpirateegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_DROWNED_PIRATE, + Color.getByName("blue"), + Color.getByName("white"), + (new Item.Properties()))); + registry.register(new ResourceLocation(Constants.MOD_ID, "drownedpiratearcheregg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_DROWNED_ARCHERPIRATE, + Color.getByName("blue"), + Color.getByName("green"), + new Item.Properties())); + registry.register(new ResourceLocation(Constants.MOD_ID, "drownedpiratecaptainegg"), new ForgeSpawnEggItem(() -> ModEntities.CAMP_DROWNED_CHIEFPIRATE, + Color.getByName("blue"), + Color.getByName("yellow"), + (new Item.Properties()))); } } diff --git a/src/main/java/com/minecolonies/core/MineColonies.java b/src/main/java/com/minecolonies/core/MineColonies.java index c599e54483d..231e4697160 100755 --- a/src/main/java/com/minecolonies/core/MineColonies.java +++ b/src/main/java/com/minecolonies/core/MineColonies.java @@ -12,7 +12,7 @@ import com.minecolonies.api.enchants.ModEnchants; import com.minecolonies.api.entity.ModEntities; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.entity.mobs.RaiderMobUtils; import com.minecolonies.api.items.ModBannerPatterns; import com.minecolonies.api.items.ModTags; @@ -179,24 +179,43 @@ public static void createEntityAttribute(final EntityAttributeCreationEvent even event.put(ModEntities.CITIZEN, AbstractEntityCitizen.getDefaultAttributes().build()); event.put(ModEntities.VISITOR, AbstractEntityCitizen.getDefaultAttributes().build()); event.put(ModEntities.MERCENARY, EntityMercenary.getDefaultAttributes().build()); - event.put(ModEntities.BARBARIAN, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.ARCHERBARBARIAN, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.CHIEFBARBARIAN, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.PHARAO, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.MUMMY, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.ARCHERMUMMY, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.PIRATE, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.ARCHERPIRATE, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.CHIEFPIRATE, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.AMAZON, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.AMAZONSPEARMAN, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.AMAZONCHIEF, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.NORSEMEN_ARCHER, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.NORSEMEN_CHIEF, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.SHIELDMAIDEN, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.DROWNED_PIRATE, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.DROWNED_ARCHERPIRATE, AbstractEntityRaiderMob.getDefaultAttributes().build()); - event.put(ModEntities.DROWNED_CHIEFPIRATE, AbstractEntityRaiderMob.getDefaultAttributes().build()); + event.put(ModEntities.BARBARIAN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.ARCHERBARBARIAN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CHIEFBARBARIAN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.PHARAO, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.MUMMY, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.ARCHERMUMMY, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.PIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.ARCHERPIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CHIEFPIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.AMAZON, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.AMAZONSPEARMAN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.AMAZONCHIEF, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.NORSEMEN_ARCHER, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.NORSEMEN_CHIEF, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.SHIELDMAIDEN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.DROWNED_PIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.DROWNED_ARCHERPIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.DROWNED_CHIEFPIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + + event.put(ModEntities.CAMP_BARBARIAN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_ARCHERBARBARIAN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_CHIEFBARBARIAN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_PIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_ARCHERPIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_CHIEFPIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_PHARAO, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_MUMMY, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_ARCHERMUMMY, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_AMAZON, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_AMAZONSPEARMAN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_AMAZONCHIEF, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_NORSEMEN_ARCHER, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_NORSEMEN_CHIEF, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_SHIELDMAIDEN, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_DROWNED_PIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_DROWNED_ARCHERPIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); + event.put(ModEntities.CAMP_DROWNED_CHIEFPIRATE, AbstractEntityMinecoloniesRaider.getDefaultAttributes().build()); } @SubscribeEvent diff --git a/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazon.java b/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazon.java index 7909f354504..4bb8f5f9cb7 100755 --- a/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazon.java +++ b/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazon.java @@ -1,7 +1,7 @@ package com.minecolonies.core.client.model.raiders; import com.minecolonies.api.client.render.modeltype.AmazonModel; -import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.PartPose; @@ -10,7 +10,7 @@ /** * General amazon model. */ -public class ModelAmazon extends AmazonModel +public class ModelAmazon extends AmazonModel { /** * Create an instance of it. diff --git a/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazonChief.java b/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazonChief.java index ee70e6ad363..950c4d554ef 100755 --- a/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazonChief.java +++ b/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazonChief.java @@ -1,7 +1,7 @@ package com.minecolonies.core.client.model.raiders; import com.minecolonies.api.client.render.modeltype.AmazonModel; -import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazonRaider; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.PartPose; @@ -10,7 +10,7 @@ /** * Amazon Chief model. */ -public class ModelAmazonChief extends AmazonModel +public class ModelAmazonChief extends AmazonModel { /** * Create an instance of it. diff --git a/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazonSpearman.java b/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazonSpearman.java index c1b8cdf4890..4e592ad1012 100644 --- a/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazonSpearman.java +++ b/src/main/java/com/minecolonies/core/client/model/raiders/ModelAmazonSpearman.java @@ -1,7 +1,7 @@ package com.minecolonies.core.client.model.raiders; import com.minecolonies.api.client.render.modeltype.AmazonModel; -import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazonRaider; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.PartPose; @@ -10,7 +10,7 @@ /** * General amazon model. */ -public class ModelAmazonSpearman extends AmazonModel +public class ModelAmazonSpearman extends AmazonModel { /** * Create an instance of it. diff --git a/src/main/java/com/minecolonies/core/client/model/raiders/ModelArcherMummy.java b/src/main/java/com/minecolonies/core/client/model/raiders/ModelArcherMummy.java index c7009d9e0f2..ca82bc3af44 100755 --- a/src/main/java/com/minecolonies/core/client/model/raiders/ModelArcherMummy.java +++ b/src/main/java/com/minecolonies/core/client/model/raiders/ModelArcherMummy.java @@ -1,7 +1,8 @@ package com.minecolonies.core.client.model.raiders; import com.minecolonies.api.client.render.modeltype.EgyptianModel; -import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; +import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptianRaider; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.PartPose; import net.minecraft.client.model.geom.builders.*; @@ -11,7 +12,7 @@ /** * Archer mummy model. Created using Tabula 7.0.0 */ -public class ModelArcherMummy extends EgyptianModel +public class ModelArcherMummy extends EgyptianModel { private ModelPart stripRightA; private ModelPart stripRightB; @@ -106,7 +107,7 @@ public void setRotateAngle(ModelPart modelRenderer, float x, float y, float z) } @Override - public void setupAnim(AbstractEntityEgyptian entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) + public void setupAnim(AbstractEntityMinecoloniesMonster entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { super.setupAnim(entityIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); float f = 0.05F * Mth.sin((float) Math.PI * ageInTicks / 30.0F) % 2.0F; diff --git a/src/main/java/com/minecolonies/core/client/model/raiders/ModelMummy.java b/src/main/java/com/minecolonies/core/client/model/raiders/ModelMummy.java index 52023780928..d492038db5e 100755 --- a/src/main/java/com/minecolonies/core/client/model/raiders/ModelMummy.java +++ b/src/main/java/com/minecolonies/core/client/model/raiders/ModelMummy.java @@ -1,7 +1,7 @@ package com.minecolonies.core.client.model.raiders; import com.minecolonies.api.client.render.modeltype.EgyptianModel; -import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.PartPose; import net.minecraft.client.model.geom.builders.*; @@ -11,7 +11,7 @@ /** * Create a mummy model. Created using Tabula 7.0.0 */ -public class ModelMummy extends EgyptianModel +public class ModelMummy extends EgyptianModel { private ModelPart stripRightA; private ModelPart stripRightB; @@ -106,7 +106,7 @@ public void setRotateAngle(ModelPart modelRenderer, float x, float y, float z) } @Override - public void setupAnim(AbstractEntityEgyptian entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) + public void setupAnim(AbstractEntityMinecoloniesMonster entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { super.setupAnim(entityIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); float f = 0.05F * Mth.sin((float) Math.PI * ageInTicks / 30.0F) % 2.0F; diff --git a/src/main/java/com/minecolonies/core/client/model/raiders/ModelPharaoh.java b/src/main/java/com/minecolonies/core/client/model/raiders/ModelPharaoh.java index 74f8d20130a..5d922b43d0c 100755 --- a/src/main/java/com/minecolonies/core/client/model/raiders/ModelPharaoh.java +++ b/src/main/java/com/minecolonies/core/client/model/raiders/ModelPharaoh.java @@ -1,7 +1,8 @@ package com.minecolonies.core.client.model.raiders; import com.minecolonies.api.client.render.modeltype.EgyptianModel; -import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; +import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptianRaider; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.PartPose; import net.minecraft.client.model.geom.builders.*; @@ -11,7 +12,7 @@ /** * ModelPharaohMummy. Created using Tabula 7.0.0 */ -public class ModelPharaoh extends EgyptianModel +public class ModelPharaoh extends EgyptianModel { private ModelPart bodyGoldenStrip; private ModelPart jaw; @@ -44,13 +45,11 @@ public static LayerDefinition createMesh() PartDefinition bodyDefinition = partDefinition.addOrReplaceChild("body", CubeListBuilder.create() - .texOffs(0, 16).addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F).mirror() + .texOffs(0, 16).addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).mirror() .texOffs(44, 0).addBox(-5.5F, -0.2F, -2.5F, 11.0F, 5.0F, 5.0F, new CubeDeformation( 0.15F)).mirror() .texOffs(0, 32).addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation( 0.3F)).mirror() - .texOffs(52, 11).addBox(-4.5F, 8.5F, -2.5F, 9.0F, 4.0F, 5.0F).mirror() - .texOffs(0, 0).addBox(-1.5F, -1.5F, -1.0F, 3.0F, 3.0F, 1.0F, new CubeDeformation( -0.3F)).mirror() - .texOffs(38, 12).addBox(-1.5F, 0.0F, 0.0F, 3.0F, 8.0F, 0.0F).mirror() - , PartPose.offset(0.0F, 10.0F, -2.6F)); + .texOffs(52, 11).addBox(-4.5F, 8.5F, -2.5F, 9.0F, 4.0F, 5.0F, new CubeDeformation(0.0F)).mirror() + , PartPose.offset(0.0F, 0.0F, 0.0F)); PartDefinition bodyJewelDefinition = bodyDefinition.addOrReplaceChild("bodyJewel", CubeListBuilder.create() @@ -84,16 +83,7 @@ public static LayerDefinition createMesh() .texOffs(0, 14).addBox(-2.5F, -2.0F, -3.5F, 5.0F, 1.0F, 0.0F).mirror() .texOffs(10, 10).addBox(-2.5F, -2.0F, -3.5F, 0.0F, 1.0F, 4.0F).mirror() .texOffs(10, 10).addBox(2.5F, -2.0F, -3.5F, 0.0F, 1.0F, 4.0F).mirror() - .texOffs(0, 51).addBox(-5.15F, 0.13F, 0.19F, 5.0F, 4.0F, 2.0F, new CubeDeformation( 0.13F)) - .texOffs(14, 51).addBox(0.0F, 0.0F, 0.19F, 5.0F, 6.0F, 2.0F, new CubeDeformation( 0.14F)) - .texOffs(0, 57).addBox(0.0F, -1.0F, -4.0F, 3.0F, 1.0F, 4.0F) - .texOffs(0, 51).addBox(0.15F, 0.13F, 0.19F, 5.0F, 4.0F, 2.0F, new CubeDeformation( 0.13F)).mirror() - .texOffs(14, 51).addBox(-5.0F, 0.0F, 0.19F, 5.0F, 6.0F, 2.0F, new CubeDeformation( 0.14F)).mirror() - .texOffs(0, 57).addBox(-3.0F, -1.0F, -4.0F, 3.0F, 1.0F, 4.0F).mirror() - .texOffs(28, 51).addBox(-3.0F, 0.0F, 0.0F, 3.0F, 6.0F, 2.0F, new CubeDeformation( -0.2F)).mirror() - .texOffs(76, 18).addBox(-4.5F, 0.0F, 0.0F, 9.0F, 4.0F, 8.0F, new CubeDeformation( 0.09F)).mirror() - .texOffs(18, 49).addBox(-4.5F, 0.15F, 0.19F, 9.0F, 0.0F, 2.0F, new CubeDeformation( 0.13F)).mirror() - , PartPose.offset(0.0F, -11.4F, 0.85F)); + , PartPose.offset(0.0F, 0.0F, -1.0F)); PartDefinition snakeBodyDefinition = headDefinition.addOrReplaceChild("snakeBody", CubeListBuilder.create() @@ -167,7 +157,7 @@ private static float sinPi(float f) } @Override - public void setupAnim(AbstractEntityEgyptian entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) + public void setupAnim(AbstractEntityMinecoloniesMonster entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { super.setupAnim(entityIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); this.bodyGoldenStrip.xRot = -Math.max(this.rightLeg.xRot, this.leftLeg.xRot); diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/amazon/AbstractRendererAmazon.java b/src/main/java/com/minecolonies/core/client/render/mobs/amazon/AbstractRendererAmazon.java index aa71b94ed4a..1e44d31e9af 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/amazon/AbstractRendererAmazon.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/amazon/AbstractRendererAmazon.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.amazon; -import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.render.RenderUtils; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.model.HumanoidModel; @@ -15,7 +15,7 @@ /** * Abstract for rendering amazons. */ -public abstract class AbstractRendererAmazon> extends HumanoidMobRenderer +public abstract class AbstractRendererAmazon> extends HumanoidMobRenderer { public AbstractRendererAmazon(final EntityRendererProvider.Context context, final M modelBipedIn, final float shadowSize) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererAmazon.java b/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererAmazon.java index eeaab40fdba..58c87407408 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererAmazon.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererAmazon.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.amazon; -import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelAmazon; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for archer amazons. */ -public class RendererAmazon extends AbstractRendererAmazon +public class RendererAmazon extends AbstractRendererAmazon { /** * Texture of the entity. @@ -29,7 +29,7 @@ public RendererAmazon(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(@NotNull final AbstractEntityAmazon entity) + public ResourceLocation getTextureLocation(@NotNull final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererAmazonSpearman.java b/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererAmazonSpearman.java index cee95f61169..6f4e5c345b9 100644 --- a/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererAmazonSpearman.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererAmazonSpearman.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.amazon; -import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelAmazonSpearman; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for spearman amazons. */ -public class RendererAmazonSpearman extends AbstractRendererAmazon +public class RendererAmazonSpearman extends AbstractRendererAmazon { /** * Texture of the entity. @@ -29,7 +29,7 @@ public RendererAmazonSpearman(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(@NotNull final AbstractEntityAmazon entity) + public ResourceLocation getTextureLocation(@NotNull final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererChiefAmazon.java b/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererChiefAmazon.java index a2431bf4d91..e4aaf6117a7 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererChiefAmazon.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/amazon/RendererChiefAmazon.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.amazon; -import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelAmazonChief; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for Chief amazons. */ -public class RendererChiefAmazon extends AbstractRendererAmazon +public class RendererChiefAmazon extends AbstractRendererAmazon { /** * Texture of the entity. @@ -29,7 +29,7 @@ public RendererChiefAmazon(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractEntityAmazon entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/AbstractRendererBarbarian.java b/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/AbstractRendererBarbarian.java index 56f21712376..0e3c33bf46c 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/AbstractRendererBarbarian.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/AbstractRendererBarbarian.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.barbarians; -import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.render.RenderUtils; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.model.HumanoidModel; @@ -15,7 +15,7 @@ /** * Abstract for rendering Barbarians. */ -public abstract class AbstractRendererBarbarian> extends HumanoidMobRenderer +public abstract class AbstractRendererBarbarian> extends HumanoidMobRenderer { public AbstractRendererBarbarian(final EntityRendererProvider.Context context, final M modelBipedIn, final float shadowSize) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/RendererBarbarian.java b/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/RendererBarbarian.java index 2139a5d4034..95c1e247db1 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/RendererBarbarian.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/RendererBarbarian.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.barbarians; -import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.model.HumanoidModel; @@ -9,7 +9,7 @@ /** * Renderer used for Barbarians And Archer Barbarians. */ -public class RendererBarbarian extends AbstractRendererBarbarian> +public class RendererBarbarian extends AbstractRendererBarbarian> { /** * Texture of the entity. @@ -28,7 +28,7 @@ public RendererBarbarian(final EntityRendererProvider.Context context) @Override - public ResourceLocation getTextureLocation(final AbstractEntityBarbarian entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/RendererChiefBarbarian.java b/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/RendererChiefBarbarian.java index 4bfca73b193..1fc719efb99 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/RendererChiefBarbarian.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/barbarians/RendererChiefBarbarian.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.barbarians; -import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.model.HumanoidModel; @@ -9,7 +9,7 @@ /** * Renderer used for Chief Barbarians. */ -public class RendererChiefBarbarian extends AbstractRendererBarbarian> +public class RendererChiefBarbarian extends AbstractRendererBarbarian> { /** * Texture of the entity. @@ -27,7 +27,7 @@ public RendererChiefBarbarian(final EntityRendererProvider.Context context) } @Override - public ResourceLocation getTextureLocation(final AbstractEntityBarbarian entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/AbstractRendererDrownedPirate.java b/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/AbstractRendererDrownedPirate.java index 3f33c11f369..9bf227a5f6c 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/AbstractRendererDrownedPirate.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/AbstractRendererDrownedPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.drownedpirates; -import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.render.RenderUtils; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.model.HumanoidModel; @@ -15,7 +15,7 @@ /** * Abstract for rendering Pirates. */ -public abstract class AbstractRendererDrownedPirate> extends HumanoidMobRenderer +public abstract class AbstractRendererDrownedPirate> extends HumanoidMobRenderer { public AbstractRendererDrownedPirate(final EntityRendererProvider.Context context, final M modelBipedIn, final float shadowSize) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedArcherPirate.java b/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedArcherPirate.java index f71a4df5b95..52c209d69f1 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedArcherPirate.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedArcherPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.drownedpirates; -import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for Barbarians And Archer Barbarians. */ -public class RendererDrownedArcherPirate extends AbstractRendererDrownedPirate> +public class RendererDrownedArcherPirate extends AbstractRendererDrownedPirate> { /** * Texture of the entity. @@ -32,7 +32,7 @@ public RendererDrownedArcherPirate(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractDrownedEntityPirate entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { switch (entity.getTextureId()) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedChiefPirate.java b/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedChiefPirate.java index ea9a8665750..4df36cbed49 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedChiefPirate.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedChiefPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.drownedpirates; -import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for Chief Barbarians. */ -public class RendererDrownedChiefPirate extends AbstractRendererDrownedPirate> +public class RendererDrownedChiefPirate extends AbstractRendererDrownedPirate> { /** * Texture of the entity. @@ -30,7 +30,7 @@ public RendererDrownedChiefPirate(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractDrownedEntityPirate entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { return TEXTURE1; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedPirate.java b/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedPirate.java index 2b61c0934c1..428d3ebd127 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedPirate.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/drownedpirates/RendererDrownedPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.drownedpirates; -import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for Barbarians And Archer Barbarians. */ -public class RendererDrownedPirate extends AbstractRendererDrownedPirate> +public class RendererDrownedPirate extends AbstractRendererDrownedPirate> { /** * Texture of the entity. @@ -32,7 +32,7 @@ public RendererDrownedPirate(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractDrownedEntityPirate entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { switch (entity.getTextureId()) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/AbstractRendererEgyptian.java b/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/AbstractRendererEgyptian.java index 2887b1c82ae..eb1a0bc1385 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/AbstractRendererEgyptian.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/AbstractRendererEgyptian.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.egyptians; -import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.render.RenderUtils; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.model.HumanoidModel; @@ -15,7 +15,7 @@ /** * Abstract for rendering Pirates. */ -public abstract class AbstractRendererEgyptian> extends HumanoidMobRenderer +public abstract class AbstractRendererEgyptian> extends HumanoidMobRenderer { public AbstractRendererEgyptian(final EntityRendererProvider.Context context, final M modelBipedIn, final float shadowSize) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererArcherMummy.java b/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererArcherMummy.java index 8617e7d4ba7..aef94bd7999 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererArcherMummy.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererArcherMummy.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.egyptians; -import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelArcherMummy; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -9,7 +9,7 @@ /** * Renderer used for archer mummy. */ -public class RendererArcherMummy extends AbstractRendererEgyptian +public class RendererArcherMummy extends AbstractRendererEgyptian { /** * Texture of the entity. @@ -27,7 +27,7 @@ public RendererArcherMummy(final EntityRendererProvider.Context context) } @Override - public ResourceLocation getTextureLocation(final AbstractEntityEgyptian entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererMummy.java b/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererMummy.java index f9723b43ca1..71ddf37108a 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererMummy.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererMummy.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.egyptians; -import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelMummy; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -9,7 +9,7 @@ /** * Renderer used for mummies. */ -public class RendererMummy extends AbstractRendererEgyptian +public class RendererMummy extends AbstractRendererEgyptian { /** * Texture of the entity. @@ -27,7 +27,7 @@ public RendererMummy(final EntityRendererProvider.Context context) } @Override - public ResourceLocation getTextureLocation(final AbstractEntityEgyptian entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererPharao.java b/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererPharao.java index d62010dad9f..fb99981bc43 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererPharao.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/egyptians/RendererPharao.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.egyptians; -import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelPharaoh; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -9,7 +9,7 @@ /** * Renderer used for the pharao. */ -public class RendererPharao extends AbstractRendererEgyptian +public class RendererPharao extends AbstractRendererEgyptian { /** * Texture of the entity. @@ -27,7 +27,7 @@ public RendererPharao(final EntityRendererProvider.Context context) } @Override - public ResourceLocation getTextureLocation(final AbstractEntityEgyptian entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/AbstractRendererNorsemen.java b/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/AbstractRendererNorsemen.java index 4512f91b4e4..b0650a36fe6 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/AbstractRendererNorsemen.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/AbstractRendererNorsemen.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.norsemen; -import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.render.RenderUtils; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.model.HumanoidModel; @@ -15,7 +15,7 @@ /** * Abstract for rendering amazons. */ -public abstract class AbstractRendererNorsemen> extends HumanoidMobRenderer +public abstract class AbstractRendererNorsemen> extends HumanoidMobRenderer { public AbstractRendererNorsemen(final EntityRendererProvider.Context context, final M modelBipedIn, final float shadowSize) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererArcherNorsemen.java b/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererArcherNorsemen.java index e84e724d72d..0b54ce5b7d0 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererArcherNorsemen.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererArcherNorsemen.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.norsemen; -import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelArcherNorsemen; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for archer amazons. */ -public class RendererArcherNorsemen extends AbstractRendererNorsemen +public class RendererArcherNorsemen extends AbstractRendererNorsemen { /** * Texture of the entity. @@ -30,7 +30,7 @@ public RendererArcherNorsemen(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractEntityNorsemen entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { if (entity.getTextureId() == 1) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererChiefNorsemen.java b/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererChiefNorsemen.java index 2e4f235e732..4a917fa25c3 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererChiefNorsemen.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererChiefNorsemen.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.norsemen; -import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelChiefNorsemen; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for Chief norsemen. */ -public class RendererChiefNorsemen extends AbstractRendererNorsemen +public class RendererChiefNorsemen extends AbstractRendererNorsemen { /** * Texture of the entity. @@ -29,7 +29,7 @@ public RendererChiefNorsemen(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractEntityNorsemen entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { return TEXTURE; } diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererShieldmaidenNorsemen.java b/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererShieldmaidenNorsemen.java index e2e903bac3f..fb5dc4b8085 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererShieldmaidenNorsemen.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/norsemen/RendererShieldmaidenNorsemen.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.norsemen; -import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.model.raiders.ModelShieldmaiden; import com.minecolonies.core.event.ClientRegistryHandler; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -10,7 +10,7 @@ /** * Renderer used for the shieldmaiden. */ -public class RendererShieldmaidenNorsemen extends AbstractRendererNorsemen +public class RendererShieldmaidenNorsemen extends AbstractRendererNorsemen { /** * Texture of the entity. @@ -30,7 +30,7 @@ public RendererShieldmaidenNorsemen(final EntityRendererProvider.Context context @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractEntityNorsemen entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { if (entity.getTextureId() == 1) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/pirates/AbstractRendererPirate.java b/src/main/java/com/minecolonies/core/client/render/mobs/pirates/AbstractRendererPirate.java index 50fba0dba8d..adcdf0a0ff5 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/pirates/AbstractRendererPirate.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/pirates/AbstractRendererPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.pirates; -import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.core.client.render.RenderUtils; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.model.HumanoidModel; @@ -15,7 +15,7 @@ /** * Abstract for rendering Pirates. */ -public abstract class AbstractRendererPirate> extends HumanoidMobRenderer +public abstract class AbstractRendererPirate> extends HumanoidMobRenderer { public AbstractRendererPirate(final EntityRendererProvider.Context context, final M modelBipedIn, final float shadowSize) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererArcherPirate.java b/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererArcherPirate.java index 66f905eb7c1..bb3fc807ccd 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererArcherPirate.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererArcherPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.pirates; -import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.model.HumanoidModel; @@ -10,7 +10,7 @@ /** * Renderer used for Barbarians And Archer Barbarians. */ -public class RendererArcherPirate extends AbstractRendererPirate> +public class RendererArcherPirate extends AbstractRendererPirate> { /** * Texture of the entity. @@ -32,7 +32,7 @@ public RendererArcherPirate(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractEntityPirate entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { switch (entity.getTextureId()) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererChiefPirate.java b/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererChiefPirate.java index ed5ece88bdf..997fa4385f1 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererChiefPirate.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererChiefPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.pirates; -import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.model.HumanoidModel; @@ -10,7 +10,7 @@ /** * Renderer used for Chief Barbarians. */ -public class RendererChiefPirate extends AbstractRendererPirate> +public class RendererChiefPirate extends AbstractRendererPirate> { /** * Texture of the entity. @@ -32,7 +32,7 @@ public RendererChiefPirate(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractEntityPirate entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { switch (entity.getTextureId()) { diff --git a/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererPirate.java b/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererPirate.java index 7e3ccb5bdae..67fa6c8ceb7 100755 --- a/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererPirate.java +++ b/src/main/java/com/minecolonies/core/client/render/mobs/pirates/RendererPirate.java @@ -1,6 +1,6 @@ package com.minecolonies.core.client.render.mobs.pirates; -import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.model.HumanoidModel; @@ -10,7 +10,7 @@ /** * Renderer used for Barbarians And Archer Barbarians. */ -public class RendererPirate extends AbstractRendererPirate> +public class RendererPirate extends AbstractRendererPirate> { /** * Texture of the entity. @@ -32,7 +32,7 @@ public RendererPirate(final EntityRendererProvider.Context context) @NotNull @Override - public ResourceLocation getTextureLocation(final AbstractEntityPirate entity) + public ResourceLocation getTextureLocation(final AbstractEntityMinecoloniesMonster entity) { switch (entity.getTextureId()) { diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/AbstractShipRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/AbstractShipRaidEvent.java index 4484b84527c..8bee6289033 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/AbstractShipRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/AbstractShipRaidEvent.java @@ -7,7 +7,7 @@ import com.minecolonies.api.colony.colonyEvents.EventStatus; import com.minecolonies.api.colony.colonyEvents.IColonyRaidEvent; import com.minecolonies.api.colony.colonyEvents.IColonyStructureSpawnEvent; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.entity.mobs.RaiderMobUtils; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.MessageUtils; @@ -382,7 +382,7 @@ public void onEntityDeath(final LivingEntity entity) @Override public void registerEntity(final Entity entity) { - if (!(entity instanceof AbstractEntityRaiderMob) || !entity.isAlive() || status != EventStatus.PROGRESSING) + if (!(entity instanceof AbstractEntityMinecoloniesRaider) || !entity.isAlive() || status != EventStatus.PROGRESSING) { entity.remove(Entity.RemovalReason.DISCARDED); return; diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/HordeRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/HordeRaidEvent.java index 8e6aae93b66..5af99f5c8d7 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/HordeRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/HordeRaidEvent.java @@ -6,7 +6,7 @@ import com.minecolonies.api.colony.colonyEvents.IColonyCampFireRaidEvent; import com.minecolonies.api.colony.colonyEvents.IColonyEvent; import com.minecolonies.api.colony.colonyEvents.IColonyRaidEvent; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.entity.mobs.RaiderMobUtils; import com.minecolonies.api.sounds.RaidSounds; import com.minecolonies.api.util.*; @@ -214,9 +214,9 @@ public void unregisterEntity(final Entity entity) @Override public void onEntityDeath(final LivingEntity entity) { - if (entity instanceof AbstractEntityRaiderMob) + if (entity instanceof AbstractEntityMinecoloniesRaider) { - colony.getRaiderManager().onRaiderDeath((AbstractEntityRaiderMob) entity); + colony.getRaiderManager().onRaiderDeath((AbstractEntityMinecoloniesRaider) entity); } } diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/RaidManager.java b/src/main/java/com/minecolonies/core/colony/events/raid/RaidManager.java index aabbc3a7c18..636f8c03738 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/RaidManager.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/RaidManager.java @@ -11,7 +11,7 @@ import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.entity.citizen.happiness.ExpirationBasedHappinessModifier; import com.minecolonies.api.entity.citizen.happiness.StaticHappinessSupplier; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.sounds.RaidSounds; import com.minecolonies.api.util.*; import com.minecolonies.api.util.constant.ColonyConstants; @@ -1018,7 +1018,7 @@ public int getLostCitizen() } @Override - public void onRaiderDeath(final AbstractEntityRaiderMob entity) + public void onRaiderDeath(final AbstractEntityMinecoloniesRaider entity) { final RaidHistory last = getLastRaid(); if (last != null) diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/amazonevent/AmazonRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/amazonevent/AmazonRaidEvent.java index e1f97e72292..4383faf9b12 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/amazonevent/AmazonRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/amazonevent/AmazonRaidEvent.java @@ -2,13 +2,13 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.colonyEvents.EventStatus; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.sounds.RaidSounds; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.colony.events.raid.HordeRaidEvent; -import com.minecolonies.core.entity.mobs.amazons.EntityAmazonChief; -import com.minecolonies.core.entity.mobs.amazons.EntityAmazonSpearman; -import com.minecolonies.core.entity.mobs.amazons.EntityArcherAmazon; +import com.minecolonies.core.entity.mobs.raider.amazons.EntityAmazonChiefRaider; +import com.minecolonies.core.entity.mobs.raider.amazons.EntityAmazonSpearmanRaider; +import com.minecolonies.core.entity.mobs.raider.amazons.EntityArcherAmazonRaider; import com.minecolonies.core.network.messages.client.PlayAudioMessage; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; @@ -50,25 +50,25 @@ public ResourceLocation getEventTypeID() @Override public void registerEntity(final Entity entity) { - if (!(entity instanceof AbstractEntityRaiderMob) || !entity.isAlive()) + if (!(entity instanceof AbstractEntityMinecoloniesRaider) || !entity.isAlive()) { entity.remove(Entity.RemovalReason.DISCARDED); return; } - if (entity instanceof EntityAmazonChief && boss.keySet().size() < horde.numberOfBosses) + if (entity instanceof EntityAmazonChiefRaider && boss.keySet().size() < horde.numberOfBosses) { boss.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityArcherAmazon && archers.keySet().size() < horde.numberOfArchers) + if (entity instanceof EntityArcherAmazonRaider && archers.keySet().size() < horde.numberOfArchers) { archers.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityAmazonSpearman && normal.keySet().size() < horde.numberOfRaiders) + if (entity instanceof EntityAmazonSpearmanRaider && normal.keySet().size() < horde.numberOfRaiders) { normal.put(entity, entity.getUUID()); return; @@ -105,24 +105,24 @@ public void onUpdate() public void onEntityDeath(final LivingEntity entity) { super.onEntityDeath(entity); - if (!(entity instanceof AbstractEntityRaiderMob)) + if (!(entity instanceof AbstractEntityMinecoloniesRaider)) { return; } - if (entity instanceof EntityAmazonChief) + if (entity instanceof EntityAmazonChiefRaider) { boss.remove(entity); horde.numberOfBosses--; } - if (entity instanceof EntityArcherAmazon) + if (entity instanceof EntityArcherAmazonRaider) { archers.remove(entity); horde.numberOfArchers--; } - if (entity instanceof EntityAmazonSpearman) + if (entity instanceof EntityAmazonSpearmanRaider) { normal.remove(entity); horde.numberOfRaiders--; diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/barbarianEvent/BarbarianRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/barbarianEvent/BarbarianRaidEvent.java index 8ceea8f2773..d2798a3e4dd 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/barbarianEvent/BarbarianRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/barbarianEvent/BarbarianRaidEvent.java @@ -2,12 +2,12 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.colonyEvents.EventStatus; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.colony.events.raid.HordeRaidEvent; -import com.minecolonies.core.entity.mobs.barbarians.EntityArcherBarbarian; -import com.minecolonies.core.entity.mobs.barbarians.EntityBarbarian; -import com.minecolonies.core.entity.mobs.barbarians.EntityChiefBarbarian; +import com.minecolonies.core.entity.mobs.raider.barbarians.EntityArcherBarbarianRaider; +import com.minecolonies.core.entity.mobs.raider.barbarians.EntityBarbarianRaider; +import com.minecolonies.core.entity.mobs.raider.barbarians.EntityChiefBarbarianRaider; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -43,25 +43,25 @@ public ResourceLocation getEventTypeID() @Override public void registerEntity(final Entity entity) { - if (!(entity instanceof AbstractEntityRaiderMob) || !entity.isAlive()) + if (!(entity instanceof AbstractEntityMinecoloniesRaider) || !entity.isAlive()) { entity.remove(Entity.RemovalReason.DISCARDED); return; } - if (entity instanceof EntityChiefBarbarian && boss.keySet().size() < horde.numberOfBosses) + if (entity instanceof EntityChiefBarbarianRaider && boss.keySet().size() < horde.numberOfBosses) { boss.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityArcherBarbarian && archers.keySet().size() < horde.numberOfArchers) + if (entity instanceof EntityArcherBarbarianRaider && archers.keySet().size() < horde.numberOfArchers) { archers.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityBarbarian && normal.keySet().size() < horde.numberOfRaiders) + if (entity instanceof EntityBarbarianRaider && normal.keySet().size() < horde.numberOfRaiders) { normal.put(entity, entity.getUUID()); return; @@ -74,24 +74,24 @@ public void registerEntity(final Entity entity) public void onEntityDeath(final LivingEntity entity) { super.onEntityDeath(entity); - if (!(entity instanceof AbstractEntityRaiderMob)) + if (!(entity instanceof AbstractEntityMinecoloniesRaider)) { return; } - if (entity instanceof EntityChiefBarbarian) + if (entity instanceof EntityChiefBarbarianRaider) { boss.remove(entity); horde.numberOfBosses--; } - if (entity instanceof EntityArcherBarbarian) + if (entity instanceof EntityArcherBarbarianRaider) { archers.remove(entity); horde.numberOfArchers--; } - if (entity instanceof EntityBarbarian) + if (entity instanceof EntityBarbarianRaider) { normal.remove(entity); horde.numberOfRaiders--; diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/egyptianevent/EgyptianRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/egyptianevent/EgyptianRaidEvent.java index 4eacb9b9583..96387ea7f03 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/egyptianevent/EgyptianRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/egyptianevent/EgyptianRaidEvent.java @@ -2,13 +2,13 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.colonyEvents.EventStatus; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.sounds.RaidSounds; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.colony.events.raid.HordeRaidEvent; -import com.minecolonies.core.entity.mobs.egyptians.EntityArcherMummy; -import com.minecolonies.core.entity.mobs.egyptians.EntityMummy; -import com.minecolonies.core.entity.mobs.egyptians.EntityPharao; +import com.minecolonies.core.entity.mobs.raider.egyptians.EntityArcherMummyRaider; +import com.minecolonies.core.entity.mobs.raider.egyptians.EntityMummyRaider; +import com.minecolonies.core.entity.mobs.raider.egyptians.EntityPharaoRaider; import com.minecolonies.core.network.messages.client.PlayAudioMessage; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; @@ -76,25 +76,25 @@ public void onUpdate() @Override public void registerEntity(final Entity entity) { - if (!(entity instanceof AbstractEntityRaiderMob) || !entity.isAlive()) + if (!(entity instanceof AbstractEntityMinecoloniesRaider) || !entity.isAlive()) { entity.remove(Entity.RemovalReason.DISCARDED); return; } - if (entity instanceof EntityPharao && boss.keySet().size() < horde.numberOfBosses) + if (entity instanceof EntityPharaoRaider && boss.keySet().size() < horde.numberOfBosses) { boss.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityArcherMummy && archers.keySet().size() < horde.numberOfArchers) + if (entity instanceof EntityArcherMummyRaider && archers.keySet().size() < horde.numberOfArchers) { archers.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityMummy && normal.keySet().size() < horde.numberOfRaiders) + if (entity instanceof EntityMummyRaider && normal.keySet().size() < horde.numberOfRaiders) { normal.put(entity, entity.getUUID()); return; @@ -107,24 +107,24 @@ public void registerEntity(final Entity entity) public void onEntityDeath(final LivingEntity entity) { super.onEntityDeath(entity); - if (!(entity instanceof AbstractEntityRaiderMob)) + if (!(entity instanceof AbstractEntityMinecoloniesRaider)) { return; } - if (entity instanceof EntityPharao) + if (entity instanceof EntityPharaoRaider) { boss.remove(entity); horde.numberOfBosses--; } - if (entity instanceof EntityArcherMummy) + if (entity instanceof EntityArcherMummyRaider) { archers.remove(entity); horde.numberOfArchers--; } - if (entity instanceof EntityMummy) + if (entity instanceof EntityMummyRaider) { normal.remove(entity); horde.numberOfRaiders--; diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/norsemenevent/NorsemenRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/norsemenevent/NorsemenRaidEvent.java index 440f2f02d0e..e1e00d0bb26 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/norsemenevent/NorsemenRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/norsemenevent/NorsemenRaidEvent.java @@ -2,12 +2,12 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.colonyEvents.EventStatus; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.colony.events.raid.HordeRaidEvent; -import com.minecolonies.core.entity.mobs.norsemen.EntityNorsemenArcher; -import com.minecolonies.core.entity.mobs.norsemen.EntityNorsemenChief; -import com.minecolonies.core.entity.mobs.norsemen.EntityShieldmaiden; +import com.minecolonies.core.entity.mobs.raider.norsemen.EntityNorsemenArcherRaider; +import com.minecolonies.core.entity.mobs.raider.norsemen.EntityNorsemenChiefRaider; +import com.minecolonies.core.entity.mobs.raider.norsemen.EntityShieldmaidenRaider; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -50,25 +50,25 @@ protected void updateRaidBar() @Override public void registerEntity(final Entity entity) { - if (!(entity instanceof AbstractEntityRaiderMob) || !entity.isAlive()) + if (!(entity instanceof AbstractEntityMinecoloniesRaider) || !entity.isAlive()) { entity.remove(Entity.RemovalReason.DISCARDED); return; } - if (entity instanceof EntityNorsemenChief && boss.keySet().size() < horde.numberOfBosses) + if (entity instanceof EntityNorsemenChiefRaider && boss.keySet().size() < horde.numberOfBosses) { boss.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityNorsemenArcher && archers.keySet().size() < horde.numberOfArchers) + if (entity instanceof EntityNorsemenArcherRaider && archers.keySet().size() < horde.numberOfArchers) { archers.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityShieldmaiden && normal.keySet().size() < horde.numberOfRaiders) + if (entity instanceof EntityShieldmaidenRaider && normal.keySet().size() < horde.numberOfRaiders) { normal.put(entity, entity.getUUID()); return; @@ -81,24 +81,24 @@ public void registerEntity(final Entity entity) public void onEntityDeath(final LivingEntity entity) { super.onEntityDeath(entity); - if (!(entity instanceof AbstractEntityRaiderMob)) + if (!(entity instanceof AbstractEntityMinecoloniesRaider)) { return; } - if (entity instanceof EntityNorsemenChief) + if (entity instanceof EntityNorsemenChiefRaider) { boss.remove(entity); horde.numberOfBosses--; } - if (entity instanceof EntityNorsemenArcher) + if (entity instanceof EntityNorsemenArcherRaider) { archers.remove(entity); horde.numberOfArchers--; } - if (entity instanceof EntityShieldmaiden) + if (entity instanceof EntityShieldmaidenRaider) { normal.remove(entity); horde.numberOfRaiders--; diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/PirateGroundRaidEvent.java b/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/PirateGroundRaidEvent.java index 5bc1eabf9f6..f39fcdeb753 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/PirateGroundRaidEvent.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/PirateGroundRaidEvent.java @@ -2,12 +2,12 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.colonyEvents.EventStatus; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.colony.events.raid.HordeRaidEvent; -import com.minecolonies.core.entity.mobs.pirates.EntityArcherPirate; -import com.minecolonies.core.entity.mobs.pirates.EntityCaptainPirate; -import com.minecolonies.core.entity.mobs.pirates.EntityPirate; +import com.minecolonies.core.entity.mobs.raider.pirates.EntityArcherPirateRaider; +import com.minecolonies.core.entity.mobs.raider.pirates.EntityCaptainPirateRaider; +import com.minecolonies.core.entity.mobs.raider.pirates.EntityPirateRaider; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -62,25 +62,25 @@ public void onUpdate() @Override public void registerEntity(final Entity entity) { - if (!(entity instanceof AbstractEntityRaiderMob) || !entity.isAlive()) + if (!(entity instanceof AbstractEntityMinecoloniesRaider) || !entity.isAlive()) { entity.remove(Entity.RemovalReason.DISCARDED); return; } - if (entity instanceof EntityCaptainPirate && boss.keySet().size() < horde.numberOfBosses) + if (entity instanceof EntityCaptainPirateRaider && boss.keySet().size() < horde.numberOfBosses) { boss.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityArcherPirate && archers.keySet().size() < horde.numberOfArchers) + if (entity instanceof EntityArcherPirateRaider && archers.keySet().size() < horde.numberOfArchers) { archers.put(entity, entity.getUUID()); return; } - if (entity instanceof EntityPirate && normal.keySet().size() < horde.numberOfRaiders) + if (entity instanceof EntityPirateRaider && normal.keySet().size() < horde.numberOfRaiders) { normal.put(entity, entity.getUUID()); return; @@ -93,24 +93,24 @@ public void registerEntity(final Entity entity) public void onEntityDeath(final LivingEntity entity) { super.onEntityDeath(entity); - if (!(entity instanceof AbstractEntityRaiderMob)) + if (!(entity instanceof AbstractEntityMinecoloniesRaider)) { return; } - if (entity instanceof EntityCaptainPirate) + if (entity instanceof EntityCaptainPirateRaider) { boss.remove(entity); horde.numberOfBosses--; } - if (entity instanceof EntityArcherPirate) + if (entity instanceof EntityArcherPirateRaider) { archers.remove(entity); horde.numberOfArchers--; } - if (entity instanceof EntityPirate) + if (entity instanceof EntityPirateRaider) { normal.remove(entity); horde.numberOfRaiders--; diff --git a/src/main/java/com/minecolonies/core/commands/killcommands/CommandKillRaider.java b/src/main/java/com/minecolonies/core/commands/killcommands/CommandKillRaider.java index dacb4a10f33..da42f9d4055 100755 --- a/src/main/java/com/minecolonies/core/commands/killcommands/CommandKillRaider.java +++ b/src/main/java/com/minecolonies/core/commands/killcommands/CommandKillRaider.java @@ -2,7 +2,7 @@ import com.minecolonies.api.colony.colonyEvents.EventStatus; import com.minecolonies.api.colony.colonyEvents.IColonyEvent; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.util.DamageSourceKeys; import com.minecolonies.core.commands.commandTypes.IMCOPCommand; import com.mojang.brigadier.context.CommandContext; @@ -25,11 +25,11 @@ public int onExecute(final CommandContext context) { entitiesKilled = 0; - context.getSource().getLevel().getEntities(EntityTypeTest.forClass(AbstractEntityRaiderMob.class), (e) -> true).forEach(entity -> + context.getSource().getLevel().getEntities(EntityTypeTest.forClass(AbstractEntityMinecoloniesRaider.class), (e) -> true).forEach(entity -> { if (entity != null) { - final AbstractEntityRaiderMob mob = (AbstractEntityRaiderMob) entity; + final AbstractEntityMinecoloniesRaider mob = (AbstractEntityMinecoloniesRaider) entity; mob.die(context.getSource().getLevel().damageSources().source(DamageSourceKeys.CONSOLE)); mob.remove(Entity.RemovalReason.DISCARDED); diff --git a/src/main/java/com/minecolonies/core/compatibility/journeymap/EventListener.java b/src/main/java/com/minecolonies/core/compatibility/journeymap/EventListener.java index 39459526c80..99e9e535223 100644 --- a/src/main/java/com/minecolonies/core/compatibility/journeymap/EventListener.java +++ b/src/main/java/com/minecolonies/core/compatibility/journeymap/EventListener.java @@ -7,7 +7,7 @@ import com.minecolonies.api.colony.jobs.registry.IJobRegistry; import com.minecolonies.api.colony.jobs.registry.JobEntry; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.core.colony.jobs.AbstractJobGuard; import com.minecolonies.core.entity.visitor.VisitorCitizen; import journeymap.client.api.display.Context; @@ -152,7 +152,7 @@ public void onUpdateEntityRadar(@NotNull final EntityRadarUpdateEvent event) wrapper.setColor(entity.getTeamColor()); } } - else if (entity instanceof AbstractEntityRaiderMob) + else if (entity instanceof AbstractEntityMinecoloniesRaider) { final JourneymapOptions.RaiderColor color = JourneymapOptions.getRaiderColor(this.jmap.getOptions()); diff --git a/src/main/java/com/minecolonies/core/entity/ai/combat/CombatUtils.java b/src/main/java/com/minecolonies/core/entity/ai/combat/CombatUtils.java index 467026724e2..1776be9b29d 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/combat/CombatUtils.java +++ b/src/main/java/com/minecolonies/core/entity/ai/combat/CombatUtils.java @@ -4,7 +4,7 @@ import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.entity.ModEntities; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.core.colony.buildings.AbstractBuildingGuards; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.items.ItemSpear; @@ -98,7 +98,7 @@ public static void notifyGuardsOfTarget(final AbstractEntityCitizen user, final } } - if (target instanceof AbstractEntityRaiderMob) + if (target instanceof AbstractEntityMinecoloniesRaider) { for (final Map.Entry entry : user.getCitizenColonyHandler().getColonyOrRegister().getBuildingManager().getBuildings().entrySet()) { diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/CampWalkAI.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/CampWalkAI.java new file mode 100644 index 00000000000..4ae3f64a6ee --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/CampWalkAI.java @@ -0,0 +1,102 @@ +package com.minecolonies.core.entity.mobs.aitasks; + +import com.minecolonies.api.entity.ai.IStateAI; +import com.minecolonies.api.entity.ai.combat.CombatAIStates; +import com.minecolonies.api.entity.ai.statemachine.states.IState; +import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; +import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; +import com.minecolonies.api.entity.pathfinding.IPathJob; +import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Tuple; + +import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND; + +/** + * AI for handling the raiders walking directions + */ +public class CampWalkAI implements IStateAI +{ + /** + * The entity using this AI + */ + private final AbstractEntityMinecoloniesMonster entity; + + /** + * Target block we're walking to + */ + private BlockPos targetBlock = null; + + /** + * Walk timer + */ + private long walkTimer = 0; + + /** + * Random path result. + */ + private PathResult randomPathResult; + + /** + * Spawn center box cache. + */ + private Tuple spawnCenterBoxCache = null; + + public CampWalkAI(final AbstractEntityMinecoloniesMonster raider, final ITickRateStateMachine stateMachine) + { + this.entity = raider; + stateMachine.addTransition(new TickingTransition<>(CombatAIStates.NO_TARGET, this::walk, () -> null, 80)); + } + + /** + * Walk raider towards the colony or campfires + * + */ + private boolean walk() + { + if (targetBlock == null || entity.level.getGameTime() > walkTimer) + { + targetBlock = findRandomPositionToWalkTo(); + walkTimer = entity.level.getGameTime() + TICKS_SECOND * 30; + } + else + { + entity.getNavigation().moveToXYZ(targetBlock.getX(), targetBlock.getY(), targetBlock.getZ(),1.1); + randomPathResult = null; + } + + return false; + } + + protected BlockPos findRandomPositionToWalkTo() + { + if (randomPathResult == null || randomPathResult.failedToReachDestination()) + { + if (spawnCenterBoxCache == null) + { + final BlockPos startPos = entity.getSpawnPos() == null ? entity.blockPosition() : entity.getSpawnPos(); + spawnCenterBoxCache = new Tuple<>(startPos.offset(-10,-5,-10), startPos.offset(10,5,10)); + } + + randomPathResult = entity.getNavigation().moveToRandomPos(10, 0.9, spawnCenterBoxCache); + if (randomPathResult != null) + { + randomPathResult.getJob().getPathingOptions().withCanEnterDoors(true).withToggleCost(0).withNonLadderClimbableCost(0); + } + } + + if (randomPathResult.isPathReachingDestination()) + { + return randomPathResult.getPath().getEndNode().asBlockPos(); + } + + if (randomPathResult.isCancelled()) + { + randomPathResult = null; + return null; + } + + return null; + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/EntityAIBreakDoor.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/EntityAIBreakDoor.java index 0de00d2356f..27e8a3f799b 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/EntityAIBreakDoor.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/EntityAIBreakDoor.java @@ -2,7 +2,7 @@ import com.minecolonies.api.blocks.decorative.AbstractBlockGate; import com.minecolonies.api.colony.IColony; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.core.MineColonies; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Mob; @@ -58,9 +58,9 @@ public void start() hardness = (int) (1 + mob.level.getBlockState(doorPos).getDestroySpeed(mob.level, doorPos)); // No stuck during door break - if (mob instanceof AbstractEntityRaiderMob) + if (mob instanceof AbstractEntityMinecoloniesRaider) { - ((AbstractEntityRaiderMob) mob).setCanBeStuck(false); + ((AbstractEntityMinecoloniesRaider) mob).setCanBeStuck(false); } } @@ -68,9 +68,9 @@ public void stop() { super.stop(); this.mob.level.destroyBlockProgress(this.mob.getId(), this.doorPos, -1); - if (mob instanceof AbstractEntityRaiderMob) + if (mob instanceof AbstractEntityMinecoloniesRaider) { - ((AbstractEntityRaiderMob) mob).setCanBeStuck(true); + ((AbstractEntityMinecoloniesRaider) mob).setCanBeStuck(true); } } @@ -92,16 +92,16 @@ public void tick() { double fasterBreakPerXNearby = 5; - if (mob instanceof AbstractEntityRaiderMob && !mob.level.isClientSide() && mob.level.getBlockState(doorPos).getBlock() instanceof AbstractBlockGate) + if (mob instanceof AbstractEntityMinecoloniesRaider && !mob.level.isClientSide() && mob.level.getBlockState(doorPos).getBlock() instanceof AbstractBlockGate) { - final IColony colony = ((AbstractEntityRaiderMob) mob).getColony(); + final IColony colony = ((AbstractEntityMinecoloniesRaider) mob).getColony(); fasterBreakPerXNearby += colony.getResearchManager().getResearchEffects().getEffectStrength(MECHANIC_ENHANCED_GATES); } fasterBreakPerXNearby /= 2; breakChance = (int) Math.max(1, - hardness / (1 + (mob.level.getEntitiesOfClass(AbstractEntityRaiderMob.class, mob.getBoundingBox().inflate(5)).size() / fasterBreakPerXNearby))); + hardness / (1 + (mob.level.getEntitiesOfClass(AbstractEntityMinecoloniesRaider.class, mob.getBoundingBox().inflate(5)).size() / fasterBreakPerXNearby))); } if (this.breakTime == this.getDoorBreakTime() - 1) diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderMeleeAI.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderMeleeAI.java index 14561f495ea..461f34d2214 100644 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderMeleeAI.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderMeleeAI.java @@ -3,7 +3,8 @@ import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity; import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.entity.ai.combat.AttackMoveAI; @@ -23,7 +24,7 @@ /** * Raider AI for melee attacking a target */ -public class RaiderMeleeAI extends AttackMoveAI +public class RaiderMeleeAI extends AttackMoveAI { /** * Extended reach based on difficulty @@ -84,7 +85,7 @@ protected int getAttackDelay() protected PathResult moveInAttackPosition(final LivingEntity target) { return user.getNavigation() - .moveToXYZ(target.getX(), target.getY(), target.getZ(), user.getDifficulty() < ADD_SPEED_DIFFICULTY ? BASE_COMBAT_SPEED : BASE_COMBAT_SPEED * BONUS_SPEED); + .moveToXYZ(target.getX(), target.getY(), target.getZ(), user.getDifficulty() < ADD_SPEED_DIFFICULTY ? BASE_COMBAT_SPEED : BASE_COMBAT_SPEED * BONUS_SPEED); } @Override diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderRangedAI.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderRangedAI.java index 2627fcaf1f6..39ecdff9b83 100644 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderRangedAI.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderRangedAI.java @@ -3,7 +3,8 @@ import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity; import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.entity.mobs.ICustomAttackSound; import com.minecolonies.api.entity.mobs.IRangedMobEntity; import com.minecolonies.api.util.EntityUtils; @@ -24,7 +25,7 @@ /** * Raider AI for shooting arrows at a target */ -public class RaiderRangedAI extends AttackMoveAI +public class RaiderRangedAI extends AttackMoveAI { /** * Max delay between attacks is 3s, aka 60 ticks. diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderWalkAI.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderWalkAI.java index acd66cfd147..a1a0c52f9d7 100644 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderWalkAI.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderWalkAI.java @@ -8,7 +8,7 @@ import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.entity.pathfinding.IPathJob; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.Log; @@ -30,7 +30,7 @@ public class RaiderWalkAI implements IStateAI /** * The entity using this AI */ - private final AbstractEntityRaiderMob raider; + private final AbstractEntityMinecoloniesRaider raider; /** * Target block we're walking to @@ -52,7 +52,7 @@ public class RaiderWalkAI implements IStateAI */ private boolean walkInBuildingState = false; - public RaiderWalkAI(final AbstractEntityRaiderMob raider, final ITickRateStateMachine stateMachine) + public RaiderWalkAI(final AbstractEntityMinecoloniesRaider raider, final ITickRateStateMachine stateMachine) { this.raider = raider; stateMachine.addTransition(new TickingTransition<>(CombatAIStates.NO_TARGET, this::walk, () -> null, 80)); @@ -167,6 +167,12 @@ protected BlockPos findRandomPositionToWalkTo() } } + if (randomPathResult == null) + { + return null; + } + + if (randomPathResult.isPathReachingDestination()) { return randomPathResult.getPath().getEndNode().asBlockPos(); diff --git a/src/main/java/com/minecolonies/core/entity/mobs/amazons/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/amazons/package-info.java deleted file mode 100755 index c7a3af81556..00000000000 --- a/src/main/java/com/minecolonies/core/entity/mobs/amazons/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes describing the amazon raiders. - */ -package com.minecolonies.core.entity.mobs.amazons; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/barbarians/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/barbarians/package-info.java deleted file mode 100755 index ddedd89b57f..00000000000 --- a/src/main/java/com/minecolonies/core/entity/mobs/barbarians/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes describing the Barbarian entities. - */ -package com.minecolonies.core.entity.mobs.barbarians; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityAmazonChief.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityAmazonChief.java similarity index 86% rename from src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityAmazonChief.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityAmazonChief.java index 2e9bfc3f98d..12047372c4a 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityAmazonChief.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityAmazonChief.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.amazons; +package com.minecolonies.core.entity.mobs.camp.amazons; import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; import com.minecolonies.api.entity.mobs.amazons.IAmazonChief; @@ -7,7 +7,6 @@ import net.minecraft.world.level.Level; import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; -import static com.minecolonies.api.util.constant.RaiderConstants.BASE_ENV_DAMAGE_RESIST; import static com.minecolonies.api.util.constant.RaiderConstants.CHIEF_BONUS_ARMOR; /** @@ -15,7 +14,6 @@ */ public class EntityAmazonChief extends AbstractEntityAmazon implements IAmazonChief { - /** * Constructor of the entity. * @@ -34,7 +32,6 @@ public void initStatsFor(final double baseHealth, final double difficulty, final final double chiefArmor = difficulty * CHIEF_BONUS_ARMOR * 2; this.getAttribute(Attributes.ARMOR).setBaseValue(chiefArmor); this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 1.0); - this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5); this.setHealth(this.getMaxHealth()); } diff --git a/src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityAmazonSpearman.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityAmazonSpearman.java similarity index 83% rename from src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityAmazonSpearman.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityAmazonSpearman.java index ae3a37b6fc2..94568bf03c4 100644 --- a/src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityAmazonSpearman.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityAmazonSpearman.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.amazons; +package com.minecolonies.core.entity.mobs.camp.amazons; import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; +import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazonRaider; import com.minecolonies.api.entity.mobs.amazons.IAmazonSpearman; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityArcherAmazon.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityArcherAmazon.java similarity index 92% rename from src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityArcherAmazon.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityArcherAmazon.java index 6273edcae4d..495fbd8ccd8 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/amazons/EntityArcherAmazon.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/amazons/EntityArcherAmazon.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.amazons; +package com.minecolonies.core.entity.mobs.camp.amazons; import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazon; import com.minecolonies.api.entity.mobs.amazons.IArcherAmazon; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityArcherBarbarian.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityArcherBarbarian.java similarity index 92% rename from src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityArcherBarbarian.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityArcherBarbarian.java index 14990db4b94..504d7802d8b 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityArcherBarbarian.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityArcherBarbarian.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.barbarians; +package com.minecolonies.core.entity.mobs.camp.barbarians; import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarian; import com.minecolonies.api.entity.mobs.barbarians.IArcherBarbarianEntity; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityBarbarian.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityBarbarian.java similarity index 91% rename from src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityBarbarian.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityBarbarian.java index adf6d0bcc2a..65dfda93c8a 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityBarbarian.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityBarbarian.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.barbarians; +package com.minecolonies.core.entity.mobs.camp.barbarians; import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarian; import com.minecolonies.api.entity.mobs.barbarians.IMeleeBarbarianEntity; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityChiefBarbarian.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityChiefBarbarian.java similarity index 86% rename from src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityChiefBarbarian.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityChiefBarbarian.java index 2c13187fd2e..7de99e970f7 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/barbarians/EntityChiefBarbarian.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/EntityChiefBarbarian.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.barbarians; +package com.minecolonies.core.entity.mobs.camp.barbarians; import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarian; import com.minecolonies.api.entity.mobs.barbarians.IChiefBarbarianEntity; @@ -7,7 +7,6 @@ import net.minecraft.world.level.Level; import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; -import static com.minecolonies.api.util.constant.RaiderConstants.BASE_ENV_DAMAGE_RESIST; import static com.minecolonies.api.util.constant.RaiderConstants.CHIEF_BONUS_ARMOR; /** @@ -15,7 +14,6 @@ */ public class EntityChiefBarbarian extends AbstractEntityBarbarian implements IChiefBarbarianEntity { - /** * Constructor of the entity. * @@ -34,7 +32,6 @@ public void initStatsFor(final double baseHealth, final double difficulty, final final double chiefArmor = difficulty * CHIEF_BONUS_ARMOR; this.getAttribute(Attributes.ARMOR).setBaseValue(chiefArmor); this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 1.0); - this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5); this.setHealth(this.getMaxHealth()); } diff --git a/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/package-info.java new file mode 100755 index 00000000000..9264c336133 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/barbarians/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes describing the Barbarian entities. + */ +package com.minecolonies.core.entity.mobs.raider.barbarians; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedArcherPirate.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedArcherPirate.java similarity index 95% rename from src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedArcherPirate.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedArcherPirate.java index 6fe2635d491..85d5b5728ee 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedArcherPirate.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedArcherPirate.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.drownedpirates; +package com.minecolonies.core.entity.mobs.camp.drownedpirates; import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; import com.minecolonies.api.entity.mobs.pirates.IArcherPirateEntity; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedCaptainPirate.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedCaptainPirate.java similarity index 91% rename from src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedCaptainPirate.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedCaptainPirate.java index c29152f4783..7c70a19e372 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedCaptainPirate.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedCaptainPirate.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.drownedpirates; +package com.minecolonies.core.entity.mobs.camp.drownedpirates; import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; +import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirateRaider; import com.minecolonies.api.entity.mobs.pirates.ICaptainPirateEntity; import com.minecolonies.api.util.MathUtils; import net.minecraft.network.chat.Component; @@ -33,7 +34,6 @@ public void initStatsFor(final double baseHealth, final double difficulty, final super.initStatsFor(baseHealth, difficulty, baseDamage); this.getAttribute(Attributes.ARMOR).setBaseValue(-1); this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage); - this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 2.0); this.setHealth(this.getMaxHealth()); if (MathUtils.RANDOM.nextInt(100) < 2) diff --git a/src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedPirate.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedPirate.java similarity index 95% rename from src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedPirate.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedPirate.java index 6e838ceb8cf..79b12566fc2 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/drownedpirates/EntityDrownedPirate.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/drownedpirates/EntityDrownedPirate.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.drownedpirates; +package com.minecolonies.core.entity.mobs.camp.drownedpirates; import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; import com.minecolonies.api.entity.mobs.pirates.IMeleePirateEntity; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityArcherMummy.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityArcherMummy.java similarity index 82% rename from src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityArcherMummy.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityArcherMummy.java index 8d6d544592a..94c4e8efd98 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityArcherMummy.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityArcherMummy.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.egyptians; +package com.minecolonies.core.entity.mobs.camp.egyptians; import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptianRaider; import com.minecolonies.api.entity.mobs.egyptians.IArcherMummyEntity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityMummy.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityMummy.java similarity index 92% rename from src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityMummy.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityMummy.java index 868f8247db8..496f43637ab 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityMummy.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityMummy.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.egyptians; +package com.minecolonies.core.entity.mobs.camp.egyptians; import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; import com.minecolonies.api.entity.mobs.egyptians.IMeleeMummyEntity; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityPharao.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityPharao.java similarity index 91% rename from src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityPharao.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityPharao.java index 3851e0625a2..159bcfcb5b2 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/egyptians/EntityPharao.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/EntityPharao.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.egyptians; +package com.minecolonies.core.entity.mobs.camp.egyptians; import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptian; +import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptianRaider; import com.minecolonies.api.entity.mobs.egyptians.IPharaoEntity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ai.attributes.Attributes; @@ -34,7 +35,6 @@ public void initStatsFor(final double baseHealth, final double difficulty, final final double chiefArmor = difficulty * CHIEF_BONUS_ARMOR; this.getAttribute(Attributes.ARMOR).setBaseValue(chiefArmor); this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 1.0); - this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 4.5); this.setHealth(this.getMaxHealth()); } diff --git a/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/package-info.java new file mode 100755 index 00000000000..ffaf42480a5 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/egyptians/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes describing the Egyptian raiders. + */ +package com.minecolonies.core.entity.mobs.raider.egyptians; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityNorsemenArcher.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityNorsemenArcher.java similarity index 83% rename from src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityNorsemenArcher.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityNorsemenArcher.java index 26ebb846450..f5ebeb0a2a3 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityNorsemenArcher.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityNorsemenArcher.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.norsemen; +package com.minecolonies.core.entity.mobs.camp.norsemen; import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemenRaider; import com.minecolonies.api.entity.mobs.vikings.IArcherNorsemenEntity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityNorsemenChief.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityNorsemenChief.java similarity index 91% rename from src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityNorsemenChief.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityNorsemenChief.java index e3582f264d6..4ea19f820af 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityNorsemenChief.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityNorsemenChief.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.norsemen; +package com.minecolonies.core.entity.mobs.camp.norsemen; import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemenRaider; import com.minecolonies.api.entity.mobs.vikings.INorsemenChiefEntity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ai.attributes.Attributes; @@ -33,7 +34,6 @@ public void initStatsFor(final double baseHealth, final double difficulty, final final double chiefArmor = difficulty * CHIEF_BONUS_ARMOR; this.getAttribute(Attributes.ARMOR).setBaseValue(chiefArmor); this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 1.0); - this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5); this.setHealth(this.getMaxHealth()); } diff --git a/src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityShieldmaiden.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityShieldmaiden.java similarity index 83% rename from src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityShieldmaiden.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityShieldmaiden.java index c7323837c0c..d8d78147793 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/norsemen/EntityShieldmaiden.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/EntityShieldmaiden.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.norsemen; +package com.minecolonies.core.entity.mobs.camp.norsemen; import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemen; +import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemenRaider; import com.minecolonies.api.entity.mobs.vikings.IMeleeNorsemenEntity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/package-info.java new file mode 100755 index 00000000000..fc141751a02 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/norsemen/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes describing the Norsemen entities. + */ +package com.minecolonies.core.entity.mobs.raider.norsemen; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityArcherPirate.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityArcherPirate.java similarity index 83% rename from src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityArcherPirate.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityArcherPirate.java index 475d5875e92..1090b95f97c 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityArcherPirate.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityArcherPirate.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.pirates; +package com.minecolonies.core.entity.mobs.camp.pirates; import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirate; +import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirateRaider; import com.minecolonies.api.entity.mobs.pirates.IArcherPirateEntity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityCaptainPirate.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityCaptainPirate.java similarity index 90% rename from src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityCaptainPirate.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityCaptainPirate.java index f925da07e04..2340833f5ff 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityCaptainPirate.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityCaptainPirate.java @@ -1,6 +1,7 @@ -package com.minecolonies.core.entity.mobs.pirates; +package com.minecolonies.core.entity.mobs.camp.pirates; import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirate; +import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirateRaider; import com.minecolonies.api.entity.mobs.pirates.ICaptainPirateEntity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ai.attributes.Attributes; @@ -32,7 +33,6 @@ public void initStatsFor(final double baseHealth, final double difficulty, final super.initStatsFor(baseHealth, difficulty, baseDamage); this.getAttribute(Attributes.ARMOR).setBaseValue(-1); this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 2.0); - this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.3); this.setHealth(this.getMaxHealth()); } diff --git a/src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityPirate.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityPirate.java similarity index 93% rename from src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityPirate.java rename to src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityPirate.java index c64ce9ca564..4b91b5628f8 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/pirates/EntityPirate.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/EntityPirate.java @@ -1,4 +1,4 @@ -package com.minecolonies.core.entity.mobs.pirates; +package com.minecolonies.core.entity.mobs.camp.pirates; import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirate; import com.minecolonies.api.entity.mobs.pirates.IMeleePirateEntity; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/package-info.java new file mode 100755 index 00000000000..930b9dc3c13 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/camp/pirates/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes describing the pirate entities. + */ +package com.minecolonies.core.entity.mobs.raider.pirates; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/egyptians/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/egyptians/package-info.java deleted file mode 100755 index f938c31a328..00000000000 --- a/src/main/java/com/minecolonies/core/entity/mobs/egyptians/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes describing the Egyptian raiders. - */ -package com.minecolonies.core.entity.mobs.egyptians; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/norsemen/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/norsemen/package-info.java deleted file mode 100755 index b4a1d83122e..00000000000 --- a/src/main/java/com/minecolonies/core/entity/mobs/norsemen/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes describing the Norsemen entities. - */ -package com.minecolonies.core.entity.mobs.norsemen; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/pirates/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/pirates/package-info.java deleted file mode 100755 index 74e15aee406..00000000000 --- a/src/main/java/com/minecolonies/core/entity/mobs/pirates/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes describing the pirate entities. - */ -package com.minecolonies.core.entity.mobs.pirates; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityAmazonChiefRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityAmazonChiefRaider.java new file mode 100755 index 00000000000..a97b052d73c --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityAmazonChiefRaider.java @@ -0,0 +1,41 @@ +package com.minecolonies.core.entity.mobs.raider.amazons; + +import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazonRaider; +import com.minecolonies.api.entity.mobs.amazons.IAmazonChief; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.level.Level; + +import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; +import static com.minecolonies.api.util.constant.RaiderConstants.BASE_ENV_DAMAGE_RESIST; +import static com.minecolonies.api.util.constant.RaiderConstants.CHIEF_BONUS_ARMOR; + +/** + * Class for the Amazon Chief entity. + */ +public class EntityAmazonChiefRaider extends AbstractEntityAmazonRaider implements IAmazonChief +{ + + /** + * Constructor of the entity. + * + * @param type the entity type. + * @param worldIn world to construct it in. + */ + public EntityAmazonChiefRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } + + @Override + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + super.initStatsFor(baseHealth, difficulty, baseDamage); + final double chiefArmor = difficulty * CHIEF_BONUS_ARMOR * 2; + this.getAttribute(Attributes.ARMOR).setBaseValue(chiefArmor); + this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 1.0); + this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5); + this.setHealth(this.getMaxHealth()); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityAmazonSpearmanRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityAmazonSpearmanRaider.java new file mode 100644 index 00000000000..2d9cbe56493 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityAmazonSpearmanRaider.java @@ -0,0 +1,23 @@ +package com.minecolonies.core.entity.mobs.raider.amazons; + +import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazonRaider; +import com.minecolonies.api.entity.mobs.amazons.IAmazonSpearman; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Amazon Spearman entity. + */ +public class EntityAmazonSpearmanRaider extends AbstractEntityAmazonRaider implements IAmazonSpearman +{ + /** + * Constructor of the entity. + * + * @param type the entity type + * @param world the world to construct it in + */ + public EntityAmazonSpearmanRaider(final EntityType type, final Level world) + { + super(type, world); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityArcherAmazonRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityArcherAmazonRaider.java new file mode 100755 index 00000000000..c111611178d --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/amazons/EntityArcherAmazonRaider.java @@ -0,0 +1,29 @@ +package com.minecolonies.core.entity.mobs.raider.amazons; + +import com.minecolonies.api.entity.mobs.amazons.AbstractEntityAmazonRaider; +import com.minecolonies.api.entity.mobs.amazons.IArcherAmazon; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Archer amazon entity. + */ +public class EntityArcherAmazonRaider extends AbstractEntityAmazonRaider implements IArcherAmazon +{ + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityArcherAmazonRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } + + @Override + public double getAttackDelayModifier() + { + return 2; + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityArcherBarbarianRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityArcherBarbarianRaider.java new file mode 100755 index 00000000000..7ada1ccc5f6 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityArcherBarbarianRaider.java @@ -0,0 +1,24 @@ +package com.minecolonies.core.entity.mobs.raider.barbarians; + +import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarianRaider; +import com.minecolonies.api.entity.mobs.barbarians.IArcherBarbarianEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Archer Barbarian entity. + */ +public class EntityArcherBarbarianRaider extends AbstractEntityBarbarianRaider implements IArcherBarbarianEntity +{ + + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityArcherBarbarianRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityBarbarianRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityBarbarianRaider.java new file mode 100755 index 00000000000..7ce9c596040 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityBarbarianRaider.java @@ -0,0 +1,24 @@ +package com.minecolonies.core.entity.mobs.raider.barbarians; + +import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarianRaider; +import com.minecolonies.api.entity.mobs.barbarians.IMeleeBarbarianEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Barbarian entity. + */ +public class EntityBarbarianRaider extends AbstractEntityBarbarianRaider implements IMeleeBarbarianEntity +{ + + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityBarbarianRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityChiefBarbarianRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityChiefBarbarianRaider.java new file mode 100755 index 00000000000..5778f606f27 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/EntityChiefBarbarianRaider.java @@ -0,0 +1,41 @@ +package com.minecolonies.core.entity.mobs.raider.barbarians; + +import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarianRaider; +import com.minecolonies.api.entity.mobs.barbarians.IChiefBarbarianEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.level.Level; + +import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; +import static com.minecolonies.api.util.constant.RaiderConstants.BASE_ENV_DAMAGE_RESIST; +import static com.minecolonies.api.util.constant.RaiderConstants.CHIEF_BONUS_ARMOR; + +/** + * Class for the Chief Barbarian entity. + */ +public class EntityChiefBarbarianRaider extends AbstractEntityBarbarianRaider implements IChiefBarbarianEntity +{ + + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityChiefBarbarianRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } + + @Override + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + super.initStatsFor(baseHealth, difficulty, baseDamage); + final double chiefArmor = difficulty * CHIEF_BONUS_ARMOR; + this.getAttribute(Attributes.ARMOR).setBaseValue(chiefArmor); + this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 1.0); + this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5); + this.setHealth(this.getMaxHealth()); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/package-info.java new file mode 100755 index 00000000000..9264c336133 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/barbarians/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes describing the Barbarian entities. + */ +package com.minecolonies.core.entity.mobs.raider.barbarians; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedArcherPirateRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedArcherPirateRaider.java new file mode 100755 index 00000000000..f192f5ac9dd --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedArcherPirateRaider.java @@ -0,0 +1,39 @@ +package com.minecolonies.core.entity.mobs.raider.drownedpirates; + +import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirateRaider; +import com.minecolonies.api.entity.mobs.pirates.IArcherPirateEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.level.Level; + +/** + * Class for the Archer drowned Pirate entity. + */ +public class EntityDrownedArcherPirateRaider extends AbstractDrownedEntityPirateRaider implements IArcherPirateEntity +{ + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityDrownedArcherPirateRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } + + @Override + public boolean penetrateFluids() + { + return true; + } + + @Override + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + super.initStatsFor(baseHealth, difficulty, baseDamage); + this.getAttribute(Attributes.ARMOR).setBaseValue(0.25); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5); + this.setHealth(this.getMaxHealth()); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedCaptainPirateRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedCaptainPirateRaider.java new file mode 100755 index 00000000000..d7dc17a4e28 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedCaptainPirateRaider.java @@ -0,0 +1,44 @@ +package com.minecolonies.core.entity.mobs.raider.drownedpirates; + +import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirateRaider; +import com.minecolonies.api.entity.mobs.pirates.ICaptainPirateEntity; +import com.minecolonies.api.util.MathUtils; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.level.Level; + +import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; +import static com.minecolonies.api.util.constant.RaiderConstants.BASE_ENV_DAMAGE_RESIST; + +/** + * Class for the Chief Pirate entity. + */ +public class EntityDrownedCaptainPirateRaider extends AbstractDrownedEntityPirateRaider implements ICaptainPirateEntity +{ + /** + * Constructor of the entity. + * + * @param type the entity type. + * @param worldIn world to construct it in. + */ + public EntityDrownedCaptainPirateRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } + + @Override + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + super.initStatsFor(baseHealth, difficulty, baseDamage); + this.getAttribute(Attributes.ARMOR).setBaseValue(-1); + this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage); + this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 2.0); + this.setHealth(this.getMaxHealth()); + if (MathUtils.RANDOM.nextInt(100) < 2) + { + setCustomName(Component.literal("Davy Jones")); + } + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedPirateRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedPirateRaider.java new file mode 100755 index 00000000000..20630d5b0f7 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/drownedpirates/EntityDrownedPirateRaider.java @@ -0,0 +1,36 @@ +package com.minecolonies.core.entity.mobs.raider.drownedpirates; + +import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirateRaider; +import com.minecolonies.api.entity.mobs.pirates.IMeleePirateEntity; +import com.minecolonies.core.entity.pathfinding.navigation.MovementHandler; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.level.Level; + +/** + * Class for the Pirate entity. + */ +public class EntityDrownedPirateRaider extends AbstractDrownedEntityPirateRaider implements IMeleePirateEntity +{ + + /** + * Constructor of the entity. + * + * @param type the entity type. + * @param worldIn world to construct it in. + */ + public EntityDrownedPirateRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + this.moveControl = new MovementHandler(this); + } + + @Override + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + super.initStatsFor(baseHealth, difficulty, baseDamage); + this.getAttribute(Attributes.ARMOR).setBaseValue(0.25); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5); + this.setHealth(this.getMaxHealth()); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityArcherMummyRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityArcherMummyRaider.java new file mode 100755 index 00000000000..f6b74072ac0 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityArcherMummyRaider.java @@ -0,0 +1,23 @@ +package com.minecolonies.core.entity.mobs.raider.egyptians; + +import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptianRaider; +import com.minecolonies.api.entity.mobs.egyptians.IArcherMummyEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Archer mummy entity. + */ +public class EntityArcherMummyRaider extends AbstractEntityEgyptianRaider implements IArcherMummyEntity +{ + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityArcherMummyRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityMummyRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityMummyRaider.java new file mode 100755 index 00000000000..15e3c4c7bbf --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityMummyRaider.java @@ -0,0 +1,26 @@ +package com.minecolonies.core.entity.mobs.raider.egyptians; + +import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptianRaider; +import com.minecolonies.api.entity.mobs.egyptians.IMeleeMummyEntity; +import com.minecolonies.core.entity.pathfinding.navigation.MovementHandler; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Mummy entity. + */ +public class EntityMummyRaider extends AbstractEntityEgyptianRaider implements IMeleeMummyEntity +{ + + /** + * Constructor of the entity. + * + * @param type the entity type. + * @param worldIn world to construct it in. + */ + public EntityMummyRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + this.moveControl = new MovementHandler(this); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityPharaoRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityPharaoRaider.java new file mode 100755 index 00000000000..e33f967326f --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/EntityPharaoRaider.java @@ -0,0 +1,41 @@ +package com.minecolonies.core.entity.mobs.raider.egyptians; + +import com.minecolonies.api.entity.mobs.egyptians.AbstractEntityEgyptianRaider; +import com.minecolonies.api.entity.mobs.egyptians.IPharaoEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.level.Level; + +import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; +import static com.minecolonies.api.util.constant.RaiderConstants.BASE_ENV_DAMAGE_RESIST; +import static com.minecolonies.api.util.constant.RaiderConstants.CHIEF_BONUS_ARMOR; + +/** + * Class for the Pharao entity. + */ +public class EntityPharaoRaider extends AbstractEntityEgyptianRaider implements IPharaoEntity +{ + + /** + * Constructor of the entity. + * + * @param type the entity type. + * @param worldIn world to construct it in. + */ + public EntityPharaoRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } + + @Override + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + super.initStatsFor(baseHealth, difficulty, baseDamage); + final double chiefArmor = difficulty * CHIEF_BONUS_ARMOR; + this.getAttribute(Attributes.ARMOR).setBaseValue(chiefArmor); + this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 1.0); + this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 4.5); + this.setHealth(this.getMaxHealth()); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/package-info.java new file mode 100755 index 00000000000..ffaf42480a5 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/egyptians/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes describing the Egyptian raiders. + */ +package com.minecolonies.core.entity.mobs.raider.egyptians; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityNorsemenArcherRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityNorsemenArcherRaider.java new file mode 100755 index 00000000000..eb93d2ec60a --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityNorsemenArcherRaider.java @@ -0,0 +1,24 @@ +package com.minecolonies.core.entity.mobs.raider.norsemen; + +import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemenRaider; +import com.minecolonies.api.entity.mobs.vikings.IArcherNorsemenEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Archer norsemen entity. + */ +public class EntityNorsemenArcherRaider extends AbstractEntityNorsemenRaider implements IArcherNorsemenEntity +{ + + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityNorsemenArcherRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityNorsemenChiefRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityNorsemenChiefRaider.java new file mode 100755 index 00000000000..ed894b1e719 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityNorsemenChiefRaider.java @@ -0,0 +1,40 @@ +package com.minecolonies.core.entity.mobs.raider.norsemen; + +import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemenRaider; +import com.minecolonies.api.entity.mobs.vikings.INorsemenChiefEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.level.Level; + +import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; +import static com.minecolonies.api.util.constant.RaiderConstants.BASE_ENV_DAMAGE_RESIST; +import static com.minecolonies.api.util.constant.RaiderConstants.CHIEF_BONUS_ARMOR; + +/** + * Class for the Chief norsemen entity. + */ +public class EntityNorsemenChiefRaider extends AbstractEntityNorsemenRaider implements INorsemenChiefEntity +{ + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityNorsemenChiefRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } + + @Override + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + super.initStatsFor(baseHealth, difficulty, baseDamage); + final double chiefArmor = difficulty * CHIEF_BONUS_ARMOR; + this.getAttribute(Attributes.ARMOR).setBaseValue(chiefArmor); + this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 1.0); + this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5); + this.setHealth(this.getMaxHealth()); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityShieldmaidenRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityShieldmaidenRaider.java new file mode 100755 index 00000000000..c23e4309cdf --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/EntityShieldmaidenRaider.java @@ -0,0 +1,24 @@ +package com.minecolonies.core.entity.mobs.raider.norsemen; + +import com.minecolonies.api.entity.mobs.vikings.AbstractEntityNorsemenRaider; +import com.minecolonies.api.entity.mobs.vikings.IMeleeNorsemenEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Norsemen Shieldmaiden entity. + */ +public class EntityShieldmaidenRaider extends AbstractEntityNorsemenRaider implements IMeleeNorsemenEntity +{ + + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityShieldmaidenRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/package-info.java new file mode 100755 index 00000000000..fc141751a02 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/norsemen/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes describing the Norsemen entities. + */ +package com.minecolonies.core.entity.mobs.raider.norsemen; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityArcherPirateRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityArcherPirateRaider.java new file mode 100755 index 00000000000..d66acdfd172 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityArcherPirateRaider.java @@ -0,0 +1,23 @@ +package com.minecolonies.core.entity.mobs.raider.pirates; + +import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirateRaider; +import com.minecolonies.api.entity.mobs.pirates.IArcherPirateEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Archer Pirate entity. + */ +public class EntityArcherPirateRaider extends AbstractEntityPirateRaider implements IArcherPirateEntity +{ + /** + * Constructor of the entity. + * + * @param worldIn world to construct it in. + * @param type the entity type. + */ + public EntityArcherPirateRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityCaptainPirateRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityCaptainPirateRaider.java new file mode 100755 index 00000000000..a8cbedc2098 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityCaptainPirateRaider.java @@ -0,0 +1,39 @@ +package com.minecolonies.core.entity.mobs.raider.pirates; + +import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirateRaider; +import com.minecolonies.api.entity.mobs.pirates.ICaptainPirateEntity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.level.Level; + +import static com.minecolonies.api.entity.mobs.RaiderMobUtils.MOB_ATTACK_DAMAGE; +import static com.minecolonies.api.util.constant.RaiderConstants.BASE_ENV_DAMAGE_RESIST; + +/** + * Class for the Chief Pirate entity. + */ +public class EntityCaptainPirateRaider extends AbstractEntityPirateRaider implements ICaptainPirateEntity +{ + + /** + * Constructor of the entity. + * + * @param type the entity type. + * @param worldIn world to construct it in. + */ + public EntityCaptainPirateRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + } + + @Override + public void initStatsFor(final double baseHealth, final double difficulty, final double baseDamage) + { + super.initStatsFor(baseHealth, difficulty, baseDamage); + this.getAttribute(Attributes.ARMOR).setBaseValue(-1); + this.getAttribute(MOB_ATTACK_DAMAGE.get()).setBaseValue(baseDamage + 2.0); + this.setEnvDamageInterval((int) (BASE_ENV_DAMAGE_RESIST * 2 * difficulty)); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth * 1.3); + this.setHealth(this.getMaxHealth()); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityPirateRaider.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityPirateRaider.java new file mode 100755 index 00000000000..ef7c4404aa8 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/EntityPirateRaider.java @@ -0,0 +1,26 @@ +package com.minecolonies.core.entity.mobs.raider.pirates; + +import com.minecolonies.api.entity.mobs.pirates.AbstractEntityPirateRaider; +import com.minecolonies.api.entity.mobs.pirates.IMeleePirateEntity; +import com.minecolonies.core.entity.pathfinding.navigation.MovementHandler; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; + +/** + * Class for the Pirate entity. + */ +public class EntityPirateRaider extends AbstractEntityPirateRaider implements IMeleePirateEntity +{ + + /** + * Constructor of the entity. + * + * @param type the entity type. + * @param worldIn world to construct it in. + */ + public EntityPirateRaider(final EntityType type, final Level worldIn) + { + super(type, worldIn); + this.moveControl = new MovementHandler(this); + } +} diff --git a/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/package-info.java b/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/package-info.java new file mode 100755 index 00000000000..930b9dc3c13 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/mobs/raider/pirates/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes describing the pirate entities. + */ +package com.minecolonies.core.entity.mobs.raider.pirates; \ No newline at end of file diff --git a/src/main/java/com/minecolonies/core/entity/mobs/registry/MobAIRegistry.java b/src/main/java/com/minecolonies/core/entity/mobs/registry/MobAIRegistry.java index 04208cdaaab..d448bbab35d 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/registry/MobAIRegistry.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/registry/MobAIRegistry.java @@ -3,17 +3,15 @@ import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.minecolonies.api.entity.ai.IStateAI; -import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; +import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirateRaider; import com.minecolonies.api.entity.mobs.registry.IMobAIRegistry; -import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob; +import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.api.entity.mobs.IArcherMobEntity; import com.minecolonies.api.entity.mobs.IRangedMobEntity; import com.minecolonies.core.entity.ai.minimal.EntityAIInteractToggleAble; import com.minecolonies.core.entity.citizen.EntityCitizen; -import com.minecolonies.core.entity.mobs.aitasks.EntityAIBreakDoor; -import com.minecolonies.core.entity.mobs.aitasks.RaiderMeleeAI; -import com.minecolonies.core.entity.mobs.aitasks.RaiderRangedAI; -import com.minecolonies.core.entity.mobs.aitasks.RaiderWalkAI; +import com.minecolonies.core.entity.mobs.aitasks.*; import com.minecolonies.core.util.MultimapCollector; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ai.goal.Goal; @@ -31,9 +29,9 @@ public class MobAIRegistry implements IMobAIRegistry { - private final List> mobAiTasks = Lists.newArrayList(); - private final List> mobAiTargetTasks = Lists.newArrayList(); - private final List> mobStateAITasks = Lists.newArrayList(); + private final List> mobAiTasks = Lists.newArrayList(); + private final List> mobAiTargetTasks = Lists.newArrayList(); + private final List> mobStateAITasks = Lists.newArrayList(); public MobAIRegistry() { @@ -48,19 +46,20 @@ public MobAIRegistry() private static void setupMobAiTasks(final IMobAIRegistry registry) { registry - .registerNewAiTaskForMobs(PRIORITY_ZERO, FloatGoal::new, mob -> !(mob instanceof AbstractDrownedEntityPirate)) + .registerNewAiTaskForMobs(PRIORITY_ZERO, FloatGoal::new, mob -> !(mob instanceof AbstractDrownedEntityPirateRaider)) .registerNewAiTargetTaskForMobs(PRIORITY_THREE, mob -> new EntityAIInteractToggleAble(mob, FENCE_TOGGLE)) .registerNewAiTargetTaskForMobs(PRIORITY_THREE, mob -> new EntityAIBreakDoor(mob)) .registerNewAiTaskForMobs(PRIORITY_FIVE, mob -> new LookAtPlayerGoal(mob, Player.class, MAX_WATCH_DISTANCE)) .registerNewAiTaskForMobs(PRIORITY_SIX, mob -> new LookAtPlayerGoal(mob, EntityCitizen.class, MAX_WATCH_DISTANCE)) .registerNewStateAI(mob -> new RaiderMeleeAI<>(mob, mob.getAI()), mob -> !(mob instanceof IArcherMobEntity)) .registerNewStateAI(mob -> new RaiderRangedAI(mob, mob.getAI()), mob -> mob instanceof IRangedMobEntity) - .registerNewStateAI(mob -> new RaiderWalkAI(mob, mob.getAI()), mob -> true); + .registerNewStateAI(mob -> new RaiderWalkAI((AbstractEntityMinecoloniesRaider) mob, mob.getAI()), mob -> mob instanceof AbstractEntityMinecoloniesRaider) + .registerNewStateAI(mob -> new CampWalkAI(mob, mob.getAI()), mob -> !(mob instanceof AbstractEntityMinecoloniesRaider)); } @NotNull @Override - public Multimap getEntityAiTasksForMobs(final AbstractEntityRaiderMob mob) + public Multimap getEntityAiTasksForMobs(final AbstractEntityMinecoloniesMonster mob) { return mobAiTasks.stream().filter(wrapper -> wrapper.entityPredicate.test(mob)).collect(MultimapCollector.toMultimap( TaskInformationWrapper::getPriority, @@ -72,7 +71,7 @@ public Multimap getEntityAiTasksForMobs(final AbstractEntityRaide @NotNull @Override public IMobAIRegistry registerNewAiTaskForMobs( - final int priority, final Function aiTaskProducer, final Predicate applyPredicate) + final int priority, final Function aiTaskProducer, final Predicate applyPredicate) { mobAiTasks.add(new TaskInformationWrapper<>(priority, aiTaskProducer, applyPredicate)); return this; @@ -81,7 +80,7 @@ public IMobAIRegistry registerNewAiTaskForMobs( @NotNull @Override public IMobAIRegistry registerNewStateAI( - final Function aiTaskProducer, final Predicate applyPredicate) + final Function aiTaskProducer, final Predicate applyPredicate) { mobStateAITasks.add(new TaskInformationWrapper<>(0, aiTaskProducer, applyPredicate)); return this; @@ -89,9 +88,9 @@ public IMobAIRegistry registerNewStateAI( @NotNull @Override - public void applyToMob(final AbstractEntityRaiderMob mob) + public void applyToMob(final AbstractEntityMinecoloniesMonster mob) { - for (final TaskInformationWrapper task : mobStateAITasks) + for (final TaskInformationWrapper task : mobStateAITasks) { if (task.entityPredicate.test(mob)) { @@ -99,7 +98,7 @@ public void applyToMob(final AbstractEntityRaiderMob mob) } } - for (final TaskInformationWrapper task : mobAiTargetTasks) + for (final TaskInformationWrapper task : mobAiTargetTasks) { if (task.entityPredicate.test(mob)) { @@ -107,7 +106,7 @@ public void applyToMob(final AbstractEntityRaiderMob mob) } } - for (final TaskInformationWrapper task : mobAiTasks) + for (final TaskInformationWrapper task : mobAiTasks) { if (task.entityPredicate.test(mob)) { @@ -118,7 +117,7 @@ public void applyToMob(final AbstractEntityRaiderMob mob) @NotNull @Override - public Multimap getEntityAiTargetTasksForMobs(final AbstractEntityRaiderMob mob) + public Multimap getEntityAiTargetTasksForMobs(final AbstractEntityMinecoloniesMonster mob) { return mobAiTargetTasks.stream().filter(wrapper -> wrapper.getEntityPredicate().test(mob)).collect(MultimapCollector.toMultimap( TaskInformationWrapper::getPriority, @@ -130,7 +129,7 @@ public Multimap getEntityAiTargetTasksForMobs(final AbstractEntit @NotNull @Override public IMobAIRegistry registerNewAiTargetTaskForMobs( - final int priority, final Function aiTaskProducer, final Predicate applyPredicate) + final int priority, final Function aiTaskProducer, final Predicate applyPredicate) { mobAiTargetTasks.add(new TaskInformationWrapper<>(priority, aiTaskProducer, applyPredicate)); return this; @@ -143,13 +142,13 @@ public IMobAIRegistry registerNewAiTargetTaskForMobs( */ private static final class TaskInformationWrapper { - private final int priority; - private final Function aiTaskProducer; - private final Predicate entityPredicate; + private final int priority; + private final Function aiTaskProducer; + private final Predicate entityPredicate; TaskInformationWrapper( final int priority, - final Function aiTaskProducer, final Predicate entityPredicate) + final Function aiTaskProducer, final Predicate entityPredicate) { this.priority = priority; this.aiTaskProducer = aiTaskProducer; @@ -161,7 +160,7 @@ public int getPriority() return priority; } - public Function getAiTaskProducer() + public Function getAiTaskProducer() { return aiTaskProducer; } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/PathfindingUtils.java b/src/main/java/com/minecolonies/core/entity/pathfinding/PathfindingUtils.java index 6cb69926fc3..c58ce47c8c4 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/PathfindingUtils.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/PathfindingUtils.java @@ -3,7 +3,7 @@ import com.ldtteam.domumornamentum.block.decorative.PanelBlock; import com.ldtteam.domumornamentum.block.vanilla.TrapdoorBlock; import com.minecolonies.api.blocks.huts.AbstractBlockMinecoloniesDefault; -import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirate; +import com.minecolonies.api.entity.mobs.drownedpirate.AbstractDrownedEntityPirateRaider; import com.minecolonies.api.items.ModTags; import com.minecolonies.api.util.ShapeUtil; import com.minecolonies.core.Network; @@ -122,7 +122,7 @@ public static BlockPos prepareStart(@NotNull final LivingEntity entity) final Block b = bs.getBlock(); - if (entity.isInWater() && !(entity instanceof AbstractDrownedEntityPirate)) + if (entity.isInWater() && !(entity instanceof AbstractDrownedEntityPirateRaider)) { while (!bs.getFluidState().isEmpty()) { diff --git a/src/main/java/com/minecolonies/core/event/ClientRegistryHandler.java b/src/main/java/com/minecolonies/core/event/ClientRegistryHandler.java index d1be1713109..7db0862f148 100644 --- a/src/main/java/com/minecolonies/core/event/ClientRegistryHandler.java +++ b/src/main/java/com/minecolonies/core/event/ClientRegistryHandler.java @@ -280,6 +280,8 @@ public static void doClientStuff(final EntityRenderersEvent.RegisterRenderers ev event.registerEntityRenderer(ModEntities.MC_NORMAL_ARROW, TippableArrowRenderer::new); event.registerEntityRenderer(ModEntities.DRUID_POTION, m -> new ThrownItemRenderer<>(m, 1.0F, true)); + // Raiders + event.registerEntityRenderer(ModEntities.BARBARIAN, RendererBarbarian::new); event.registerEntityRenderer(ModEntities.ARCHERBARBARIAN, RendererBarbarian::new); event.registerEntityRenderer(ModEntities.CHIEFBARBARIAN, RendererChiefBarbarian::new); @@ -304,6 +306,34 @@ public static void doClientStuff(final EntityRenderersEvent.RegisterRenderers ev event.registerEntityRenderer(ModEntities.DROWNED_ARCHERPIRATE, RendererDrownedArcherPirate::new); event.registerEntityRenderer(ModEntities.DROWNED_CHIEFPIRATE, RendererDrownedChiefPirate::new); + // Camp Raiders + + event.registerEntityRenderer(ModEntities.CAMP_BARBARIAN, RendererBarbarian::new); + event.registerEntityRenderer(ModEntities.CAMP_ARCHERBARBARIAN, RendererBarbarian::new); + event.registerEntityRenderer(ModEntities.CAMP_CHIEFBARBARIAN, RendererChiefBarbarian::new); + + event.registerEntityRenderer(ModEntities.CAMP_PIRATE, RendererPirate::new); + event.registerEntityRenderer(ModEntities.CAMP_ARCHERPIRATE, RendererArcherPirate::new); + event.registerEntityRenderer(ModEntities.CAMP_CHIEFPIRATE, RendererChiefPirate::new); + + event.registerEntityRenderer(ModEntities.CAMP_MUMMY, RendererMummy::new); + event.registerEntityRenderer(ModEntities.CAMP_ARCHERMUMMY, RendererArcherMummy::new); + event.registerEntityRenderer(ModEntities.CAMP_PHARAO, RendererPharao::new); + + event.registerEntityRenderer(ModEntities.CAMP_SHIELDMAIDEN, RendererShieldmaidenNorsemen::new); + event.registerEntityRenderer(ModEntities.CAMP_NORSEMEN_ARCHER, RendererArcherNorsemen::new); + event.registerEntityRenderer(ModEntities.CAMP_NORSEMEN_CHIEF, RendererChiefNorsemen::new); + + event.registerEntityRenderer(ModEntities.CAMP_AMAZON, RendererAmazon::new); + event.registerEntityRenderer(ModEntities.CAMP_AMAZONCHIEF, RendererChiefAmazon::new); + event.registerEntityRenderer(ModEntities.CAMP_AMAZONSPEARMAN, RendererAmazonSpearman::new); + + event.registerEntityRenderer(ModEntities.CAMP_DROWNED_PIRATE, RendererDrownedPirate::new); + event.registerEntityRenderer(ModEntities.CAMP_DROWNED_ARCHERPIRATE, RendererDrownedArcherPirate::new); + event.registerEntityRenderer(ModEntities.CAMP_DROWNED_CHIEFPIRATE, RendererDrownedChiefPirate::new); + + // Misc + event.registerEntityRenderer(ModEntities.MERCENARY, RenderMercenary::new); event.registerEntityRenderer(ModEntities.SITTINGENTITY, RenderSitting::new); event.registerEntityRenderer(ModEntities.MINECART, (context) -> new MinecartRenderer<>(context, ModelLayers.MINECART)); diff --git a/src/main/java/com/minecolonies/core/generation/defaults/DefaultDamageTypeProvider.java b/src/main/java/com/minecolonies/core/generation/defaults/DefaultDamageTypeProvider.java index 830d828b5ca..d91c4d3caab 100644 --- a/src/main/java/com/minecolonies/core/generation/defaults/DefaultDamageTypeProvider.java +++ b/src/main/java/com/minecolonies/core/generation/defaults/DefaultDamageTypeProvider.java @@ -60,7 +60,27 @@ private static Map getDamageTypes() Map.entry(DamageSourceKeys.VISITOR.location(), entityDamage(ModEntities.VISITOR)), Map.entry(DamageSourceKeys.DROWNED_PIRATE.location(), entityDamage(ModEntities.DROWNED_PIRATE)), Map.entry(DamageSourceKeys.DROWNED_ARCHERPIRATE.location(), entityDamage(ModEntities.DROWNED_ARCHERPIRATE)), - Map.entry(DamageSourceKeys.DROWNED_CHIEFPIRATE.location(), entityDamage(ModEntities.DROWNED_CHIEFPIRATE)) + Map.entry(DamageSourceKeys.DROWNED_CHIEFPIRATE.location(), entityDamage(ModEntities.DROWNED_CHIEFPIRATE)), + + Map.entry(DamageSourceKeys.CAMP_AMAZON.location(), entityDamage(ModEntities.CAMP_AMAZON)), + Map.entry(DamageSourceKeys.CAMP_AMAZONCHIEF.location(), entityDamage(ModEntities.CAMP_AMAZONCHIEF)), + Map.entry(DamageSourceKeys.CAMP_AMAZONSPEARMAN.location(), entityDamage(ModEntities.CAMP_AMAZONSPEARMAN)), + + Map.entry(DamageSourceKeys.CAMP_BARBARIAN.location(), entityDamage(ModEntities.CAMP_BARBARIAN)), + Map.entry(DamageSourceKeys.CAMP_CHIEFBARBARIAN.location(), entityDamage(ModEntities.CAMP_CHIEFBARBARIAN)), + Map.entry(DamageSourceKeys.CAMP_ARCHERBARBARIAN.location(), entityDamage(ModEntities.CAMP_ARCHERBARBARIAN)), + + Map.entry(DamageSourceKeys.CAMP_MUMMY.location(), entityDamage(ModEntities.CAMP_MUMMY)), + Map.entry(DamageSourceKeys.CAMP_ARCHERMUMMY.location(), entityDamage(ModEntities.CAMP_ARCHERMUMMY)), + Map.entry(DamageSourceKeys.CAMP_PHARAO.location(), entityDamage(ModEntities.CAMP_PHARAO)), + + Map.entry(DamageSourceKeys.CAMP_PIRATE.location(), entityDamage(ModEntities.CAMP_PIRATE)), + Map.entry(DamageSourceKeys.CAMP_ARCHERPIRATE.location(), entityDamage(ModEntities.CAMP_ARCHERPIRATE)), + Map.entry(DamageSourceKeys.CAMP_CHIEFPIRATE.location(), entityDamage(ModEntities.CAMP_CHIEFPIRATE)), + + Map.entry(DamageSourceKeys.CAMP_NORSEMENARCHER.location(), entityDamage(ModEntities.CAMP_NORSEMEN_ARCHER)), + Map.entry(DamageSourceKeys.CAMP_NORSEMENCHIEF.location(), entityDamage(ModEntities.CAMP_NORSEMEN_CHIEF)), + Map.entry(DamageSourceKeys.CAMP_SHIELDMAIDEN.location(), entityDamage(ModEntities.CAMP_SHIELDMAIDEN)) ); } diff --git a/src/main/java/com/minecolonies/core/items/ItemChiefSword.java b/src/main/java/com/minecolonies/core/items/ItemChiefSword.java index 30c84451e6c..0d4a9ad0dfa 100755 --- a/src/main/java/com/minecolonies/core/items/ItemChiefSword.java +++ b/src/main/java/com/minecolonies/core/items/ItemChiefSword.java @@ -1,7 +1,7 @@ package com.minecolonies.core.items; import com.minecolonies.api.entity.mobs.RaiderMobUtils; -import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarian; +import com.minecolonies.api.entity.mobs.barbarians.AbstractEntityBarbarianRaider; import com.minecolonies.api.items.IChiefSwordItem; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; @@ -46,7 +46,7 @@ public void inventoryTick(final ItemStack stack, final Level worldIn, final Enti @Override public boolean hurtEnemy(final ItemStack stack, final LivingEntity target, @NotNull final LivingEntity attacker) { - if (attacker instanceof Player && target instanceof AbstractEntityBarbarian) + if (attacker instanceof Player && target instanceof AbstractEntityBarbarianRaider) { target.addEffect(new MobEffectInstance(LEVITATION_EFFECT, LEVITATION_EFFECT_DURATION, LEVITATION_EFFECT_MULTIPLIER)); } diff --git a/src/main/resources/assets/minecolonies/lang/manual_en_us.json b/src/main/resources/assets/minecolonies/lang/manual_en_us.json index 20f4fc361d8..c9b1624ac4b 100644 --- a/src/main/resources/assets/minecolonies/lang/manual_en_us.json +++ b/src/main/resources/assets/minecolonies/lang/manual_en_us.json @@ -1119,6 +1119,9 @@ "item.minecolonies.pirateegg": "Pirate Spawn Egg", "item.minecolonies.piratearcheregg": "Archer Pirate Spawn Egg", "item.minecolonies.piratecaptainegg": "Pirate Captain Spawn Egg", + "item.minecolonies.drownedpirateegg": "Drowned Pirate Spawn Egg", + "item.minecolonies.drownedpiratearcheregg": "Drowned Archer Pirate Spawn Egg", + "item.minecolonies.drownedpiratecaptainegg": "Drowned Pirate Captain Spawn Egg", "item.minecolonies.mercegg": "Mercenary Spawn Egg", "com.minecolonies.coremod.cook.serve.player": "%s: Here Governor, take this food!", @@ -1872,6 +1875,11 @@ "item.minecolonies.amazonegg": "Amazon Spawn Egg", "item.minecolonies.amazonspearmanegg": "Amazon Spearman Spawn Egg", "item.minecolonies.amazonchiefegg": "Amazon Leader Spawn Egg", + + "item.minecolonies.mummyegg": "Mummy Spawn Egg", + "item.minecolonies.mummyarcheregg": "Archer Mummy Spawn Egg", + "item.minecolonies.pharaoegg": "Pharao Spawn Egg", + "com.minecolonies.coremod.playerinvfull": "You can't pick up this item, as your inventory is full!", "com.minecolonies.coremod.playerinvfull.hotbarinsert": " was dropped in front of you, as your inventory is full!", diff --git a/src/main/resources/assets/minecolonies/models/item/drownedpiratearcheregg.json b/src/main/resources/assets/minecolonies/models/item/drownedpiratearcheregg.json new file mode 100755 index 00000000000..fb8b11e6670 --- /dev/null +++ b/src/main/resources/assets/minecolonies/models/item/drownedpiratearcheregg.json @@ -0,0 +1,3 @@ +{ + "parent": "item/template_spawn_egg" +} diff --git a/src/main/resources/assets/minecolonies/models/item/drownedpiratecaptainegg.json b/src/main/resources/assets/minecolonies/models/item/drownedpiratecaptainegg.json new file mode 100755 index 00000000000..fb8b11e6670 --- /dev/null +++ b/src/main/resources/assets/minecolonies/models/item/drownedpiratecaptainegg.json @@ -0,0 +1,3 @@ +{ + "parent": "item/template_spawn_egg" +} diff --git a/src/main/resources/assets/minecolonies/models/item/drownedpirateegg.json b/src/main/resources/assets/minecolonies/models/item/drownedpirateegg.json new file mode 100755 index 00000000000..fb8b11e6670 --- /dev/null +++ b/src/main/resources/assets/minecolonies/models/item/drownedpirateegg.json @@ -0,0 +1,3 @@ +{ + "parent": "item/template_spawn_egg" +} From 748a3f560623df2a34f3f8b19672282088567202 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Wed, 18 Dec 2024 10:49:12 +0100 Subject: [PATCH 26/33] hotfix derp --- src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java b/src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java index 6f52bf95772..2b6c5b50811 100755 --- a/src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java +++ b/src/main/java/com/minecolonies/api/sounds/ModSoundEvents.java @@ -93,6 +93,7 @@ private ModSoundEvents() individualSounds.add(new Tuple<>(maleSoundEvent, femaleSoundEvent)); individualSounds.add(new Tuple<>(maleSoundEvent, femaleSoundEvent)); } + map.put(event, individualSounds); } CITIZEN_SOUND_EVENTS.put("child", map); From 60a8933952c8233d54a6ab93da044ef1b4e0cf29 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Thu, 19 Dec 2024 22:51:31 +0100 Subject: [PATCH 27/33] fix christmas! (#10538) fix christmas and halloween event code --- .../client/render/modeltype/CitizenModel.java | 2 +- .../render/modeltype/ISimpleModelType.java | 35 ++++++++++++++++-- .../render/modeltype/SimpleModelType.java | 5 +++ .../api/colony/ICitizenDataView.java | 9 +++++ .../core/client/render/CitizenArmorLayer.java | 12 +------ .../core/colony/CitizenDataView.java | 36 +++++++++++++++++++ .../com/minecolonies/core/colony/Colony.java | 10 ------ .../core/entity/citizen/EntityCitizen.java | 13 ------- 8 files changed, 85 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/minecolonies/api/client/render/modeltype/CitizenModel.java b/src/main/java/com/minecolonies/api/client/render/modeltype/CitizenModel.java index 95f61bd2f55..676c1fa98d9 100755 --- a/src/main/java/com/minecolonies/api/client/render/modeltype/CitizenModel.java +++ b/src/main/java/com/minecolonies/api/client/render/modeltype/CitizenModel.java @@ -89,6 +89,6 @@ public boolean displayHat(final AbstractEntityCitizen citizen) { return false; } - return citizen.getCitizenDataView() == null || (citizen.getCitizenDataView().getInventory().getArmorInSlot(EquipmentSlot.HEAD).isEmpty() && citizen.getCitizenDataView().getCustomTextureUUID() == null); + return citizen.getCitizenDataView() == null || (citizen.getCitizenDataView().getDisplayArmor(EquipmentSlot.HEAD).isEmpty() && citizen.getCitizenDataView().getCustomTextureUUID() == null); } } diff --git a/src/main/java/com/minecolonies/api/client/render/modeltype/ISimpleModelType.java b/src/main/java/com/minecolonies/api/client/render/modeltype/ISimpleModelType.java index e5db1fc4846..d0173c4af37 100755 --- a/src/main/java/com/minecolonies/api/client/render/modeltype/ISimpleModelType.java +++ b/src/main/java/com/minecolonies/api/client/render/modeltype/ISimpleModelType.java @@ -2,10 +2,15 @@ import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.util.constant.Constants; +import com.minecolonies.core.MineColonies; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; +import java.time.LocalDateTime; +import java.time.Month; + +import static com.minecolonies.api.client.render.modeltype.SimpleModelType.cachedHalloweenStyle; import static com.minecolonies.api.entity.citizen.AbstractEntityCitizen.DATA_STYLE; import static com.minecolonies.api.entity.citizen.AbstractEntityCitizen.DATA_TEXTURE_SUFFIX; @@ -44,10 +49,30 @@ public interface ISimpleModelType extends IModelType */ default ResourceLocation getTexture(@NotNull final AbstractEntityCitizen entityCitizen) { + if (cachedHalloweenStyle == null) + { + if (MineColonies.getConfig().getServer().holidayFeatures.get() && + ((LocalDateTime.now().getDayOfMonth() >= 29 && LocalDateTime.now().getMonth() == Month.OCTOBER) + || (LocalDateTime.now().getDayOfMonth() <= 2 && LocalDateTime.now().getMonth() == Month.NOVEMBER))) + { + cachedHalloweenStyle = "nether"; + } + else + { + cachedHalloweenStyle = ""; + } + } + + String style = entityCitizen.getEntityData().get(DATA_STYLE); + if (!cachedHalloweenStyle.isEmpty()) + { + style = cachedHalloweenStyle; + } + final int moddedTextureId = (entityCitizen.getTextureId() % getNumTextures()) + 1; final String textureIdentifier = getName().getPath() + (entityCitizen.isFemale() ? "female" : "male") + moddedTextureId + entityCitizen.getEntityData().get(DATA_TEXTURE_SUFFIX); - final ResourceLocation modified = new ResourceLocation(Constants.MOD_ID, BASE_FOLDER + entityCitizen.getEntityData().get(DATA_STYLE) + "/" + textureIdentifier + ".png"); + final ResourceLocation modified = new ResourceLocation(Constants.MOD_ID, BASE_FOLDER + style + "/" + textureIdentifier + ".png"); if (Minecraft.getInstance().getResourceManager().getResource(modified).isPresent()) { return modified; @@ -58,10 +83,16 @@ default ResourceLocation getTexture(@NotNull final AbstractEntityCitizen entityC default ResourceLocation getTextureIcon(@NotNull final AbstractEntityCitizen entityCitizen) { + String style = entityCitizen.getEntityData().get(DATA_STYLE); + if (cachedHalloweenStyle != null && !cachedHalloweenStyle.isEmpty()) + { + style = cachedHalloweenStyle; + } + final int moddedTextureId = (entityCitizen.getTextureId() % getNumTextures()) + 1; final String textureIdentifier = getTextureBase() + (entityCitizen.isFemale() ? "female" : "male") + moddedTextureId + entityCitizen.getEntityData() .get(DATA_TEXTURE_SUFFIX); - return new ResourceLocation(Constants.MOD_ID, "textures/entity_icon/citizen/" + entityCitizen.getEntityData().get(DATA_STYLE) + "/" + textureIdentifier + ".png"); + return new ResourceLocation(Constants.MOD_ID, "textures/entity_icon/citizen/" + style + "/" + textureIdentifier + ".png"); } } diff --git a/src/main/java/com/minecolonies/api/client/render/modeltype/SimpleModelType.java b/src/main/java/com/minecolonies/api/client/render/modeltype/SimpleModelType.java index 2681a37d6c5..63168bfbdf8 100644 --- a/src/main/java/com/minecolonies/api/client/render/modeltype/SimpleModelType.java +++ b/src/main/java/com/minecolonies/api/client/render/modeltype/SimpleModelType.java @@ -8,6 +8,11 @@ */ public class SimpleModelType implements ISimpleModelType { + /** + * Halloween style string. Null = uninitialized. + */ + static String cachedHalloweenStyle = null; + /** * String describing the citizen. Used by the renderer. Starts with a capital, and does not contain spaces or other special characters. */ diff --git a/src/main/java/com/minecolonies/api/colony/ICitizenDataView.java b/src/main/java/com/minecolonies/api/colony/ICitizenDataView.java index 269d80c9734..20b6e40f3b1 100755 --- a/src/main/java/com/minecolonies/api/colony/ICitizenDataView.java +++ b/src/main/java/com/minecolonies/api/colony/ICitizenDataView.java @@ -11,6 +11,8 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -227,4 +229,11 @@ public interface ICitizenDataView extends ICitizen * @return the uuid. */ UUID getCustomTextureUUID(); + + /** + * Get Armor in slot of citizen data view. + * @param equipmentSlot the equipment slot to get it from. + * @return the armor in the slot. + */ + ItemStack getDisplayArmor(EquipmentSlot equipmentSlot); } diff --git a/src/main/java/com/minecolonies/core/client/render/CitizenArmorLayer.java b/src/main/java/com/minecolonies/core/client/render/CitizenArmorLayer.java index 821ab946225..8a70c23b12f 100644 --- a/src/main/java/com/minecolonies/core/client/render/CitizenArmorLayer.java +++ b/src/main/java/com/minecolonies/core/client/render/CitizenArmorLayer.java @@ -3,7 +3,6 @@ import com.minecolonies.api.colony.ICitizenDataView; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.mojang.authlib.GameProfile; -import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Axis; @@ -20,20 +19,12 @@ import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.DefaultPlayerSkin; import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.WalkAnimationState; import net.minecraft.world.item.*; import net.minecraft.world.item.armortrim.ArmorTrim; -import net.minecraft.world.level.block.AbstractSkullBlock; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SkullBlock; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -42,7 +33,6 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; @OnlyIn(Dist.CLIENT) public class CitizenArmorLayer, A extends HumanoidModel> extends HumanoidArmorLayer @@ -130,7 +120,7 @@ public void render( private void renderArmorPiece(PoseStack poseStack, MultiBufferSource bufferSource, T citizen, EquipmentSlot equipmentSlot, int light, A armor, final ICitizenDataView citizenDataView) { - ItemStack itemstack = citizenDataView.getInventory().getArmorInSlot(equipmentSlot); + ItemStack itemstack = citizenDataView.getDisplayArmor(equipmentSlot); if (itemstack.isEmpty()) { itemstack = citizen.getItemBySlot(equipmentSlot); diff --git a/src/main/java/com/minecolonies/core/colony/CitizenDataView.java b/src/main/java/com/minecolonies/core/colony/CitizenDataView.java index c064ac18d32..d79e3efd36f 100644 --- a/src/main/java/com/minecolonies/core/colony/CitizenDataView.java +++ b/src/main/java/com/minecolonies/core/colony/CitizenDataView.java @@ -13,9 +13,11 @@ import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenHappinessHandler; import com.minecolonies.api.entity.citizen.citizenhandlers.ICitizenSkillHandler; import com.minecolonies.api.inventory.InventoryCitizen; +import com.minecolonies.api.items.ModItems; import com.minecolonies.api.util.Tuple; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.api.util.constant.Suppression; +import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.interactionhandling.ServerCitizenInteraction; import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenHappinessHandler; import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenSkillHandler; @@ -28,10 +30,15 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.time.Clock; +import java.time.LocalDate; +import java.time.Month; import java.util.*; import static com.minecolonies.api.util.constant.NbtTagConstants.TAG_OFFHAND_HELD_ITEM_SLOT; @@ -43,6 +50,11 @@ */ public class CitizenDataView implements ICitizenDataView { + /** + * Santa Hat. + */ + private static ItemStack cachedDisplaySantaHat = null; + private static final String TAG_HELD_ITEM_SLOT = "HeldItemSlot"; /** @@ -614,4 +626,28 @@ public boolean equals(final Object o) return id == data.getId(); } + + @Override + public ItemStack getDisplayArmor(final EquipmentSlot equipmentSlot) + { + if (cachedDisplaySantaHat == null) + { + if (MineColonies.getConfig().getServer().holidayFeatures.get() && LocalDate.now(Clock.systemDefaultZone()).getMonth() == Month.DECEMBER) + { + cachedDisplaySantaHat = new ItemStack(ModItems.santaHat); + } + else + { + cachedDisplaySantaHat = ItemStack.EMPTY; + } + } + + final ItemStack currentHat = getInventory().getArmorInSlot(equipmentSlot); + if (currentHat.isEmpty() && cachedDisplaySantaHat != null && cachedDisplaySantaHat != ItemStack.EMPTY && equipmentSlot == EquipmentSlot.HEAD) + { + return cachedDisplaySantaHat; + } + + return currentHat; + } } diff --git a/src/main/java/com/minecolonies/core/colony/Colony.java b/src/main/java/com/minecolonies/core/colony/Colony.java index 1400e409339..646e7dae166 100644 --- a/src/main/java/com/minecolonies/core/colony/Colony.java +++ b/src/main/java/com/minecolonies/core/colony/Colony.java @@ -25,7 +25,6 @@ import com.minecolonies.api.util.constant.Constants; import com.minecolonies.api.util.constant.NbtTagConstants; import com.minecolonies.api.util.constant.Suppression; -import com.minecolonies.core.MineColonies; import com.minecolonies.core.Network; import com.minecolonies.core.colony.buildings.modules.BuildingModules; import com.minecolonies.core.colony.buildings.modules.SettingsModule; @@ -65,8 +64,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.time.LocalDateTime; -import java.time.Month; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -1867,13 +1864,6 @@ public void setTextureStyle(final String style) @Override public String getTextureStyleId() { - if (MineColonies.getConfig().getServer().holidayFeatures.get() && - ((LocalDateTime.now().getDayOfMonth() >= 29 && LocalDateTime.now().getMonth() == Month.OCTOBER) - || (LocalDateTime.now().getDayOfMonth() <= 2 && LocalDateTime.now().getMonth() == Month.NOVEMBER))) - { - return "nether"; - } - return this.textureStyle; } diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index be1a8ff21d5..c1897d4e546 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -783,19 +783,6 @@ public int getMaxAirSupply() */ private boolean updateVisualData() { - final ItemStack hat = getItemBySlot(EquipmentSlot.HEAD); - if (LocalDate.now(Clock.systemDefaultZone()).getMonth() == Month.DECEMBER - && MineColonies.getConfig().getServer().holidayFeatures.get()) - { - if (hat.isEmpty()) - { - this.setItemSlot(EquipmentSlot.HEAD, new ItemStack(ModItems.santaHat)); - } - } - else if (!hat.isEmpty() && hat.getItem() == ModItems.santaHat) - { - this.setItemSlot(EquipmentSlot.HEAD, ItemStackUtils.EMPTY); - } this.setCustomNameVisible(MineColonies.getConfig().getServer().alwaysRenderNameTag.get()); if (!citizenColonyHandler.getColonyOrRegister().getTextureStyleId().equals(getEntityData().get(DATA_STYLE))) From f8aac520a754343d18dcfd92c226744c65d3c649 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Sun, 22 Dec 2024 13:48:30 +0100 Subject: [PATCH 28/33] Several adjustments (#10539) Add names for new entities Allow new entities to open doors Move holiday effects to client config --- .../render/modeltype/ISimpleModelType.java | 2 +- .../configuration/ClientConfiguration.java | 2 + .../configuration/ServerConfiguration.java | 2 - .../AbstractEntityMinecoloniesMonster.java | 10 +-- .../AbstractEntityMinecoloniesRaider.java | 33 ++++++++ .../core/colony/CitizenDataView.java | 2 +- .../minecolonies/core/event/EventHandler.java | 2 +- .../minecolonies/lang/manual_en_us.json | 75 ++++++++++++++++++- 8 files changed, 113 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/minecolonies/api/client/render/modeltype/ISimpleModelType.java b/src/main/java/com/minecolonies/api/client/render/modeltype/ISimpleModelType.java index d0173c4af37..5be7d9be2c5 100755 --- a/src/main/java/com/minecolonies/api/client/render/modeltype/ISimpleModelType.java +++ b/src/main/java/com/minecolonies/api/client/render/modeltype/ISimpleModelType.java @@ -51,7 +51,7 @@ default ResourceLocation getTexture(@NotNull final AbstractEntityCitizen entityC { if (cachedHalloweenStyle == null) { - if (MineColonies.getConfig().getServer().holidayFeatures.get() && + if (MineColonies.getConfig().getClient().holidayFeatures.get() && ((LocalDateTime.now().getDayOfMonth() >= 29 && LocalDateTime.now().getMonth() == Month.OCTOBER) || (LocalDateTime.now().getDayOfMonth() <= 2 && LocalDateTime.now().getMonth() == Month.NOVEMBER))) { diff --git a/src/main/java/com/minecolonies/api/configuration/ClientConfiguration.java b/src/main/java/com/minecolonies/api/configuration/ClientConfiguration.java index fb74e377d05..2442b502161 100755 --- a/src/main/java/com/minecolonies/api/configuration/ClientConfiguration.java +++ b/src/main/java/com/minecolonies/api/configuration/ClientConfiguration.java @@ -12,6 +12,7 @@ public class ClientConfiguration extends AbstractConfiguration public final ForgeConfigSpec.IntValue neighborbuildingrange; public final ForgeConfigSpec.IntValue buildgogglerange; public final ForgeConfigSpec.BooleanValue colonyteamborders; + public final ForgeConfigSpec.BooleanValue holidayFeatures; /** * Builds client configuration. @@ -26,6 +27,7 @@ protected ClientConfiguration(final ForgeConfigSpec.Builder builder) neighborbuildingrange = defineInteger(builder, "neighborbuildingrange", 4, -2, 16); buildgogglerange = defineInteger(builder, "buildgogglerange", 50, 1, 250); colonyteamborders = defineBoolean(builder, "colonyteamborders", true); + holidayFeatures = defineBoolean(builder, "holidayfeatures", true); swapToCategory(builder, "pathfinding"); diff --git a/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java b/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java index 3d33f5ee439..96e367723c0 100755 --- a/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java +++ b/src/main/java/com/minecolonies/api/configuration/ServerConfiguration.java @@ -26,7 +26,6 @@ public class ServerConfiguration extends AbstractConfiguration public final ForgeConfigSpec.BooleanValue enableInDevelopmentFeatures; public final ForgeConfigSpec.BooleanValue alwaysRenderNameTag; public final ForgeConfigSpec.BooleanValue workersAlwaysWorkInRain; - public final ForgeConfigSpec.BooleanValue holidayFeatures; public final ForgeConfigSpec.IntValue luckyBlockChance; public final ForgeConfigSpec.IntValue minThLevelToTeleport; public final ForgeConfigSpec.DoubleValue foodModifier; @@ -132,7 +131,6 @@ protected ServerConfiguration(final ForgeConfigSpec.Builder builder) enableInDevelopmentFeatures = defineBoolean(builder, "enableindevelopmentfeatures", false); alwaysRenderNameTag = defineBoolean(builder, "alwaysrendernametag", true); workersAlwaysWorkInRain = defineBoolean(builder, "workersalwaysworkinrain", false); - holidayFeatures = defineBoolean(builder, "holidayfeatures", true); luckyBlockChance = defineInteger(builder, "luckyblockchance", 1, 0, 100); minThLevelToTeleport = defineInteger(builder, "minthleveltoteleport", 3, 0, 5); foodModifier = defineDouble(builder, "foodmodifier", 1.0, 0.1, 100); diff --git a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesMonster.java b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesMonster.java index 26b80dfcf8c..146189ccc2b 100644 --- a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesMonster.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesMonster.java @@ -20,7 +20,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; -import net.minecraft.util.Tuple; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.*; @@ -178,15 +177,12 @@ public AbstractAdvancedPathNavigate getNavigation() this.navigation = newNavigator; this.newNavigator.setCanFloat(true); newNavigator.setSwimSpeedFactor(getSwimSpeedFactor()); - this.newNavigator.getPathingOptions().setEnterDoors(true); + newNavigator.getPathingOptions().setEnterDoors(true); + newNavigator.getPathingOptions().setCanOpenDoors(true); newNavigator.getPathingOptions().withDropCost(1D); newNavigator.getPathingOptions().withJumpCost(1D); newNavigator.getPathingOptions().setPassDanger(true); - PathingStuckHandler stuckHandler = PathingStuckHandler.createStuckHandler() - .withTakeDamageOnStuck(0.4f) - .withBuildLeafBridges() - .withChanceToByPassMovingAway(0.20) - .withPlaceLadders(); + PathingStuckHandler stuckHandler = PathingStuckHandler.createStuckHandler(); if (MinecoloniesAPIProxy.getInstance().getConfig().getServer().raidersbreakblocks.get()) { diff --git a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesRaider.java b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesRaider.java index 8b50e8825b4..a4ccb91ecf4 100644 --- a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesRaider.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityMinecoloniesRaider.java @@ -9,10 +9,12 @@ import com.minecolonies.api.enchants.ModEnchants; import com.minecolonies.api.entity.CustomGoalSelector; import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity; +import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; import com.minecolonies.api.items.IChiefSwordItem; import com.minecolonies.api.util.ColonyUtils; import com.minecolonies.api.util.DamageSourceKeys; import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; +import com.minecolonies.core.entity.pathfinding.navigation.PathingStuckHandler; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.DifficultyInstance; @@ -171,6 +173,37 @@ public AbstractEntityMinecoloniesRaider(final EntityType Date: Mon, 23 Dec 2024 01:48:55 +1300 Subject: [PATCH 29/33] Only upload resources for 1.21 (#10535) Only upload language resources to crowdin in 1.21 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 3ef01c00ac9..db000abde1c 100755 --- a/gradle.properties +++ b/gradle.properties @@ -93,6 +93,6 @@ usesSonarQube=true usesCrowdInTranslationManagement=true crowdInDownloadDirectory=src/main/resources/assets/minecolonies/lang -usesCrowdInUploadWithFilteredBranchesSpec=(version|release)\/.+ +usesCrowdInUploadWithFilteredBranchesSpec=(version|release)\/1\.21 additionalModsInDataGen=structurize;domum_ornamentum From 03f58b57173ce1ae60de4f0f33805caccacc6d01 Mon Sep 17 00:00:00 2001 From: Gavin Lambert Date: Mon, 23 Dec 2024 01:49:14 +1300 Subject: [PATCH 30/33] Only cache JEI citizens temporarily (#10489) Change JEI citizens to only temporarily be cached instead of caching for lifetime of the world session. This further reduces the lifetime of the client level, as a follow-up to Use fake level for JEI #10304. --- .../jei/JobBasedRecipeCategory.java | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) 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 5f9a1af38f9..d001f34d674 100644 --- a/src/main/java/com/minecolonies/core/compatibility/jei/JobBasedRecipeCategory.java +++ b/src/main/java/com/minecolonies/core/compatibility/jei/JobBasedRecipeCategory.java @@ -1,5 +1,6 @@ package com.minecolonies.core.compatibility.jei; +import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -12,6 +13,7 @@ import com.minecolonies.api.entity.ModEntities; import com.minecolonies.api.equipment.ModEquipmentTypes; import com.minecolonies.api.equipment.registry.EquipmentTypeEntry; +import com.minecolonies.api.util.Log; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.api.util.constant.TranslationConstants; import com.minecolonies.core.colony.CitizenData; @@ -48,7 +50,9 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.time.Duration; import java.util.*; import java.util.stream.Collectors; @@ -67,10 +71,13 @@ public abstract class JobBasedRecipeCategory implements IRecipeCategory @NotNull private final IDrawable icon; @NotNull protected final IDrawableStatic slot; @NotNull protected final IDrawableStatic chanceSlot; - @NotNull private final EntityCitizen citizen; @NotNull private final List description; @NotNull private final LoadingCache> infoBlocksCache; + private static final Cache, EntityCitizen> citizenCache = CacheBuilder.newBuilder() + .expireAfterAccess(Duration.ofMinutes(2)) + .build(); + protected static final int WIDTH = 167; protected static final int HEIGHT = 120; protected static final int CITIZEN_X = 2; @@ -92,8 +99,6 @@ protected JobBasedRecipeCategory(@NotNull final IJob job, this.slot = guiHelper.getSlotDrawable(); this.chanceSlot = guiHelper.createDrawable(TEXTURE, 0, 121, 18, 18); - this.citizen = createCitizenWithJob(this.job); - this.description = wordWrap(breakLines(translateDescription( TranslationConstants.PARTIAL_JEI_INFO + this.job.getJobRegistryEntry().getKey().getPath()))); @@ -210,12 +215,16 @@ public void draw(@NotNull final T recipe, final int citizen_by = CITIZEN_Y + CITIZEN_H; final int offsetY = 4; - final float headYaw = (float) Math.atan((citizen_cx - mouseX) / 40.0F) * 40.0F; - final float yaw = (float) Math.atan((citizen_cx - mouseX) / 40.0F) * 20.0F; - final float pitch = (float) Math.atan((citizen_cy - offsetY - mouseY) / 40.0F) * 20.0F; - Lighting.setupForFlatItems(); - UiRenderMacros.drawEntity(stack.pose(), citizen_cx, citizen_by - offsetY, scale, headYaw, yaw, pitch, this.citizen); - Lighting.setupFor3DItems(); + final EntityCitizen citizen = createCitizenWithJob(this.job); + if (citizen != null) + { + final float headYaw = (float) Math.atan((citizen_cx - mouseX) / 40.0F) * 40.0F; + final float yaw = (float) Math.atan((citizen_cx - mouseX) / 40.0F) * 20.0F; + final float pitch = (float) Math.atan((citizen_cy - offsetY - mouseY) / 40.0F) * 20.0F; + Lighting.setupForFlatItems(); + UiRenderMacros.drawEntity(stack.pose(), citizen_cx, citizen_by - offsetY, scale, headYaw, yaw, pitch, citizen); + Lighting.setupFor3DItems(); + } int y = 0; final Minecraft mc = Minecraft.getInstance(); @@ -298,15 +307,26 @@ public InfoBlock(final String text, final String tip, final Rect2i bounds) public final Rect2i bounds; } - @NotNull + @Nullable private static EntityCitizen createCitizenWithJob(@NotNull final IJob job) { - 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()))); - citizen.setModelId(job.getModel()); - return citizen; + try + { + return citizenCache.get(job, () -> + { + 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()))); + citizen.setModelId(job.getModel()); + return citizen; + }); + } + catch (final Throwable e) + { + Log.getLogger().error("Error creating citizen for {}", job.getJobRegistryEntry().getTranslationKey(), e); + return null; + } } @NotNull From 3c8a387df98bdaff93d113b8bdc00ac1eb524241 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Sun, 22 Dec 2024 13:49:40 +0100 Subject: [PATCH 31/33] Update all forge event code, attempt to become loader unaware (#10468) Introduce a new event handler in the IMinecoloniesAPI, which is backed by an interface containing basic methods for the events we want to send Event handler is implemented in such a way it could be made loader unaware in the future if needed. All logic for sending Forge specific events is ripped out in favor of the API event handler --- .../minecolonies/api/IMinecoloniesAPI.java | 3 + .../api/MinecoloniesAPIProxy.java | 9 ++- .../event/BuildingConstructionEvent.java | 65 ----------------- .../event/ColonyInformationChangedEvent.java | 47 ------------ .../api/eventbus/DefaultEventBus.java | 52 +++++++++++++ .../minecolonies/api/eventbus/EventBus.java | 36 +++++++++ .../minecolonies/api/eventbus/IModEvent.java | 16 ++++ .../api/eventbus/events/AbstractModEvent.java | 30 ++++++++ .../events/ColonyManagerLoadedModEvent.java} | 10 +-- .../ColonyManagerUnloadedModEvent.java} | 10 +-- .../events}/CustomRecipesReloadedEvent.java | 4 +- .../colony/AbstractColonyModEvent.java} | 73 +++++++++---------- .../events/colony/ColonyCreatedModEvent.java} | 6 +- .../events/colony/ColonyDeletedModEvent.java} | 6 +- .../colony/ColonyFlagChangedModEvent.java | 20 +++++ .../colony/ColonyNameChangedModEvent.java | 20 +++++ .../ColonyTeamColorChangedModEvent.java | 20 +++++ .../colony/ColonyViewUpdatedModEvent.java} | 52 ++++++------- .../buildings/AbstractBuildingModEvent.java} | 8 +- .../BuildingConstructionModEvent.java | 37 ++++++++++ .../citizens/AbstractCitizenModEvent.java} | 8 +- .../citizens/CitizenAddedModEvent.java} | 12 +-- .../colony/citizens/CitizenDiedModEvent.java} | 12 +-- .../citizens/CitizenRemovedModEvent.java | 39 ++++++++++ .../minecolonies/api/events/ColonyEvents.java | 38 ---------- .../apiimp/CommonMinecoloniesAPIImpl.java | 10 +++ .../core/colony/ColonyManager.java | 38 +++------- .../colony/crafting/CustomRecipeManager.java | 1 + .../RecruitmentInteraction.java | 16 ++-- .../core/colony/managers/CitizenManager.java | 22 +----- .../CommandCitizenSpawnNew.java | 14 +--- .../journeymap/EventListener.java | 9 ++- ...bstractEntityAIStructureWithWorkOrder.java | 56 +++++--------- .../core/entity/citizen/EntityCitizen.java | 21 +++--- .../event/ClientChunkUpdatedEvent.java | 70 +++++++++--------- .../messages/server/CreateColonyMessage.java | 15 +--- .../colony/ColonyFlagChangeMessage.java | 31 ++++---- .../colony/TeamColonyColorChangeMessage.java | 14 +--- .../server/colony/TownHallRenameMessage.java | 17 +---- .../main/SurvivalHandler.java | 2 + .../core/util/ChunkClientDataHelper.java | 2 +- 41 files changed, 512 insertions(+), 459 deletions(-) delete mode 100644 src/main/java/com/minecolonies/api/colony/buildings/event/BuildingConstructionEvent.java delete mode 100644 src/main/java/com/minecolonies/api/colony/event/ColonyInformationChangedEvent.java create mode 100644 src/main/java/com/minecolonies/api/eventbus/DefaultEventBus.java create mode 100644 src/main/java/com/minecolonies/api/eventbus/EventBus.java create mode 100644 src/main/java/com/minecolonies/api/eventbus/IModEvent.java create mode 100644 src/main/java/com/minecolonies/api/eventbus/events/AbstractModEvent.java rename src/main/java/com/minecolonies/api/{colony/managers/events/ColonyManagerLoadedEvent.java => eventbus/events/ColonyManagerLoadedModEvent.java} (63%) rename src/main/java/com/minecolonies/api/{colony/managers/events/ColonyManagerUnloadedEvent.java => eventbus/events/ColonyManagerUnloadedModEvent.java} (63%) rename src/main/java/com/minecolonies/{core/colony/crafting => api/eventbus/events}/CustomRecipesReloadedEvent.java (63%) rename src/main/java/com/minecolonies/api/{colony/event/AbstractColonyEvent.java => eventbus/events/colony/AbstractColonyModEvent.java} (56%) rename src/main/java/com/minecolonies/api/{colony/event/ColonyCreatedEvent.java => eventbus/events/colony/ColonyCreatedModEvent.java} (59%) rename src/main/java/com/minecolonies/api/{colony/event/ColonyDeletedEvent.java => eventbus/events/colony/ColonyDeletedModEvent.java} (59%) create mode 100644 src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyFlagChangedModEvent.java create mode 100644 src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyNameChangedModEvent.java create mode 100644 src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyTeamColorChangedModEvent.java rename src/main/java/com/minecolonies/api/{colony/event/ColonyViewUpdatedEvent.java => eventbus/events/colony/ColonyViewUpdatedModEvent.java} (69%) rename src/main/java/com/minecolonies/api/{colony/buildings/event/AbstractBuildingEvent.java => eventbus/events/colony/buildings/AbstractBuildingModEvent.java} (68%) create mode 100644 src/main/java/com/minecolonies/api/eventbus/events/colony/buildings/BuildingConstructionModEvent.java rename src/main/java/com/minecolonies/api/{colony/citizens/event/AbstractCitizenEvent.java => eventbus/events/colony/citizens/AbstractCitizenModEvent.java} (71%) rename src/main/java/com/minecolonies/api/{colony/citizens/event/CitizenAddedEvent.java => eventbus/events/colony/citizens/CitizenAddedModEvent.java} (77%) rename src/main/java/com/minecolonies/api/{colony/citizens/event/CitizenRemovedEvent.java => eventbus/events/colony/citizens/CitizenDiedModEvent.java} (66%) create mode 100644 src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenRemovedModEvent.java delete mode 100644 src/main/java/com/minecolonies/api/events/ColonyEvents.java rename src/main/java/com/minecolonies/{api/colony => core}/event/ClientChunkUpdatedEvent.java (87%) diff --git a/src/main/java/com/minecolonies/api/IMinecoloniesAPI.java b/src/main/java/com/minecolonies/api/IMinecoloniesAPI.java index 8c90e379254..80b9ddade15 100755 --- a/src/main/java/com/minecolonies/api/IMinecoloniesAPI.java +++ b/src/main/java/com/minecolonies/api/IMinecoloniesAPI.java @@ -22,6 +22,7 @@ import com.minecolonies.api.entity.citizen.happiness.HappinessRegistry; import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; import com.minecolonies.api.equipment.registry.EquipmentTypeEntry; +import com.minecolonies.api.eventbus.EventBus; import com.minecolonies.api.quests.registries.QuestRegistries; import com.minecolonies.api.research.IGlobalResearchTree; import com.minecolonies.api.research.ModResearchCostTypes.ResearchCostType; @@ -101,4 +102,6 @@ static IMinecoloniesAPI getInstance() void onRegistryNewRegistry(NewRegistryEvent event); IForgeRegistry getEquipmentTypeRegistry(); + + EventBus getEventBus(); } diff --git a/src/main/java/com/minecolonies/api/MinecoloniesAPIProxy.java b/src/main/java/com/minecolonies/api/MinecoloniesAPIProxy.java index 12d82f35011..18dddf94003 100755 --- a/src/main/java/com/minecolonies/api/MinecoloniesAPIProxy.java +++ b/src/main/java/com/minecolonies/api/MinecoloniesAPIProxy.java @@ -22,6 +22,7 @@ import com.minecolonies.api.entity.citizen.happiness.HappinessRegistry; import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; import com.minecolonies.api.equipment.registry.EquipmentTypeEntry; +import com.minecolonies.api.eventbus.EventBus; import com.minecolonies.api.quests.registries.QuestRegistries; import com.minecolonies.api.research.IGlobalResearchTree; import com.minecolonies.api.research.ModResearchCostTypes.ResearchCostType; @@ -32,7 +33,7 @@ public final class MinecoloniesAPIProxy implements IMinecoloniesAPI { - private static MinecoloniesAPIProxy ourInstance = new MinecoloniesAPIProxy(); + private static final MinecoloniesAPIProxy ourInstance = new MinecoloniesAPIProxy(); private IMinecoloniesAPI apiInstance; @@ -235,4 +236,10 @@ public IForgeRegistry getEquipmentTypeRegistry() { return apiInstance.getEquipmentTypeRegistry(); } + + @Override + public EventBus getEventBus() + { + return apiInstance.getEventBus(); + } } diff --git a/src/main/java/com/minecolonies/api/colony/buildings/event/BuildingConstructionEvent.java b/src/main/java/com/minecolonies/api/colony/buildings/event/BuildingConstructionEvent.java deleted file mode 100644 index f470839e587..00000000000 --- a/src/main/java/com/minecolonies/api/colony/buildings/event/BuildingConstructionEvent.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.minecolonies.api.colony.buildings.event; - -import com.minecolonies.api.colony.buildings.IBuilding; -import com.minecolonies.api.colony.workorders.WorkOrderType; - -/** - * Event for when a building was built/repaired/removed. - */ -public final class BuildingConstructionEvent extends AbstractBuildingEvent -{ - /** - * What happened to the building. - */ - private final EventType eventType; - - /** - * Building construction event. - * - * @param building the building the event was for. - * @param eventType what happened to the building. - */ - public BuildingConstructionEvent(final IBuilding building, final EventType eventType) - { - super(building); - this.eventType = eventType; - } - - /** - * Get what happened to the building. - * - * @return the event type. - */ - public EventType getEventType() - { - return eventType; - } - - /** - * What happened to the building. - */ - public enum EventType - { - BUILT, - UPGRADED, - REPAIRED, - REMOVED; - - /** - * Obtain the construction event type from the work order type. - * - * @param workOrderType the work order type. - * @return the construction event type. - */ - public static EventType fromWorkOrderType(final WorkOrderType workOrderType) - { - return switch (workOrderType) - { - case BUILD -> BUILT; - case UPGRADE -> UPGRADED; - case REPAIR -> REPAIRED; - case REMOVE -> REMOVED; - }; - } - } -} diff --git a/src/main/java/com/minecolonies/api/colony/event/ColonyInformationChangedEvent.java b/src/main/java/com/minecolonies/api/colony/event/ColonyInformationChangedEvent.java deleted file mode 100644 index 69e62fdb966..00000000000 --- a/src/main/java/com/minecolonies/api/colony/event/ColonyInformationChangedEvent.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.minecolonies.api.colony.event; - -import com.minecolonies.api.colony.IColony; -import org.jetbrains.annotations.NotNull; - -/** - * Colony information changed event. - */ -public class ColonyInformationChangedEvent extends AbstractColonyEvent -{ - /** - * What type of information changed on the colony. - */ - private final Type type; - - /** - * Constructs a colony information changed event. - * - * @param colony the colony related to the event. - * @param type what type of information changed on the colony. - */ - public ColonyInformationChangedEvent(final @NotNull IColony colony, final Type type) - { - super(colony); - this.type = type; - } - - /** - * Get what type of information changed on the colony. - * - * @return the enum value. - */ - public Type getType() - { - return type; - } - - /** - * What information of the colony changed. - */ - public enum Type - { - NAME, - TEAM_COLOR, - FLAG - } -} diff --git a/src/main/java/com/minecolonies/api/eventbus/DefaultEventBus.java b/src/main/java/com/minecolonies/api/eventbus/DefaultEventBus.java new file mode 100644 index 00000000000..1dd55fc1ce1 --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/DefaultEventBus.java @@ -0,0 +1,52 @@ +package com.minecolonies.api.eventbus; + +import com.minecolonies.api.util.Log; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Default implementation of the mod event bus. + */ +public class DefaultEventBus implements EventBus +{ + /** + * The map of event handlers. + */ + private final Map, List>> eventHandlersPerType = new HashMap<>(); + + @Override + public void subscribe(final @NotNull Class eventType, final @NotNull EventHandler handler) + { + Log.getLogger().debug("Registering event handler for id {}.", eventType.getSimpleName()); + + eventHandlersPerType.computeIfAbsent(eventType, (f) -> new ArrayList<>()).add(handler); + } + + @Override + public void post(final @NotNull IModEvent event) + { + final List> eventHandlers = eventHandlersPerType.get(event.getClass()); + if (eventHandlers == null) + { + return; + } + + Log.getLogger().debug("Sending event '{}' for type '{}'. Sending to {} handlers.", event.getEventId(), event.getClass().getSimpleName(), eventHandlers.size()); + + for (final EventHandler handler : eventHandlers) + { + try + { + ((EventHandler) handler).apply(event); + } + catch (Exception ex) + { + Log.getLogger().warn("Sending event '{}' for type '{}'. Error occurred in handler:", event.getEventId(), event.getClass().getSimpleName(), ex); + } + } + } +} diff --git a/src/main/java/com/minecolonies/api/eventbus/EventBus.java b/src/main/java/com/minecolonies/api/eventbus/EventBus.java new file mode 100644 index 00000000000..bf899439f40 --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/EventBus.java @@ -0,0 +1,36 @@ +package com.minecolonies.api.eventbus; + +import org.jetbrains.annotations.NotNull; + +/** + * Interface for the mod event bus. + */ +public interface EventBus +{ + /** + * Subscribe to the given event type, providing a handler function. + * + * @param eventType the event class type. + * @param handler the handler function handling the event logic. + * @param the generic type of the event class. + */ + void subscribe(final @NotNull Class eventType, final @NotNull EventHandler handler); + + /** + * Posts a new event on the event bus for the given type. + * + * @param event the event to send. + */ + void post(final @NotNull IModEvent event); + + /** + * The event handler lambda definition. + * + * @param the generic type of the event class. + */ + @FunctionalInterface + interface EventHandler + { + void apply(final @NotNull T event); + } +} diff --git a/src/main/java/com/minecolonies/api/eventbus/IModEvent.java b/src/main/java/com/minecolonies/api/eventbus/IModEvent.java new file mode 100644 index 00000000000..619d7afa4a7 --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/IModEvent.java @@ -0,0 +1,16 @@ +package com.minecolonies.api.eventbus; + +import java.util.UUID; + +/** + * Default event interface. + */ +public interface IModEvent +{ + /** + * The unique id for this event. + * + * @return the event id. + */ + UUID getEventId(); +} diff --git a/src/main/java/com/minecolonies/api/eventbus/events/AbstractModEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/AbstractModEvent.java new file mode 100644 index 00000000000..d4f88210bf4 --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/events/AbstractModEvent.java @@ -0,0 +1,30 @@ +package com.minecolonies.api.eventbus.events; + +import com.minecolonies.api.eventbus.IModEvent; + +import java.util.UUID; + +/** + * Abstract implementation for this mod bus events. + */ +public class AbstractModEvent implements IModEvent +{ + /** + * The unique id for this event. + */ + private final UUID eventId; + + /** + * Default constructor. + */ + protected AbstractModEvent() + { + this.eventId = UUID.randomUUID(); + } + + @Override + public UUID getEventId() + { + return eventId; + } +} diff --git a/src/main/java/com/minecolonies/api/colony/managers/events/ColonyManagerLoadedEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/ColonyManagerLoadedModEvent.java similarity index 63% rename from src/main/java/com/minecolonies/api/colony/managers/events/ColonyManagerLoadedEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/ColonyManagerLoadedModEvent.java index a3d7a78881a..6a45bfce5e4 100644 --- a/src/main/java/com/minecolonies/api/colony/managers/events/ColonyManagerLoadedEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/ColonyManagerLoadedModEvent.java @@ -1,13 +1,12 @@ -package com.minecolonies.api.colony.managers.events; +package com.minecolonies.api.eventbus.events; import com.minecolonies.api.colony.IColonyManager; -import net.minecraftforge.eventbus.api.Event; import org.jetbrains.annotations.NotNull; /** * Colony manager loaded event. */ -public final class ColonyManagerLoadedEvent extends Event +public final class ColonyManagerLoadedModEvent extends AbstractModEvent { /** * The colony manager instance. @@ -18,7 +17,7 @@ public final class ColonyManagerLoadedEvent extends Event /** * Event for colony manager loaded. */ - public ColonyManagerLoadedEvent(final @NotNull IColonyManager colonyManager) + public ColonyManagerLoadedModEvent(final @NotNull IColonyManager colonyManager) { this.colonyManager = colonyManager; } @@ -28,7 +27,8 @@ public ColonyManagerLoadedEvent(final @NotNull IColonyManager colonyManager) * * @return the colony manager. */ - public @NotNull IColonyManager getColonyManager() + @NotNull + public IColonyManager getColonyManager() { return colonyManager; } diff --git a/src/main/java/com/minecolonies/api/colony/managers/events/ColonyManagerUnloadedEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/ColonyManagerUnloadedModEvent.java similarity index 63% rename from src/main/java/com/minecolonies/api/colony/managers/events/ColonyManagerUnloadedEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/ColonyManagerUnloadedModEvent.java index 980b9719932..7443b63d1fd 100644 --- a/src/main/java/com/minecolonies/api/colony/managers/events/ColonyManagerUnloadedEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/ColonyManagerUnloadedModEvent.java @@ -1,13 +1,12 @@ -package com.minecolonies.api.colony.managers.events; +package com.minecolonies.api.eventbus.events; import com.minecolonies.api.colony.IColonyManager; -import net.minecraftforge.eventbus.api.Event; import org.jetbrains.annotations.NotNull; /** * Colony manager unloaded event. */ -public class ColonyManagerUnloadedEvent extends Event +public final class ColonyManagerUnloadedModEvent extends AbstractModEvent { /** * The colony manager instance. @@ -18,7 +17,7 @@ public class ColonyManagerUnloadedEvent extends Event /** * Event for colony manager loaded. */ - public ColonyManagerUnloadedEvent(final @NotNull IColonyManager colonyManager) + public ColonyManagerUnloadedModEvent(final @NotNull IColonyManager colonyManager) { this.colonyManager = colonyManager; } @@ -28,7 +27,8 @@ public ColonyManagerUnloadedEvent(final @NotNull IColonyManager colonyManager) * * @return the colony manager. */ - public @NotNull IColonyManager getColonyManager() + @NotNull + public IColonyManager getColonyManager() { return colonyManager; } diff --git a/src/main/java/com/minecolonies/core/colony/crafting/CustomRecipesReloadedEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/CustomRecipesReloadedEvent.java similarity index 63% rename from src/main/java/com/minecolonies/core/colony/crafting/CustomRecipesReloadedEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/CustomRecipesReloadedEvent.java index f1397c855cb..57d80030fae 100644 --- a/src/main/java/com/minecolonies/core/colony/crafting/CustomRecipesReloadedEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/CustomRecipesReloadedEvent.java @@ -1,10 +1,10 @@ -package com.minecolonies.core.colony.crafting; +package com.minecolonies.api.eventbus.events; import net.minecraftforge.eventbus.api.Event; /** * This event is fired on the client side whenever the CustomRecipeManager has been - * populated. This occurs once on world load/connect and again whenever datapacks are reloaded. + * populated. This occurs once on world load/connect and again whenever data-packs are reloaded. */ public class CustomRecipesReloadedEvent extends Event { diff --git a/src/main/java/com/minecolonies/api/colony/event/AbstractColonyEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/AbstractColonyModEvent.java similarity index 56% rename from src/main/java/com/minecolonies/api/colony/event/AbstractColonyEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/colony/AbstractColonyModEvent.java index 4e672d2faa2..3e60277cb26 100644 --- a/src/main/java/com/minecolonies/api/colony/event/AbstractColonyEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/AbstractColonyModEvent.java @@ -1,37 +1,36 @@ -package com.minecolonies.api.colony.event; - -import com.minecolonies.api.colony.IColony; -import net.minecraftforge.eventbus.api.Event; -import org.jetbrains.annotations.NotNull; - -/** - * This is a colony-related event in the Forge sense, not in the - * {@link com.minecolonies.api.colony.colonyEvents.IColonyEvent} sense. - */ -public abstract class AbstractColonyEvent extends Event -{ - /** - * The colony this event was called in. - */ - @NotNull - private final IColony colony; - - /** - * Constructs a colony-based event. - * - * @param colony The colony related to the event. - */ - protected AbstractColonyEvent(@NotNull final IColony colony) - { - this.colony = colony; - } - - /** - * Gets the colony related to the event. - */ - @NotNull - public IColony getColony() - { - return colony; - } -} +package com.minecolonies.api.eventbus.events.colony; + +import com.minecolonies.api.colony.IColony; +import com.minecolonies.api.eventbus.events.AbstractModEvent; +import org.jetbrains.annotations.NotNull; + +/** + * Any colony related event, provides the target colony the event occurred in. + */ +public abstract class AbstractColonyModEvent extends AbstractModEvent +{ + /** + * The colony this event was called in. + */ + @NotNull + private final IColony colony; + + /** + * Constructs a colony-based event. + * + * @param colony The colony related to the event. + */ + protected AbstractColonyModEvent(@NotNull final IColony colony) + { + this.colony = colony; + } + + /** + * Gets the colony related to the event. + */ + @NotNull + public IColony getColony() + { + return colony; + } +} diff --git a/src/main/java/com/minecolonies/api/colony/event/ColonyCreatedEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyCreatedModEvent.java similarity index 59% rename from src/main/java/com/minecolonies/api/colony/event/ColonyCreatedEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyCreatedModEvent.java index 8b0e1d66fef..8fb54bdc6e7 100644 --- a/src/main/java/com/minecolonies/api/colony/event/ColonyCreatedEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyCreatedModEvent.java @@ -1,4 +1,4 @@ -package com.minecolonies.api.colony.event; +package com.minecolonies.api.eventbus.events.colony; import com.minecolonies.api.colony.IColony; import org.jetbrains.annotations.NotNull; @@ -6,14 +6,14 @@ /** * Colony created event. */ -public class ColonyCreatedEvent extends AbstractColonyEvent +public final class ColonyCreatedModEvent extends AbstractColonyModEvent { /** * Constructs a colony created event. * * @param colony The colony related to the event. */ - public ColonyCreatedEvent(final @NotNull IColony colony) + public ColonyCreatedModEvent(final @NotNull IColony colony) { super(colony); } diff --git a/src/main/java/com/minecolonies/api/colony/event/ColonyDeletedEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyDeletedModEvent.java similarity index 59% rename from src/main/java/com/minecolonies/api/colony/event/ColonyDeletedEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyDeletedModEvent.java index cb08a6daecc..ef0bb7e0089 100644 --- a/src/main/java/com/minecolonies/api/colony/event/ColonyDeletedEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyDeletedModEvent.java @@ -1,4 +1,4 @@ -package com.minecolonies.api.colony.event; +package com.minecolonies.api.eventbus.events.colony; import com.minecolonies.api.colony.IColony; import org.jetbrains.annotations.NotNull; @@ -6,14 +6,14 @@ /** * Colony deleted event. */ -public class ColonyDeletedEvent extends AbstractColonyEvent +public final class ColonyDeletedModEvent extends AbstractColonyModEvent { /** * Constructs a colony deleted event. * * @param colony The colony related to the event. */ - public ColonyDeletedEvent(final @NotNull IColony colony) + public ColonyDeletedModEvent(final @NotNull IColony colony) { super(colony); } diff --git a/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyFlagChangedModEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyFlagChangedModEvent.java new file mode 100644 index 00000000000..a6a6ec1a67d --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyFlagChangedModEvent.java @@ -0,0 +1,20 @@ +package com.minecolonies.api.eventbus.events.colony; + +import com.minecolonies.api.colony.IColony; +import org.jetbrains.annotations.NotNull; + +/** + * Colony flag changed event. + */ +public final class ColonyFlagChangedModEvent extends AbstractColonyModEvent +{ + /** + * Constructs a colony flag changed event. + * + * @param colony the colony related to the event. + */ + public ColonyFlagChangedModEvent(final @NotNull IColony colony) + { + super(colony); + } +} diff --git a/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyNameChangedModEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyNameChangedModEvent.java new file mode 100644 index 00000000000..b457042535b --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyNameChangedModEvent.java @@ -0,0 +1,20 @@ +package com.minecolonies.api.eventbus.events.colony; + +import com.minecolonies.api.colony.IColony; +import org.jetbrains.annotations.NotNull; + +/** + * Colony name changed event. + */ +public final class ColonyNameChangedModEvent extends AbstractColonyModEvent +{ + /** + * Constructs a colony name changed event. + * + * @param colony the colony related to the event. + */ + public ColonyNameChangedModEvent(final @NotNull IColony colony) + { + super(colony); + } +} diff --git a/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyTeamColorChangedModEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyTeamColorChangedModEvent.java new file mode 100644 index 00000000000..00fb7ac90f7 --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyTeamColorChangedModEvent.java @@ -0,0 +1,20 @@ +package com.minecolonies.api.eventbus.events.colony; + +import com.minecolonies.api.colony.IColony; +import org.jetbrains.annotations.NotNull; + +/** + * Colony team changed event. + */ +public final class ColonyTeamColorChangedModEvent extends AbstractColonyModEvent +{ + /** + * Constructs a colony team changed event. + * + * @param colony the colony related to the event. + */ + public ColonyTeamColorChangedModEvent(final @NotNull IColony colony) + { + super(colony); + } +} diff --git a/src/main/java/com/minecolonies/api/colony/event/ColonyViewUpdatedEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyViewUpdatedModEvent.java similarity index 69% rename from src/main/java/com/minecolonies/api/colony/event/ColonyViewUpdatedEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyViewUpdatedModEvent.java index 23e7a3f0151..77d5bed15ce 100644 --- a/src/main/java/com/minecolonies/api/colony/event/ColonyViewUpdatedEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/ColonyViewUpdatedModEvent.java @@ -1,26 +1,26 @@ -package com.minecolonies.api.colony.event; - -import com.minecolonies.api.colony.IColonyView; -import org.jetbrains.annotations.NotNull; - -/** - * This event is raised client-side whenever a particular colony's data is refreshed. - */ -public class ColonyViewUpdatedEvent extends AbstractColonyEvent -{ - /** - * Constructs a new event. - * - * @param colony The colony (view) that was just updated. - */ - public ColonyViewUpdatedEvent(final @NotNull IColonyView colony) - { - super(colony); - } - - @Override - public @NotNull IColonyView getColony() - { - return (IColonyView) super.getColony(); - } -} +package com.minecolonies.api.eventbus.events.colony; + +import com.minecolonies.api.colony.IColonyView; +import org.jetbrains.annotations.NotNull; + +/** + * This event is raised client-side whenever a particular colony's data is refreshed. + */ +public final class ColonyViewUpdatedModEvent extends AbstractColonyModEvent +{ + /** + * Constructs a new event. + * + * @param colony The colony (view) that was just updated. + */ + public ColonyViewUpdatedModEvent(final @NotNull IColonyView colony) + { + super(colony); + } + + @Override + public @NotNull IColonyView getColony() + { + return (IColonyView) super.getColony(); + } +} diff --git a/src/main/java/com/minecolonies/api/colony/buildings/event/AbstractBuildingEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/buildings/AbstractBuildingModEvent.java similarity index 68% rename from src/main/java/com/minecolonies/api/colony/buildings/event/AbstractBuildingEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/colony/buildings/AbstractBuildingModEvent.java index f5759a3399f..dd0a737e6df 100644 --- a/src/main/java/com/minecolonies/api/colony/buildings/event/AbstractBuildingEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/buildings/AbstractBuildingModEvent.java @@ -1,12 +1,12 @@ -package com.minecolonies.api.colony.buildings.event; +package com.minecolonies.api.eventbus.events.colony.buildings; import com.minecolonies.api.colony.buildings.IBuilding; -import com.minecolonies.api.colony.event.AbstractColonyEvent; +import com.minecolonies.api.eventbus.events.colony.AbstractColonyModEvent; /** * Abstract event for building related things. */ -public abstract class AbstractBuildingEvent extends AbstractColonyEvent +public abstract class AbstractBuildingModEvent extends AbstractColonyModEvent { /** * The building related to the event. @@ -18,7 +18,7 @@ public abstract class AbstractBuildingEvent extends AbstractColonyEvent * * @param building the building related to the event. */ - protected AbstractBuildingEvent(final IBuilding building) + protected AbstractBuildingModEvent(final IBuilding building) { super(building.getColony()); this.building = building; diff --git a/src/main/java/com/minecolonies/api/eventbus/events/colony/buildings/BuildingConstructionModEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/buildings/BuildingConstructionModEvent.java new file mode 100644 index 00000000000..87e133bdf15 --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/buildings/BuildingConstructionModEvent.java @@ -0,0 +1,37 @@ +package com.minecolonies.api.eventbus.events.colony.buildings; + +import com.minecolonies.api.colony.buildings.IBuilding; +import com.minecolonies.core.colony.workorders.WorkOrderBuilding; + +/** + * Event for when a building was built, upgraded, repaired or removed. + */ +public final class BuildingConstructionModEvent extends AbstractBuildingModEvent +{ + /** + * The work order which was completed. + */ + private final WorkOrderBuilding workOrder; + + /** + * Building construction event. + * + * @param building the building the event was for. + * @param workOrder the work order which was completed. + */ + public BuildingConstructionModEvent(final IBuilding building, final WorkOrderBuilding workOrder) + { + super(building); + this.workOrder = workOrder; + } + + /** + * Get the work order which was completed. + * + * @return the event type. + */ + public WorkOrderBuilding getWorkOrder() + { + return workOrder; + } +} diff --git a/src/main/java/com/minecolonies/api/colony/citizens/event/AbstractCitizenEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/AbstractCitizenModEvent.java similarity index 71% rename from src/main/java/com/minecolonies/api/colony/citizens/event/AbstractCitizenEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/AbstractCitizenModEvent.java index 05942def618..eca9aa3123d 100644 --- a/src/main/java/com/minecolonies/api/colony/citizens/event/AbstractCitizenEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/AbstractCitizenModEvent.java @@ -1,14 +1,14 @@ -package com.minecolonies.api.colony.citizens.event; +package com.minecolonies.api.eventbus.events.colony.citizens; import com.minecolonies.api.colony.ICitizen; import com.minecolonies.api.colony.ICitizenData; -import com.minecolonies.api.colony.event.AbstractColonyEvent; +import com.minecolonies.api.eventbus.events.colony.AbstractColonyModEvent; import org.jetbrains.annotations.NotNull; /** * Abstract event for citizen related things. */ -public class AbstractCitizenEvent extends AbstractColonyEvent +public class AbstractCitizenModEvent extends AbstractColonyModEvent { /** * The citizen related to the event. @@ -20,7 +20,7 @@ public class AbstractCitizenEvent extends AbstractColonyEvent * * @param citizen the citizen related to the event. */ - protected AbstractCitizenEvent(final @NotNull ICitizenData citizen) + protected AbstractCitizenModEvent(final @NotNull ICitizenData citizen) { super(citizen.getColony()); this.citizen = citizen; diff --git a/src/main/java/com/minecolonies/api/colony/citizens/event/CitizenAddedEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenAddedModEvent.java similarity index 77% rename from src/main/java/com/minecolonies/api/colony/citizens/event/CitizenAddedEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenAddedModEvent.java index c2baf35e0d0..559e5ec8f27 100644 --- a/src/main/java/com/minecolonies/api/colony/citizens/event/CitizenAddedEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenAddedModEvent.java @@ -1,16 +1,16 @@ -package com.minecolonies.api.colony.citizens.event; +package com.minecolonies.api.eventbus.events.colony.citizens; import com.minecolonies.api.colony.ICitizenData; /** * Event for when a citizen was added to the colony. */ -public class CitizenAddedEvent extends AbstractCitizenEvent +public final class CitizenAddedModEvent extends AbstractCitizenModEvent { /** * The way the citizen came into the colony. */ - private final Source source; + private final CitizenAddedSource source; /** * Citizen added event. @@ -18,7 +18,7 @@ public class CitizenAddedEvent extends AbstractCitizenEvent * @param citizen the citizen related to the event. * @param source the way the citizen came into the colony. */ - public CitizenAddedEvent(final ICitizenData citizen, final Source source) + public CitizenAddedModEvent(final ICitizenData citizen, final CitizenAddedSource source) { super(citizen); this.source = source; @@ -29,7 +29,7 @@ public CitizenAddedEvent(final ICitizenData citizen, final Source source) * * @return the enum value. */ - public Source getSource() + public CitizenAddedSource getSource() { return source; } @@ -37,7 +37,7 @@ public Source getSource() /** * How the citizen came into the colony. */ - public enum Source + public enum CitizenAddedSource { /** * The citizen spawned as part of the {@link com.minecolonies.api.configuration.ServerConfiguration#initialCitizenAmount}. diff --git a/src/main/java/com/minecolonies/api/colony/citizens/event/CitizenRemovedEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenDiedModEvent.java similarity index 66% rename from src/main/java/com/minecolonies/api/colony/citizens/event/CitizenRemovedEvent.java rename to src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenDiedModEvent.java index 779372a5be6..c5b9366a573 100644 --- a/src/main/java/com/minecolonies/api/colony/citizens/event/CitizenRemovedEvent.java +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenDiedModEvent.java @@ -1,13 +1,13 @@ -package com.minecolonies.api.colony.citizens.event; +package com.minecolonies.api.eventbus.events.colony.citizens; import com.minecolonies.api.colony.ICitizenData; import net.minecraft.world.damagesource.DamageSource; import org.jetbrains.annotations.NotNull; /** - * Event for when a citizen was removed from the colony. + * Event for when a citizen died in any colony. */ -public class CitizenRemovedEvent extends AbstractCitizenEvent +public final class CitizenDiedModEvent extends AbstractCitizenModEvent { /** * The damage source that caused a citizen to die. @@ -15,12 +15,12 @@ public class CitizenRemovedEvent extends AbstractCitizenEvent private final @NotNull DamageSource source; /** - * Citizen removed event. + * Citizen died event. * * @param citizen the citizen related to the event. - * @param source the way the citizen went out of the colony. + * @param source the damage source the citizen died from. */ - public CitizenRemovedEvent(final @NotNull ICitizenData citizen, final @NotNull DamageSource source) + public CitizenDiedModEvent(final @NotNull ICitizenData citizen, final @NotNull DamageSource source) { super(citizen); this.source = source; diff --git a/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenRemovedModEvent.java b/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenRemovedModEvent.java new file mode 100644 index 00000000000..859bd3a0b34 --- /dev/null +++ b/src/main/java/com/minecolonies/api/eventbus/events/colony/citizens/CitizenRemovedModEvent.java @@ -0,0 +1,39 @@ +package com.minecolonies.api.eventbus.events.colony.citizens; + +import com.minecolonies.api.colony.ICitizenData; +import net.minecraft.world.entity.Entity; +import org.jetbrains.annotations.NotNull; + +/** + * Event for when a citizen was removed from the colony. + */ +public final class CitizenRemovedModEvent extends AbstractCitizenModEvent +{ + /** + * The damage source that caused a citizen to die. + */ + private final @NotNull Entity.RemovalReason reason; + + /** + * Citizen removed event. + * + * @param citizen the citizen related to the event. + * @param reason the reason the citizen was removed. + */ + public CitizenRemovedModEvent(final @NotNull ICitizenData citizen, final @NotNull Entity.RemovalReason reason) + { + super(citizen); + this.reason = reason; + } + + /** + * The damage source that caused the citizen to die. + * + * @return the damage source. + */ + @NotNull + public Entity.RemovalReason getRemovalReason() + { + return reason; + } +} diff --git a/src/main/java/com/minecolonies/api/events/ColonyEvents.java b/src/main/java/com/minecolonies/api/events/ColonyEvents.java deleted file mode 100644 index aef3f6d7b4c..00000000000 --- a/src/main/java/com/minecolonies/api/events/ColonyEvents.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.minecolonies.api.events; - -import com.minecolonies.api.colony.IColony; -import com.minecolonies.api.colony.event.ColonyDeletedEvent; -import com.minecolonies.api.util.Log; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.Event; - -/** - * Event manager for all forge events. - */ -public class ColonyEvents -{ - /** - * Event triggered when a colony is being deleted. - * - * @param colony the colony in question. - */ - public static void deleteColony(final IColony colony) - { - sendEventSafe(new ColonyDeletedEvent(colony)); - } - - /** - * Underlying logic for transmitting an event. - */ - private static void sendEventSafe(final Event event) - { - try - { - MinecraftForge.EVENT_BUS.post(event); - } - catch (final Exception e) - { - Log.getLogger().atError().withThrowable(e).log("Exception occurred during {} event", event.getClass().getName()); - } - } -} diff --git a/src/main/java/com/minecolonies/apiimp/CommonMinecoloniesAPIImpl.java b/src/main/java/com/minecolonies/apiimp/CommonMinecoloniesAPIImpl.java index 7400bf0fa5e..dd69ac6d1c9 100755 --- a/src/main/java/com/minecolonies/apiimp/CommonMinecoloniesAPIImpl.java +++ b/src/main/java/com/minecolonies/apiimp/CommonMinecoloniesAPIImpl.java @@ -24,6 +24,8 @@ import com.minecolonies.api.entity.citizen.happiness.HappinessRegistry; import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; import com.minecolonies.api.equipment.registry.EquipmentTypeEntry; +import com.minecolonies.api.eventbus.DefaultEventBus; +import com.minecolonies.api.eventbus.EventBus; import com.minecolonies.api.quests.registries.QuestRegistries; import com.minecolonies.api.research.IGlobalResearchTree; import com.minecolonies.api.research.ModResearchCostTypes.ResearchCostType; @@ -81,6 +83,8 @@ public class CommonMinecoloniesAPIImpl implements IMinecoloniesAPI private IForgeRegistry happinessFactorTypeRegistry; private IForgeRegistry happinessFunctionRegistry; + private EventBus eventBus = new DefaultEventBus(); + @Override @NotNull public IColonyManager getColonyManager() @@ -393,5 +397,11 @@ public IForgeRegistry getEquipmentTypeRegistry() { return equipmentTypeRegistry; } + + @Override + public EventBus getEventBus() + { + return eventBus; + } } diff --git a/src/main/java/com/minecolonies/core/colony/ColonyManager.java b/src/main/java/com/minecolonies/core/colony/ColonyManager.java index b11c9cbed41..88b2d6c56b4 100755 --- a/src/main/java/com/minecolonies/core/colony/ColonyManager.java +++ b/src/main/java/com/minecolonies/core/colony/ColonyManager.java @@ -1,17 +1,18 @@ package com.minecolonies.core.colony; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.blocks.AbstractBlockHut; import com.minecolonies.api.colony.*; import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.colony.buildings.views.IBuildingView; -import com.minecolonies.api.colony.event.ColonyViewUpdatedEvent; -import com.minecolonies.api.colony.managers.events.ColonyManagerLoadedEvent; -import com.minecolonies.api.colony.managers.events.ColonyManagerUnloadedEvent; import com.minecolonies.api.colony.permissions.ColonyPlayer; import com.minecolonies.api.compatibility.CompatibilityManager; import com.minecolonies.api.compatibility.ICompatibilityManager; import com.minecolonies.api.crafting.IRecipeManager; -import com.minecolonies.api.events.ColonyEvents; +import com.minecolonies.api.eventbus.events.ColonyManagerLoadedModEvent; +import com.minecolonies.api.eventbus.events.ColonyManagerUnloadedModEvent; +import com.minecolonies.api.eventbus.events.colony.ColonyDeletedModEvent; +import com.minecolonies.api.eventbus.events.colony.ColonyViewUpdatedModEvent; import com.minecolonies.api.sounds.SoundManager; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.ColonyUtils; @@ -202,7 +203,7 @@ private void deleteColony(@Nullable final IColony iColony, final boolean canDest return; } - ColonyEvents.deleteColony(colony); + IMinecoloniesAPI.getInstance().getEventBus().post(new ColonyDeletedModEvent(colony)); cap.deleteColony(id); BackUpHelper.markColonyDeleted(colony.getID(), colony.getDimension()); colony.getImportantMessageEntityPlayers() @@ -645,14 +646,7 @@ public void onWorldLoad(@NotNull final Level world) c.onWorldLoad(world); } - try - { - MinecraftForge.EVENT_BUS.post(new ColonyManagerLoadedEvent(this)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyManagerLoadedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new ColonyManagerLoadedModEvent(this)); } } @@ -679,14 +673,7 @@ public void onWorldUnload(@NotNull final Level world) BackUpHelper.backupColonyData(); } - try - { - MinecraftForge.EVENT_BUS.post(new ColonyManagerUnloadedEvent(this)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyManagerUnloadedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new ColonyManagerUnloadedModEvent(this)); } } @@ -715,14 +702,7 @@ public void handleColonyViewMessage( } view.handleColonyViewMessage(colonyData, world, isNewSubscription); - try - { - MinecraftForge.EVENT_BUS.post(new ColonyViewUpdatedEvent(view)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyViewUpdatedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new ColonyViewUpdatedModEvent(view)); } @Override diff --git a/src/main/java/com/minecolonies/core/colony/crafting/CustomRecipeManager.java b/src/main/java/com/minecolonies/core/colony/crafting/CustomRecipeManager.java index 0d599b9de2c..73cf557d99a 100644 --- a/src/main/java/com/minecolonies/core/colony/crafting/CustomRecipeManager.java +++ b/src/main/java/com/minecolonies/core/colony/crafting/CustomRecipeManager.java @@ -5,6 +5,7 @@ import com.minecolonies.api.colony.buildings.modules.ICraftingBuildingModule; import com.minecolonies.api.colony.buildings.registry.BuildingEntry; import com.minecolonies.api.crafting.ItemStorage; +import com.minecolonies.api.eventbus.events.CustomRecipesReloadedEvent; import com.minecolonies.api.loot.ModLootTables; import com.minecolonies.api.util.Log; import com.minecolonies.core.Network; diff --git a/src/main/java/com/minecolonies/core/colony/interactionhandling/RecruitmentInteraction.java b/src/main/java/com/minecolonies/core/colony/interactionhandling/RecruitmentInteraction.java index cce517c02d3..696b4525557 100644 --- a/src/main/java/com/minecolonies/core/colony/interactionhandling/RecruitmentInteraction.java +++ b/src/main/java/com/minecolonies/core/colony/interactionhandling/RecruitmentInteraction.java @@ -6,13 +6,13 @@ import com.ldtteam.blockui.controls.Text; import com.ldtteam.blockui.views.BOWindow; import com.ldtteam.blockui.views.Box; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.*; -import com.minecolonies.api.colony.citizens.event.CitizenAddedEvent; import com.minecolonies.api.colony.interactionhandling.IChatPriority; import com.minecolonies.api.colony.interactionhandling.IInteractionResponseHandler; import com.minecolonies.api.colony.interactionhandling.ModInteractionResponseHandlers; +import com.minecolonies.api.eventbus.events.colony.citizens.CitizenAddedModEvent; import com.minecolonies.api.util.InventoryUtils; -import com.minecolonies.api.util.Log; import com.minecolonies.api.util.MessageUtils; import com.minecolonies.api.util.Tuple; import com.minecolonies.api.util.constant.Constants; @@ -23,7 +23,6 @@ import net.minecraft.world.item.ItemStack; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.items.wrapper.InvWrapper; import java.util.Collections; @@ -189,14 +188,9 @@ public void onServerResponseTriggered(final int responseId, final Player player, MessageUtils.format(MESSAGE_RECRUITMENT_SUCCESS, data.getName()).sendTo(colony).forAllPlayers(); } - try - { - MinecraftForge.EVENT_BUS.post(new CitizenAddedEvent(newCitizen, CitizenAddedEvent.Source.HIRED)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during CitizenAddedEvent", e); - } + IMinecoloniesAPI.getInstance() + .getEventBus() + .post(new CitizenAddedModEvent(newCitizen, CitizenAddedModEvent.CitizenAddedSource.HIRED)); } } else diff --git a/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java b/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java index 0ac81368971..5ab0edfc09c 100755 --- a/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java +++ b/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java @@ -1,5 +1,6 @@ package com.minecolonies.core.colony.managers; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.MinecoloniesAPIProxy; import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.ICitizenDataManager; @@ -7,12 +8,12 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.buildings.HiringMode; import com.minecolonies.api.colony.buildings.IBuilding; -import com.minecolonies.api.colony.citizens.event.CitizenAddedEvent; import com.minecolonies.api.colony.managers.interfaces.ICitizenManager; import com.minecolonies.api.entity.ModEntities; import com.minecolonies.api.entity.citizen.AbstractCivilianEntity; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.entity.citizen.happiness.IHappinessModifier; +import com.minecolonies.api.eventbus.events.colony.citizens.CitizenAddedModEvent; import com.minecolonies.api.util.*; import com.minecolonies.api.util.constant.CitizenConstants; import com.minecolonies.core.MineColonies; @@ -40,7 +41,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; -import net.minecraftforge.common.MinecraftForge; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -363,14 +363,7 @@ public ICitizenData resurrectCivilianData(@NotNull final CompoundTag compoundNBT citizens.put(citizenData.getId(), citizenData); spawnOrCreateCitizen(citizenData, world, spawnPos); - try - { - MinecraftForge.EVENT_BUS.post(new CitizenAddedEvent(citizenData, CitizenAddedEvent.Source.RESURRECTED)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during CitizenAddedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new CitizenAddedModEvent(citizenData, CitizenAddedModEvent.CitizenAddedSource.RESURRECTED)); return citizenData; } @@ -628,14 +621,7 @@ else if (femaleCount < (getCitizens().size() - 1) / 2.0) spawnOrCreateCivilian(newCitizen, colony.getWorld(), null, true); - try - { - MinecraftForge.EVENT_BUS.post(new CitizenAddedEvent(newCitizen, CitizenAddedEvent.Source.INITIAL)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during CitizenAddedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new CitizenAddedModEvent(newCitizen, CitizenAddedModEvent.CitizenAddedSource.INITIAL)); colony.getEventDescriptionManager().addEventDescription(new CitizenSpawnedEvent(colony.getBuildingManager().getTownHall().getPosition(), newCitizen.getName())); } diff --git a/src/main/java/com/minecolonies/core/commands/citizencommands/CommandCitizenSpawnNew.java b/src/main/java/com/minecolonies/core/commands/citizencommands/CommandCitizenSpawnNew.java index 0e8cddcbee6..0c587343a6b 100755 --- a/src/main/java/com/minecolonies/core/commands/citizencommands/CommandCitizenSpawnNew.java +++ b/src/main/java/com/minecolonies/core/commands/citizencommands/CommandCitizenSpawnNew.java @@ -1,10 +1,10 @@ package com.minecolonies.core.commands.citizencommands; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.IColonyManager; -import com.minecolonies.api.colony.citizens.event.CitizenAddedEvent; -import com.minecolonies.api.util.Log; +import com.minecolonies.api.eventbus.events.colony.citizens.CitizenAddedModEvent; import com.minecolonies.core.commands.commandTypes.IMCCommand; import com.minecolonies.core.commands.commandTypes.IMCOPCommand; import com.mojang.brigadier.arguments.IntegerArgumentType; @@ -12,7 +12,6 @@ import com.mojang.brigadier.context.CommandContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.chat.Component; -import net.minecraftforge.common.MinecraftForge; import static com.minecolonies.api.util.constant.translation.CommandTranslationConstants.COMMAND_CITIZEN_SPAWN_SUCCESS; import static com.minecolonies.api.util.constant.translation.CommandTranslationConstants.COMMAND_COLONY_ID_NOT_FOUND; @@ -43,14 +42,7 @@ public int onExecute(final CommandContext context) final ICitizenData newCitizen = colony.getCitizenManager().spawnOrCreateCivilian(null, colony.getWorld(), null, true); context.getSource().sendSuccess(() -> Component.translatable(COMMAND_CITIZEN_SPAWN_SUCCESS, newCitizen.getName()), true); - try - { - MinecraftForge.EVENT_BUS.post(new CitizenAddedEvent(newCitizen, CitizenAddedEvent.Source.COMMANDS)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during CitizenAddedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new CitizenAddedModEvent(newCitizen, CitizenAddedModEvent.CitizenAddedSource.COMMANDS)); return 1; } diff --git a/src/main/java/com/minecolonies/core/compatibility/journeymap/EventListener.java b/src/main/java/com/minecolonies/core/compatibility/journeymap/EventListener.java index 99e9e535223..7dc6a0e2fa6 100644 --- a/src/main/java/com/minecolonies/core/compatibility/journeymap/EventListener.java +++ b/src/main/java/com/minecolonies/core/compatibility/journeymap/EventListener.java @@ -1,8 +1,9 @@ package com.minecolonies.core.compatibility.journeymap; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.IColonyView; -import com.minecolonies.api.colony.event.ClientChunkUpdatedEvent; -import com.minecolonies.api.colony.event.ColonyViewUpdatedEvent; +import com.minecolonies.core.event.ClientChunkUpdatedEvent; +import com.minecolonies.api.eventbus.events.colony.ColonyViewUpdatedModEvent; import com.minecolonies.api.colony.jobs.IJob; import com.minecolonies.api.colony.jobs.registry.IJobRegistry; import com.minecolonies.api.colony.jobs.registry.JobEntry; @@ -50,6 +51,7 @@ public EventListener(@NotNull final Journeymap jmap) this.jmap = jmap; MinecraftForge.EVENT_BUS.register(this); + IMinecoloniesAPI.getInstance().getEventBus().subscribe(ColonyViewUpdatedModEvent.class, this::onColonyViewUpdated); } @SubscribeEvent @@ -80,8 +82,7 @@ public void onColonyChunkDataUpdated(@NotNull final ClientChunkUpdatedEvent even ColonyBorderMapping.updateChunk(this.jmap, dimension, event.getChunk()); } - @SubscribeEvent - public void onColonyViewUpdated(@NotNull final ColonyViewUpdatedEvent event) + public void onColonyViewUpdated(@NotNull final ColonyViewUpdatedModEvent event) { final IColonyView colony = event.getColony(); final Set graves = colony.getGraveManager().getGraves().keySet(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructureWithWorkOrder.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructureWithWorkOrder.java index 35133163f24..abbb1889014 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructureWithWorkOrder.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructureWithWorkOrder.java @@ -6,13 +6,14 @@ import com.ldtteam.structurize.placement.StructurePlacer; import com.ldtteam.structurize.util.BlockUtils; import com.ldtteam.structurize.util.PlacementSettings; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.buildings.IBuilding; -import com.minecolonies.api.colony.buildings.event.BuildingConstructionEvent; import com.minecolonies.api.colony.workorders.IWorkOrder; import com.minecolonies.api.colony.workorders.WorkOrderType; import com.minecolonies.api.crafting.ItemStorage; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; +import com.minecolonies.api.eventbus.events.colony.buildings.BuildingConstructionModEvent; import com.minecolonies.api.tileentities.AbstractTileEntityColonyBuilding; import com.minecolonies.api.util.*; import com.minecolonies.api.util.constant.Constants; @@ -31,7 +32,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.common.MinecraftForge; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -421,31 +421,24 @@ public void executeSpecificCompleteActions() job.complete(); - if (wo instanceof WorkOrderBuilding) + if (wo instanceof WorkOrderBuilding workOrderBuilding) { final IBuilding building = colony.getBuildingManager().getBuilding(wo.getLocation()); - try - { - MinecraftForge.EVENT_BUS.post(new BuildingConstructionEvent(building, BuildingConstructionEvent.EventType.fromWorkOrderType(wo.getWorkOrderType()))); - } - catch (final Exception e) + if (building == null) { - Log.getLogger().error("Error during BuildingConstructionEvent", e); + Log.getLogger() + .error("Builder ({}:{}) ERROR - Finished, but missing building({})", + worker.getCitizenColonyHandler().getColonyOrRegister().getID(), + worker.getCitizenData().getId(), + wo.getLocation()); } - switch (wo.getWorkOrderType()) + else { - case BUILD: - case UPGRADE: - case REPAIR: - if (building == null) - { - Log.getLogger().error(String.format("Builder (%d:%d) ERROR - Finished, but missing building(%s)", - worker.getCitizenColonyHandler().getColonyOrRegister().getID(), - worker.getCitizenData().getId(), - wo.getLocation())); - } - else - { + switch (wo.getWorkOrderType()) + { + case BUILD: + case UPGRADE: + case REPAIR: // Normally levels are done through the schematic data, but in case it is missing we do it manually here. final BlockEntity te = worker.level.getBlockEntity(building.getID()); if (te instanceof AbstractTileEntityColonyBuilding && ((IBlueprintDataProviderBE) te).getSchematicName().isEmpty()) @@ -453,21 +446,12 @@ public void executeSpecificCompleteActions() building.onUpgradeComplete(wo.getTargetLevel()); building.setBuildingLevel(wo.getTargetLevel()); } - } - break; - case REMOVE: - if (building == null) - { - Log.getLogger().error(String.format("Builder (%d:%d) ERROR - Finished, but missing building(%s)", - worker.getCitizenColonyHandler().getColonyOrRegister().getID(), - worker.getCitizenData().getId(), - wo.getLocation())); - } - else - { + break; + case REMOVE: building.setDeconstructed(); - } - break; + break; + } + IMinecoloniesAPI.getInstance().getEventBus().post(new BuildingConstructionModEvent(building, workOrderBuilding)); } } } diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index c1897d4e546..ccc43ca34b5 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -1,10 +1,10 @@ package com.minecolonies.core.entity.citizen; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.blocks.AbstractBlockHut; import com.minecolonies.api.colony.*; import com.minecolonies.api.colony.buildings.IGuardBuilding; import com.minecolonies.api.colony.buildings.registry.BuildingEntry; -import com.minecolonies.api.colony.citizens.event.CitizenRemovedEvent; import com.minecolonies.api.colony.jobs.IJob; import com.minecolonies.api.colony.permissions.Action; import com.minecolonies.api.colony.permissions.IPermissions; @@ -28,6 +28,8 @@ import com.minecolonies.api.entity.citizen.happiness.ExpirationBasedHappinessModifier; import com.minecolonies.api.entity.citizen.happiness.StaticHappinessSupplier; import com.minecolonies.api.entity.pathfinding.proxy.IWalkToProxy; +import com.minecolonies.api.eventbus.events.colony.citizens.CitizenDiedModEvent; +import com.minecolonies.api.eventbus.events.colony.citizens.CitizenRemovedModEvent; import com.minecolonies.api.inventory.InventoryCitizen; import com.minecolonies.api.inventory.container.ContainerCitizenInventory; import com.minecolonies.api.items.ModItems; @@ -101,7 +103,6 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.common.util.LazyOptional; @@ -1614,18 +1615,18 @@ public void die(@NotNull final DamageSource damageSource) Component.literal(damageSource.getLocalizedDeathMessage(this).getString()).getString().replaceFirst(this.getDisplayName().getString(), "Citizen"); citizenColonyHandler.getColonyOrRegister().getEventDescriptionManager().addEventDescription(new CitizenDiedEvent(blockPosition(), citizenData.getName(), deathCause)); - try - { - MinecraftForge.EVENT_BUS.post(new CitizenRemovedEvent(citizenData, damageSource)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during CitizenRemovedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new CitizenDiedModEvent(citizenData, damageSource)); } super.die(damageSource); } + @Override + public void remove(final @NotNull RemovalReason reason) + { + super.remove(reason); + IMinecoloniesAPI.getInstance().getEventBus().post(new CitizenRemovedModEvent(citizenData, reason)); + } + /** * Trigger the corresponding death achievement. * diff --git a/src/main/java/com/minecolonies/api/colony/event/ClientChunkUpdatedEvent.java b/src/main/java/com/minecolonies/core/event/ClientChunkUpdatedEvent.java similarity index 87% rename from src/main/java/com/minecolonies/api/colony/event/ClientChunkUpdatedEvent.java rename to src/main/java/com/minecolonies/core/event/ClientChunkUpdatedEvent.java index 742fce230ad..36429d48204 100644 --- a/src/main/java/com/minecolonies/api/colony/event/ClientChunkUpdatedEvent.java +++ b/src/main/java/com/minecolonies/core/event/ClientChunkUpdatedEvent.java @@ -1,35 +1,35 @@ -package com.minecolonies.api.colony.event; - -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraftforge.eventbus.api.Event; -import org.jetbrains.annotations.NotNull; - -/** - * This event is fired client-side after the colony chunk capabilities are synched to the player; - * i.e. there might be an update to which colony claims a particular chunk. This is fired even if - * no colony owns the chunk in question, as that may also be interesting; and even if the data did - * not actually change, as it might still be new to the listener. - */ -public class ClientChunkUpdatedEvent extends Event -{ - private final LevelChunk chunk; - - /** - * Constructs a chunk update event. - * - * @param chunk The chunk that was updated. - */ - public ClientChunkUpdatedEvent(@NotNull final LevelChunk chunk) - { - this.chunk = chunk; - } - - /** - * Gets the chunk related to the event. - */ - @NotNull - public LevelChunk getChunk() - { - return this.chunk; - } -} +package com.minecolonies.core.event; + +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraftforge.eventbus.api.Event; +import org.jetbrains.annotations.NotNull; + +/** + * This event is fired client-side after the colony chunk capabilities are synched to the player; + * i.e. there might be an update to which colony claims a particular chunk. This is fired even if + * no colony owns the chunk in question, as that may also be interesting; and even if the data did + * not actually change, as it might still be new to the listener. + */ +public final class ClientChunkUpdatedEvent extends Event +{ + private final LevelChunk chunk; + + /** + * Constructs a chunk update event. + * + * @param chunk The chunk that was updated. + */ + public ClientChunkUpdatedEvent(@NotNull final LevelChunk chunk) + { + this.chunk = chunk; + } + + /** + * Gets the chunk related to the event. + */ + @NotNull + public LevelChunk getChunk() + { + return this.chunk; + } +} diff --git a/src/main/java/com/minecolonies/core/network/messages/server/CreateColonyMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/CreateColonyMessage.java index 995c8bc45ab..4edf35ef90a 100755 --- a/src/main/java/com/minecolonies/core/network/messages/server/CreateColonyMessage.java +++ b/src/main/java/com/minecolonies/core/network/messages/server/CreateColonyMessage.java @@ -1,12 +1,12 @@ package com.minecolonies.core.network.messages.server; import com.ldtteam.structurize.storage.StructurePacks; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.IColonyManager; import com.minecolonies.api.colony.buildings.IBuilding; -import com.minecolonies.api.colony.event.ColonyCreatedEvent; +import com.minecolonies.api.eventbus.events.colony.ColonyCreatedModEvent; import com.minecolonies.api.network.IMessage; -import com.minecolonies.api.util.Log; import com.minecolonies.core.Network; import com.minecolonies.core.network.messages.client.colony.OpenBuildingUIMessage; import com.minecolonies.core.tileentities.TileEntityColonyBuilding; @@ -20,7 +20,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.network.NetworkEvent; import org.jetbrains.annotations.Nullable; @@ -188,16 +187,8 @@ else if (spawnDistance > MineColonies.getConfig().getServer().maxDistanceFromWor .sendTo(sender); } + IMinecoloniesAPI.getInstance().getEventBus().post(new ColonyCreatedModEvent(createdColony)); Network.getNetwork().sendToPlayer(new OpenBuildingUIMessage(building), sender); - - try - { - MinecraftForge.EVENT_BUS.post(new ColonyCreatedEvent(createdColony)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyCreatedEvent", e); - } return; } diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/ColonyFlagChangeMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/ColonyFlagChangeMessage.java index a127e6613d4..79b606c3375 100644 --- a/src/main/java/com/minecolonies/core/network/messages/server/colony/ColonyFlagChangeMessage.java +++ b/src/main/java/com/minecolonies/core/network/messages/server/colony/ColonyFlagChangeMessage.java @@ -1,14 +1,13 @@ package com.minecolonies.core.network.messages.server.colony; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.IColony; -import com.minecolonies.api.colony.event.ColonyInformationChangedEvent; -import com.minecolonies.api.util.Log; +import com.minecolonies.api.eventbus.events.colony.ColonyFlagChangedModEvent; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.network.messages.server.AbstractColonyServerMessage; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.network.NetworkEvent; import static com.minecolonies.api.util.constant.NbtTagConstants.TAG_BANNER_PATTERNS; @@ -18,18 +17,23 @@ */ public class ColonyFlagChangeMessage extends AbstractColonyServerMessage { - /** The chosen list of patterns from the window */ + /** + * The chosen list of patterns from the window + */ private ListTag patterns; - /** Default constructor **/ - public ColonyFlagChangeMessage () { super(); } + /** + * Default constructor + **/ + public ColonyFlagChangeMessage() {super();} /** * Spawn a new change message - * @param colony the colony the player changed the banner in + * + * @param colony the colony the player changed the banner in * @param patternList the list of patterns they set in the banner picker */ - public ColonyFlagChangeMessage (IColony colony, ListTag patternList) + public ColonyFlagChangeMessage(IColony colony, ListTag patternList) { super(colony); @@ -40,14 +44,7 @@ public ColonyFlagChangeMessage (IColony colony, ListTag patternList) protected void onExecute(NetworkEvent.Context ctxIn, boolean isLogicalServer, IColony colony) { colony.setColonyFlag(patterns); - try - { - MinecraftForge.EVENT_BUS.post(new ColonyInformationChangedEvent(colony, ColonyInformationChangedEvent.Type.FLAG)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyInformationChangedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new ColonyFlagChangedModEvent(colony)); } @Override @@ -63,6 +60,8 @@ protected void fromBytesOverride(FriendlyByteBuf buf) { CompoundTag nbt = buf.readNbt(); if (nbt != null) + { this.patterns = nbt.getList(TAG_BANNER_PATTERNS, Constants.TAG_COMPOUND); + } } } diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/TeamColonyColorChangeMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/TeamColonyColorChangeMessage.java index b54453ca333..afe5f860aa0 100755 --- a/src/main/java/com/minecolonies/core/network/messages/server/colony/TeamColonyColorChangeMessage.java +++ b/src/main/java/com/minecolonies/core/network/messages/server/colony/TeamColonyColorChangeMessage.java @@ -1,13 +1,12 @@ package com.minecolonies.core.network.messages.server.colony; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.buildings.views.IBuildingView; -import com.minecolonies.api.colony.event.ColonyInformationChangedEvent; -import com.minecolonies.api.util.Log; +import com.minecolonies.api.eventbus.events.colony.ColonyTeamColorChangedModEvent; import com.minecolonies.core.network.messages.server.AbstractColonyServerMessage; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.ChatFormatting; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.network.NetworkEvent; import org.jetbrains.annotations.NotNull; @@ -68,13 +67,6 @@ public void toBytesOverride(@NotNull final FriendlyByteBuf buf) protected void onExecute(final NetworkEvent.Context ctxIn, final boolean isLogicalServer, final IColony colony) { colony.setColonyColor(ChatFormatting.values()[colorOrdinal]); - try - { - MinecraftForge.EVENT_BUS.post(new ColonyInformationChangedEvent(colony, ColonyInformationChangedEvent.Type.TEAM_COLOR)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyInformationChangedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new ColonyTeamColorChangedModEvent(colony)); } } diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/TownHallRenameMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/TownHallRenameMessage.java index d2d94f7c951..19f83a57b06 100755 --- a/src/main/java/com/minecolonies/core/network/messages/server/colony/TownHallRenameMessage.java +++ b/src/main/java/com/minecolonies/core/network/messages/server/colony/TownHallRenameMessage.java @@ -1,18 +1,16 @@ package com.minecolonies.core.network.messages.server.colony; +import com.minecolonies.api.IMinecoloniesAPI; import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.IColonyView; -import com.minecolonies.api.colony.event.ColonyInformationChangedEvent; -import com.minecolonies.api.util.Log; -import com.minecolonies.core.Network; +import com.minecolonies.api.eventbus.events.colony.ColonyNameChangedModEvent; import com.minecolonies.core.network.messages.server.AbstractColonyServerMessage; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.network.NetworkEvent; import org.jetbrains.annotations.NotNull; /** - * Message to execute the renaiming of the townHall. + * Message to execute the renaming of the townHall. */ public class TownHallRenameMessage extends AbstractColonyServerMessage { @@ -57,13 +55,6 @@ protected void onExecute(final NetworkEvent.Context ctxIn, final boolean isLogic { name = (name.length() <= MAX_NAME_LENGTH) ? name : name.substring(0, SUBSTRING_LENGTH); colony.setName(name); - try - { - MinecraftForge.EVENT_BUS.post(new ColonyInformationChangedEvent(colony, ColonyInformationChangedEvent.Type.NAME)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyInformationChangedEvent", e); - } + IMinecoloniesAPI.getInstance().getEventBus().post(new ColonyNameChangedModEvent(colony)); } } diff --git a/src/main/java/com/minecolonies/core/placementhandlers/main/SurvivalHandler.java b/src/main/java/com/minecolonies/core/placementhandlers/main/SurvivalHandler.java index 45864dd6693..cdfdb66cb11 100644 --- a/src/main/java/com/minecolonies/core/placementhandlers/main/SurvivalHandler.java +++ b/src/main/java/com/minecolonies/core/placementhandlers/main/SurvivalHandler.java @@ -39,7 +39,9 @@ import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.event.entity.EntityAttributeCreationEvent; import net.minecraftforge.event.level.BlockEvent; +import net.minecraftforge.event.level.BlockEvent.EntityPlaceEvent; import net.minecraftforge.items.wrapper.InvWrapper; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/minecolonies/core/util/ChunkClientDataHelper.java b/src/main/java/com/minecolonies/core/util/ChunkClientDataHelper.java index f33f6a36099..d5d445efc9b 100755 --- a/src/main/java/com/minecolonies/core/util/ChunkClientDataHelper.java +++ b/src/main/java/com/minecolonies/core/util/ChunkClientDataHelper.java @@ -1,7 +1,7 @@ package com.minecolonies.core.util; import com.minecolonies.api.colony.IColonyTagCapability; -import com.minecolonies.api.colony.event.ClientChunkUpdatedEvent; +import com.minecolonies.core.event.ClientChunkUpdatedEvent; import com.minecolonies.api.util.ChunkCapData; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraftforge.common.MinecraftForge; From 5f82e615e64fb6e8ba5989b9e63082f0998f8468 Mon Sep 17 00:00:00 2001 From: Raycoms Date: Sun, 22 Dec 2024 13:50:01 +0100 Subject: [PATCH 32/33] Feature/world ships (#10541) Spawn Raider Ship structures in the world --- .../structures/MineColoniesStructures.java | 3 +- .../structures/ships/large_norse_ship.nbt | Bin 0 -> 72541 bytes .../structures/ships/large_pirate_ship.nbt | Bin 0 -> 108029 bytes .../structures/ships/medium_norse_ship.nbt | Bin 0 -> 37182 bytes .../structures/ships/medium_pirate_ship.nbt | Bin 0 -> 42276 bytes .../structures/ships/small_norse_ship.nbt | Bin 0 -> 8658 bytes .../structures/ships/small_pirate_ship.nbt | Bin 0 -> 8653 bytes .../worldgen/biome/has_structure/ship.json | 6 ++ .../placeholder_replacement.json | 44 +++++++++++++ .../minecolonies/worldgen/structure/ship.json | 16 +++++ .../worldgen/structure_set/ship.json | 14 ++++ .../worldgen/template_pool/ship_pool.json | 60 ++++++++++++++++++ 12 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/data/minecolonies/structures/ships/large_norse_ship.nbt create mode 100644 src/main/resources/data/minecolonies/structures/ships/large_pirate_ship.nbt create mode 100644 src/main/resources/data/minecolonies/structures/ships/medium_norse_ship.nbt create mode 100644 src/main/resources/data/minecolonies/structures/ships/medium_pirate_ship.nbt create mode 100644 src/main/resources/data/minecolonies/structures/ships/small_norse_ship.nbt create mode 100644 src/main/resources/data/minecolonies/structures/ships/small_pirate_ship.nbt create mode 100644 src/main/resources/data/minecolonies/tags/worldgen/biome/has_structure/ship.json create mode 100644 src/main/resources/data/minecolonies/worldgen/processor_list/placeholder_replacement.json create mode 100644 src/main/resources/data/minecolonies/worldgen/structure/ship.json create mode 100644 src/main/resources/data/minecolonies/worldgen/structure_set/ship.json create mode 100644 src/main/resources/data/minecolonies/worldgen/template_pool/ship_pool.json diff --git a/src/main/java/com/minecolonies/core/structures/MineColoniesStructures.java b/src/main/java/com/minecolonies/core/structures/MineColoniesStructures.java index ccc6fafb273..9cc16059b29 100644 --- a/src/main/java/com/minecolonies/core/structures/MineColoniesStructures.java +++ b/src/main/java/com/minecolonies/core/structures/MineColoniesStructures.java @@ -20,8 +20,7 @@ public class MineColoniesStructures public static final DeferredRegister> DEFERRED_REGISTRY_STRUCTURE = DeferredRegister.create(Registries.STRUCTURE_TYPE, Constants.MOD_ID); /** - * Registers the base structure itself and sets what its path is. In this case, - * this base structure will have the resourcelocation of structure_tutorial:sky_structures. + * Empty colony structure. */ public static final RegistryObject> EMPTY_COLONY = DEFERRED_REGISTRY_STRUCTURE.register("empty_colony", () -> () -> COLONY_CODEC); } diff --git a/src/main/resources/data/minecolonies/structures/ships/large_norse_ship.nbt b/src/main/resources/data/minecolonies/structures/ships/large_norse_ship.nbt new file mode 100644 index 0000000000000000000000000000000000000000..6b4e8812362e83cd4f6c2209c7b4599e5c1a10c2 GIT binary patch literal 72541 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 Dg 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/data/minecolonies/structures/ships/medium_pirate_ship.nbt b/src/main/resources/data/minecolonies/structures/ships/medium_pirate_ship.nbt new file mode 100644 index 0000000000000000000000000000000000000000..2d4be1dd6268b0279e1177b6e853743c1483fd56 GIT binary patch literal 42276 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/data/minecolonies/structures/ships/small_norse_ship.nbt b/src/main/resources/data/minecolonies/structures/ships/small_norse_ship.nbt new file mode 100644 index 0000000000000000000000000000000000000000..42593c5946fb8259674cc2915ec73f0ad204d0f4 GIT binary patch literal 8658 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 L`A6=BuU+#WXoBNy literal 0 HcmV?d00001 diff --git a/src/main/resources/data/minecolonies/tags/worldgen/biome/has_structure/ship.json b/src/main/resources/data/minecolonies/tags/worldgen/biome/has_structure/ship.json new file mode 100644 index 00000000000..b9aaf01eda3 --- /dev/null +++ b/src/main/resources/data/minecolonies/tags/worldgen/biome/has_structure/ship.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "#minecraft:is_ocean" + ] +} diff --git a/src/main/resources/data/minecolonies/worldgen/processor_list/placeholder_replacement.json b/src/main/resources/data/minecolonies/worldgen/processor_list/placeholder_replacement.json new file mode 100644 index 00000000000..36137bc0526 --- /dev/null +++ b/src/main/resources/data/minecolonies/worldgen/processor_list/placeholder_replacement.json @@ -0,0 +1,44 @@ +{ + "processors": [ + { + "blocks": [ + { + "Name": "structurize:blocksubstitution" + }, + { + "Name": "minecolonies:blockwaypoint" + } + ], + "processor_type": "minecraft:block_ignore" + }, + { + "rules": [ + { + "output_state": { + "Name": "minecraft:grass_block" + }, + "input_predicate": { + "block": "structurize:blocksolidsubstitution", + "predicate_type": "minecraft:block_match" + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + } + }, + { + "output_state": { + "Name": "minecraft:water" + }, + "input_predicate": { + "block": "structurize:blockfluidsubstitution", + "predicate_type": "minecraft:block_match" + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + } + } + ], + "processor_type": "minecraft:rule" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/minecolonies/worldgen/structure/ship.json b/src/main/resources/data/minecolonies/worldgen/structure/ship.json new file mode 100644 index 00000000000..401dece0425 --- /dev/null +++ b/src/main/resources/data/minecolonies/worldgen/structure/ship.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:jigsaw", + "biomes": "#minecolonies:has_structure/ship", + "adapt_noise": false, + "start_pool": "minecolonies:ship_pool", + "spawn_overrides": {}, + "size": 1, + "step": "surface_structures", + + "start_height": { + "absolute": -3 + }, + "project_start_to_heightmap": "WORLD_SURFACE_WG", + "max_distance_from_center": 16, + "use_expansion_hack": false +} diff --git a/src/main/resources/data/minecolonies/worldgen/structure_set/ship.json b/src/main/resources/data/minecolonies/worldgen/structure_set/ship.json new file mode 100644 index 00000000000..a9abff716ad --- /dev/null +++ b/src/main/resources/data/minecolonies/worldgen/structure_set/ship.json @@ -0,0 +1,14 @@ +{ + "structures": [ + { + "structure": "minecolonies:ship", + "weight": 1 + } + ], + "placement": { + "salt": 1225566777, + "spacing": 55, + "separation": 25, + "type": "minecraft:random_spread" + } +} \ No newline at end of file diff --git a/src/main/resources/data/minecolonies/worldgen/template_pool/ship_pool.json b/src/main/resources/data/minecolonies/worldgen/template_pool/ship_pool.json new file mode 100644 index 00000000000..73f5c34a460 --- /dev/null +++ b/src/main/resources/data/minecolonies/worldgen/template_pool/ship_pool.json @@ -0,0 +1,60 @@ +{ + "name": "minecolonies:start_pool", + "fallback": "minecraft:empty", + "elements": [ + { + "weight": 1, + "element": { + "location": "minecolonies:ships/large_pirate_ship", + "processors": "minecolonies:placeholder_replacement", + "projection": "rigid", + "element_type": "minecraft:single_pool_element" + } + }, + { + "weight": 1, + "element": { + "location": "minecolonies:ships/medium_pirate_ship", + "processors": "minecolonies:placeholder_replacement", + "projection": "rigid", + "element_type": "minecraft:single_pool_element" + } + }, + { + "weight": 1, + "element": { + "location": "minecolonies:ships/small_pirate_ship", + "processors": "minecolonies:placeholder_replacement", + "projection": "rigid", + "element_type": "minecraft:single_pool_element" + } + }, + { + "weight": 1, + "element": { + "location": "minecolonies:ships/large_norse_ship", + "processors": "minecolonies:placeholder_replacement", + "projection": "rigid", + "element_type": "minecraft:single_pool_element" + } + }, + { + "weight": 1, + "element": { + "location": "minecolonies:ships/medium_norse_ship", + "processors": "minecolonies:placeholder_replacement", + "projection": "rigid", + "element_type": "minecraft:single_pool_element" + } + }, + { + "weight": 1, + "element": { + "location": "minecolonies:ships/small_norse_ship", + "processors": "minecolonies:placeholder_replacement", + "projection": "rigid", + "element_type": "minecraft:single_pool_element" + } + } + ] +} From 7c1f25ecc1101044e29ee2e6a0d6eaea7a6dc8ef Mon Sep 17 00:00:00 2001 From: someaddons <38401808+someaddons@users.noreply.github.com> Date: Sun, 22 Dec 2024 14:00:54 +0100 Subject: [PATCH 33/33] Reworked AI to pathfinding link: (#10543) -AI now passes along more information about safe target locations and is using better fitting pathfinding tasks when going to buildings All pathfinding calls now return true on reaching their target, and false while walking unlike being mixed before All logic for creating pathing tasks is now consolidated in a dedicated util: EntityNavigationUtils, slimming down the Navigator class a bit. --- .../api/colony/buildings/IBuilding.java | 6 - .../entity/citizen/AbstractEntityCitizen.java | 17 -- .../minecolonies/api/util/BlockPosUtil.java | 27 -- .../minecolonies/api/util/EntityUtils.java | 58 +--- .../minecolonies/api/util/ItemStackUtils.java | 77 ----- .../minecolonies/core/colony/CitizenData.java | 4 +- .../colony/buildings/AbstractBuilding.java | 55 ---- .../pirateEvent/ShipBasedRaiderUtils.java | 2 +- .../core/entity/ai/combat/AttackMoveAI.java | 7 +- .../minimal/EntityAICitizenAvoidEntity.java | 13 +- .../ai/minimal/EntityAICitizenChild.java | 24 +- .../ai/minimal/EntityAICitizenWander.java | 12 +- .../entity/ai/minimal/EntityAIEatTask.java | 14 +- .../ai/minimal/EntityAIMournCitizen.java | 38 +-- .../entity/ai/minimal/EntityAISickTask.java | 26 +- .../core/entity/ai/minimal/EntityAISleep.java | 13 +- .../entity/ai/visitor/EntityAIVisitor.java | 22 +- .../ai/workers/AbstractEntityAIBasic.java | 95 ++++-- .../ai/workers/AbstractEntityAIInteract.java | 93 +----- .../ai/workers/AbstractEntityAIStructure.java | 11 +- .../workers/AbstractEntityAIUsesFurnace.java | 8 +- .../builder/EntityAIStructureBuilder.java | 4 +- .../crafting/AbstractEntityAICrafting.java | 7 +- .../AbstractEntityAIRequestSmelter.java | 10 +- .../crafting/EntityAIConcreteMixer.java | 16 +- .../crafting/EntityAIWorkAlchemist.java | 28 +- .../workers/crafting/EntityAIWorkCrusher.java | 11 +- .../workers/crafting/EntityAIWorkSifter.java | 10 +- .../ai/workers/education/EntityAIStudy.java | 5 +- .../workers/education/EntityAIWorkPupil.java | 27 +- .../education/EntityAIWorkResearcher.java | 5 +- .../education/EntityAIWorkTeacher.java | 8 +- .../workers/guard/AbstractEntityAIFight.java | 2 +- .../workers/guard/AbstractEntityAIGuard.java | 53 ++-- .../ai/workers/guard/DruidCombatAI.java | 17 +- .../ai/workers/guard/EntityAIDruid.java | 10 +- .../ai/workers/guard/EntityAIRanger.java | 6 +- .../ai/workers/guard/KnightCombatAI.java | 6 +- .../ai/workers/guard/RangerCombatAI.java | 3 +- .../training/AbstractEntityAITraining.java | 35 +-- .../training/EntityAICombatTraining.java | 13 +- .../workers/production/EntityAIQuarrier.java | 19 +- .../production/EntityAIStructureMiner.java | 23 +- .../production/EntityAIWorkLumberjack.java | 14 +- .../production/EntityAIWorkNether.java | 14 +- .../agriculture/EntityAIWorkBeekeeper.java | 12 +- .../agriculture/EntityAIWorkComposter.java | 10 +- .../agriculture/EntityAIWorkFarmer.java | 8 +- .../agriculture/EntityAIWorkFisherman.java | 8 +- .../agriculture/EntityAIWorkFlorist.java | 6 +- .../agriculture/EntityAIWorkPlanter.java | 7 +- .../herders/AbstractEntityAIHerder.java | 12 +- .../herders/EntityAIWorkCowboy.java | 4 +- .../ai/workers/service/EntityAIWorkCook.java | 4 +- .../service/EntityAIWorkDeliveryman.java | 41 ++- .../service/EntityAIWorkEnchanter.java | 24 +- .../workers/service/EntityAIWorkHealer.java | 19 +- .../service/EntityAIWorkUndertaker.java | 17 +- .../util/BuildingStructureHandler.java | 4 +- .../core/entity/citizen/EntityCitizen.java | 64 +--- .../core/entity/mobs/EntityMercenary.java | 5 +- .../core/entity/mobs/EntityMercenaryAI.java | 11 +- .../core/entity/mobs/aitasks/CampWalkAI.java | 59 +--- .../entity/mobs/aitasks/RaiderMeleeAI.java | 10 +- .../entity/mobs/aitasks/RaiderRangedAI.java | 5 +- .../entity/mobs/aitasks/RaiderWalkAI.java | 110 ++----- .../AbstractAdvancedPathNavigate.java | 42 ++- .../navigation/EntityNavigationUtils.java | 289 ++++++++++++++++++ .../MinecoloniesAdvancedPathNavigate.java | 163 ++++------ .../navigation/PathfindingAIHelper.java | 53 ---- .../navigation/PathingStuckHandler.java | 3 +- .../pathfinding/pathjobs/AbstractPathJob.java | 16 +- .../pathjobs/PathJobMoveAwayFromLocation.java | 15 + .../pathjobs/PathJobMoveCloseToXNearY.java | 17 +- .../pathjobs/PathJobMoveToLocation.java | 30 +- .../pathjobs/PathJobRandomPos.java | 38 ++- .../proxy/EntityCitizenWalkToProxy.java | 34 ++- .../core/entity/visitor/VisitorCitizen.java | 35 +-- .../core/util/TeleportHelper.java | 19 +- .../minecolonies/core/util/WorkerUtil.java | 40 +-- 80 files changed, 990 insertions(+), 1212 deletions(-) create mode 100644 src/main/java/com/minecolonies/core/entity/pathfinding/navigation/EntityNavigationUtils.java delete mode 100644 src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathfindingAIHelper.java diff --git a/src/main/java/com/minecolonies/api/colony/buildings/IBuilding.java b/src/main/java/com/minecolonies/api/colony/buildings/IBuilding.java index 2d2f76cb36d..283581306bd 100755 --- a/src/main/java/com/minecolonies/api/colony/buildings/IBuilding.java +++ b/src/main/java/com/minecolonies/api/colony/buildings/IBuilding.java @@ -506,10 +506,4 @@ default boolean canEat(final ItemStack stack) { return true; } - - /** - * Get the standing position for a building. - * @return the standing pos. - */ - BlockPos getStandingPosition(); } diff --git a/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java b/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java index 21b8b75c468..f7fbb28df07 100755 --- a/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java +++ b/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java @@ -14,7 +14,6 @@ import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickRateStateMachine; import com.minecolonies.api.entity.citizen.citizenhandlers.*; import com.minecolonies.api.entity.other.MinecoloniesMinecart; -import com.minecolonies.api.entity.pathfinding.proxy.IWalkToProxy; import com.minecolonies.api.entity.pathfinding.registry.IPathNavigateRegistry; import com.minecolonies.api.inventory.InventoryCitizen; import com.minecolonies.api.sounds.EventType; @@ -554,15 +553,6 @@ public boolean checkCanDropLoot() */ public abstract ILocation getLocation(); - /** - * Checks if a worker is at his working site. If he isn't, sets it's path to the location - * - * @param site the place where he should walk to - * @param range Range to check in - * @return True if worker is at site, otherwise false. - */ - public abstract boolean isWorkerAtSiteWithMove(@NotNull BlockPos site, int range); - /** * Getter for the citizendata. Tries to get it from the colony is the data is null. * @@ -593,13 +583,6 @@ public boolean checkCanDropLoot() */ public abstract void playMoveAwaySound(); - /** - * Get the path proxy of the citizen. - * - * @return the proxy. - */ - public abstract IWalkToProxy getProxy(); - /** * Decrease the saturation of the citizen for 1 action. */ diff --git a/src/main/java/com/minecolonies/api/util/BlockPosUtil.java b/src/main/java/com/minecolonies/api/util/BlockPosUtil.java index 6ec59aa69a1..eb0a466ef91 100755 --- a/src/main/java/com/minecolonies/api/util/BlockPosUtil.java +++ b/src/main/java/com/minecolonies/api/util/BlockPosUtil.java @@ -1,7 +1,6 @@ package com.minecolonies.api.util; import com.ldtteam.structurize.util.BlockUtils; -import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.util.constant.ColonyConstants; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -14,7 +13,6 @@ import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.Mob; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; @@ -667,31 +665,6 @@ public static boolean setBlock(@NotNull final Level worldIn, @NotNull final Bloc return worldIn.setBlock(coords, state, flag); } - /** - * @param living A living entity. - * @param destination chunk coordinates to check moving to. - * @return True when XYZ is found, an set moving to, otherwise false. - */ - public static boolean tryMoveBaseCitizenEntityToXYZ(@NotNull final AbstractEntityCitizen living, @NotNull final BlockPos destination) - { - if (!(living instanceof LivingEntity)) - { - return false; - } - - return EntityUtils.tryMoveLivingToXYZ(living, destination.getX(), destination.getY(), destination.getZ()); - } - - /** - * @param living A living entity. - * @param destination chunk coordinates to check moving to. - * @return True when XYZ is found, an set moving to, otherwise false. - */ - public static boolean tryMoveLivingToXYZ(@NotNull final Mob living, @NotNull final BlockPos destination) - { - return EntityUtils.tryMoveLivingToXYZ(living, destination.getX(), destination.getY(), destination.getZ()); - } - /** * Create a method for using a {@link BlockPos}. * diff --git a/src/main/java/com/minecolonies/api/util/EntityUtils.java b/src/main/java/com/minecolonies/api/util/EntityUtils.java index f162fb3c1cf..1ba6d630d9e 100755 --- a/src/main/java/com/minecolonies/api/util/EntityUtils.java +++ b/src/main/java/com/minecolonies/api/util/EntityUtils.java @@ -1,11 +1,11 @@ package com.minecolonies.api.util; import com.ldtteam.structurize.util.BlockUtils; -import com.minecolonies.api.crafting.ItemStorage; -import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; +import com.minecolonies.api.entity.other.AbstractFastMinecoloniesEntity; import com.minecolonies.api.items.ModTags; import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.SurfaceType; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.tags.BlockTags; @@ -17,7 +17,6 @@ import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; import net.minecraftforge.common.util.FakePlayer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -216,6 +215,7 @@ private static boolean checkValidSpawn(@NotNull final BlockGetter world, final B || SurfaceType.getSurfaceType(world, world.getBlockState(pos.below(2)), pos.below(2)) == SurfaceType.WALKABLE; } + // TODO: Move out movement stuff /** * Sets the movement of the entity to specific point. Returns true if direction is set, otherwise false. @@ -239,27 +239,15 @@ public static boolean tryMoveLivingToXYZ(@NotNull final Mob living, final int x, * @param y y-coordinate * @param z z-coordinate * @param speedFactor Speedfactor to modify base speed with - * @return True if the path is set to destination, otherwise false + * @return true if arrived */ public static boolean tryMoveLivingToXYZ(@NotNull final Mob living, final int x, final int y, final int z, final double speedFactor) { - return living.getNavigation().moveTo(x, y, z, speedFactor); - } - - /** - * {@link #isLivingAtSiteWithMove(LivingEntity, int, int, int)} - * - * @param entity entity to check - * @param x X-coordinate - * @param y Y-coordinate - * @param z Z-coordinate - * @return True if entity is at site, otherwise false - */ - public static boolean isLivingAtSiteWithMove(@NotNull final LivingEntity entity, final int x, final int y, final int z) - { - //Default range of 3 works better - //Range of 2 get some entitys stuck - return isLivingAtSiteWithMove(entity, x, y, z, DEFAULT_MOVE_RANGE); + if (living instanceof AbstractFastMinecoloniesEntity entity) + { + return EntityNavigationUtils.walkToPos(entity, new BlockPos(x, y, z), 4, true, speedFactor); + } + return true; } /** @@ -300,34 +288,6 @@ public static boolean isLivingAtSiteWithMove(@NotNull final LivingEntity entity, return EntityUtils.isLivingAtSite(entity, x, y, z, range); } - /** - * Checks if a certain entity is in the world at a certain position already. - * - * @param entity the entity. - * @param world the world. - * @param placer the entity to get the itemstacks from to check. - * @return true if there. - */ - public static boolean isEntityAtPosition(final Entity entity, final Level world, final Entity placer) - { - final List existingReq = ItemStackUtils.getListOfStackForEntity(entity, placer); - final BlockPos pos = BlockPos.containing(entity.getX(), entity.getY(), entity.getZ()); - return world.getEntitiesOfClass(Entity.class, new AABB(pos.offset(1, 1, 1), pos.offset(-1, -1, -1))) - .stream() - .anyMatch(ent -> ent.getX() == entity.getX() && ent.getY() == entity.getY() && ent.getZ() == entity.getZ() && ItemStackUtils.getListOfStackForEntity(entity, placer) - .equals(existingReq)); - } - - public static boolean isEntityAtPosition(final Entity entity, final Level world, final AbstractEntityCitizen entityCitizen) - { - if (entity != null) - { - return EntityUtils.isEntityAtPosition(entity, world, (Entity) entityCitizen); - } - - return false; - } - /** * Returns whether or not the entity is within a specific range of his working site. * diff --git a/src/main/java/com/minecolonies/api/util/ItemStackUtils.java b/src/main/java/com/minecolonies/api/util/ItemStackUtils.java index ee4283d2ce1..e3d25492cbe 100755 --- a/src/main/java/com/minecolonies/api/util/ItemStackUtils.java +++ b/src/main/java/com/minecolonies/api/util/ItemStackUtils.java @@ -1,6 +1,5 @@ package com.minecolonies.api.util; -import com.google.common.collect.Lists; import com.minecolonies.api.advancements.AdvancementTriggers; import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.IColony; @@ -27,14 +26,12 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.ItemTags; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.food.FoodProperties; import net.minecraft.world.item.*; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BrewingStandBlockEntity; import net.minecraft.world.level.block.entity.FurnaceBlockEntity; import net.minecraft.world.phys.EntityHitResult; @@ -140,80 +137,6 @@ private ItemStackUtils() */ } - /** - * Get the entity of an entityInfo object. - * - * @param entityData the input. - * @param world the world. - * @return the output object or null. - */ - @Nullable - public static Entity getEntityFromEntityInfoOrNull(final CompoundTag entityData, final Level world) - { - try - { - final Optional> type = EntityType.by(entityData); - if (type.isPresent()) - { - final Entity entity = type.get().create(world); - if (entity != null) - { - entity.load(entityData); - return entity; - } - } - } - catch (final RuntimeException e) - { - Log.getLogger().info("Couldn't restore entitiy", e); - return null; - } - return null; - } - - /** - * Adds entities to the builder building if he needs it. - * - * @param entityData the entity info object. - * @param world the world. - * @param placer the entity placer. - * @return a list of stacks. - */ - public static List getListOfStackForEntityInfo(final CompoundTag entityData, final Level world, final Entity placer) - { - if (entityData != null) - { - final Entity entity = getEntityFromEntityInfoOrNull(entityData, world); - if (entity != null) - { - if (EntityUtils.isEntityAtPosition(entity, world, placer)) - { - return Collections.emptyList(); - } - return getListOfStackForEntity(entity, placer); - } - } - return Collections.emptyList(); - } - - /** - * Adds entities to the builder building if he needs it. - * - * @param entityData the entity info object. - * @param world the world. - * @param placer the entity placer. - * @return a list of stacks. - */ - public static List getListOfStackForEntityInfo(final CompoundTag entityData, final Level world, final AbstractEntityCitizen placer) - { - if (placer != null) - { - return getListOfStackForEntityInfo(entityData, world, (Entity) placer); - } - - return Lists.newArrayList(); - } - /** * Adds entities to the builder building if he needs it. * diff --git a/src/main/java/com/minecolonies/core/colony/CitizenData.java b/src/main/java/com/minecolonies/core/colony/CitizenData.java index 6b41abd58f5..004359e3cb6 100755 --- a/src/main/java/com/minecolonies/core/colony/CitizenData.java +++ b/src/main/java/com/minecolonies/core/colony/CitizenData.java @@ -2016,7 +2016,7 @@ public BlockPos getHomePosition() @Nullable final IBuilding homeBuilding = getHomeBuilding(); if (homeBuilding != null) { - return homeBuilding.getStandingPosition(); + return homeBuilding.getPosition(); } if (colony != null) @@ -2024,7 +2024,7 @@ public BlockPos getHomePosition() final IBuilding tavern = colony.getBuildingManager().getFirstBuildingMatching(b -> b.getBuildingType() == ModBuildings.tavern.get()); if (tavern != null) { - return tavern.getStandingPosition(); + return tavern.getPosition(); } else if (colony.getBuildingManager().getTownHall() != null) { diff --git a/src/main/java/com/minecolonies/core/colony/buildings/AbstractBuilding.java b/src/main/java/com/minecolonies/core/colony/buildings/AbstractBuilding.java index f8f0345de2d..433e96bed50 100755 --- a/src/main/java/com/minecolonies/core/colony/buildings/AbstractBuilding.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/AbstractBuilding.java @@ -1046,61 +1046,6 @@ public void resetGuardBuildingNear() this.recheckGuardBuildingNear = true; } - @Override - public BlockPos getStandingPosition() - { - if (cachedStandingPosition == null) - { - if (!WorldUtil.isEntityBlockLoaded(colony.getWorld(), getPosition())) - { - return getPosition(); - } - - BlockPos bestPos = getPosition(); - int bestScore = 0; - - //Return true if the building is null to stall the worker - for (final Direction dir : Direction.Plane.HORIZONTAL) - { - final BlockPos currentPos = getPosition().relative(dir); - final BlockState hereState = colony.getWorld().getBlockState(currentPos); - // Check air here and air above. - if ((!hereState.getBlock().properties.hasCollision || hereState.is(BlockTags.WOOL_CARPETS)) - && !colony.getWorld().getBlockState(currentPos.above()).getBlock().properties.hasCollision - && BlockUtils.isAnySolid(colony.getWorld().getBlockState(currentPos.below()))) - { - int localScore = BEST_STANDING_SCORE; - if (colony.getWorld().canSeeSky(currentPos)) - { - // More critical - localScore-=2; - } - if (colony.getWorld().getBlockState(getPosition()).getValue(AbstractBlockHut.FACING) == dir) - { - // Less critical - localScore--; - } - - if (localScore == BEST_STANDING_SCORE) - { - cachedStandingPosition = currentPos; - return cachedStandingPosition; - } - - if (localScore > bestScore) - { - bestScore = localScore; - bestPos = currentPos; - } - } - } - - // prefer default rotation of the building facing this. - cachedStandingPosition = bestPos; - } - return cachedStandingPosition == null ? getPosition() : cachedStandingPosition; - } - //------------------------- Starting Required Tools/Item handling -------------------------// @Override diff --git a/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/ShipBasedRaiderUtils.java b/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/ShipBasedRaiderUtils.java index 40e0bdae836..fa5b70de9d7 100644 --- a/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/ShipBasedRaiderUtils.java +++ b/src/main/java/com/minecolonies/core/colony/events/raid/pirateEvent/ShipBasedRaiderUtils.java @@ -416,7 +416,7 @@ public static List createWaypoints(final Level world, final Path path, { final BlockPos point = path.getNode(i).asBlockPos(); if (lastPoint.distManhattan(point) > spacing - && world.getBlockState(point).isAir()) + && world.getBlockState(point).isAir() && world.getBlockState(point.above()).isAir()) { wayPoints.add(point); lastPoint = point; diff --git a/src/main/java/com/minecolonies/core/entity/ai/combat/AttackMoveAI.java b/src/main/java/com/minecolonies/core/entity/ai/combat/AttackMoveAI.java index 756d377fd8b..42e334fe814 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/combat/AttackMoveAI.java +++ b/src/main/java/com/minecolonies/core/entity/ai/combat/AttackMoveAI.java @@ -6,8 +6,10 @@ import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; +import com.minecolonies.api.entity.other.AbstractFastMinecoloniesEntity; import com.minecolonies.api.util.DamageSourceKeys; -import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; +import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.LivingEntity; @@ -211,6 +213,7 @@ protected int getAttackDelay() */ protected PathResult moveInAttackPosition(final LivingEntity target) { - return ((AbstractAdvancedPathNavigate) user.getNavigation()).moveToLivingEntity(target, 1d); + EntityNavigationUtils.walkToPos((AbstractFastMinecoloniesEntity) user, target.blockPosition(), 1, false); + return ((MinecoloniesAdvancedPathNavigate) user.getNavigation()).getPathResult(); } } diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenAvoidEntity.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenAvoidEntity.java index ef363b9d2c8..f1acde761b3 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenAvoidEntity.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenAvoidEntity.java @@ -5,9 +5,10 @@ import com.minecolonies.api.entity.ai.statemachine.states.CitizenAIState; import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import com.minecolonies.api.util.CompatibilityUtils; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; +import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -173,9 +174,11 @@ private boolean performMoveAway() { if ((moveAwayPath == null || !moveAwayPath.isInProgress()) && citizen.getNavigation().isDone()) { - moveAwayPath = - citizen.getNavigation() - .moveAwayFromXYZ(citizen.blockPosition().offset(rand.nextInt(2), 0, rand.nextInt(2)), distanceFromEntity + getMoveAwayDist(citizen), nearSpeed, true); + EntityNavigationUtils.walkAwayFrom(citizen, + citizen.blockPosition().offset(rand.nextInt(2), 0, rand.nextInt(2)), + (int) (distanceFromEntity + getMoveAwayDist(citizen)), + nearSpeed); + moveAwayPath = citizen.getNavigation().getPathResult(); return true; } return false; @@ -248,7 +251,7 @@ public void reset() safeTime = 0; if (startingPos != null) { - citizen.getNavigation().tryMoveToBlockPos(startingPos, 1); + EntityNavigationUtils.walkToPos(citizen, startingPos, 1, true); } closestLivingEntity = null; moveAwayPath = null; diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenChild.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenChild.java index 0c1d4fa9eb6..442f7936918 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenChild.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenChild.java @@ -1,5 +1,6 @@ package com.minecolonies.core.entity.ai.minimal; +import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.entity.ai.IStateAI; import com.minecolonies.api.entity.ai.statemachine.AIEventTarget; import com.minecolonies.api.entity.ai.statemachine.AITarget; @@ -8,11 +9,12 @@ import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.citizen.AbstractCivilianEntity; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import com.minecolonies.api.util.CompatibilityUtils; import com.minecolonies.api.util.MessageUtils; import com.minecolonies.core.colony.eventhooks.citizenEvents.CitizenGrownUpEvent; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; +import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -92,7 +94,7 @@ public boolean isOkayToEat() /** * The blockpos the child is visiting */ - private BlockPos visitHutPos; + private IBuilding visitingHut; /** * The path for visiting the hut @@ -195,13 +197,13 @@ private IState followingEntity() if (actionTimer <= 0 || followTarget.get() == null) { // run back to start position - child.getNavigation().moveToXYZ(followStart.getX(), followStart.getY(), followStart.getZ(), 1.0d); + EntityNavigationUtils.walkToPos(child, followStart, 2, true); setDelayForNextAction(); return CitizenAIState.IDLE; } - child.getNavigation().moveToLivingEntity(followTarget.get(), 1.0d); + EntityNavigationUtils.walkToPos(child, followTarget.get().blockPosition(), 2, false); return State.FOLLOWING; } @@ -216,7 +218,7 @@ private IState visitHuts() if (visitingPath == null && child.getCitizenColonyHandler().getColonyOrRegister() != null) { // Visiting huts for 3min. - if (actionTimer <= 0 && visitHutPos == null) + if (actionTimer <= 0 && visitingHut == null) { actionTimer = 3 * 60 * 20; } @@ -225,10 +227,11 @@ private IState visitHuts() index = rand.nextInt(index); - final List buildings = new ArrayList<>(child.getCitizenColonyHandler().getColonyOrRegister().getBuildingManager().getBuildings().keySet()); - visitHutPos = buildings.get(index); + final List buildings = new ArrayList<>(child.getCitizenColonyHandler().getColonyOrRegister().getBuildingManager().getBuildings().values()); + visitingHut = buildings.get(index); - visitingPath = child.getNavigation().moveToXYZ(visitHutPos.getX(), visitHutPos.getY(), visitHutPos.getZ(), 1.0d); + EntityNavigationUtils.walkToBuilding(child, visitingHut); + visitingPath = child.getNavigation().getPathResult(); } actionTimer -= 120; @@ -238,7 +241,8 @@ private IState visitHuts() // Path got interrupted by sth if (visitingPath != null && !visitingPath.isInProgress()) { - visitingPath = child.getNavigation().moveToXYZ(visitHutPos.getX(), visitHutPos.getY(), visitHutPos.getZ(), 1.0d); + EntityNavigationUtils.walkToBuilding(child, visitingHut); + visitingPath = child.getNavigation().getPathResult(); } return State.VISITING; @@ -246,7 +250,7 @@ private IState visitHuts() child.getNavigation().stop(); visitingPath = null; - visitHutPos = null; + visitingHut = null; setDelayForNextAction(); return CitizenAIState.IDLE; diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenWander.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenWander.java index 061fe362d9e..79db6c7b081 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenWander.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAICitizenWander.java @@ -10,6 +10,7 @@ import com.minecolonies.core.entity.ai.workers.education.EntityAIStudy; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.entity.other.SittingEntity; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.tileentities.TileEntityColonyBuilding; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.EquipmentSlot; @@ -92,7 +93,7 @@ private IState readABook() if (walkTo != null) { - if (!citizen.isWorkerAtSiteWithMove(walkTo, 3)) + if (!EntityNavigationUtils.walkToPos(citizen, walkTo, 3, true)) { return READ_A_BOOK; } @@ -129,7 +130,7 @@ private IState goToLeisureSite() return CitizenAIState.IDLE; } - if (!citizen.isWorkerAtSiteWithMove(leisureSite, 3)) + if (!EntityNavigationUtils.walkToPos(citizen, leisureSite, 3, true)) { return GO_TO_LEISURE_SITE; } @@ -146,7 +147,7 @@ private IState wanderAtLeisureSite() return CitizenAIState.IDLE; } - if (walkTo != null && !citizen.isWorkerAtSiteWithMove(walkTo, 3)) + if (walkTo != null && !EntityNavigationUtils.walkToPos(citizen, walkTo, 3, true)) { return WANDER_AT_LEISURE_SITE; } @@ -161,8 +162,7 @@ private IState wanderAtLeisureSite() { if (walkTo == null && citizen.getRandom().nextBoolean()) { - citizen.getNavigation() - .moveToRandomPos(10, DEFAULT_SPEED, ((IBlueprintDataProviderBE) blockEntity).getInWorldCorners()); + EntityNavigationUtils.walkToRandomPosWithin(citizen, 10, DEFAULT_SPEED, ((IBlueprintDataProviderBE) blockEntity).getInWorldCorners()); } if (walkTo == null && blockEntity instanceof TileEntityColonyBuilding && ((TileEntityColonyBuilding) blockEntity).getBuilding() instanceof BuildingLibrary && citizen.getRandom().nextInt(100) < 5) @@ -223,7 +223,7 @@ private IState decide() } } - citizen.getNavigation().moveToRandomPos(10, this.speed); + EntityNavigationUtils.walkToRandomPos(citizen, 10, this.speed); return CitizenAIState.IDLE; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIEatTask.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIEatTask.java index 93fdf5ed380..386509f1e22 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIEatTask.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIEatTask.java @@ -19,6 +19,7 @@ import com.minecolonies.core.colony.jobs.JobCook; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.entity.other.SittingEntity; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.network.messages.client.ItemParticleEffectMessage; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; @@ -49,11 +50,6 @@ public class EntityAIEatTask implements IStateAI */ private static final int MINUTES_WAITING_TIME = 2; - /** - * Min distance in blocks to placeToPath block. - */ - private static final int MIN_DISTANCE_TO_RESTAURANT = 2; - /** * Time required to eat in seconds. */ @@ -253,7 +249,7 @@ private EatingState getFoodYourself() final IBuilding cookBuilding = colony.getBuildingManager().getBuilding(restaurantPos); if (cookBuilding instanceof BuildingCook) { - if (!citizen.isWorkerAtSiteWithMove(cookBuilding.getPosition(), MIN_DISTANCE_TO_RESTAURANT)) + if (!EntityNavigationUtils.walkToBuilding(citizen, cookBuilding)) { return GET_FOOD_YOURSELF; } @@ -304,7 +300,7 @@ private EatingState goToEatingPlace() } } - if (citizen.isWorkerAtSiteWithMove(eatPos, 2)) + if (EntityNavigationUtils.walkToPos(citizen, eatPos, 2, true)) { SittingEntity.sitDown(eatPos, citizen, TICKS_SECOND * 60); // Delay till they start eating @@ -392,7 +388,7 @@ private EatingState goToHut() return SEARCH_RESTAURANT; } - if (citizen.isWorkerAtSiteWithMove(buildingWorker.getPosition(), MIN_DISTANCE_TO_RESTAURANT)) + if (EntityNavigationUtils.walkToBuilding(citizen, buildingWorker)) { final int slot = FoodUtils.getBestFoodForCitizen(citizen.getInventoryCitizen(), citizen.getCitizenData(), null); if (slot != -1) @@ -427,7 +423,7 @@ private EatingState goToRestaurant() { return WAIT_FOR_FOOD; } - else if (!citizen.isWorkerAtSiteWithMove(restaurantPos, MIN_DISTANCE_TO_RESTAURANT)) + else if (!EntityNavigationUtils.walkToBuilding(citizen, building)) { return GO_TO_RESTAURANT; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIMournCitizen.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIMournCitizen.java index e6170b11543..117343db263 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIMournCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAIMournCitizen.java @@ -6,7 +6,6 @@ import com.minecolonies.api.entity.ai.statemachine.states.CitizenAIState; import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; -import com.minecolonies.core.tileentities.TileEntityNamedGrave; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.MathUtils; import com.minecolonies.api.util.Tuple; @@ -14,6 +13,8 @@ import com.minecolonies.core.colony.buildings.modules.GraveyardManagementModule; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingGraveyard; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; +import com.minecolonies.core.tileentities.TileEntityNamedGrave; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.entity.Entity; @@ -71,7 +72,7 @@ public enum MourningState implements IState /** * The position of the graveyard. */ - private BlockPos graveyard; + private IBuilding graveyard; /** * Position of the grave to walk to. @@ -110,13 +111,13 @@ public EntityAIMournCitizen(final EntityCitizen citizen, final double speed) */ private IState walkToTownHall() { - final BlockPos pos = getMournLocation(); - if (pos == null) + final IBuilding building = getMournLocation(); + if (building == null) { return CitizenAIState.IDLE; } - if (!citizen.isWorkerAtSiteWithMove(pos, 3)) + if (!EntityNavigationUtils.walkToBuilding(citizen, building)) { return MourningState.WALKING_TO_TOWNHALL; } @@ -136,7 +137,7 @@ private IState walkToGraveyard() return MourningState.DECIDE; } - if (!citizen.isWorkerAtSiteWithMove(graveyard, 3)) + if (!EntityNavigationUtils.walkToBuilding(citizen, graveyard)) { return MourningState.WALKING_TO_GRAVEYARD; } @@ -157,13 +158,6 @@ private IState wanderAtGraveyard() return MourningState.DECIDE; } - final IBuilding graveyardBuilding = citizen.getCitizenColonyHandler().getColonyOrRegister().getBuildingManager().getBuilding(graveyard); - if (!(graveyardBuilding instanceof BuildingGraveyard)) - { - graveyard = null; - return MourningState.DECIDE; - } - if (!citizen.getNavigation().isDone()) { return MourningState.WANDER_AT_GRAVEYARD; @@ -172,12 +166,12 @@ private IState wanderAtGraveyard() // Wander around randomly. if (MathUtils.RANDOM.nextInt(100) < 90) { - citizen.getNavigation().moveToRandomPos(10, DEFAULT_SPEED, graveyardBuilding.getCorners()); + EntityNavigationUtils.walkToRandomPosWithin(citizen, 10, DEFAULT_SPEED, graveyard.getCorners()); return MourningState.WANDER_AT_GRAVEYARD; } // Try find the grave of one of the diseased. - final Set> gravePositions = ((BuildingGraveyard) graveyardBuilding).getGravePositions(); + final Set> gravePositions = ((BuildingGraveyard) graveyard).getGravePositions(); for (final Tuple gravePos : gravePositions) { if (WorldUtil.isBlockLoaded(citizen.level, gravePos.getA())) @@ -219,7 +213,7 @@ private IState walkToGrave() return MourningState.DECIDE; } - if (!citizen.isWorkerAtSiteWithMove(gravePos, 3)) + if (!EntityNavigationUtils.walkToPosInBuilding(citizen, gravePos, graveyard, 3)) { return MourningState.WALK_TO_GRAVE; } @@ -234,7 +228,7 @@ private IState walkToGrave() */ private IState wander() { - citizen.getNavigation().moveToRandomPos(10, this.speed); + EntityNavigationUtils.walkToRandomPos(citizen, 10, this.speed); return CitizenAIState.IDLE; } @@ -300,7 +294,7 @@ private IState decide() GraveyardManagementModule.class).hasRestingCitizen(citizen.getCitizenData().getCitizenMournHandler().getDeceasedCitizens())); if (graveyardBuilding != null) { - this.graveyard = graveyardBuilding.getPosition(); + this.graveyard = graveyardBuilding; } } @@ -312,7 +306,7 @@ private IState decide() citizen.getLookControl().setLookAt(citizen.getX(), citizen.getY() - 10, citizen.getZ(), (float) citizen.getMaxHeadYRot(), (float) citizen.getMaxHeadXRot()); - if (BlockPosUtil.getDistance2D(this.citizen.blockPosition(), getMournLocation()) > MIN_DESTINATION_TO_LOCATION) + if (getMournLocation() != null && BlockPosUtil.getDistance2D(this.citizen.blockPosition(), getMournLocation().getPosition()) > MIN_DESTINATION_TO_LOCATION) { return MourningState.WALKING_TO_TOWNHALL; } @@ -332,14 +326,14 @@ public void reset() * * @return blockPos of the location to mourn at */ - protected BlockPos getMournLocation() + protected IBuilding getMournLocation() { final IColony colony = citizen.getCitizenColonyHandler().getColonyOrRegister(); if (colony != null && colony.getBuildingManager().hasTownHall()) { - return colony.getBuildingManager().getTownHall().getStandingPosition(); + return colony.getBuildingManager().getTownHall(); } - return citizen.getCitizenData().getHomePosition(); + return citizen.getCitizenData().getHomeBuilding(); } } diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java index 842246b6eed..305db4e6bdd 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISickTask.java @@ -16,9 +16,9 @@ import com.minecolonies.core.Network; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingHospital; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; -import com.minecolonies.core.datalistener.DiseasesListener; import com.minecolonies.core.datalistener.model.Disease; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.network.messages.client.CircleParticleEffectMessage; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; @@ -113,7 +113,7 @@ public enum DiseaseState implements IState /** * Restaurant to which the citizen should path. */ - private BlockPos placeToPath; + private BlockPos bestHospital; /** * Instantiates this task. @@ -158,7 +158,7 @@ private boolean isSick() */ public DiseaseState wander() { - citizen.getNavigation().moveToRandomPos(10, 0.6D); + EntityNavigationUtils.walkToRandomPos(citizen, 10, 0.6D); return CHECK_FOR_CURE; } @@ -214,7 +214,7 @@ private DiseaseState findEmptyBed() } } - if (citizen.isWorkerAtSiteWithMove(usedBed, 3)) + if (EntityNavigationUtils.walkToPosInBuilding(citizen, usedBed, hospital, 3)) { waitingTicks++; if (!citizen.getCitizenSleepHandler().trySleep(usedBed)) @@ -318,9 +318,9 @@ private void cure() private IState waitForCure() { final IColony colony = citizenData.getColony(); - placeToPath = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class); + bestHospital = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class); - if (placeToPath == null) + if (bestHospital == null) { return SEARCH_HOSPITAL; } @@ -355,7 +355,7 @@ else if (state == CitizenAIState.IDLE) } } - if (!citizen.getCitizenSleepHandler().isAsleep() && BlockPosUtil.getDistance2D(placeToPath, citizen.blockPosition()) > MINIMUM_DISTANCE_TO_HOSPITAL) + if (!citizen.getCitizenSleepHandler().isAsleep() && BlockPosUtil.getDistance2D(bestHospital, citizen.blockPosition()) > MINIMUM_DISTANCE_TO_HOSPITAL) { return GO_TO_HOSPITAL; } @@ -383,7 +383,7 @@ private IState goToHut() return SEARCH_HOSPITAL; } - if (citizen.getCitizenSleepHandler().isAsleep() || citizen.isWorkerAtSiteWithMove(buildingWorker.getPosition(), MIN_DIST_TO_HUT)) + if (citizen.getCitizenSleepHandler().isAsleep() || EntityNavigationUtils.walkToBuilding(citizen, buildingWorker)) { return SEARCH_HOSPITAL; } @@ -398,12 +398,12 @@ private IState goToHut() private IState goToHospital() { citizen.getCitizenData().getCitizenDiseaseHandler().setSleepsAtHospital(false); - if (placeToPath == null) + if (bestHospital == null) { return SEARCH_HOSPITAL; } - if (citizen.getCitizenSleepHandler().isAsleep() || (citizen.getNavigation().isDone() && citizen.isWorkerAtSiteWithMove(placeToPath, MIN_DIST_TO_HOSPITAL))) + if (citizen.getCitizenSleepHandler().isAsleep() || EntityNavigationUtils.walkToPos(citizen, bestHospital, MIN_DIST_TO_HOSPITAL, true)) { return WAIT_FOR_CURE; } @@ -419,9 +419,9 @@ private IState searchHospital() { final IColony colony = citizenData.getColony(); final Disease disease = citizen.getCitizenData().getCitizenDiseaseHandler().getDisease(); - placeToPath = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class); + bestHospital = colony.getBuildingManager().getBestBuilding(citizen, BuildingHospital.class); - if (placeToPath == null) + if (bestHospital == null) { if (disease == null) { @@ -485,7 +485,7 @@ private void reset() citizen.releaseUsingItem(); citizen.stopUsingItem(); citizen.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); - placeToPath = null; + bestHospital = null; citizen.getCitizenData().getCitizenDiseaseHandler().setSleepsAtHospital(false); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISleep.java b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISleep.java index af02042cba1..a1d4c0fad8c 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISleep.java +++ b/src/main/java/com/minecolonies/core/entity/ai/minimal/EntityAISleep.java @@ -17,6 +17,7 @@ import com.minecolonies.core.colony.buildings.AbstractBuilding; import com.minecolonies.core.colony.buildings.modules.BuildingModules; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.network.messages.client.SleepingParticleMessage; import net.minecraft.core.BlockPos; import net.minecraft.tags.BlockTags; @@ -200,7 +201,7 @@ private void findBedAndTryToSleep() usedBed = homePos; } - if (citizen.isWorkerAtSiteWithMove(usedBed, 3)) + if (EntityNavigationUtils.walkToPosInBuilding(citizen, usedBed, citizen.getCitizenData().getHomeBuilding(), 5)) { bedTicks++; if (!citizen.getCitizenSleepHandler().trySleep(usedBed)) @@ -237,10 +238,14 @@ private IState sleep() */ private void goHome() { - final BlockPos pos = citizen.getCitizenData().getHomePosition(); - if (pos != null && !citizen.isWorkerAtSiteWithMove(pos, 2) && citizen.getPose() == Pose.SLEEPING) + final IBuilding home = citizen.getCitizenData().getHomeBuilding(); + if (home != null) { - citizen.setPose(Pose.STANDING); + EntityNavigationUtils.walkToBuilding(citizen, home); + } + else + { + EntityNavigationUtils.walkToPos(citizen, citizen.getCitizenData().getHomePosition(), 4, true); } final int chance = citizen.getRandom().nextInt(CHANCE); diff --git a/src/main/java/com/minecolonies/core/entity/ai/visitor/EntityAIVisitor.java b/src/main/java/com/minecolonies/core/entity/ai/visitor/EntityAIVisitor.java index 16195643d4a..bfa5502b4e3 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/visitor/EntityAIVisitor.java +++ b/src/main/java/com/minecolonies/core/entity/ai/visitor/EntityAIVisitor.java @@ -7,13 +7,13 @@ import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.util.DamageSourceKeys; -import com.minecolonies.api.util.Log; import com.minecolonies.api.util.WorldUtil; import com.minecolonies.core.colony.VisitorData; import com.minecolonies.core.colony.buildings.DefaultBuildingInstance; import com.minecolonies.core.colony.buildings.modules.BuildingModules; import com.minecolonies.core.colony.buildings.modules.TavernBuildingModule; import com.minecolonies.core.entity.other.SittingEntity; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.visitor.VisitorCitizen; import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionHand; @@ -121,7 +121,7 @@ private boolean doFight() return true; } - if (citizen.isWorkerAtSiteWithMove(target.blockPosition(), 2) && citizen.hasLineOfSight(target)) + if (EntityNavigationUtils.walkToPos(citizen, target.blockPosition(), 2, false) && citizen.hasLineOfSight(target)) { citizen.swing(InteractionHand.MAIN_HAND); target.hurt(target.level.damageSources().source(DamageSourceKeys.VISITOR), 10.0f); @@ -142,7 +142,7 @@ private boolean wander() return true; } - citizen.getNavigation().moveToRandomPos(10, 0.6D); + EntityNavigationUtils.walkToRandomPos(citizen, 10, 0.6D); return false; } @@ -175,14 +175,14 @@ private VisitorState decide() if (pos != null) { ((VisitorData) citizen.getCitizenData()).setSittingPosition(pos); - citizen.isWorkerAtSiteWithMove(pos, 1); + EntityNavigationUtils.walkToPosInBuilding(citizen, pos, tavern, 3); actionTimeoutCounter = citizen.getRandom().nextInt(2500) + 3000; return VisitorState.SITTING; } } else if (random == 2) { - citizen.getNavigation().moveToRandomPos(10, 0.6D); + EntityNavigationUtils.walkToRandomPos(citizen, 10, 0.6D); actionTimeoutCounter = citizen.getCitizenColonyHandler().getColonyOrRegister().isDay() ? citizen.getRandom().nextInt(1000) + 1000 : 300; return VisitorState.WANDERING; } @@ -209,7 +209,7 @@ private boolean sit() } final BlockPos moveTo = ((VisitorData) citizen.getCitizenData()).getSittingPosition(); - if (citizen.isWorkerAtSiteWithMove(moveTo, 1)) + if (EntityNavigationUtils.walkToPosInBuilding(citizen, moveTo, tavern, 3)) { SittingEntity.sitDown(moveTo, citizen, actionTimeoutCounter); } @@ -257,16 +257,6 @@ private Entity getTarget() return target; } - /** - * Handles any exceptions for this AI. - * - * @param e exception to handle - */ - private void onException(final RuntimeException e) - { - Log.getLogger().warn("Visitor AI of:" + citizen.getName() + " threw an Exception:", e); - } - /** * Resets saved data of internal logic */ diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIBasic.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIBasic.java index 3339c47103a..bcb5d82e677 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIBasic.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIBasic.java @@ -35,6 +35,7 @@ import com.minecolonies.core.colony.jobs.AbstractJob; import com.minecolonies.core.colony.jobs.JobDeliveryman; import com.minecolonies.core.colony.requestsystem.resolvers.StationRequestResolver; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.entity.pathfinding.proxy.EntityCitizenWalkToProxy; import com.minecolonies.core.tileentities.TileEntityRack; @@ -73,6 +74,7 @@ import static com.minecolonies.api.util.constant.TranslationConstants.COM_MINECOLONIES_COREMOD_ENTITY_WORKER_INVENTORYFULLCHEST; import static com.minecolonies.api.util.constant.TranslationConstants.WORKER_AI_EXCEPTION; import static com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract.RENDER_META_WORKING; +import static com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils.WOKR_IN_BUILDING_DIST; /** * This class provides basic ai functionality. @@ -278,13 +280,13 @@ public void setWalkTo(final BlockPos walkto) } /** - * Special walk state.. + * Only used for command-triggered walking * * @return IDLE once arrived. */ private IAIState walkToState() { - if (walkToBlock(walkTo, DEFAULT_RANGE_FOR_DELAY)) + if (!walkWithProxy(walkTo, DEFAULT_RANGE_FOR_DELAY)) { return getState(); } @@ -317,7 +319,7 @@ private IAIState getNeededItem() walkTo = pos; } - if (walkToBlock(walkTo) && pickUpCounter++ < PICKUP_ATTEMPTS) + if (!walkToWorkPos(walkTo) && pickUpCounter++ < PICKUP_ATTEMPTS) { return getState(); } @@ -599,7 +601,7 @@ private IAIState lookForRequests() } final ILocation pickupLocation = resolver instanceof StationRequestResolver ? resolver.getLocation() : building.getLocation(); - if (walkToBlock(pickupLocation.getInDimensionLocation()) || !WorldUtil.isBlockLoaded(world, pickupLocation.getInDimensionLocation())) + if (!walkToWorkPos(pickupLocation.getInDimensionLocation()) || !WorldUtil.isBlockLoaded(world, pickupLocation.getInDimensionLocation())) { return NEEDS_ITEM; } @@ -769,9 +771,9 @@ public int getTotalRequiredAmount(final ItemStack deliveredItemStack) } /** - * Walk the worker to it's building chest. Please return immediately if this returns true. + * Walk the worker to it's work building. * - * @return false if the worker is at his building + * @return true on arrival */ protected final boolean walkToBuilding() { @@ -780,13 +782,68 @@ protected final boolean walkToBuilding() { return true; } - final BlockPos standingPos = ownBuilding.getStandingPosition(); - int range = 2; - if (standingPos.equals(ownBuilding.getPosition())) + + return EntityNavigationUtils.walkToBuilding(worker, ownBuilding); + } + + /** + * Walk the worker to the given building. + * + * @return true while walking + */ + protected final boolean walkToWorkPos(final BlockPos pos) + { + if (pos == null) + { + return true; + } + + return EntityNavigationUtils.walkToPosInBuilding(worker, pos, building, WOKR_IN_BUILDING_DIST); + } + + /** + * Walk the worker to the given building. + * + * @return true while walking + */ + protected final boolean walkToBuilding(final IBuilding building) + { + if (building == null) { - range = 3; + return true; } - return walkToBlock(ownBuilding.getStandingPosition(), range); + + return EntityNavigationUtils.walkToBuilding(worker, building); + } + + /** + * Walk the worker to the safe position + * + * @return false while walking + */ + protected final boolean walkToSafePos(final BlockPos pos) + { + return EntityNavigationUtils.walkToPos(worker, pos, 4, true); + } + + /** + * Walk the worker to the unsafe position + * + * @return false while walking + */ + protected final boolean walkToUnSafePos(final BlockPos pos) + { + return EntityNavigationUtils.walkToPos(worker, pos, 4, false); + } + + /** + * Walk the worker to the unsafe position + * + * @return false while walking + */ + protected final boolean walkToUnSafePos(final BlockPos pos, final int distance) + { + return EntityNavigationUtils.walkToPos(worker, pos, distance, false); } /** @@ -820,9 +877,9 @@ public boolean checkAndTransferFromHut(@Nullable final ItemStack is) * @param stand where to walk to * @return true while walking to the block */ - protected final boolean walkToBlock(@NotNull final BlockPos stand) + protected final boolean walkWithProxy(@NotNull final BlockPos stand) { - return walkToBlock(stand, DEFAULT_RANGE_FOR_DELAY); + return walkWithProxy(stand, DEFAULT_RANGE_FOR_DELAY); } /** @@ -832,7 +889,7 @@ protected final boolean walkToBlock(@NotNull final BlockPos stand) * @param range how close we need to be * @return true while walking to the block */ - protected final boolean walkToBlock(@NotNull final BlockPos stand, final int range) + protected final boolean walkWithProxy(@NotNull final BlockPos stand, final int range) { if (proxy == null) { @@ -1019,7 +1076,7 @@ private boolean checkForNeededTool(@NotNull final EquipmentTypeEntry toolType, f } delay += DELAY_RECHECK; - return walkToBuilding() || !retrieveToolInHut(toolType, minimalLevel); + return !walkToBuilding() || !retrieveToolInHut(toolType, minimalLevel); } /** @@ -1092,7 +1149,7 @@ private IAIState dumpInventory() return afterDump(); } - if (!worker.isWorkerAtSiteWithMove(building.getPosition(), DEFAULT_RANGE_FOR_DELAY)) + if (!walkToBuilding()) { setDelay(WALK_DELAY); return INVENTORY_FULL; @@ -1171,7 +1228,7 @@ public IAIState afterDump() @SuppressWarnings("PMD.PrematureDeclaration") private boolean dumpOneMoreSlot() { - if (walkToBlock(getBuildingToDump().getPosition())) + if (!walkToWorkPos(getBuildingToDump().getPosition())) { return true; } @@ -1790,11 +1847,11 @@ private IAIState bePaused() final int percent = worker.getRandom().nextInt(ONE_HUNDRED_PERCENT); if (percent < VISIT_BUILDING_CHANCE) { - worker.getNavigation().tryMoveToBlockPos(building.getPosition(), worker.getRandom().nextBoolean() ? DEFAULT_SPEED * 1.5D : DEFAULT_SPEED * 2.2D); + walkToBuilding(); } else if (percent < WANDER_CHANCE) { - worker.getNavigation().moveToRandomPos(10, DEFAULT_SPEED); + EntityNavigationUtils.walkToRandomPos(worker, 10, DEFAULT_SPEED); } return null; diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java index b41d475743e..7def80efbdb 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIInteract.java @@ -8,8 +8,8 @@ import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.buildings.AbstractBuilding; import com.minecolonies.core.colony.jobs.AbstractJob; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.util.citizenutils.CitizenItemUtils; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; @@ -92,16 +92,6 @@ public abstract class AbstractEntityAIInteract, B ex @Nullable private List items; - /** - * The current path to the random position - */ - private PathResult pathResult; - - /** - * The backup factor of the path. - */ - protected int pathBackupFactor = 1; - /** * Block mining delay base */ @@ -297,7 +287,7 @@ private boolean checkMiningLocation(@NotNull final BlockPos blockToMine, @Nullab return true; } - if (safeStand != null && walkToBlock(safeStand) && MathUtils.twoDimDistance(worker.blockPosition(), safeStand) > MIN_WORKING_RANGE) + if (safeStand != null && walkWithProxy(safeStand) && MathUtils.twoDimDistance(worker.blockPosition(), safeStand) > MIN_WORKING_RANGE) { return true; } @@ -400,7 +390,7 @@ public void gatherItems() if (worker.getNavigation().isDone() || worker.getNavigation().getPath() == null) { final BlockPos pos = getAndRemoveClosestItemPosition(); - worker.isWorkerAtSiteWithMove(pos, ITEM_PICKUP_RANGE); + EntityNavigationUtils.walkToPos(worker, pos, 2, false); return; } @@ -449,83 +439,6 @@ private BlockPos getAndRemoveClosestItemPosition() return items.remove(index); } - /** - * Search for a random position to go to, anchored around the citizen. - * - * @param range the max range - * @return null until position was found. - */ - protected BlockPos findRandomPositionToWalkTo(final int range) - { - return findRandomPositionToWalkTo(range, worker.blockPosition()); - } - - /** - * Search for a random position to go to. - * - * @param range the max range - * @param pos position we want to find a random position around in the given range - * @return null until position was found. - */ - protected BlockPos findRandomPositionToWalkTo(final int range, final BlockPos pos) - { - if (pathResult == null) - { - pathBackupFactor = 1; - pathResult = getRandomNavigationPath(range, pos); - } - else if (pathResult.failedToReachDestination()) - { - pathBackupFactor++; - pathResult = getRandomNavigationPath(range * pathBackupFactor, pos); - } - - if (pathResult == null) - { - return null; - } - - if (pathResult.isPathReachingDestination()) - { - final BlockPos resultPos = pathResult.getPath().getEndNode().asBlockPos(); - pathResult = null; - return resultPos; - } - - if (pathResult.isCancelled()) - { - pathResult = null; - return null; - } - - if (pathBackupFactor > 10) - { - pathResult = null; - return null; - } - - return null; - } - - /** - * Get a navigator to find a certain position. - * - * @param range the max range. - * @param pos the position to - * @return the navigator. - */ - protected PathResult getRandomNavigationPath(final int range, final BlockPos pos) - { - if (pos == null || pos == worker.blockPosition()) - { - return worker.getNavigation().moveToRandomPos(range, 1.0D); - } - else - { - return worker.getNavigation().moveToRandomPosAroundX(range, 1.0D, pos); - } - } - /** * Reset the gathering items to null. */ diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructure.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructure.java index e7655f8f098..865d008019e 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructure.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIStructure.java @@ -323,16 +323,7 @@ public IAIState afterStructureLoading() * @param currentBlock the current block it is working on. * @return true while walking to the site. */ - public boolean walkToConstructionSite(final BlockPos currentBlock) - { - if (workFrom == null) - { - workFrom = getWorkingPosition(currentBlock); - } - - //The miner shouldn't search for a save position. Just let him build from where he currently is. - return worker.isWorkerAtSiteWithMove(workFrom, STANDARD_WORKING_RANGE) || MathUtils.twoDimDistance(worker.blockPosition(), workFrom) < MIN_WORKING_RANGE; - } + public abstract boolean walkToConstructionSite(final BlockPos currentBlock); /** * Checks for blocks that need to be treated as deco diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIUsesFurnace.java b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIUsesFurnace.java index 26b5928643a..5cbc15ae56f 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIUsesFurnace.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/AbstractEntityAIUsesFurnace.java @@ -180,7 +180,7 @@ protected BlockPos getPositionOfOvenToRetrieveFuelFrom() */ public IAIState startWorking() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } @@ -393,7 +393,7 @@ private IAIState retrieveSmeltableFromFurnace() return START_WORKING; } - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -426,7 +426,7 @@ private IAIState retrieveUsedFuel() return START_WORKING; } - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -468,7 +468,7 @@ private IAIState fillUpFurnace() return START_WORKING; } - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/builder/EntityAIStructureBuilder.java b/src/main/java/com/minecolonies/core/entity/ai/workers/builder/EntityAIStructureBuilder.java index 7df9cdf604c..b11111febda 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/builder/EntityAIStructureBuilder.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/builder/EntityAIStructureBuilder.java @@ -145,7 +145,7 @@ public boolean isAfterDumpPickupAllowed() private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } @@ -230,7 +230,7 @@ else if (gotoPath.isDone()) return false; } - if (walkToBlock(workFrom)) + if (!walkToSafePos(workFrom)) { return false; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAICrafting.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAICrafting.java index 106f0a28b63..1bfd8233c15 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAICrafting.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAICrafting.java @@ -24,6 +24,7 @@ import com.minecolonies.core.colony.jobs.AbstractJobCrafter; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.network.messages.client.BlockParticleEffectMessage; import com.minecolonies.core.network.messages.client.LocalizedParticleEffectMessage; @@ -147,7 +148,7 @@ protected IAIState decide() if (building.isInBuilding(worker.blockPosition()) && ColonyConstants.rand.nextInt(20) != 0) { setDelay(TICKS_20 * 20); - worker.getNavigation().moveToRandomPos(10, DEFAULT_SPEED, building.getCorners()); + EntityNavigationUtils.walkToRandomPosWithin(worker, 10, DEFAULT_SPEED, building.getCorners()); } else { @@ -162,7 +163,7 @@ protected IAIState decide() return IDLE; } - if (walkToBuilding()) + if (!walkToBuilding()) { return START_WORKING; } @@ -395,7 +396,7 @@ protected IAIState craft() return GET_RECIPE; } - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAIRequestSmelter.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAIRequestSmelter.java index 8763a043d8c..b28c743dbad 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAIRequestSmelter.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/AbstractEntityAIRequestSmelter.java @@ -378,7 +378,7 @@ private IAIState addFuelToFurnace() return START_WORKING; } - if (fuelPos == null || walkToBlock(fuelPos)) + if (fuelPos == null || !walkToWorkPos(fuelPos)) { return getState(); } @@ -533,7 +533,7 @@ private IAIState retrieveSmeltableFromFurnace() return START_WORKING; } - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -585,7 +585,7 @@ private IAIState retrieveUsedFuel() return START_WORKING; } - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -737,7 +737,7 @@ private IAIState fillUpFurnace() } if (toTransfer > 0) { - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -813,7 +813,7 @@ protected IAIState craft() possibleFuels.removeIf(stack -> ItemStackUtils.compareItemStacksIgnoreStackSize(stack, currentRecipeStorage.getCleanedInput().get(0).getItemStack())); } - if (walkToBuilding()) + if (!walkToBuilding()) { setDelay(AbstractEntityAIBasic.STANDARD_DELAY); return getState(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java index 0917133d94b..42f7b99c021 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIConcreteMixer.java @@ -8,12 +8,12 @@ import com.minecolonies.api.util.Tuple; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingConcreteMixer; import com.minecolonies.core.colony.jobs.JobConcreteMixer; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.ConcretePowderBlock; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; -import net.minecraft.core.Direction; -import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.ConcretePowderBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.common.capabilities.ForgeCapabilities; import org.jetbrains.annotations.NotNull; @@ -81,7 +81,7 @@ private IAIState placePowder() return START_WORKING; } - if (walkToBlock(posToPlace)) + if (!walkToWorkPos(posToPlace)) { return getState(); } @@ -110,7 +110,7 @@ private IAIState harvestConcrete() return START_WORKING; } - if (walkToBlock(posToMine)) + if (!walkToWorkPos(posToMine)) { return getState(); } @@ -171,7 +171,7 @@ protected IAIState decide() return performMixingWork(); } - if (walkTo == null && walkToBuilding()) + if (walkTo == null && !walkToBuilding()) { return START_WORKING; } @@ -209,7 +209,7 @@ protected IAIState craft() return GET_RECIPE; } - if (walkTo == null && walkToBuilding()) + if (walkTo == null && !walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkAlchemist.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkAlchemist.java index 918dc28a7bf..370b6e01885 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkAlchemist.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkAlchemist.java @@ -15,13 +15,17 @@ import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; import com.minecolonies.api.equipment.ModEquipmentTypes; import com.minecolonies.api.items.ModItems; -import com.minecolonies.api.util.*; +import com.minecolonies.api.util.InventoryUtils; +import com.minecolonies.api.util.ItemStackUtils; +import com.minecolonies.api.util.Tuple; +import com.minecolonies.api.util.WorldUtil; import com.minecolonies.core.Network; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingAlchemist; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobAlchemist; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.network.messages.client.BlockParticleEffectMessage; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundSource; @@ -150,7 +154,7 @@ else if (world.isEmptyBlock(randomSoil.above())) if (WorldUtil.isBlockLoaded(world, walkTo) && world.getBlockState(walkTo).getBlock() == Blocks.SOUL_SAND) { - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return HARVEST_NETHERWART; } @@ -240,7 +244,7 @@ private IAIState harvestMistleToe() if (WorldUtil.isBlockLoaded(world, walkTo) && world.getBlockState(walkTo).getBlock() instanceof LeavesBlock) { - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return HARVEST_MISTLETOE; } @@ -298,7 +302,7 @@ protected IAIState decide() if (building.isInBuilding(worker.blockPosition())) { setDelay(TICKS_20 * 20); - worker.getNavigation().moveToRandomPos(10, DEFAULT_SPEED, building.getCorners()); + EntityNavigationUtils.walkToRandomPosWithin(worker, 10, DEFAULT_SPEED, building.getCorners()); } else { @@ -308,7 +312,7 @@ protected IAIState decide() return IDLE; } - if (walkToBuilding()) + if (!walkToBuilding()) { return START_WORKING; } @@ -577,7 +581,7 @@ private IAIState addFuelToBrewingStand() return START_WORKING; } - if (fuelPos == null || walkToBlock(fuelPos)) + if (fuelPos == null || !walkToWorkPos(fuelPos)) { return getState(); } @@ -718,7 +722,7 @@ private IAIState retrieveBrewableFromBrewingStand() return START_WORKING; } - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -780,7 +784,7 @@ private IAIState retrieveUsedFuel() return START_WORKING; } - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -927,7 +931,7 @@ private IAIState fillUpBrewingStand() } if (toTransfer > 0) { - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -986,7 +990,7 @@ else if (isEmpty(((BrewingStandBlockEntity) entity).getItem(INGREDIENT_SLOT))) } if (toTransfer > 0) { - if (walkToBlock(walkTo)) + if (!walkToWorkPos(walkTo)) { return getState(); } @@ -1027,7 +1031,7 @@ else if (!(world.getBlockState(walkTo).getBlock() instanceof BrewingStandBlock)) @Override protected IAIState craft() { - if (walkToBuilding()) + if (!walkToBuilding()) { setDelay(STANDARD_DELAY); return getState(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkCrusher.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkCrusher.java index 6b27a8711f7..a446ed5be02 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkCrusher.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkCrusher.java @@ -6,14 +6,15 @@ import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.Network; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingCrusher; import com.minecolonies.core.colony.jobs.JobCrusher; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.network.messages.client.LocalizedParticleEffectMessage; import com.minecolonies.core.util.WorkerUtil; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.InteractionHand; @@ -78,7 +79,7 @@ protected IAIState decide() if (building.isInBuilding(worker.blockPosition())) { setDelay(TICKS_20 * 20); - worker.getNavigation().moveToRandomPos(10, DEFAULT_SPEED, building.getCorners()); + EntityNavigationUtils.walkToRandomPosWithin(worker, 10, DEFAULT_SPEED, building.getCorners()); } else { @@ -93,7 +94,7 @@ protected IAIState decide() return IDLE; } - if (walkToBuilding()) + if (!walkToBuilding()) { return START_WORKING; } @@ -114,7 +115,7 @@ protected IAIState decide() */ protected IAIState crush() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } @@ -211,7 +212,7 @@ protected IAIState craft() return GET_RECIPE; } - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkSifter.java b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkSifter.java index eea5cf424b5..74de7c4e32c 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkSifter.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/crafting/EntityAIWorkSifter.java @@ -13,14 +13,12 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingSifter; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobSifter; -import com.minecolonies.core.entity.ai.workers.crafting.AbstractEntityAICrafting; import com.minecolonies.core.network.messages.client.LocalizedParticleEffectMessage; import com.minecolonies.core.util.WorkerUtil; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.InteractionHand; -import net.minecraft.sounds.SoundEvents; import net.minecraft.network.chat.Component; - +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; @@ -104,7 +102,7 @@ protected IAIState sift() return IDLE; } - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java index dee2f982caa..e0b1715e773 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java @@ -12,7 +12,6 @@ import com.minecolonies.core.datalistener.StudyItemListener; import com.minecolonies.core.datalistener.StudyItemListener.StudyItem; import com.minecolonies.core.entity.ai.workers.AbstractEntityAISkill; -import com.minecolonies.core.entity.pathfinding.navigation.PathfindingAIHelper; import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.InteractionHand; @@ -107,7 +106,7 @@ private IAIState study() studyPos = building.getRandomBookShelf(); } - if (PathfindingAIHelper.walkCloseToXNearY(worker, studyPos, building.getPosition(), 7)) + if (!walkToWorkPos(studyPos)) { setDelay(WALK_DELAY); return getState(); @@ -185,7 +184,7 @@ private IAIState study() */ private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkPupil.java b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkPupil.java index e07ca0abfab..d5fe774e52e 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkPupil.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkPupil.java @@ -9,9 +9,10 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingSchool; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobPupil; -import com.minecolonies.core.entity.other.SittingEntity; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.other.SittingEntity; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.network.messages.client.CircleParticleEffectMessage; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; @@ -26,6 +27,7 @@ import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; import static com.minecolonies.api.research.util.ResearchConstants.TEACHING; +import static com.minecolonies.api.util.constant.Constants.DEFAULT_SPEED; import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND; import static com.minecolonies.api.util.constant.TranslationConstants.PUPIL_NO_CARPET; @@ -56,11 +58,6 @@ public class EntityAIWorkPupil extends AbstractEntityAIInteract getExpectedBuildingClass() */ private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkResearcher.java b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkResearcher.java index 976acb9d692..972e8aed1d1 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkResearcher.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkResearcher.java @@ -7,7 +7,6 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingUniversity; import com.minecolonies.core.colony.jobs.JobResearch; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; -import com.minecolonies.core.entity.pathfinding.navigation.PathfindingAIHelper; import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; import org.jetbrains.annotations.NotNull; @@ -68,7 +67,7 @@ private IAIState study() studyPos = building.getRandomBookShelf(); } - if (PathfindingAIHelper.walkCloseToXNearY(worker, studyPos, building.getPosition(), 7)) + if (!walkToWorkPos(studyPos)) { return getState(); } @@ -104,7 +103,7 @@ private IAIState study() */ private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkTeacher.java b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkTeacher.java index 9297ca57114..a9a204ad1a8 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkTeacher.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkTeacher.java @@ -13,11 +13,11 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingSchool; import com.minecolonies.core.colony.jobs.JobPupil; import com.minecolonies.core.colony.jobs.JobTeacher; -import com.minecolonies.core.entity.other.SittingEntity; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.entity.other.SittingEntity; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -118,7 +118,7 @@ private IAIState teach() } worker.getCitizenData().setVisibleStatus(TEACHING_ICON); - if (walkToBlock(pupilToTeach.blockPosition())) + if (!walkToWorkPos(pupilToTeach.blockPosition())) { return getState(); } @@ -202,7 +202,7 @@ public Class getExpectedBuildingClass() */ private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIFight.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIFight.java index b14f9d68051..8d0d52e346d 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIFight.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIFight.java @@ -90,7 +90,7 @@ public AbstractEntityAIFight(@NotNull final J job) */ protected IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIGuard.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIGuard.java index 3f201d91e46..83fae8e1ffc 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIGuard.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/AbstractEntityAIGuard.java @@ -5,7 +5,6 @@ import com.minecolonies.api.colony.IColonyManager; import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.colony.buildings.IGuardBuilding; -import com.minecolonies.api.colony.buildings.modules.ISettingsModule; import com.minecolonies.api.colony.jobs.ModJobs; import com.minecolonies.api.colony.permissions.Action; import com.minecolonies.api.colony.requestsystem.location.ILocation; @@ -23,14 +22,15 @@ import com.minecolonies.api.util.LookHandler; import com.minecolonies.core.Network; import com.minecolonies.core.colony.buildings.AbstractBuildingGuards; +import com.minecolonies.core.colony.buildings.modules.BuildingModules; import com.minecolonies.core.colony.buildings.modules.EntityListModule; -import com.minecolonies.core.colony.buildings.modules.MinerLevelManagementModule; import com.minecolonies.core.colony.buildings.modules.settings.GuardTaskSetting; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingMiner; import com.minecolonies.core.colony.jobs.AbstractJobGuard; import com.minecolonies.core.entity.ai.workers.util.MinerLevel; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.entity.other.SittingEntity; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.network.messages.client.SleepingParticleMessage; import com.minecolonies.core.util.TeleportHelper; import net.minecraft.core.BlockPos; @@ -49,7 +49,8 @@ import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; import static com.minecolonies.api.research.util.ResearchConstants.*; import static com.minecolonies.api.util.constant.Constants.*; -import static com.minecolonies.api.util.constant.GuardConstants.*; +import static com.minecolonies.api.util.constant.GuardConstants.GUARD_FOLLOW_LOSE_RANGE; +import static com.minecolonies.api.util.constant.GuardConstants.GUARD_FOLLOW_TIGHT_RANGE; import static com.minecolonies.core.colony.buildings.AbstractBuildingGuards.HOSTILE_LIST; /** @@ -249,7 +250,7 @@ private IAIState wakeUpGuard() // Move into range if (BlockPosUtil.getDistanceSquared(sleepingCitizen.blockPosition(), worker.blockPosition()) > 2.25) { - worker.getNavigation().moveToLivingEntity(sleepingCitizen, 1.0); + walkToUnSafePos(sleepingCitizen.blockPosition()); } else { @@ -402,7 +403,7 @@ private IAIState flee() } } - if (walkToBuilding()) + if (!walkToBuilding()) { return GUARD_FLEE; } @@ -426,7 +427,7 @@ private IAIState guard() */ public void guardMovement() { - worker.isWorkerAtSiteWithMove(buildingGuards.getGuardPos(), GUARD_POS_RANGE); + walkToSafePos(buildingGuards.getGuardPos()); } /** @@ -442,14 +443,7 @@ private IAIState follow() return null; } - if (buildingGuards.isTightGrouping()) - { - worker.isWorkerAtSiteWithMove(buildingGuards.getPositionToFollow(), GUARD_FOLLOW_TIGHT_RANGE); - } - else - { - worker.isWorkerAtSiteWithMove(buildingGuards.getPositionToFollow(), GUARD_FOLLOW_LOSE_RANGE); - } + walkToUnSafePos(buildingGuards.getPositionToFollow(), buildingGuards.isTightGrouping() ? GUARD_FOLLOW_TIGHT_RANGE : GUARD_FOLLOW_LOSE_RANGE); return null; } @@ -467,7 +461,7 @@ protected int getActionsDoneUntilDumping() private IAIState rally(final ILocation location) { final ICitizenData citizenData = worker.getCitizenData(); - if (!worker.isWorkerAtSiteWithMove(location.getInDimensionLocation() + if (!walkToUnSafePos(location.getInDimensionLocation() .offset(randomGenerator.nextInt(GUARD_FOLLOW_TIGHT_RANGE) - GUARD_FOLLOW_TIGHT_RANGE / 2, 0, randomGenerator.nextInt(GUARD_FOLLOW_TIGHT_RANGE) - GUARD_FOLLOW_TIGHT_RANGE / 2), @@ -508,20 +502,21 @@ public IAIState patrol() { if (buildingGuards.requiresManualTarget()) { - if (currentPatrolPoint == null || worker.isWorkerAtSiteWithMove(currentPatrolPoint, 3)) + if (currentPatrolPoint == null || walkToSafePos(currentPatrolPoint)) { - if (worker.getRandom().nextInt(5) <= 1) - { - currentPatrolPoint = buildingGuards.getColony().getBuildingManager().getRandomBuilding(b -> true); - } - else + currentPatrolPoint = null; + if (!EntityNavigationUtils.walkToRandomPos(worker, 20, 1.0)) { - currentPatrolPoint = findRandomPositionToWalkTo(20); + return getState(); } - if (currentPatrolPoint != null) + if (worker.getRandom().nextInt(5) <= 1) { - setNextPatrolTarget(currentPatrolPoint); + currentPatrolPoint = buildingGuards.getColony().getBuildingManager().getRandomBuilding(b -> true); + if (currentPatrolPoint != null) + { + walkToSafePos(currentPatrolPoint); + } } } } @@ -532,7 +527,7 @@ public IAIState patrol() currentPatrolPoint = buildingGuards.getNextPatrolTarget(false); } - if (currentPatrolPoint != null && (worker.isWorkerAtSiteWithMove(currentPatrolPoint, 3))) + if (currentPatrolPoint != null && (walkToSafePos(currentPatrolPoint))) { buildingGuards.arrivedAtPatrolPoint(worker); } @@ -551,7 +546,7 @@ public IAIState patrolMine() { return PREPARING; } - if (currentPatrolPoint == null || worker.isWorkerAtSiteWithMove(currentPatrolPoint, 2)) + if (currentPatrolPoint == null || walkToSafePos(currentPatrolPoint)) { final IBuilding building = buildingGuards.getColony().getBuildingManager().getBuilding(buildingGuards.getMinePos()); if (building != null) @@ -559,7 +554,7 @@ public IAIState patrolMine() if (building instanceof BuildingMiner) { final BuildingMiner buildingMiner = (BuildingMiner) building; - final MinerLevel level = buildingMiner.getFirstModuleOccurance(MinerLevelManagementModule.class).getCurrentLevel(); + final MinerLevel level = buildingMiner.getModule(BuildingModules.MINER_LEVELS).getCurrentLevel(); if (level == null) { setNextPatrolTarget(buildingMiner.getPosition()); @@ -571,12 +566,12 @@ public IAIState patrolMine() } else { - buildingGuards.getFirstModuleOccurance(ISettingsModule.class).getSetting(AbstractBuildingGuards.GUARD_TASK).set(GuardTaskSetting.PATROL); + buildingGuards.getModule(BuildingModules.GUARD_SETTINGS).getSetting(AbstractBuildingGuards.GUARD_TASK).set(GuardTaskSetting.PATROL); } } else { - buildingGuards.getFirstModuleOccurance(ISettingsModule.class).getSetting(AbstractBuildingGuards.GUARD_TASK).set(GuardTaskSetting.PATROL); + buildingGuards.getModule(BuildingModules.GUARD_SETTINGS).getSetting(AbstractBuildingGuards.GUARD_TASK).set(GuardTaskSetting.PATROL); } } return null; diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/DruidCombatAI.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/DruidCombatAI.java index 1dd075118c9..8e77268474f 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/DruidCombatAI.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/DruidCombatAI.java @@ -2,12 +2,9 @@ import com.google.common.collect.ImmutableList; import com.minecolonies.api.colony.guardtype.registry.ModGuardTypes; +import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; import com.minecolonies.api.entity.citizen.Skill; -import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity; -import com.minecolonies.core.entity.pathfinding.PathfindingUtils; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; -import com.minecolonies.core.entity.pathfinding.PathingOptions; import com.minecolonies.api.items.ModItems; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.InventoryUtils; @@ -15,11 +12,17 @@ import com.minecolonies.core.colony.buildings.modules.settings.GuardTaskSetting; import com.minecolonies.core.colony.jobs.AbstractJobGuard; import com.minecolonies.core.colony.jobs.JobDruid; -import com.minecolonies.core.entity.other.DruidPotionEntity; import com.minecolonies.core.entity.ai.combat.AttackMoveAI; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.other.DruidPotionEntity; +import com.minecolonies.core.entity.pathfinding.PathfindingUtils; +import com.minecolonies.core.entity.pathfinding.PathingOptions; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; -import com.minecolonies.core.entity.pathfinding.pathjobs.*; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobCanSee; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveAwayFromLocation; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveToLocation; +import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; @@ -114,7 +117,7 @@ protected void doAttack(final LivingEntity target) if (user.getRandom().nextInt(FLEE_CHANCE) == 0 && !((AbstractBuildingGuards) user.getCitizenData().getWorkBuilding()).getTask().equals(GuardTaskSetting.GUARD)) { - user.getNavigation().moveAwayFromLivingEntity(target, getAttackDistance() / 2.0, getCombatMovementSpeed()); + EntityNavigationUtils.walkAwayFrom(user, target.blockPosition(), (int) (getAttackDistance() / 2.0), getCombatMovementSpeed()); } } else diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/EntityAIDruid.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/EntityAIDruid.java index 2c84251e2ae..49f9606adbe 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/EntityAIDruid.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/EntityAIDruid.java @@ -1,6 +1,7 @@ package com.minecolonies.core.entity.ai.workers.guard; import com.minecolonies.api.items.ModItems; +import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.core.colony.buildings.AbstractBuildingGuards; import com.minecolonies.core.colony.jobs.JobDruid; @@ -67,16 +68,17 @@ public void guardMovement() { if (worker.getRandom().nextInt(3) < 1) { - worker.isWorkerAtSiteWithMove(buildingGuards.getGuardPos(), 3); + walkToSafePos(buildingGuards.getGuardPos()); return; } - if (worker.isWorkerAtSiteWithMove(buildingGuards.getGuardPos(), 10) || Math.abs(buildingGuards.getGuardPos().getY() - worker.blockPosition().getY()) > 3) + if ((BlockPosUtil.dist(buildingGuards.getGuardPos(), worker.blockPosition()) <= 10 || walkToSafePos(buildingGuards.getGuardPos())) + || Math.abs(buildingGuards.getGuardPos().getY() - worker.blockPosition().getY()) > 3) { // Moves the druid randomly to close edges, for better vision to mobs ((MinecoloniesAdvancedPathNavigate) worker.getNavigation()).setPathJob(new PathJobWalkRandomEdge(world, buildingGuards.getGuardPos(), 20, worker), - null, - 1.0, true); + null, + 1.0, true); } } } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/EntityAIRanger.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/EntityAIRanger.java index 1b0039eeeb6..3011b57aff8 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/EntityAIRanger.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/EntityAIRanger.java @@ -1,6 +1,7 @@ package com.minecolonies.core.entity.ai.workers.guard; import com.minecolonies.api.equipment.ModEquipmentTypes; +import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.core.colony.buildings.AbstractBuildingGuards; import com.minecolonies.core.colony.jobs.JobRanger; @@ -66,11 +67,12 @@ public void guardMovement() { if (worker.getRandom().nextInt(3) < 1) { - worker.isWorkerAtSiteWithMove(buildingGuards.getGuardPos(), 3); + walkToSafePos(buildingGuards.getGuardPos()); return; } - if (worker.isWorkerAtSiteWithMove(buildingGuards.getGuardPos(), 10) || Math.abs(buildingGuards.getGuardPos().getY() - worker.blockPosition().getY()) > 3) + if ((BlockPosUtil.dist(buildingGuards.getGuardPos(), worker.blockPosition()) <= 10 || walkToSafePos(buildingGuards.getGuardPos())) + || Math.abs(buildingGuards.getGuardPos().getY() - worker.blockPosition().getY()) > 3) { // Moves the ranger randomly to close edges, for better vision to mobs ((MinecoloniesAdvancedPathNavigate) worker.getNavigation()).setPathJob(new PathJobWalkRandomEdge(world, buildingGuards.getGuardPos(), 20, worker), diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/KnightCombatAI.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/KnightCombatAI.java index d0e720a0187..8cb0739ee49 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/KnightCombatAI.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/KnightCombatAI.java @@ -14,14 +14,15 @@ import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.api.util.constant.ColonyConstants; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.MineColonies; import com.minecolonies.core.colony.jobs.AbstractJobGuard; import com.minecolonies.core.entity.ai.combat.AttackMoveAI; import com.minecolonies.core.entity.ai.combat.CombatUtils; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.contents.TranslatableContents; @@ -302,7 +303,8 @@ protected int getAttackDelay() @Override protected PathResult moveInAttackPosition(final LivingEntity target) { - return user.getNavigation().moveToXYZ(target.getX(), target.getY(), target.getZ(), getCombatMovementSpeed()); + EntityNavigationUtils.walkToPos(user, target.blockPosition(), (int) getAttackDistance(), false, getCombatMovementSpeed()); + return user.getNavigation().getPathResult(); } /** diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java index a409be80f4a..ccd8aeff70a 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/RangerCombatAI.java @@ -20,6 +20,7 @@ import com.minecolonies.core.entity.other.CustomArrowEntity; import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.PathingOptions; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobCanSee; import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveAwayFromLocation; @@ -143,7 +144,7 @@ protected void doAttack(final LivingEntity target) if (user.getRandom().nextInt(FLEE_CHANCE) == 0 && !((AbstractBuildingGuards) user.getCitizenData().getWorkBuilding()).getTask().equals(GuardTaskSetting.GUARD)) { - user.getNavigation().moveAwayFromLivingEntity(target, getAttackDistance() / 2.0, getCombatMovementSpeed()); + EntityNavigationUtils.walkAwayFrom(user, target.blockPosition(), (int) (getAttackDistance() / 2.0), getCombatMovementSpeed()); } } else diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/AbstractEntityAITraining.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/AbstractEntityAITraining.java index a68094698f1..d21d8042f4b 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/AbstractEntityAITraining.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/AbstractEntityAITraining.java @@ -5,6 +5,7 @@ import com.minecolonies.core.colony.buildings.AbstractBuilding; import com.minecolonies.core.colony.jobs.AbstractJob; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import net.minecraft.core.BlockPos; import org.jetbrains.annotations.NotNull; @@ -93,19 +94,12 @@ public IAIState decide() */ private IAIState wander() { - if (currentPathingTarget == null) + if (!EntityNavigationUtils.walkToRandomPosWithin(worker, 20, 0.6, building.getCorners())) { - currentPathingTarget = getWanderPosition(); return getState(); } - if (!walkToBlock(currentPathingTarget)) - { - currentPathingTarget = null; - return DECIDE; - } - - return TRAINING_WANDER; + return DECIDE; } /** @@ -115,34 +109,13 @@ private IAIState wander() */ private IAIState pathToTarget() { - if (walkToBlock(currentPathingTarget, 2)) + if (!walkToWorkPos(currentPathingTarget)) { return getState(); } return stateAfterPathing; } - /** - * Get a wander position within the archer training camp to walk to. - * - * @return the position or the location of the hut chest if not found. - */ - private BlockPos getWanderPosition() - { - final BlockPos pos = findRandomPositionToWalkTo(20); - if (pos == null) - { - return null; - } - - if (building.isInBuilding(pos)) - { - return pos; - } - - return building.getPosition(); - } - /** * Reduces the attack delay by the given Tickrate */ diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAICombatTraining.java b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAICombatTraining.java index 4e98efbe600..bcf5fb04d47 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAICombatTraining.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/guard/training/EntityAICombatTraining.java @@ -10,12 +10,13 @@ import com.minecolonies.api.util.SoundUtils; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingCombatAcademy; import com.minecolonies.core.colony.jobs.JobCombatTraining; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.util.WorkerUtil; -import net.minecraft.world.item.Items; -import net.minecraft.world.InteractionHand; -import net.minecraft.sounds.SoundEvents; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.Items; import org.jetbrains.annotations.NotNull; import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; @@ -145,7 +146,7 @@ private IAIState trainWithPartner() return COMBAT_TRAINING; } - if (BlockPosUtil.getDistance2D(worker.blockPosition(), trainingPartner.blockPosition()) > MIN_DISTANCE_TO_TRAIN && walkToBlock(trainingPartner.blockPosition())) + if (BlockPosUtil.getDistance2D(worker.blockPosition(), trainingPartner.blockPosition()) > MIN_DISTANCE_TO_TRAIN && !walkToWorkPos(trainingPartner.blockPosition())) { return KNIGHT_TRAIN_WITH_PARTNER; } @@ -198,7 +199,7 @@ private IAIState attack() trainingPartner.hurt(world.damageSources().source(DamageSourceKeys.TRAINING, worker), 0.0F); CitizenItemUtils.damageItemInHand(worker, InteractionHand.MAIN_HAND, 1); } - worker.getNavigation().moveAwayFromXYZ(trainingPartner.blockPosition(), 4.0, 1.0, true); + EntityNavigationUtils.walkAwayFrom(worker, trainingPartner.blockPosition(), 4, 1.0); targetCounter++; if (targetCounter > building.getBuildingLevel() * ACTIONS_PER_BUILDING_LEVEL) diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIQuarrier.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIQuarrier.java index 9bb0748683b..0e2ab15e4cb 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIQuarrier.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIQuarrier.java @@ -16,7 +16,6 @@ import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; -import com.minecolonies.core.entity.ai.workers.util.LayerBlueprintIterator; import com.minecolonies.api.tileentities.AbstractTileEntityColonyBuilding; import com.minecolonies.api.util.*; import com.minecolonies.core.colony.buildings.AbstractBuildingStructureBuilder; @@ -27,7 +26,9 @@ import com.minecolonies.core.colony.workorders.WorkOrderMiner; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIStructureWithWorkOrder; import com.minecolonies.core.entity.ai.workers.util.BuildingStructureHandler; +import com.minecolonies.core.entity.ai.workers.util.LayerBlueprintIterator; import com.minecolonies.core.entity.ai.workers.util.WorkerLoadOnlyStructureHandler; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; @@ -123,7 +124,7 @@ private IAIState startWorkingAtOwnBuilding() return IDLE; } - if (walkToBlock(quarry.getPosition())) + if (!walkToBuilding(quarry)) { return getState(); } @@ -669,35 +670,29 @@ public boolean walkToConstructionSite(final BlockPos currentBlock) { if (workFrom == null) { - workFrom = findRandomPositionToWalkTo(5, currentBlock); - if (workFrom == null && pathBackupFactor > 10) + if (EntityNavigationUtils.walkToRandomPosAround(worker, currentBlock, 5, 1.0)) { workFrom = worker.blockPosition(); } return false; } - if (BlockPosUtil.getDistance(worker.blockPosition(), currentBlock) <= 5 + 5 * pathBackupFactor) + if (BlockPosUtil.getDistance(worker.blockPosition(), currentBlock) <= 5 + 5) { return true; } - if (walkToBlock(workFrom)) + if (!walkToSafePos(workFrom)) { return false; } - if (BlockPosUtil.getDistance(worker.blockPosition(), currentBlock) > 5 + 5 * pathBackupFactor) + if (BlockPosUtil.getDistance(worker.blockPosition(), currentBlock) > 5 + 5) { workFrom = null; return false; } - if (pathBackupFactor > 1) - { - pathBackupFactor--; - } - return true; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIStructureMiner.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIStructureMiner.java index ee298b7b719..c197e310a9d 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIStructureMiner.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIStructureMiner.java @@ -45,6 +45,8 @@ import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; import static com.minecolonies.api.research.util.ResearchConstants.MORE_ORES; +import static com.minecolonies.api.util.constant.CitizenConstants.MIN_WORKING_RANGE; +import static com.minecolonies.api.util.constant.CitizenConstants.STANDARD_WORKING_RANGE; import static com.minecolonies.api.util.constant.Constants.ONE_HUNDRED_PERCENT; import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND; import static com.minecolonies.api.util.constant.StatisticsConstants.*; @@ -173,7 +175,7 @@ public Class getExpectedBuildingClass() private IAIState startWorkingAtOwnBuilding() { worker.getCitizenData().setVisibleStatus(VisibleCitizenStatus.WORKING); - if ((building.getLadderLocation() == null || worker.getY() >= building.getPosition().getY()) && walkToBuilding()) + if ((building.getLadderLocation() == null || worker.getY() >= building.getPosition().getY()) && !walkToBuilding()) { return START_WORKING; } @@ -308,7 +310,7 @@ private BlockPos getSurroundingOreOrDefault(final BlockPos pos) @NotNull private IAIState goToLadder() { - if (walkToLadder()) + if (!walkToLadder()) { return MINER_WALKING_TO_LADDER; } @@ -317,7 +319,18 @@ private IAIState goToLadder() private boolean walkToLadder() { - return walkToBlock(building.getLadderLocation()); + return walkToWorkPos(building.getLadderLocation()); + } + + public boolean walkToConstructionSite(final BlockPos currentBlock) + { + if (workFrom == null) + { + workFrom = getWorkingPosition(currentBlock); + } + + //The miner shouldn't search for a save position. Just let him build from where he currently is. + return walkWithProxy(workFrom, STANDARD_WORKING_RANGE) || MathUtils.twoDimDistance(worker.blockPosition(), workFrom) < MIN_WORKING_RANGE; } @NotNull @@ -627,7 +640,7 @@ private BlockPos getNextBlockInShaftToMine() @NotNull private IAIState doShaftBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return MINER_BUILDING_SHAFT; } @@ -730,7 +743,7 @@ else if (vectorZ == 1) return MINER_MINING_SHAFT; } - if ((workingNode.getStatus() == MineNode.NodeStatus.AVAILABLE || workingNode.getStatus() == MineNode.NodeStatus.IN_PROGRESS) && !walkToBlock(standingPosition)) + if ((workingNode.getStatus() == MineNode.NodeStatus.AVAILABLE || workingNode.getStatus() == MineNode.NodeStatus.IN_PROGRESS) && !walkWithProxy(standingPosition)) { workingNode.setRot(rotation); return executeStructurePlacement(workingNode, standingPosition, rotation); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkLumberjack.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkLumberjack.java index 4ec4498d1b1..fb796961bf5 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkLumberjack.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkLumberjack.java @@ -5,8 +5,8 @@ import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; -import com.minecolonies.api.items.ModTags; import com.minecolonies.api.equipment.ModEquipmentTypes; +import com.minecolonies.api.items.ModTags; import com.minecolonies.api.util.*; import com.minecolonies.api.util.constant.ColonyConstants; import com.minecolonies.api.util.constant.Constants; @@ -17,13 +17,13 @@ import com.minecolonies.core.colony.jobs.JobLumberjack; import com.minecolonies.core.entity.ai.workers.crafting.AbstractEntityAICrafting; import com.minecolonies.core.entity.ai.workers.util.Tree; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveToWithPassable; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import com.minecolonies.core.entity.pathfinding.pathresults.TreePathResult; import com.minecolonies.core.util.WorkerUtil; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; @@ -223,7 +223,7 @@ protected IAIState decide() return getState(); } - if (walkToBuilding()) + if (!walkToBuilding()) { return START_WORKING; } @@ -268,7 +268,7 @@ private boolean isStackLog(@Nullable final ItemStack stack) */ private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } @@ -393,7 +393,7 @@ private IAIState findTree() final BlockPos endPos = building.getEndRestriction(); pathResult = worker.getNavigation() - .moveToTree(startPos, + .walkToTree(startPos, endPos, 1.0D, building.getModuleMatching(ItemListModule.class, m -> m.getId().equals(SAPLINGS_LIST)).getList(), @@ -403,7 +403,7 @@ private IAIState findTree() else { pathResult = worker.getNavigation() - .moveToTree(SEARCH_RANGE + searchIncrement, + .walkToTree(SEARCH_RANGE + searchIncrement, 1.0D, building.getModuleMatching(ItemListModule.class, m -> m.getId().equals(SAPLINGS_LIST)).getList(), building.getSetting(BuildingLumberjack.DYNAMIC_TREES_SIZE).getValue(), @@ -853,7 +853,7 @@ private boolean plantSapling(@NotNull final BlockPos location) worker.swing(worker.getUsedItemHand()); } - if (timeWaited >= MAX_WAITING_TIME / 2 && !checkedInHut && !walkToBuilding()) + if (timeWaited >= MAX_WAITING_TIME / 2 && !checkedInHut && walkToBuilding()) { checkAndTransferFromHut(job.getTree().getSapling()); checkedInHut = true; diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java index 66880efd086..3463229eae2 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/EntityAIWorkNether.java @@ -22,9 +22,9 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingNetherWorker; import com.minecolonies.core.colony.jobs.JobNetherWorker; import com.minecolonies.core.entity.ai.workers.crafting.AbstractEntityAICrafting; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.items.ItemAdventureToken; import com.minecolonies.core.util.TeleportHelper; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -308,7 +308,7 @@ protected IAIState decide() setDelay(120); return IDLE; } - if (walkTo != null || walkToBuilding()) + if (walkTo != null || !walkToBuilding()) { return getState(); } @@ -381,7 +381,7 @@ protected IAIState leaveForNether() final BlockState block = world.getBlockState(portal); if (block.is(Blocks.NETHER_PORTAL)) { - if (walkToBlock(portal, 1)) + if (!walkToWorkPos(portal)) { return getState(); } @@ -419,7 +419,7 @@ protected IAIState stayInNether() { //Ensure we stay put in the portal final BlockPos portal = building.getPortalLocation(); - if (portal != null && walkToBlock(portal, 1)) + if (portal != null && !walkToWorkPos(portal)) { return getState(); } @@ -689,7 +689,7 @@ protected IAIState returnFromNether() return NETHER_CLOSEPORTAL; } - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } @@ -710,7 +710,7 @@ protected IAIState openPortal() final BlockPos portal = building.getPortalLocation(); if (portal != null && currentRecipeStorage != null) { - if (walkToBlock(portal, 1)) + if (!walkToWorkPos(portal)) { return getState(); } @@ -744,7 +744,7 @@ protected IAIState closePortal() if (block.is(Blocks.NETHER_PORTAL)) { - if (walkToBlock(portal, 1)) + if (!walkToWorkPos(portal)) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkBeekeeper.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkBeekeeper.java index 03ea995a813..e761f268d43 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkBeekeeper.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkBeekeeper.java @@ -181,7 +181,7 @@ private IAIState prepareForHerding() */ private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { setDelay(2); return getState(); @@ -349,7 +349,7 @@ private IAIState harvestHoney() building.removeHive(hive); return PREPARING; } - if (walkToBlock(hive)) + if (!walkToWorkPos(hive)) { return getState(); } @@ -404,17 +404,17 @@ else if (!building.getHarvestTypes().equals(BuildingBeekeeper.HONEYCOMB) && item * Lets the herder walk to the animal. * * @param animal the animal to walk to. - * @return true if the herder is walking to the animal. + * @return false if the herder is walking to the animal. */ public boolean walkingToAnimal(final Animal animal) { if (animal != null) { - return walkToBlock(animal.blockPosition()); + return walkToWorkPos(animal.blockPosition()); } else { - return false; + return true; } } @@ -473,7 +473,7 @@ private void breedTwoAnimals(final Animal animalOne, final Animal animalTwo) for (final Animal animal : animalsToBreed) { - if (!animal.isInLove() && !walkingToAnimal(animal)) + if (!animal.isInLove() && walkingToAnimal(animal)) { animal.setInLove(null); worker.swing(InteractionHand.MAIN_HAND); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkComposter.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkComposter.java index a682e335406..a43cb5020d6 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkComposter.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkComposter.java @@ -17,8 +17,8 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingComposter; import com.minecolonies.core.colony.jobs.JobComposter; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.tileentities.TileEntityBarrel; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; @@ -135,7 +135,7 @@ private IAIState accelerateBarrels() */ private IAIState getMaterials() { - if (walkToBuilding()) + if (!walkToBuilding()) { setDelay(2); return getState(); @@ -201,7 +201,7 @@ private IAIState decideWhatToDo() { worker.getCitizenData().setVisibleStatus(VisibleCitizenStatus.WORKING); - if (walkToBuilding()) + if (!walkToBuilding()) { setDelay(2); return getState(); @@ -264,7 +264,7 @@ private IAIState fillBarrels() return GET_MATERIALS; } } - if (walkToBlock(currentTarget)) + if (!walkToWorkPos(currentTarget)) { setDelay(2); return getState(); @@ -295,7 +295,7 @@ private IAIState fillBarrels() private IAIState harvestBarrels() { - if (walkToBlock(currentTarget)) + if (!walkToWorkPos(currentTarget)) { setDelay(2); return getState(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFarmer.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFarmer.java index 87629b7ed48..6ccf8f363c1 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFarmer.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFarmer.java @@ -29,10 +29,10 @@ import com.minecolonies.core.colony.interactionhandling.StandardInteraction; import com.minecolonies.core.colony.jobs.JobFarmer; import com.minecolonies.core.entity.ai.workers.crafting.AbstractEntityAICrafting; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.items.ItemCrop; import com.minecolonies.core.network.messages.client.CompostParticleMessage; import com.minecolonies.core.util.AdvancementUtils; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.NonNullList; @@ -66,8 +66,8 @@ import static com.minecolonies.api.util.constant.CitizenConstants.BLOCK_BREAK_SOUND_RANGE; import static com.minecolonies.api.util.constant.Constants.STACKSIZE; import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND; -import static com.minecolonies.api.util.constant.StatisticsConstants.*; import static com.minecolonies.api.util.constant.EquipmentLevelConstants.TOOL_LEVEL_WOOD_OR_GOLD; +import static com.minecolonies.api.util.constant.StatisticsConstants.*; import static com.minecolonies.api.util.constant.TranslationConstants.NO_FREE_FIELDS; import static com.minecolonies.core.colony.buildings.modules.BuildingModules.STATS_MODULE; @@ -338,7 +338,7 @@ private IAIState canGoPlanting(@NotNull final FarmField farmField) return FARMER_PLANT; } - if (walkToBuilding()) + if (!walkToBuilding()) { return PREPARING; } @@ -520,7 +520,7 @@ private IAIState workAtField() final BlockPos position = farmField.getPosition().below().south(workingOffset.getZ()).east(workingOffset.getX()); // Still moving to the block - if (walkToBlock(position.above())) + if (!walkToSafePos(position.above())) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFisherman.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFisherman.java index a0583a3e8b0..70f079498eb 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFisherman.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFisherman.java @@ -15,13 +15,13 @@ import com.minecolonies.core.colony.jobs.JobFisherman; import com.minecolonies.core.entity.ai.workers.AbstractEntityAISkill; import com.minecolonies.core.entity.citizen.EntityCitizen; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.entity.other.NewBobberEntity; import com.minecolonies.core.entity.pathfinding.Pathfinding; import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobFindWater; import com.minecolonies.core.entity.pathfinding.pathresults.WaterPathResult; import com.minecolonies.core.util.WorkerUtil; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -182,7 +182,7 @@ public Class getExpectedBuildingClass() */ private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } @@ -274,7 +274,7 @@ private IAIState getToWater() return FISHERMAN_SEARCHING_WATER; } - if (walkToWater()) + if (!walkToWater()) { return getState(); } @@ -288,7 +288,7 @@ private IAIState getToWater() */ private boolean walkToWater() { - return job.getWater() != null && walkToBlock(job.getWater().getB()); + return job.getWater() != null && walkToSafePos(job.getWater().getB()); } /** diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFlorist.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFlorist.java index 38e1a228736..90fa4310d4f 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFlorist.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkFlorist.java @@ -153,7 +153,7 @@ private IAIState decide() worker.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); final long distance = BlockPosUtil.getDistance2D(worker.blockPosition(), building.getPosition()); - if (distance > MAX_DISTANCE && walkToBuilding()) + if (distance > MAX_DISTANCE && !walkToBuilding()) { return DECIDE; } @@ -209,7 +209,7 @@ private IAIState compost() worker.getCitizenData().setVisibleStatus(GARDENING); - if (walkToBlock(compostPosition)) + if (!walkToWorkPos(compostPosition)) { return getState(); } @@ -251,7 +251,7 @@ private IAIState harvest() worker.getCitizenData().setVisibleStatus(GARDENING); - if (walkToBlock(harvestPosition)) + if (!walkToWorkPos(harvestPosition)) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkPlanter.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkPlanter.java index b82f2a25693..6acda120ba6 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkPlanter.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/agriculture/EntityAIWorkPlanter.java @@ -14,7 +14,6 @@ import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.api.util.Tuple; -import com.minecolonies.api.util.constant.CitizenConstants; import com.minecolonies.api.util.constant.TypeConstants; import com.minecolonies.api.util.constant.translation.RequestSystemTranslationConstants; import com.minecolonies.core.colony.buildings.modules.FieldsModule; @@ -166,7 +165,7 @@ private IAIState moveToField() return PLANTATION_PICK_FIELD; } - if (walkToBlock(currentPlantationField.getPosition(), CitizenConstants.DEFAULT_RANGE_FOR_DELAY)) + if (!walkToSafePos(currentPlantationField.getPosition())) { return getState(); } @@ -208,7 +207,7 @@ private IAIState decideFieldWork() private IAIState workField() { IPlantationModule planterModule = activeModuleResult.getModule(); - if (!Objects.isNull(activeModuleResult.getActionPosition()) && walkToBlock(planterModule.getPositionToWalkTo(world, activeModuleResult.getActionPosition()))) + if (!Objects.isNull(activeModuleResult.getActionPosition()) && !walkToSafePos(planterModule.getPositionToWalkTo(world, activeModuleResult.getActionPosition()))) { return PLANTATION_WORK_FIELD; } @@ -263,7 +262,7 @@ else if (handlerResult.equals(ActionHandlerResult.NEEDS_ITEM)) */ private IAIState returnToBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/AbstractEntityAIHerder.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/AbstractEntityAIHerder.java index 081e0c32970..ad5785b9975 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/AbstractEntityAIHerder.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/AbstractEntityAIHerder.java @@ -33,8 +33,8 @@ import static com.minecolonies.api.entity.ai.statemachine.states.AIWorkerState.*; import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND; -import static com.minecolonies.api.util.constant.StatisticsConstants.ITEM_USED; import static com.minecolonies.api.util.constant.EquipmentLevelConstants.TOOL_LEVEL_WOOD_OR_GOLD; +import static com.minecolonies.api.util.constant.StatisticsConstants.ITEM_USED; import static com.minecolonies.core.colony.buildings.modules.BuildingModules.STATS_MODULE; /** @@ -280,7 +280,7 @@ protected boolean canBreedChildren() */ private IAIState startWorkingAtOwnBuilding() { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } @@ -567,7 +567,7 @@ private IAIState pickupItems() { final List items = searchForItemsInArea(); - if (!items.isEmpty() && walkToBlock(items.get(0).blockPosition(), 1)) + if (!items.isEmpty() && walkWithProxy(items.get(0).blockPosition(), 1)) { return getState(); } @@ -613,11 +613,11 @@ public boolean walkingToAnimal(final Animal animal) { if (animal != null) { - return walkToBlock(animal.blockPosition()); + return walkToWorkPos(animal.blockPosition()); } else { - return false; + return true; } } @@ -635,7 +635,7 @@ private boolean breedTwoAnimals() { it.remove(); } - else if (walkingToAnimal(animal)) + else if (!walkingToAnimal(animal)) { break; } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkCowboy.java b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkCowboy.java index 72350cf0f3b..afdeed0b28b 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkCowboy.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/production/herders/EntityAIWorkCowboy.java @@ -146,7 +146,7 @@ private IAIState milkCows() if (!worker.getCitizenInventoryHandler().hasItemInInventory(building.getMilkInputItem().getItem())) { if (InventoryUtils.hasBuildingEnoughElseCount(building, new ItemStorage(building.getMilkInputItem()), 1) > 0 - && !walkToBuilding()) + && walkToBuilding()) { checkAndTransferFromHut(building.getMilkInputItem()); } @@ -196,7 +196,7 @@ private IAIState milkMooshrooms() if (!worker.getCitizenInventoryHandler().hasItemInInventory(Items.BOWL)) { if (InventoryUtils.hasBuildingEnoughElseCount(building, new ItemStorage(new ItemStack(Items.BOWL, 1)), 1) > 0 - && !walkToBuilding()) + && walkToBuilding()) { checkAndTransferFromHut(new ItemStack(Items.BOWL, 1)); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkCook.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkCook.java index cb3b58424e0..5bae5217766 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkCook.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkCook.java @@ -172,7 +172,7 @@ private IAIState serveFoodToCitizen() return getState(); } - if (walkToBlock(citizenToServe.peek().blockPosition())) + if (!walkToWorkPos(citizenToServe.peek().blockPosition())) { return getState(); } @@ -257,7 +257,7 @@ private IAIState serveFoodToPlayer() return START_WORKING; } - if (walkToBlock(playerToServe.peek().blockPosition())) + if (!walkToWorkPos(playerToServe.peek().blockPosition())) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkDeliveryman.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkDeliveryman.java index 7305fba6c78..2c5196edb97 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkDeliveryman.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkDeliveryman.java @@ -12,10 +12,6 @@ import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; -import com.minecolonies.api.tileentities.AbstractTileEntityColonyBuilding; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; -import com.minecolonies.core.tileentities.TileEntityColonyBuilding; -import com.minecolonies.core.tileentities.TileEntityRack; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.api.util.Log; @@ -29,6 +25,9 @@ import com.minecolonies.core.colony.requestsystem.requests.StandardRequests.DeliveryRequest; import com.minecolonies.core.colony.requestsystem.requests.StandardRequests.PickupRequest; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.tileentities.TileEntityColonyBuilding; +import com.minecolonies.core.tileentities.TileEntityRack; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -161,11 +160,6 @@ private IAIState pickup() worker.getCitizenData().setVisibleStatus(DELIVERING); final BlockPos pickupTarget = currentTask.getRequester().getLocation().getInDimensionLocation(); - if (pickupTarget != BlockPos.ZERO && !worker.isWorkerAtSiteWithMove(pickupTarget, MIN_DISTANCE_TO_WAREHOUSE)) - { - return PICKUP; - } - final IBuilding pickupBuilding = building.getColony().getBuildingManager().getBuilding(pickupTarget); if (pickupBuilding == null) { @@ -173,6 +167,11 @@ private IAIState pickup() return START_WORKING; } + if (!walkToBuilding(pickupBuilding)) + { + return PICKUP; + } + if (pickupFromBuilding(pickupBuilding)) { this.alreadyKept = new ArrayList<>(); @@ -298,7 +297,7 @@ private IAIState dump() return START_WORKING; } - if (!worker.isWorkerAtSiteWithMove(warehouse.getPosition(), MIN_DISTANCE_TO_WAREHOUSE)) + if (!walkToBuilding(warehouse)) { setDelay(WALK_DELAY); return DUMPING; @@ -346,22 +345,18 @@ private IAIState deliver() return START_WORKING; } - if (!worker.isWorkerAtSiteWithMove(targetBuildingLocation.getInDimensionLocation(), MIN_DISTANCE_TO_WAREHOUSE)) - { - setDelay(WALK_DELAY); - return DELIVERY; - } - - final BlockEntity tileEntity = world.getBlockEntity(targetBuildingLocation.getInDimensionLocation()); - - if (!(tileEntity instanceof TileEntityColonyBuilding) || ((AbstractTileEntityColonyBuilding) tileEntity).getBuilding() == null) + final IBuilding targetBuilding = worker.getCitizenColonyHandler().getColony().getBuildingManager().getBuilding(targetBuildingLocation.getInDimensionLocation()); + if (targetBuilding == null) { - // TODO: Non-Colony deliveries are unsupported yet. Fix that at some point in time. job.finishRequest(true); return START_WORKING; } - final IBuilding targetBuilding = ((AbstractTileEntityColonyBuilding) tileEntity).getBuilding(); + if (!walkToBuilding(targetBuilding)) + { + setDelay(WALK_DELAY); + return DELIVERY; + } boolean success = true; boolean extracted = false; @@ -523,7 +518,7 @@ private IAIState prepareDelivery() return START_WORKING; } - if (walkToBlock(location.getInDimensionLocation())) + if (!walkToSafePos(location.getInDimensionLocation())) { return PREPARE_DELIVERY; } @@ -595,7 +590,7 @@ private IAIState decide() if (currentTask == null) { // If there are no deliveries/pickups pending, just loiter around the warehouse. - if (!worker.isWorkerAtSiteWithMove(getAndCheckWareHouse().getPosition(), MIN_DISTANCE_TO_WAREHOUSE)) + if (!walkToBuilding(getAndCheckWareHouse())) { setDelay(WALK_DELAY); return START_WORKING; diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkEnchanter.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkEnchanter.java index b94e618206c..0e238308866 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkEnchanter.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkEnchanter.java @@ -2,6 +2,7 @@ import com.minecolonies.api.colony.ICitizenData; import com.minecolonies.api.colony.IColonyManager; +import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.colony.interactionhandling.ChatPriority; import com.minecolonies.api.colony.requestsystem.token.IToken; import com.minecolonies.api.crafting.IRecipeStorage; @@ -12,7 +13,7 @@ import com.minecolonies.api.items.ModItems; import com.minecolonies.api.util.*; import com.minecolonies.core.Network; -import com.minecolonies.core.colony.buildings.AbstractBuilding; +import com.minecolonies.core.colony.buildings.modules.BuildingModules; import com.minecolonies.core.colony.buildings.modules.EnchanterStationsModule; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingEnchanter; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; @@ -21,17 +22,17 @@ import com.minecolonies.core.network.messages.client.CircleParticleEffectMessage; import com.minecolonies.core.network.messages.client.StreamParticleEffectMessage; import com.minecolonies.core.util.WorkerUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundEvents; -import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.InteractionHand; import net.minecraft.world.item.EnchantedBookItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.world.InteractionHand; -import net.minecraft.core.BlockPos; +import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.phys.Vec3; -import net.minecraft.network.chat.Component; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -117,7 +118,7 @@ public EntityAIWorkEnchanter(@NotNull final JobEnchanter job) protected IAIState decide() { worker.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); - if (walkToBuilding()) + if (!walkToBuilding()) { return START_WORKING; } @@ -137,7 +138,7 @@ protected IAIState decide() if (getPrimarySkillLevel() < building.getBuildingLevel() * MANA_REQ_PER_LEVEL) { final BuildingEnchanter enchanterBuilding = building; - final EnchanterStationsModule module = enchanterBuilding.getFirstModuleOccurance(EnchanterStationsModule.class); + final EnchanterStationsModule module = enchanterBuilding.getModule(BuildingModules.ENCHANTER_STATIONS); if (module.getBuildingsToGatherFrom().isEmpty()) { if (worker.getCitizenData() != null) @@ -298,13 +299,12 @@ private IAIState gatherAndDrain() return IDLE; } - if (walkToBlock(job.getPosToDrainFrom())) + final IBuilding buildingWorker = building.getColony().getBuildingManager().getBuilding(job.getPosToDrainFrom()); + if (!walkToBuilding(buildingWorker)) { return getState(); } - final AbstractBuilding buildingWorker = building.getColony().getBuildingManager().getBuilding(job.getPosToDrainFrom(), AbstractBuilding.class); - if (buildingWorker == null) { resetDraining(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java index 0528966f01b..62f7e75575c 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkHealer.java @@ -10,7 +10,10 @@ import com.minecolonies.api.entity.ai.statemachine.AITarget; import com.minecolonies.api.entity.ai.statemachine.states.IAIState; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.api.util.*; +import com.minecolonies.api.util.BlockPosUtil; +import com.minecolonies.api.util.InventoryUtils; +import com.minecolonies.api.util.Tuple; +import com.minecolonies.api.util.WorldUtil; import com.minecolonies.core.Network; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingHospital; import com.minecolonies.core.colony.interactionhandling.StandardInteraction; @@ -21,9 +24,9 @@ import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.network.messages.client.CircleParticleEffectMessage; import com.minecolonies.core.network.messages.client.StreamParticleEffectMessage; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; @@ -100,7 +103,7 @@ public EntityAIWorkHealer(@NotNull final JobHealer job) */ private IAIState decide() { - if (walkToBuilding()) + if (!walkToBuilding()) { return DECIDE; } @@ -252,7 +255,7 @@ private IAIState requestCure() } final EntityCitizen citizen = (EntityCitizen) data.getEntity().get(); - if (walkToBlock(citizen.blockPosition())) + if (!walkToSafePos(citizen.blockPosition())) { return REQUEST_CURE; } @@ -322,7 +325,7 @@ private IAIState cure() } final EntityCitizen citizen = (EntityCitizen) data.getEntity().get(); - if (walkToBlock(data.getEntity().get().blockPosition())) + if (!walkToSafePos(data.getEntity().get().blockPosition())) { return CURE; } @@ -400,7 +403,7 @@ private IAIState freeCure() } final EntityCitizen citizen = (EntityCitizen) data.getEntity().get(); - if (walkToBlock(citizen.blockPosition())) + if (!walkToSafePos(citizen.blockPosition())) { progressTicks = 0; return FREE_CURE; @@ -446,7 +449,7 @@ private IAIState curePlayer() return DECIDE; } - if (walkToBlock(playerToHeal.blockPosition())) + if (!walkToUnSafePos(playerToHeal.blockPosition())) { return getState(); } @@ -476,7 +479,7 @@ private IAIState wander() } final EntityCitizen citizen = (EntityCitizen) remotePatient.getEntity().get(); - if (walkToBlock(remotePatient.getEntity().get().blockPosition())) + if (!walkToUnSafePos(remotePatient.getEntity().get().blockPosition())) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkUndertaker.java b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkUndertaker.java index 0fa07fab0fc..9a3b4325d59 100644 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkUndertaker.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/service/EntityAIWorkUndertaker.java @@ -9,8 +9,6 @@ import com.minecolonies.api.entity.citizen.Skill; import com.minecolonies.api.entity.citizen.VisibleCitizenStatus; import com.minecolonies.api.equipment.ModEquipmentTypes; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; -import com.minecolonies.core.tileentities.TileEntityGrave; import com.minecolonies.api.util.InventoryUtils; import com.minecolonies.api.util.MessageUtils; import com.minecolonies.api.util.Tuple; @@ -19,8 +17,11 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingGraveyard; import com.minecolonies.core.colony.jobs.JobUndertaker; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.network.messages.client.VanillaParticleMessage; +import com.minecolonies.core.tileentities.TileEntityGrave; import com.minecolonies.core.util.AdvancementUtils; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.particles.ParticleTypes; @@ -115,7 +116,7 @@ private IAIState startWorking() @Nullable final BlockPos currentGrave = building.getGraveToWorkOn(); if (currentGrave != null) { - if (walkToBuilding()) + if (!walkToBuilding()) { return getState(); } @@ -143,7 +144,7 @@ private IAIState wander() { if (building.isInBuilding(worker.blockPosition())) { - worker.getNavigation().moveToRandomPos(10, DEFAULT_SPEED, building.getCorners()); + EntityNavigationUtils.walkToRandomPosWithin(worker, 10, DEFAULT_SPEED, building.getCorners()); } else { @@ -176,7 +177,7 @@ private IAIState emptyGrave() @Nullable final BlockPos gravePos = buildingGraveyard.getGraveToWorkOn(); // Still moving to the block - if (walkToBlock(gravePos, 3)) + if (walkWithProxy(gravePos, 3)) { return getState(); } @@ -237,7 +238,7 @@ private IAIState digGrave() } // Still moving to the block - if (walkToBlock(gravePos, 3)) + if (walkWithProxy(gravePos, 3)) { return getState(); } @@ -311,7 +312,7 @@ private IAIState tryResurrect() } // Still moving to the block - if (walkToBlock(gravePos, 3)) + if (walkWithProxy(gravePos, 3)) { return getState(); } @@ -444,7 +445,7 @@ private IAIState buryCitizen() return IDLE; } - if (walkToBlock(burialPos.getA(), 4)) + if (walkWithProxy(burialPos.getA(), 4)) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/util/BuildingStructureHandler.java b/src/main/java/com/minecolonies/core/entity/ai/workers/util/BuildingStructureHandler.java index 553c73d76f2..8e30e9576ee 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/util/BuildingStructureHandler.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/util/BuildingStructureHandler.java @@ -15,6 +15,7 @@ import com.minecolonies.core.colony.buildings.AbstractBuildingStructureBuilder; import com.minecolonies.core.colony.jobs.AbstractJobStructure; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIStructure; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.util.WorkerUtil; import net.minecraft.core.BlockPos; import net.minecraft.tags.ItemTags; @@ -35,7 +36,6 @@ import java.util.concurrent.Future; import java.util.function.Function; -import static com.minecolonies.api.util.constant.CitizenConstants.RUN_AWAY_SPEED; import static com.minecolonies.api.util.constant.StatisticsConstants.BLOCKS_PLACED; /** @@ -182,7 +182,7 @@ public void prePlacementLogic(final BlockPos worldPos, final BlockState blockSta && Mth.floor(structureAI.getWorker().getZ()) == worldPos.getZ() && structureAI.getWorker().getNavigation().isDone()) { - structureAI.getWorker().getNavigation().moveAwayFromXYZ(worldPos, RUN_AWAY_SPEED, 1, true); + EntityNavigationUtils.walkAwayFrom(structureAI.getWorker(), worldPos, 1, 1.0); } structureAI.getWorker().swing(InteractionHand.MAIN_HAND); diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index ccc43ca34b5..d5c73d58186 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -27,7 +27,6 @@ import com.minecolonies.api.entity.citizen.citizenhandlers.*; import com.minecolonies.api.entity.citizen.happiness.ExpirationBasedHappinessModifier; import com.minecolonies.api.entity.citizen.happiness.StaticHappinessSupplier; -import com.minecolonies.api.entity.pathfinding.proxy.IWalkToProxy; import com.minecolonies.api.eventbus.events.colony.citizens.CitizenDiedModEvent; import com.minecolonies.api.eventbus.events.colony.citizens.CitizenRemovedModEvent; import com.minecolonies.api.inventory.InventoryCitizen; @@ -57,9 +56,8 @@ import com.minecolonies.core.entity.ai.workers.CitizenAI; import com.minecolonies.core.entity.ai.workers.guard.AbstractEntityAIGuard; import com.minecolonies.core.entity.citizen.citizenhandlers.*; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.pathfinding.navigation.MovementHandler; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; -import com.minecolonies.core.entity.pathfinding.proxy.EntityCitizenWalkToProxy; import com.minecolonies.core.event.EventHandler; import com.minecolonies.core.event.TextureReloadListener; import com.minecolonies.core.network.messages.client.ItemParticleEffectMessage; @@ -67,8 +65,8 @@ import com.minecolonies.core.network.messages.client.colony.ColonyViewCitizenViewMessage; import com.minecolonies.core.network.messages.client.colony.PlaySoundForCitizenMessage; import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage; -import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import com.minecolonies.core.util.TeleportHelper; +import com.minecolonies.core.util.citizenutils.CitizenItemUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.particles.ParticleTypes; @@ -112,9 +110,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.time.Clock; -import java.time.LocalDate; -import java.time.Month; import java.util.*; import static com.minecolonies.api.research.util.ResearchConstants.*; @@ -153,10 +148,7 @@ public class EntityCitizen extends AbstractEntityCitizen implements IThreatTable * It's citizen Id. */ private int citizenId = 0; - /** - * The Walk to proxy (Shortest path through intermediate blocks). - */ - private IWalkToProxy proxy; + /** * Reference to the data representation inside the colony. */ @@ -191,11 +183,6 @@ public class EntityCitizen extends AbstractEntityCitizen implements IThreatTable */ private final CitizenCombatTracker combatTracker; - /** - * The path-result of trying to move away - */ - private PathResult moveAwayPath; - /** * IsChild flag */ @@ -543,7 +530,7 @@ private InteractionResult directPlayerInteraction(final Player player, final Int if (!level.isClientSide()) { MessageUtils.format(MESSAGE_INTERACTION_OUCH, getCitizenData().getName()).sendTo(player); - getNavigation().moveAwayFromLivingEntity(player, 5, 1); + EntityNavigationUtils.walkAwayFrom(this, player.blockPosition(), 5, 1); setJumping(true); } @@ -962,23 +949,6 @@ public ILocation getLocation() return location; } - /** - * Checks if a worker is at his working site. If he isn't, sets it's path to the location - * - * @param site the place where he should walk to - * @param range Range to check in - * @return True if worker is at site, otherwise false. - */ - @Override - public boolean isWorkerAtSiteWithMove(@NotNull final BlockPos site, final int range) - { - if (proxy == null) - { - proxy = new EntityCitizenWalkToProxy(this); - } - return proxy.walkToBlock(site, range, true); - } - /** * Getter for the citizendata. Tries to get it from the colony is the data is null. * @@ -1085,17 +1055,6 @@ public void playMoveAwaySound() } } - /** - * Get the path proxy of the citizen. - * - * @return the proxy. - */ - @Override - public IWalkToProxy getProxy() - { - return proxy; - } - /** * Decrease the saturation of the citizen for 1 action. */ @@ -1459,10 +1418,12 @@ private void performMoveAway(@Nullable final Entity attacker) if (!(attacker instanceof LivingEntity) && (!(getCitizenJobHandler().getColonyJob() instanceof AbstractJobGuard) || getCitizenJobHandler().getColonyJob().canAIBeInterrupted())) { - if (moveAwayPath == null || !moveAwayPath.isInProgress()) - { - moveAwayPath = this.getNavigation().moveAwayFromLivingEntity(this, 5, INITIAL_RUN_SPEED_AVOID); - } + EntityNavigationUtils.walkAwayFrom(this, blockPosition(), 5, INITIAL_RUN_SPEED_AVOID); + return; + } + + if (attacker == null) + { return; } @@ -1475,10 +1436,7 @@ private void performMoveAway(@Nullable final Entity attacker) citizenAI.addTransition(new AIOneTimeEventTarget<>(CitizenAIState.FLEE)); callForHelp(attacker, MAX_GUARD_CALL_RANGE); - if (moveAwayPath == null || !moveAwayPath.isInProgress()) - { - moveAwayPath = this.getNavigation().moveAwayFromLivingEntity(attacker, 15, INITIAL_RUN_SPEED_AVOID); - } + EntityNavigationUtils.walkAwayFrom(this, attacker.blockPosition(), 15, INITIAL_RUN_SPEED_AVOID); } @Override diff --git a/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenary.java b/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenary.java index 686e5a1cefe..58fe5f90553 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenary.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenary.java @@ -18,6 +18,7 @@ import com.minecolonies.core.entity.ai.minimal.EntityAIInteractToggleAble; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.proxy.GeneralEntityWalkToProxy; import net.minecraft.core.BlockPos; @@ -261,11 +262,11 @@ private boolean spawnEvent() playSound(MercenarySounds.mercenaryCelebrate, 2.0f, 1.0f); if (blockPosition().equals(first)) { - getNavigation().tryMoveToBlockPos(last, 0.5); + EntityNavigationUtils.walkToPos(this, last, 2, true, 0.5); } else { - getNavigation().tryMoveToBlockPos(first, 0.5); + EntityNavigationUtils.walkToPos(this, first, 2, true, 0.5); } return false; diff --git a/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenaryAI.java b/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenaryAI.java index 80ad81e5c3d..e47015ea507 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenaryAI.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenaryAI.java @@ -5,13 +5,14 @@ import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickRateStateMachine; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import com.minecolonies.api.sounds.MercenarySounds; import com.minecolonies.api.util.*; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; +import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.InteractionHand; -import net.minecraft.core.BlockPos; import net.minecraftforge.items.IItemHandler; import java.util.ArrayList; @@ -226,8 +227,8 @@ private boolean fighting() if (attackPath == null || !attackPath.isInProgress()) { - entity.getNavigation().moveToLivingEntity(entity.getTarget(), 1); - entity.getLookControl().setLookAt(entity.getTarget(), 180f, 180f); + EntityNavigationUtils.walkToPos(entity, entity.getTarget().blockPosition(), false); + entity.getLookControl().setLookAt(entity.getTarget()); } final int distance = BlockPosUtil.getMaxDistance2D(entity.blockPosition(), entity.getTarget().blockPosition()); diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/CampWalkAI.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/CampWalkAI.java index 4ae3f64a6ee..b65682b0f4b 100644 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/CampWalkAI.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/CampWalkAI.java @@ -7,6 +7,7 @@ import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; import com.minecolonies.api.entity.pathfinding.IPathJob; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.BlockPos; import net.minecraft.util.Tuple; @@ -23,16 +24,6 @@ public class CampWalkAI implements IStateAI */ private final AbstractEntityMinecoloniesMonster entity; - /** - * Target block we're walking to - */ - private BlockPos targetBlock = null; - - /** - * Walk timer - */ - private long walkTimer = 0; - /** * Random path result. */ @@ -46,57 +37,21 @@ public class CampWalkAI implements IStateAI public CampWalkAI(final AbstractEntityMinecoloniesMonster raider, final ITickRateStateMachine stateMachine) { this.entity = raider; - stateMachine.addTransition(new TickingTransition<>(CombatAIStates.NO_TARGET, this::walk, () -> null, 80)); + stateMachine.addTransition(new TickingTransition<>(CombatAIStates.NO_TARGET, this::walk, () -> null, TICKS_SECOND * 30)); } /** - * Walk raider towards the colony or campfires - * + * Walk camp mob randomly */ private boolean walk() { - if (targetBlock == null || entity.level.getGameTime() > walkTimer) + if (spawnCenterBoxCache == null) { - targetBlock = findRandomPositionToWalkTo(); - walkTimer = entity.level.getGameTime() + TICKS_SECOND * 30; - } - else - { - entity.getNavigation().moveToXYZ(targetBlock.getX(), targetBlock.getY(), targetBlock.getZ(),1.1); - randomPathResult = null; + final BlockPos startPos = entity.getSpawnPos() == null ? entity.blockPosition() : entity.getSpawnPos(); + spawnCenterBoxCache = new Tuple<>(startPos.offset(-10, -5, -10), startPos.offset(10, 5, 10)); } + EntityNavigationUtils.walkToRandomPosWithin(entity, 10, 0.6, spawnCenterBoxCache); return false; } - - protected BlockPos findRandomPositionToWalkTo() - { - if (randomPathResult == null || randomPathResult.failedToReachDestination()) - { - if (spawnCenterBoxCache == null) - { - final BlockPos startPos = entity.getSpawnPos() == null ? entity.blockPosition() : entity.getSpawnPos(); - spawnCenterBoxCache = new Tuple<>(startPos.offset(-10,-5,-10), startPos.offset(10,5,10)); - } - - randomPathResult = entity.getNavigation().moveToRandomPos(10, 0.9, spawnCenterBoxCache); - if (randomPathResult != null) - { - randomPathResult.getJob().getPathingOptions().withCanEnterDoors(true).withToggleCost(0).withNonLadderClimbableCost(0); - } - } - - if (randomPathResult.isPathReachingDestination()) - { - return randomPathResult.getPath().getEndNode().asBlockPos(); - } - - if (randomPathResult.isCancelled()) - { - randomPathResult = null; - return null; - } - - return null; - } } diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderMeleeAI.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderMeleeAI.java index 461f34d2214..994895f8dc2 100644 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderMeleeAI.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderMeleeAI.java @@ -4,11 +4,11 @@ import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; -import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.util.SoundUtils; import com.minecolonies.api.util.constant.Constants; import com.minecolonies.core.entity.ai.combat.AttackMoveAI; import com.minecolonies.core.entity.citizen.EntityCitizen; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.contents.TranslatableContents; @@ -84,8 +84,12 @@ protected int getAttackDelay() @Override protected PathResult moveInAttackPosition(final LivingEntity target) { - return user.getNavigation() - .moveToXYZ(target.getX(), target.getY(), target.getZ(), user.getDifficulty() < ADD_SPEED_DIFFICULTY ? BASE_COMBAT_SPEED : BASE_COMBAT_SPEED * BONUS_SPEED); + EntityNavigationUtils.walkToPos(user, + target.blockPosition(), + (int) getAttackDistance(), + false, + user.getDifficulty() < ADD_SPEED_DIFFICULTY ? BASE_COMBAT_SPEED : BASE_COMBAT_SPEED * BONUS_SPEED); + return user.getNavigation().getPathResult(); } @Override diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderRangedAI.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderRangedAI.java index 39ecdff9b83..3d3e144764b 100644 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderRangedAI.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderRangedAI.java @@ -4,7 +4,6 @@ import com.minecolonies.api.entity.ai.statemachine.states.IState; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesMonster; -import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; import com.minecolonies.api.entity.mobs.ICustomAttackSound; import com.minecolonies.api.entity.mobs.IRangedMobEntity; import com.minecolonies.api.util.EntityUtils; @@ -12,6 +11,7 @@ import com.minecolonies.core.entity.ai.combat.CombatUtils; import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.entity.other.CustomArrowEntity; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; @@ -185,7 +185,8 @@ protected boolean checkForTarget() @Override protected PathResult moveInAttackPosition(final LivingEntity target) { - return user.getNavigation().moveToXYZ(target.getX(), target.getY(), target.getZ(), COMBAT_MOVEMENT_SPEED); + EntityNavigationUtils.walkToPos(user, target.blockPosition(), (int) getAttackDistance(), false, COMBAT_MOVEMENT_SPEED); + return user.getNavigation().getPathResult(); } @Override diff --git a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderWalkAI.java b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderWalkAI.java index a1a0c52f9d7..abef1781cbc 100644 --- a/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderWalkAI.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/aitasks/RaiderWalkAI.java @@ -1,5 +1,6 @@ package com.minecolonies.core.entity.mobs.aitasks; +import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.colony.colonyEvents.EventStatus; import com.minecolonies.api.colony.colonyEvents.IColonyEvent; import com.minecolonies.api.colony.colonyEvents.IColonyRaidEvent; @@ -9,13 +10,10 @@ import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; import com.minecolonies.api.entity.mobs.AbstractEntityMinecoloniesRaider; -import com.minecolonies.api.entity.pathfinding.IPathJob; -import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.Log; -import com.minecolonies.core.colony.buildings.AbstractBuilding; import com.minecolonies.core.colony.events.raid.HordeRaidEvent; import com.minecolonies.core.colony.events.raid.pirateEvent.ShipBasedRaiderUtils; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; +import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils; import net.minecraft.core.BlockPos; import java.util.List; @@ -43,14 +41,9 @@ public class RaiderWalkAI implements IStateAI private long walkTimer = 0; /** - * Random path result. + * Building the raider is checking out */ - private PathResult randomPathResult; - - /** - * If we are currently trying to move to a random block. - */ - private boolean walkInBuildingState = false; + private IBuilding walkInBuilding = null; public RaiderWalkAI(final AbstractEntityMinecoloniesRaider raider, final ITickRateStateMachine stateMachine) { @@ -87,43 +80,27 @@ private boolean walk() final List wayPoints = ((IColonyRaidEvent) event).getWayPoints(); final BlockPos moveToPos = ShipBasedRaiderUtils.chooseWaypointFor(wayPoints, raider.blockPosition(), targetBlock); - raider.getNavigation().moveToXYZ(moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), !moveToPos.equals(targetBlock) && moveToPos.distManhattan(wayPoints.get(0)) > 50 ? 1.8 : 1.1); - walkInBuildingState = false; - randomPathResult = null; + EntityNavigationUtils.walkToPos(raider, moveToPos, 4, false, !moveToPos.equals(targetBlock) && moveToPos.distManhattan(wayPoints.get(0)) > 50 ? 1.8 : 1.1); + walkInBuilding = null; } - else if (walkInBuildingState) + else if (walkInBuilding != null) { - final BlockPos moveToPos = findRandomPositionToWalkTo(); - if (moveToPos != null) + if (EntityNavigationUtils.walkToRandomPosWithin(raider, 10, 0.7, walkInBuilding.getCorners()) + && raider.getRandom().nextDouble() < 0.25) { - if (moveToPos == BlockPos.ZERO) - { - walkInBuildingState = false; - targetBlock = null; - return false; - } - raider.getNavigation().moveToXYZ(moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), 0.9); - if (raider.blockPosition().distSqr(moveToPos) < 4) - { - if (raider.getRandom().nextDouble() < 0.25) - { - walkInBuildingState = false; - targetBlock = null; - } - else - { - randomPathResult = null; - walkTimer = raider.level.getGameTime() + TICKS_SECOND * 60; - findRandomPositionToWalkTo(); - } - } + walkInBuilding = null; + targetBlock = null; + } + + if (raider.getNavigation().getPathResult() != null) + { + raider.getNavigation().getPathResult().getJob().getPathingOptions().withCanEnterDoors(true).withToggleCost(0).withNonLadderClimbableCost(0); } } else if (raider.blockPosition().distSqr(targetBlock) < 25) { - findRandomPositionToWalkTo(); walkTimer = raider.level.getGameTime() + TICKS_SECOND * 30; - walkInBuildingState = true; + walkInBuilding = raider.getColony().getBuildingManager().getBuilding(targetBlock); } else if (raider.getNavigation().isDone() || raider.getNavigation().getDesiredPos() == null) { @@ -139,54 +116,13 @@ else if (raider.getNavigation().isDone() || raider.getNavigation().getDesiredPos } } - raider.getNavigation() - .moveToXYZ(moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), !moveToPos.equals(targetBlock) && moveToPos.distManhattan(wayPoints.get(0)) > 50 ? 1.8 : 1.1); + EntityNavigationUtils.walkToPos(raider, moveToPos, 7, true, !moveToPos.equals(targetBlock) && moveToPos.distManhattan(wayPoints.get(0)) > 50 ? 1.8 : 1.1); } } return false; } - protected BlockPos findRandomPositionToWalkTo() - { - if (randomPathResult == null || randomPathResult.failedToReachDestination()) - { - if (raider.getColony().getBuildingManager().getBuilding(targetBlock) instanceof AbstractBuilding building - && building.getBuildingLevel() > 0 - && !building.getCorners().getA().equals(building.getCorners().getB())) - { - randomPathResult = raider.getNavigation().moveToRandomPos(10, 0.9, building.getCorners()); - if (randomPathResult != null) - { - randomPathResult.getJob().getPathingOptions().withCanEnterDoors(true).withToggleCost(0).withNonLadderClimbableCost(0); - } - } - else - { - return BlockPos.ZERO; - } - } - - if (randomPathResult == null) - { - return null; - } - - - if (randomPathResult.isPathReachingDestination()) - { - return randomPathResult.getPath().getEndNode().asBlockPos(); - } - - if (randomPathResult.isCancelled()) - { - randomPathResult = null; - return null; - } - - return null; - } - /** * Chooses and walks to a random campfire */ @@ -205,15 +141,7 @@ private void walkToCampFire() } walkTimer = raider.level.getGameTime() + raider.level.random.nextInt(1000); - final BlockPos posAroundCampfire = BlockPosUtil.getRandomPosition(raider.level, - campFire, - BlockPos.ZERO, - 3, - 6); - if (posAroundCampfire != null && posAroundCampfire != BlockPos.ZERO) - { - raider.getNavigation().moveToXYZ(posAroundCampfire.getX(), posAroundCampfire.getY(), posAroundCampfire.getZ(), 1.0); - } + EntityNavigationUtils.walkToRandomPosAround(raider, campFire, 10, 0.7); } } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/AbstractAdvancedPathNavigate.java b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/AbstractAdvancedPathNavigate.java index 4741a7fb26f..8b2a8688af2 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/AbstractAdvancedPathNavigate.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/AbstractAdvancedPathNavigate.java @@ -6,6 +6,7 @@ import com.minecolonies.api.entity.pathfinding.IStuckHandler; import com.minecolonies.core.entity.pathfinding.PathingOptions; import com.minecolonies.core.entity.pathfinding.pathjobs.AbstractPathJob; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveCloseToXNearY; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import com.minecolonies.core.entity.pathfinding.pathresults.TreePathResult; import net.minecraft.core.BlockPos; @@ -61,7 +62,7 @@ public BlockPos getDestination() * @param safeDestination if the destination is save and should be set. * @return the result of the pathing. */ - public abstract PathResult moveAwayFromXYZ(final BlockPos currentPosition, final double range, final double speed, final boolean safeDestination); + protected abstract PathResult walkAwayFrom(final BlockPos currentPosition, final double range, final double speed, final boolean safeDestination); /** * Try to move to a certain position. @@ -72,7 +73,7 @@ public BlockPos getDestination() * @param speed the speed to walk. * @return the PathResult. */ - public abstract PathResult moveToXYZ(final double x, final double y, final double z, final double speed); + protected abstract PathResult walkTo(final BlockPos pos, final double speed, final boolean safeDestination); /** * Used to path away from a ourEntity. @@ -82,7 +83,7 @@ public BlockPos getDestination() * @param combatMovementSpeed the speed to run at. * @return the result of the pathing. */ - public abstract PathResult moveAwayFromLivingEntity(final Entity target, final double distance, final double combatMovementSpeed); + protected abstract PathResult moveAwayFromLivingEntity(final Entity target, final double distance, final double combatMovementSpeed); /** * Attempt to move to a specific pos. @@ -91,7 +92,7 @@ public BlockPos getDestination() * @param speed the speed. * @return true if successful. */ - public abstract boolean tryMoveToBlockPos(final BlockPos position, final double speed); + protected abstract boolean walkTo(final BlockPos position, final double speed); /** * Attemps to move in the given direction, walking at least range blocks @@ -102,7 +103,7 @@ public BlockPos getDestination() * @return */ @Nullable - public abstract PathResult moveTowards(BlockPos towards, double range, double speedFactor); + protected abstract PathResult walkTowards(BlockPos towards, double range, double speedFactor); /** * Used to path towards a random pos. @@ -111,7 +112,7 @@ public BlockPos getDestination() * @param speed the speed to run at. * @return the result of the pathing. */ - public abstract PathResult moveToRandomPos(final double range, final double speed); + protected abstract PathResult walkToRandomPos(final int range, final double speed); /** * Used to path towards a random pos. @@ -121,7 +122,24 @@ public BlockPos getDestination() * @param pos the pos to circle around. * @return the result of the pathing. */ - public abstract PathResult moveToRandomPosAroundX(final int range, final double speed, final BlockPos pos); + protected abstract PathResult walkToRandomPosAround(final int range, final double speed, final BlockPos pos); + + /** + * Walks towards the desired position, while trying to not steer too far from the nearby position + * + * @param desiredPosition + * @param nearbyPosition + * @param distToDesired + * @param speedFactor + * @param safeDestination + * @return + */ + protected abstract PathResult walkCloseToXNearY( + BlockPos desiredPosition, + BlockPos nearbyPosition, + int distToDesired, + double speedFactor, + boolean safeDestination); /** * Used to path towards a random pos within some restrictions @@ -131,7 +149,7 @@ public BlockPos getDestination() * @param corners the corners they can't leave. * @return the result of the pathing. */ - public abstract PathResult moveToRandomPos( + protected abstract PathResult walkToRandomPos( final int range, final double speed, final net.minecraft.util.Tuple corners); @@ -145,7 +163,7 @@ public abstract PathResult moveToRandomPos( * @param excludedTrees the trees which should be cut. * @return the result of the search. */ - public abstract TreePathResult moveToTree( + public abstract TreePathResult walkToTree( final BlockPos startRestriction, final BlockPos endRestriction, final double speed, @@ -161,16 +179,16 @@ public abstract TreePathResult moveToTree( * @param excludedTrees the trees which should be cut. * @return the result of the search. */ - public abstract TreePathResult moveToTree(final int range, final double speed, final List excludedTrees, final int dyntreesize, final IColony colony); + public abstract TreePathResult walkToTree(final int range, final double speed, final List excludedTrees, final int dyntreesize, final IColony colony); /** - * Used to move a living ourEntity with a speed. + * Used to walk a living ourEntity with a speed. * * @param e the ourEntity. * @param speed the speed. * @return the result. */ - public abstract PathResult moveToLivingEntity(@NotNull final Entity e, final double speed); + protected abstract PathResult walkToEntity(@NotNull final Entity e, final double speed); /** * Get the pathing options diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/EntityNavigationUtils.java b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/EntityNavigationUtils.java new file mode 100644 index 00000000000..c4f3c5be86e --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/EntityNavigationUtils.java @@ -0,0 +1,289 @@ +package com.minecolonies.core.entity.pathfinding.navigation; + +import com.minecolonies.api.colony.buildings.IBuilding; +import com.minecolonies.api.entity.other.AbstractFastMinecoloniesEntity; +import com.minecolonies.api.util.BlockPosUtil; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveAwayFromLocation; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveCloseToXNearY; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveToLocation; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobRandomPos; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Tuple; + +public class EntityNavigationUtils +{ + /** + * Distance to consider being near a building block as reached + */ + public static int BUILDING_REACH_DIST = 4; + + /** + * Distance to consider being near a block inside a building as reached + */ + public static int WOKR_IN_BUILDING_DIST = 7; + + /** + * Distance which counts as reached + */ + public static double REACHED_DIST = 1.5; + + /** + * Tries to walk close to a given pos, staying near another position. + * + * @param entity + * @param desiredPosition + * @param nearbyPosition + * @param distToDesired + * @return True when arrived + */ + public static boolean walkCloseToXNearY( + final AbstractFastMinecoloniesEntity entity, final BlockPos desiredPosition, + final BlockPos nearbyPosition, + final int distToDesired, final boolean safeDestination) + { + return walkCloseToXNearY(entity, desiredPosition, nearbyPosition, distToDesired, safeDestination, 1.0); + } + + /** + * Tries to walk close to a given pos, staying near another position. + * + * @return True when arrived + */ + public static boolean walkCloseToXNearY( + final AbstractFastMinecoloniesEntity entity, final BlockPos desiredPosition, + final BlockPos nearbyPosition, + final int distToDesired, final boolean safeDestination, final double speedFactor) + { + final MinecoloniesAdvancedPathNavigate nav = ((MinecoloniesAdvancedPathNavigate) entity.getNavigation()); + + // Three cases + // 1. Navigation Finished + // 2. Navigation is progressing towards a previous task + // 3. Navigation did not try once + boolean isOnRightTask = (nav.getPathResult() != null + && PathJobMoveCloseToXNearY.isJobFor(nav.getPathResult().getJob(), desiredPosition, nearbyPosition, distToDesired)); + + if (nav.isDone() || !isOnRightTask) + { + if (isOnRightTask) + { + // Check distance once navigation is done, to let the entity walk + if (BlockPosUtil.dist(entity.blockPosition(), desiredPosition) <= distToDesired) + { + nav.stop(); + return true; + } + } + else if (BlockPosUtil.dist(entity.blockPosition(), desiredPosition) <= REACHED_DIST) + { + nav.stop(); + return true; + } + + nav.walkCloseToXNearY(desiredPosition, nearbyPosition, 1, speedFactor, safeDestination); + } + + return false; + } + + /** + * Walks to a position within a building + * + * @return True when arrived + */ + public static boolean walkToPosInBuilding( + final AbstractFastMinecoloniesEntity entity, final BlockPos destination, final IBuilding building, final int reachDistance) + { + if (building == null) + { + return walkToPos(entity, destination, reachDistance, true); + } + + Tuple corners = building.getCorners(); + final BlockPos center = + new BlockPos((corners.getA().getX() + corners.getB().getX()) / 2, building.getPosition().getY(), (corners.getA().getZ() + corners.getB().getZ()) / 2); + + return walkCloseToXNearY(entity, destination, center, reachDistance, true); + } + + /** + * Walks to a position within a building + * + * @return True when arrived + */ + public static boolean walkToBuilding( + final AbstractFastMinecoloniesEntity entity, final IBuilding building) + { + if (building == null) + { + return true; + } + + return walkToPosInBuilding(entity, building.getPosition(), building, BUILDING_REACH_DIST); + } + + /** + * Walks to a given position + * + * @return True when arrived + */ + public static boolean walkToPos( + final AbstractFastMinecoloniesEntity entity, final BlockPos desiredPosition, final boolean safeDestination) + { + return walkToPos(entity, desiredPosition, BUILDING_REACH_DIST, safeDestination, 1.0); + } + + /** + * Walks to a given position + * + * @return True when arrived + */ + public static boolean walkToPos( + final AbstractFastMinecoloniesEntity entity, final BlockPos desiredPosition, + final int distToDesired, final boolean safeDestination) + { + return walkToPos(entity, desiredPosition, distToDesired, safeDestination, 1.0); + } + + /** + * Walks to a given position + * + * @return True when arrived + */ + public static boolean walkToPos( + final AbstractFastMinecoloniesEntity entity, final BlockPos desiredPosition, + final int distToDesired, final boolean safeDestination, final double speedFactor) + { + final MinecoloniesAdvancedPathNavigate nav = ((MinecoloniesAdvancedPathNavigate) entity.getNavigation()); + + boolean isOnRightTask = (nav.getPathResult() != null + && PathJobMoveToLocation.isJobFor(nav.getPathResult().getJob(), desiredPosition)); + + if (nav.isDone() || !isOnRightTask) + { + if (isOnRightTask) + { + // Check distance once navigation is done, to let the entity walk + if (BlockPosUtil.dist(entity.blockPosition(), desiredPosition) <= distToDesired) + { + nav.stop(); + return true; + } + } + else if (BlockPosUtil.dist(entity.blockPosition(), desiredPosition) <= REACHED_DIST) + { + nav.stop(); + return true; + } + + nav.walkTo(desiredPosition, speedFactor, safeDestination); + } + + return false; + } + + /** + * Walks away from a given position + * + * @return True when arrived + */ + public static boolean walkAwayFrom(final AbstractFastMinecoloniesEntity entity, final BlockPos avoid, final int distance, final double speed) + { + final MinecoloniesAdvancedPathNavigate nav = ((MinecoloniesAdvancedPathNavigate) entity.getNavigation()); + boolean isOnRightTask = (nav.getPathResult() != null && PathJobMoveAwayFromLocation.isJobFor(nav.getPathResult().getJob(), distance, avoid)); + + if (nav.isDone() || !isOnRightTask) + { + if (isOnRightTask) + { + // Check distance once navigation is done, to let the entity walk + if (BlockPosUtil.dist(entity.blockPosition(), avoid) >= distance) + { + nav.stop(); + return true; + } + } + else if (BlockPosUtil.dist(entity.blockPosition(), avoid) >= REACHED_DIST) + { + nav.stop(); + return true; + } + + nav.walkAwayFrom(avoid, distance, speed, false); + } + + return false; + } + + /** + * Walks to a random position a given distance away + * + * @return True when arrived + */ + public static boolean walkToRandomPos(final AbstractFastMinecoloniesEntity entity, final int range, final double speedFactor) + { + final MinecoloniesAdvancedPathNavigate nav = ((MinecoloniesAdvancedPathNavigate) entity.getNavigation()); + boolean isOnRightTask = (nav.getPathResult() != null && nav.getPathResult().getJob() instanceof PathJobRandomPos); + + if (nav.isDone() || !isOnRightTask) + { + if (isOnRightTask) + { + nav.stop(); + return true; + } + + nav.walkToRandomPos(range, speedFactor); + } + + return false; + } + + /** + * Walks to a random position a given distance away within the provided box + * + * @return True when arrived + */ + public static boolean walkToRandomPosWithin(final AbstractFastMinecoloniesEntity entity, final int range, final double speedFactor, final Tuple corners) + { + final MinecoloniesAdvancedPathNavigate nav = ((MinecoloniesAdvancedPathNavigate) entity.getNavigation()); + boolean isOnRightTask = (nav.getPathResult() != null && nav.getPathResult().getJob() instanceof PathJobRandomPos); + + if (nav.isDone() || !isOnRightTask) + { + if (isOnRightTask) + { + nav.stop(); + return true; + } + + nav.walkToRandomPos(range, speedFactor, corners); + } + + return false; + } + + /** + * Walks to a random position a given distance away around the provided center + * + * @return True when arrived + */ + public static boolean walkToRandomPosAround(final AbstractFastMinecoloniesEntity entity, final BlockPos center, final int range, final double speedFactor) + { + final MinecoloniesAdvancedPathNavigate nav = ((MinecoloniesAdvancedPathNavigate) entity.getNavigation()); + boolean isOnRightTask = (nav.getPathResult() != null && PathJobRandomPos.isJobFor(nav.getPathResult().getJob(), center, range)); + + if (nav.isDone() || !isOnRightTask) + { + if (isOnRightTask) + { + nav.stop(); + return true; + } + + nav.walkToRandomPosAround(range, speedFactor, center); + } + + return false; + } +} diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/MinecoloniesAdvancedPathNavigate.java b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/MinecoloniesAdvancedPathNavigate.java index 6e09ed3e275..a071975cc6a 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/MinecoloniesAdvancedPathNavigate.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/MinecoloniesAdvancedPathNavigate.java @@ -7,7 +7,6 @@ import com.minecolonies.api.entity.other.MinecoloniesMinecart; import com.minecolonies.api.entity.pathfinding.IStuckHandler; import com.minecolonies.api.util.*; -import com.minecolonies.api.util.constant.ColonyConstants; import com.minecolonies.core.entity.pathfinding.PathFindingStatus; import com.minecolonies.core.entity.pathfinding.PathPointExtended; import com.minecolonies.core.entity.pathfinding.Pathfinding; @@ -58,12 +57,7 @@ public class MinecoloniesAdvancedPathNavigate extends AbstractAdvancedPathNaviga public static final double MIN_SPEED_ALLOWED = 0.1; @Nullable - private PathResult pathResult; - - /** - * The world time when a path was added. - */ - private long pathStartTime = 0; + private PathResult pathResult; /** * Spawn pos of minecart. @@ -144,7 +138,7 @@ public BlockPos getDestination() } @Nullable - public PathResult moveAwayFromXYZ(final BlockPos avoid, final double range, final double speedFactor, final boolean safeDestination) + protected PathResult walkAwayFrom(final BlockPos avoid, final double range, final double speedFactor, final boolean safeDestination) { @NotNull final BlockPos start = PathfindingUtils.prepareStart(ourEntity); @@ -158,7 +152,7 @@ public PathResult moveAwayFromXYZ(final BlockPos avoid, final d @Nullable @Override - public PathResult moveTowards(final BlockPos towards, final double range, final double speedFactor) + protected PathResult walkTowards(final BlockPos towards, final double range, final double speedFactor) { return setPathJob(new PathJobMoveTowards(CompatibilityUtils.getWorldFromEntity(ourEntity), PathfindingUtils.prepareStart(ourEntity), @@ -168,37 +162,29 @@ public PathResult moveTowards(final BlockPos towards, final dou } @Nullable - public PathResult moveToRandomPos(final double range, final double speedFactor) + protected PathResult walkToRandomPos(final int range, final double speedFactor) { - if (pathResult != null && pathResult.isInProgress() && pathResult.getJob() instanceof PathJobRandomPos) - { - return pathResult; - } - - desiredPos = BlockPos.ZERO; - final int theRange = (int) (mob.getRandom().nextInt((int) range) + range / 2); @NotNull final BlockPos start = PathfindingUtils.prepareStart(ourEntity); - - return setPathJob(new PathJobRandomPos(CompatibilityUtils.getWorldFromEntity(ourEntity), + final PathResult result = setPathJob(new PathJobRandomPos(CompatibilityUtils.getWorldFromEntity(ourEntity), start, - theRange, + range, (int) ourEntity.getAttribute(Attributes.FOLLOW_RANGE).getValue(), + ourEntity), null, speedFactor, true); - } - @Nullable - public PathResult moveToRandomPosAroundX(final int range, final double speedFactor, final BlockPos pos) - { - if (pathResult != null - && pathResult.isInProgress() - && pathResult.getJob() instanceof PathJobRandomPos - && ((((PathJobRandomPos) pathResult.getJob()).posAndRangeMatch(range, pos)))) + if (result == null) { - return pathResult; + return null; } - desiredPos = BlockPos.ZERO; - final PathResult result = setPathJob(new PathJobRandomPos(CompatibilityUtils.getWorldFromEntity(ourEntity), + result.getJob().getPathingOptions().withToggleCost(1).withJumpCost(1).withDropCost(1).canDrop = false; + return result; + } + + @Nullable + protected PathResult walkToRandomPosAround(final int range, final double speedFactor, final BlockPos pos) + { + final PathResult result = setPathJob(new PathJobRandomPos(CompatibilityUtils.getWorldFromEntity(ourEntity), PathfindingUtils.prepareStart(ourEntity), 3, (int) ourEntity.getAttribute(Attributes.FOLLOW_RANGE).getValue(), @@ -210,28 +196,21 @@ public PathResult moveToRandomPosAroundX(final int range, final return null; } - result.getJob().getPathingOptions().withToggleCost(1).withJumpCost(1).withDropCost(1); + result.getJob().getPathingOptions().withToggleCost(1).withJumpCost(1).withDropCost(1).canDrop = false; return result; } @Override - public PathResult moveToRandomPos( + protected PathResult walkToRandomPos( final int range, final double speedFactor, final net.minecraft.util.Tuple corners) { - if (pathResult != null && pathResult.isInProgress() && pathResult.getJob() instanceof PathJobRandomPos) - { - return pathResult; - } - - desiredPos = BlockPos.ZERO; - final int theRange = (mob.getRandom().nextInt(range) + range / 2); @NotNull final BlockPos start = PathfindingUtils.prepareStart(ourEntity); - final PathResult result = setPathJob(new PathJobRandomPos(CompatibilityUtils.getWorldFromEntity(ourEntity), + final PathResult result = setPathJob(new PathJobRandomPos(CompatibilityUtils.getWorldFromEntity(ourEntity), start, - theRange, + range, (int) ourEntity.getAttribute(Attributes.FOLLOW_RANGE).getValue(), ourEntity, corners.getA(), @@ -242,12 +221,24 @@ public PathResult moveToRandomPos( return null; } - result.getJob().getPathingOptions().withJumpCost(1).withDropCost(1); + result.getJob().getPathingOptions().withJumpCost(1).withDropCost(1).canDrop = false; return result; } + @Override + protected PathResult walkCloseToXNearY( + final BlockPos desiredPosition, + final BlockPos nearbyPosition, + final int distToDesired, + final double speedFactor, + final boolean safeDestination) + { + PathJobMoveCloseToXNearY pathJob = new PathJobMoveCloseToXNearY(ourEntity.level, desiredPosition, nearbyPosition, 1, ourEntity); + return setPathJob(pathJob, desiredPosition, speedFactor, safeDestination); + } + @Nullable - public PathResult setPathJob( + public PathResult setPathJob( @NotNull final AbstractPathJob job, final BlockPos dest, final double speedFactor, final boolean safeDestination) @@ -258,6 +249,18 @@ public PathResult setPathJob( } stop(); + if (dest != null && !dest.equals(BlockPos.ZERO)) + { + if (job.getStart().distSqr(dest) > 500 * 500) + { + Log.getLogger() + .error( + "Entity: " + ourEntity.getDisplayName().getString() + " is trying to walk too far! distance:" + Math.sqrt(job.getStart().distSqr(dest)) + " from:" + + job.getStart() + " to:" + + dest, new Exception()); + return null; + } + } this.destination = dest; this.originalDestination = dest; @@ -281,7 +284,7 @@ public PathResult setPathJob( job.setPathingOptions(getPathingOptions()); pathResult = job.getResult(); pathResult.startJob(Pathfinding.getExecutor()); - return pathResult; + return (PathResult) pathResult; } @Override @@ -438,56 +441,23 @@ public static double getSmartGroundY(final BlockGetter world, final BlockPos.Mut } @Nullable - public PathResult moveToXYZ(final double x, final double y, final double z, final double speedFactor) + protected PathResult walkTo(final BlockPos desiredPos, final double speedFactor, final boolean safeDestination) { - final int newX = Mth.floor(x); - final int newY = (int) y; - final int newZ = Mth.floor(z); - - if (pathResult != null && pathResult.getJob() instanceof PathJobMoveToLocation) - { - if (pathResult.isComputing()) - { - return pathResult; - } - - if (((destination != null && BlockPosUtil.equals(destination, newX, newY, newZ)) || (originalDestination != null && BlockPosUtil.equals(originalDestination, - newX, - newY, - newZ)))) - { - if (pathResult.getStatus() == IN_PROGRESS_FOLLOWING || ColonyConstants.rand.nextInt(20) != 0) - { - return pathResult; - } - } - } - @NotNull final BlockPos start = PathfindingUtils.prepareStart(ourEntity); - desiredPos = new BlockPos(newX, newY, newZ); - - if (start.distSqr(desiredPos) > 500 * 500) - { - Log.getLogger() - .error( - "Entity: " + ourEntity.getDisplayName().getString() + " is trying to walk too far! distance:" + Math.sqrt(start.distSqr(desiredPos)) + " from:" + start + " to:" - + desiredPos, new Exception()); - return null; - } - return setPathJob( new PathJobMoveToLocation(CompatibilityUtils.getWorldFromEntity(ourEntity), start, desiredPos, (int) ourEntity.getAttribute(Attributes.FOLLOW_RANGE).getValue(), ourEntity), - desiredPos, speedFactor, true); + desiredPos, speedFactor, safeDestination); } + @Deprecated(since = "Do not use, always returns true, vanilla override") @Override - public boolean tryMoveToBlockPos(final BlockPos pos, final double speedFactor) + public boolean walkTo(final BlockPos pos, final double speedFactor) { - moveToXYZ(pos.getX(), pos.getY(), pos.getZ(), speedFactor); + walkTo(pos, speedFactor, false); return true; } @@ -586,31 +556,25 @@ public void setSpeedModifier(final double speedFactor) walkSpeedFactor = speedFactor; } - /** - * Deprecated - try to use BlockPos instead - */ + @Deprecated(since = "Do not use, always returns true, vanilla override") @Override public boolean moveTo(final double x, final double y, final double z, final double speedFactor) { - if (x == 0 && y == 0 && z == 0) - { - return false; - } - - moveToXYZ(x, y, z, speedFactor); + walkTo(BlockPos.containing(x, y, z), speedFactor, false); return true; } @Override public boolean moveTo(final Entity entityIn, final double speedFactor) { - return tryMoveToBlockPos(entityIn.blockPosition(), speedFactor); + return walkTo(entityIn.blockPosition(), speedFactor); } // Removes stupid vanilla stuff, causing our pathpoints to occasionally be replaced by vanilla ones. @Override protected void trimPath() {} + @Deprecated(since = "Do not use, always returns true, vanilla override") @Override public boolean moveTo(@Nullable final Path path, final double speedFactor) { @@ -619,7 +583,6 @@ public boolean moveTo(@Nullable final Path path, final double speedFactor) super.stop(); return false; } - pathStartTime = level.getGameTime(); return super.moveTo(convertPath(path), speedFactor); } @@ -1115,7 +1078,7 @@ public void stop() } @Override - public TreePathResult moveToTree( + public TreePathResult walkToTree( final BlockPos startRestriction, final BlockPos endRestriction, final double speed, @@ -1141,7 +1104,7 @@ public TreePathResult moveToTree( } @Override - public TreePathResult moveToTree(final int range, final double speed, final List excludedTrees, final int dyntreesize, final IColony colony) + public TreePathResult walkToTree(final int range, final double speed, final List excludedTrees, final int dyntreesize, final IColony colony) { @NotNull BlockPos start = PathfindingUtils.prepareStart(ourEntity); final BlockPos buildingPos = ((AbstractEntityCitizen) mob).getCitizenColonyHandler().getWorkBuilding().getPosition(); @@ -1157,16 +1120,16 @@ public TreePathResult moveToTree(final int range, final double speed, final List @Nullable @Override - public PathResult moveToLivingEntity(@NotNull final Entity e, final double speed) + public PathResult walkToEntity(@NotNull final Entity e, final double speed) { - return moveToXYZ(e.getX(), e.getY(), e.getZ(), speed); + return walkTo(e.blockPosition(), speed, false); } @Nullable @Override - public PathResult moveAwayFromLivingEntity(@NotNull final Entity e, final double distance, final double speed) + public PathResult moveAwayFromLivingEntity(@NotNull final Entity e, final double distance, final double speed) { - return moveAwayFromXYZ(e.blockPosition(), distance, speed, true); + return walkAwayFrom(e.blockPosition(), distance, speed, true); } @Override diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathfindingAIHelper.java b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathfindingAIHelper.java deleted file mode 100644 index 4a596badd3d..00000000000 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathfindingAIHelper.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.minecolonies.core.entity.pathfinding.navigation; - -import com.minecolonies.api.entity.other.AbstractFastMinecoloniesEntity; -import com.minecolonies.api.util.BlockPosUtil; -import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveCloseToXNearY; -import net.minecraft.core.BlockPos; - -public class PathfindingAIHelper -{ - /** - * Tries to walk close to a given pos, staying near another position. - * - * @param entity - * @param desiredPosition - * @param nearbyPosition - * @param distToDesired - * @return True while walking, false when reached - */ - public static boolean walkCloseToXNearY( - final AbstractFastMinecoloniesEntity entity, final BlockPos desiredPosition, - final BlockPos nearbyPosition, - final int distToDesired) - { - final MinecoloniesAdvancedPathNavigate nav = ((MinecoloniesAdvancedPathNavigate) entity.getNavigation()); - - // Three cases - // 1. Navigation Finished - // 2. Navigation is progressing towards a previous task - // 3. Navigation did not try once - boolean isOnRightTask = (nav.getPathResult() != null - && nav.getPathResult().getJob() instanceof PathJobMoveCloseToXNearY job - && job.nearbyPosition.equals(nearbyPosition) - && job.desiredPosition.equals(desiredPosition)); - - if (nav.isDone() || !isOnRightTask) - { - if (isOnRightTask) - { - // Check distance once navigation is done, to let the entity walk - if (BlockPosUtil.dist(entity.blockPosition(), desiredPosition) < distToDesired) - { - nav.stop(); - return false; - } - } - - PathJobMoveCloseToXNearY pathJob = new PathJobMoveCloseToXNearY(entity.level, desiredPosition, nearbyPosition, 1, entity); - nav.setPathJob(pathJob, desiredPosition, 1.0, false); - } - - return true; - } -} diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathingStuckHandler.java b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathingStuckHandler.java index b02e0c6f46d..b58fac9dd67 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathingStuckHandler.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathingStuckHandler.java @@ -149,6 +149,7 @@ public static PathingStuckHandler createStuckHandler() @Override public void checkStuck(final AbstractAdvancedPathNavigate navigator) { + // TODO: rework to allow paths to nonsafe locations still benefit from non-teleport options(skip ahead, reset path etc) if (navigator.getDesiredPos() == null || navigator.getDesiredPos().equals(BlockPos.ZERO)) { resetGlobalStuckTimers(); @@ -338,7 +339,7 @@ private void tryUnstuck(final AbstractAdvancedPathNavigate navigator) navigator.stop(); final int range = ColonyConstants.rand.nextInt(20) + Math.min(100, Math.max(20, BlockPosUtil.distManhattan(navigator.ourEntity.blockPosition(), prevDestination))); - navigator.moveTowards(navigator.getOurEntity().blockPosition().relative(movingAwayDir, 40), range, 1.0f); + navigator.walkTowards(navigator.getOurEntity().blockPosition().relative(movingAwayDir, 40), range, 1.0f); movingAwayDir = movingAwayDir.getClockWise(); navigator.setPauseTicks(range * TICKS_PER_BLOCK); return; diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java index 4b76b8066f4..84890d07d08 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java @@ -149,7 +149,7 @@ public abstract class AbstractPathJob implements Callable, IPathJob /** * Heuristic modifier */ - private double heuristicMod = 1; + private double heuristicMod = 2; /** * First node @@ -192,6 +192,10 @@ public AbstractPathJob(final Level world, @NotNull final BlockPos start, int ran result.setJob(this); this.entity = entity; + if (entity != null && entity.getNavigation() instanceof IDynamicHeuristicNavigator navigator) + { + heuristicMod = 1 + navigator.getAvgHeuristicModifier(); + } } /** @@ -218,6 +222,10 @@ protected AbstractPathJob(final Level actualWorld, final LevelReader chunkCache, result.setJob(this); this.entity = entity; + if (entity != null && entity.getNavigation() instanceof IDynamicHeuristicNavigator navigator) + { + heuristicMod = 1 + navigator.getAvgHeuristicModifier(); + } } /** @@ -256,6 +264,10 @@ public AbstractPathJob(final Level world, @NotNull final BlockPos start, @NotNul this.result = result; result.setJob(this); this.entity = entity; + if (entity != null && entity.getNavigation() instanceof IDynamicHeuristicNavigator navigator) + { + heuristicMod = 1 + navigator.getAvgHeuristicModifier(); + } } /** @@ -285,7 +297,7 @@ public final Path call() */ private MNode getAndSetupStartNode() { - final MNode startNode = new MNode(null, start.getX(), start.getY(), start.getZ(), 0, computeHeuristic(start.getX(), start.getY(), start.getZ())); + final MNode startNode = new MNode(null, start.getX(), start.getY(), start.getZ(), 0, computeHeuristic(start.getX(), start.getY(), start.getZ()) * heuristicMod); if (PathfindingUtils.isLadder(cachedBlockLookup.getBlockState(start.getX(), start.getY(), start.getZ()), pathingOptions)) { diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveAwayFromLocation.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveAwayFromLocation.java index 582ff0d55c8..0e10ffa7080 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveAwayFromLocation.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveAwayFromLocation.java @@ -135,4 +135,19 @@ public BlockPos getDestination() { return preferredDirection; } + + /** + * Helper to compare if the given move away job matches the input parameters + * + * @return true if the given job is the same + */ + public static boolean isJobFor(final AbstractPathJob job, final int avoidDistance, final BlockPos toAvoid) + { + if (job instanceof PathJobMoveAwayFromLocation pathJob) + { + return pathJob.avoidDistance == avoidDistance && pathJob.avoid.equals(toAvoid); + } + + return false; + } } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveCloseToXNearY.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveCloseToXNearY.java index 66db7c3cad8..ac43838b65b 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveCloseToXNearY.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveCloseToXNearY.java @@ -60,7 +60,7 @@ protected boolean isAtDestination(@NotNull final MNode n) return false; } - return BlockPosUtil.distManhattan(desiredPosition, n.x, n.y, n.z) < distToDesired + return BlockPosUtil.distManhattan(desiredPosition, n.x, n.y, n.z) <= distToDesired && SurfaceType.getSurfaceType(world, cachedBlockLookup.getBlockState(n.x, n.y - 1, n.z), tempWorldPos.set(n.x, n.y - 1, n.z), getPathingOptions()) == SurfaceType.WALKABLE; } @@ -105,4 +105,19 @@ public BlockPos getDestination() { return desiredPosition; } + + /** + * Helper to compare if the given move close to X near Y job matches the input parameters + * + * @return true if the given job is the same + */ + public static boolean isJobFor(final AbstractPathJob job, final BlockPos desiredPosition, final BlockPos nearbyPosition, final int distance) + { + if (job instanceof PathJobMoveCloseToXNearY pathJob) + { + return pathJob.nearbyPosition.equals(desiredPosition) && pathJob.nearbyPosition.equals(nearbyPosition) && pathJob.distToDesired == distance; + } + + return false; + } } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveToLocation.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveToLocation.java index a7097d8cc90..53421e1ff3c 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveToLocation.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveToLocation.java @@ -6,7 +6,6 @@ import com.minecolonies.core.entity.pathfinding.MNode; import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.SurfaceType; -import com.minecolonies.core.entity.pathfinding.navigation.IDynamicHeuristicNavigator; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Mob; @@ -28,11 +27,6 @@ public class PathJobMoveToLocation extends AbstractPathJob implements IDestinati // 0 = exact match private float destinationSlack = DESTINATION_SLACK_NONE; - /** - * Modifier to the heuristics - */ - private double heuristicModifier = 1; - /** * Prepares the PathJob for the path finding system. * @@ -49,13 +43,6 @@ public PathJobMoveToLocation(final Level world, @NotNull final BlockPos start, @ maxNodes += range; this.destination = new BlockPos(end); - if (entity != null && entity.getNavigation() instanceof IDynamicHeuristicNavigator) - { - heuristicModifier = ((IDynamicHeuristicNavigator) entity.getNavigation()).getAvgHeuristicModifier(); - } - - // Overestimate for long distances, +1 per 100 blocks - heuristicModifier += BlockPosUtil.distManhattan(start, end) / 100.0; extraNodes = 4; } @@ -80,7 +67,7 @@ protected Path search() @Override protected double computeHeuristic(final int x, final int y, final int z) { - return BlockPosUtil.distManhattan(destination, x, y, z) * heuristicModifier; + return BlockPosUtil.distManhattan(destination, x, y, z); } /** @@ -174,4 +161,19 @@ public BlockPos getDestination() { return destination; } + + /** + * Helper to compare if the given move to location job matches the input parameters + * + * @return true if the given job is the same + */ + public static boolean isJobFor(final AbstractPathJob job, final BlockPos desiredPosition) + { + if (job instanceof PathJobMoveToLocation pathJob) + { + return pathJob.getDestination().equals(desiredPosition); + } + + return false; + } } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobRandomPos.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobRandomPos.java index b70c2b0fb7d..c4f77836cf1 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobRandomPos.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobRandomPos.java @@ -5,7 +5,6 @@ import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.PathingOptions; import com.minecolonies.core.entity.pathfinding.SurfaceType; -import com.minecolonies.core.entity.pathfinding.navigation.IDynamicHeuristicNavigator; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Mob; @@ -38,11 +37,7 @@ public class PathJobRandomPos extends AbstractPathJob implements IDestinationPat * Box restriction area */ private AABB restrictionBox = null; - - /** - * Modifier to the heuristics - */ - private double heuristicModifier = 1.0; + private BlockPos restrictionBoxCenter = null; /** * Prepares the PathJob for the path finding system. @@ -65,11 +60,6 @@ public PathJobRandomPos( this.maxDistToDest = -1; this.destination = BlockPosUtil.getRandomPosAround(start, minDistFromStart); - - if (entity != null && entity.getNavigation() instanceof IDynamicHeuristicNavigator) - { - heuristicModifier = ((IDynamicHeuristicNavigator) entity.getNavigation()).getAvgHeuristicModifier(); - } } /** @@ -122,7 +112,7 @@ public PathJobRandomPos( Math.max(startRestriction.getX(), endRestriction.getX()), Math.max(startRestriction.getY(), endRestriction.getY()), Math.max(startRestriction.getZ(), endRestriction.getZ())); - + restrictionBoxCenter = BlockPos.containing(restrictionBox.getCenter()); this.minDistFromStart = minDistFromStart; this.maxDistToDest = -1; @@ -132,7 +122,12 @@ public PathJobRandomPos( @Override protected double computeHeuristic(final int x, final int y, final int z) { - return BlockPosUtil.distManhattan(destination, x, y, z) * heuristicModifier; + if (restrictionBox != null) + { + return (BlockPosUtil.distManhattan(destination, x, y, z) + BlockPosUtil.distManhattan(restrictionBoxCenter, x, y, z) / 2.0); + } + + return BlockPosUtil.distManhattan(destination, x, y, z); } @Override @@ -172,7 +167,7 @@ public void setPathingOptions(final PathingOptions pathingOptions) */ public boolean posAndRangeMatch(final int range, final BlockPos pos) { - return destination != null && pos != null && range == maxDistToDest && destination.equals(pos); + return; } @Override @@ -180,4 +175,19 @@ public BlockPos getDestination() { return destination; } + + /** + * Helper to compare if the given random pos job matches the input parameters + * + * @return true if the given job is the same + */ + public static boolean isJobFor(final AbstractPathJob job, final BlockPos center, final int range) + { + if (job instanceof PathJobRandomPos pathJob) + { + return pathJob.destination != null && pathJob.destination.equals(center) && pathJob.maxDistToDest == range; + } + + return false; + } } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/proxy/EntityCitizenWalkToProxy.java b/src/main/java/com/minecolonies/core/entity/pathfinding/proxy/EntityCitizenWalkToProxy.java index b02676f410f..fbea2a62064 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/proxy/EntityCitizenWalkToProxy.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/proxy/EntityCitizenWalkToProxy.java @@ -11,16 +11,16 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingMiner; import com.minecolonies.core.colony.jobs.AbstractJobGuard; import com.minecolonies.core.colony.jobs.JobMiner; -import com.minecolonies.core.entity.ai.workers.util.MinerLevel; import com.minecolonies.core.entity.ai.workers.util.MineNode; -import com.minecolonies.core.util.WorkerUtil; -import net.minecraft.world.entity.Mob; -import net.minecraft.core.Direction; +import com.minecolonies.core.entity.ai.workers.util.MinerLevel; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.entity.Mob; import org.jetbrains.annotations.NotNull; import java.util.*; +// TODO: Rework public class EntityCitizenWalkToProxy extends AbstractWalkToProxy { /** @@ -269,11 +269,35 @@ private void calculateNodes(final MinerLevel level, final int levelDepth, final @Override public boolean isLivingAtSiteWithMove(final Mob entity, final int x, final int y, final int z, final int range) { - if (!WorkerUtil.isWorkerAtSiteWithMove((AbstractEntityCitizen) entity, x, y, z, range)) + if (!isWorkerAtSiteWithMove((AbstractEntityCitizen) entity, x, y, z, range)) { EntityUtils.tryMoveLivingToXYZ(entity, x, y, z); return false; } return true; } + + /** + * Checks if a worker is at his working site. If he isn't, sets it's path to the location. + * + * @param worker Worker to check + * @param x X-coordinate + * @param y Y-coordinate + * @param z Z-coordinate + * @param range Range to check in + * @return True if worker is at site, otherwise false. + */ + public static boolean isWorkerAtSiteWithMove(@NotNull final AbstractEntityCitizen worker, final int x, final int y, final int z, final int range) + { + if (!EntityUtils.isLivingAtSiteWithMove(worker, x, y, z, range)) + { + //If not moving the try setting the point where the entity should move to + if (worker.getNavigation().isDone()) + { + EntityUtils.tryMoveLivingToXYZ(worker, x, y, z); + } + return false; + } + return true; + } } diff --git a/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java b/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java index 7b5745b1487..f6427bfc7f8 100644 --- a/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java @@ -5,10 +5,8 @@ import com.minecolonies.api.colony.permissions.Action; import com.minecolonies.api.colony.requestsystem.StandardFactoryController; import com.minecolonies.api.colony.requestsystem.location.ILocation; -import com.minecolonies.api.entity.CustomGoalSelector; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.entity.citizen.citizenhandlers.*; -import com.minecolonies.api.entity.pathfinding.proxy.IWalkToProxy; import com.minecolonies.api.inventory.InventoryCitizen; import com.minecolonies.api.inventory.container.ContainerCitizenInventory; import com.minecolonies.api.util.*; @@ -24,9 +22,11 @@ import com.minecolonies.core.entity.ai.minimal.LookAtEntityInteractGoal; import com.minecolonies.core.entity.ai.visitor.EntityAIVisitor; import com.minecolonies.core.entity.citizen.EntityCitizen; -import com.minecolonies.core.entity.citizen.citizenhandlers.*; +import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenExperienceHandler; +import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenInventoryHandler; +import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenJobHandler; +import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenSleepHandler; import com.minecolonies.core.entity.pathfinding.navigation.MovementHandler; -import com.minecolonies.core.entity.pathfinding.proxy.EntityCitizenWalkToProxy; import com.minecolonies.core.network.messages.client.ItemParticleEffectMessage; import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage; import com.minecolonies.core.util.citizenutils.CitizenItemUtils; @@ -78,10 +78,6 @@ public class VisitorCitizen extends AbstractEntityCitizen * It's citizen Id. */ private int citizenId = 0; - /** - * The Walk to proxy (Shortest path through intermediate blocks). - */ - private IWalkToProxy proxy; /** * Reference to the data representation inside the colony. */ @@ -200,23 +196,6 @@ public boolean hurt(@NotNull final DamageSource damageSource, final float damage return false; } - /** - * Checks if a worker is at his working site. If he isn't, sets it's path to the location - * - * @param site the place where he should walk to - * @param range Range to check in - * @return True if worker is at site, otherwise false. - */ - @Override - public boolean isWorkerAtSiteWithMove(@NotNull final BlockPos site, final int range) - { - if (proxy == null) - { - proxy = new EntityCitizenWalkToProxy(this); - } - return proxy.walkToBlock(site, range, true); - } - @Nullable @Override public ICitizenData getCitizenData() @@ -283,12 +262,6 @@ public void playMoveAwaySound() } - @Override - public IWalkToProxy getProxy() - { - return proxy; - } - @Override public void decreaseSaturationForAction() { diff --git a/src/main/java/com/minecolonies/core/util/TeleportHelper.java b/src/main/java/com/minecolonies/core/util/TeleportHelper.java index 77b1ccc2700..6e1ae9f89bb 100755 --- a/src/main/java/com/minecolonies/core/util/TeleportHelper.java +++ b/src/main/java/com/minecolonies/core/util/TeleportHelper.java @@ -6,13 +6,13 @@ import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.EntityUtils; import com.minecolonies.api.util.MessageUtils; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.resources.ResourceKey; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.Level; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.TicketType; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; import org.jetbrains.annotations.NotNull; import static com.minecolonies.api.util.constant.translation.CommandTranslationConstants.COMMAND_COLONY_ID_NOT_FOUND; @@ -51,6 +51,7 @@ public static boolean teleportCitizen(final AbstractEntityCitizen citizen, final citizen.getCitizenSleepHandler().onWakeUp(); } + citizen.getNavigation().stop(); citizen.stopRiding(); citizen.moveTo( spawnPoint.getX() + MIDDLE_BLOCK_OFFSET, @@ -58,16 +59,6 @@ public static boolean teleportCitizen(final AbstractEntityCitizen citizen, final spawnPoint.getZ() + MIDDLE_BLOCK_OFFSET, citizen.getRotationYaw(), citizen.getRotationPitch()); - if (citizen.getProxy() != null) - { - citizen.getProxy().reset(); - } - citizen.getNavigation().stop(); - if (citizen.getProxy() != null) - { - citizen.getProxy().reset(); - } - return true; } diff --git a/src/main/java/com/minecolonies/core/util/WorkerUtil.java b/src/main/java/com/minecolonies/core/util/WorkerUtil.java index d42a9028a8e..16a16fc770d 100755 --- a/src/main/java/com/minecolonies/core/util/WorkerUtil.java +++ b/src/main/java/com/minecolonies/core/util/WorkerUtil.java @@ -7,9 +7,9 @@ import com.minecolonies.api.crafting.ItemStorage; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; import com.minecolonies.api.equipment.ModEquipmentTypes; +import com.minecolonies.api.equipment.registry.EquipmentTypeEntry; import com.minecolonies.api.inventory.InventoryCitizen; import com.minecolonies.api.items.ModTags; -import com.minecolonies.api.equipment.registry.EquipmentTypeEntry; import com.minecolonies.api.util.EntityUtils; import com.minecolonies.api.util.ItemStackUtils; import com.minecolonies.api.util.Tuple; @@ -18,7 +18,6 @@ import com.minecolonies.core.colony.buildings.modules.SettingsModule; import com.minecolonies.core.colony.buildings.workerbuildings.BuildingFlorist; import com.minecolonies.core.entity.ai.workers.util.MinerLevel; -import com.minecolonies.core.entity.citizen.EntityCitizen; import com.minecolonies.core.tileentities.TileEntityCompostedDirt; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -109,43 +108,6 @@ public static boolean isPathBlock(final Block block) return block.defaultBlockState().is(ModTags.pathingBlocks); } - /** - * {@link WorkerUtil#isWorkerAtSiteWithMove(AbstractEntityCitizen, int, int, int, int)}. - * - * @param worker Worker to check. - * @param site Chunk coordinates of site to check. - * @param range Range to check in. - * @return True when within range, otherwise false. - */ - public static boolean isWorkerAtSiteWithMove(@NotNull final EntityCitizen worker, @NotNull final BlockPos site, final int range) - { - return isWorkerAtSiteWithMove(worker, site.getX(), site.getY(), site.getZ(), range); - } - - /** - * Checks if a worker is at his working site. If he isn't, sets it's path to the location. - * - * @param worker Worker to check - * @param x X-coordinate - * @param y Y-coordinate - * @param z Z-coordinate - * @param range Range to check in - * @return True if worker is at site, otherwise false. - */ - public static boolean isWorkerAtSiteWithMove(@NotNull final AbstractEntityCitizen worker, final int x, final int y, final int z, final int range) - { - if (!EntityUtils.isLivingAtSiteWithMove(worker, x, y, z, range)) - { - //If not moving the try setting the point where the entity should move to - if (worker.getNavigation().isDone()) - { - EntityUtils.tryMoveLivingToXYZ(worker, x, y, z); - } - return false; - } - return true; - } - /** * Recalls the citizen, notifies player if not successful. *