use of com.minecolonies.api.entity.ai.citizen.builder.IBuilderUndestroyable in project minecolonies by Minecolonies.
the class AbstractEntityAIInteract method mineBlock.
/**
* Will simulate mining a block with particles ItemDrop etc. Attention: Because it simulates delay, it has to be called 2 times. So make sure the code path up to this function
* is reachable a second time. And make sure to immediately exit the update function when this returns false.
*
* @param blockToMine the block that should be mined
* @param safeStand the block we want to stand on to do that
* @param damageTool boolean wether we want to damage the tool used
* @param getDrops boolean wether we want to get Drops
* @param blockBreakAction Runnable that is used instead of the default block break action, can be null
* @return true once we're done
*/
protected final boolean mineBlock(@NotNull final BlockPos blockToMine, @NotNull final BlockPos safeStand, final boolean damageTool, final boolean getDrops, final Runnable blockBreakAction) {
final BlockState curBlockState = world.getBlockState(blockToMine);
@Nullable final Block curBlock = curBlockState.getBlock();
if (curBlock instanceof AirBlock || curBlock instanceof IBuilderUndestroyable || curBlock == Blocks.BEDROCK) {
if (curBlockState.getMaterial().isLiquid()) {
world.removeBlock(blockToMine, false);
}
// no need to mine block...
return true;
}
if (checkMiningLocation(blockToMine, safeStand)) {
// we have to wait for delay
return false;
}
final ItemStack tool = worker.getMainHandItem();
if (getDrops) {
// calculate fortune enchantment
final int fortune = ItemStackUtils.getFortuneOf(tool);
// check if tool has Silk Touch
final boolean silkTouch = ItemStackUtils.hasSilkTouch(tool);
// create list for all item drops to be stored in
List<ItemStack> localItems = new ArrayList<ItemStack>();
// Checks to see if the equipped tool has Silk Touch AND if the blocktoMine has a viable Item SilkTouch can get.
if (silkTouch && Item.byBlock(BlockPosUtil.getBlock(world, blockToMine)) != null) {
// Stores Silk Touch Block in localItems
final ItemStack silkItem = new ItemStack(Item.byBlock(BlockPosUtil.getBlock(world, blockToMine)), 1);
localItems.add(silkItem);
} else // If Silk Touch doesn't work, get blocks with Fortune value as normal.
{
localItems.addAll(BlockPosUtil.getBlockDrops(world, blockToMine, fortune, tool, worker));
}
localItems = increaseBlockDrops(localItems);
// add the drops to the citizen
for (final ItemStack item : localItems) {
InventoryUtils.transferItemStackIntoNextBestSlotInItemHandler(item, worker.getInventoryCitizen());
}
}
triggerMinedBlock(curBlockState);
if (blockBreakAction == null) {
// Break the block
worker.getCitizenItemHandler().breakBlockWithToolInHand(blockToMine);
} else {
blockBreakAction.run();
}
if (tool != ItemStack.EMPTY && damageTool) {
tool.getItem().inventoryTick(tool, world, worker, worker.getCitizenInventoryHandler().findFirstSlotInInventoryWith(tool.getItem()), true);
}
worker.getCitizenExperienceHandler().addExperience(XP_PER_BLOCK);
this.incrementActionsDone();
return true;
}
use of com.minecolonies.api.entity.ai.citizen.builder.IBuilderUndestroyable in project minecolonies by Minecolonies.
the class EntityAIQuarrier method structureStep.
@Override
protected IAIState structureStep() {
if (structurePlacer.getB().getStage() == null) {
return PICK_UP_RESIDUALS;
}
if (InventoryUtils.isItemHandlerFull(worker.getInventoryCitizen())) {
return INVENTORY_FULL;
}
worker.getCitizenStatusHandler().setLatestStatus(new TranslationTextComponent("com.minecolonies.coremod.status.building"));
checkForExtraBuildingActions();
// some things to do first! then we go to the actual phase!
// Fill workFrom with the position from where the builder should build.
// also ensure we are at that position.
final BlockPos progress = getProgressPos() == null ? NULL_POS : getProgressPos().getA();
final BlockPos worldPos = structurePlacer.getB().getProgressPosInWorld(progress);
if (getProgressPos() != null) {
structurePlacer.getB().setStage(getProgressPos().getB());
}
if (!progress.equals(NULL_POS) && !limitReached && (blockToMine == null ? !walkToConstructionSite(worldPos) : !walkToConstructionSite(blockToMine))) {
return getState();
}
limitReached = false;
final StructurePhasePlacementResult result;
final StructurePlacer placer = structurePlacer.getA();
switch(structurePlacer.getB().getStage()) {
case BUILD_SOLID:
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().decrement(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> !info.getBlockInfo().getState().getMaterial().isSolid() || isDecoItem(info.getBlockInfo().getState().getBlock()) || pos.getY() < worldPos.getY())), false);
if (progress.getY() != -1 && result.getIteratorPos().getY() < progress.getY()) {
structurePlacer.getB().nextStage();
this.storeProgressPos(new BlockPos(0, progress.getY() + 1, 0), structurePlacer.getB().getStage());
} else {
this.storeProgressPos(result.getIteratorPos(), structurePlacer.getB().getStage());
}
break;
case DECORATE:
if (progress.getY() >= structurePlacer.getB().getBluePrint().getSizeY()) {
structurePlacer.getB().nextStage();
this.storeProgressPos(new BlockPos(structurePlacer.getB().getBluePrint().getSizeX(), progress.getY() - 1, structurePlacer.getB().getBluePrint().getSizeZ() - 1), structurePlacer.getB().getStage());
return getState();
}
// not solid
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().increment(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> (info.getBlockInfo().getState().getMaterial().isSolid() && !isDecoItem(info.getBlockInfo().getState().getBlock())) || pos.getY() > worldPos.getY())), false);
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.FINISHED) {
structurePlacer.getB().nextStage();
this.storeProgressPos(new BlockPos(structurePlacer.getB().getBluePrint().getSizeX(), progress.getY() - 1, structurePlacer.getB().getBluePrint().getSizeZ() - 1), structurePlacer.getB().getStage());
} else if (progress.getY() != -1 && result.getIteratorPos().getY() > progress.getY()) {
structurePlacer.getB().nextStage();
this.storeProgressPos(new BlockPos(structurePlacer.getB().getBluePrint().getSizeX(), progress.getY() - 1, structurePlacer.getB().getBluePrint().getSizeZ() - 1), structurePlacer.getB().getStage());
} else {
this.storeProgressPos(result.getIteratorPos(), structurePlacer.getB().getStage());
}
break;
case CLEAR:
default:
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> handler.getWorld().getBlockState(pos).getBlock() instanceof IBuilderUndestroyable || handler.getWorld().getBlockState(pos).getBlock() == Blocks.BEDROCK || handler.getWorld().getBlockState(pos).getBlock() instanceof AirBlock || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockFluidSubstitution.get() || !handler.getWorld().getBlockState(pos).getFluidState().isEmpty()), false);
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.FINISHED) {
getOwnBuilding().nextStage();
getOwnBuilding().setProgressPos(null, null);
return COMPLETE_BUILD;
} else if (progress.getY() != -1 && (result.getIteratorPos().getY() < progress.getY() || result.getBlockResult().getWorldPos().getY() < worldPos.getY())) {
structurePlacer.getB().setStage(BUILD_SOLID);
this.storeProgressPos(new BlockPos(structurePlacer.getB().getBluePrint().getSizeX(), progress.getY() - 1, structurePlacer.getB().getBluePrint().getSizeZ() - 1), structurePlacer.getB().getStage());
} else {
this.storeProgressPos(result.getIteratorPos(), structurePlacer.getB().getStage());
}
break;
}
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.LIMIT_REACHED) {
this.limitReached = true;
}
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.MISSING_ITEMS) {
if (hasListOfResInInvOrRequest(this, result.getBlockResult().getRequiredItems(), result.getBlockResult().getRequiredItems().size() > 1) == RECALC) {
job.getWorkOrder().setRequested(false);
return LOAD_STRUCTURE;
}
return NEEDS_ITEM;
}
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.BREAK_BLOCK) {
final BlockPos currentWorldPos = result.getBlockResult().getWorldPos();
if (currentWorldPos.getY() < 5) {
getOwnBuilding().setProgressPos(null, null);
return COMPLETE_BUILD;
}
blockToMine = currentWorldPos;
return MINE_BLOCK;
}
if (MineColonies.getConfig().getServer().builderBuildBlockDelay.get() > 0) {
final double decrease = 1 - worker.getCitizenColonyHandler().getColony().getResearchManager().getResearchEffects().getEffectStrength(BLOCK_PLACE_SPEED);
setDelay((int) ((MineColonies.getConfig().getServer().builderBuildBlockDelay.get() * PROGRESS_MULTIPLIER / (getPlaceSpeedLevel() / 2 + PROGRESS_MULTIPLIER)) * decrease));
}
return getState();
}
use of com.minecolonies.api.entity.ai.citizen.builder.IBuilderUndestroyable in project minecolonies by ldtteam.
the class PathingStuckHandler method setAirIfPossible.
/**
* Check if the block at the position is indestructible, if not, attempt to break it.
*
* @param world the world the block is in.
* @param pos the pos the block is at.
*/
private void setAirIfPossible(final World world, final BlockPos pos) {
final Block blockAtPos = world.getBlockState(pos).getBlock();
if (blockAtPos instanceof IBuilderUndestroyable || ModTags.indestructible.contains(blockAtPos)) {
return;
}
world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState());
}
use of com.minecolonies.api.entity.ai.citizen.builder.IBuilderUndestroyable in project minecolonies by ldtteam.
the class BuildToolPlaceMessage method handleHut.
/**
* Handles the placement of huts.
*
* @param world World the hut is being placed into.
* @param player Who placed the hut.
* @param sn The name of the structure.
* @param rotation The number of times the structure should be rotated.
* @param buildPos The location the hut is being placed.
* @param mirror Whether or not the strcture is mirrored.
* @param state the state.
*/
private static void handleHut(@NotNull final World world, @NotNull final PlayerEntity player, final StructureName sn, final int rotation, @NotNull final BlockPos buildPos, final boolean mirror, final BlockState state) {
final Block blockAtPos = world.getBlockState(buildPos).getBlock();
if (blockAtPos instanceof IBuilderUndestroyable || ModTags.indestructible.contains(blockAtPos)) {
LanguageHandler.sendPlayerMessage(player, INDESTRUCTIBLE_BLOCK_AT_POS);
SoundUtils.playErrorSound(player, buildPos);
return;
}
final Block block = state.getBlock();
final ItemStack tempStack = new ItemStack(block, 1);
final int slot = InventoryUtils.findFirstSlotInItemHandlerWith(new InvWrapper(player.inventory), s -> ItemStackUtils.compareItemStacksIgnoreStackSize(tempStack, s, false, false));
if (slot < 0) {
return;
}
final ItemStack stack = player.inventory.getItem(slot);
final IColony tempColony = IColonyManager.getInstance().getClosestColony(world, buildPos);
if (tempColony != null && (!tempColony.getPermissions().hasPermission(player, Action.MANAGE_HUTS) && !(block instanceof BlockHutTownHall && IColonyManager.getInstance().isFarEnoughFromColonies(world, buildPos)))) {
return;
}
final CompoundNBT compound = stack.getTag();
if (tempColony != null && compound != null && compound.contains(TAG_COLONY_ID) && tempColony.getID() != compound.getInt(TAG_COLONY_ID)) {
LanguageHandler.sendPlayerMessage(player, WRONG_COLONY, compound.getInt(TAG_COLONY_ID));
return;
}
if (block != null && player.inventory.contains(new ItemStack(block))) {
if (EventHandler.onBlockHutPlaced(world, player, block, buildPos)) {
if (tempColony != null) {
AdvancementUtils.TriggerAdvancementPlayersForColony(tempColony, playerMP -> AdvancementTriggers.PLACE_STRUCTURE.trigger(playerMP, sn));
} else {
AdvancementTriggers.PLACE_STRUCTURE.trigger((ServerPlayerEntity) player, sn);
}
world.destroyBlock(buildPos, true);
world.setBlockAndUpdate(buildPos, state);
((AbstractBlockHut<?>) block).onBlockPlacedByBuildTool(world, buildPos, world.getBlockState(buildPos), player, null, mirror, sn.getStyle());
boolean complete = false;
int level = 0;
if (compound != null) {
if (compound.getAllKeys().contains(TAG_OTHER_LEVEL)) {
level = compound.getInt(TAG_OTHER_LEVEL);
}
if (compound.getAllKeys().contains(TAG_PASTEABLE)) {
String schematic = sn.toString();
schematic = schematic.substring(0, schematic.length() - 1);
schematic += level;
CreativeBuildingStructureHandler.loadAndPlaceStructureWithRotation(player.level, schematic, buildPos, BlockPosUtil.getRotationFromRotations(rotation), mirror ? Mirror.FRONT_BACK : Mirror.NONE, true, (ServerPlayerEntity) player);
complete = true;
}
}
InventoryUtils.reduceStackInItemHandler(new InvWrapper(player.inventory), stack, 1);
setupBuilding(world, player, sn, rotation, buildPos, mirror, level, complete);
}
} else {
LanguageHandler.sendPlayerMessage(player, NO_HUT_IN_INVENTORY);
}
}
use of com.minecolonies.api.entity.ai.citizen.builder.IBuilderUndestroyable in project minecolonies by ldtteam.
the class AbstractEntityAIStructure method structureStep.
/**
* The Structure step to execute the actual placement actions etc.
*
* @return the next step to go to.
*/
protected IAIState structureStep() {
if (structurePlacer.getB().getStage() == null) {
return PICK_UP_RESIDUALS;
}
if (InventoryUtils.isItemHandlerFull(worker.getInventoryCitizen())) {
return INVENTORY_FULL;
}
worker.getCitizenStatusHandler().setLatestStatus(new TranslationTextComponent("com.minecolonies.coremod.status.building"));
checkForExtraBuildingActions();
// some things to do first! then we go to the actual phase!
// Fill workFrom with the position from where the builder should build.
// also ensure we are at that position.
final BlockPos progress = getProgressPos() == null ? NULL_POS : getProgressPos().getA();
final BlockPos worldPos = structurePlacer.getB().getProgressPosInWorld(progress);
if (getProgressPos() != null) {
structurePlacer.getB().setStage(getProgressPos().getB());
}
if (!progress.equals(NULL_POS) && !limitReached && (blockToMine == null ? !walkToConstructionSite(worldPos) : !walkToConstructionSite(blockToMine))) {
return getState();
}
limitReached = false;
final StructurePhasePlacementResult result;
final StructurePlacer placer = structurePlacer.getA();
switch(structurePlacer.getB().getStage()) {
case BUILD_SOLID:
// structure
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().increment(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> !info.getBlockInfo().getState().getMaterial().isSolid() || isDecoItem(info.getBlockInfo().getState().getBlock()))), false);
break;
case CLEAR_WATER:
// water
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.WATER_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> handler.getWorld().getBlockState(pos).getFluidState().isEmpty()), false);
break;
case CLEAR_NON_SOLIDS:
// clear air
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().decrement(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> !(info.getBlockInfo().getState().getBlock() instanceof AirBlock) || (handler.getWorld().isEmptyBlock(pos)))), false);
break;
case DECORATE:
// not solid
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().increment(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> info.getBlockInfo().getState().getMaterial().isSolid() && !isDecoItem(info.getBlockInfo().getState().getBlock()))), false);
break;
case SPAWN:
// entities
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_PLACEMENT, () -> placer.getIterator().increment(DONT_TOUCH_PREDICATE.or((info, pos, handler) -> info.getEntities().length == 0)), true);
break;
case REMOVE_WATER:
// water
placer.getIterator().setRemoving();
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.WATER_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> info.getBlockInfo().getState().getFluidState().isEmpty()), false);
break;
case REMOVE:
placer.getIterator().setRemoving();
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> handler.getWorld().getBlockState(pos).getBlock() instanceof AirBlock || info.getBlockInfo().getState().getBlock() instanceof AirBlock || !handler.getWorld().getBlockState(pos).getFluidState().isEmpty() || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockSolidSubstitution.get() || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockSubstitution.get() || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockSubstitution.get() || handler.getWorld().getBlockState(pos).getBlock() instanceof IBuilderUndestroyable), true);
break;
case CLEAR:
default:
result = placer.executeStructureStep(world, null, progress, StructurePlacer.Operation.BLOCK_REMOVAL, () -> placer.getIterator().decrement((info, pos, handler) -> handler.getWorld().getBlockState(pos).getBlock() instanceof IBuilderUndestroyable || handler.getWorld().getBlockState(pos).getBlock() == Blocks.BEDROCK || handler.getWorld().getBlockState(pos).getBlock() instanceof AirBlock || info.getBlockInfo().getState().getBlock() == com.ldtteam.structurize.blocks.ModBlocks.blockFluidSubstitution.get() || !handler.getWorld().getBlockState(pos).getFluidState().isEmpty()), false);
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.FINISHED) {
getOwnBuilding().checkOrRequestBucket(getOwnBuilding().getRequiredResources(), worker.getCitizenData(), true);
}
break;
}
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.FAIL) {
Log.getLogger().error("Failed placement at: " + result.getBlockResult().getWorldPos().toShortString());
}
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.FINISHED) {
getOwnBuilding().nextStage();
if (!structurePlacer.getB().nextStage()) {
getOwnBuilding().setProgressPos(null, null);
return COMPLETE_BUILD;
}
} else if (result.getBlockResult().getResult() == BlockPlacementResult.Result.LIMIT_REACHED) {
this.limitReached = true;
}
this.storeProgressPos(result.getIteratorPos(), structurePlacer.getB().getStage());
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.MISSING_ITEMS) {
if (hasListOfResInInvOrRequest(this, result.getBlockResult().getRequiredItems(), result.getBlockResult().getRequiredItems().size() > 1) == RECALC) {
job.getWorkOrder().setRequested(false);
return LOAD_STRUCTURE;
}
return NEEDS_ITEM;
}
if (result.getBlockResult().getResult() == BlockPlacementResult.Result.BREAK_BLOCK) {
blockToMine = result.getBlockResult().getWorldPos();
return MINE_BLOCK;
} else {
blockToMine = null;
}
if (MineColonies.getConfig().getServer().builderBuildBlockDelay.get() > 0) {
final double decrease = 1 - worker.getCitizenColonyHandler().getColony().getResearchManager().getResearchEffects().getEffectStrength(BLOCK_PLACE_SPEED);
setDelay((int) ((MineColonies.getConfig().getServer().builderBuildBlockDelay.get() * PROGRESS_MULTIPLIER / (getPlaceSpeedLevel() / 2 + PROGRESS_MULTIPLIER)) * decrease));
}
return getState();
}
Aggregations