Jump to content

InspectorCaracal

Members
  • Posts

    63
  • Joined

  • Last visited

Posts posted by InspectorCaracal

  1. 1 hour ago, diesieben07 said:

    I don't think so. Look at ForgeInternalHandler.

    Ah, mild bummer. Yeah, I took a look at it, but I'm not at my dev machine right now so it'll be a few hours before I can try anything out.

    In the meantime, though, I noticed the delayed executor uses addFreshEntity, which is the same method for bees leaving hives and has me questioning my entire event. I had assumed addFreshEntity triggers the onEntityJoinWorld event, but that makes ForgeInternalHandler look like it would just continually remove and recreate the entity every tick which is obviously not right. Does the executor not trigger events, or does addFreshEntity not count as an entity join event? If it's the latter, what does addFreshEntity trigger, because that's what I need to be using.

     

    (Tangentially, I've been continually impressed by the scope of your knowledge of the code base and active presence on the forum, and I know that support work can feel incredibly thankless and exhausting so I wanted to mention that I really appreciate all the help!)

  2. 8 hours ago, diesieben07 said:

    Yes, EntityJoinWorldEvent is called during chunk loading. So if you try to access the chunk (which you do indirectly with getBlockState) then you have a deadlock, because the chunk can't be loaded until your event handler is completed, but your event handler is waiting for the chunk to be loaded.

    From what I can tell the reason getChunkNow doesn't work for you here is that the chunk is already half-loaded (see ChunkStatus) and in this case getChunkNow does not bail out and return null, instead if waits for it to be fully loaded.

    See ForgeInternalHandler for how Forge deals with this problem by delaying things by 1 tick.

    I'll take a look, but does this mean there isn't anything that'll tell me if it's only half loaded? I was really aiming for not executing the code block during chunk loading as much as possible, but as far as I can tell, this is the event to use for bees exiting their hives so I have to account for chunk loading as well.

  3. I know I said I didn't want to make a new thread, but it's still not working, so here we are.

    I have an EntityJoinWorldEvent function. I'm trying to set it so that it has a check to make sure it's not while the chunk is loading. So far, everything I've tried has resulted in the game saying the chunk is loaded during the initial entering-the-game loading phase and then never getting past the 100% indicator.

    This is what I currently have:

    @SubscribeEvent
    public static void beeSpawn(EntityJoinWorldEvent event) {
    	if (event.getEntity() instanceof BeeEntity) {
    		LOGGER.debug("It's a bee!");
    		BeeEntity bee = (BeeEntity)event.getEntity();
    		World world = event.getWorld();
    		if (!world.isClientSide()) {
    			LOGGER.debug("It's the server!");
    			if (bee.hasHive()) {
    				BlockPos hive_pos = bee.getHivePos();
    				if (world.getChunkSource().getChunkNow(hive_pos.getX() >> 4, hive_pos.getY() >> 4) != null) {
    					LOGGER.debug("Hive is loaded");
    					Block hive_block =  world.getBlockState(hive_pos).getBlock();
    					LOGGER.debug(hive_block.toString());
    					if (hive_block instanceof BeehiveBlock) {
    						BeehiveTileEntity hiveEntity = (BeehiveTileEntity)world.getBlockEntity(hive_pos);
    						if (world.getBiome(hive_pos).getTemperature(hive_pos) < 0.95F) {
    							LOGGER.debug("Bee attempted leaving the hive, but it's too cold.");
    							hiveEntity.addOccupant(bee, false);
    							event.setCanceled(true);
    						}
    					}
    					
    				} else {
    					LOGGER.debug("Hive isn't loaded yet, ignoring");
    				}
    			} else {
    				LOGGER.debug("Hiveless bee, ignoring");
    			}
    		}
    	}
    }

     

    And this is what I get to console:

    [20:10:42] [Server thread/INFO] [minecraft/MinecraftServer]: Preparing start region for dimension minecraft:overworld
    [20:10:44] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 0%
    [20:10:44] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 0%
    [20:10:44] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 0%
    [20:10:44] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 0%
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: It's a bee!
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: It's the server!
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: Hive isn't loaded yet, ignoring
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: It's a bee!
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: It's the server!
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: Hiveless bee, ignoring
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: It's a bee!
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: It's the server!
    [20:10:44] [Server thread/DEBUG] [co.cl.be.ev.ModEvents/]: Hive is loaded
    [20:10:47] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 83%
    [20:10:47] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 83%
    [20:10:47] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 83%
    [20:10:47] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 83%
    [20:10:47] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 83%
    [20:10:47] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 95%
    [20:10:48] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 95%
    [20:10:48] [Render thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 96%

    Aaaand then it just sits with the loading screen saying 100% forever. It's obviously getting stuck on "Block hive_block =  world.getBlockState(hive_pos).getBlock();" which I'm guessing is because it's trying to access block info while the chunk is loading and causing a deadlock, which means that this is still the wrong way to check if a chunk is fully loaded.

    How do I fix this?

  4. I'm not on my dev machine so I can't check the code myself, but I'm fairly certain the bee nest generation is attached to and triggered by the tree generation itself. If you want to use that approach, you'll need to hook into the lava pool generation, which I suspect is pretty difficult.

    Alternatively, I took a peek at some world gen stuff, and have you considered making the valid replacement block be lava source blocks instead of stone? It has the small chance of completely filling an underground lava pool, but otherwise I think it might do what you need.

    • Like 1
  5. This has nothing to do with the OP but it's a direct result of my previous post and I hate how I keep making new threads so I'm reusing this one >.>

    I'm trying to implement my entity join event solution, but I'm stuck because I can't figure out how to check if a chunk is fully loaded or not. My searching turned up exactly one solution, which is for 1.14 and references World.getChunkProvider().isChunkLoaded(pos) - which doesn't appear to exist in 1.16

    How do I check if a chunk is fully loaded in 1.16.x?

  6. So to summarize, it sounds like if I have a specific change in mind, the first step is to make absolutely sure there are no existing hooks that can do the thing, and then, if it's likely enough other people will want to modify the thing themselves to cause inter-mod compatability issues, I should look into making a forge hook PR everyone can use, and if it's not likely, then I don't really need to worry about it and can just replace them. Which is extremely reasonable.

    p.s. Thanks to going back and reviewing all the stuff that is in Forge already, I think I got a solution involving cancelling the bee entity join event and re-adding the bee data to the hive as an alternative to changing the release conditions, so I shouldn't have to break into anything after all. It's kinda tricky to find the stuff I need to use as a fresh modder but I'm continually impressed by how Forge is put together to let you do stuff.

  7. 8 hours ago, diesieben07 said:

    If there are no hooks in place for what you want to do, you can go down several routes.

    • Make a pull request into Forge if you think the hook could be useful for others as well.
    • Replace the vanilla objects
    • Just not alter vanilla things

    Ah, hmm! I hadn't thought about adding a hook to Forge myself. I'll have to sit down and go through everything to figure out if there's a most generally useful approach that could use a new hook.

     

    7 hours ago, MFMods said:

    there is no definite answer.

    for your case - bees - you need to investigate bee entity and bee hive and see what code is where.

    investigate bee goals (or ai tasks). goals can be replaced with your own. or, maybe instead of removing original goal for finding flowers, you can just add your own and bee will sometimes use original code and sometimes your code for finding flowers.

    and there are always events - when a bee entity is about to be spawned, you can decide you don't want that. store all the bee's data and cancel it being added to the world. then later (when it gets warmer or whatever), take the bees you stored and add them to the world yourself (when you deserialize their data, they'll know their hive location).... events can do wonders, but onlyu after you looked into the flow of original code.

    I've already done all those things, but it's a good reminder to look at the original source. (Speaking of flow of original code, the changes I want to make are on the TileEntity for the hive, not the bee, but that's tangential.)

    Although, when I was investigating the bee-goals angle, I couldn't find an easy way to replace or add AI goals without writing your own custom extension class? I don't need it for this, but if there's a hook for that, I'd love to learn what it is.

  8. I've been enjoying my dive into Forge modding so far, but I'm being presented with a pretty steep compatability conundrum at the moment. (I'm interested in general best practices and solutions, not just this specific case, but to make explaining it easier, I'm just going to talk about my current specific scenario rather than try to generalize.)

    My current end-goal here is bee hibernation: if the temperature at the hive's location is below freezing, then the bees won't come out. For my own hives, this is a trivial modification, since they already use mod classes that extend vanilla and I can override methods there with impunity. But this does Absolutely Nothing for the vanilla bee nests.

    The obvious solution is to replace all the vanilla bee nests with my own modded version as well, but that raises potential compatability issues if there's ever a different hypothetical mod that also wants to extend beehive functionality. I'd likely have to write in compatability with other mods on a case-by-case basis.

    (The only other thing I've stumbled across is coremods and I am absolutely not going to touch core modding. xD If I can't do a thing without coremodding I am simply not going to do it.)

    So, that said: what should I be doing here? Is replacing the vanilla entities with modded extensions typical, or is there a better solution?

  9. 11 hours ago, diesieben07 said:

    It's a field. You have to set it using reflection because it is private.

    Sorry, I'm not very good at keeping track of specific terminology and tend to just throw the closest word I can think of at it. Anyway, let me rephrase my question a little more clearly.

    Is the thing I'm supposed to modify a field called "matchingStates", or is it the field called "BEEHIVE"? I assumed you meant matchingStates at first, but there's no field by that name or even a similar name in PointOfInterestType, or even in the entire code base.

    I ran with it being the BEEHIVE field yesterday because I knew where that was, but it didn't work, and I want to find out if that's where you were pointing me before putting more work into figuring out what I might've done wrong.

    edit: Oh, it just occurred to me while looking at the fields again that you might've meant `Set<BlockState> blockStates` so I'm going to give that one a shot

  10. Well, that fix handles the specific problem I was having in regards to the constructor re: inheritance, but I'll be damned if I make another thread again at this point so my last remaining problem (optimistically) which I hunted down trying to figure it out is that the bees will only identify a hive as a valid potential target if they're BEEHIVE or BEE_NEST in the PointOfInterestType registry.

    Is there something else I can overload somewhere to get my hives in there?

  11. 4 hours ago, Draco18s said:

    This is basic java. It's called "type casting."

    I'm familiar with type casting, thank you. 😜 See: "not have it cast to Block"

    I suppose I will thank you for reminding me to look up the explicit typecasting syntax for Java, since that was a useful side-effect.

    I admit I started this thread in the hopes of discussing the general concept and implementation of a block activation method override done via an event handler, not for basic Java or debugging, but oh well.

    Anyway! Based on my own attempt, the original topic doesn't seem like a very useful way to replace the onUseActivation method, because bypassing the entire use chain is rather more of a pain in the butt than it's worth. It's definitely a solid way to add an additional check beforehand, though, which I wish was good enough for what I'm doing (it should be!) but oof. The bee code has everything hardcoded in like three different places, it's really annoying. I'm going to have to just extend the classes with my own versions after all.

  12. 11 minutes ago, Aaric90 said:

    I've been trying to figure out how to directly reference where i have installed Java 8, but I cant figure it out. I've put the path to the folder. Am I missing something? Just got forge for a server, with a mod that only works on 1.15.2 currently so I have the latest version of 1.15.2. Waiting for the mod to update beyond that so I wont have this headache. 

    Your server will have a default version of java that gets used when you just use the command "java" - in this case, it sounds like java 16

    What you need to do is instead of just "java -jar etc", use the path to the java executable in place of java. So instead of "java -jar etc." it's "/full/path/to/java1.8/executable -jar etc"

  13. On 5/7/2021 at 10:06 AM, Draco_Magnus said:

    Fair enough, but to me, for new coders, like me, it's a little aggressive, because I use W3Schools for my coding, and sometimes it can be confusing(and its even more so with me being low scale autistic). I just was wondering, x D

    I know this post is relatively ancient and all but please for the love of all good things, NOBODY SHOULD USE W3SCHOOLS EVER.

    1. It is not associated with w3.org
    2. It is full of OUTRIGHT WRONG INFORMATION
    3. It is a Bad Website and will teach you Bad Code, and anyone else who stumbles on this thread should know this.

    I'm all for using lots of reference and tutorial websites and examples when learning to code, but not W3Schools. Please. Anything else.

  14. I'm making my own beehives and I want to create them with the vanilla BeehiveBlock and BeehiveTileEntity classes. I've gotten it 99% working, except that when I place my custom hive, I get a warning and bees don't seem to recognize it (indicating there's no valid beehive te present).

    [minecraft/TileEntity]: Block entity invalid: minecraft:beehive @ BlockPos{x=-232, y=65, z=60}

    I'm not clear on why exactly this is happening, but my best guess is that it's due to the BeehiveTileEntity initially being registered with the bee nest and beehive blocks:

    public static final TileEntityType<BeehiveTileEntity> BEEHIVE = register("beehive", TileEntityType.Builder.create(BeehiveTileEntity::new, Blocks.BEE_NEST, Blocks.BEEHIVE));

     

    I've tried registering it with my own block in my registry class according to the TileEntityType registry docs and examples, but it didn't seem to affect anything. Is there a different syntax for adding new valid blocks to an already registered TileEntityType?

     

    edit: I should specify, the BeehiveTileEntity class has TileEntityType.BEEHIVE hardcoded into the constructor, which is likely what's complicating things.

×
×
  • Create New...

Important Information

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