Implement Energy Portal
EnergonRelics/pipeline/head This commit looks good Details

This commit is contained in:
TheBrokenRail 2020-08-01 19:28:24 -04:00
parent 07f3cad621
commit 5a3f8c94e6
6 changed files with 109 additions and 10 deletions

View File

@ -10,7 +10,8 @@ compileJava {
version = project.mod_version
group = project.maven_group
minecraft {
loom {
accessWidener "src/main/resources/energonrelics.accesswidener"
}
repositories {

View File

@ -2,12 +2,18 @@ package com.thebrokenrail.energonrelics.block.portal;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.block.util.SimpleBlock;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.entity.Entity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.function.BooleanBiFunction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
@ -16,6 +22,8 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import java.util.Random;
@SuppressWarnings("deprecation")
public class EnergyPortalBlock extends SimpleBlock {
public EnergyPortalBlock() {
@ -27,11 +35,6 @@ public class EnergyPortalBlock extends SimpleBlock {
return false;
}
@Override
public VoxelShape getVisualShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return VoxelShapes.empty();
}
private static final VoxelShape SHAPE = createCuboidShape(0, 6, 0, 16, 10, 16);
@Override
@ -65,7 +68,7 @@ public class EnergyPortalBlock extends SimpleBlock {
return validSides == 4;
}
private static BlockPos getCenterPos(WorldAccess world, BlockPos pos) {
static BlockPos getCenterPos(WorldAccess world, BlockPos pos) {
BlockPos centerPos = pos;
for (Direction side : Direction.values()) {
if (isValidDirection(side)) {
@ -137,9 +140,19 @@ public class EnergyPortalBlock extends SimpleBlock {
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
super.onEntityCollision(state, world, pos, entity);
if (!world.isClient() && !entity.hasVehicle() && entity.canUsePortals() && ((PortalCooldownEntity) entity).isEnergyPortalCooldown()) {
// Teleport
if (!world.isClient() && !entity.hasVehicle() && entity.canUsePortals() && !((PortalCooldownEntity) entity).isEnergyPortalCooldown() && VoxelShapes.matchesAnywhere(VoxelShapes.cuboid(entity.getBoundingBox().offset(-pos.getX(), -pos.getY(), -pos.getZ())), state.getOutlineShape(world, pos), BooleanBiFunction.AND)) {
((PortalCooldownEntity) entity).resetEnergyPortalCooldown();
EnergyTeleporter.teleport((ServerWorld) world, entity.getPos(), pos, entity);
}
}
@Environment(EnvType.CLIENT)
@Override
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
super.randomDisplayTick(state, world, pos, random);
if (random.nextInt(100) == 0) {
world.playSound((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.BLOCK_PORTAL_AMBIENT, SoundCategory.BLOCKS, 0.5f, random.nextFloat() * 0.4f + 0.8f, false);
}
}
}

View File

@ -0,0 +1,81 @@
package com.thebrokenrail.energonrelics.block.portal;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.thebrokenrail.energonrelics.config.HardcodedConfig;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket;
import net.minecraft.server.command.TeleportCommand;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.Heightmap;
import net.minecraft.world.World;
import java.util.EnumSet;
class EnergyTeleporter {
private static void teleport(Entity entity, ServerWorld to, Vec3d pos) {
try {
TeleportCommand.teleport(null, entity, to, pos.getX(), pos.getY(), pos.getZ(), EnumSet.noneOf(PlayerPositionLookS2CPacket.Flag.class), entity.yaw, entity.pitch, null);
} catch (CommandSyntaxException ignored) {
}
}
static void teleport(ServerWorld world, Vec3d pos, BlockPos blockPos, Entity entity) {
BlockPos center = EnergyPortalBlock.getCenterPos(world, blockPos);
Vec3d offset = pos.subtract(Vec3d.ofBottomCenter(center));
RegistryKey<World> worldKey = world.getRegistryKey();
if (worldKey == World.OVERWORLD) {
teleportWithMultiplier(world, entity, center, offset, World.NETHER, 1d / HardcodedConfig.ENERGY_PORTAL_MULTIPLIER);
} else if (worldKey == World.NETHER) {
teleportWithMultiplier(world, entity, center, offset, World.OVERWORLD, HardcodedConfig.ENERGY_PORTAL_MULTIPLIER);
} else {
teleportToWorldSpawn(world, entity);
}
}
private static void teleportWithMultiplier(ServerWorld world, Entity entity, BlockPos center, Vec3d offset, RegistryKey<World> toKey, double multiplier) {
ServerWorld to = world.getServer().getWorld(toKey);
assert to != null;
float yMultiplier = (float) to.getDimensionHeight() / (float) world.getDimensionHeight();
int y = (int) (center.getY() * yMultiplier);
int x = (int) (center.getX() * multiplier);
int z = (int) (center.getZ() * multiplier);
BlockPos targetBlock = new BlockPos(x, y, z);
BlockPos start = targetBlock.add(-1, -1, -1);
for (int xPos = 0; xPos < 3; xPos++) {
for (int yPos = 0; yPos < 4; yPos++) {
for (int zPos = 0; zPos < 3; zPos++) {
BlockPos pos = start.add(xPos, yPos, zPos);
BlockState oldState = to.getBlockState(pos);
if (oldState.getHardness(world, pos) >= 0) {
Block block = yPos == 0 ? Blocks.OBSIDIAN : Blocks.AIR;
BlockState state = block.getDefaultState();
to.setBlockState(pos, state);
}
}
}
}
Vec3d target = Vec3d.ofBottomCenter(targetBlock).add(offset);
target = new Vec3d(target.getX(), Math.max(0, target.getY()), target.getZ());
teleport(entity, to, target);
}
private static void teleportToWorldSpawn(ServerWorld world, Entity entity) {
ServerWorld to = world.getServer().getWorld(World.OVERWORLD);
assert to != null;
BlockPos dest = to.getTopPosition(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, to.getSpawnPos());
teleport(entity, to, Vec3d.ofBottomCenter(dest));
}
}

View File

@ -46,5 +46,6 @@ public class HardcodedConfig {
public static final int INFUSER_TIME = 2200;
public static final long ENERGY_PROJECTOR_ENERGY_REQUIRED = 37;
public static final int ENERGY_PORTAL_COOLDOWN = 20;
public static final int ENERGY_PORTAL_COOLDOWN = 28;
public static final int ENERGY_PORTAL_MULTIPLIER = 32;
}

View File

@ -0,0 +1,2 @@
accessWidener v1 named
accessible method net/minecraft/server/command/TeleportCommand teleport (Lnet/minecraft/server/command/ServerCommandSource;Lnet/minecraft/entity/Entity;Lnet/minecraft/server/world/ServerWorld;DDDLjava/util/Set;FFLnet/minecraft/server/command/TeleportCommand$LookTarget;)V

View File

@ -32,6 +32,7 @@
"mixins": [
"energonrelics.mixins.json"
],
"accessWidener" : "energonrelics.accesswidener",
"depends": {
"fabricloader": ">=0.7.4",
"fabric": "*",