-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Prevent item frame transmutation #8552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: mc1.20.1/dev
Are you sure you want to change the base?
Conversation
b079685
to
d7c6927
Compare
@@ -141,10 +142,10 @@ public static ItemRequirement of(Entity entity) { | |||
} | |||
|
|||
if (entity instanceof ItemFrame itemFrame) { | |||
ItemStack frame = new ItemStack(Items.ITEM_FRAME); | |||
ItemStack frame = new ItemStack(entity instanceof GlowItemFrame ? Items.GLOW_ITEM_FRAME : Items.ITEM_FRAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be best to use an accessor to call ItemFrame#getFrameItemStack
instead. That way modded item frames are supported too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be best to use an accessor to call
ItemFrame#getFrameItemStack
instead. That way modded item frames are supported too
IDEA didn't find it :/ i don't see a getFrameItemStack method in the ItemFrame class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
intermediary class_1533.method_33340
, which is ItemFrame#getFrameItemStack
in mojmap and ItemFrameEntity.getAsItemStack
in yarn
it is protected, so if you're doing itemFrame.getFrame[TAB]
then autocomplete won't find it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then something like this?
ItemStack frame;
try{
Method m = ItemFrame.class.getDeclaredMethod("getFrameItemStack");
m.setAccessible(true);
frame = (ItemStack) m.invoke(itemFrame);
}catch (Exception ignored) {
frame = new ItemStack(entity instanceof GlowItemFrame ? Items.GLOW_ITEM_FRAME : Items.ITEM_FRAME);
}
:/ i don't remember reading something similar in the codebase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your almost there, you want a invoker instead:
@Mixin(ItemFrame.class)
public class ItemFrameAccessor {
@Invoker("getFrameItemStack")
ItemStack create$getFrameItemStack()
}
And then this would go in a file named ItemFrameAccessor under https://github.com/Creators-of-Create/Create/tree/mc1.20.1/dev/src/main/java/com/simibubi/create/foundation/mixin
Now to call this, you would do the following:
ItemFrame frame = [...]
ItemStack stack = ((ItemFrameAccessor) frame).create$getFrameItemStack();
More in-depth write up of accessor's and invoker's
Accessor's and Invoker's
Accessor's/Invoker's can replace AW/AT's and be faster since you don't need to wait for loom/FG/NG/MDG to recompile the Minecraft jar.
(They are also really helpful when you need to access stuff in other mods as AW/AT's only work on Minecraft's source and aren't able to be used for other mods)
Accessor
@Accessor
lets you access protected/private fields.
Below is a example for a Accessor getter and setter.
@Mixin(LootPool.class)
public interface AccessorLootPool {
// Gets the entries field
@Accessor("entries")
LootPoolEntryContainer[] zeta$getEntries();
// Sets the entries field
@Accessor("entries")
void zeta$setEntries(LootPoolEntryContainer[] entries);
}
Usage:
// Getter
LootPool pool = ...
((AccessorLootPool) pool).zeta$getEntries();
// Setter
LootPoolEntryContainer[] entries = ...
((AccessorLootPool) pool).zeta$setEntries(entries);
Accessor for static fields
You'll want to throw a AssertionError
or any other error inside of the static method, Don't be afraid however it wont actually throw a error once used, it'll be overriden by the class you are mixing into, and the get/set operation instead of the error being thrown.
@Mixin(AxeItem.class)
public interface AccessorAxeItem {
@Accessor("STRIPPABLES")
static Map<Block, Block> zeta$getStrippables() {
throw new AssertionError();
}
}
Usage:
AccessorAxeItem.zeta$getStrippables(...)
Invoker
@Invoker
lets you call protected/private methods.
@Mixin(FireBlock.class)
public interface AccessorFireBlock {
@Invoker("getBurnOdds")
int zeta$getBurnOdds(BlockState state);
}
Usage:
((AccessorFireBlock) Blocks.FIRE).zeta$getBurnOdds(state)
Invoker for static method's
You'll want to throw a AssertionError
or any other error inside of the static method, Don't be afraid however it wont actually throw a error once used, it'll be overriden by the class you are mixing into, and the method you want to call will be called instead of the error being thrown.
@Mixin(CriteriaTriggers.class)
public interface AccessorCriteriaTriggers {
@Invoker("register")
static <T extends CriterionTrigger<?>> T zeta$register(T criterion) {
throw new AssertionError();
};
}
Usage:
AccessorCriteriaTriggers.zeta$register(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it'd be an @Invoker
, no?
Also, do they delegate to subclasses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it'd be an
@Invoker
, no?Also, do they delegate to subclasses?
Ah yeah, it'd be a invoker, i've fixed that.
And yeah they do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your almost there, you want a invoker instead:
@Mixin(ItemFrame.class) public class ItemFrameAccessor { @Invoker("getFrameItemStack") ItemStack create$getFrameItemStack() }And then this would go in a file named ItemFrameAccessor under https://github.com/Creators-of-Create/Create/tree/mc1.20.1/dev/src/main/java/com/simibubi/create/foundation/mixin
Now to call this, you would do the following:
ItemFrame frame = [...] ItemStack stack = ((ItemFrameAccessor) frame).create$getFrameItemStack();More in-depth write up of accessor's and invoker's
Thankiu so much, :D changes done
Fixes schematicannon consuming an item frame when printing a glow item frame. didn't find a open or close issue about it.