Feeder block mostly implemented

This commit is contained in:
Michael Hillcox 2021-01-03 11:12:30 +00:00
parent 1995378d49
commit 4da92fd505
No known key found for this signature in database
GPG key ID: 971C5B254742488F
16 changed files with 422 additions and 15 deletions

View file

@ -122,7 +122,7 @@ e2c81adfe240117fa0ce2e3dfcfd04f4e1034153 assets/actuallyadditions/blockstates/wh
3670535838b4c26d01afe7ee4807c53a6cbaba12 assets/actuallyadditions/blockstates/white_wall_block.json 3670535838b4c26d01afe7ee4807c53a6cbaba12 assets/actuallyadditions/blockstates/white_wall_block.json
78e89628e3c6e891f2994b2a1794672f69826516 assets/actuallyadditions/blockstates/wood_casing_block.json 78e89628e3c6e891f2994b2a1794672f69826516 assets/actuallyadditions/blockstates/wood_casing_block.json
207adf3d139369e983100a6002f6f77d36d40916 assets/actuallyadditions/blockstates/xp_solidifier_block.json 207adf3d139369e983100a6002f6f77d36d40916 assets/actuallyadditions/blockstates/xp_solidifier_block.json
57f188ff4295a701102e0f7084a59d8b01a79112 assets/actuallyadditions/lang/en_us.json 05c5a950e54b4a1640a8afc2f596b6a636577761 assets/actuallyadditions/lang/en_us.json
997ea09e934d491608895093fc7ba8d2022a50f5 assets/actuallyadditions/models/block/black_brick_quartz_slab_block.json 997ea09e934d491608895093fc7ba8d2022a50f5 assets/actuallyadditions/models/block/black_brick_quartz_slab_block.json
fa8ed5a44ee7475368eaa6c8afcd2fdcc0342a4f assets/actuallyadditions/models/block/black_brick_quartz_slab_block_top.json fa8ed5a44ee7475368eaa6c8afcd2fdcc0342a4f assets/actuallyadditions/models/block/black_brick_quartz_slab_block_top.json
00fe865b4ff89f2a82cc40bf11c806fd5ef22130 assets/actuallyadditions/models/block/black_brick_quartz_stair_block.json 00fe865b4ff89f2a82cc40bf11c806fd5ef22130 assets/actuallyadditions/models/block/black_brick_quartz_stair_block.json

View file

@ -1,5 +1,9 @@
{ {
"actuallyadditions.gui.name.drill": "Drill", "actuallyadditions.gui.name.drill": "Drill",
"actuallyadditions.info.gui.animals": "%s Animals",
"actuallyadditions.info.gui.enoughToBreed": "Enough to breed!",
"actuallyadditions.info.gui.notEnough": "Not enough to breed!",
"actuallyadditions.info.gui.tooMany": "Too many to breed!",
"actuallyadditions.storage.crystal-flux": "%s/%s Crystal Flux", "actuallyadditions.storage.crystal-flux": "%s/%s Crystal Flux",
"actuallyadditions.tooltip.battery.charge-help": "Sneak-right-click to toggle", "actuallyadditions.tooltip.battery.charge-help": "Sneak-right-click to toggle",
"actuallyadditions.tooltip.battery.charging": "Charging other item in inventory", "actuallyadditions.tooltip.battery.charging": "Charging other item in inventory",

View file

@ -1,6 +1,7 @@
package de.ellpeck.actuallyadditions.client; package de.ellpeck.actuallyadditions.client;
import de.ellpeck.actuallyadditions.client.screens.DrillScreen; import de.ellpeck.actuallyadditions.client.screens.DrillScreen;
import de.ellpeck.actuallyadditions.client.screens.FeederScreen;
import de.ellpeck.actuallyadditions.common.container.ActuallyContainers; import de.ellpeck.actuallyadditions.common.container.ActuallyContainers;
import net.minecraft.client.gui.ScreenManager; import net.minecraft.client.gui.ScreenManager;
@ -11,5 +12,6 @@ public class ClientSetup {
private static void setupScreens() { private static void setupScreens() {
ScreenManager.registerFactory(ActuallyContainers.DRILL_CONTAINER.get(), DrillScreen::new); ScreenManager.registerFactory(ActuallyContainers.DRILL_CONTAINER.get(), DrillScreen::new);
ScreenManager.registerFactory(ActuallyContainers.FEEDER_CONTAINER.get(), FeederScreen::new);
} }
} }

View file

@ -0,0 +1,69 @@
package de.ellpeck.actuallyadditions.client.screens;
import com.mojang.blaze3d.matrix.MatrixStack;
import de.ellpeck.actuallyadditions.common.container.FeederContainer;
import de.ellpeck.actuallyadditions.common.tiles.FeederTileEntity;
import de.ellpeck.actuallyadditions.common.utilities.Help;
import de.ellpeck.actuallyadditions.common.utilities.ScreenHelper;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.ITextProperties;
import net.minecraft.util.text.LanguageMap;
import java.util.ArrayList;
import java.util.List;
public class FeederScreen extends WtfMojangScreen<FeederContainer> {
private static final ResourceLocation background = ScreenHelper.getGuiLocation("gui_feeder");
public final FeederTileEntity tileFeeder;
public FeederScreen(FeederContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
super(screenContainer, inv, titleIn);
this.xSize = 176;
this.ySize = 70 + 86;
this.titleY += 90;
this.tileFeeder = (FeederTileEntity) inv.player.world.getTileEntity(screenContainer.tile.getPos());
}
@Override
protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int x, int y) {
getMinecraft().getTextureManager().bindTexture(ScreenHelper.INVENTORY_GUI);
blit(matrixStack, this.guiLeft, this.guiTop + 70, 0, 0, 176, 86);
getMinecraft().getTextureManager().bindTexture(background);
blit(matrixStack, this.guiLeft, this.guiTop, 0, 0, 176, 70);
if (this.tileFeeder.currentTimer > 0) {
int i = this.tileFeeder.getCurrentTimerToScale(20);
this.blit(matrixStack, this.guiLeft + 85, this.guiTop + 42 - i, 181, 19 + 19 - i, 6, 20);
}
if (this.tileFeeder.currentAnimalAmount >= 2 && this.tileFeeder.currentAnimalAmount < FeederTileEntity.THRESHOLD) {
this.blit(matrixStack, this.guiLeft + 70, this.guiTop + 31, 192, 16, 8, 8);
}
if (this.tileFeeder.currentAnimalAmount >= FeederTileEntity.THRESHOLD) {
this.blit(matrixStack, this.guiLeft + 70, this.guiTop + 31, 192, 24, 8, 8);
}
}
@Override
public void render(MatrixStack matrixStack, int x, int y, float partialTicks) {
super.render(matrixStack, x, y, partialTicks);
if (x >= this.guiLeft + 69 && y >= this.guiTop + 30 && x <= this.guiLeft + 69 + 10 && y <= this.guiTop + 30 + 10) {
List<ITextProperties> array = new ArrayList<>();
array.add(Help.trans("info.gui.animals", this.tileFeeder.currentAnimalAmount));
array.add(tileFeeder.currentAnimalAmount >= 2 && tileFeeder.currentAnimalAmount < FeederTileEntity.THRESHOLD
? Help.trans("info.gui.enoughToBreed")
: tileFeeder.currentAnimalAmount >= FeederTileEntity.THRESHOLD
? Help.trans("info.gui.tooMany")
: Help.trans("info.gui.notEnough"));
this.renderToolTip(matrixStack, LanguageMap.getInstance().func_244260_a(array), x, y, font);
}
}
}

View file

@ -6,6 +6,7 @@ import de.ellpeck.actuallyadditions.common.commands.DebugCommand;
import de.ellpeck.actuallyadditions.common.config.Config; import de.ellpeck.actuallyadditions.common.config.Config;
import de.ellpeck.actuallyadditions.common.container.ActuallyContainers; import de.ellpeck.actuallyadditions.common.container.ActuallyContainers;
import de.ellpeck.actuallyadditions.common.items.ActuallyItems; import de.ellpeck.actuallyadditions.common.items.ActuallyItems;
import de.ellpeck.actuallyadditions.common.tiles.ActuallyTiles;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup; import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.command.Commands; import net.minecraft.command.Commands;
@ -46,6 +47,7 @@ public class ActuallyAdditions {
ActuallyBlocks.BLOCKS.register(eventBus); ActuallyBlocks.BLOCKS.register(eventBus);
ActuallyItems.ITEMS.register(eventBus); ActuallyItems.ITEMS.register(eventBus);
ActuallyContainers.CONTAINERS.register(eventBus); ActuallyContainers.CONTAINERS.register(eventBus);
ActuallyTiles.TILES.register(eventBus);
eventBus.addListener(this::setup); eventBus.addListener(this::setup);
eventBus.addListener(this::clientSetup); eventBus.addListener(this::clientSetup);

View file

@ -1,16 +1,27 @@
package de.ellpeck.actuallyadditions.common.blocks.functional; package de.ellpeck.actuallyadditions.common.blocks.functional;
import de.ellpeck.actuallyadditions.common.blocks.ActuallyBlock; import de.ellpeck.actuallyadditions.common.blocks.ActuallyBlock;
import de.ellpeck.actuallyadditions.common.tiles.ActuallyTiles;
import de.ellpeck.actuallyadditions.common.tiles.FeederTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;
import javax.annotation.Nullable;
import java.util.stream.Stream; import java.util.stream.Stream;
public class FeederBlock extends ActuallyBlock { public class FeederBlock extends ActuallyBlock {
@ -33,8 +44,33 @@ public class FeederBlock extends ActuallyBlock {
Block.makeCuboidShape(12, 14, 1, 15, 15, 15), Block.makeCuboidShape(1, 1, 1, 15, 2, 15), Block.makeCuboidShape(12, 14, 1, 15, 15, 15), Block.makeCuboidShape(1, 1, 1, 15, 2, 15),
Block.makeCuboidShape(14, 2, 1, 15, 14, 15), Block.makeCuboidShape(1, 2, 1, 2, 14, 15), Block.makeCuboidShape(14, 2, 1, 15, 14, 15), Block.makeCuboidShape(1, 2, 1, 2, 14, 15),
Block.makeCuboidShape(2, 2, 14, 14, 14, 15), Block.makeCuboidShape(2, 2, 1, 14, 14, 2) Block.makeCuboidShape(2, 2, 14, 14, 14, 15), Block.makeCuboidShape(2, 2, 1, 14, 14, 2)
).reduce((v1, v2) -> {return VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR);}).get(); ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get();
@Nullable
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return ActuallyTiles.FEEDER_TILE.get().create();
}
@Override
public boolean hasTileEntity(BlockState state) {
return true;
}
@Override
public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
if (worldIn.isRemote) {
return ActionResultType.SUCCESS;
}
TileEntity te = worldIn.getTileEntity(pos);
if (! (te instanceof FeederTileEntity)) {
return ActionResultType.FAIL;
}
NetworkHooks.openGui((ServerPlayerEntity) player, (FeederTileEntity) te, pos);
return ActionResultType.SUCCESS;
}
@Override @Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {

View file

@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package de.ellpeck.actuallyadditions.common.blocks.functional;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -5,14 +5,20 @@ import static net.minecraftforge.common.ForgeConfigSpec.*;
public class GeneralConfig { public class GeneralConfig {
public final BooleanValue advancedInfo; public final BooleanValue advancedInfo;
public final IntValue tileEntityUpdateInterval;
public GeneralConfig() { public GeneralConfig() {
CLIENT_BUILDER.comment("Actually Additions General Config").push("general"); CLIENT_BUILDER.comment("Actually Additions General Config").push("general");
SERVER_BUILDER.comment("Actually Additions General Config").push("general");
advancedInfo = CLIENT_BUILDER advancedInfo = CLIENT_BUILDER
.comment("Shows advanced item info when holding control on every item") .comment("Shows advanced item info when holding control on every item")
.define("Advanced Info", true); .define("Advanced Info", true);
tileEntityUpdateInterval = CLIENT_BUILDER
.comment("The amount of ticks waited before a TileEntity sends an additional update to the client")
.defineInRange("Tile Entities Update Interval", 5, 1, 100);
CLIENT_BUILDER.pop(); CLIENT_BUILDER.pop();
} }
} }

View file

@ -12,4 +12,7 @@ public final class ActuallyContainers {
public static final RegistryObject<ContainerType<DrillContainer>> DRILL_CONTAINER public static final RegistryObject<ContainerType<DrillContainer>> DRILL_CONTAINER
= CONTAINERS.register("drill_container", () -> IForgeContainerType.create(DrillContainer::fromNetwork)); = CONTAINERS.register("drill_container", () -> IForgeContainerType.create(DrillContainer::fromNetwork));
public static final RegistryObject<ContainerType<FeederContainer>> FEEDER_CONTAINER
= CONTAINERS.register("feeder_container", () -> IForgeContainerType.create(FeederContainer::fromNetwork));
} }

View file

