java 覆盖Minecraft重生行为

xiozqbni  于 2023-06-20  发布在  Java
关注(0)|答案(2)|浏览(126)

bounty已结束。回答此问题可获得+200声望奖励。赏金宽限期17小时后结束。CaseyB希望吸引更多的注意力这个问题:我正在寻找帮助,让这个工作。第一个实现正确行为的解决方案将获得奖励。

我想创建一个模式,覆盖默认的重生机制。我希望每个球员开始100,000块从产卵在不同的方向,并有这是他们的默认重生位置。我试着用这个行为覆盖ServerPlayerEntity,看起来它可能起作用了,但是我找不到一种方法让服务器用我的子类替换默认的ServerPlayerEntity。
这就是我想做的

public class Server100KMPlayerEntity extends ServerPlayerEntity {
    public Server100KMPlayerEntity(MinecraftServer server, ServerWorld world, GameProfile profile) {
        super(server, world, profile);
    }

    @Override
    public void setSpawnPoint(RegistryKey<World> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
        if (pos != null) {
            super.setSpawnPoint(dimension, pos, angle, forced, sendMessage);
        } else {
            BlockPos newPos = PlayerPositions.valueOf(getEntityName()).getPosition(getServer().getWorld(World.OVERWORLD));
            super.setSpawnPoint(World.OVERWORLD, newPos, 0f, false, sendMessage);
        }
    }

    enum PlayerPositions {
        Player1(-70711, -70711),
        Player2(70711, -70711),
        Player3(-70711, 70711),
        Player4(70711, 70711);

        private final int x, z;

        PlayerPositions(int x, int z) {
            this.x = x;
            this.z = z;
        }

        public BlockPos getPosition(World world) {
            for (int d = world.getTopY(); d > world.getBottomY(); --d) {
                if (!world.isSpaceEmpty(new Box(new BlockPos(x, d, z)))) {
                    return new BlockPos(x, d - 1, z);
                }
            }
            return null;
        }
    }
}

我还研究了S2 C和C2 S事件,但没有看到任何看起来有帮助的东西。任何建议将不胜感激。

xhv8bpkk

xhv8bpkk1#

您可以将Mixin注入到PlayerManager类中的respawnPlayer方法中,每次在玩家生成之前,您都可以在其中设置玩家的生成点。
下面是一个例子:

@Mixin(PlayerManager.class)
public class ServerPlayerEntityMixin {
    @Inject(method = "respawnPlayer", at = @At("HEAD"))
    public void respawnPlayer(ServerPlayerEntity player, boolean alive, CallbackInfoReturnable<ServerPlayerEntity> cir) {
        BlockPos yourPos = new BlockPos(0, 200, 0); // Whatever position you'd like (you can match the player's display name to a value or something)
        RegistryKey<World> dimension = World.OVERWORLD; // I'm assuming you'd like this to be in the overworld
        player.setSpawnPoint(dimension, yourPos, 0, true, false);
    }
}

有一点需要注意:当你把Y轴传递给setSpawnPoint时,Y轴很重要,如果有块出现在玩家要出生的地方,它会默认回到世界出生点。地面以上的位置,甚至在空中应该工作得很好。

ffscu2ro

ffscu2ro2#

示例实现

import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import java.util.Random;

public class CustomRespawnHandler extends ServerPlayerEntity {
    public CustomRespawnHandler(MinecraftServer server, ServerWorld world, GameProfile profile) {
        super(server, world, profile);
    }

    @Override
    public void setSpawnPoint(RegistryKey<World> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
        if (pos == null) {
            // Calculate the new respawn position based on player-specific logic
            BlockPos newPos = calculateRespawnPosition(getServerWorld());
            super.setSpawnPoint(World.OVERWORLD, newPos, 0f, false, sendMessage);
        } else {
            super.setSpawnPoint(dimension, pos, angle, forced, sendMessage);
        }
    }

    private BlockPos calculateRespawnPosition(ServerWorld world) {
        // Generate random coordinates
        Random random = new Random(getEntityName().hashCode());
        int x = random.nextInt(200000) - 100000;
        int z = random.nextInt(200000) - 100000;

        // Find a suitable respawn position
        for (int d = world.getTopY(); d > world.getBottomY(); d--) {
            if (!world.isAir(new BlockPos(x, d, z))) {
                return new BlockPos(x, d, z);
            }
        }

        // Return a fallback position if no suitable position is found
        return new BlockPos(x, world.getTopY(), z);
    }
}

相关问题