Jump to content

Recommended Posts

Posted (edited)

How do you do this or is there no set definition for default spawn block? I need this to change my dungeon floor if it can't spawn under a specified block such as cobblestone when it's looking for grass block

 

Solved: you can't but, for dungeon tweaks during word gen I have the floor being parsed through config files and if IAnimal config will be by default grass. There is another way but, way unoptimized create a fake world do 255*2(one day one night) of a single block in a fake world for all blocks* amount of entities but, I don't really know how to do that t that's not a success always for grabbing the blocks as entity can be bigger so then you would have to fill on layers from 0-255 yes it could be done but, parsing floors from a couple files is probably more optimized.

Edited by jredfox
Posted (edited)
12 minutes ago, diesieben07 said:

There is no set definition. You can query it for an entity by calling ForgeEventFactory.canEntitySpawn(EntityLiving, World, float, float, float, MobSpawnerBaseLogic). If that returns Result.DEFAULT fall back to EntityLiving::getCanSpawnHere && EntityLiving::isNotColliding.

mobspawnerbaselogic? can't use that I want a cache. So what make a fake world set light level to dark 0 and make of 16 both times each time and iterate through all blocks and entities then?


is there at least a way to determine light level?
 

well I think there should be a set of resource locations of blocks that the entity can spawn on ignoring light level. or a method that determines if a entity can spawn on a block

Edited by jredfox
Posted (edited)

because this is ridiculous 

 

0-255day + 0-255 night iterations per block * amount of blocks * amount of entities + a constant fill command based on entities width and length for a fake world object on startup.

 

Is there any better way of doing this if I do it the only way I can think of then that's highly unoptimized probably will delay the game startup a full minuet on post init during a modpack.

 

my goal is to set the floor of the dungeon with whatever block the entity is suppose to spawn on I could hard code stuff but, then it won't work with mobs from other dimensions like the aether bunny then I would have to add the ability for users to parse floor blocks and override the floor per mob

Edited by jredfox
Posted (edited)
44 minutes ago, diesieben07 said:

Read the Javadocs.

 

No.

 

Entity spawn conditions are not just based on block below. They can depend on biome, dimension, nearby blocks, nearby entities, the current time of day, whatever.

What you want is not possible.

 

You can override the entity's default spawning behavior using LivingSpawnEvent.CheckSpawn, that would be what I'd do instead of trying to match the floor. Because like I said above, the floor might not be enough.

I only plan on changing the floor during worldgen if the entity can't spawn on the block of cobblestone or mossy cobblestone. I think the best way to do this is for users to define the floors but, give them some auto detection if it's IAnimal put the default floor to an actual block rather then the keyword of "default".


As for the lightlevel the user will be able to define torches on the walls somehow haven't thought of it yet


Then for specific dungeon dimension overrides and advanced xml entries they can override the global floors walls roof there

Edited by jredfox
Posted (edited)

Why not use the LivingSpawnEvent.CheckSpawn? Because in that case you could just force it to spawn on your blocks. Also, if you're concerned with world gen and if the event doesn't fire at that time at least during world gen you can generate any entities you want yourself.

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted (edited)
50 minutes ago, jabelar said:

Why not use the LivingSpawnEvent.CheckSpawn? Because in that case you could just force it to spawn on your blocks. Also, if you're concerned with world gen and if the event doesn't fire at that time at least during world gen you can generate any entities you want yourself.

 because this needs to be done during chunk populate event I create the instanceof the base entity simply to see what the floor should be nothing to do with a mob spawning from a spawner it's worldgen. that would turn the floor anywhere you place it I only want that to be in the dungeon specified so...

Edited by jredfox
Posted
19 minutes ago, jabelar said:

But since you're doing your own world gen why can't you just spawn your own entities?

it's a dungeon, with a spawner that could be any mob. I plan on not adding any entities to the game it's a server utility. An override for the current dungeon

Posted
43 minutes ago, jredfox said:

it's a dungeon, with a spawner that could be any mob. I plan on not adding any entities to the game it's a server utility. An override for the current dungeon

Do you really need to change your dungeon floor? I'd look at it the other way -- just force the entities to spawn on your floor.

 

During world gen you can generate a mob or two as you want and after that you can handle the spawner generation with the event.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted (edited)
9 minutes ago, jabelar said:

Do you really need to change your dungeon floor? I'd look at it the other way -- just force the entities to spawn on your floor.

 

During world gen you can generate a mob or two as you want and after that you can handle the spawner generation with the event.

Then that would involve replacing the tile entity mob spawner not going to happen. Also the width and dungeon height will get adjusted if entity is to big. It would make sense if you have a sheep dungeon you have good green floor with torches. So you go why do I hear sheep in a cave sheep spawner! I am thinking of having some kind of loot tables per entity in the dungeon for entity definitions so for a creeper spawner you might find a bedrock pickaxe, or a sheep spawner find wool apples, golden apples, wood water healing and light, and coal. Main dungeon only though

Edited by jredfox
Posted (edited)
11 minutes ago, jabelar said:

Do you really need to change your dungeon floor? I'd look at it the other way -- just force the entities to spawn on your floor.

 

During world gen you can generate a mob or two as you want and after that you can handle the spawner generation with the event.

there is no mob tile entity spawning event the mob spawner tile entity spawns them in if and only if the mob can spawn their via entity getCanSpawnHere() boolean. The living spawn event is for biome spawns

Edited by jredfox
Posted

Okay, I understand what you're trying to do. But honestly you're really describing generating dungeons that are semi-custom depending on the mob spawner. In that case you're going to in some way need to have a list of the things you need to customize based on the entity, such as the floor, loot table, and any other things like height of the ceiling or other decorations.

 

Once you get to that point, you might as well just create a list for each entity. There are not really that many vanilla entities -- maybe about 25 land-based ones. I would just make a "hard coded" Map collect with suitable blocks associated with each.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted
4 hours ago, jabelar said:

Okay, I understand what you're trying to do. But honestly you're really describing generating dungeons that are semi-custom depending on the mob spawner. In that case you're going to in some way need to have a list of the things you need to customize based on the entity, such as the floor, loot table, and any other things like height of the ceiling or other decorations.

 

Once you get to that point, you might as well just create a list for each entity. There are not really that many vanilla entities -- maybe about 25 land-based ones. I would just make a "hard coded" Map collect with suitable blocks associated with each.

already planned out I am editing my library now painfully editing it, changing from base class to interface and two base classes for line parsing. 

Yep I know this is for dungeon tweaks and tweaks will come not just mob editing this thread is now marked 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.