I want to partly change JigsawManager's functionality for my custom structure in mod. However, vanilla JigsawManager is not really that expendible as almost all code is in the same function and some properties are private so the only possible solution currently seems to be to copy whole JigsawManager and manually customize it. This is not really easy and many mappings are missing (both in 1.15.2 and 1.16.1).
This is what I want to achive:
Chose and place first piece from pool "mystructure/entrance."
Start processing all children jigsaw connections.
Normally process all children who aren't in pool "mystructure/special" (but also apply following steps on their children if needed).
If connection's pool is "mystructure/special," chose one piece from that pool. New piece is guaranteed to contain one or more jigsaw connections of that same type/pool. For all of such connections, chose and the exact same piece again with the same orientation. Repeat doing this (chosing the same piece for that pool) until certain condition is meet (y coordinate is almost the same as randomly choosen number between 10 and 50). For all other types/pools, go to step 3 (normally process and place them, but still check for that specific pool). Jigsaw's current depth should not be changed/increased when placing special pieces from pool "mystructure/special," but should be changed/increased normally when placing other pieces.
After that condition is meet, stop placing pieces from "mystructure/special." Place random piece from "mystructure/finish" with same orientation as before, Start placing other pieces normally eith any orientation (step 3).
Thing that pieces from special pool should keep rotation from parent piece is probably easy to do in 1.16 as jigsaws now have joint type aligned which seem to cause them to keep rotation from parent (I'm not sure if this is true so it should still be tested. If it not true, some additional things should be done). However, other things are more advanced and it seems there is no good solution currently.
I found PRs #6378 and #6732 which add events which enable mods to add custom pieces or remove original ones on generation. However, they still don't help me in current state:
First PR provides access to ResourceLocation but only fires on init so I can't dynamically check condition.
Second PR fires event on generation so I could check for condition (but I can't because of following limitations) but parses ResourceLocation according to "village pool-naming rules" so it may not be the best for custom structures. Parameters like "generalType," "specificType," and "isZombie" should probably be provided and one more village-specific way and raw ResourceLocation should also be accessble.
It should be possible to listen for event just on specific structure type to improve performance and make checks easier.
They don't provide a way for me to check my condition (no way to check current BlockPos so I can check if y coordinate is correct). This could probably be solved if event also gets BlockPos parameter.
They don't provide a way to prevent depth from chaning. This is harder because you can't modify parameter's value because it is passed by value.
I don't know if there is any way to chose that random y coordinate for every structure, keep it forever for that structure and access it from event.
Once those limitations are fixed in some way, I could probably implement structure in this way:
Before generation starts, get and save random y coordinate. Also get and save random piece from "mystructure/special" pool. This is part I don't really know how to do.
Listen on event similar to that in #6732. Every time that event is triggered for my specific structure:
Check if target pool is "mystructure/special" and if it is not just skip other steps and return unmodified pool and normally increase depth.
If current y coordinate is bigger/higher than stored random value, remove all existing pieces from pool and add pre-chosen piece into it. Make sure it keeps rotation. Don't increase depth.
If current y coordinate is smaller/lower than stored random value, remove all existing pieces from pool and add random piece from "mystructure/finish" into it.. Make sure it keeps rotation. Don't increase depth. - Then normal generation will start. Because following pieces won't have any connection from "mystructure/special" pool, condition from step 3 won't be evaluated and special generation won't be executed, so there isn't anything special to do.
Do you think it would make sense to improve event handling from those PRs (and merge them)? Would this be a good way to generate such structure? Does joint type in jigsaw blocks prevent rotation like I think it does? How to chose y coordinate and piece for each structure and keep it until generation is done?
If possible, I would like that this is added to Forge 1.16.