Skip to content

Commit 7a18e5b

Browse files
i love javadocs
1 parent 9d29eab commit 7a18e5b

File tree

1 file changed

+110
-22
lines changed

1 file changed

+110
-22
lines changed

src/main/java/com/gregtechceu/gtceu/core/mixins/ItemStackMixin.java

Lines changed: 110 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,9 @@
3737
@Mixin(ItemStack.class)
3838
public abstract class ItemStackMixin implements ISpoilableItemStackExtension {
3939

40-
@Unique
41-
private boolean gtceu$isUpdating = false;
42-
43-
@Unique
44-
private @Nullable SpoilContext gtceu$lastSpoilContext = new SpoilContext();
45-
46-
@Unique
47-
private boolean gtceu$fakeTooltip;
48-
49-
@Inject(at = @At("RETURN"),
50-
method = "<init>(Lnet/minecraft/world/level/ItemLike;ILnet/minecraft/nbt/CompoundTag;)V")
51-
private void gtceu$injectFakeTooltipInit(ItemLike item, int count, CompoundTag tag, CallbackInfo ci) {
52-
gtceu$fakeTooltip = GTValues.FOOLS.getAsBoolean() && GTValues.RNG.nextFloat() < .1f;
53-
}
40+
// ***************************//
41+
// Shadow fields and methods //
42+
// ***************************//
5443

5544
@Shadow
5645
public abstract CompoundTag getOrCreateTagElement(String key);
@@ -91,17 +80,77 @@ public abstract class ItemStackMixin implements ISpoilableItemStackExtension {
9180
@Shadow(remap = false)
9281
protected abstract void forgeInit();
9382

83+
// ***************************//
84+
// Unique fields //
85+
// ***************************//
86+
87+
/**
88+
* Whether {@link ItemStackMixin#gtceu$updateFreshness(SpoilContext, boolean)}
89+
* was called and did not return yet.
90+
* <br>
91+
* Used to prevent stack overflows.
92+
*/
93+
@Unique
94+
private boolean gtceu$isUpdating = false;
95+
96+
/**
97+
* The value of the last non-empty (determined by {@link SpoilContext#isEmpty()})
98+
* context passed into {@link ItemStackMixin#gtceu$updateFreshness(SpoilContext, boolean)}.
99+
* <br>
100+
* Used to as an argument for {@link ISpoilableItem#spoilResult(SpoilContext, boolean)}
101+
* when this stack spoils.
102+
*/
103+
@Unique
104+
private @Nullable SpoilContext gtceu$lastSpoilContext = new SpoilContext();
105+
106+
/**
107+
* Whether to display a fake "spoils into" tooltip for an item if it's not spoilable.
108+
* <br>
109+
* Has a 10% chance of being {@code true} for any stack on april fools.
110+
* The chance is rolled once in the constructor (injected by {@link ItemStackMixin#gtceu$injectFakeTooltipInit}).
111+
*/
112+
@Unique
113+
private boolean gtceu$fakeTooltip;
114+
94115
@Unique
95116
private ItemStack gtceu$self() {
96117
return (ItemStack) (Object) this;
97118
}
98119

120+
// ***************************//
121+
// Interface implementations //
122+
// ***************************//
123+
124+
/**
125+
* Primarily used as debug info when advanced tooltips are turned on.
126+
*
127+
* @return the last known context of this stack
128+
*/
99129
@Unique
100130
@Override
101131
public SpoilContext gtceu$getSpoilContext() {
102132
return gtceu$lastSpoilContext;
103133
}
104134

135+
/**
136+
* Checks if this item should've already spoiled, and calls
137+
* {@link ISpoilableItem#spoilResult(SpoilContext, boolean)}
138+
* with {@link ItemStackMixin#gtceu$lastSpoilContext}
139+
* and replaces this item with its return value if so.<br>
140+
* Also sets {@link ItemStackMixin#gtceu$lastSpoilContext} to the provided
141+
* context if it is non-empty (determined by {@link SpoilContext#isEmpty()}).<br>
142+
* <br>
143+
* If {@code createTag = true} and the spoilage tag did not exist, creates
144+
* the tag and sets the creation tick to this tick.<br>
145+
* If {@code createTag = false} and the spoilage tag isn't present, does nothing.
146+
*
147+
* @param createTag Whether to create a spoilage tag if it wasn't present.
148+
* Usually {@code true} for stacks that are present in-world,
149+
* and {@code false} for stacks in XEI, icons, quests, etc.
150+
*
151+
* @implNote This method is injected into all of {@link ItemStack}'s getters to
152+
* be called with an empty {@link SpoilContext} and {@code createTag = false}.
153+
*/
105154
@Unique
106155
@Override
107156
public void gtceu$updateFreshness(@NotNull SpoilContext spoilContext, boolean createTag) {
@@ -143,14 +192,19 @@ public abstract class ItemStackMixin implements ISpoilableItemStackExtension {
143192
try {
144193
gtceu$isUpdating = false;
145194
gtceu$updateFreshness(spoilContext, false);
146-
} catch (StackOverflowError ignored) {} // if some crazy pack dev makes an item spoil into a
147-
// spoilable that spoils into a spoilable 1000 times
195+
} catch (StackOverflowError ignored) {
196+
// if items spoil in a giant chain or a loop
197+
}
148198
}
149199
}
150200
}
151201
gtceu$isUpdating = false;
152202
}
153203

