mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 19:46:42 +01:00
Added respawn logic to place seaponies in water
This commit is contained in:
parent
c656eb2309
commit
873297ca44
2 changed files with 66 additions and 28 deletions
|
@ -54,6 +54,7 @@ import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.particle.ParticleTypes;
|
import net.minecraft.particle.ParticleTypes;
|
||||||
import net.minecraft.registry.tag.DamageTypeTags;
|
import net.minecraft.registry.tag.DamageTypeTags;
|
||||||
|
import net.minecraft.registry.tag.FluidTags;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
@ -340,11 +341,12 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSpawn() {
|
public void onSpawn() {
|
||||||
if (entity.getWorld() instanceof ServerWorld sw
|
if (entity.getWorld() instanceof ServerWorld sw && sw.getServer().getSaveProperties().getGameMode() != GameMode.ADVENTURE) {
|
||||||
&& getObservedSpecies() == Race.BAT
|
boolean mustAvoidSun = getObservedSpecies() == Race.BAT && MeteorlogicalUtil.isPositionExposedToSun(sw, getOrigin());
|
||||||
&& sw.getServer().getSaveProperties().getGameMode() != GameMode.ADVENTURE
|
boolean mustAvoidAir = getCompositeRace().includes(Race.SEAPONY) && !sw.getFluidState(getOrigin()).isIn(FluidTags.WATER);
|
||||||
&& MeteorlogicalUtil.isPositionExposedToSun(sw, getOrigin())) {
|
if (mustAvoidSun || mustAvoidAir) {
|
||||||
SpawnLocator.selectSpawnPosition(sw, entity);
|
SpawnLocator.selectSpawnPosition(sw, entity, mustAvoidAir, mustAvoidSun);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ticksSunImmunity = INITIAL_SUN_IMMUNITY;
|
ticksSunImmunity = INITIAL_SUN_IMMUNITY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,68 @@
|
||||||
package com.minelittlepony.unicopia.entity.player;
|
package com.minelittlepony.unicopia.entity.player;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.util.MeteorlogicalUtil;
|
import com.minelittlepony.unicopia.util.MeteorlogicalUtil;
|
||||||
|
|
||||||
import net.minecraft.entity.ai.FuzzyPositions;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.fluid.FluidState;
|
||||||
|
import net.minecraft.registry.tag.FluidTags;
|
||||||
import net.minecraft.server.network.SpawnLocating;
|
import net.minecraft.server.network.SpawnLocating;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.random.Random;
|
import net.minecraft.util.math.random.Random;
|
||||||
|
import net.minecraft.world.Heightmap;
|
||||||
|
import net.minecraft.world.chunk.WorldChunk;
|
||||||
|
|
||||||
public class SpawnLocator extends SpawnLocating {
|
public class SpawnLocator extends SpawnLocating {
|
||||||
|
private static BlockPos findSafeSpawnLocation(ServerWorld world, int x, int z, boolean avoidAir) {
|
||||||
public static BlockPos findSafeSpawnLocation(ServerWorld world, int x, int z) {
|
if (!avoidAir) {
|
||||||
return SpawnLocating.findOverworldSpawn(world, x, z);
|
return findOverworldSpawn(world, x, z);
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<BlockPos> fuzz(ServerWorld world, BlockPos pos, int horizontal, int vertical) {
|
|
||||||
|
|
||||||
for (int attempt = 0; attempt < 6; attempt++) {
|
|
||||||
BlockPos target = FuzzyPositions.localFuzz(world.random, horizontal, vertical);
|
|
||||||
target = findSafeSpawnLocation(world, target.getX(), target.getZ());
|
|
||||||
|
|
||||||
if (target != null) {
|
|
||||||
return Optional.of(target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.empty();
|
boolean hasCeiling = world.getDimension().hasCeiling();
|
||||||
|
WorldChunk chunk = world.getChunk(ChunkSectionPos.getSectionCoord(x), ChunkSectionPos.getSectionCoord(z));
|
||||||
|
int startHeight = hasCeiling
|
||||||
|
? world.getChunkManager().getChunkGenerator().getSpawnHeight(world)
|
||||||
|
: chunk.sampleHeightmap(Heightmap.Type.MOTION_BLOCKING, x & 0xF, z & 0xF);
|
||||||
|
if (startHeight < world.getBottomY()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int terrainHeight = chunk.sampleHeightmap(Heightmap.Type.WORLD_SURFACE, x & 0xF, z & 0xF);
|
||||||
|
if (terrainHeight <= startHeight && terrainHeight > chunk.sampleHeightmap(Heightmap.Type.OCEAN_FLOOR, x & 0xF, z & 0xF)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPos.Mutable mutable = new BlockPos.Mutable();
|
||||||
|
for (int y = startHeight + 1; y >= world.getBottomY(); --y) {
|
||||||
|
mutable.set(x, y, z);
|
||||||
|
BlockState state = world.getBlockState(mutable);
|
||||||
|
FluidState fluid = state.getFluidState();
|
||||||
|
if (fluid.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!fluid.isIn(FluidTags.WATER)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!Block.isFaceFullSquare(state.getCollisionShape(world, mutable), Direction.UP)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mutable.up().toImmutable();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void selectSpawnPosition(ServerWorld world, PlayerEntity entity) {
|
private static boolean checkAtmosphere(ServerWorld world, BlockPos pos, boolean avoidAir) {
|
||||||
|
if (avoidAir) {
|
||||||
|
return world.getFluidState(pos).isIn(FluidTags.WATER);
|
||||||
|
|
||||||
|
}
|
||||||
|
return world.getFluidState(pos).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void selectSpawnPosition(ServerWorld world, PlayerEntity entity, boolean avoidAir, boolean avoidSun) {
|
||||||
BlockPos spawnPos = world.getSpawnPos();
|
BlockPos spawnPos = world.getSpawnPos();
|
||||||
int spawnRadius = Math.min(
|
int spawnRadius = Math.min(
|
||||||
MathHelper.floor(world.getWorldBorder().getDistanceInsideBorder(spawnPos.getX(), spawnPos.getZ())),
|
MathHelper.floor(world.getWorldBorder().getDistanceInsideBorder(spawnPos.getX(), spawnPos.getZ())),
|
||||||
|
@ -53,7 +84,8 @@ public class SpawnLocator extends SpawnLocating {
|
||||||
|
|
||||||
BlockPos candidatePos = findSafeSpawnLocation(world,
|
BlockPos candidatePos = findSafeSpawnLocation(world,
|
||||||
spawnPos.getX() + x - spawnRadius,
|
spawnPos.getX() + x - spawnRadius,
|
||||||
spawnPos.getZ() + z - spawnRadius
|
spawnPos.getZ() + z - spawnRadius,
|
||||||
|
avoidAir
|
||||||
);
|
);
|
||||||
|
|
||||||
if (candidatePos == null) {
|
if (candidatePos == null) {
|
||||||
|
@ -70,7 +102,7 @@ public class SpawnLocator extends SpawnLocating {
|
||||||
mutable.move(0, -1, 0);
|
mutable.move(0, -1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!world.getFluidState(mutable).isEmpty()) {
|
if (!checkAtmosphere(world, mutable, avoidAir)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,13 +110,17 @@ public class SpawnLocator extends SpawnLocating {
|
||||||
mutable.move(0, 1, 0);
|
mutable.move(0, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!world.getFluidState(mutable).isEmpty()) {
|
if (!checkAtmosphere(world, mutable, avoidAir)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.refreshPositionAndAngles(mutable, 0, 0);
|
entity.refreshPositionAndAngles(mutable, 0, 0);
|
||||||
|
|
||||||
if (!world.isSpaceEmpty(entity) || MeteorlogicalUtil.isPositionExposedToSun(world, mutable)) {
|
if (!world.isSpaceEmpty(entity)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avoidSun && MeteorlogicalUtil.isPositionExposedToSun(world, mutable)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue