Skip to content

Commit

Permalink
Fix cross dimensional Atem's Homecoming and return to Atum after deat…
Browse files Browse the repository at this point in the history
…h in foreign dimension (#391)

Co-authored-by: Steven Xu <stevendoesstuffs@protonmail.com>
  • Loading branch information
StevenDoesStuffs and Steven Xu committed Jun 3, 2022
1 parent f4b8044 commit d1e7dc4
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,23 @@
import com.teammetallurgy.atum.api.IArtifact;
import com.teammetallurgy.atum.init.AtumItems;
import com.teammetallurgy.atum.init.AtumParticles;
import com.teammetallurgy.atum.world.DimensionHelper;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Rarity;
import net.minecraft.network.play.server.SPlayerPositionLookPacket;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;

import javax.annotation.Nonnull;
import java.util.EnumSet;
import java.util.Set;
import java.util.*;

public class AtemsHomecomingItem extends Item implements IArtifact {

Expand Down Expand Up @@ -69,59 +66,20 @@ public ActionResult<ItemStack> onItemRightClick(@Nonnull World world, PlayerEnti
}

public static BlockPos recall(World world, PlayerEntity player) {
BlockPos pos = null;
if (world instanceof ServerWorld) {
ServerWorld serverWorld = (ServerWorld) world;
if (player instanceof ServerPlayerEntity) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
pos = serverPlayer.func_241140_K_(); //Bed pos
if (pos == null) {
BlockPos spawnPointPos = serverWorld.getSpawnPoint();
while (spawnPointPos.getY() > 1 && world.isAirBlock(spawnPointPos)) {
spawnPointPos = spawnPointPos.down();
}
while (!world.canBlockSeeSky(spawnPointPos)) {
spawnPointPos = spawnPointPos.up();
}
pos = new BlockPos(spawnPointPos.getX(), spawnPointPos.getY(), spawnPointPos.getZ());
}
}
}
if (pos != null) {
teleport(world, player, pos.getX(), pos.getY(), pos.getZ());
onTeleport(world, player);
}
return pos;
}

private static void teleport(World world, Entity entity, int x, int y, int z) {
float yaw = entity.rotationYaw;
float pitch = entity.rotationPitch;
if (entity instanceof ServerPlayerEntity) {
Set<SPlayerPositionLookPacket.Flags> set = EnumSet.noneOf(SPlayerPositionLookPacket.Flags.class);
float f = MathHelper.wrapDegrees(yaw);
float f1 = MathHelper.wrapDegrees(pitch);

entity.stopRiding();
onTeleport(world, entity);
((ServerPlayerEntity) entity).connection.setPlayerLocation(x, y, z, f, f1, set);
entity.setRotationYawHead(f);
} else {
float f2 = MathHelper.wrapDegrees(yaw);
float f3 = MathHelper.wrapDegrees(pitch);
f3 = MathHelper.clamp(f3, -90.0F, 90.0F);
entity.setLocationAndAngles(x, y, z, f2, f3);
entity.setRotationYawHead(f2);
}

if (!(entity instanceof LivingEntity) || !((LivingEntity) entity).isElytraFlying()) {
Vector3d motion = entity.getMotion();
entity.setMotion(new Vector3d(motion.x, 0.0D, motion.z));
entity.setOnGround(true);
}
if (!(world instanceof ServerWorld) || !(player instanceof ServerPlayerEntity)) return null;
ServerWorld serverWorld = (ServerWorld) world;
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
AbstractMap.SimpleEntry<ServerWorld, BlockPos> pair = DimensionHelper.validateAndGetSpawnPoint(serverWorld, serverPlayer, true);
ServerWorld spawnWorld = pair.getKey();
BlockPos spawnPos = pair.getValue();

playTeleportEffects(world, player);
serverPlayer.teleport(spawnWorld, spawnPos.getX() + 0.5, spawnPos.getY(), spawnPos.getZ() + 0.5, player.rotationYaw, player.rotationPitch);
playTeleportEffects(spawnWorld, player);
return spawnPos;
}

private static void onTeleport(World world, Entity entity) {
private static void playTeleportEffects(World world, Entity entity) {
if (world instanceof ServerWorld) {
float timesRandom = world.rand.nextFloat() * 4.0F;
float cosRandom = world.rand.nextFloat() * ((float) Math.PI * 2F);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.teammetallurgy.atum.items.WandererDyeableArmor;
import com.teammetallurgy.atum.items.artifacts.atem.AtemsBountyItem;
import com.teammetallurgy.atum.misc.AtumConfig;
import com.teammetallurgy.atum.misc.StackHelper;
import com.teammetallurgy.atum.world.DimensionHelper;
import com.teammetallurgy.atum.world.teleporter.TeleporterAtumStart;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
Expand Down Expand Up @@ -40,13 +40,11 @@
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.living.LivingDamageEvent;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.living.LivingSpawnEvent;
Expand All @@ -62,7 +60,6 @@
import net.minecraftforge.fml.common.Mod;

import java.util.List;
import java.util.Optional;

@Mod.EventBusSubscriber(modid = Atum.MOD_ID)
public class AtumEventListener {
Expand All @@ -82,8 +79,7 @@ public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
ServerWorld world = (ServerWorld) player.world;
PortalBlock.changeDimension(world, serverPlayer, new TeleporterAtumStart());
serverPlayer.func_242111_a(Atum.ATUM, serverPlayer.getPosition(), serverPlayer.getRotationYawHead(), true, false); //Set players spawn point in Atum, when starting in Atum
world.func_241124_a__(serverPlayer.getPosition(), 16);
DimensionHelper.validateAndGetSpawnPoint(world, serverPlayer, false);
}
}

Expand All @@ -94,13 +90,7 @@ public static void onPlayerDeath(LivingDeathEvent event) {
if (livingEntity instanceof ServerPlayerEntity) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) livingEntity;
ServerWorld serverWorld = serverPlayer.getServerWorld();
BlockPos respawnPos = serverPlayer.func_241140_K_();
if (respawnPos != null) {
Optional<Vector3d> bedPos = PlayerEntity.func_242374_a(serverWorld, respawnPos, serverPlayer.func_242109_L(), serverPlayer.func_241142_M_(), false);
if (!bedPos.isPresent()) {
serverPlayer.func_242111_a(Atum.ATUM, serverWorld.getSpawnPoint(), serverPlayer.getRotationYawHead(), true, false); //Ensure that the player respawns in Atum, when bed is broken
}
}
DimensionHelper.validateAndGetSpawnPoint(serverWorld, serverPlayer, true);
}
}
}
Expand Down
71 changes: 69 additions & 2 deletions src/main/java/com/teammetallurgy/atum/world/DimensionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
import com.teammetallurgy.atum.blocks.SandLayersBlock;
import com.teammetallurgy.atum.init.AtumBiomes;
import com.teammetallurgy.atum.init.AtumBlocks;
import com.teammetallurgy.atum.misc.AtumConfig;
import com.teammetallurgy.atum.world.gen.structure.StructureHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.ISeedReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
Expand All @@ -24,6 +30,7 @@
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import java.util.AbstractMap;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -77,15 +84,75 @@ public static boolean canPlaceSandLayer(ISeedReader world, BlockPos pos) {
* @return surface pos
*/
public static BlockPos getSurfacePos(World world, BlockPos pos) {
while (pos.getY() > 1 && world.isAirBlock(pos.down())) {
while (pos.getY() > 1 && world.isAirBlock(pos)) {
pos = pos.down();
}
while (!world.isAirBlock(pos.up()) && (SURFACE_BLOCKS.contains(world.getBlockState(pos.down()).getBlock()) || world.getBlockState(pos.down()).getBlock() != AtumBlocks.SAND_LAYERED) || pos.getY() < 60) {
while (!world.canBlockSeeSky(pos)) {
pos = pos.up();
}
return pos;
}

private static final StringTextComponent BED_MISSING_MSG = new StringTextComponent("You have no home bed or respawn anchor, or it was obstructed");
/**
* Gets a player's spawnpoint, resetting if the bed is invalid
* Always returns a valid world and position which can be teleported to.
*
* @param serverWorld any world
* @param serverPlayer the player
* @param msg whether to tell the player if their bed is missing
* @return surface pos of the spawnpoint
*/
public static AbstractMap.SimpleEntry<ServerWorld, BlockPos> validateAndGetSpawnPoint(ServerWorld serverWorld, ServerPlayerEntity serverPlayer, boolean msg) {
boolean atumSpawn = AtumConfig.ATUM_START.startInAtum.get();
boolean forcedSpawn = serverPlayer.func_241142_M_(); // if true -> don't check for valid bed
ServerWorld spawnWorld = serverWorld.getServer().getWorld(serverPlayer.func_241141_L_());
BlockPos spawnPos = serverPlayer.func_241140_K_();

Optional<Vector3d> bedPos = Optional.empty();
if (spawnPos != null) {
bedPos = PlayerEntity.func_242374_a(spawnWorld, spawnPos, serverPlayer.func_242109_L(), forcedSpawn, false);
}

boolean reset = false;
if (atumSpawn) {
ServerWorld atumWorld = serverWorld.getServer().getWorld(Atum.ATUM);
BlockPos defaultSpawnPos = DimensionHelper.getSurfacePos(atumWorld, atumWorld.getSpawnPoint()).up();
// best attempt at checking whether this is the default atum spawnpoint
boolean isSpawnPosDefault = forcedSpawn &&
spawnWorld.getDimensionKey() == Atum.ATUM &&
spawnPos != null &&
spawnPos.getX() == defaultSpawnPos.getX() &&
spawnPos.getZ() == defaultSpawnPos.getZ();

if (!bedPos.isPresent() || isSpawnPosDefault) {
if (msg && !forcedSpawn && spawnPos != null) {
serverPlayer.sendMessage(BED_MISSING_MSG, Util.DUMMY_UUID);
}
serverPlayer.func_242111_a(Atum.ATUM, defaultSpawnPos, serverPlayer.getRotationYawHead(), true, false);
spawnWorld = atumWorld;
spawnPos = defaultSpawnPos;
reset = true;
}
} else {
if (!bedPos.isPresent()) {
if (msg && !forcedSpawn && spawnPos != null) {
serverPlayer.sendMessage(BED_MISSING_MSG, Util.DUMMY_UUID);
}
serverPlayer.func_242111_a(World.OVERWORLD, null, serverPlayer.getRotationYawHead(), false, false);
spawnWorld = serverWorld.getServer().getWorld(World.OVERWORLD);
spawnPos = DimensionHelper.getSurfacePos(spawnWorld, spawnWorld.getSpawnPoint()).up();
reset = true;
}
}

if (!reset) {
spawnPos = spawnPos.up();
}

return new AbstractMap.SimpleEntry<>(spawnWorld, spawnPos);
}

public static boolean isBeatenPyramid(ServerWorld serverWorld, MutableBoundingBox box2) {
boolean validBox = false;
for (MutableBoundingBox box1 : getData(serverWorld).getBeatenPyramids()) {
Expand Down

0 comments on commit d1e7dc4

Please sign in to comment.