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;
|
package org.embeddedt.modernfix.forge.structure.logic;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
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.network.chat.TranslatableComponent;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
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;
|
import org.embeddedt.modernfix.forge.mixin.perf.async_locator.MapItemAccess;
|
||||||
|
|
||||||
public class CommonLogic {
|
public class CommonLogic {
|
||||||
|
private static final String MAP_HOVER_NAME_KEY = "menu.working";
|
||||||
|
private static final String KEY_LOCATING = "asynclocator.locating";
|
||||||
|
|
||||||
private CommonLogic() {}
|
private CommonLogic() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -24,10 +29,23 @@ public class CommonLogic {
|
||||||
*/
|
*/
|
||||||
public static ItemStack createEmptyMap() {
|
public static ItemStack createEmptyMap() {
|
||||||
ItemStack stack = new ItemStack(Items.FILLED_MAP);
|
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;
|
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.
|
* Updates the map stack with all the given data.
|
||||||
*
|
*
|
||||||
|
|
@ -44,7 +62,7 @@ public class CommonLogic {
|
||||||
int scale,
|
int scale,
|
||||||
MapDecoration.Type destinationType
|
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,
|
int scale,
|
||||||
MapDecoration.Type destinationType,
|
MapDecoration.Type destinationType,
|
||||||
String displayName
|
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(
|
MapItemAccess.callCreateAndStoreSavedData(
|
||||||
mapStack, level, pos.getX(), pos.getZ(), scale, true, true, level.dimension()
|
mapStack, level, pos.getX(), pos.getZ(), scale, true, true, level.dimension()
|
||||||
|
|
@ -71,7 +110,8 @@ public class CommonLogic {
|
||||||
MapItem.renderBiomePreviewMap(level, mapStack);
|
MapItem.renderBiomePreviewMap(level, mapStack);
|
||||||
MapItemSavedData.addTargetDecoration(mapStack, pos, "+", destinationType);
|
MapItemSavedData.addTargetDecoration(mapStack, pos, "+", destinationType);
|
||||||
if (displayName != null)
|
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;
|
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 com.google.common.collect.ImmutableSet;
|
||||||
import net.minecraft.core.BlockPos;
|
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.server.level.ServerLevel;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
|
|
@ -15,13 +19,29 @@ import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
import org.embeddedt.modernfix.forge.structure.AsyncLocator;
|
import org.embeddedt.modernfix.forge.structure.AsyncLocator;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
// TODO: Need to test this
|
// TODO: Need to test this
|
||||||
public class ExplorationMapFunctionLogic {
|
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 static final int MAX_STACK_SIZE = 64;
|
||||||
private ExplorationMapFunctionLogic() {}
|
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) {
|
public static void invalidateMap(ItemStack mapStack, ServerLevel level, BlockPos pos) {
|
||||||
handleUpdateMapInChest(mapStack, level, pos, (handler, slot) -> {
|
handleUpdateMapInChest(mapStack, level, pos, (handler, slot) -> {
|
||||||
if (handler instanceof IItemHandlerModifiable) {
|
if (handler instanceof IItemHandlerModifiable) {
|
||||||
|
|
@ -39,9 +59,10 @@ public class ExplorationMapFunctionLogic {
|
||||||
BlockPos pos,
|
BlockPos pos,
|
||||||
int scale,
|
int scale,
|
||||||
MapDecoration.Type destinationType,
|
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
|
// Shouldn't need to set the stack in its slot again, as we're modifying the same instance
|
||||||
handleUpdateMapInChest(mapStack, level, invPos, (handler, slot) -> {});
|
handleUpdateMapInChest(mapStack, level, invPos, (handler, slot) -> {});
|
||||||
}
|
}
|
||||||
|
|
@ -84,12 +105,17 @@ public class ExplorationMapFunctionLogic {
|
||||||
BlockPos pos,
|
BlockPos pos,
|
||||||
int scale,
|
int scale,
|
||||||
MapDecoration.Type destinationType,
|
MapDecoration.Type destinationType,
|
||||||
|
StructureFeature<?> destination,
|
||||||
BlockPos invPos
|
BlockPos invPos
|
||||||
) {
|
) {
|
||||||
if (pos == null) {
|
if (pos == null) {
|
||||||
invalidateMap(mapStack, level, invPos);
|
invalidateMap(mapStack, level, invPos);
|
||||||
} else {
|
} 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();
|
ItemStack mapStack = CommonLogic.createEmptyMap();
|
||||||
AsyncLocator.locateLevel(level, ImmutableSet.of(destination), blockPos, searchRadius, skipKnownStructures)
|
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;
|
return mapStack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user