@ -0,0 +1,63 @@
package de.ellpeck.actuallyadditions.common.container;
import de.ellpeck.actuallyadditions.common.tiles.FeederTileEntity;
import de.ellpeck.actuallyadditions.common.utilities.ContainerHelper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper;
import java.util.Objects;
public class FeederContainer extends Container {
private final PlayerInventory inv;
public final FeederTileEntity tile;
public static FeederContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer data) {
return new FeederContainer(windowId, inv, (FeederTileEntity) Objects.requireNonNull(inv.player.world.getTileEntity(data.readBlockPos())));
}
public FeederContainer(int windowId, PlayerInventory inv, FeederTileEntity tile) {
super(ActuallyContainers.FEEDER_CONTAINER.get(), windowId);
this.inv = inv;
this.tile = tile;
ContainerHelper.setupPlayerInventory(new InvWrapper(inv), 0, ContainerHelper.DEFAULT_SLOTS_X, 132, this::addSlot);
this.tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(e -> addSlot(new SlotItemHandler(e, 0, 80, 45)));
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return true;
}
@Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
Slot fromSlot = this.inventorySlots.get(index);
if (fromSlot == null || !fromSlot.getHasStack()) {
return ItemStack.EMPTY;
}
ItemStack fromStack = fromSlot.getStack();
if (index > ContainerHelper.PLAYER_INVENTORY_END_SLOT) {
if (!this.mergeItemStack(fromStack, 0, ContainerHelper.PLAYER_INVENTORY_END_SLOT, false)) {
return ItemStack.EMPTY;
}
} else {
if (!this.mergeItemStack(fromStack, ContainerHelper.PLAYER_INVENTORY_END_SLOT + 1, ContainerHelper.PLAYER_INVENTORY_END_SLOT + 2, false)) {
return ItemStack.EMPTY;
}
}
return fromStack;
}
}

View file

