Skip to content

Commit

Permalink
Merge branch 'screen' of https://github.com/ch-yx/fabric-carpet into …
Browse files Browse the repository at this point in the history
…screen
  • Loading branch information
17183248569 committed Nov 17, 2023
2 parents 3ab4c32 + 38cd733 commit 642876a
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package carpet.mixins;

import net.minecraft.network.protocol.game.ServerboundContainerSlotStateChangedPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.world.inventory.CrafterMenu;
import net.minecraft.world.level.block.entity.CrafterBlockEntity;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ServerGamePacketListenerImpl.class)
public abstract class ServerGamePacketListenerImpl_scarpetCrafterScreen
{

@Shadow
public ServerPlayer player;

@Inject(method = "handleContainerSlotStateChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/CrafterMenu;getContainer()Lnet/minecraft/world/Container;"))

private void injected(ServerboundContainerSlotStateChangedPacket serverboundContainerSlotStateChangedPacket,CallbackInfo ci) {
CrafterMenu cm =(CrafterMenu)this.player.containerMenu;
if(!(cm.getContainer() instanceof CrafterBlockEntity)){
cm.setSlotState(serverboundContainerSlotStateChangedPacket.slotId(), serverboundContainerSlotStateChangedPacket.newState());
};
}
}
14 changes: 14 additions & 0 deletions src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static carpet.script.CarpetEventServer.Event.PLAYER_CHANGES_DIMENSION;
import static carpet.script.CarpetEventServer.Event.PLAYER_DIES;
import static carpet.script.CarpetEventServer.Event.PLAYER_FINISHED_USING_ITEM;
import static carpet.script.CarpetEventServer.Event.PLAYER_OPEN_SCREEN;
import static carpet.script.CarpetEventServer.Event.STATISTICS;

@Mixin(ServerPlayer.class)
Expand All @@ -45,6 +46,19 @@ public ServerPlayer_scarpetEventMixin(Level level, BlockPos blockPos, float f, G

@Shadow public boolean wonGame;

@Inject(method = "openMenu", at = @At("RETURN"))//"at return" so that the screen can be get by scarpet.
private void onOpenScreen(CallbackInfoReturnable<java.util.OptionalInt> cir)
{
if (cir.getReturnValue().isPresent()) {
PLAYER_OPEN_SCREEN.onPlayerEvent((ServerPlayer)(Object)this);
};
}
@Inject(method = "openHorseInventory", at = @At("RETURN"))//"at return" so that the screen can be get by scarpet.
private void onOpenScreen(CallbackInfo ci)
{
PLAYER_OPEN_SCREEN.onPlayerEvent((ServerPlayer)(Object)this);
}

@Redirect(method = "completeUsingItem", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/player/Player;completeUsingItem()V"
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/carpet/script/CarpetEventServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import carpet.script.value.ListValue;
import carpet.script.value.NBTSerializableValue;
import carpet.script.value.NumericValue;
import carpet.script.value.ScreenValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
Expand Down Expand Up @@ -853,6 +854,18 @@ public void onSlotSwitch(ServerPlayer player, int from, int to)
), player::createCommandSourceStack);
}
};
public static final Event PLAYER_OPEN_SCREEN = new Event("player_open_screen", 2, false)
{
@Override
public boolean onPlayerEvent(ServerPlayer player)
{
return handler.call(() ->
Arrays.asList(
new EntityValue(player)
, StringValue.of(ScreenValue.playerScreenTypeName(player))
), player::createCommandSourceStack);
}
};
public static final Event PLAYER_SWAPS_HANDS = new Event("player_swaps_hands", 1, false)
{
@Override
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/carpet/script/api/Inventories.java
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,27 @@ else if (owner instanceof LivingEntity livingEntity)
return new ScreenValue(player, type, name, function, c);
});

expression.addContextFunction("get_current_screen", -1, (c, t, lv) ->
{
if (lv.size() < 1)
{
throw new InternalExpressionException("'get_current_screen' requires at least 1 argument");
}
Value playerValue = lv.get(0);
ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), playerValue);
if (player == null)
{
throw new InternalExpressionException("'get_current_screen' requires a valid online player as the first argument.");
}
FunctionValue function = null;
if (lv.size() > 1)
{
function = FunctionArgument.findIn(c, expression.module, lv, 1, true, false).function;
}

