Player spawn in Overworld fix
This commit is contained in:
parent
e09d1d2235
commit
56591633ec
12 changed files with 370 additions and 41 deletions
|
@ -31,7 +31,6 @@ import ru.betterend.util.BonemealUtil;
|
||||||
import ru.betterend.util.Logger;
|
import ru.betterend.util.Logger;
|
||||||
import ru.betterend.world.generator.BetterEndBiomeSource;
|
import ru.betterend.world.generator.BetterEndBiomeSource;
|
||||||
import ru.betterend.world.generator.GeneratorOptions;
|
import ru.betterend.world.generator.GeneratorOptions;
|
||||||
import ru.betterend.world.generator.TerrainGenerator;
|
|
||||||
import ru.betterend.world.surface.SurfaceBuilders;
|
import ru.betterend.world.surface.SurfaceBuilders;
|
||||||
|
|
||||||
public class BetterEnd implements ModInitializer {
|
public class BetterEnd implements ModInitializer {
|
||||||
|
@ -60,7 +59,6 @@ public class BetterEnd implements ModInitializer {
|
||||||
EndStructures.register();
|
EndStructures.register();
|
||||||
Integrations.register();
|
Integrations.register();
|
||||||
BonemealUtil.init();
|
BonemealUtil.init();
|
||||||
TerrainGenerator.init();
|
|
||||||
GeneratorOptions.init();
|
GeneratorOptions.init();
|
||||||
|
|
||||||
if (hasGuideBook()) {
|
if (hasGuideBook()) {
|
||||||
|
|
|
@ -111,8 +111,6 @@ public class EndPortalBlock extends NetherPortalBlock implements IRenderTypeable
|
||||||
while (checkPos.getY() > 5) {
|
while (checkPos.getY() > 5) {
|
||||||
BlockState state = world.getBlockState(checkPos);
|
BlockState state = world.getBlockState(checkPos);
|
||||||
if (state.isOf(this)) {
|
if (state.isOf(this)) {
|
||||||
System.out.println("Out: " + checkPos);
|
|
||||||
|
|
||||||
Axis axis = state.get(AXIS);
|
Axis axis = state.get(AXIS);
|
||||||
checkPos = this.findCenter(world, checkPos, axis);
|
checkPos = this.findCenter(world, checkPos, axis);
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.resource.ServerResourceManager;
|
import net.minecraft.resource.ServerResourceManager;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.PlayerManager;
|
||||||
|
import net.minecraft.server.WorldGenerationProgressListener;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.SaveProperties;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.level.ServerWorldProperties;
|
||||||
import ru.betterend.recipe.EndRecipeManager;
|
import ru.betterend.recipe.EndRecipeManager;
|
||||||
import ru.betterend.registry.EndBiomes;
|
import ru.betterend.registry.EndBiomes;
|
||||||
import ru.betterend.world.generator.GeneratorOptions;
|
import ru.betterend.world.generator.GeneratorOptions;
|
||||||
|
@ -31,6 +35,10 @@ public class MinecraftServerMixin {
|
||||||
@Shadow
|
@Shadow
|
||||||
private Map<RegistryKey<World>, ServerWorld> worlds;
|
private Map<RegistryKey<World>, ServerWorld> worlds;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
protected SaveProperties saveProperties;
|
||||||
|
|
||||||
@Inject(method = "reloadResources", at = @At(value = "RETURN"), cancellable = true)
|
@Inject(method = "reloadResources", at = @At(value = "RETURN"), cancellable = true)
|
||||||
private void beOnReload(Collection<String> collection, CallbackInfoReturnable<CompletableFuture<Void>> info) {
|
private void beOnReload(Collection<String> collection, CallbackInfoReturnable<CompletableFuture<Void>> info) {
|
||||||
beInjectRecipes();
|
beInjectRecipes();
|
||||||
|
@ -54,6 +62,36 @@ public class MinecraftServerMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = "createWorlds", at = @At(value = "TAIL"))
|
||||||
|
private final void be_CreateWorlds(WorldGenerationProgressListener worldGenerationProgressListener, CallbackInfo info) {
|
||||||
|
if (GeneratorOptions.swapOverworldToEnd()) {
|
||||||
|
ServerWorld world = worlds.get(World.END);
|
||||||
|
if (world == null) {
|
||||||
|
world = worlds.get(World.OVERWORLD);
|
||||||
|
}
|
||||||
|
this.getPlayerManager().setMainWorld(world);
|
||||||
|
ServerWorldProperties serverWorldProperties = saveProperties.getMainWorldProperties();
|
||||||
|
net.minecraft.world.gen.GeneratorOptions generatorOptions = saveProperties.getGeneratorOptions();
|
||||||
|
boolean bl = generatorOptions.isDebugWorld();
|
||||||
|
setupSpawn(world, serverWorldProperties, generatorOptions.hasBonusChest(), bl, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "setupSpawn", at = @At(value = "HEAD"), cancellable = true)
|
||||||
|
private static void be_SetupSpawn(ServerWorld world, ServerWorldProperties serverWorldProperties, boolean bonusChest, boolean debugWorld, boolean bl, CallbackInfo info) {
|
||||||
|
if (GeneratorOptions.swapOverworldToEnd() && world.getRegistryKey() == World.OVERWORLD) {
|
||||||
|
info.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private static void setupSpawn(ServerWorld world, ServerWorldProperties serverWorldProperties, boolean bonusChest, boolean debugWorld, boolean bl) {}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public PlayerManager getPlayerManager() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void beInjectRecipes() {
|
private void beInjectRecipes() {
|
||||||
if (FabricLoader.getInstance().isModLoaded("kubejs")) {
|
if (FabricLoader.getInstance().isModLoaded("kubejs")) {
|
||||||
RecipeManagerAccessor accessor = (RecipeManagerAccessor) serverResourceManager.getRecipeManager();
|
RecipeManagerAccessor accessor = (RecipeManagerAccessor) serverResourceManager.getRecipeManager();
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import net.minecraft.world.biome.source.BiomeSource;
|
import net.minecraft.world.biome.source.BiomeSource;
|
||||||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||||
import net.minecraft.world.gen.chunk.NoiseChunkGenerator;
|
import net.minecraft.world.gen.chunk.NoiseChunkGenerator;
|
||||||
|
import ru.betterend.world.generator.GeneratorOptions;
|
||||||
import ru.betterend.world.generator.TerrainGenerator;
|
import ru.betterend.world.generator.TerrainGenerator;
|
||||||
|
|
||||||
@Mixin(NoiseChunkGenerator.class)
|
@Mixin(NoiseChunkGenerator.class)
|
||||||
|
@ -27,7 +28,7 @@ public abstract class NoiseChunkGeneratorMixin {
|
||||||
|
|
||||||
@Inject(method = "sampleNoiseColumn([DII)V", at = @At("HEAD"), cancellable = true, allow = 2)
|
@Inject(method = "sampleNoiseColumn([DII)V", at = @At("HEAD"), cancellable = true, allow = 2)
|
||||||
private void beSampleNoiseColumn(double[] buffer, int x, int z, CallbackInfo info) {
|
private void beSampleNoiseColumn(double[] buffer, int x, int z, CallbackInfo info) {
|
||||||
if (TerrainGenerator.useNewGenerator() && settings.get().equals(ChunkGeneratorSettings.END)) {
|
if (GeneratorOptions.useNewGenerator() && settings.get().equals(ChunkGeneratorSettings.END)) {
|
||||||
if (TerrainGenerator.canGenerate(x, z)) {
|
if (TerrainGenerator.canGenerate(x, z)) {
|
||||||
TerrainGenerator.fillTerrainDensity(buffer, x, z);
|
TerrainGenerator.fillTerrainDensity(buffer, x, z);
|
||||||
info.cancel();
|
info.cancel();
|
||||||
|
|
260
src/main/java/ru/betterend/mixin/common/PlayerManagerMixin.java
Normal file
260
src/main/java/ru/betterend/mixin/common/PlayerManagerMixin.java
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
package ru.betterend.mixin.common;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
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.mojang.authlib.GameProfile;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
import com.mojang.serialization.Dynamic;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.NbtOps;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
|
import net.minecraft.network.ClientConnection;
|
||||||
|
import net.minecraft.network.MessageType;
|
||||||
|
import net.minecraft.network.Packet;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.DifficultyS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.EntityStatusEffectS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.HeldItemChangeS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.PlayerAbilitiesS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.SynchronizeTagsS2CPacket;
|
||||||
|
import net.minecraft.scoreboard.ServerScoreboard;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.PlayerManager;
|
||||||
|
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
import net.minecraft.util.UserCache;
|
||||||
|
import net.minecraft.util.Util;
|
||||||
|
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.GameRules;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldProperties;
|
||||||
|
import net.minecraft.world.biome.source.BiomeAccess;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import ru.betterend.world.generator.GeneratorOptions;
|
||||||
|
|
||||||
|
@Mixin(PlayerManager.class)
|
||||||
|
public class PlayerManagerMixin {
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private static Logger LOGGER;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private MinecraftServer server;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private DynamicRegistryManager.Impl registryManager;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private int viewDistance;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private List<ServerPlayerEntity> players;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
private Map<UUID, ServerPlayerEntity> playerMap;
|
||||||
|
|
||||||
|
@Inject(method = "onPlayerConnect", at = @At(value = "HEAD"), cancellable = true)
|
||||||
|
public void be_onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, CallbackInfo info) {
|
||||||
|
if (GeneratorOptions.swapOverworldToEnd()) {
|
||||||
|
GameProfile gameProfile = player.getGameProfile();
|
||||||
|
UserCache userCache = this.server.getUserCache();
|
||||||
|
GameProfile gameProfile2 = userCache.getByUuid(gameProfile.getId());
|
||||||
|
String string = gameProfile2 == null ? gameProfile.getName() : gameProfile2.getName();
|
||||||
|
userCache.add(gameProfile);
|
||||||
|
CompoundTag compoundTag = this.loadPlayerData(player);
|
||||||
|
RegistryKey<World> var23;
|
||||||
|
if (compoundTag != null) {
|
||||||
|
DataResult<RegistryKey<World>> var10000 = DimensionType.method_28521(new Dynamic<Tag>(NbtOps.INSTANCE, compoundTag.get("Dimension")));
|
||||||
|
Logger var10001 = LOGGER;
|
||||||
|
var10001.getClass();
|
||||||
|
var23 = (RegistryKey<World>) var10000.resultOrPartial(var10001::error).orElse(World.END);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var23 = World.END;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("World " + this.server.getWorld(World.END));
|
||||||
|
|
||||||
|
RegistryKey<World> registryKey = var23;
|
||||||
|
ServerWorld serverWorld = this.server.getWorld(registryKey);
|
||||||
|
ServerWorld serverWorld3;
|
||||||
|
if (serverWorld == null) {
|
||||||
|
LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", registryKey);
|
||||||
|
serverWorld3 = this.server.getOverworld();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
serverWorld3 = serverWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.setWorld(serverWorld3);
|
||||||
|
player.interactionManager.setWorld((ServerWorld) player.world);
|
||||||
|
String string2 = "local";
|
||||||
|
if (connection.getAddress() != null) {
|
||||||
|
string2 = connection.getAddress().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", player.getName().getString(), string2, player.getEntityId(), player.getX(), player.getY(), player.getZ());
|
||||||
|
WorldProperties worldProperties = serverWorld3.getLevelProperties();
|
||||||
|
this.setGameMode(player, (ServerPlayerEntity) null, serverWorld3);
|
||||||
|
ServerPlayNetworkHandler serverPlayNetworkHandler = new ServerPlayNetworkHandler(this.server, connection, player);
|
||||||
|
GameRules gameRules = serverWorld3.getGameRules();
|
||||||
|
boolean bl = gameRules.getBoolean(GameRules.DO_IMMEDIATE_RESPAWN);
|
||||||
|
boolean bl2 = gameRules.getBoolean(GameRules.REDUCED_DEBUG_INFO);
|
||||||
|
serverPlayNetworkHandler.sendPacket(new GameJoinS2CPacket(player.getEntityId(), player.interactionManager.getGameMode(), player.interactionManager.getPreviousGameMode(), BiomeAccess.hashSeed(serverWorld3.getSeed()),
|
||||||
|
worldProperties.isHardcore(), this.server.getWorldRegistryKeys(), this.registryManager, serverWorld3.getDimension(), serverWorld3.getRegistryKey(), this.getMaxPlayerCount(), this.viewDistance, bl2, !bl,
|
||||||
|
serverWorld3.isDebugWorld(), serverWorld3.isFlat()));
|
||||||
|
serverPlayNetworkHandler.sendPacket(new CustomPayloadS2CPacket(CustomPayloadS2CPacket.BRAND, (new PacketByteBuf(Unpooled.buffer())).writeString(this.getServer().getServerModName())));
|
||||||
|
serverPlayNetworkHandler.sendPacket(new DifficultyS2CPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked()));
|
||||||
|
serverPlayNetworkHandler.sendPacket(new PlayerAbilitiesS2CPacket(player.abilities));
|
||||||
|
serverPlayNetworkHandler.sendPacket(new HeldItemChangeS2CPacket(player.inventory.selectedSlot));
|
||||||
|
serverPlayNetworkHandler.sendPacket(new SynchronizeRecipesS2CPacket(this.server.getRecipeManager().values()));
|
||||||
|
serverPlayNetworkHandler.sendPacket(new SynchronizeTagsS2CPacket(this.server.getTagManager()));
|
||||||
|
this.sendCommandTree(player);
|
||||||
|
player.getStatHandler().updateStatSet();
|
||||||
|
player.getRecipeBook().sendInitRecipesPacket(player);
|
||||||
|
this.sendScoreboard(serverWorld3.getScoreboard(), player);
|
||||||
|
this.server.forcePlayerSampleUpdate();
|
||||||
|
TranslatableText mutableText2;
|
||||||
|
if (player.getGameProfile().getName().equalsIgnoreCase(string)) {
|
||||||
|
mutableText2 = new TranslatableText("multiplayer.player.joined", new Object[] { player.getDisplayName() });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mutableText2 = new TranslatableText("multiplayer.player.joined.renamed", new Object[] { player.getDisplayName(), string });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.broadcastChatMessage(mutableText2.formatted(Formatting.YELLOW), MessageType.SYSTEM, Util.NIL_UUID);
|
||||||
|
serverPlayNetworkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), player.yaw, player.pitch);
|
||||||
|
this.players.add(player);
|
||||||
|
this.playerMap.put(player.getUuid(), player);
|
||||||
|
this.sendToAll(new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER, new ServerPlayerEntity[] { player }));
|
||||||
|
|
||||||
|
for (int i = 0; i < this.players.size(); ++i) {
|
||||||
|
player.networkHandler.sendPacket(new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER, new ServerPlayerEntity[] { (ServerPlayerEntity) this.players.get(i) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
serverWorld3.onPlayerConnected(player);
|
||||||
|
this.server.getBossBarManager().onPlayerConnect(player);
|
||||||
|
this.sendWorldInfo(player, serverWorld3);
|
||||||
|
if (!this.server.getResourcePackUrl().isEmpty()) {
|
||||||
|
player.sendResourcePackUrl(this.server.getResourcePackUrl(), this.server.getResourcePackHash());
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<?> var24 = player.getStatusEffects().iterator();
|
||||||
|
|
||||||
|
while (var24.hasNext()) {
|
||||||
|
StatusEffectInstance statusEffectInstance = (StatusEffectInstance) var24.next();
|
||||||
|
serverPlayNetworkHandler.sendPacket(new EntityStatusEffectS2CPacket(player.getEntityId(), statusEffectInstance));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compoundTag != null && compoundTag.contains("RootVehicle", 10)) {
|
||||||
|
CompoundTag compoundTag2 = compoundTag.getCompound("RootVehicle");
|
||||||
|
Entity entity = EntityType.loadEntityWithPassengers(compoundTag2.getCompound("Entity"), serverWorld3, (vehicle) -> {
|
||||||
|
return !serverWorld3.tryLoadEntity(vehicle) ? null : vehicle;
|
||||||
|
});
|
||||||
|
if (entity != null) {
|
||||||
|
UUID uUID2;
|
||||||
|
if (compoundTag2.containsUuid("Attach")) {
|
||||||
|
uUID2 = compoundTag2.getUuid("Attach");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uUID2 = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<?> var21;
|
||||||
|
Entity entity3;
|
||||||
|
if (entity.getUuid().equals(uUID2)) {
|
||||||
|
player.startRiding(entity, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var21 = entity.getPassengersDeep().iterator();
|
||||||
|
|
||||||
|
while (var21.hasNext()) {
|
||||||
|
entity3 = (Entity) var21.next();
|
||||||
|
if (entity3.getUuid().equals(uUID2)) {
|
||||||
|
player.startRiding(entity3, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.hasVehicle()) {
|
||||||
|
LOGGER.warn("Couldn't reattach entity to player");
|
||||||
|
serverWorld3.removeEntity(entity);
|
||||||
|
var21 = entity.getPassengersDeep().iterator();
|
||||||
|
|
||||||
|
while (var21.hasNext()) {
|
||||||
|
entity3 = (Entity) var21.next();
|
||||||
|
serverWorld3.removeEntity(entity3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.onSpawn();
|
||||||
|
info.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public CompoundTag loadPlayerData(ServerPlayerEntity player) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private void setGameMode(ServerPlayerEntity player, @Nullable ServerPlayerEntity oldPlayer, ServerWorld world) {}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public void sendCommandTree(ServerPlayerEntity player) {}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public int getMaxPlayerCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public MinecraftServer getServer() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
protected void sendScoreboard(ServerScoreboard scoreboard, ServerPlayerEntity player) {}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public void broadcastChatMessage(Text message, MessageType type, UUID senderUuid) {}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public void sendToAll(Packet<?> packet) {}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public void sendWorldInfo(ServerPlayerEntity player, ServerWorld world) {}
|
||||||
|
}
|
|
@ -1,34 +1,57 @@
|
||||||
package ru.betterend.mixin.common;
|
package ru.betterend.mixin.common;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
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.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import ru.betterend.interfaces.TeleportingEntity;
|
import ru.betterend.interfaces.TeleportingEntity;
|
||||||
|
|
||||||
@Mixin(ServerPlayerEntity.class)
|
@Mixin(ServerPlayerEntity.class)
|
||||||
public abstract class ServerPlayerEntityMixin implements TeleportingEntity {
|
public abstract class ServerPlayerEntityMixin extends PlayerEntity implements TeleportingEntity {
|
||||||
|
private static final Map<ServerPlayerEntity, Long> COOLDOWN = Maps.newHashMap();
|
||||||
|
|
||||||
private long beCooldown;
|
public ServerPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile profile) {
|
||||||
|
super(world, pos, yaw, profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private RegistryKey<World> spawnPointDimension;
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At("TAIL"))
|
@Inject(method = "tick", at = @At("TAIL"))
|
||||||
public void be_baseTick(CallbackInfo info) {
|
public void be_baseTick(CallbackInfo info) {
|
||||||
if (hasCooldown()) {
|
if (hasCooldown()) {
|
||||||
this.beCooldown--;
|
ServerPlayerEntity key = (ServerPlayerEntity) (Object) this;
|
||||||
|
long value = COOLDOWN.getOrDefault(key, 0L) - 1;
|
||||||
|
COOLDOWN.put(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private void moveToSpawn(ServerWorld world) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long beGetCooldown() {
|
public long beGetCooldown() {
|
||||||
return this.beCooldown;
|
ServerPlayerEntity key = (ServerPlayerEntity) (Object) this;
|
||||||
|
return COOLDOWN.getOrDefault(key, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beSetCooldown(long time) {
|
public void beSetCooldown(long time) {
|
||||||
this.beCooldown = time;
|
ServerPlayerEntity key = (ServerPlayerEntity) (Object) this;
|
||||||
|
COOLDOWN.put(key, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -176,6 +176,7 @@ public class EndBiomes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (BetterEnd.isDevEnvironment()) {
|
if (BetterEnd.isDevEnvironment()) {
|
||||||
|
System.out.println("==================================");
|
||||||
System.out.println("Added void biomes from Fabric API:");
|
System.out.println("Added void biomes from Fabric API:");
|
||||||
FABRIC_VOID.forEach((id) -> {
|
FABRIC_VOID.forEach((id) -> {
|
||||||
System.out.println(id);
|
System.out.println(id);
|
||||||
|
@ -324,7 +325,6 @@ public class EndBiomes {
|
||||||
public static void addSubBiomeIntegration(EndBiome biome, Identifier parent) {
|
public static void addSubBiomeIntegration(EndBiome biome, Identifier parent) {
|
||||||
if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) {
|
if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) {
|
||||||
EndBiome parentBiome = ID_MAP.get(parent);
|
EndBiome parentBiome = ID_MAP.get(parent);
|
||||||
System.out.println(parentBiome);
|
|
||||||
if (parentBiome != null && !parentBiome.containsSubBiome(biome)) {
|
if (parentBiome != null && !parentBiome.containsSubBiome(biome)) {
|
||||||
parentBiome.addSubBiome(biome);
|
parentBiome.addSubBiome(biome);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class BetterEndBiomeSource extends BiomeSource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
||||||
boolean hasVoid = !TerrainGenerator.useNewGenerator() || !TerrainGenerator.noRingVoid();
|
boolean hasVoid = !GeneratorOptions.useNewGenerator() || !GeneratorOptions.noRingVoid();
|
||||||
long i = (long) biomeX * (long) biomeX;
|
long i = (long) biomeX * (long) biomeX;
|
||||||
long j = (long) biomeZ * (long) biomeZ;
|
long j = (long) biomeZ * (long) biomeZ;
|
||||||
if (hasVoid && i + j <= 65536L) return this.centerBiome;
|
if (hasVoid && i + j <= 65536L) return this.centerBiome;
|
||||||
|
@ -80,7 +80,7 @@ public class BetterEndBiomeSource extends BiomeSource {
|
||||||
mapVoid.clearCache();
|
mapVoid.clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TerrainGenerator.useNewGenerator()) {
|
if (GeneratorOptions.useNewGenerator()) {
|
||||||
if (TerrainGenerator.isLand(biomeX, biomeZ)) {
|
if (TerrainGenerator.isLand(biomeX, biomeZ)) {
|
||||||
return mapLand.getBiome(biomeX << 2, biomeZ << 2).getActualBiome();
|
return mapLand.getBiome(biomeX << 2, biomeZ << 2).getActualBiome();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@ public class GeneratorOptions {
|
||||||
private static boolean swapOverworldToEnd;
|
private static boolean swapOverworldToEnd;
|
||||||
private static boolean changeChorusPlant;
|
private static boolean changeChorusPlant;
|
||||||
private static boolean removeChorusFromVanillaBiomes;
|
private static boolean removeChorusFromVanillaBiomes;
|
||||||
|
private static boolean newGenerator;
|
||||||
|
private static boolean noRingVoid;
|
||||||
|
private static boolean generateCentralIsland;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
biomeSizeLand = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeLand", 256);
|
biomeSizeLand = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeLand", 256);
|
||||||
|
@ -21,6 +24,9 @@ public class GeneratorOptions {
|
||||||
swapOverworldToEnd = Configs.GENERATOR_CONFIG.getBooleanRoot("swapOverworldToEnd", false);
|
swapOverworldToEnd = Configs.GENERATOR_CONFIG.getBooleanRoot("swapOverworldToEnd", false);
|
||||||
changeChorusPlant = Configs.GENERATOR_CONFIG.getBoolean("chorusPlant", "changeChorusPlant", true);
|
changeChorusPlant = Configs.GENERATOR_CONFIG.getBoolean("chorusPlant", "changeChorusPlant", true);
|
||||||
removeChorusFromVanillaBiomes = Configs.GENERATOR_CONFIG.getBoolean("chorusPlant", "removeChorusFromVanillaBiomes", true);
|
removeChorusFromVanillaBiomes = Configs.GENERATOR_CONFIG.getBoolean("chorusPlant", "removeChorusFromVanillaBiomes", true);
|
||||||
|
newGenerator = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "useNewGenerator", false);
|
||||||
|
noRingVoid = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "noRingVoid", false);
|
||||||
|
generateCentralIsland = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "generateCentralIsland", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getBiomeSizeLand() {
|
public static int getBiomeSizeLand() {
|
||||||
|
@ -54,4 +60,16 @@ public class GeneratorOptions {
|
||||||
public static boolean removeChorusFromVanillaBiomes() {
|
public static boolean removeChorusFromVanillaBiomes() {
|
||||||
return removeChorusFromVanillaBiomes;
|
return removeChorusFromVanillaBiomes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean noRingVoid() {
|
||||||
|
return noRingVoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean useNewGenerator() {
|
||||||
|
return newGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasCentralIsland() {
|
||||||
|
return generateCentralIsland;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,10 +29,11 @@ public class IslandLayer {
|
||||||
private final int minY;
|
private final int minY;
|
||||||
private final int maxY;
|
private final int maxY;
|
||||||
private final long center;
|
private final long center;
|
||||||
|
private final boolean hasCentralIsland;
|
||||||
private int lastX = Integer.MIN_VALUE;
|
private int lastX = Integer.MIN_VALUE;
|
||||||
private int lastZ = Integer.MIN_VALUE;
|
private int lastZ = Integer.MIN_VALUE;
|
||||||
|
|
||||||
public IslandLayer(int seed, double distance, float scale, int center, int heightVariation) {
|
public IslandLayer(int seed, double distance, float scale, int center, int heightVariation, boolean hasCentralIsland) {
|
||||||
this.distance = distance;
|
this.distance = distance;
|
||||||
this.density = new OpenSimplexNoise(seed);
|
this.density = new OpenSimplexNoise(seed);
|
||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
|
@ -40,6 +41,7 @@ public class IslandLayer {
|
||||||
this.minY = center - heightVariation;
|
this.minY = center - heightVariation;
|
||||||
this.maxY = center + heightVariation;
|
this.maxY = center + heightVariation;
|
||||||
this.center = MHelper.floor(1000 / distance);
|
this.center = MHelper.floor(1000 / distance);
|
||||||
|
this.hasCentralIsland = hasCentralIsland;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getSeed(int x, int z) {
|
private int getSeed(int x, int z) {
|
||||||
|
@ -59,7 +61,7 @@ public class IslandLayer {
|
||||||
int px = pox + ix;
|
int px = pox + ix;
|
||||||
for (int poz = -1; poz < 2; poz++) {
|
for (int poz = -1; poz < 2; poz++) {
|
||||||
int pz = poz + iz;
|
int pz = poz + iz;
|
||||||
if (TerrainGenerator.noRingVoid() || (long) px + (long) pz > center) {
|
if (GeneratorOptions.noRingVoid() || (long) px + (long) pz > center) {
|
||||||
RANDOM.setSeed(getSeed(px, pz));
|
RANDOM.setSeed(getSeed(px, pz));
|
||||||
double posX = (px + RANDOM.nextFloat()) * distance;
|
double posX = (px + RANDOM.nextFloat()) * distance;
|
||||||
double posY = MHelper.randRange(minY, maxY, RANDOM);
|
double posY = MHelper.randRange(minY, maxY, RANDOM);
|
||||||
|
@ -70,6 +72,14 @@ public class IslandLayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hasCentralIsland && GeneratorOptions.hasCentralIsland() && ix == 0 && iz == 0) {
|
||||||
|
if (positions.size() > 4) {
|
||||||
|
positions.set(4, new BlockPos(0, 64, 0));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
positions.add(new BlockPos(0, 64, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import java.util.Random;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import ru.betterend.config.Configs;
|
|
||||||
import ru.betterend.noise.OpenSimplexNoise;
|
import ru.betterend.noise.OpenSimplexNoise;
|
||||||
import ru.betterend.util.MHelper;
|
import ru.betterend.util.MHelper;
|
||||||
|
|
||||||
|
@ -19,35 +18,20 @@ public class TerrainGenerator {
|
||||||
private static IslandLayer smallIslands;
|
private static IslandLayer smallIslands;
|
||||||
private static OpenSimplexNoise noise1;
|
private static OpenSimplexNoise noise1;
|
||||||
private static OpenSimplexNoise noise2;
|
private static OpenSimplexNoise noise2;
|
||||||
private static boolean newGenerator;
|
|
||||||
private static boolean noRingVoid;
|
|
||||||
|
|
||||||
public static void init() {
|
public static boolean canGenerate(int x, int z) {
|
||||||
newGenerator = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "useNewGenerator", false);
|
return GeneratorOptions.noRingVoid() || (long) x + (long) z > CENTER;
|
||||||
noRingVoid = Configs.GENERATOR_CONFIG.getBoolean("customGenerator", "noRingVoid", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initNoise(long seed) {
|
public static void initNoise(long seed) {
|
||||||
Random random = new Random(seed);
|
Random random = new Random(seed);
|
||||||
largeIslands = new IslandLayer(random.nextInt(), 300, 200, 70, 10);
|
largeIslands = new IslandLayer(random.nextInt(), 300, 200, 70, 10, false);
|
||||||
mediumIslands = new IslandLayer(random.nextInt(), 150, 100, 70, 20);
|
mediumIslands = new IslandLayer(random.nextInt(), 150, 100, 70, 20, true);
|
||||||
smallIslands = new IslandLayer(random.nextInt(), 60, 50, 70, 30);
|
smallIslands = new IslandLayer(random.nextInt(), 60, 50, 70, 30, false);
|
||||||
noise1 = new OpenSimplexNoise(random.nextInt());
|
noise1 = new OpenSimplexNoise(random.nextInt());
|
||||||
noise2 = new OpenSimplexNoise(random.nextInt());
|
noise2 = new OpenSimplexNoise(random.nextInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canGenerate(int x, int z) {
|
|
||||||
return noRingVoid || (long) x + (long) z > CENTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean noRingVoid() {
|
|
||||||
return noRingVoid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean useNewGenerator() {
|
|
||||||
return newGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fillTerrainDensity(double[] buffer, int x, int z) {
|
public static void fillTerrainDensity(double[] buffer, int x, int z) {
|
||||||
LOCKER.lock();
|
LOCKER.lock();
|
||||||
|
|
||||||
|
@ -128,8 +112,6 @@ public class TerrainGenerator {
|
||||||
public static int getHeight(int x, int z) {
|
public static int getHeight(int x, int z) {
|
||||||
LOCKER.lock();
|
LOCKER.lock();
|
||||||
|
|
||||||
//x >>= 3;
|
|
||||||
//z >>= 3;
|
|
||||||
double px = (double) x / 8.0;
|
double px = (double) x / 8.0;
|
||||||
double pz = (double) z / 8.0;
|
double pz = (double) z / 8.0;
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,17 @@
|
||||||
"MinecraftServerMixin",
|
"MinecraftServerMixin",
|
||||||
"TagGroupLoaderMixin",
|
"TagGroupLoaderMixin",
|
||||||
"EndermanEntityMixin",
|
"EndermanEntityMixin",
|
||||||
"DimensionTypeMixin",
|
|
||||||
"RecipeManagerMixin",
|
|
||||||
"AbstractBlockMixin",
|
"AbstractBlockMixin",
|
||||||
|
"DimensionTypeMixin",
|
||||||
|
"PlayerManagerMixin",
|
||||||
|
"RecipeManagerMixin",
|
||||||
"HostileEntityMixin",
|
"HostileEntityMixin",
|
||||||
"LivingEntityMixin",
|
"LivingEntityMixin",
|
||||||
"BoneMealItemMixin",
|
"BoneMealItemMixin",
|
||||||
"PlayerEntityMixin",
|
"PlayerEntityMixin",
|
||||||
"SlimeEntityMixin",
|
"SlimeEntityMixin",
|
||||||
"BrewingAccessor",
|
"BrewingAccessor",
|
||||||
"EntityMixin"
|
"EntityMixin",
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue