位于common: trou/arch/item/ItemExpContainer.java
public static void raiseMode(ItemStack stack, int value) {
if (!(stack.getItem() instanceof ItemExpContainer)) return;
CompoundTag tag = stack.hasTag() ? stack.getTag() : new CompoundTag();
assert tag != null;
int newValue = Math.max(tag.getInt("mode") + value, 0); // 限制不为负
tag.putInt("mode", newValue);
}
位于common: trou/arch/item/ItemExpContainer.java
@Override
public InteractionResultHolder<ItemStack> use(@NotNull Level level, @NotNull Player player, @NotNull InteractionHand usedHand) {
ItemStack stack = player.getItemInHand(usedHand);
if (level.isClientSide || usedHand == InteractionHand.OFF_HAND) return InteractionResultHolder.fail(stack);
CompoundTag tag = stack.hasTag() ? stack.getTag() : new CompoundTag();
assert tag != null;
int mode = tag.getInt("mode");
if (player.isShiftKeyDown()) {
int storedExp = tag.getInt("exp");
int amount = Math.min(mode, storedExp);
player.giveExperiencePoints(amount);
tag.putInt("exp", storedExp - amount);
} else {
int ownedExp = player.totalExperience;
int cost = Math.min(ownedExp, mode);
player.giveExperiencePoints(-cost);
tag.putInt("exp", tag.getInt("exp") + cost);
}
stack.setTag(tag);
return InteractionResultHolder.sidedSuccess(stack, level.isClientSide());
}
位于common: trou/arch/item/ItemExpContainer.java
public static void appendTooltip(ItemStack stack, List<Component> lines, TooltipFlag flag) {
if (stack.getItem() instanceof ItemExpContainer) {
CompoundTag tag = stack.hasTag() ? stack.getTag() : new CompoundTag();
assert tag != null;
lines.add(new TranslatableComponent("tooltip.exp_container", tag.getInt("exp")));
lines.add(new TranslatableComponent("tooltip.exp_container_mode", tag.getInt("mode")));
}
}
位于common: trou/arch/object/ModEvents.java
public class ModEvents {
public static void register() {
ClientTooltipEvent.ITEM.register(ItemExpContainer::appendTooltip);
ClientRawInputEvent.MOUSE_SCROLLED.register(ItemExpContainer::mouseScroll);
}
}
位于common: trou/arch/item/ItemExpContainer.java
// 向上滚动 v = 1.0 向下滚动 v = -1.0
public static EventResult mouseScroll(Minecraft minecraft, double v) {
assert minecraft.player != null; // 断定minecraft.player不为空
ItemStack heldItem = minecraft.player.getItemInHand(InteractionHand.MAIN_HAND);
if (heldItem.getItem() instanceof ItemExpContainer) {
if (minecraft.player.isShiftKeyDown()) {
ModPackets.sendExpContainerMousePacket((int) v);
return EventResult.interruptFalse();
}
}
return EventResult.pass();
}
位于common: trou/arch/network/MessageThrowExp.java
public class MessageThrowExp {
public final UUID targetPlayerUUID;
// 收到消息时, 会调用这个方法来从buf中取出数据
public MessageThrowExp(FriendlyByteBuf buf) {
this(buf.readUUID());
}
// 创建消息时提供数据的构造器
public MessageThrowExp(UUID targetPlayerUUID) {
this.targetPlayerUUID = targetPlayerUUID;
}
// 发送消息时将数据写入buf的方法
public void encode(FriendlyByteBuf buf) {
buf.writeUUID(targetPlayerUUID);
}
// 收到消息后, 调用的处理事件
public void apply(Supplier<NetworkManager.PacketContext> contextSupplier) {
Player self = contextSupplier.get().getPlayer();
Player target = self.level.getPlayerByUUID(targetPlayerUUID);
if (target == null) return;
ItemStack stack = self.getItemInHand(InteractionHand.MAIN_HAND);
ItemExpContainer.doThrow(stack, target);
}
}
位于common: trou/arch/network/ModChannels.java
public class ModChannels {
public static final NetworkChannel CHANNEL = NetworkChannel.create(new ResourceLocation("arch", "exp_container"));
public static void register() {
CHANNEL.register(MessageThrowExp.class, MessageThrowExp::encode, MessageThrowExp::new, MessageThrowExp::apply);
}
}
位于common: trou/arch/item/ItemExpContainer.java
public static void doThrow(ItemStack stack, Player target) {
if (!(stack.getItem() instanceof ItemExpContainer)) return;
CompoundTag tag = stack.hasTag() ? stack.getTag() : new CompoundTag();
assert tag != null;
int storedExp = tag.getInt("exp");
int mode = tag.getInt("mode");
int amount = Math.min(mode, storedExp);
target.giveExperiencePoints(amount);
tag.putInt("exp", storedExp - amount);
}
位于common: trou/arch/client/ModKeys.java
public class ModKeys {
public static final KeyMapping THROW_EXP = new KeyMapping("key.arch.throw_exp", InputConstants.Type.KEYSYM, InputConstants.KEY_Z, "category.arch");
public static void register() {
KeyMappingRegistry.register(THROW_EXP);
}
}
位于common: trou/arch/object/ModEvents.java
public class ModEvents {
public static void register() {
...
ClientTickEvent.CLIENT_POST.register(ModKeys::handleThrowExpKey);
}
}
位于位于common: trou/arch/client/ModKeys.java
public static void handleThrowExpKey(Minecraft minecraft) {
while (THROW_EXP.consumeClick()) {
if (minecraft.player == null) return;
// minecraft.crosshairPickEntity 可以获取到玩家光标瞄准的实体
if (minecraft.crosshairPickEntity instanceof Player) {
UUID playerUUID = minecraft.crosshairPickEntity.getUUID();
// Channel提供了发送Message的几个方法
// 这里使用了我们创建的Message的构造器来提供playerUUID数据
ModChannels.CHANNEL.sendToServer(new MessageThrowExp(playerUUID));
}
}
}
位于common: trou/arch/Arch.java
public class Arch {
public static final String MOD_ID = "arch";
public static void init() {
System.out.println("Hello Architectury!");
Storyteller.tellStory();
ModItems.register();
ModKeys.register();
ModEvents.register();
ModPackets.register();
ModChannels.register();
}
}