@ -56,15 +56,13 @@ public class DrillItem extends CrystalFluxItem {
private static final int BASE_ENERGY_USE = 100; private static final int BASE_ENERGY_USE = 100;
public DrillItem() { public DrillItem() {
super( super(baseProps()
baseProps()
.maxDamage(0) .maxDamage(0)
.setNoRepair() .setNoRepair()
.addToolType(ToolType.PICKAXE, 4) .addToolType(ToolType.PICKAXE, 4)
.addToolType(ToolType.SHOVEL, 4), .addToolType(ToolType.SHOVEL, 4),
Config.ITEM_CONFIG.drillMaxEnergy::get, Config.ITEM_CONFIG.drillMaxEnergy::get,
1000 1000);
);
} }
@Override @Override
@ -98,7 +96,7 @@ public class DrillItem extends CrystalFluxItem {
int crystalFlux = getCrystalFlux(stack).map(IEnergyStorage::getEnergyStored).orElse(0); int crystalFlux = getCrystalFlux(stack).map(IEnergyStorage::getEnergyStored).orElse(0);
int fluxPerBlock = this.getFluxPerBlock(stack); int fluxPerBlock = this.getFluxPerBlock(stack);
if (crystalFlux < fluxPerBlock) { if (crystalFlux < fluxPerBlock && !player.isCreative()) {
return false; return false;
} }
@ -140,9 +138,10 @@ public class DrillItem extends CrystalFluxItem {
Set<BlockPos> posSet = new HashSet<>(); Set<BlockPos> posSet = new HashSet<>();
int y = radius == 2 ? pos.getY() + 1 : pos.getY();
// Uses the facing axis to move around the X,Y,Z to allow for multiple faces in 2 for loops // Uses the facing axis to move around the X,Y,Z to allow for multiple faces in 2 for loops
int a = axis != Direction.Axis.X ? pos.getX() : pos.getY(); // Z & Y plane both use X int a = axis != Direction.Axis.X ? pos.getX() : y; // Z & Y plane both use X
int b = axis != Direction.Axis.Z ? pos.getZ() : pos.getY(); // X & Y plane both use Z int b = axis != Direction.Axis.Z ? pos.getZ() : y; // X & Y plane both use Z
for (int i = (a - radius); i < (a + radius) + 1; i++) { for (int i = (a - radius); i < (a + radius) + 1; i++) {
for (int j = (b - radius); j < (b + radius) + 1; j++) { for (int j = (b - radius); j < (b + radius) + 1; j++) {
@ -156,11 +155,11 @@ public class DrillItem extends CrystalFluxItem {
} }
Set<BlockPos> failed = new HashSet<>(); Set<BlockPos> failed = new HashSet<>();
posSet.forEach(e -> { for (BlockPos e : posSet) {
if (!destroyBlock(e, pick.getFace(), player, world, drill, drillEnchanted, fluxPerBlock, (cost) -> getCrystalFlux(drill).ifPresent(x -> x.extractEnergy(cost, false)))) { if (!destroyBlock(e, pick.getFace(), player, world, drill, drillEnchanted, fluxPerBlock, (cost) -> getCrystalFlux(drill).ifPresent(x -> x.extractEnergy(cost, false)))) {
failed.add(e); failed.add(e);
} }
}); }
return failed.contains(pick.getPos()); return failed.contains(pick.getPos());
} }
@ -180,14 +179,14 @@ public class DrillItem extends CrystalFluxItem {
* *
* @return returns false if the block gets blocked by another mod * @return returns false if the block gets blocked by another mod
*/ */
// Todo: if we ever need this again, move to world helper // TODO: if we ever need this again, move to world helper
private boolean destroyBlock(BlockPos pos, Direction face, PlayerEntity player, World world, ItemStack drill, ItemStack drillEnchanted, int fluxPerBlock, Consumer<Integer> onBreak) { private boolean destroyBlock(BlockPos pos, Direction face, PlayerEntity player, World world, ItemStack drill, ItemStack drillEnchanted, int fluxPerBlock, Consumer<Integer> onBreak) {
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
int flux = this.getCrystalFlux(drill).map(IEnergyStorage::getEnergyStored).orElse(0); int flux = this.getCrystalFlux(drill).map(IEnergyStorage::getEnergyStored).orElse(0);
if (world.isAirBlock(pos) if (world.isAirBlock(pos)
|| flux < fluxPerBlock || (flux < fluxPerBlock && !player.isCreative())
|| state.getBlockHardness(world, pos) <= 0f || state.getBlockHardness(world, pos) <= 0
|| !ForgeHooks.canHarvestBlock(state, player, world, pos)) { || !ForgeHooks.canHarvestBlock(state, player, world, pos)) {
return false; return false;
} }
@ -207,7 +206,6 @@ public class DrillItem extends CrystalFluxItem {
((ServerPlayerEntity) player).connection.sendPacket(new SChangeBlockPacket(world, pos)); ((ServerPlayerEntity) player).connection.sendPacket(new SChangeBlockPacket(world, pos));
} }
onBreak.accept(fluxPerBlock);
return true; return true;
} }

View file

@ -0,0 +1,49 @@
package de.ellpeck.actuallyadditions.common.tiles;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.server.ServerWorld;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.stream.Stream;
public class ActuallyTile extends TileEntity {
public ActuallyTile(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
}
@Override
public CompoundNBT getUpdateTag() {
return this.write(new CompoundNBT());
}
@Override
public void handleUpdateTag(BlockState state, CompoundNBT tag) {
this.read(state, tag);
}
@Override
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
this.read(this.getBlockState(), pkt.getNbtCompound());
}
@Nullable
@Override
public SUpdateTileEntityPacket getUpdatePacket() {
return new SUpdateTileEntityPacket(this.pos, -1, this.serializeNBT());
}
public void sendTileEntityToClients() {
ServerWorld world = (ServerWorld) this.getWorld();
Stream<ServerPlayerEntity> entities = world.getChunkProvider().chunkManager.getTrackingPlayers(new ChunkPos(this.getPos()), false);
SUpdateTileEntityPacket packet = this.getUpdatePacket();
entities.forEach(e -> e.connection.sendPacket(Objects.requireNonNull(packet)));
}
}

View file

@ -0,0 +1,14 @@
package de.ellpeck.actuallyadditions.common.tiles;
import de.ellpeck.actuallyadditions.common.ActuallyAdditions;
import de.ellpeck.actuallyadditions.common.blocks.ActuallyBlocks;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
public final class ActuallyTiles {
public static final DeferredRegister<TileEntityType<?>> TILES = DeferredRegister.create(ForgeRegistries.TILE_ENTITIES, ActuallyAdditions.MOD_ID);
public static final RegistryObject<TileEntityType<FeederTileEntity>> FEEDER_TILE = TILES.register("feeder_tile", () -> TileEntityType.Builder.create(FeederTileEntity::new, ActuallyBlocks.FEEDER.get()).build(null));
}

View file

@ -0,0 +1,142 @@
package de.ellpeck.actuallyadditions.common.tiles;
import de.ellpeck.actuallyadditions.common.container.FeederContainer;
import net.minecraft.block.BlockState;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
public class FeederTileEntity extends ActuallyTile implements INamedContainerProvider, ITickableTileEntity {
public static final int THRESHOLD = 30;
private static final int TIME = 100;
private final ItemStackHandler itemStackHandler = new ItemStackHandler(1) {
@Override
protected void onContentsChanged(int slot) {
FeederTileEntity.this.markDirty();
}
};
private final LazyOptional<IItemHandler> handler = LazyOptional.of(() -> itemStackHandler);
public int currentTimer;
public int currentAnimalAmount;
public FeederTileEntity() {
super(ActuallyTiles.FEEDER_TILE.get());
}
@Override
public void tick() {
int last = this.currentTimer;
this.currentTimer = MathHelper.clamp(this.currentTimer + 1, 0, 100);
if (this.world == null || this.world.isRemote) {
return;
}
ItemStack stack = this.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).map(e -> e.getStackInSlot(0)).orElse(ItemStack.EMPTY);
if (stack.isEmpty()) {
return;
}
List<AnimalEntity> animals = this.world.getEntitiesWithinAABB(AnimalEntity.class, new AxisAlignedBB(pos).grow(5));
this.currentAnimalAmount = animals.size();
if (last != this.currentTimer) {
System.out.println(this.currentAnimalAmount);
this.sendTileEntityToClients();
}
if (this.currentAnimalAmount < 2 || this.currentAnimalAmount > THRESHOLD || this.currentTimer < TIME) {
return;
}
for (AnimalEntity animal : animals) {
if (animal.getGrowingAge() != 0 || animal.isInLove() || !animal.isBreedingItem(stack)) {
continue;
}
animal.setInLove(null);
for (int i = 0; i < 7; i++) {
double d = animal.world.rand.nextGaussian() * 0.02D;
double d1 = animal.world.rand.nextGaussian() * 0.02D;
double d2 = animal.world.rand.nextGaussian() * 0.02D;
animal.world.addParticle(ParticleTypes.HEART, animal.getPosX() + animal.world.rand.nextFloat() * animal.getWidth() * 2.0F - animal.getWidth(), animal.getPosY() + 0.5D + animal.world.rand.nextFloat() * animal.getHealth(), animal.getPosZ() + animal.world.rand.nextFloat() * animal.getWidth() * 2.0F - animal.getWidth(), d, d1, d2);
}
stack.shrink(1);
this.currentTimer = 0;
this.markDirty();
this.sendTileEntityToClients();
break;
}
}
public int getCurrentTimerToScale(int i) {
return this.currentTimer * i / TIME;
}
@Override
public ITextComponent getDisplayName() {
return StringTextComponent.EMPTY;
}
@Nullable
@Override
public Container createMenu(int windowId, PlayerInventory playerInventory, PlayerEntity playerEntity) {
return new FeederContainer(windowId, playerInventory, this);
}
@Override
public void read(BlockState state, CompoundNBT nbt) {
super.read(state, nbt);
this.currentTimer = nbt.getInt("timer");
this.currentAnimalAmount = nbt.getInt("animals");
if (nbt.contains("items")) {
itemStackHandler.deserializeNBT(nbt.getCompound("items"));
}
}
@Override
public CompoundNBT write(CompoundNBT compound) {
compound.put("items", itemStackHandler.serializeNBT());
compound.putInt("timer", this.currentTimer);
compound.putInt("animals", this.currentAnimalAmount);
return super.write(compound);
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return handler.cast();
}
return super.getCapability(cap, side);
}
@Override
public void remove() {
super.remove();
handler.invalidate();
}
}

View file

@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package de.ellpeck.actuallyadditions.common.tiles;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -341,6 +341,11 @@ public class GeneratorLanguage extends LanguageProvider {
// Screen names // Screen names
addPrefixed("gui.name.drill", "Drill"); addPrefixed("gui.name.drill", "Drill");
addPrefixed("info.gui.animals","%s Animals");
addPrefixed("info.gui.enoughToBreed","Enough to breed!");
addPrefixed("info.gui.tooMany","Too many to breed!");
addPrefixed("info.gui.notEnough","Not enough to breed!");
// Storage // Storage
addPrefixed("storage.crystal-flux", "%s/%s Crystal Flux"); addPrefixed("storage.crystal-flux", "%s/%s Crystal Flux");