MineColonies

MineColonies

53M Downloads

[Feature Request] Scan tool C&B compatibility

thephoenixlodge opened this issue · 49 comments

commented

Currently blocks constructed with C&B cause strange issues such as the builder consuming the blocks without placing them, etc. I would to provide scans of some of my custom village buildings I use in Sprout as things the builder can build in the pack, but currently these issues make it unviable. I would love to see compatibility here, even if it required the player to provide each individual bit required to construct the blocks, or if the builder could somehow deduct bits from whole blocks provided.

commented
  1. Unfortunately C&B requires Tile Entity Data, hence the IBlockAccess or World requirement. If you only have an IBlockState I'm not sure what you can accomplish, since that will only tell C&B what "class" of block it is, stone, snow, fluid, or what like. It doesn't contain any of the actual structure of the block.

  2. The Visitor is something you implement, you implement and create an new IBitVisitor and C&B calls your implemented method with the data.

commented

I have the tileEntity data as well, I just don't have the block in the world.

commented

So if you had a method, IBitAccess getBitAccess(TileEntity te); it would work?

commented
commented

Well... technically if you have the TileEntity, doesn't that mean you could just call te.getWorld() and te.getPos() on it?

commented
commented

Alright, I've added a new method to IChiseledBlockTileEntity.

if ( TileEntity instanceof IChiseledBlockTileEntity ) (
IBitAccess access = ((IChiseledBlockTileEntity)te).getBitAccess();
... do things ...
}

Should be available, you should be able to do introspection without a world, but a fake would would probably work as well.

Test Build, https://dvs1.progwml6.com/jenkins/job/Chisels-and-Bits/127/

commented
commented

@AlgorithmX2 I checked out your API today, since I finally got time to work at this.
But some things are extremely bad to hook into for us:

a) You need a world to get IBitAccess (We only have the IBlockState)
b) After hacking me the IBitAccess with a wrong pos and wrong world but the right state I need a visitor, but I don't seem to find a way to get that.

Can you help me out here?

commented

I just wrote a new test https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/debug/DebugAction.java#L394-L410 and it seems to be working fine, I tested it on a block with a single layer mix of 3 materials and the counts and the material types were both valid.

Are you sure your block contains what you think it does? and that however your using them is working properly?

commented
commented

Only the NBT is different, since those are bits. this is normal since the Item implements the proper behavior to prevent stacking when NBT is different.

commented

@OverRide
public IBitBrush visitBit(final int x, final int y, final int z, final IBitBrush iBitBrush)
{
if(iBitBrush.getStateID() != 0)
{
stacks.add(iBitBrush.getItemStack(1));
}
return iBitBrush;
}

This only seems to add the sand bits and not the gold and birch bits I have in it.

commented

@AlgorithmX2 when will you merge those changes to maven so I can check out your latest link?

commented

If your tests are all working I can probably push out a new build soon, maybe tonight or the next few days.

commented
commented

I've gone ahead and done an official release that includes the new API Method.

commented
commented
commented

Did you add it to the maven repository as well already?
http://dvs1.progwml6.com/files/maven/mod/chiselsandbits/chiselsandbits/
Can't find it here.

commented

The maven only stores the build server builds, and so far I've not been using the build server builds as official releases, 14.0.128 is the build server number for 14.16 Its something that I've not really though about since it was a late addition and I've not had a lot of time to really consider changing my processes for it.

commented

What is C&B?

commented

Ah Chisel and Bits

commented

@thephoenixlodge Is there something special that needs to be done here?
We basically just place block and load the TE from NBT?

commented

Watch this to get a an idea of the current problems: https://youtu.be/57eM8clrNkg?t=20m35s

I don't really know enough of the way C&B works internally to provide more insight, though I know Recurrent Complex has handling for it and is open source so maybe looking to see how they do it would be an option?

commented

Sure, send me the schematics first i will dig a bit into them seeing if they are actually in the schematic or if they are skipped entirely

commented

Looking at Recurrent Complex they handle it exactly the same way as we are.... Set block -> Load TE data if present.... Weird.

commented
commented

