Jump to content

[1.11] [SOLVED] Making sure players don't spawn in deep water/ocean areas.


Recommended Posts

Posted

I'm curious as to which way I could go about making sure that players only spawn on land. I'm used to bukkit and they just had a biome.isOcean method. I can't seem to find anything similar for forge.

 

Thanks.

Posted

Use the biome dictionary.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Use the biome dictionary.

 

Hmm. I was looking into that. I'll mess around with it now. I'll probably have some poorly written code coming up soon! :P

Posted

Ok after messing with that and other things I'm writing. I got this code, but of course, it doesn't work. I'm sure I'm miss using the BiomeDictonary but I couldn't find much documentation on it.

 

@SubscribeEvent
    public void playerSpawn (PlayerEvent.PlayerRespawnEvent e)
    {
        BlockPos spawnPos = randomSpawn();
        Biome biome = grabBiome(e.player, spawnPos);

        do
        {
            e.player.getEntityWorld().getWorldInfo().setSpawn(spawnPos);
        }
        while (BiomeDictionary.hasType(biome, BiomeDictionary.Type.OCEAN) | e.player.getEntityWorld().getBlockState(spawnPos).getMaterial() == Material.WATER);
        {
            e.player.getEntityWorld().getWorldInfo().setSpawn(randomSpawn());
            spawnPos = e.player.getEntityWorld().getSpawnPoint();
            biome = grabBiome(e.player, spawnPos);
        }
    }

 

Also bonus points if someone knows how I can delay my code like sleep.thread() without it making Minecraft freeze. I'm trying to wait 8 seconds then it kills a mob. I can get it to pause for like a second then do it, but it looks so unnatural like that. Also how do you set it so that a mob doesn't drop anything? I set entity.setDropItemsWhenDead() to false and it still drops their items on death.

 

Sorry for the question inside a question, didn't want to make a whole new topic if I didn't have to.

 

Thanks in advance.

Posted

It doesn't work because you have a while loop that does nothing.  It continually sets the spawn point to a fixed location.

Then after it leaves the infinite loop, it sets the spawn to a random location.

 

Also, thread.sleep is not how you make things happen across time.  If you want something to occur across ticks, you need to count ticks in a tick event handler.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

So the while statement is broke? Heres how I -thought- it worked.

 

-while the biome equals ocean or the block the player is going to be spawned to is in water

 

- Set another spawn location with the randomSpawn() method

 

- Get the new spawn location information and assign it to the spawnPos variable

 

-From the spawnPos field find write over the biome field so that it can find the new biome instead of it staying on the old biome.

 

-back to the while statement to see if the information to see if the biome is an ocean or the block is water.

 

Where did I go wrong along the way?

Posted

So the while statement is broke? Heres how I -thought- it worked.

 

-while the biome equals ocean or the block the player is going to be spawned to is in water

 

- Set another spawn location with the randomSpawn() method

 

Going to stop you right there.  You're wrong:

loop.png

That's your loop.

 

"While the biome equals ocean or the block is water, setSpawn(spawnPos);"

 

do { /*something } while(/*condition*/);

 

You do not have a "while loop."  You have a "do-while loop" and it ends with the semicolon.

 

Those other three lines exist inside a block that is just a block.  There's no wrapper conditional or anything on it.  It's just a code block.

 

public void someMethod() {
    //method block
    {
        //some unnamed block. perfectly valid code.
    }
    while(/*condition*/) {
        //loop block  
    }
}

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Ah whoops, I'm still kinda rusty right now at coding.

 

I'm guessing the logic part is also wrong in the while statement? Because I moved all the code up to the do statement and I still spawn in water, and sometimes it just spawns me in this weird dark place and the game locks up.

 

 

@SubscribeEvent
    public void playerSpawn (PlayerEvent.PlayerRespawnEvent e)
    {
        BlockPos spawnPos = randomSpawn();
        Biome biome = grabBiome(e.player, spawnPos);

        do
        {
            e.player.getEntityWorld().getWorldInfo().setSpawn(spawnPos);
            spawnPos = e.player.getEntityWorld().getSpawnPoint();
            biome = grabBiome(e.player, spawnPos);
        }
        while (BiomeDictionary.hasType(biome, BiomeDictionary.Type.OCEAN) | e.player.getEntityWorld().getBlockState(spawnPos).getMaterial() == Material.WATER);
    }

 

 

Thanks for helping me out.

Posted

I'm also having problems getting the TickEvent to work for me. I just need a timer to count 8 seconds whenever the mob is set on fire. I've been working on it a couple hours and it either doesn't work, or looks very unnatural. I've tried looking on google and tried finding source code to read with stuff I would suspect had timers, but did not.

Posted

Ah whoops, I'm still kinda rusty right now at coding.

 

Oh... That can get you into trouble in this forum if you stack up Java ignorance. Once is understandable, because anyone can have a slip, but a losing streak will wear out mods' patience.

 

I recommend finding a Java helper through whom you can filter your questions, at least until you have more confidence that your questions are really about Forge and Minecraft, not basic coding.

 

Also: Eclipse (or any IDE worth the name) can help you too. It has features to show you matching braces, whole statements etc. Running in the debugger can let you step through your methods to see what it is doing and what variables have what values at various places. If you use these features before posting here, then you'll have solved more yourself and arrive with more information to give us.

 

PS: Yes, your program logic makes no sense. Find help with intro programming (ask a programmer to tell you how local variables work within computer programs) and get it cleaned up.

 

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

I know the basics at the very least. I've never been too advanced of a coder but I do have a grip on scope, variables, and using the debugger. I even set up my IDE to filter out from stepping into the APIs so I don't have to step out of thousands of line of code.

 

I've stepped through the code it says that it is an Ocean biome, but yet it doesn't try to grab another spawnpoint. I'm guessing I'm just using the wrong calls due to an ignorance of the forge API. I do know of a good java coders discord server, so maybe I'll run somethings past those guys too.

 

I do try very hard to come up with answers myself, I usually do not post until I've tried several approaches, google my problem , read other modders source code. I know how much coding forums hate people asking for them to write the code and I'm not trying to do that.

 

I will reassess my code though, thank you for your help and responding kindly.

Posted
I've stepped through the code it says that it is an Ocean biome, but yet it doesn't try to grab another spawnpoint.

 

You've stated that you understand scope and how to step through code.

 

Please show where the code is to fetch a new, random, spawn point and explain why it should be called during the second iteration of the loop.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

 

@SubscribeEvent

    public void playerSpawn (PlayerEvent.PlayerRespawnEvent e)

    {

        BlockPos spawnPos = randomSpawn();

        Biome biome = grabBiome(e.player, spawnPos);

 

        do

        {

            e.player.getEntityWorld().getWorldInfo().setSpawn(spawnPos);

            spawnPos = e.player.getEntityWorld().getSpawnPoint();

            biome = grabBiome(e.player, spawnPos);

        }

        while(BiomeDictionary.hasType(biome, BiomeDictionary.Type.OCEAN) | e.player.getEntityWorld().getBlockState(spawnPos).getMaterial() == Material.WATER);

    }

 

    public Biome grabBiome(Entity e, BlockPos pos)

    {

        return e.getEntityWorld().getBiome(pos);

    }

 

    private BlockPos randomSpawn()

    {

        double min = Math.ceil(0);

        double max = Math.floor(1000000);

 

        int randomX = (int) (Math.floor(Math.random() * (max - min)) + min);

        int randomZ = (int) (Math.floor(Math.random() * (max - min)) + min);

        int y = 1;

 

        BlockPos spawn = new BlockPos(randomX, y, randomZ);

        return spawn;

    }

 

 

There is all my spawn code.

 

Well I put it in there because if it looped around it would need another random spawn then I noticed, it never was getting another spawn point. so I rewrote it and it seems to be working, tried 15 times only problem was once I spawned in a tree...I thought MC checked to see if it's a spawnable block before placing you? Or is this something I have to write myself? Here is the new code btw.

 

 

public void playerSpawn (PlayerEvent.PlayerRespawnEvent e)
    {
        Biome biome;
        BlockPos spawnPos;

        do
        {
            spawnPos = randomSpawn();
            e.player.getEntityWorld().getWorldInfo().setSpawn(spawnPos);
            spawnPos = e.player.getEntityWorld().getSpawnPoint();
            biome = grabBiome(e.player, spawnPos);
        }
        while(BiomeDictionary.hasType(biome, BiomeDictionary.Type.OCEAN));
    }

 

 

 

Posted

Player spawn gives no fucks about trees. It's only mob spawn that requires a full, non-transparent, block. And even then is on a mob-by-mob basis (most mobs don't override that default though).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I threw this at the end of my code

 

e.player.preparePlayerToSpawn();

 

After 30 respawns I haven't spawned in a tree, it looks like this method checks to make sure that a player can spawn properly? Thank you so much for your patience and help. I think I'm going to list this one as solved!

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.