Skip to content

Commit 7b1d9ff

Browse files
committed
Improve Async Locator backport for 1.16
1 parent 5c21a98 commit 7b1d9ff

File tree

4 files changed

+127
-7
lines changed

4 files changed

+127
-7
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
2+
3+
import net.minecraft.network.chat.Component;
4+
import net.minecraft.world.item.ItemStack;
5+
import net.minecraft.world.level.storage.loot.functions.SetNameFunction;
6+
import org.embeddedt.modernfix.forge.structure.logic.CommonLogic;
7+
import org.embeddedt.modernfix.forge.structure.logic.ExplorationMapFunctionLogic;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.injection.At;
10+
import org.spongepowered.asm.mixin.injection.Redirect;
11+
12+
@Mixin(SetNameFunction.class)
13+
public class SetNameFunctionMixin {
14+
@Redirect(
15+
method = "run",
16+
at = @At(
17+
value = "INVOKE",
18+
target = "Lnet/minecraft/world/item/ItemStack;setHoverName(Lnet/minecraft/network/chat/Component;)Lnet/minecraft/world/item/ItemStack;"
19+
)
20+
)
21+
public ItemStack deferSetName(ItemStack stack, Component name) {
22+
if (CommonLogic.isEmptyPendingMap(stack))
23+
ExplorationMapFunctionLogic.cacheName(stack, name);
24+
return stack;
25+
}
26+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
2+
3+
import net.minecraft.world.entity.player.Player;
4+
import net.minecraft.world.inventory.Slot;
5+
import net.minecraft.world.item.ItemStack;
6+
import org.embeddedt.modernfix.forge.structure.logic.CommonLogic;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.Shadow;
9+
import org.spongepowered.asm.mixin.injection.At;
10+
import org.spongepowered.asm.mixin.injection.Inject;
11+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
12+
13+
@Mixin(Slot.class)
14+
public abstract class SlotMixin {
15+
@Shadow
16+
public abstract ItemStack getItem();
17+
18+
@Inject(
19+
method = "mayPickup",
20+
at = @At(value = "HEAD"),
21+
cancellable = true
22+
)
23+
public void preventPickupOfPendingExplorationMap(Player player, CallbackInfoReturnable<Boolean> cir) {
24+
if (CommonLogic.isEmptyPendingMap(getItem())) {
25+
cir.setReturnValue(false);
26+
}
27+
}
28+
}

forge/src/main/java/org/embeddedt/modernfix/forge/structure/logic/CommonLogic.java

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.embeddedt.modernfix.forge.structure.logic;
22

33
import net.minecraft.core.BlockPos;
4+
import net.minecraft.nbt.ByteTag;
5+
import net.minecraft.network.chat.Component;
46
import net.minecraft.network.chat.TranslatableComponent;
57
import net.minecraft.server.level.ServerLevel;
68
import net.minecraft.world.inventory.AbstractContainerMenu;
@@ -15,6 +17,9 @@
1517
import org.embeddedt.modernfix.forge.mixin.perf.async_locator.MapItemAccess;
1618

1719
public class CommonLogic {
20+
private static final String MAP_HOVER_NAME_KEY = "menu.working";
21+
private static final String KEY_LOCATING = "asynclocator.locating";
22+
1823
private CommonLogic() {}
1924

2025
/**
@@ -24,10 +29,23 @@ private CommonLogic() {}
2429
*/
2530
public static ItemStack createEmptyMap() {
2631
ItemStack stack = new ItemStack(Items.FILLED_MAP);
27-
stack.setHoverName(new TranslatableComponent("asynclocator.map.locating"));
32+
stack.setHoverName(new TranslatableComponent(MAP_HOVER_NAME_KEY));
33+
stack.addTagElement(KEY_LOCATING, ByteTag.ONE);
2834
return stack;
2935
}
3036

37+
/**
38+
* Returns true if the stack is an empty FILLED_MAP item with the hover tooltip name stating that it's locating a
39+
* feature.
40+
*
41+
* @param stack The stack to check.
42+
* @return True if the stack is an empty FILLED_MAP awaiting to be populated with location data.
43+
*/
44+
@SuppressWarnings("DataFlowIssue")
45+
public static boolean isEmptyPendingMap(ItemStack stack) {
46+
return stack.getItem() == Items.FILLED_MAP && stack.hasTag() && stack.getTag().contains(KEY_LOCATING);
47+
}
48+
3149
/**
3250
* Updates the map stack with all the given data.
3351
*
@@ -44,7 +62,7 @@ public static void updateMap(
4462
int scale,
4563
MapDecoration.Type destinationType
4664
) {
47-
updateMap(mapStack, level, pos, scale, destinationType, null);
65+
updateMap(mapStack, level, pos, scale, destinationType, (Component)null);
4866
}
4967

5068
/**
@@ -64,14 +82,36 @@ public static void updateMap(
6482
int scale,
6583
MapDecoration.Type destinationType,
6684
String displayName
85+
) {
86+
updateMap(mapStack, level, pos, scale, destinationType, new TranslatableComponent(displayName));
87+
}
88+
89+
/**
90+
* Updates the map stack with all the given data.
91+
*
92+
* @param mapStack The map ItemStack to update
93+
* @param level The ServerLevel
94+
* @param pos The feature position
95+
* @param scale The map scale
96+
* @param destinationType The map feature type
97+
* @param displayName The hover tooltip display name of the ItemStack
98+
*/
99+
public static void updateMap(
100+
ItemStack mapStack,
101+
ServerLevel level,
102+
BlockPos pos,
103+
int scale,
104+
MapDecoration.Type destinationType,
105+
Component displayName
67106
) {
68107
MapItemAccess.callCreateAndStoreSavedData(
69108
mapStack, level, pos.getX(), pos.getZ(), scale, true, true, level.dimension()
70109
);
71110
MapItem.renderBiomePreviewMap(level, mapStack);
72111
MapItemSavedData.addTargetDecoration(mapStack, pos, "+", destinationType);
73112
if (displayName != null)
74-
mapStack.setHoverName(new TranslatableComponent(displayName));
113+
mapStack.setHoverName(displayName);
114+
mapStack.removeTagKey(KEY_LOCATING);
75115
}
76116

77117
/**

forge/src/main/java/org/embeddedt/modernfix/forge/structure/logic/ExplorationMapFunctionLogic.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package org.embeddedt.modernfix.forge.structure.logic;
22

3+
import com.google.common.cache.Cache;
4+
import com.google.common.cache.CacheBuilder;
35
import com.google.common.collect.ImmutableSet;
46
import net.minecraft.core.BlockPos;
7+
import net.minecraft.network.chat.Component;
8+
import net.minecraft.network.chat.TranslatableComponent;
59
import net.minecraft.server.level.ServerLevel;
610
import net.minecraft.world.item.ItemStack;
711
import net.minecraft.world.item.Items;
@@ -15,13 +19,29 @@
1519
import org.embeddedt.modernfix.ModernFix;
1620
import org.embeddedt.modernfix.forge.structure.AsyncLocator;
1721

22+
import java.util.Locale;
23+
import java.util.concurrent.TimeUnit;
1824
import java.util.function.BiConsumer;
1925

2026
// TODO: Need to test this
2127
public class ExplorationMapFunctionLogic {
28+
// I'd like to think that structure locating shouldn't take *this* long
29+
private static final Cache<ItemStack, Component> MAP_NAME_CACHE =
30+
CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
31+
2232
private static final int MAX_STACK_SIZE = 64;
2333
private ExplorationMapFunctionLogic() {}
2434

35+
public static void cacheName(ItemStack stack, Component name) {
36+
MAP_NAME_CACHE.put(stack, name);
37+
}
38+
39+
public static Component getCachedName(ItemStack stack) {
40+
Component name = MAP_NAME_CACHE.getIfPresent(stack);
41+
MAP_NAME_CACHE.invalidate(stack);
42+
return name;
43+
}
44+
2545
public static void invalidateMap(ItemStack mapStack, ServerLevel level, BlockPos pos) {
2646
handleUpdateMapInChest(mapStack, level, pos, (handler, slot) -> {
2747
if (handler instanceof IItemHandlerModifiable) {
@@ -39,9 +59,10 @@ public static void updateMap(
3959
BlockPos pos,
4060
int scale,
4161
MapDecoration.Type destinationType,
42-
BlockPos invPos
62+
BlockPos invPos,
63+
Component displayName
4364
) {
44-
CommonLogic.updateMap(mapStack, level, pos, scale, destinationType);
65+
CommonLogic.updateMap(mapStack, level, pos, scale, destinationType, displayName);
4566
// Shouldn't need to set the stack in its slot again, as we're modifying the same instance
4667
handleUpdateMapInChest(mapStack, level, invPos, (handler, slot) -> {});
4768
}
@@ -84,12 +105,17 @@ public static void handleLocationFound(
84105
BlockPos pos,
85106
int scale,
86107
MapDecoration.Type destinationType,
108+
StructureFeature<?> destination,
87109
BlockPos invPos
88110
) {
89111
if (pos == null) {
90112
invalidateMap(mapStack, level, invPos);
91113
} else {
92-
updateMap(mapStack, level, pos, scale, destinationType, invPos);
114+
Component displayName = getCachedName(mapStack);
115+
if(displayName == null) {
116+
displayName = new TranslatableComponent("filled_map." + destination.getFeatureName().toLowerCase(Locale.ROOT));
117+
}
118+
updateMap(mapStack, level, pos, scale, destinationType, invPos, displayName);
93119
}
94120
}
95121

@@ -104,7 +130,7 @@ public static ItemStack updateMapAsync(
104130
) {
105131
ItemStack mapStack = CommonLogic.createEmptyMap();
106132
AsyncLocator.locateLevel(level, ImmutableSet.of(destination), blockPos, searchRadius, skipKnownStructures)
107-
.thenOnServerThread(pos -> handleLocationFound(mapStack, level, pos, scale, destinationType, blockPos));
133+
.thenOnServerThread(pos -> handleLocationFound(mapStack, level, pos, scale, destinationType, destination, blockPos));
108134
return mapStack;
109135
}
110136
}

0 commit comments

Comments
 (0)