Files
fabric-carpet/src/main/java/carpet/mixins/ScreenHandler_scarpetMixin.java
T
replaceitemandreplaceitem 3f6ddc43e5 Added screen handler system (#888)
* Added screen handler value

* Added screen handler constructor and function to show to player

* Made inventory_* functions work with screen handlers

* Event callbacks and some refactoring

* Exception if screen has no inventory

* Fixed NPE

* Close screen when null

* Added screen_property

* UNKNOWN_SCREEN throwable

* Fix error when not specifying click callback

* Access to non-container screen handler slots via the inventory_* functions

* Change lectern page

* Added button event

* Added 'close' event and refactoring callback

* Beacon and Brewing screens

* Cartography table screen

* Crafting screen

* Enchantment screen

* Grindstone

* Loom

* Merchant

* Shulkerbox

* Smithing table

* Stonecutter

* Use strings as screen type instead of ScreenHandlerType

* Remove support for multiple players

* Combining create_screen and open_screen and refactoring

* Allow modifying cursor stack

* Cleanup

* Docs

* Added multiple screen examples

* Rename to screen

* Added smoker and blast furnace

* Serialize screen content

* Store host name instead of context

* Add button value special cases to docs

* Spelling and grammar fixes by @James103

* Optimize screen inventory access

* Use -1 for slot click outside the screen

* As boolean, ScreenValue equals isOpen

* Revert "Use -1 for slot click outside the screen"

This reverts commit 68c113e71bb653191cedf4cc356ab7705838dc25.

* Rework of callback function

* Improve screen functionality with drop_item

* Editor keywords

* Only check syncId

* slot_update event callback

* Screem typo

* Mistake

* toTag returns "null" NBT for  closed screen

* Use null for slot index of -999

Co-authored-by: replaceitem <replaceitem.mc@gmail.com>
2022-01-12 22:52:38 +01:00

79 lines
3.3 KiB
Java

package carpet.mixins;
import carpet.fakes.ScreenHandlerInterface;
import carpet.script.value.ScreenValue;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.recipe.Recipe;
import net.minecraft.screen.Property;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerListener;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Final;
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;
import java.util.List;
@Mixin(ScreenHandler.class)
public abstract class ScreenHandler_scarpetMixin implements ScreenHandlerInterface
{
@Shadow @Final private List<ScreenHandlerListener> listeners;
@Shadow public abstract void syncState();
@Shadow @Final private List<Property> properties;
@Inject(method = "internalOnSlotClick", at = @At("HEAD"), cancellable = true)
private void callSlotClickListener(int slotIndex, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo ci) {
if(!(player instanceof ServerPlayerEntity serverPlayerEntity)) return;
for(ScreenHandlerListener screenHandlerListener : this.listeners) {
if(screenHandlerListener instanceof ScreenValue.ScarpetScreenHandlerListener scarpetScreenHandlerListener) {
if(scarpetScreenHandlerListener.onSlotClick(serverPlayerEntity, actionType, slotIndex, button)) {
ci.cancel();
syncState();
}
}
}
}
@Inject(method = "close", at = @At("HEAD"), cancellable = true)
private void callCloseListener(PlayerEntity player, CallbackInfo ci) {
if(!(player instanceof ServerPlayerEntity serverPlayerEntity)) return;
for(ScreenHandlerListener screenHandlerListener : this.listeners) {
if(screenHandlerListener instanceof ScreenValue.ScarpetScreenHandlerListener scarpetScreenHandlerListener) {
scarpetScreenHandlerListener.onClose(serverPlayerEntity);
}
}
}
@Override
public boolean callButtonClickListener(int button, PlayerEntity player) {
if(!(player instanceof ServerPlayerEntity serverPlayerEntity)) return false;
for(ScreenHandlerListener screenHandlerListener : listeners) {
if(screenHandlerListener instanceof ScreenValue.ScarpetScreenHandlerListener scarpetScreenHandlerListener) {
if(scarpetScreenHandlerListener.onButtonClick(serverPlayerEntity, button))
return true;
}
}
return false;
}
@Override
public boolean callSelectRecipeListener(ServerPlayerEntity player, Recipe<?> recipe, boolean craftAll) {
for(ScreenHandlerListener screenHandlerListener : listeners) {
if(screenHandlerListener instanceof ScreenValue.ScarpetScreenHandlerListener scarpetScreenHandlerListener) {
if(scarpetScreenHandlerListener.onSelectRecipe(player, recipe, craftAll))
return true;
}
}
return false;
}
@Override
public Property getProperty(int index) {
return this.properties.get(index);
}
}