Skip to content

Commit

Permalink
24w40a
Browse files Browse the repository at this point in the history
  • Loading branch information
gnembon committed Oct 4, 2024
1 parent 6144967 commit 3a66dd0
Show file tree
Hide file tree
Showing 17 changed files with 269 additions and 232 deletions.
10 changes: 3 additions & 7 deletions docs/scarpet/api/Inventories.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,15 @@ 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
* `['smelting', duration, xp]` - smelting/cooking recipes
* `['cutting']` - stonecutter recipe
* `['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
Expand All @@ -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)`

Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 0 additions & 17 deletions src/main/java/carpet/fakes/RecipeManagerInterface.java

This file was deleted.

234 changes: 140 additions & 94 deletions src/main/java/carpet/helpers/HopperCounter.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,7 +16,7 @@
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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,7 +16,7 @@
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);
}
Expand Down
55 changes: 0 additions & 55 deletions src/main/java/carpet/mixins/RecipeManager_scarpetMixin.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
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;
Expand Down Expand Up @@ -255,7 +256,11 @@ private void onRecipeSelectedInRecipeManager(ServerboundPlaceRecipePacket packet
{
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();
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
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;
Expand Down Expand Up @@ -86,20 +86,20 @@ private void onDeathEvent(DamageSource source, CallbackInfo ci)
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)
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/carpet/patches/EntityPlayerMPFake.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
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;
Expand All @@ -31,7 +31,7 @@
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;
Expand Down Expand Up @@ -84,7 +84,7 @@ public static boolean createFake(String username, MinecraftServer server, Vec3 p
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;
Expand Down Expand Up @@ -216,9 +216,9 @@ protected void checkFallDamage(double y, boolean onGround, BlockState state, Blo
}

@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);
Expand Down
52 changes: 34 additions & 18 deletions src/main/java/carpet/script/api/Inventories.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
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;
Expand Down Expand Up @@ -49,6 +49,7 @@
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
Expand Down Expand Up @@ -103,7 +104,7 @@ public static void apply(Expression expression)
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();
Expand All @@ -113,30 +114,44 @@ public static void apply(Expression expression)
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);
ingredientValue.add(ListValue.wrap(alternatives));
});
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)
Expand All @@ -155,8 +170,8 @@ else if (recipe instanceof AbstractCookingRecipe abstractCookingRecipe)
{
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)
Expand All @@ -172,7 +187,7 @@ else if (recipe instanceof CustomRecipe)
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);
});
Expand All @@ -181,10 +196,11 @@ else if (recipe instanceof CustomRecipe)
{
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) ->
Expand Down
9 changes: 2 additions & 7 deletions src/main/java/carpet/script/command/CommandArgument.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
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;
Expand Down Expand Up @@ -204,12 +203,8 @@ public static CommandSyntaxException error(String text)

// 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)
),
Expand Down
Loading

0 comments on commit 3a66dd0

Please sign in to comment.