Skip to content

Add dynamic drum colors#164

Open
FourIsTheNumber wants to merge 9 commits into
masterfrom
drum-color-strip
Open

Add dynamic drum colors#164
FourIsTheNumber wants to merge 9 commits into
masterfrom
drum-color-strip

Conversation

@FourIsTheNumber

Copy link
Copy Markdown
Collaborator
image

-Split the model's middle block into 3 separate cubes and made two of them have face tinting

-FluidColorCache builds a mapping between FluidRegistry fluids and colors by pulling fluid icons off the block texture atlas during TextureStitchEvent.Post and averaging their colors by pixel. If it gets a "useful" value from getColor (not 0xFFFFFF) it will just add that and skip all of the texture averaging for that fluid.

-When the drum is placed, emptied, or filled after being empty, it sends a packet to the client so the render can be refreshed.

"south": {"uv": [0, 5, 2.5, 6], "texture": "#0", "tintindex": 0},
"west": {"uv": [2.5, 5, 5, 6], "texture": "#0", "tintindex": 0},
"up": {"uv": [7.5, 7.5, 5, 5], "texture": "#0"},
"down": {"uv": [2.5, 6, 0, 8.5], "texture": "#0"}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have entries for the top & bottom faces for the middle parts of the drum? Those shouldn't need to be rendered, and thus should be removed, I think.

GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buf);

int[] pixels = new int[width * height];
buf.get(pixels);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why allocate an array to hold a copy of the buffer instead of getting the pixels directly from the IntBuffer?

Comment on lines +115 to +120
@Override
public Packet getDescriptionPacket() {
NBTTagCompound tag = new NBTTagCompound();
writeToNBT(tag);
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 2, tag);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why send over all the data, and not just the fluid ID?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because colorMultiplier in BlockDrum accesses the tank. To send over just the fluid id I would have to do a bunch of careful manual overwriting of the state of the tank on the client, which sometimes contains a serialized FluidStack and sometimes does not.

This block has very little NBT data and this packet is fired only on update, I think this is harmless.

: tank.getFluid()
.getFluid();
if (before != after) {
worldObj.markBlockRangeForRenderUpdate(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worldObj.markBlockForUpdate does the same thing on the client, and it's simpler.

}

private void renderUpdate() {
if (worldObj != null && !worldObj.isRemote) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't need to be gated behind worldObj.isRemote - if it is called on the client, it will just call markBlockRangeForRenderUpdate

public void setFluid(FluidStack stack) {
this.tank.setFluid(stack);
markDirty();
renderUpdate();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No check to see if renderUpdate is necessary?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only time this is called is when it's placed. I supposed someone could technically use this method for something else that might benefit from a check, but it's so unlikely to be used frequently. I guess I can add a check though


for (Fluid fluid : FluidRegistry.getRegisteredFluids()
.values()) {
if (colorMap.containsKey(fluid)) continue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause issues. If I load a texture pack which changes the color of a fluid, then this check will skip updating its color and use the color it calculated on game load.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's really just for water and lava. I guess a better approach would be to just add them after the fluidregistry loop.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You never clear the colorMap. The texture build step can happen multiple times, especially if I reload texture packs or something like that. After the first time this method runs, it will just skip all the fluids.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that makes sense. I was thinking of it as a once per load thing.

@FourIsTheNumber FourIsTheNumber mentioned this pull request Jun 25, 2026
20 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants