#Is it possible to override a vanilla object? How to use .set() instead of .register()!?
48 messages · Page 1 of 1 (latest)
Any help is appreciated

Is it possible to override a vanilla object? How to use .set() instead of .register()!?
I have just found the torch item. it is a block item:
@Mixin(Items.class)
public class ItemMixin {
// Torch block item
@Redirect(
method = "<clinit>",
at = @At(
value = "NEW",
target = "net/minecraft/item/BlockItem"
)
)
private static BlockItem redirectTorchBlockItem(Block block, Item.Settings settings) {
if (block == Blocks.TORCH) {
return new AgeingTorchItem(Blocks.TORCH, Blocks.WALL_TORCH, settings);
}
return new BlockItem(block, settings);
}
}
All works as expected it seems I am on the right track with using mixins.
How to use the set() method is still unknown
Have you considered redirecting the calls to register the torch block and item register your own variants instead?
The other option is to just create your own, then overwrite the recipe to create vanilla torches to your own
A third option is to hook into the properties of the torch and add in an age property that increments every successful random tick with a very small percentage to increment. This would prevent you from creating a block entity to do ticking.
Then once it has hit the maximum age, the drops for the block change to whatever you were planning
why would you do this instead of just mixing into the original item/block class and checking if the blockstates block/itemstacks item is the vanilla torch before doing any custom logic
Agreed! The current idea seems a bit overengineered
This way keeps the project structure simple for me to understand without adding a bunch of injections that i still vaguely comprehend the function of.
i would love an example of what you mean.
This sounds good to me, but methods like randomDisplayTick and onUse are overriden in my current implementation to change particles and functionality based on state. This is still doable?
An example would be great for my comprehension.
❤️
after pondering i realize it might be just as simple yet more effective to mixin to the original class. let me try it
Keep in mind that registry replacement seems easy until you try it 🙂
@Mixin(TorchBlock.class)
public class TorchBlockMixin {
@Inject(
method = "randomDisplayTick",
at = @At("HEAD"),
cancellable = true
)
private void cancelDisplayTick(BlockState state, World world, BlockPos pos, Random random, CallbackInfo ci) {
// do nothing if another block uses this class
if (state.getBlock() != Blocks.TORCH) return;
ci.cancel();
}
}
-# does that depend on the flag in AbstractBlock$Settings?
I have taken the suggested approach and it does indeed have some nuances
I can't seem to make a conditional for configuring the appendProperties for the torch class.
@Mixin(Block.class)
public class BlockMixin {
// Block
//
@Inject(
method = "appendProperties",
at = @At("HEAD"),
cancellable = true
)
protected void injectAppendProperties(StateManager.Builder<Block, BlockState> builder, CallbackInfo ci) {
if (builder.NAME.equals("Torch")) {
builder.add(ModProperties.AGE, ModProperties.MAX_AGE);
}
}
}
I also am having trouble with manipulating the settings as i cannot target the constructor:
@Mixin(TorchBlock.class)
public abstract class TorchBlockMixin {
// Torch block
//
@Inject(
method = "TorchBlock",
at = @At("HEAD"),
cancellable = true
)
public injectTorchBlock(AbstractBlock.Settings settings) {
super(settings
.luminance(state -> 14)
.ticksRandomly()
,null);
setDefaultState(this.stateManager.getDefaultState()
//.with(Properties.LIT, true)
.with(ModProperties.AGE, ModProperties.MAX_AGE));
}
You can target the constructor
oh?
You just can't reference this before the call to super
You can't call super though. Probably use ModifyArg on it
What version are you on again?
mc 1.20.1 fabric 0.16.14
perhaps there is another way to add properties to vanilla class?
like what?
Synced data attachments
The easiest way I can think of is to use a flag when you're in the correct constructor
Maybe I could have the condition check the owner property in the builder class?
public static class Builder<O, S extends State<O, S>> {
private final O owner;
protected void injectAppendProperties(StateManager.Builder<Block, BlockState> builder, CallbackInfo ci) {
Potentially, but what are you going to check it against?
inject a method to get the owner since its private 😵💫
Or use an accessor
idk let me check the owner property.
The main problem is that the block isn't yet registered, and the field isn't assigned
If you wanted to be jank
You could check the field before and the field after
Here is how I made the conditional in the appendProperties() @inject:
// appendProperties
@Inject(
method = "appendProperties",
at = @At("HEAD"),
cancellable = true
)
protected void injectAppendProperties(StateManager.Builder<Block, BlockState> builder, CallbackInfo ci) {
Object owner = ((BuilderAccessor)(Object)builder).getOwner();
// TorchBlock
if (owner instanceof TorchBlock) {
builder.add(ModProperties.AGE);
}
// WallTorchBlock
if (owner instanceof WallTorchBlock) {
builder.add(ModProperties.AGE);
}
}
Owner indeed had the data I needed.
Using an accessor did get me through the private access modifier
Thanks for all your help guys!
/close