return new ScreenValue(player, function, c);
});

expression.addContextFunction("close_screen", 1, (c, t, lv) ->
{
Value value = lv.get(0);
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/carpet/script/value/ScreenValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.OptionalInt;

import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
Expand All @@ -39,6 +40,7 @@
import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.inventory.ContainerListener;
import net.minecraft.world.inventory.CraftingMenu;
import net.minecraft.world.inventory.CrafterMenu;
import net.minecraft.world.inventory.DataSlot;
import net.minecraft.world.inventory.EnchantmentMenu;
import net.minecraft.world.inventory.FurnaceMenu;
Expand Down Expand Up @@ -101,6 +103,7 @@ public class ScreenValue extends Value
screenHandlerFactories.put("smithing", SmithingMenu::new);
screenHandlerFactories.put("smoker", SmokerMenu::new);
screenHandlerFactories.put("stonecutter", StonecutterMenu::new);
screenHandlerFactories.put("crafter_3x3", (x,y)->{var m =new CrafterMenu(x,y);m.addSlotListener(m);return m;});
}


Expand Down Expand Up @@ -130,6 +133,37 @@ public ScreenValue(ServerPlayer player, String type, Component name, @Nullable F
this.inventory = new ScreenHandlerInventory(this.screenHandler);
}

public ScreenValue(ServerPlayer player, @Nullable FunctionValue callback, Context c)
{
this.screenHandler = player.containerMenu;

this.name = null; //seems that the game forgot that. should i make something like a weak map to remember it?
this.typestring = playerScreenTypeName(player);

if (callback != null)
{
callback.checkArgs(4);
}
this.callback = callback;
this.hostname = c.host.getName();
this.scriptServer = (CarpetScriptServer) c.host.scriptServer();
this.player = player;

addListenerCallback(screenHandler);
this.inventory = new ScreenHandlerInventory(this.screenHandler);
}

public static String playerScreenTypeName(ServerPlayer player) {
if (!player.hasContainerOpen()) {
return "inventory";
}
try {
return ValueConversions.simplify(BuiltInRegistries.MENU.getKey(player.containerMenu.getType()));
} catch (java.lang.UnsupportedOperationException e) {
return "unknown";
}
}

private MenuProvider createScreenHandlerFactory()
{
if (!screenHandlerFactories.containsKey(this.typestring))
Expand Down Expand Up @@ -316,6 +350,17 @@ private DataSlot getProperty(String propertyName)
case "enchantment_level_3" -> getPropertyForType(EnchantmentMenu.class, "enchantment", 9, propertyName);
case "banner_pattern" -> getPropertyForType(LoomMenu.class, "loom", 0, propertyName);
case "stonecutter_recipe" -> getPropertyForType(StonecutterMenu.class, "stonecutter", 0, propertyName);
case "crafter_slot_disable_0" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 0, propertyName);
case "crafter_slot_disable_1" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 1, propertyName);
case "crafter_slot_disable_2" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 2, propertyName);
case "crafter_slot_disable_3" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 3, propertyName);
case "crafter_slot_disable_4" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 4, propertyName);
case "crafter_slot_disable_5" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 5, propertyName);
case "crafter_slot_disable_6" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 6, propertyName);
case "crafter_slot_disable_7" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 7, propertyName);
case "crafter_slot_disable_8" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 8, propertyName);
case "crafter_enable" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 9, propertyName);

default -> throw new InternalExpressionException("Invalid screen property: " + propertyName);
};

Expand Down
1 change: 1 addition & 0 deletions src/main/resources/carpet.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"Villager_aiMixin",
"Player_fakePlayersMixin",
"ServerGamePacketListenerImpl_coreMixin",
"ServerGamePacketListenerImpl_scarpetCrafterScreen",
"MinecraftServer_scarpetMixin",
"ExperienceOrb_xpNoCooldownMixin",
"Player_xpNoCooldownMixin",
Expand Down

0 comments on commit 642876a

Please sign in to comment.