diff --git a/src/main/java/de/ellpeck/naturesaura/entities/EntityMoverMinecart.java b/src/main/java/de/ellpeck/naturesaura/entities/EntityMoverMinecart.java new file mode 100644 index 00000000..9c2e719d --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/entities/EntityMoverMinecart.java @@ -0,0 +1,137 @@ +package de.ellpeck.naturesaura.entities; + +import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; +import de.ellpeck.naturesaura.items.ModItems; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagLong; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; + +import java.util.ArrayList; +import java.util.List; + +public class EntityMoverMinecart extends EntityMinecart { + + private final List spotOffsets = new ArrayList<>(); + private BlockPos lastPosition = BlockPos.ORIGIN; + public boolean isActive; + + public EntityMoverMinecart(World worldIn) { + super(worldIn); + } + + public EntityMoverMinecart(World worldIn, double x, double y, double z) { + super(worldIn, x, y, z); + } + + @Override + public void moveMinecartOnRail(BlockPos railPos) { + super.moveMinecartOnRail(railPos); + if (!this.isActive) + return; + BlockPos pos = this.getPosition(); + if (pos.distanceSq(this.lastPosition) < 8 * 8) + return; + + for (BlockPos offset : this.spotOffsets) { + BlockPos spot = this.lastPosition.add(offset); + IAuraChunk chunk = IAuraChunk.getAuraChunk(this.world, spot); + int amount = chunk.getDrainSpot(spot); + if (amount <= 0) + continue; + int toMove = Math.min(amount, 3000); + int drained = chunk.drainAura(spot, toMove, false, false); + if (drained <= 0) + continue; + int toLose = MathHelper.ceil(drained / 250F); + BlockPos newSpot = pos.add(offset); + IAuraChunk.getAuraChunk(this.world, newSpot).storeAura(newSpot, drained - toLose, false, false); + } + this.lastPosition = pos; + } + + @Override + public void onActivatorRailPass(int x, int y, int z, boolean receivingPower) { + if (this.isActive != receivingPower) { + this.isActive = receivingPower; + + if (!this.isActive) { + this.spotOffsets.clear(); + this.lastPosition = BlockPos.ORIGIN; + return; + } + + BlockPos pos = this.getPosition(); + IAuraChunk.getSpotsInArea(this.world, pos, 25, (spot, amount) -> { + if (amount > 0) + this.spotOffsets.add(spot.subtract(pos)); + }); + this.lastPosition = pos; + } + } + + @Override + protected void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setBoolean("active", this.isActive); + compound.setLong("last_pos", this.lastPosition.toLong()); + + NBTTagList list = new NBTTagList(); + for (BlockPos offset : this.spotOffsets) + list.appendTag(new NBTTagLong(offset.toLong())); + compound.setTag("offsets", list); + } + + @Override + protected void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.isActive = compound.getBoolean("active"); + this.lastPosition = BlockPos.fromLong(compound.getLong("last_pos")); + + this.spotOffsets.clear(); + NBTTagList list = compound.getTagList("offsets", Constants.NBT.TAG_LONG); + for (NBTBase base : list) + this.spotOffsets.add(BlockPos.fromLong(((NBTTagLong) base).getLong())); + } + + @Override + public IBlockState getDisplayTile() { + return Blocks.STONE.getDefaultState(); + } + + @Override + public Type getType() { + return Type.RIDEABLE; + } + + @Override + public ItemStack getCartItem() { + return new ItemStack(ModItems.MOVER_MINECART); + } + + @Override + public ItemStack getPickedResult(RayTraceResult target) { + return new ItemStack(ModItems.MOVER_MINECART); + } + + @Override + public boolean canBeRidden() { + return false; + } + + @Override + protected void applyDrag() { + this.motionX *= 0.99F; + this.motionY *= 0.0D; + this.motionZ *= 0.99F; + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/entities/ModEntities.java b/src/main/java/de/ellpeck/naturesaura/entities/ModEntities.java index 17140b61..65514eff 100644 --- a/src/main/java/de/ellpeck/naturesaura/entities/ModEntities.java +++ b/src/main/java/de/ellpeck/naturesaura/entities/ModEntities.java @@ -2,6 +2,7 @@ package de.ellpeck.naturesaura.entities; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.entities.render.RenderEffectInhibitor; +import de.ellpeck.naturesaura.entities.render.RenderMoverMinecart; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.registry.EntityRegistry; @@ -11,7 +12,13 @@ public final class ModEntities { EntityRegistry.registerModEntity( new ResourceLocation(NaturesAura.MOD_ID, "effect_inhibitor"), EntityEffectInhibitor.class, NaturesAura.MOD_ID + ".effect_inhibitor", - 0, NaturesAura.MOD_ID, 64, 1, false); + 0, NaturesAura.MOD_ID, 64, 20, false); NaturesAura.proxy.registerEntityRenderer(EntityEffectInhibitor.class, () -> RenderEffectInhibitor::new); + + EntityRegistry.registerModEntity( + new ResourceLocation(NaturesAura.MOD_ID, "mover_cart"), + EntityMoverMinecart.class, NaturesAura.MOD_ID + ".mover_cart", + 1, NaturesAura.MOD_ID, 64, 3, true); + NaturesAura.proxy.registerEntityRenderer(EntityMoverMinecart.class, () -> RenderMoverMinecart::new); } } diff --git a/src/main/java/de/ellpeck/naturesaura/entities/render/RenderMoverMinecart.java b/src/main/java/de/ellpeck/naturesaura/entities/render/RenderMoverMinecart.java new file mode 100644 index 00000000..1f457d72 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/entities/render/RenderMoverMinecart.java @@ -0,0 +1,17 @@ +package de.ellpeck.naturesaura.entities.render; + +import de.ellpeck.naturesaura.entities.EntityMoverMinecart; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.RenderMinecart; + +public class RenderMoverMinecart extends RenderMinecart { + public RenderMoverMinecart(RenderManager renderManagerIn) { + super(renderManagerIn); + } + + @Override + protected void renderCartContents(EntityMoverMinecart cart, float partialTicks, IBlockState state) { + + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/items/ItemMoverMinecart.java b/src/main/java/de/ellpeck/naturesaura/items/ItemMoverMinecart.java new file mode 100644 index 00000000..e2e24fde --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/items/ItemMoverMinecart.java @@ -0,0 +1,35 @@ +package de.ellpeck.naturesaura.items; + +import de.ellpeck.naturesaura.entities.EntityMoverMinecart; +import net.minecraft.block.BlockRailBase; +import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import javax.annotation.Nonnull; + +public class ItemMoverMinecart extends ItemImpl { + + public ItemMoverMinecart() { + super("mover_cart"); + this.setMaxStackSize(1); + } + + @Nonnull + @Override + public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { + if (BlockRailBase.isRailBlock(world.getBlockState(pos))) { + if (!world.isRemote) { + EntityMinecart cart = new EntityMoverMinecart(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + world.spawnEntity(cart); + } + player.getHeldItem(hand).shrink(1); + return EnumActionResult.SUCCESS; + } + return EnumActionResult.PASS; + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/items/ModItems.java b/src/main/java/de/ellpeck/naturesaura/items/ModItems.java index 16ee7c89..1efee405 100644 --- a/src/main/java/de/ellpeck/naturesaura/items/ModItems.java +++ b/src/main/java/de/ellpeck/naturesaura/items/ModItems.java @@ -43,4 +43,5 @@ public final class ModItems { public static final Item CALLING_SPIRIT = new ItemGlowing("calling_spirit"); public static final Item EFFECT_POWDER = new ItemEffectPowder(); public static final Item BIRTH_SPIRIT = new ItemBirthSpirit(); + public static final Item MOVER_MINECART = new ItemMoverMinecart(); }