forked from RubixDev/Inventorio
-
Notifications
You must be signed in to change notification settings - Fork 1
/
PlayerEntityMixin.java
154 lines (140 loc) · 6.15 KB
/
PlayerEntityMixin.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package me.lizardofoz.inventorio.mixin;
import com.mojang.authlib.GameProfile;
import me.lizardofoz.inventorio.player.InventorioScreenHandler;
import me.lizardofoz.inventorio.player.PlayerAddonSerializer;
import me.lizardofoz.inventorio.player.PlayerInventoryAddon;
import me.lizardofoz.inventorio.util.MixinHelpers;
import me.lizardofoz.inventorio.util.PlayerDuck;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.encryption.PlayerPublicKey;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerEntity.class)
public abstract class PlayerEntityMixin implements PlayerDuck
{
@Shadow public abstract PlayerInventory getInventory();
@Unique public PlayerInventoryAddon inventorioAddon;
@Inject(method = "<init>", at = @At(value = "RETURN"))
private void inventorioCreateAddon(World world, BlockPos pos, float yaw, GameProfile gameProfile, PlayerPublicKey publicKey, CallbackInfo ci)
{
PlayerEntity thisPlayer = (PlayerEntity) (Object) this;
inventorioAddon = new PlayerInventoryAddon(thisPlayer);
}
/**
* This inject causes the selected UtilityBelt item to be displayed in the offhand
*/
@Inject(method = "getEquippedStack", at = @At(value = "HEAD"), cancellable = true)
private void inventorioDisplayOffhand(EquipmentSlot slot, CallbackInfoReturnable<ItemStack> cir)
{
if (slot == EquipmentSlot.OFFHAND)
cir.setReturnValue(inventorioAddon.getDisplayedOffHandStack());
}
/**
* These 2 mixins govern the custom behavior of displaying items in both hands.
* First, the offhand is attached to the utility belt, rather than a vanilla slot.
* Second, a player can swap the main hand and the offhand.
*/
@Redirect(method = "equipStack",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/util/collection/DefaultedList;set(ILjava/lang/Object;)Ljava/lang/Object;",
ordinal = 0))
private <E> E inventorioEquipMainHand(DefaultedList<E> defaultedList, int index, E stack)
{
ItemStack itemStack = (ItemStack) stack;
if (inventorioAddon.getSwappedHands())
inventorioAddon.setSelectedUtilityStack(itemStack);
else
getInventory().main.set(getInventory().selectedSlot, itemStack);
return (E) ItemStack.EMPTY;
}
@Redirect(method = "equipStack",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/util/collection/DefaultedList;set(ILjava/lang/Object;)Ljava/lang/Object;",
ordinal = 1))
private <E> E inventorioEquipOffhand(DefaultedList<E> defaultedList, int index, E stack)
{
ItemStack itemStack = (ItemStack) stack;
if (inventorioAddon.getSwappedHands())
inventorioAddon.setSelectedHotbarStack(itemStack);
else
inventorioAddon.setSelectedUtilityStack(itemStack);
return (E) ItemStack.EMPTY;
}
/**
* This mixin refreshes the available slots when we equip armor through right clicking or a dispenser
*/
@Inject(method = "equipStack", at = @At(value = "RETURN"))
private void inventorioOnEquipArmor(EquipmentSlot slot, ItemStack stack, CallbackInfo ci)
{
if (slot.getType() == EquipmentSlot.Type.ARMOR)
MixinHelpers.withScreenHandler((PlayerEntity) (Object) this, InventorioScreenHandler::updateDeepPocketsCapacity);
}
/**
* This mixin allows arrows stored in the addon slots to be used by a bow
*/
@Inject(method = "getArrowType", at = @At(value = "RETURN"), cancellable = true)
private void inventorioGetArrowType(ItemStack bowStack, CallbackInfoReturnable<ItemStack> cir)
{
if (!cir.getReturnValue().isEmpty())
return;
ItemStack arrowStack = inventorioAddon.getActiveArrowType(bowStack);
if (arrowStack != null)
cir.setReturnValue(arrowStack);
}
/**
* These 2 injects cause a correct weapon to be automatically selected and withdrawn upon attack
*/
@Inject(method = "attack", at = @At(value = "HEAD"))
private void inventorioPreAttack(Entity target, CallbackInfo ci)
{
if (target.isAttackable())
inventorioAddon.prePlayerAttack();
}
@Inject(method = "attack", at = @At(value = "RETURN"))
private void inventorioPostAttack(Entity target, CallbackInfo ci)
{
if (target.isAttackable())
inventorioAddon.postPlayerAttack();
}
/**
* These 2 injects read and write additional data into Player's NBT
*/
@Inject(method = "readCustomDataFromNbt", at = @At(value = "RETURN"))
private void inventorioDeserializePlayerAddon(NbtCompound tag, CallbackInfo ci)
{
PlayerAddonSerializer.INSTANCE.deserialize(inventorioAddon, tag.getCompound("Inventorio"));
}
@Inject(method = "writeCustomDataToNbt", at = @At(value = "RETURN"))
private void inventorioSerializePlayerAddon(NbtCompound tag, CallbackInfo ci)
{
NbtCompound inventorioTag = new NbtCompound();
PlayerAddonSerializer.INSTANCE.serialize(inventorioAddon, inventorioTag);
tag.put("Inventorio", inventorioTag);
}
@Inject(method = "tickMovement", at = @At(value = "RETURN"))
private void inventorioEmptyMainHandDisplayTool(CallbackInfo ci)
{
inventorioAddon.tick();
}
@Nullable
@Override
public PlayerInventoryAddon getInventorioAddon()
{
return inventorioAddon;
}
}