PrettyPipes/src/main/java/de/ellpeck/prettypipes/entities/PipeFrameEntity.java
2021-12-02 11:35:52 +01:00

176 lines
6.1 KiB
Java

package de.ellpeck.prettypipes.entities;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.network.NetworkLocation;
import de.ellpeck.prettypipes.network.PipeNetwork;
import de.ellpeck.prettypipes.pipe.PipeBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemFrameEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FilledMapItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.IPacket;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
import net.minecraft.world.storage.MapData;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.network.NetworkHooks;
import javax.annotation.Nullable;
import java.util.List;
public class PipeFrameEntity extends ItemFrameEntity implements IEntityAdditionalSpawnData {
private static final DataParameter<Integer> AMOUNT = EntityDataManager.createKey(PipeFrameEntity.class, DataSerializers.VARINT);
public PipeFrameEntity(EntityType<PipeFrameEntity> type, World world) {
super(type, world);
}
public PipeFrameEntity(EntityType<PipeFrameEntity> type, World world, BlockPos pos, Direction dir) {
this(type, world);
this.hangingPosition = pos;
this.updateFacingWithBoundingBox(dir);
}
@Override
protected void registerData() {
super.registerData();
this.dataManager.register(AMOUNT, -1);
}
@Override
public void tick() {
super.tick();
if (this.world.isRemote)
return;
if (this.ticksExisted % 40 != 0)
return;
PipeNetwork network = PipeNetwork.get(this.world);
BlockPos attached = getAttachedPipe(this.world, this.hangingPosition, this.facingDirection);
if (attached != null) {
BlockPos node = network.getNodeFromPipe(attached);
if (node != null) {
ItemStack stack = this.getDisplayedItem();
if (!stack.isEmpty()) {
List<NetworkLocation> items = network.getOrderedNetworkItems(node);
int amount = items.stream().mapToInt(i -> i.getItemAmount(this.world, stack)).sum();
this.dataManager.set(AMOUNT, amount);
return;
}
}
}
this.dataManager.set(AMOUNT, -1);
}
@Override
public boolean onValidSurface() {
return super.onValidSurface() && canPlace(this.world, this.hangingPosition, this.facingDirection);
}
private static BlockPos getAttachedPipe(World world, BlockPos pos, Direction direction) {
for (int i = 1; i <= 2; i++) {
BlockPos offset = pos.offset(direction.getOpposite(), i);
BlockState state = world.getBlockState(offset);
if (state.getBlock() instanceof PipeBlock)
return offset;
}
return null;
}
public static boolean canPlace(World world, BlockPos pos, Direction direction) {
return getAttachedPipe(world, pos, direction) != null;
}
public int getAmount() {
return this.dataManager.get(AMOUNT);
}
@Override
public boolean attackEntityFrom(DamageSource source, float amount) {
if (this.isInvulnerableTo(source)) {
return false;
} else if (!source.isExplosion() && !this.getDisplayedItem().isEmpty()) {
if (!this.world.isRemote) {
this.dropItemOrSelf(source.getTrueSource(), false);
this.playSound(SoundEvents.ENTITY_ITEM_FRAME_REMOVE_ITEM, 1.0F, 1.0F);
}
return true;
} else {
return super.attackEntityFrom(source, amount);
}
}
@Override
public void onBroken(@Nullable Entity brokenEntity) {
this.playSound(SoundEvents.ENTITY_ITEM_FRAME_BREAK, 1.0F, 1.0F);
this.dropItemOrSelf(brokenEntity, true);
}
private void dropItemOrSelf(@Nullable Entity entityIn, boolean b) {
if (!this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) {
if (entityIn == null)
this.getDisplayedItem().setAttachedEntity(null);
} else {
ItemStack itemstack = this.getDisplayedItem();
this.setDisplayedItem(ItemStack.EMPTY);
if (entityIn instanceof PlayerEntity) {
PlayerEntity playerentity = (PlayerEntity) entityIn;
if (playerentity.abilities.isCreativeMode) {
itemstack.setAttachedEntity(null);
return;
}
}
if (b)
this.entityDropItem(Registry.pipeFrameItem);
if (!itemstack.isEmpty()) {
itemstack = itemstack.copy();
itemstack.setAttachedEntity(null);
this.entityDropItem(itemstack);
}
}
}
@Override
public ActionResultType processInitialInteract(PlayerEntity player, Hand hand) {
if (this.getDisplayedItem().isEmpty())
return super.processInitialInteract(player, hand);
return ActionResultType.FAIL;
}
@Override
public ItemStack getPickedResult(RayTraceResult target) {
return new ItemStack(Registry.pipeFrameItem);
}
@Override
public IPacket<?> createSpawnPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public void writeSpawnData(PacketBuffer buffer) {
buffer.writeBlockPos(this.hangingPosition);
buffer.writeInt(this.facingDirection.getIndex());
}
@Override
public void readSpawnData(PacketBuffer additionalData) {
this.hangingPosition = additionalData.readBlockPos();
this.updateFacingWithBoundingBox(Direction.values()[additionalData.readInt()]);
}
}