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+)
|
* `'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
|
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
|
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 triples, or `null` if its a shaped recipe and a given slot in the patterns is left
|
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:
|
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.
|
* `['shaped', width, height]` - shaped crafting. `width` and `height` can be 1, 2 or 3.
|
||||||
* `['shapeless']` - shapeless crafting
|
* `['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
|
* `['special']` - special crafting recipe, typically not present in the crafting menu
|
||||||
* `['custom']` - other recipe types
|
* `['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
|
Also note that some recipes leave some products in the crafting window, and these can be determined using
|
||||||
`crafting_remaining_item()` function
|
`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)`
|
### `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
|
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)`
|
### `inventory_size(inventory)`
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -3,10 +3,10 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check https://fabricmc.net/develop/
|
# check https://fabricmc.net/develop/
|
||||||
minecraft_version=24w39a
|
minecraft_version=24w40a
|
||||||
loader_version=0.16.5
|
loader_version=0.16.5
|
||||||
jsr305_version=3.0.2
|
jsr305_version=3.0.2
|
||||||
fabric_version=0.102.0+1.21
|
fabric_version=0.105.1+1.21.2
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 1.4.154
|
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;
|
package carpet.helpers;
|
||||||
|
|
||||||
import carpet.CarpetServer;
|
import carpet.CarpetServer;
|
||||||
import carpet.fakes.RecipeManagerInterface;
|
import carpet.script.utils.RecipeHelper;
|
||||||
import carpet.utils.Messenger;
|
import carpet.utils.Messenger;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.Registries;
|
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.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
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.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.AbstractBannerBlock;
|
||||||
import net.minecraft.world.level.block.BeaconBeamBlock;
|
import net.minecraft.world.level.block.BeaconBeamBlock;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
@@ -36,7 +37,6 @@ import java.util.EnumMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
@@ -101,7 +101,9 @@ public class HopperCounter
|
|||||||
this.color = color;
|
this.color = color;
|
||||||
String hexColor = Integer.toHexString(color.getTextColor());
|
String hexColor = Integer.toHexString(color.getTextColor());
|
||||||
if (hexColor.length() < 6)
|
if (hexColor.length() < 6)
|
||||||
|
{
|
||||||
hexColor = "0".repeat(6 - hexColor.length()) + hexColor;
|
hexColor = "0".repeat(6 - hexColor.length()) + hexColor;
|
||||||
|
}
|
||||||
this.coloredName = '#' + hexColor + ' ' + color.getName();
|
this.coloredName = '#' + hexColor + ' ' + color.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +137,7 @@ public class HopperCounter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets all counters, clearing their items.
|
* Resets all counters, clearing their items.
|
||||||
|
*
|
||||||
* @param fresh Whether or not to start the clocks going immediately or later.
|
* @param fresh Whether or not to start the clocks going immediately or later.
|
||||||
*/
|
*/
|
||||||
public static void resetAll(MinecraftServer server, boolean fresh)
|
public static void resetAll(MinecraftServer server, boolean fresh)
|
||||||
@@ -142,7 +145,10 @@ public class HopperCounter
|
|||||||
for (HopperCounter counter : COUNTERS.values())
|
for (HopperCounter counter : COUNTERS.values())
|
||||||
{
|
{
|
||||||
counter.reset(server);
|
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);
|
List<Component> temp = counter.format(server, realtime, false);
|
||||||
if (temp.size() > 1)
|
if (temp.size() > 1)
|
||||||
{
|
{
|
||||||
if (!text.isEmpty()) text.add(Messenger.s(""));
|
if (!text.isEmpty())
|
||||||
|
{
|
||||||
|
text.add(Messenger.s(""));
|
||||||
|
}
|
||||||
text.addAll(temp);
|
text.addAll(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,7 +223,7 @@ public class HopperCounter
|
|||||||
Item item = e.getKey();
|
Item item = e.getKey();
|
||||||
MutableComponent itemName = Component.translatable(item.getDescriptionId());
|
MutableComponent itemName = Component.translatable(item.getDescriptionId());
|
||||||
Style itemStyle = itemName.getStyle();
|
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));
|
itemName.setStyle((color != null) ? itemStyle.withColor(color) : itemStyle.withItalic(true));
|
||||||
long count = e.getLongValue();
|
long count = e.getLongValue();
|
||||||
return Messenger.c("g - ", itemName,
|
return Messenger.c("g - ", itemName,
|
||||||
@@ -231,13 +240,25 @@ public class HopperCounter
|
|||||||
*/
|
*/
|
||||||
public static int appropriateColor(int color)
|
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 r = (color >> 16 & 255);
|
||||||
int g = (color >> 8 & 255);
|
int g = (color >> 8 & 255);
|
||||||
int b = (color & 255);
|
int b = (color & 255);
|
||||||
if (r < 70) r = 70;
|
if (r < 70)
|
||||||
if (g < 70) g = 70;
|
{
|
||||||
if (b < 70) b = 70;
|
r = 70;
|
||||||
|
}
|
||||||
|
if (g < 70)
|
||||||
|
{
|
||||||
|
g = 70;
|
||||||
|
}
|
||||||
|
if (b < 70)
|
||||||
|
{
|
||||||
|
b = 70;
|
||||||
|
}
|
||||||
return (r << 16) + (g << 8) + b;
|
return (r << 16) + (g << 8) + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,8 +358,14 @@ public class HopperCounter
|
|||||||
*/
|
*/
|
||||||
public static TextColor fromItem(Item item, RegistryAccess registryAccess)
|
public static TextColor fromItem(Item item, RegistryAccess registryAccess)
|
||||||
{
|
{
|
||||||
if (DEFAULTS.containsKey(item)) return TextColor.fromRgb(appropriateColor(DEFAULTS.get(item).defaultMapColor().col));
|
if (DEFAULTS.containsKey(item))
|
||||||
if (item instanceof DyeItem dye) return TextColor.fromRgb(appropriateColor(dye.getDyeColor().getMapColor().col));
|
{
|
||||||
|
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;
|
Block block = null;
|
||||||
final Registry<Item> itemRegistry = registryAccess.lookupOrThrow(Registries.ITEM);
|
final Registry<Item> itemRegistry = registryAccess.lookupOrThrow(Registries.ITEM);
|
||||||
final Registry<Block> blockRegistry = registryAccess.lookupOrThrow(Registries.BLOCK);
|
final Registry<Block> blockRegistry = registryAccess.lookupOrThrow(Registries.BLOCK);
|
||||||
@@ -353,8 +380,14 @@ public class HopperCounter
|
|||||||
}
|
}
|
||||||
if (block != null)
|
if (block != null)
|
||||||
{
|
{
|
||||||
if (block instanceof AbstractBannerBlock) return TextColor.fromRgb(appropriateColor(((AbstractBannerBlock) block).getColor().getMapColor().col));
|
if (block instanceof AbstractBannerBlock)
|
||||||
if (block instanceof BeaconBeamBlock) return TextColor.fromRgb(appropriateColor( ((BeaconBeamBlock) block).getColor().getMapColor().col));
|
{
|
||||||
|
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 TextColor.fromRgb(appropriateColor(block.defaultMapColor().col));
|
||||||
}
|
}
|
||||||
return null;
|
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
|
* 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
|
* 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);
|
TextColor direct = fromItem(item, registryAccess);
|
||||||
if (direct != null) return direct;
|
if (direct != null)
|
||||||
if (CarpetServer.minecraft_server == null) return WHITE;
|
{
|
||||||
|
return direct;
|
||||||
|
}
|
||||||
|
if (CarpetServer.minecraft_server == null)
|
||||||
|
{
|
||||||
|
return WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
ResourceLocation id = registryAccess.lookupOrThrow(Registries.ITEM).getKey(item);
|
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)
|
if (cand != null)
|
||||||
|
{
|
||||||
return cand;
|
return cand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the hopper counter for the given color
|
* Returns the hopper counter for the given color
|
||||||
*/
|
*/
|
||||||
public static HopperCounter getCounter(DyeColor color) {
|
public static HopperCounter getCounter(DyeColor color)
|
||||||
|
{
|
||||||
return COUNTERS.get(color);
|
return COUNTERS.get(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.fakes.AbstractContainerMenuInterface;
|
import carpet.fakes.AbstractContainerMenuInterface;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.inventory.AbstractCraftingMenu;
|
import net.minecraft.world.inventory.AbstractCraftingMenu;
|
||||||
@@ -15,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
public class AbstractCraftingMenu_scarpetMixin
|
public class AbstractCraftingMenu_scarpetMixin
|
||||||
{
|
{
|
||||||
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
|
@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))
|
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener((ServerPlayer) player.player ,recipe,craftAll))
|
||||||
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.fakes.AbstractContainerMenuInterface;
|
import carpet.fakes.AbstractContainerMenuInterface;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.inventory.AbstractFurnaceMenu;
|
import net.minecraft.world.inventory.AbstractFurnaceMenu;
|
||||||
@@ -15,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
public class AbstractFurnaceMenu_scarpetMixin
|
public class AbstractFurnaceMenu_scarpetMixin
|
||||||
{
|
{
|
||||||
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
|
@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))
|
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener((ServerPlayer) player.player ,recipe,craftAll))
|
||||||
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
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 carpet.fakes.EntityInterface;
|
||||||
import net.minecraft.network.protocol.game.ServerboundChatCommandPacket;
|
import net.minecraft.network.protocol.game.ServerboundChatCommandPacket;
|
||||||
import net.minecraft.world.entity.player.Input;
|
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.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -255,7 +256,11 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
|
|||||||
{
|
{
|
||||||
if (PLAYER_CHOOSES_RECIPE.isNeeded())
|
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.Entity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.Level;
|
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 net.minecraft.world.phys.Vec3;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
@@ -86,20 +86,20 @@ public abstract class ServerPlayer_scarpetEventMixin extends Player implements S
|
|||||||
private Vec3 previousLocation;
|
private Vec3 previousLocation;
|
||||||
private ResourceKey<Level> previousDimension;
|
private ResourceKey<Level> previousDimension;
|
||||||
|
|
||||||
@Inject(method = "changeDimension", at = @At("HEAD"))
|
@Inject(method = "teleport", at = @At("HEAD"))
|
||||||
private void logPreviousCoordinates(DimensionTransition serverWorld, CallbackInfoReturnable<Entity> cir)
|
private void logPreviousCoordinates(TeleportTransition serverWorld, CallbackInfoReturnable<Entity> cir)
|
||||||
{
|
{
|
||||||
previousLocation = position();
|
previousLocation = position();
|
||||||
previousDimension = level().dimension(); //dimension type
|
previousDimension = level().dimension(); //dimension type
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "changeDimension", at = @At("RETURN"))
|
@Inject(method = "teleport", at = @At("RETURN"))
|
||||||
private void atChangeDimension(DimensionTransition destinationP, CallbackInfoReturnable<Entity> cir)
|
private void atChangeDimension(TeleportTransition destinationP, CallbackInfoReturnable<Entity> cir)
|
||||||
{
|
{
|
||||||
if (PLAYER_CHANGES_DIMENSION.isNeeded())
|
if (PLAYER_CHANGES_DIMENSION.isNeeded())
|
||||||
{
|
{
|
||||||
ServerPlayer player = (ServerPlayer) (Object)this;
|
ServerPlayer player = (ServerPlayer) (Object)this;
|
||||||
DimensionTransition destinationTransition = destinationP;
|
TeleportTransition destinationTransition = destinationP;
|
||||||
ServerLevel destination = destinationTransition.newLevel();
|
ServerLevel destination = destinationTransition.newLevel();
|
||||||
Vec3 to = null;
|
Vec3 to = null;
|
||||||
if (!wonGame || previousDimension != Level.END || destination.dimension() != Level.OVERWORLD)
|
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.Component;
|
||||||
import net.minecraft.network.chat.contents.TranslatableContents;
|
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||||
import net.minecraft.network.protocol.PacketFlow;
|
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.ClientboundPlayerInfoUpdatePacket;
|
||||||
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
|
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
|
||||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
|
|
||||||
import net.minecraft.network.protocol.game.ServerboundClientCommandPacket;
|
import net.minecraft.network.protocol.game.ServerboundClientCommandPacket;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.MinecraftServer;
|
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.Level;
|
||||||
import net.minecraft.world.level.block.entity.SkullBlockEntity;
|
import net.minecraft.world.level.block.entity.SkullBlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
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 net.minecraft.world.phys.Vec3;
|
||||||
import carpet.fakes.ServerPlayerInterface;
|
import carpet.fakes.ServerPlayerInterface;
|
||||||
import carpet.utils.Messenger;
|
import carpet.utils.Messenger;
|
||||||
@@ -84,7 +84,7 @@ public class EntityPlayerMPFake extends ServerPlayer
|
|||||||
instance.getAttribute(Attributes.STEP_HEIGHT).setBaseValue(0.6F);
|
instance.getAttribute(Attributes.STEP_HEIGHT).setBaseValue(0.6F);
|
||||||
instance.gameMode.changeGameModeForPlayer(gamemode);
|
instance.gameMode.changeGameModeForPlayer(gamemode);
|
||||||
server.getPlayerList().broadcastAll(new ClientboundRotateHeadPacket(instance, (byte) (instance.yHeadRot * 256 / 360)), dimensionId);//instance.dimension);
|
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.world.getChunkManager(). updatePosition(instance);
|
||||||
instance.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0x7f); // show all model layers (incl. capes)
|
instance.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0x7f); // show all model layers (incl. capes)
|
||||||
instance.getAbilities().flying = flying;
|
instance.getAbilities().flying = flying;
|
||||||
@@ -216,9 +216,9 @@ public class EntityPlayerMPFake extends ServerPlayer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Player changeDimension(DimensionTransition serverLevel)
|
public ServerPlayer teleport(TeleportTransition serverLevel)
|
||||||
{
|
{
|
||||||
super.changeDimension(serverLevel);
|
super.teleport(serverLevel);
|
||||||
if (wonGame) {
|
if (wonGame) {
|
||||||
ServerboundClientCommandPacket p = new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN);
|
ServerboundClientCommandPacket p = new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN);
|
||||||
connection.handleClientCommand(p);
|
connection.handleClientCommand(p);
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import carpet.script.argument.FunctionArgument;
|
|||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.exception.ThrowStatement;
|
import carpet.script.exception.ThrowStatement;
|
||||||
import carpet.script.exception.Throwables;
|
import carpet.script.exception.Throwables;
|
||||||
import carpet.script.external.Vanilla;
|
|
||||||
import carpet.script.utils.InputValidator;
|
import carpet.script.utils.InputValidator;
|
||||||
|
import carpet.script.utils.RecipeHelper;
|
||||||
import carpet.script.value.BooleanValue;
|
import carpet.script.value.BooleanValue;
|
||||||
import carpet.script.value.EntityValue;
|
import carpet.script.value.EntityValue;
|
||||||
import carpet.script.value.FormattedTextValue;
|
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.ShapedRecipe;
|
||||||
import net.minecraft.world.item.crafting.ShapelessRecipe;
|
import net.minecraft.world.item.crafting.ShapelessRecipe;
|
||||||
import net.minecraft.world.item.crafting.SingleItemRecipe;
|
import net.minecraft.world.item.crafting.SingleItemRecipe;
|
||||||
|
import net.minecraft.world.item.crafting.display.SlotDisplay;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class Inventories
|
public class Inventories
|
||||||
@@ -103,7 +104,7 @@ public class Inventories
|
|||||||
throw new InternalExpressionException("'recipe_data' requires at least one argument");
|
throw new InternalExpressionException("'recipe_data' requires at least one argument");
|
||||||
}
|
}
|
||||||
String recipeName = lv.get(0).getString();
|
String recipeName = lv.get(0).getString();
|
||||||
RecipeType<?> type = RecipeType.CRAFTING;
|
RecipeType<? extends Recipe<?>> type = RecipeType.CRAFTING;
|
||||||
if (lv.size() > 1)
|
if (lv.size() > 1)
|
||||||
{
|
{
|
||||||
String recipeType = lv.get(1).getString();
|
String recipeType = lv.get(1).getString();
|
||||||
@@ -113,30 +114,44 @@ public class Inventories
|
|||||||
throw new InternalExpressionException("Unknown recipe type: " + recipeType);
|
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())
|
if (recipes.isEmpty())
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
List<Value> recipesOutput = new ArrayList<>();
|
List<Value> recipesOutput = new ArrayList<>();
|
||||||
RegistryAccess regs = cc.registryAccess();
|
RegistryAccess regs = cc.registryAccess();
|
||||||
|
SlotDisplay.ResolutionContext context = SlotDisplay.ResolutionContext.forLevel(cc.level());
|
||||||
for (Recipe<?> recipe : recipes)
|
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<>();
|
List<Value> ingredientValue = new ArrayList<>();
|
||||||
recipe.placementInfo().slotInfo().forEach(ingredient -> {
|
for (Optional<PlacementInfo.SlotInfo> info : recipe.placementInfo().slotInfo())
|
||||||
if (ingredient.isEmpty())
|
{
|
||||||
|
if (info.isEmpty())
|
||||||
{
|
{
|
||||||
ingredientValue.add(Value.NULL);
|
ingredientValue.add(Value.NULL);
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
PlacementInfo.SlotInfo value = ingredient.get();
|
PlacementInfo.SlotInfo value = info.get();
|
||||||
int position = value.placerOutputPosition();
|
int ingredientIndex = value.placerOutputPosition();
|
||||||
|
|
||||||
List<Value> alternatives = new ArrayList<>();
|
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));
|
ingredientValue.add(ListValue.wrap(alternatives));
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value recipeSpec;
|
Value recipeSpec;
|
||||||
if (recipe instanceof ShapedRecipe shapedRecipe)
|
if (recipe instanceof ShapedRecipe shapedRecipe)
|
||||||
@@ -155,8 +170,8 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
recipeSpec = ListValue.of(
|
recipeSpec = ListValue.of(
|
||||||
new StringValue("smelting"),
|
new StringValue("smelting"),
|
||||||
new NumericValue(abstractCookingRecipe.getCookingTime()),
|
new NumericValue(abstractCookingRecipe.cookingTime()),
|
||||||
new NumericValue(abstractCookingRecipe.getExperience())
|
new NumericValue(abstractCookingRecipe.experience())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (recipe instanceof SingleItemRecipe)
|
else if (recipe instanceof SingleItemRecipe)
|
||||||
@@ -172,7 +187,7 @@ public class Inventories
|
|||||||
recipeSpec = ListValue.of(new StringValue("custom"));
|
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);
|
return ListValue.wrap(recipesOutput);
|
||||||
});
|
});
|
||||||
@@ -181,10 +196,11 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
String itemStr = v.get(0).getString();
|
String itemStr = v.get(0).getString();
|
||||||
ResourceLocation id = InputValidator.identifierOf(itemStr);
|
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 item = registry.getOptional(id).orElseThrow(() -> new ThrowStatement(itemStr, Throwables.UNKNOWN_ITEM));
|
||||||
Item reminder = item.getCraftingRemainingItem();
|
ItemStack reminder = item.getCraftingRemainder();
|
||||||
return reminder == null ? Value.NULL : NBTSerializableValue.nameFromRegistryId(registry.getKey(reminder));
|
return reminder.isEmpty() ? Value.NULL : ValueConversions.of(reminder, cc.registryAccess());
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("inventory_size", -1, (c, t, lv) ->
|
expression.addContextFunction("inventory_size", -1, (c, t, lv) ->
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ import java.util.function.Supplier;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.advancements.AdvancementHolder;
|
|
||||||
import net.minecraft.advancements.critereon.MinMaxBounds;
|
import net.minecraft.advancements.critereon.MinMaxBounds;
|
||||||
import net.minecraft.commands.CommandBuildContext;
|
import net.minecraft.commands.CommandBuildContext;
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
@@ -204,12 +203,8 @@ public abstract class CommandArgument
|
|||||||
|
|
||||||
// resource / identifier section
|
// resource / identifier section
|
||||||
|
|
||||||
new VanillaUnconfigurableArgument("recipe", ResourceLocationArgument::id,
|
new VanillaUnconfigurableArgument("recipe", Registries.RECIPE),
|
||||||
(c, p) -> ValueConversions.of(ResourceLocationArgument.getRecipe(c, p).id()), SuggestionProviders.ALL_RECIPES
|
new VanillaUnconfigurableArgument("advancement", Registries.ADVANCEMENT),
|
||||||
),
|
|
||||||
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("lootcondition", ResourceLocationArgument::id,
|
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)
|
(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.MinecraftServerInterface;
|
||||||
import carpet.fakes.MobEntityInterface;
|
import carpet.fakes.MobEntityInterface;
|
||||||
import carpet.fakes.RandomStateVisitorAccessor;
|
import carpet.fakes.RandomStateVisitorAccessor;
|
||||||
import carpet.fakes.RecipeManagerInterface;
|
|
||||||
import carpet.fakes.AbstractContainerMenuInterface;
|
import carpet.fakes.AbstractContainerMenuInterface;
|
||||||
import carpet.fakes.ServerPlayerInterface;
|
import carpet.fakes.ServerPlayerInterface;
|
||||||
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
||||||
import carpet.fakes.ServerWorldInterface;
|
import carpet.fakes.ServerWorldInterface;
|
||||||
import carpet.fakes.SpawnHelperInnerInterface;
|
import carpet.fakes.SpawnHelperInnerInterface;
|
||||||
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
|
|
||||||
import carpet.mixins.Objective_scarpetMixin;
|
import carpet.mixins.Objective_scarpetMixin;
|
||||||
import carpet.mixins.PoiRecord_scarpetMixin;
|
import carpet.mixins.PoiRecord_scarpetMixin;
|
||||||
import carpet.mixins.Scoreboard_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.CommandSourceStack;
|
||||||
import net.minecraft.commands.arguments.blocks.BlockInput;
|
import net.minecraft.commands.arguments.blocks.BlockInput;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.RegistryAccess;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ChunkMap;
|
import net.minecraft.server.level.ChunkMap;
|
||||||
import net.minecraft.server.level.DistanceManager;
|
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.entity.item.ItemEntity;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
import net.minecraft.world.inventory.DataSlot;
|
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.ChunkPos;
|
||||||
import net.minecraft.world.level.GameRules;
|
import net.minecraft.world.level.GameRules;
|
||||||
import net.minecraft.world.level.NaturalSpawner;
|
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.Scoreboard;
|
||||||
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -107,11 +97,6 @@ public class Vanilla
|
|||||||
return Map.of(); //return ((ThreadedAnvilChunkStorageInterface) chunkMap).regenerateChunkRegion(requestedChunks);
|
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()
|
public static int NaturalSpawner_MAGIC_NUMBER()
|
||||||
{
|
{
|
||||||
return SpawnReporter.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.core.registries.Registries;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.StringTag;
|
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.ClientboundSetExperiencePacket;
|
||||||
import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket;
|
import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket;
|
||||||
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
||||||
@@ -922,7 +924,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
else
|
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.behavior.PositionTracker;
|
||||||
import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
|
import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
|
||||||
import net.minecraft.world.entity.ai.memory.WalkTarget;
|
import net.minecraft.world.entity.ai.memory.WalkTarget;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
@@ -99,12 +100,17 @@ public class ValueConversions
|
|||||||
public static Value of(ItemStack stack, RegistryAccess regs)
|
public static Value of(ItemStack stack, RegistryAccess regs)
|
||||||
{
|
{
|
||||||
return stack == null || stack.isEmpty() ? Value.NULL : ListValue.of(
|
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()),
|
new NumericValue(stack.getCount()),
|
||||||
NBTSerializableValue.fromStack(stack, regs)
|
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)
|
public static Value of(Objective objective)
|
||||||
{
|
{
|
||||||
return ListValue.of(
|
return ListValue.of(
|
||||||
|
|||||||
@@ -151,7 +151,6 @@
|
|||||||
"CommandDispatcher_scarpetCommandsMixin",
|
"CommandDispatcher_scarpetCommandsMixin",
|
||||||
"FoodData_scarpetMixin",
|
"FoodData_scarpetMixin",
|
||||||
|
|
||||||
"RecipeManager_scarpetMixin",
|
|
||||||
"BlockInput_scarpetMixin",
|
"BlockInput_scarpetMixin",
|
||||||
"BlockPredicate_scarpetMixin",
|
"BlockPredicate_scarpetMixin",
|
||||||
"TagPredicate_scarpetMixin",
|
"TagPredicate_scarpetMixin",
|
||||||
|
|||||||
Reference in new issue
Block a user