Improve Async Locator backport for 1.16
This commit is contained in:
parent
5c21a98c7f
commit
7b1d9ff8bb
|
|
@ -0,0 +1,26 @@
|
|||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.storage.loot.functions.SetNameFunction;
|
||||
import org.embeddedt.modernfix.forge.structure.logic.CommonLogic;
|
||||
import org.embeddedt.modernfix.forge.structure.logic.ExplorationMapFunctionLogic;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(SetNameFunction.class)
|
||||
public class SetNameFunctionMixin {
|
||||
@Redirect(
|
||||
method = "run",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/item/ItemStack;setHoverName(Lnet/minecraft/network/chat/Component;)Lnet/minecraft/world/item/ItemStack;"
|
||||
)
|
||||
)
|
||||
public ItemStack deferSetName(ItemStack stack, Component name) {
|
||||
if (CommonLogic.isEmptyPendingMap(stack))
|
||||
ExplorationMapFunctionLogic.cacheName(stack, name);
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
||||
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.embeddedt.modernfix.forge.structure.logic.CommonLogic;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(Slot.class)
|
||||
public abstract class SlotMixin {
|
||||
@Shadow
|
||||
public abstract ItemStack getItem();
|
||||
|
||||
@Inject(
|
||||
method = "mayPickup",
|
||||
at = @At(value = "HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
public void preventPickupOfPendingExplorationMap(Player player, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (CommonLogic.isEmptyPendingMap(getItem())) {
|
||||
cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package org.embeddedt.modernfix.forge.structure.logic;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.ByteTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
|
|
@ -15,6 +17,9 @@ import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
|||
import org.embeddedt.modernfix.forge.mixin.perf.async_locator.MapItemAccess;
|
||||
|
||||
public class CommonLogic {
|
||||
private static final String MAP_HOVER_NAME_KEY = "menu.working";
|
||||
private static final String KEY_LOCATING = "asynclocator.locating";
|
||||
|
||||
private CommonLogic() {}
|
||||
|
||||
/**
|
||||
|
|
@ -24,10 +29,23 @@ public class CommonLogic {
|
|||
*/
|
||||
public static ItemStack createEmptyMap() {
|
||||
ItemStack stack = new ItemStack(Items.FILLED_MAP);
|
||||
stack.setHoverName(new TranslatableComponent("asynclocator.map.locating"));
|
||||
stack.setHoverName(new TranslatableComponent(MAP_HOVER_NAME_KEY));
|
||||
stack.addTagElement(KEY_LOCATING, ByteTag.ONE);
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the stack is an empty FILLED_MAP item with the hover tooltip name stating that it's locating a
|
||||
* feature.
|
||||
*
|
||||
* @param stack The stack to check.
|
||||
* @return True if the stack is an empty FILLED_MAP awaiting to be populated with location data.
|
||||
*/
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
public static boolean isEmptyPendingMap(ItemStack stack) {
|
||||
return stack.getItem() == Items.FILLED_MAP && stack.hasTag() && stack.getTag().contains(KEY_LOCATING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the map stack with all the given data.
|
||||
*
|
||||
|
|
@ -44,7 +62,7 @@ public class CommonLogic {
|
|||
int scale,
|
||||
MapDecoration.Type destinationType
|
||||
) {
|
||||
updateMap(mapStack, level, pos, scale, destinationType, null);
|
||||
updateMap(mapStack, level, pos, scale, destinationType, (Component)null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -64,6 +82,27 @@ public class CommonLogic {
|
|||
int scale,
|
||||
MapDecoration.Type destinationType,
|
||||
String displayName
|
||||
) {
|
||||
updateMap(mapStack, level, pos, scale, destinationType, new TranslatableComponent(displayName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the map stack with all the given data.
|
||||
*
|
||||
* @param mapStack The map ItemStack to update
|
||||
* @param level The ServerLevel
|
||||
* @param pos The feature position
|
||||
* @param scale The map scale
|
||||
* @param destinationType The map feature type
|
||||
* @param displayName The hover tooltip display name of the ItemStack
|
||||
*/
|
||||
public static void updateMap(
|
||||
ItemStack mapStack,
|
||||
ServerLevel level,
|
||||
BlockPos pos,
|
||||
int scale,
|
||||
MapDecoration.Type destinationType,
|
||||
Component displayName
|
||||
) {
|
||||
MapItemAccess.callCreateAndStoreSavedData(
|
||||
mapStack, level, pos.getX(), pos.getZ(), scale, true, true, level.dimension()
|
||||
|
|
@ -71,7 +110,8 @@ public class CommonLogic {
|
|||
MapItem.renderBiomePreviewMap(level, mapStack);
|
||||
MapItemSavedData.addTargetDecoration(mapStack, pos, "+", destinationType);
|
||||
if (displayName != null)
|
||||
mapStack.setHoverName(new TranslatableComponent(displayName));
|
||||
mapStack.setHoverName(displayName);
|
||||
mapStack.removeTagKey(KEY_LOCATING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
package org.embeddedt.modernfix.forge.structure.logic;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
|
@ -15,13 +19,29 @@ import net.minecraftforge.items.IItemHandlerModifiable;
|
|||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.forge.structure.AsyncLocator;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
// TODO: Need to test this
|
||||
public class ExplorationMapFunctionLogic {
|
||||
// I'd like to think that structure locating shouldn't take *this* long
|
||||
private static final Cache<ItemStack, Component> MAP_NAME_CACHE =
|
||||
CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
|
||||
|
||||
private static final int MAX_STACK_SIZE = 64;
|
||||
private ExplorationMapFunctionLogic() {}
|
||||
|
||||
public static void cacheName(ItemStack stack, Component name) {
|
||||
MAP_NAME_CACHE.put(stack, name);
|
||||
}
|
||||
|
||||
public static Component getCachedName(ItemStack stack) {
|
||||
Component name = MAP_NAME_CACHE.getIfPresent(stack);
|
||||
MAP_NAME_CACHE.invalidate(stack);
|
||||
return name;
|
||||
}
|
||||
|
||||
public static void invalidateMap(ItemStack mapStack, ServerLevel level, BlockPos pos) {
|
||||
handleUpdateMapInChest(mapStack, level, pos, (handler, slot) -> {
|
||||
if (handler instanceof IItemHandlerModifiable) {
|
||||
|
|
@ -39,9 +59,10 @@ public class ExplorationMapFunctionLogic {
|
|||
BlockPos pos,
|
||||
int scale,
|
||||
MapDecoration.Type destinationType,
|
||||
BlockPos invPos
|
||||
BlockPos invPos,
|
||||
Component displayName
|
||||
) {
|
||||
CommonLogic.updateMap(mapStack, level, pos, scale, destinationType);
|
||||
CommonLogic.updateMap(mapStack, level, pos, scale, destinationType, displayName);
|
||||
// Shouldn't need to set the stack in its slot again, as we're modifying the same instance
|
||||
handleUpdateMapInChest(mapStack, level, invPos, (handler, slot) -> {});
|
||||
}
|
||||
|
|
@ -84,12 +105,17 @@ public class ExplorationMapFunctionLogic {
|
|||
BlockPos pos,
|
||||
int scale,
|
||||
MapDecoration.Type destinationType,
|
||||
StructureFeature<?> destination,
|
||||
BlockPos invPos
|
||||
) {
|
||||
if (pos == null) {
|
||||
invalidateMap(mapStack, level, invPos);
|
||||
} else {
|
||||
updateMap(mapStack, level, pos, scale, destinationType, invPos);
|
||||
Component displayName = getCachedName(mapStack);
|
||||
if(displayName == null) {
|
||||
displayName = new TranslatableComponent("filled_map." + destination.getFeatureName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
updateMap(mapStack, level, pos, scale, destinationType, invPos, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +130,7 @@ public class ExplorationMapFunctionLogic {
|
|||
) {
|
||||
ItemStack mapStack = CommonLogic.createEmptyMap();
|
||||
AsyncLocator.locateLevel(level, ImmutableSet.of(destination), blockPos, searchRadius, skipKnownStructures)
|
||||
.thenOnServerThread(pos -> handleLocationFound(mapStack, level, pos, scale, destinationType, blockPos));
|
||||
.thenOnServerThread(pos -> handleLocationFound(mapStack, level, pos, scale, destinationType, destination, blockPos));
|
||||
return mapStack;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user