204+
// ***************************//
205+
// Injectors //
206+
// ***************************//
207+
154208
@Inject(at = @At("HEAD"),
155209
method = { "getItem", "getCount", "getTag", "getOrCreateTag", "getTagElement", "getOrCreateTagElement",
156210
"getItemHolder" })
@@ -172,6 +226,18 @@ public abstract class ItemStackMixin implements ISpoilableItemStackExtension {
172226
gtceu$updateFreshness(new SpoilContext(player, -1), true);
173227
}
174228

229+
/**
230+
* Since {@link ItemStack#isSameItemSameTags(ItemStack, ItemStack)} is commonly called
231+
* right before merging two stacks, this method averages their spoil progress (or, more
232+
* accurately, their {@link ISpoilableItem#getCreationTick()}). If {@link SpoilUtils#FROZEN_EQUALITY}
233+
* is {@code true}, this method will ignore the frozen/not frozen status of stacks when determining its
234+
* return value. Other than that, the return value is equal to the normal {@link ItemStack#isSameItemSameTags}.
235+
* <br>
236+
* This method replaces {@link ItemStack#isSameItemSameTags(ItemStack, ItemStack)}.
237+
*
238+
* @implNote This implementation may lead to spoil progress averaging in situations other
239+
* than stack merging, though I don't think this will lead to any big user-facing bugs.
240+
*/
175241
@Inject(at = @At("HEAD"), method = "isSameItemSameTags", cancellable = true)
176242
private static void gtceu$mergeSpoilables(ItemStack stack, ItemStack other, CallbackInfoReturnable<Boolean> cir) {
177243
ISpoilableItem spoilable1 = GTCapabilityHelper.getSpoilable(stack);
@@ -208,13 +274,23 @@ public abstract class ItemStackMixin implements ISpoilableItemStackExtension {
208274
cir.setReturnValue(isSameItem && Objects.equals(stack.getTag(), other.getTag()));
209275
}
210276

277+
@Inject(at = @At("RETURN"),
278+
method = "<init>(Lnet/minecraft/world/level/ItemLike;ILnet/minecraft/nbt/CompoundTag;)V")
279+
private void gtceu$injectFakeTooltipInit(ItemLike item, int count, CompoundTag tag, CallbackInfo ci) {
280+
gtceu$fakeTooltip = GTValues.FOOLS.getAsBoolean() && GTValues.RNG.nextFloat() < .1f;
281+
}
282+
283+
/**
284+
* Allows {@link ISpoilableItem} subclasses that implement {@link IAddInformation} to
285+
* actually display the added tooltip.
286+
*/
211287
@Inject(at = @At(value = "INVOKE",
212288
target = "Lnet/minecraft/world/item/Item;appendHoverText(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/level/Level;Ljava/util/List;Lnet/minecraft/world/item/TooltipFlag;)V"),
213289
method = "getTooltipLines",
214290
locals = LocalCapture.CAPTURE_FAILSOFT)
215-
private void gtceu$aprilFoolsTooltip(Player player, TooltipFlag isAdvanced,
216-
CallbackInfoReturnable<List<Component>> cir,
217-
List<Component> list) {
291+
private void gtceu$spoilageTooltip(Player player, TooltipFlag isAdvanced,
292+
CallbackInfoReturnable<List<Component>> cir,
293+
List<Component> list) {
218294
ISpoilableItem spoilable = GTCapabilityHelper.getSpoilable(gtceu$self());
219295
if (!(getItem() instanceof ISpoilableItem) && spoilable instanceof IAddInformation addInformation) {
220296
addInformation.appendHoverText(gtceu$self(), player == null ? null : player.level(), list,
@@ -229,8 +305,12 @@ public abstract class ItemStackMixin implements ISpoilableItemStackExtension {
229305
}
230306
}
231307

308+
/**
309+
* Allows {@link ISpoilableItem} subclasses that implement {@link IDurabilityBar} to
310+
* actually display the bar.
311+
*/
232312
@Inject(at = @At("HEAD"), method = "isBarVisible", cancellable = true)
233-
private void gtceu$aprilFoolsBarVisible(CallbackInfoReturnable<Boolean> cir) {
313+
private void gtceu$spoilageBarVisible(CallbackInfoReturnable<Boolean> cir) {
234314
ISpoilableItem spoilable = GTCapabilityHelper.getSpoilable(gtceu$self());
235315
if (!(getItem() instanceof ISpoilableItem) && spoilable instanceof IDurabilityBar durabilityBar) {
236316
cir.setReturnValue(durabilityBar.isBarVisible(gtceu$self()));
@@ -239,8 +319,12 @@ public abstract class ItemStackMixin implements ISpoilableItemStackExtension {
239319
}
240320
}
241321

322+
/**
323+
* Allows {@link ISpoilableItem} subclasses that implement {@link IDurabilityBar} to
324+
* actually display the bar.
325+
*/
242326
@Inject(at = @At("HEAD"), method = "getBarColor", cancellable = true)
243-
private void gtceu$aprilFoolsBarColor(CallbackInfoReturnable<Integer> cir) {
327+
private void gtceu$spoilageBarColor(CallbackInfoReturnable<Integer> cir) {
244328
ISpoilableItem spoilable = GTCapabilityHelper.getSpoilable(gtceu$self());
245329
if (!(getItem() instanceof ISpoilableItem) && spoilable instanceof IDurabilityBar durabilityBar) {
246330
cir.setReturnValue(durabilityBar.getBarColor(gtceu$self()));
@@ -249,8 +333,12 @@ public abstract class ItemStackMixin implements ISpoilableItemStackExtension {
249333
}
250334
}
251335

336+
/**
337+
* Allows {@link ISpoilableItem} subclasses that implement {@link IDurabilityBar} to
338+
* actually display the bar.
339+
*/
252340
@Inject(at = @At("HEAD"), method = "getBarWidth", cancellable = true)
253-
private void gtceu$aprilFoolsBarWidth(CallbackInfoReturnable<Integer> cir) {
341+
private void gtceu$spoilageBarWidth(CallbackInfoReturnable<Integer> cir) {
254342
ISpoilableItem spoilable = GTCapabilityHelper.getSpoilable(gtceu$self());
255343
if (!(getItem() instanceof ISpoilableItem) && spoilable instanceof IDurabilityBar durabilityBar) {
256344
cir.setReturnValue(durabilityBar.getBarWidth(gtceu$self()));

0 commit comments

Comments
 (0)