gnembon / carpet-extra

Extra Features for Carpet Mod
GNU Lesser General Public License v3.0
291 stars 62 forks source link

[REQUEST] Translocation #84

Open supersaiyansubtlety opened 4 years ago

supersaiyansubtlety commented 4 years ago

It would be great if we could restore translocation from MC1.10.

I remember seeing somewhere that this feature wouldn't be added to base carpet because translocation was a bug that had been fixed, but now carpet extra has restored dragon egg bedrock breaking.

Translocation seems like it's very similar to dragon egg bedrock breaking in that they were both very useful features for technical players while they were in the game and didn't really have downsides for other players, but were eventually patched nontheless.

Ghoulboy78 commented 4 years ago

actually translocation would break modern mob conveyors, and gnembon was pretty specific when he said he wouldn't add it back. And anyways there are still some remnants of the translocation bug in 1.16 vanilla, just they are kinda directional and obscure, but you can still in theory make a 1directional translocator using them.

supersaiyansubtlety commented 4 years ago

Ok, well it'd obviously be configurable, so it could be disabled if you want to use standard conveyors. I'm not sure what the relevance of extremely niche situations that result in translocating behavior is.

Do you know where gnembon originally wrote about translocation in carpet? I remember it but have no idea where from.

Ghoulboy78 commented 4 years ago

in his 1.12 video

zeichenreihe commented 3 years ago

I implementet translocation in a way that works for me, simply not translocate into B36 or ontop of a B36, it allows 320bps transport and only affects specific blocks (tnt duper don't translocate, because it would translocate in a MOVING_PISTON) (I know it's not good code...) (I don't do anything to the hitbox, I simply teleport the entity)

package yetAnotherCarpetAddon.mixins;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.PistonBlockEntity;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;

import java.util.Iterator;
import java.util.List;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import com.google.common.collect.Lists;

import yetAnotherCarpetAddon.YACASettings;

@Mixin(PistonBlockEntity.class)
public abstract class PistonBlockEntity_mixinTranslocation extends BlockEntity {
    @Shadow private boolean extending;
    @Shadow private boolean source;
    @Shadow private Direction facing;
    @Shadow private BlockState pushedBlock;
    @Shadow abstract BlockState getHeadBlockState();
    @Shadow abstract Box offsetHeadBox(Box box);

    private static final List<Block> TRANSLOCATION_BLOCKS;

    private boolean checkDoTransloction(Block checkedBlock) {
        return TRANSLOCATION_BLOCKS.contains(checkedBlock);
    }

    @Inject(method = "tick()V", at = @At("TAIL"))
    private void injected(CallbackInfo ci) {
        if(YACASettings.translocation) {
            if (!this.extending && this.source) {
                doTranslocation();
            }
            if(this.checkDoTransloction(this.pushedBlock.getBlock())) {
                doTranslocation();
            }
        }
    }

    private void doTranslocation() {
        BlockPos translocTo = this.getPos().offset(this.extending ? this.facing : this.facing.getOpposite(), 1);
        boolean wallbelow = !this.world.getBlockState(translocTo.down()).getBlock().equals(Blocks.MOVING_PISTON);

        if((!this.world.getBlockState(translocTo).getBlock().equals(Blocks.MOVING_PISTON)) && wallbelow){
            VoxelShape voxelShape = this.getHeadBlockState().getCollisionShape(this.world, this.getPos());
            if(voxelShape.isEmpty())
                voxelShape = Blocks.STONE.getCollisionShape(Blocks.STONE.getDefaultState(), this.world, this.getPos(), null);

            Box box = this.offsetHeadBox(voxelShape.getBoundingBox());
            //System.out.println(box.toString());

            List<Entity> list = this.world.getOtherEntities((Entity) null, box);
            int mod_value = 2;
            if (!list.isEmpty()) {
                if(this.extending)
                    mod_value = -2;

                Iterator list_iter = list.iterator();

                while (list_iter.hasNext()) {
                    Entity entity;
                    entity = (Entity) list_iter.next();
                    if(entity.getPistonBehavior() != PistonBehavior.IGNORE) {
                        Vec3d pos = entity.getPos();
                        double pos_x = pos.x;
                        double pos_y = pos.y;
                        double pos_z = pos.z;
                        switch(this.facing) {
                            case NORTH:
                                pos_z += mod_value;
                                break;
                            case SOUTH:
                                pos_z -= mod_value;
                                break;
                            case EAST:
                                pos_x -= mod_value;
                                break;
                            case WEST:
                                pos_x += mod_value;
                                break;
                            case UP:
                                pos_y -= mod_value;
                                break;
                            case DOWN:
                                pos_y += mod_value;
                                break;
                        }
                        entity.updatePosition(pos_x, pos_y, pos_z);
                    }
                }
            }
        }
    }
    public PistonBlockEntity_mixinTranslocation(BlockEntityType<?> blockEntityType_1) {
        super(blockEntityType_1);
    }

    static {
        TRANSLOCATION_BLOCKS = Lists.newArrayList(
            Blocks.DETECTOR_RAIL,
            Blocks.OAK_FENCE_GATE,
            Blocks.SPRUCE_FENCE_GATE,
            Blocks.BIRCH_FENCE_GATE,
            Blocks.JUNGLE_FENCE_GATE,
            Blocks.ACACIA_FENCE_GATE,
            Blocks.DARK_OAK_FENCE_GATE,
            Blocks.CRIMSON_FENCE_GATE,
            Blocks.WARPED_FENCE_GATE
        );
    }
}
DragonEggBedrockBreaking commented 3 years ago

I implementet translocation in a way that works for me, simply not translocate into B36 or ontop of a B36, it allows 320bps transport and only affects specific blocks (tnt duper don't translocate, because it would translocate in a MOVING_PISTON) (I know it's not good code...) (I don't do anything to the hitbox, I simply teleport the entity)

Can you make this into a mod and publish it please? I want to use it.

supersaiyansubtlety commented 3 years ago

Is johannes-schmatz implementation intended to be integrated into carpet-extra?

Also I recommend making TRANSLOCATION_BLOCKS a Tag<Block> populated from something like "<namespace>:translocation_blocks" so users can choose which block work with translocation.

zeichenreihe commented 3 years ago

Yes, it's just an example, that works for me. Feel free to implement. @DragonEggBedrockBreaking I want to publish my mod soon.