Skip to content

Commit

Permalink
Refactor spawn logic and fix bed missing message bug (#394)
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenDoesStuffs committed Jun 5, 2022
1 parent d1e7dc4 commit 11f20ca
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.teammetallurgy.atum.api.IArtifact;
import com.teammetallurgy.atum.init.AtumItems;
import com.teammetallurgy.atum.init.AtumParticles;
import com.teammetallurgy.atum.misc.SpawnHelper;
import com.teammetallurgy.atum.world.DimensionHelper;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.Enchantments;
Expand Down Expand Up @@ -69,7 +70,7 @@ public static BlockPos recall(World world, PlayerEntity player) {
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);
AbstractMap.SimpleEntry<ServerWorld, BlockPos> pair = SpawnHelper.validateAndGetSpawnPoint(serverWorld, serverPlayer, 2);
ServerWorld spawnWorld = pair.getKey();
BlockPos spawnPos = pair.getValue();

Expand Down
98 changes: 98 additions & 0 deletions src/main/java/com/teammetallurgy/atum/misc/SpawnHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.teammetallurgy.atum.misc;

import com.teammetallurgy.atum.Atum;
import com.teammetallurgy.atum.world.DimensionHelper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;

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

public class SpawnHelper {

public static final String TAG_ATUM_RESPAWN = "atum_respawn";
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 msgMode how to tell the player if their bed is missing; 0 is no message, 1 is after respawn, 2 is immediately
* @return surface pos of the spawnpoint
*/
public static AbstractMap.SimpleEntry<ServerWorld, BlockPos> validateAndGetSpawnPoint(ServerWorld serverWorld, ServerPlayerEntity serverPlayer, int msgMode) {
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 (!forcedSpawn && spawnPos != null) {
sendBedMissingMsg(serverPlayer, msgMode);
}
serverPlayer.func_242111_a(Atum.ATUM, defaultSpawnPos, serverPlayer.getRotationYawHead(), true, false);
spawnWorld = atumWorld;
spawnPos = defaultSpawnPos;
reset = true;
}
} else {
if (!bedPos.isPresent()) {
if (!forcedSpawn && spawnPos != null) {
sendBedMissingMsg(serverPlayer, msgMode);
}
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);
}

/**
* Sends a message to a player saying that their bed is missing
*
* @param serverPlayer the player
* @param msgMode how to tell the player if their bed is missing; 0 is no message, 1 is after respawn, 2 is immediately
*/
public static void sendBedMissingMsg(ServerPlayerEntity serverPlayer, int msgMode) {
if (msgMode == 1) {
CompoundNBT tag = serverPlayer.getPersistentData();
CompoundNBT persistedTag = tag.getCompound(PlayerEntity.PERSISTED_NBT_TAG);
persistedTag.putBoolean(TAG_ATUM_RESPAWN, true);
tag.put(PlayerEntity.PERSISTED_NBT_TAG, persistedTag);
} else if (msgMode == 2) {
serverPlayer.sendMessage(BED_MISSING_MSG, Util.DUMMY_UUID);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +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.SpawnHelper;
import com.teammetallurgy.atum.world.DimensionHelper;
import com.teammetallurgy.atum.world.teleporter.TeleporterAtumStart;
import net.minecraft.block.BlockState;
Expand Down Expand Up @@ -79,7 +80,7 @@ public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
ServerWorld world = (ServerWorld) player.world;
PortalBlock.changeDimension(world, serverPlayer, new TeleporterAtumStart());
DimensionHelper.validateAndGetSpawnPoint(world, serverPlayer, false);
SpawnHelper.validateAndGetSpawnPoint(world, serverPlayer, 0);
}
}

Expand All @@ -90,7 +91,22 @@ public static void onPlayerDeath(LivingDeathEvent event) {
if (livingEntity instanceof ServerPlayerEntity) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) livingEntity;
ServerWorld serverWorld = serverPlayer.getServerWorld();
DimensionHelper.validateAndGetSpawnPoint(serverWorld, serverPlayer, true);
SpawnHelper.validateAndGetSpawnPoint(serverWorld, serverPlayer, 1);
}
}
}

@SubscribeEvent
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
PlayerEntity player = event.getPlayer();
if (player instanceof ServerPlayerEntity) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
CompoundNBT tag = serverPlayer.getPersistentData();
CompoundNBT persistedTag = tag.getCompound(PlayerEntity.PERSISTED_NBT_TAG);
if (persistedTag.getBoolean(SpawnHelper.TAG_ATUM_RESPAWN)) {
SpawnHelper.sendBedMissingMsg(serverPlayer, 2);
persistedTag.remove(SpawnHelper.TAG_ATUM_RESPAWN);
tag.put(PlayerEntity.PERSISTED_NBT_TAG, persistedTag);
}
}
}
Expand Down
58 changes: 0 additions & 58 deletions src/main/java/com/teammetallurgy/atum/world/DimensionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,65 +93,7 @@ public static BlockPos getSurfacePos(World world, BlockPos pos) {
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;
Expand Down

0 comments on commit 11f20ca

Please sign in to comment.