24w40a
This commit is contained in:
1 parent
6144967299
commit
3a66dd0a9b
17 files changed
+198
-161
No files matched your search
@@ -70,8 +70,8 @@ Recipe type can take one of the following options:
|
||||
* `'smithing'` - smithing table (1.16+)
|
||||
|
||||
The return value is a list of available recipes (even if there is only one recipe available). Each recipe contains of
|
||||
an item triple of the crafting result, list of ingredients, each containing a list of possible variants of the
|
||||
ingredients in this slot, as item triples, or `null` if its a shaped recipe and a given slot in the patterns is left
|
||||
an item triple of the crafting results as a list of item stacks, list of ingredients, each containing a list of possible variants of the
|
||||
ingredients in this slot, as item ids, or `null` if it is a shaped recipe and a given slot in the patterns is left
|
||||
empty, and recipe specification as another list. Possible recipe specs is:
|
||||
* `['shaped', width, height]` - shaped crafting. `width` and `height` can be 1, 2 or 3.
|
||||
* `['shapeless']` - shapeless crafting
|
||||
@@ -80,10 +80,6 @@ Recipe type can take one of the following options:
|
||||
* `['special']` - special crafting recipe, typically not present in the crafting menu
|
||||
* `['custom']` - other recipe types
|
||||
|
||||
Note that ingredients are specified as tripes, with count and nbt information. Currently all recipes require always one
|
||||
of the ingredients, and for some recipes, even if the nbt data for the ingredient is specified (e.g. `dispenser`), it
|
||||
can accept items of any tags.
|
||||
|
||||
Also note that some recipes leave some products in the crafting window, and these can be determined using
|
||||
`crafting_remaining_item()` function
|
||||
|
||||
@@ -97,7 +93,7 @@ Also note that some recipes leave some products in the crafting window, and thes
|
||||
### `crafting_remaining_item(item)`
|
||||
|
||||
returns `null` if the item has no remaining item in the crafting window when used as a crafting ingredient, or an
|
||||
item name that serves as a replacement after crafting is done. Currently it can only be buckets and glass bottles.
|
||||
item tuple that serves as a replacement after crafting is done. Currently, it can only be buckets and glass bottles.
|
||||
|
||||
### `inventory_size(inventory)`
|
||||
|
||||
|
||||
+2
-2
@@ -3,10 +3,10 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check https://fabricmc.net/develop/
|
||||
minecraft_version=24w39a
|
||||
minecraft_version=24w40a
|
||||
loader_version=0.16.5
|
||||
jsr305_version=3.0.2
|
||||
fabric_version=0.102.0+1.21
|
||||
fabric_version=0.105.1+1.21.2
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.4.154
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
|
||||
public interface RecipeManagerInterface
|
||||
{
|
||||
/**
|
||||
* Gets all the recipes for a given item. Also used for {@link carpet.helpers.HopperCounter#guessColor} to guess the
|
||||
* colour of an item to display it prettily
|
||||
*/
|
||||
List<Recipe<?>> getAllMatching(final RecipeType<?> type, final ResourceLocation itemId, final RegistryAccess registryAccess);
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
package carpet.helpers;
|
||||
|
||||
import carpet.CarpetServer;
|
||||
import carpet.fakes.RecipeManagerInterface;
|
||||
import carpet.script.utils.RecipeHelper;
|
||||
import carpet.utils.Messenger;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
@@ -21,9 +22,9 @@ import net.minecraft.world.item.DyeItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.crafting.PlacementInfo;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AbstractBannerBlock;
|
||||
import net.minecraft.world.level.block.BeaconBeamBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -36,7 +37,6 @@ import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
@@ -101,7 +101,9 @@ public class HopperCounter
|
||||
this.color = color;
|
||||
String hexColor = Integer.toHexString(color.getTextColor());
|
||||
if (hexColor.length() < 6)
|
||||
{
|
||||
hexColor = "0".repeat(6 - hexColor.length()) + hexColor;
|
||||
}
|
||||
this.coloredName = '#' + hexColor + ' ' + color.getName();
|
||||
}
|
||||
|
||||
@@ -135,6 +137,7 @@ public class HopperCounter
|
||||
|
||||
/**
|
||||
* Resets all counters, clearing their items.
|
||||
*
|
||||
* @param fresh Whether or not to start the clocks going immediately or later.
|
||||
*/
|
||||
public static void resetAll(MinecraftServer server, boolean fresh)
|
||||
@@ -142,7 +145,10 @@ public class HopperCounter
|
||||
for (HopperCounter counter : COUNTERS.values())
|
||||
{
|
||||
counter.reset(server);
|
||||
if (fresh) counter.startTick = -1;
|
||||
if (fresh)
|
||||
{
|
||||
counter.startTick = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +164,10 @@ public class HopperCounter
|
||||
List<Component> temp = counter.format(server, realtime, false);
|
||||
if (temp.size() > 1)
|
||||
{
|
||||
if (!text.isEmpty()) text.add(Messenger.s(""));
|
||||
if (!text.isEmpty())
|
||||
{
|
||||
text.add(Messenger.s(""));
|
||||
}
|
||||
text.addAll(temp);
|
||||
}
|
||||
}
|
||||
@@ -214,7 +223,7 @@ public class HopperCounter
|
||||
Item item = e.getKey();
|
||||
MutableComponent itemName = Component.translatable(item.getDescriptionId());
|
||||
Style itemStyle = itemName.getStyle();
|
||||
TextColor color = guessColor(item, server.registryAccess());
|
||||
TextColor color = guessColor(item, server.overworld());
|
||||
itemName.setStyle((color != null) ? itemStyle.withColor(color) : itemStyle.withItalic(true));
|
||||
long count = e.getLongValue();
|
||||
return Messenger.c("g - ", itemName,
|
||||
@@ -231,13 +240,25 @@ public class HopperCounter
|
||||
*/
|
||||
public static int appropriateColor(int color)
|
||||
{
|
||||
if (color == 0) return MapColor.SNOW.col;
|
||||
if (color == 0)
|
||||
{
|
||||
return MapColor.SNOW.col;
|
||||
}
|
||||
int r = (color >> 16 & 255);
|
||||
int g = (color >> 8 & 255);
|
||||
int b = (color & 255);
|
||||
if (r < 70) r = 70;
|
||||
if (g < 70) g = 70;
|
||||
if (b < 70) b = 70;
|
||||
if (r < 70)
|
||||
{
|
||||
r = 70;
|
||||
}
|
||||
if (g < 70)
|
||||
{
|
||||
g = 70;
|
||||
}
|
||||
if (b < 70)
|
||||
{
|
||||
b = 70;
|
||||
}
|
||||
return (r << 16) + (g << 8) + b;
|
||||
}
|
||||
|
||||
@@ -337,8 +358,14 @@ public class HopperCounter
|
||||
*/
|
||||
public static TextColor fromItem(Item item, RegistryAccess registryAccess)
|
||||
{
|
||||
if (DEFAULTS.containsKey(item)) return TextColor.fromRgb(appropriateColor(DEFAULTS.get(item).defaultMapColor().col));
|
||||
if (item instanceof DyeItem dye) return TextColor.fromRgb(appropriateColor(dye.getDyeColor().getMapColor().col));
|
||||
if (DEFAULTS.containsKey(item))
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(DEFAULTS.get(item).defaultMapColor().col));
|
||||
}
|
||||
if (item instanceof DyeItem dye)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(dye.getDyeColor().getMapColor().col));
|
||||
}
|
||||
Block block = null;
|
||||
final Registry<Item> itemRegistry = registryAccess.lookupOrThrow(Registries.ITEM);
|
||||
final Registry<Block> blockRegistry = registryAccess.lookupOrThrow(Registries.BLOCK);
|
||||
@@ -353,8 +380,14 @@ public class HopperCounter
|
||||
}
|
||||
if (block != null)
|
||||
{
|
||||
if (block instanceof AbstractBannerBlock) return TextColor.fromRgb(appropriateColor(((AbstractBannerBlock) block).getColor().getMapColor().col));
|
||||
if (block instanceof BeaconBeamBlock) return TextColor.fromRgb(appropriateColor( ((BeaconBeamBlock) block).getColor().getMapColor().col));
|
||||
if (block instanceof AbstractBannerBlock)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(((AbstractBannerBlock) block).getColor().getMapColor().col));
|
||||
}
|
||||
if (block instanceof BeaconBeamBlock)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(((BeaconBeamBlock) block).getColor().getMapColor().col));
|
||||
}
|
||||
return TextColor.fromRgb(appropriateColor(block.defaultMapColor().col));
|
||||
}
|
||||
return null;
|
||||
@@ -364,35 +397,48 @@ public class HopperCounter
|
||||
* Guesses the item's colour from the item itself. It first calls {@link HopperCounter#fromItem} to see if it has a
|
||||
* valid colour there, if not just makes a guess, and if that fails just returns null
|
||||
*/
|
||||
public static TextColor guessColor(Item item, RegistryAccess registryAccess)
|
||||
public static TextColor guessColor(Item item, Level level)
|
||||
{
|
||||
RegistryAccess registryAccess = level.registryAccess();
|
||||
TextColor direct = fromItem(item, registryAccess);
|
||||
if (direct != null) return direct;
|
||||
if (CarpetServer.minecraft_server == null) return WHITE;
|
||||
if (direct != null)
|
||||
{
|
||||
return direct;
|
||||
}
|
||||
if (CarpetServer.minecraft_server == null)
|
||||
{
|
||||
return WHITE;
|
||||
}
|
||||
|
||||
ResourceLocation id = registryAccess.lookupOrThrow(Registries.ITEM).getKey(item);
|
||||
for (RecipeType<?> type: registryAccess.lookupOrThrow(Registries.RECIPE_TYPE))
|
||||
if (id == null)
|
||||
{
|
||||
for (Recipe<?> r: ((RecipeManagerInterface) CarpetServer.minecraft_server.getRecipeManager()).getAllMatching(type, id, registryAccess))
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Recipe<?> r : RecipeHelper.getRecipesForOutput(CarpetServer.minecraft_server.getRecipeManager(), id, level))
|
||||
{
|
||||
for (Optional<PlacementInfo.SlotInfo> ingredient: r.placementInfo().slotInfo())
|
||||
for (Ingredient ingredient : r.placementInfo().ingredients())
|
||||
{
|
||||
for(ItemStack stack : ingredient.get().possibleItems())
|
||||
for (Holder<Item> stack : ingredient.items())
|
||||
{
|
||||
TextColor cand = fromItem(stack.getItem(), registryAccess);
|
||||
TextColor cand = fromItem(stack.value(), registryAccess);
|
||||
if (cand != null)
|
||||
{
|
||||
return cand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hopper counter for the given color
|
||||
*/
|
||||
public static HopperCounter getCounter(DyeColor color) {
|
||||
public static HopperCounter getCounter(DyeColor color)
|
||||
{
|
||||
return COUNTERS.get(color);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.AbstractContainerMenuInterface;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractCraftingMenu;
|
||||
@@ -15,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
public class AbstractCraftingMenu_scarpetMixin
|
||||
{
|
||||
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
|
||||
private void selectRecipeCallback(boolean craftAll, boolean b, RecipeHolder<?> recipe, Inventory player, CallbackInfoReturnable<RecipeBookMenu.PostPlaceAction> cir) {
|
||||
private void selectRecipeCallback(boolean craftAll, boolean b, RecipeHolder<?> recipe, ServerLevel serverLevel, Inventory player, CallbackInfoReturnable<RecipeBookMenu.PostPlaceAction> cir) {
|
||||
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener((ServerPlayer) player.player ,recipe,craftAll))
|
||||
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.AbstractContainerMenuInterface;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractFurnaceMenu;
|
||||
@@ -15,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
public class AbstractFurnaceMenu_scarpetMixin
|
||||
{
|
||||
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
|
||||
private void selectRecipeCallback(boolean craftAll, boolean b, RecipeHolder<?> recipe, Inventory player, CallbackInfoReturnable<RecipeBookMenu.PostPlaceAction> cir) {
|
||||
private void selectRecipeCallback(boolean craftAll, boolean b, RecipeHolder<?> recipe, ServerLevel level, Inventory player, CallbackInfoReturnable<RecipeBookMenu.PostPlaceAction> cir) {
|
||||
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener((ServerPlayer) player.player ,recipe,craftAll))
|
||||
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.RecipeManagerInterface;
|
||||
import com.google.common.collect.Multimap;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
|
||||
@Mixin(RecipeManager.class)
|
||||
public class RecipeManager_scarpetMixin implements RecipeManagerInterface
|
||||
{
|
||||
@Shadow private Multimap<RecipeType<?>, RecipeHolder<?>> byType;
|
||||
|
||||
@Shadow private Map<ResourceLocation, RecipeHolder<?>> byName;
|
||||
|
||||
@Override
|
||||
public List<Recipe<?>> getAllMatching(RecipeType<?> type, ResourceLocation itemId, RegistryAccess registryAccess)
|
||||
{
|
||||
// quiq cheq
|
||||
RecipeHolder<?> recipe = byName.get(itemId);
|
||||
if (recipe != null && recipe.value().getType().equals(type))
|
||||
{
|
||||
return List.of(recipe.value());
|
||||
}
|
||||
if (!byType.containsKey(type))
|
||||
{
|
||||
// happens when mods add recipe to the registry without updating recipe manager
|
||||
return List.of();
|
||||
}
|
||||
Collection<RecipeHolder<?>> typeRecipes = byType.get(type);
|
||||
Registry<Item> regs = registryAccess.lookupOrThrow(Registries.ITEM);
|
||||
Item item = regs.getValue(itemId);
|
||||
if (item == Items.AIR)
|
||||
{
|
||||
return List.of();
|
||||
}
|
||||
return typeRecipes.stream()
|
||||
.<Recipe<?>>map(RecipeHolder::value)
|
||||
.filter(r -> r.getResultItem(registryAccess).is(item))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.fakes.EntityInterface;
|
||||
import net.minecraft.network.protocol.game.ServerboundChatCommandPacket;
|
||||
import net.minecraft.world.entity.player.Input;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -255,7 +256,11 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
|
||||
{
|
||||
if (PLAYER_CHOOSES_RECIPE.isNeeded())
|
||||
{
|
||||
if(PLAYER_CHOOSES_RECIPE.onRecipeSelected(player, packet.getRecipe(), packet.isUseMaxItems())) ci.cancel();
|
||||
RecipeManager.ServerDisplayInfo displayInfo = player.server.getRecipeManager().getRecipeFromDisplay(packet.recipe());
|
||||
if (displayInfo == null) {
|
||||
return;
|
||||
}
|
||||
if(PLAYER_CHOOSES_RECIPE.onRecipeSelected(player, displayInfo.parent().id().location(), packet.useMaxItems())) ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.portal.DimensionTransition;
|
||||
import net.minecraft.world.level.portal.TeleportTransition;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -86,20 +86,20 @@ public abstract class ServerPlayer_scarpetEventMixin extends Player implements S
|
||||
private Vec3 previousLocation;
|
||||
private ResourceKey<Level> previousDimension;
|
||||
|
||||
@Inject(method = "changeDimension", at = @At("HEAD"))
|
||||
private void logPreviousCoordinates(DimensionTransition serverWorld, CallbackInfoReturnable<Entity> cir)
|
||||
@Inject(method = "teleport", at = @At("HEAD"))
|
||||
private void logPreviousCoordinates(TeleportTransition serverWorld, CallbackInfoReturnable<Entity> cir)
|
||||
{
|
||||
previousLocation = position();
|
||||
previousDimension = level().dimension(); //dimension type
|
||||
}
|
||||
|
||||
@Inject(method = "changeDimension", at = @At("RETURN"))
|
||||
private void atChangeDimension(DimensionTransition destinationP, CallbackInfoReturnable<Entity> cir)
|
||||
@Inject(method = "teleport", at = @At("RETURN"))
|
||||
private void atChangeDimension(TeleportTransition destinationP, CallbackInfoReturnable<Entity> cir)
|
||||
{
|
||||
if (PLAYER_CHANGES_DIMENSION.isNeeded())
|
||||
{
|
||||
ServerPlayer player = (ServerPlayer) (Object)this;
|
||||
DimensionTransition destinationTransition = destinationP;
|
||||
TeleportTransition destinationTransition = destinationP;
|
||||
ServerLevel destination = destinationTransition.newLevel();
|
||||
Vec3 to = null;
|
||||
if (!wonGame || previousDimension != Level.END || destination.dimension() != Level.OVERWORLD)
|
||||
|
||||
@@ -8,9 +8,9 @@ import net.minecraft.network.DisconnectionDetails;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.game.ClientboundEntityPositionSyncPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundClientCommandPacket;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@@ -31,7 +31,7 @@ import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.portal.DimensionTransition;
|
||||
import net.minecraft.world.level.portal.TeleportTransition;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import carpet.fakes.ServerPlayerInterface;
|
||||
import carpet.utils.Messenger;
|
||||
@@ -84,7 +84,7 @@ public class EntityPlayerMPFake extends ServerPlayer
|
||||
instance.getAttribute(Attributes.STEP_HEIGHT).setBaseValue(0.6F);
|
||||
instance.gameMode.changeGameModeForPlayer(gamemode);
|
||||
server.getPlayerList().broadcastAll(new ClientboundRotateHeadPacket(instance, (byte) (instance.yHeadRot * 256 / 360)), dimensionId);//instance.dimension);
|
||||
server.getPlayerList().broadcastAll(new ClientboundTeleportEntityPacket(instance), dimensionId);//instance.dimension);
|
||||
server.getPlayerList().broadcastAll(ClientboundEntityPositionSyncPacket.of(instance), dimensionId);//instance.dimension);
|
||||
//instance.world.getChunkManager(). updatePosition(instance);
|
||||
instance.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0x7f); // show all model layers (incl. capes)
|
||||
instance.getAbilities().flying = flying;
|
||||
@@ -216,9 +216,9 @@ public class EntityPlayerMPFake extends ServerPlayer
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player changeDimension(DimensionTransition serverLevel)
|
||||
public ServerPlayer teleport(TeleportTransition serverLevel)
|
||||
{
|
||||
super.changeDimension(serverLevel);
|
||||
super.teleport(serverLevel);
|
||||
if (wonGame) {
|
||||
ServerboundClientCommandPacket p = new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN);
|
||||
connection.handleClientCommand(p);
|
||||
|
||||
@@ -6,8 +6,8 @@ import carpet.script.argument.FunctionArgument;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.exception.ThrowStatement;
|
||||
import carpet.script.exception.Throwables;
|
||||
import carpet.script.external.Vanilla;
|
||||
import carpet.script.utils.InputValidator;
|
||||
import carpet.script.utils.RecipeHelper;
|
||||
import carpet.script.value.BooleanValue;
|
||||
import carpet.script.value.EntityValue;
|
||||
import carpet.script.value.FormattedTextValue;
|
||||
@@ -49,6 +49,7 @@ import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.item.crafting.ShapedRecipe;
|
||||
import net.minecraft.world.item.crafting.ShapelessRecipe;
|
||||
import net.minecraft.world.item.crafting.SingleItemRecipe;
|
||||
import net.minecraft.world.item.crafting.display.SlotDisplay;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class Inventories
|
||||
@@ -103,7 +104,7 @@ public class Inventories
|
||||
throw new InternalExpressionException("'recipe_data' requires at least one argument");
|
||||
}
|
||||
String recipeName = lv.get(0).getString();
|
||||
RecipeType<?> type = RecipeType.CRAFTING;
|
||||
RecipeType<? extends Recipe<?>> type = RecipeType.CRAFTING;
|
||||
if (lv.size() > 1)
|
||||
{
|
||||
String recipeType = lv.get(1).getString();
|
||||
@@ -113,30 +114,44 @@ public class Inventories
|
||||
throw new InternalExpressionException("Unknown recipe type: " + recipeType);
|
||||
}
|
||||
}
|
||||
List<Recipe<?>> recipes = Vanilla.RecipeManager_getAllMatching(cc.server().getRecipeManager(), type, InputValidator.identifierOf(recipeName), cc.registryAccess());
|
||||
List<Recipe<?>> recipes = RecipeHelper.getRecipesForOutput(cc.server().getRecipeManager(), type, InputValidator.identifierOf(recipeName), cc.level());
|
||||
if (recipes.isEmpty())
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
List<Value> recipesOutput = new ArrayList<>();
|
||||
RegistryAccess regs = cc.registryAccess();
|
||||
SlotDisplay.ResolutionContext context = SlotDisplay.ResolutionContext.forLevel(cc.level());
|
||||
for (Recipe<?> recipe : recipes)
|
||||
{
|
||||
ItemStack result = recipe.getResultItem(regs);
|
||||
List<Value> results = new ArrayList<>();
|
||||
//ItemStack result = recipe.display().forEach(); getResultItem(regs);
|
||||
recipe.display().forEach(rd -> rd.result().resolveForStacks(context).forEach(is -> results.add(ValueConversions.of(is, regs))));
|
||||
|
||||
|
||||
List<Value> ingredientValue = new ArrayList<>();
|
||||
recipe.placementInfo().slotInfo().forEach(ingredient -> {
|
||||
if (ingredient.isEmpty())
|
||||
for (Optional<PlacementInfo.SlotInfo> info : recipe.placementInfo().slotInfo())
|
||||
{
|
||||
if (info.isEmpty())
|
||||
{
|
||||
ingredientValue.add(Value.NULL);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
PlacementInfo.SlotInfo value = ingredient.get();
|
||||
int position = value.placerOutputPosition();
|
||||
PlacementInfo.SlotInfo value = info.get();
|
||||
int ingredientIndex = value.placerOutputPosition();
|
||||
|
||||
List<Value> alternatives = new ArrayList<>();
|
||||
value.possibleItems().stream().map(is -> ValueConversions.of(is, regs)).forEach(alternatives::add);
|
||||
recipe.placementInfo().ingredients().get(ingredientIndex).items().forEach(item -> alternatives.add(ValueConversions.of(item.value(), regs)));
|
||||
if (alternatives.isEmpty())
|
||||
{
|
||||
ingredientValue.add(Value.NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ingredientValue.add(ListValue.wrap(alternatives));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Value recipeSpec;
|
||||
if (recipe instanceof ShapedRecipe shapedRecipe)
|
||||
@@ -155,8 +170,8 @@ public class Inventories
|
||||
{
|
||||
recipeSpec = ListValue.of(
|
||||
new StringValue("smelting"),
|
||||
new NumericValue(abstractCookingRecipe.getCookingTime()),
|
||||
new NumericValue(abstractCookingRecipe.getExperience())
|
||||
new NumericValue(abstractCookingRecipe.cookingTime()),
|
||||
new NumericValue(abstractCookingRecipe.experience())
|
||||
);
|
||||
}
|
||||
else if (recipe instanceof SingleItemRecipe)
|
||||
@@ -172,7 +187,7 @@ public class Inventories
|
||||
recipeSpec = ListValue.of(new StringValue("custom"));
|
||||
}
|
||||
|
||||
recipesOutput.add(ListValue.of(ValueConversions.of(result, regs), ListValue.wrap(ingredientValue), recipeSpec));
|
||||
recipesOutput.add(ListValue.of(ListValue.wrap(results), ListValue.wrap(ingredientValue), recipeSpec));
|
||||
}
|
||||
return ListValue.wrap(recipesOutput);
|
||||
});
|
||||
@@ -181,10 +196,11 @@ public class Inventories
|
||||
{
|
||||
String itemStr = v.get(0).getString();
|
||||
ResourceLocation id = InputValidator.identifierOf(itemStr);
|
||||
Registry<Item> registry = ((CarpetContext) c).registry(Registries.ITEM);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
Registry<Item> registry = cc.registry(Registries.ITEM);
|
||||
Item item = registry.getOptional(id).orElseThrow(() -> new ThrowStatement(itemStr, Throwables.UNKNOWN_ITEM));
|
||||
Item reminder = item.getCraftingRemainingItem();
|
||||
return reminder == null ? Value.NULL : NBTSerializableValue.nameFromRegistryId(registry.getKey(reminder));
|
||||
ItemStack reminder = item.getCraftingRemainder();
|
||||
return reminder.isEmpty() ? Value.NULL : ValueConversions.of(reminder, cc.registryAccess());
|
||||
});
|
||||
|
||||
expression.addContextFunction("inventory_size", -1, (c, t, lv) ->
|
||||
|
||||
@@ -55,7 +55,6 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.advancements.AdvancementHolder;
|
||||
import net.minecraft.advancements.critereon.MinMaxBounds;
|
||||
import net.minecraft.commands.CommandBuildContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
@@ -204,12 +203,8 @@ public abstract class CommandArgument
|
||||
|
||||
// resource / identifier section
|
||||
|
||||
new VanillaUnconfigurableArgument("recipe", ResourceLocationArgument::id,
|
||||
(c, p) -> ValueConversions.of(ResourceLocationArgument.getRecipe(c, p).id()), SuggestionProviders.ALL_RECIPES
|
||||
),
|
||||
new VanillaUnconfigurableArgument("advancement", ResourceLocationArgument::id,
|
||||
(c, p) -> ValueConversions.of(ResourceLocationArgument.getAdvancement(c, p).id()), (ctx, builder) -> SharedSuggestionProvider.suggestResource(ctx.getSource().getServer().getAdvancements().getAllAdvancements().stream().map(AdvancementHolder::id), builder)
|
||||
),
|
||||
new VanillaUnconfigurableArgument("recipe", Registries.RECIPE),
|
||||
new VanillaUnconfigurableArgument("advancement", Registries.ADVANCEMENT),
|
||||
new VanillaUnconfigurableArgument("lootcondition", ResourceLocationArgument::id,
|
||||
(c, p) -> ValueConversions.of(ResourceLocationArgument.getId(c, p)), (ctx, builder) -> SharedSuggestionProvider.suggestResource(ctx.getSource().getServer().reloadableRegistries().getKeys(Registries.LOOT_CONDITION_TYPE), builder)
|
||||
),
|
||||
|
||||
@@ -13,13 +13,11 @@ import carpet.fakes.LivingEntityInterface;
|
||||
import carpet.fakes.MinecraftServerInterface;
|
||||
import carpet.fakes.MobEntityInterface;
|
||||
import carpet.fakes.RandomStateVisitorAccessor;
|
||||
import carpet.fakes.RecipeManagerInterface;
|
||||
import carpet.fakes.AbstractContainerMenuInterface;
|
||||
import carpet.fakes.ServerPlayerInterface;
|
||||
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
||||
import carpet.fakes.ServerWorldInterface;
|
||||
import carpet.fakes.SpawnHelperInnerInterface;
|
||||
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
|
||||
import carpet.mixins.Objective_scarpetMixin;
|
||||
import carpet.mixins.PoiRecord_scarpetMixin;
|
||||
import carpet.mixins.Scoreboard_scarpetMixin;
|
||||
@@ -38,10 +36,8 @@ import net.fabricmc.loader.api.ModContainer;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.blocks.BlockInput;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
@@ -62,11 +58,6 @@ import net.minecraft.world.entity.animal.horse.AbstractHorse;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.DataSlot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.NaturalSpawner;
|
||||
@@ -83,7 +74,6 @@ import net.minecraft.world.scores.Objective;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -107,11 +97,6 @@ public class Vanilla
|
||||
return Map.of(); //return ((ThreadedAnvilChunkStorageInterface) chunkMap).regenerateChunkRegion(requestedChunks);
|
||||
}
|
||||
|
||||
public static List<Recipe<?>> RecipeManager_getAllMatching(RecipeManager recipeManager, RecipeType<?> type, ResourceLocation output, RegistryAccess registryAccess)
|
||||
{
|
||||
return ((RecipeManagerInterface) recipeManager).getAllMatching(type, output, registryAccess);
|
||||
}
|
||||
|
||||
public static int NaturalSpawner_MAGIC_NUMBER()
|
||||
{
|
||||
return SpawnReporter.MAGIC_NUMBER;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package carpet.script.utils;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.item.crafting.display.RecipeDisplay;
|
||||
import net.minecraft.world.item.crafting.display.SlotDisplay;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RecipeHelper
|
||||
{
|
||||
public static List<Recipe<?>> getRecipesForOutput(RecipeManager recipeManager, RecipeType<?> type, ResourceLocation id, Level level)
|
||||
{
|
||||
List<Recipe<?>> results = new ArrayList<>();
|
||||
SlotDisplay.ResolutionContext context = SlotDisplay.ResolutionContext.forLevel(level);
|
||||
recipeManager.getRecipes().forEach(r -> {
|
||||
if (r.value().getType() == type)
|
||||
{
|
||||
for (RecipeDisplay recipeDisplay : r.value().display())
|
||||
{
|
||||
recipeDisplay.result().resolveForStacks(context).forEach(stack -> {
|
||||
if (BuiltInRegistries.ITEM.wrapAsHolder(stack.getItem()).unwrapKey().map(ResourceKey::location).orElseThrow(IllegalStateException::new).equals(id))
|
||||
{
|
||||
results.add(r.value());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Recipe<?>> getRecipesForOutput(RecipeManager recipeManager, ResourceLocation id, Level level)
|
||||
{
|
||||
List<Recipe<?>> results = new ArrayList<>();
|
||||
SlotDisplay.ResolutionContext context = SlotDisplay.ResolutionContext.forLevel(level);
|
||||
recipeManager.getRecipes().forEach(r -> {
|
||||
for (RecipeDisplay recipeDisplay : r.value().display())
|
||||
{
|
||||
recipeDisplay.result().resolveForStacks(context).forEach(stack -> {
|
||||
if (BuiltInRegistries.ITEM.wrapAsHolder(stack.getItem()).unwrapKey().map(ResourceKey::location).orElseThrow(IllegalStateException::new).equals(id))
|
||||
{
|
||||
results.add(r.value());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
return results;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.network.protocol.game.ClientboundEntityPositionSyncPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
||||
@@ -922,7 +924,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
else
|
||||
{
|
||||
((ServerLevel) e.getCommandSenderWorld()).getChunkSource().broadcastAndSend(e, new ClientboundTeleportEntityPacket(e));
|
||||
((ServerLevel) e.getCommandSenderWorld()).getChunkSource().broadcastAndSend(e, ClientboundEntityPositionSyncPacket.of(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.ai.behavior.PositionTracker;
|
||||
import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
|
||||
import net.minecraft.world.entity.ai.memory.WalkTarget;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -99,12 +100,17 @@ public class ValueConversions
|
||||
public static Value of(ItemStack stack, RegistryAccess regs)
|
||||
{
|
||||
return stack == null || stack.isEmpty() ? Value.NULL : ListValue.of(
|
||||
of(regs.lookupOrThrow(Registries.ITEM).getKey(stack.getItem())),
|
||||
of(stack.getItem(), regs),
|
||||
new NumericValue(stack.getCount()),
|
||||
NBTSerializableValue.fromStack(stack, regs)
|
||||
);
|
||||
}
|
||||
|
||||
public static Value of(Item item, RegistryAccess regs)
|
||||
{
|
||||
return of(regs.lookupOrThrow(Registries.ITEM).getKey(item));
|
||||
}
|
||||
|
||||
public static Value of(Objective objective)
|
||||
{
|
||||
return ListValue.of(
|
||||
|
||||
@@ -151,7 +151,6 @@
|
||||
"CommandDispatcher_scarpetCommandsMixin",
|
||||
"FoodData_scarpetMixin",
|
||||
|
||||
"RecipeManager_scarpetMixin",
|
||||
"BlockInput_scarpetMixin",
|
||||
"BlockPredicate_scarpetMixin",
|
||||
"TagPredicate_scarpetMixin",
|
||||
|
||||
Reference in new issue
Block a user