Jump to content

Recommended Posts

Posted

I'm trying to create a custom biome. I wrote the biome class and registered my new biome. My custom biome generates in-game with most of the custom blocks that I want it to. My question is, how can I remove the normal minecraft stone that generates there and replace it with my custom stone block? I also have a custom ore that I want to generate in this biome only. How can I do this?

 

ModBiomeRegistry

http://pastebin.com/ubMKLHE9

 

ModBiome

http://pastebin.com/NthUZFAr

 

I've also noticed that water lilies are spawning every where in the water even though I've never told the biome to. Why is this?

 

Another problem I've noticed is that mobs are spawning in the biome even though I don't have any mobs set to spawn there.

 

One last question. I made custom dirt, grass, and stone blocks that I want to have the same properties as the vanilla dirt, grass, and stone blocks. Can I just create a class for each that extends the vanilla class?

Posted

I'm trying to create a custom biome. I wrote the biome class and registered my new biome. My custom biome generates in-game with most of the custom blocks that I want it to. My question is, how can I remove the normal minecraft stone that generates there and replace it with my custom stone block? I also have a custom ore that I want to generate in this biome only. How can I do this?

 

ModBiomeRegistry

http://pastebin.com/ubMKLHE9

 

ModBiome

http://pastebin.com/NthUZFAr

 

I've also noticed that water lilies are spawning every where in the water even though I've never told the biome to. Why is this?

 

Another problem I've noticed is that mobs are spawning in the biome even though I don't have any mobs set to spawn there.

 

One last question. I made custom dirt, grass, and stone blocks that I want to have the same properties as the vanilla dirt, grass, and stone blocks. Can I just create a class for each that extends the vanilla class?

Posted

There's more than one way to substitute the vanilla stone. I think there's an event where you can detect vanilla stone and the biome, making the switch whenever you like the combo. You could also hunt down the code that fills most deep areas with stone. Be aware though: Most ores spawn only in vanilla stone; they won't replace anything else, so your biome might not get any diamonds, gold, iron etc.

 

Mobs decide where they want to spawn. There might be some that spawn in any biome.

 

Extending dirt etc will duplicate the intrinsic characteristics, but... Some game behavior is reactive (like plants deciding where they can grow). Therefore, some other objects in the game might not recognize your dirt as dirt (e.g. Plants might refuse to grow on it.)

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

There's more than one way to substitute the vanilla stone. I think there's an event where you can detect vanilla stone and the biome, making the switch whenever you like the combo. You could also hunt down the code that fills most deep areas with stone. Be aware though: Most ores spawn only in vanilla stone; they won't replace anything else, so your biome might not get any diamonds, gold, iron etc.

 

Mobs decide where they want to spawn. There might be some that spawn in any biome.

 

Extending dirt etc will duplicate the intrinsic characteristics, but... Some game behavior is reactive (like plants deciding where they can grow). Therefore, some other objects in the game might not recognize your dirt as dirt (e.g. Plants might refuse to grow on it.)

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

There's more than one way to substitute the vanilla stone. I think there's an event where you can detect vanilla stone and the biome, making the switch whenever you like the combo. You could also hunt down the code that fills most deep areas with stone. Be aware though: Most ores spawn only in vanilla stone; they won't replace anything else, so your biome might not get any diamonds, gold, iron etc.

 

Mobs decide where they want to spawn. There might be some that spawn in any biome.

 

Extending dirt etc will duplicate the intrinsic characteristics, but... Some game behavior is reactive (like plants deciding where they can grow). Therefore, some other objects in the game might not recognize your dirt as dirt (e.g. Plants might refuse to grow on it.)

 

1. Okay thanks, I'll look into it. As far as the vanilla ores go, I was hoping there was a way to disable them and use my custom ores instead.

 

2. I'll see if I can find a way to work around that.

 

3. No plants is fine. The biome is supposed to be dead looking. Though I will add some custom plants that can only grow on my custom dirt.

Posted

There's more than one way to substitute the vanilla stone. I think there's an event where you can detect vanilla stone and the biome, making the switch whenever you like the combo. You could also hunt down the code that fills most deep areas with stone. Be aware though: Most ores spawn only in vanilla stone; they won't replace anything else, so your biome might not get any diamonds, gold, iron etc.

 

Mobs decide where they want to spawn. There might be some that spawn in any biome.

 