Okay I checked it out on the server, the chisel and bits blocks also don't get rendered at all with the buildTool + we have a problem with copy/ paste in smp because it only loads the schematic so we have to press it twice, it should happen asynch to paste as soon as the schematic arrives

commented

Yeah I am pretty sure something is wrong with the schematic here

commented

Since we can place furnaces just fine with there TE

commented

Since I saw there was an attempt at compat in the newest alpha version, I decided to have a bit of a test. There's good news and there's bad news.
First, the good news - the builder can successfully place C&B accurately to the scans.
The bad news however - it does so without caring what the NBT of the chiseled block it's given is. While this is theoretically a wise design so as to allow the player to get nice C&B builds without having to have made them themselves first, the downside is that it's highly abusable as a dupe bug. This is because you could do a scan of an expensive block with just a single bit removed, and then give the builder a block made from a single bit of the same type of material (ie. if a metal block, give the block form of a bit that count's as "Chiseled Metal") - the builder will take the single bit, and place it as the nearly full block.
To put this into perspective, as far as the builder is concerned, a single iron block bit is the same as a nearly full block of diamond.

commented

Understood, I am not sure that the API that chissel and bits offers allows us to fix something like this however.

commented

That's... not ideal. It must be frustrating, trying to add compatibility for such a complicated mod. I know I'd be frustrated beyond belief, I already am just looking at their code and yours, and well, anyone else's.
:(
But from what I see, you are copying tile entity data straight over? And requiring the item to place that tile entity? I think the problem lies in how the block and the item store their data differently. Which means instead of looking at the API, you'd have to look at the implementation of the chiseled block itself.
Which, I understand, is a crazy difficult endeavor, and I wish you all the luck, AND I may be misunderstanding the situation entirely, but as far as I know, your best bet would be to start at chiseledblock/ItemBlockChiseled

commented
commented

This is for Chisels and Bits, NOT Chisel. They're very different, and C&B's blocks can effectively have infinite different combinations of bits, so no, you can't really just transform them into a normal block.

commented

@Raycoms What he means is the following Situation:
In C&B A block exists out of 16 * 16 * 16 Bits. Given the following Situation:
Place a solid block and take 1 bit out, this turns into a C&B Block with 16 * 16 * 16-1 Bits. When the builder builds this block, he requests 1 bit effectively giving you 16 * 16 * 16-2 Bits for free.

Which ofcourse is a big dupe bug.

commented
commented

Yes, it is possible to place the bit back into the duped block and get back the block from which it was chiseled. AKA, take that diamond block with one bit missing. Have the builder place several of these for the cost of one iron-block (or diamond-block, but iron is cheaper) bit each, then place a diamond bit into the missing space, and the block turns into a diamond block. So not only are you getting free bits, you are getting free diamond blocks.

commented
commented

The way I see it, there's two viable options as solutions:

  1. The player has to give the EXACT C&B block that'll be placed. This'd work fine for Sprout where I can make it that players can get those blocks prebuilt for them by selling from Custom NPCs, but for general use is impractical and pointless as there'd be no difference from the player making and placing the bit blocks themself.

  2. Make the builder capable of converting blocks to equivalent bits for constructing these blocks and/or accept individual bits to construct the block. The ideal situation would be for this to work both ways, but it becomes a matter of whether it's possible to get the needed data from the placed blocks, and whether there'd be a way to do this in a practical manner that doesn't completely flood the builder's inventory with bits (Higher level = bigger inventory maybe? Not sure on this, other than maybe somehow working with bits bags), since a full block is 4096 bits.

An absolutely ideal situation would be for all of these options to work, but I realise that's a pretty unreasonable request at this point. Maybe it's worth contacting @AlgorithmX2 for help/advice on the matter too.

commented

You'll want to avoid using anything outside of chiselsandbits/api, since thats the API, as you have deduced core/api is the implementation of said API.

If you want to scan a block, https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/api/IBitAccess.java#L34 is your best bet, it visits each bit in a block and gives you access to https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/api/IBitBrush.java for each one of them.

This allows you get to item stacks or block states.

The entry point for the API is in https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/api/IChiselAndBitsAPI.java

I'm not sure what you mean by it not being very "functional"

commented

And if your not sure how to get started with the API, https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/debug/ApiDebug.java is an example of how to get access to the IChiselAndBitsAPI object. Note the Annotation and and interface. That folder has various tests for the API. If your looking for a larger scale use case of the API, https://github.com/Phylogeny/ExtraBitManipulation uses basically every part of it to my knowledge.

commented

:| And this is why I need to finish my courses in Java before trying to give recommendations on what to do. Clearly my idea of what an API is and what it does is not yet fully correct, nor is my idea of what an Interface is and what it does fully correct either.

What I personally mean by functional, is that there is actual code that does something in the implementation folder, as compared to the API folder, which is merely the command names with comments barely explaining what the implemented commands should do (In other words, an interface; as I understand it, an interface can be implemented by a class, which then gives function to all the commands; you'd want to program your own implementation of the interface if you're using it with something vastly different than the default implementation), and then saying not to implement them for some reason, which I took to mean, do not use these, use a different part of the API like a default implementation of the interfaces. Unfortunately, I did not find any part of the API which was allowed to use which implemented the functions of those interfaces, that is, a functional function, which is why I went looking outside of the API folder for a default implementation.

Unfortunately, everything I've said I have said as a novice in Java, and NOT as a developer for this mod, since I am not a developer. Everything so far has been a suggestion; which clearly, should all be disregarded now.

commented
commented

...this is why I hate the black-box design philosophy. Anyways.

So @AlgorithmX2 you recommend calling the method visitBits. What does it do, exactly? What do you need to do in order to call it? What does it do that you can then USE to do something else? From the comments I can deduce that you need some sort of "visitor", so I check IBitVisitor, which... calls visitBits? That's a circle!

Clearly I am not understanding this, OR how a mod like this one would use it. So all my attempts to try and help the devs out have been... for naught.

commented

@Flabort the reason the API is black box is so that C&B can undergo almost a full re-write without affecting any users of API, another mod could even implement the exact same API and allow people to access the same functionality as C&B without even being C&B. There are countless benefits to an interface only API.

As for your question, its a visitor pattern, ( https://en.wikipedia.org/wiki/Visitor_pattern )
IBitVisitor is a interface you would implement, the method on said class which implemented it is called for each bit in the block, you feed your IBitVisitor to C&B via vistBits(...) then C&B will call back to that object detailing out the information.

C&B uses this solution to optimize a considerable amount of overhead away that would normally be accrued by looping over x, y, z in the mod using the API and requesting each bit one at a time. If you only wanted to check on 1 bit however getBitAt would be more effective as it preforms this operation on 1 bit without worrying about the other data in the block.

commented

I guess I get why programs are written to be black-boxed, but it doesn't mean I have to like it.

commented

Huh. I just learned that the chisels and bits mod has two API folders. There's the src/main/java/mod/chiselsandbits/api one, but also src/main/java/mod/chiselsandbits/core/api which I just discovered. It looks a lot easier to work with than the other folder - not sure if you were already aware of it.

Possibly it just implements it's own API in that folder, which is why it looks much more functional than the other API folder. Even if this is the case, it's an example of how to use the API and still useful, right?

So my (uneducated) recommendation is to look at chiselsandbits/core/api/ChiselsAndBitsAPI.java, look at the command getBitPos, and examine it. If you can't understand it, I'm fairly certain the return type (BitLocation) is implimented in chiselsandbits/chiseledblock/data/BitLocation.java ; There's a function in there which lets you just have a bit position (the inputs being "blockpos, x, y, z", with x, y, and z referring to the bit's location in the block).

As an idea for implementing the second solution provided by Pheonix, try iterating over all 4096 possible bit locations in a chiseled block (may want to make sure it's a chiseled block before trying), and for each bit do... something. I'm still struggling to find an useful operation that takes a BitLocation as an input, but if I find one it should return an itemstack for the bit in that location. With knowing what the total itemstacks that you need are, I'm sure you could do the rest. Once the builder has all the bits for the scanned block, he places the block the way you have it now.

Aactually, there's a "Public ItemStack GetPickBlock()" in chiselsandbits/ChiseledBlock/BlockChiseled.java that shows how to get an item stack from a BitLocation - it's a bit too complex for me, but it's something of a start.