The bug
Maps in item frames (both regular and glow item frames) being tested by comparators will output 1,2,3,4 for the four orientations a map can have on an item frame, but will then output 5,6,7,8 for those same orientations when rotated a second time.
Steps to reproduce
1. Place an item frame, and a comparator that reads from it. Place a map (already 'used,' with some drawing that is not rotationally symmetrical) inside it. The map will expand to fill the edge, as expected.
2. Rotate the map 3 times; the comparator will output signals with respective strengths of 1, 2, 3, and 4, as expected.
3. Rotate the map again. The map is now back to an orientation identical to the original orientation of the map, yet the comparator now outputs 5. Continuing rotation of the map will step through 6, 7, and 8.
Code analysis
Code analysis by @unknown can be found in this comment.
Linked issues
is duplicated by 1
Attachments
Comments 13
This is confirmed for 14w05a as well. This is currently my only real hurdle in a puzzle that I'm working on. Here's an animated GIF of this issue at hand.
A very closely related problem: when upgrading from 1.7 to 1.8, Maps in Item Frames are rotated wrong. I believe this all has to do with the 1.8 feature of being able to rotate items in item frames by 45 degrees rather than 90. When 1.8 loads an item frame from 1.7, it multiplies the ItemRotation value by 2, thereby keeping most items at the same rotation angle. However, because maps still rotate by 90 degrees for every ItemRotation, maps come out rotated twice as much as they should be.
Ways to fix this: 1. When loading 1.7 item frames in 1.8, check if the item is a map and decide whether to multiply the ItemRotation by 2 accordingly. And keep ItemRotation in the range 0-3 for item frames with maps in them.
2. Redefine ItemRotation for item frames with maps in, so they are always in (0, 2, 4, 6).
P.S. This bug still affects 14w29b
This still affects 14w34d.
Also, should we add some of the information from my earlier comment to this bug report? Or maybe split it into it's own report? It seems Mojang is getting ready to release 1.8 soon and this bug is going to break maps-in-item-frames in existing worlds.
Still affects 1.8
By the way, I filed my related bug as MC-68941.
That happens because the item is technical rotated different which I am sure is not intended. If you place an item frame, put a map in it and then rotate it 4 times and then put another item in it the item will be upside down.
I’d like to request ownership of this ticket, the original reporter hasn’t been active since January 2014, I will continue updating that ticket
Okay, I just checked the source and here's the root of the issue. In RenderItemFrame.renderItem(), there is the following line:
int i = flag ? itemFrame.getRotation() % 4 * 2 : itemFrame.getRotation()
Here's a little table for that math:
Rotation = 0 | 0 % 4 = 0 | 0 x 2 = 0 | Map Rotation = 0
Rotation = 1 | 1 % 4 = 1 | 1 x 2 = 2 | Map Rotation = 2
Rotation = 2 | 2 % 4 = 2 | 2 x 2 = 4 | Map Rotation = 4
Rotation = 3 | 3 % 4 = 3 | 3 x 2 = 6 | Map Rotation = 6
Rotation = 4 | 4 % 4 = 0 | 0 x 2 = 0 | Map Rotation = 0
Rotation = 5 | 5 % 4 = 1 | 1 x 2 = 2 | Map Rotation = 2
Rotation = 6 | 6 % 4 = 2 | 2 x 2 = 4 | Map Rotation = 4
Rotation = 7 | 7 % 4 = 3 | 3 x 2 = 6 | Map Rotation = 6
You can see how these numbers reflect the rotations in the bug report. If we change that line of code to this:
int i = flag ? Math.Floor( itemFrame.getRotation() % 8 / 2 ) * 2 : itemFrame.getRotation()
Our new table looks like this:
Rotation = 0 | 0 % 8 = 0 | 0 ÷ 2 = 0.0 | floor(0.0) = 0 | 0 x 2 = 0 | Map Rotation = 0
Rotation = 1 | 1 % 8 = 1 | 1 ÷ 2 = 0.5 | floor(0.5) = 0 | 0 x 2 = 0 | Map Rotation = 0
Rotation = 2 | 2 % 8 = 2 | 2 ÷ 2 = 1.0 | floor(1.0) = 1 | 1 x 2 = 2 | Map Rotation = 2
Rotation = 3 | 3 % 8 = 3 | 3 ÷ 2 = 1.5 | floor(1.5) = 1 | 1 x 2 = 2 | Map Rotation = 2
Rotation = 4 | 4 % 8 = 4 | 4 ÷ 2 = 2.0 | floor(2.0) = 2 | 2 x 2 = 4 | Map Rotation = 4
Rotation = 5 | 5 % 8 = 5 | 5 ÷ 2 = 2.5 | floor(2.5) = 2 | 2 x 2 = 4 | Map Rotation = 4
Rotation = 6 | 6 % 8 = 6 | 6 ÷ 2 = 3.0 | floor(3.0) = 3 | 3 x 2 = 6 | Map Rotation = 6
Rotation = 7 | 7 % 8 = 7 | 7 ÷ 2 = 3.5 | floor(3.5) = 3 | 3 x 2 = 6 | Map Rotation = 6
This change makes it so that the map only has one rotation "cycle" and it rounds diagonals to the previous cardinal direction. However, this means that you have to click the map twice to visually make a single 90 degree rotation. To fix that, we move to EntityItemFrame.processInitialInteract(), and we look for the following line:
this.setItemRotation(this.getRotation() + 1);
If we add a check here for maps in the frame, we can have it increment double to make it visually rotate properly, like so:
if (this.getDisplayedItem().getItem() == FILLED_MAP)
{this.setItemRotation(this.getRotation() + 2);
}
else
{this.setItemRotation(this.getRotation() + 1);
}
Now, the last thing we need to do is make it so that when an ItemFrame is filled with a map, the rotation floor rounds so that the rotation will always be 0, 2, 4, 6, so the visuals and backend always match. To do that, we go to EntityItemFrame.setItemRotation() and find this:
this.getDataManager().set(ROTATION, Integer.valueOf(rotationIn % 8));
Now we make a similar changes here:
if (itemFrame.getDisplayedItem().getItem() == FILLED_MAP)
{this.getDataManager().set(ROTATION, Integer.valueOf(Math.Floor(rotationIn % 8 / 2) * 2));
}
else
{this.getDataManager().set(ROTATION, Integer.valueOf(rotationIn % 8));
}
There's one other instance (that I can think of) where the rotation of an ItemFrame with a map in it could be odd, and that's if the the ItemFrame was rotated with a different item before the map was placed in it. To remedy that, I can think of three solutions. We could call EntityItemFrame.setItemRotation() from EntityItemFrame.setDisplayedItem() or EntityItemFrame.setDisplayedItemWithUpdate(), or inside the code block for EntityItemFrame.setDisplayedItemWithUpdate(), we could add the same code snippet that we modified in EntityItemFrame.setItemRotation(). Any of those solutions will update the rotation immediately upon placing a map in the ItemFrame.
Confirmed.