Extending dirt etc will duplicate the intrinsic characteristics, but... Some game behavior is reactive (like plants deciding where they can grow). Therefore, some other objects in the game might not recognize your dirt as dirt (e.g. Plants might refuse to grow on it.)

 

1. Okay thanks, I'll look into it. As far as the vanilla ores go, I was hoping there was a way to disable them and use my custom ores instead.

 

2. I'll see if I can find a way to work around that.

 

3. No plants is fine. The biome is supposed to be dead looking. Though I will add some custom plants that can only grow on my custom dirt.

Posted

I tracked down the code that fills chunks with stone, and it looks like the stone is generated first then the biome blocks are placed. Not sure what to do with that. Do you happen to know the event that I can use instead?

 

Also, I managed to stop mobs from spawning here.( When I disabled creature spawning, I forgot to disable monster spawning.) I want the biome to only spawn wither skeletons. I made the biome spawn normal skeletons, how can I get wither skeletons to spawn?

 

Please Note: I am not trying to replace the stone in all biomes. I only want my custom stone to generate in my custom biome. All other biomes won't be changed.

Posted

I tracked down the code that fills chunks with stone, and it looks like the stone is generated first then the biome blocks are placed. Not sure what to do with that. Do you happen to know the event that I can use instead?

 

Also, I managed to stop mobs from spawning here.( When I disabled creature spawning, I forgot to disable monster spawning.) I want the biome to only spawn wither skeletons. I made the biome spawn normal skeletons, how can I get wither skeletons to spawn?

 

Please Note: I am not trying to replace the stone in all biomes. I only want my custom stone to generate in my custom biome. All other biomes won't be changed.

Posted

Unfortunately, I haven't worked with world generation before, so I can only give strategic advice on how to explore the Forge code yourself looking for hooks that Forge has injected. On one end, search the chunk generation source for any mention of forge or event (they often employ fully qualified names, so you can't rely on import statements to expose Forge references).

 

You might also try world's block-placement method or whatever the chunk generator returns to. You'd be looking for a call-back to a Forge method that would let you intervene. At the other end, go to net.minecraftforge.event and browse every event in every class to get an idea what's possible. Terraingen and World look like promising subfolders there.

 

Even after finding an event at a usable intervention point, you would still need to see if it carries enough information each way for you to detect your condition and achieve your goal. I think your chances are good, since this forum has discussed block substitutions before. However, I can't recall whether biome was a factor in any of them.

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

Unfortunately, I haven't worked with world generation before, so I can only give strategic advice on how to explore the Forge code yourself looking for hooks that Forge has injected. On one end, search the chunk generation source for any mention of forge or event (they often employ fully qualified names, so you can't rely on import statements to expose Forge references).

 

You might also try world's block-placement method or whatever the chunk generator returns to. You'd be looking for a call-back to a Forge method that would let you intervene. At the other end, go to net.minecraftforge.event and browse every event in every class to get an idea what's possible. Terraingen and World look like promising subfolders there.

 

Even after finding an event at a usable intervention point, you would still need to see if it carries enough information each way for you to detect your condition and achieve your goal. I think your chances are good, since this forum has discussed block substitutions before. However, I can't recall whether biome was a factor in any of them.

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've done as you said and overriden genTerrainBlocks (changed the vanilla integer names to easier to identify ones), but I can't figure out how to change the stone. I looked online for some help and the things I found told me to just copy the entire method generateBiomeTerrain in the BiomeGenBase class and then modify it to fit my needs. I do not want to copy and paste things unless it is completely necessary. How to I change the stone?

 

ModBiome.class

http://pastebin.com/4ZyHv9DJ

Posted

I've done as you said and overriden genTerrainBlocks (changed the vanilla integer names to easier to identify ones), but I can't figure out how to change the stone. I looked online for some help and the things I found told me to just copy the entire method generateBiomeTerrain in the BiomeGenBase class and then modify it to fit my needs. I do not want to copy and paste things unless it is completely necessary. How to I change the stone?

 

ModBiome.class

http://pastebin.com/4ZyHv9DJ

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

    • It is 1.12.2 - I have no idea if there is a 1.12 pack
    • Okay, but does the modpack works with 1.12 or just with 1.12.2, because I need the Forge client specifically for Minecraft 1.12, not 1.12.2
    • 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() ); } }  
  • Topics

×
×
  • Create New...

Important Information

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