增加me频道卡
This commit is contained in:
parent
39f89183e7
commit
45121b8647
|
|
@ -0,0 +1,63 @@
|
|||
package com.extendedae_plus.ae.items;
|
||||
|
||||
import appeng.items.materials.UpgradeCardItem;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 频道卡(MVP):仅存储一个 long 类型的频道号到 NBT:"channel"。
|
||||
* 继承 AE2 的 UpgradeCardItem 以复用升级卡判定与提示框架。
|
||||
*/
|
||||
public class ChannelCardItem extends UpgradeCardItem {
|
||||
public static final String TAG_CHANNEL = "channel";
|
||||
|
||||
public ChannelCardItem(Item.Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public static void setChannel(ItemStack stack, long channel) {
|
||||
CompoundTag tag = stack.getOrCreateTag();
|
||||
tag.putLong(TAG_CHANNEL, channel);
|
||||
}
|
||||
|
||||
public static long getChannel(ItemStack stack) {
|
||||
CompoundTag tag = stack.getTag();
|
||||
return tag != null && tag.contains(TAG_CHANNEL) ? tag.getLong(TAG_CHANNEL) : 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> lines, TooltipFlag flag) {
|
||||
super.appendHoverText(stack, level, lines, flag);
|
||||
long ch = getChannel(stack);
|
||||
if (ch == 0L) {
|
||||
lines.add(Component.translatable("item.extendedae_plus.channel_card.channel.unset"));
|
||||
} else {
|
||||
lines.add(Component.translatable("item.extendedae_plus.channel_card.channel", ch));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
|
||||
ItemStack stack = player.getItemInHand(hand);
|
||||
if (!level.isClientSide) {
|
||||
long ch = getChannel(stack);
|
||||
boolean dec = player.isShiftKeyDown();
|
||||
long next = dec ? Math.max(0L, ch - 1L) : ch + 1L;
|
||||
if (next != ch) {
|
||||
setChannel(stack, next);
|
||||
player.displayClientMessage(Component.translatable("item.extendedae_plus.channel_card.set", next), true);
|
||||
}
|
||||
}
|
||||
return InteractionResultHolder.sidedSuccess(stack, level.isClientSide);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.extendedae_plus.bridge;
|
||||
|
||||
/**
|
||||
* 非 mixin 包下的桥接接口,供 mixin 进行 instanceof 检测和回调。
|
||||
*/
|
||||
public interface InterfaceWirelessLinkBridge {
|
||||
void extendedae_plus$updateWirelessLink();
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import appeng.api.parts.PartModels;
|
|||
import appeng.items.parts.PartModelsHelper;
|
||||
import com.extendedae_plus.ExtendedAEPlus;
|
||||
import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem;
|
||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
||||
import com.extendedae_plus.ae.items.EntitySpeedTickerPartItem;
|
||||
import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
|
|
@ -76,6 +77,12 @@ public final class ModItems {
|
|||
"infinity_biginteger_cell", InfinityBigIntegerCellItem::new
|
||||
);
|
||||
|
||||
// 频道卡(作为 AE 升级卡使用)
|
||||
public static final RegistryObject<ChannelCardItem> CHANNEL_CARD = ITEMS.register(
|
||||
"channel_card",
|
||||
() -> new ChannelCardItem(new Item.Properties())
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 为 PartItem 注册 AE2 部件模型。
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
package com.extendedae_plus.init;
|
||||
|
||||
import appeng.api.upgrades.Upgrades;
|
||||
import appeng.core.definitions.AEBlocks;
|
||||
import appeng.core.definitions.AEItems;
|
||||
import appeng.core.definitions.AEParts;
|
||||
import appeng.core.localization.GuiText;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class UpgradeCards {
|
||||
public UpgradeCards(final FMLCommonSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
|
|
@ -12,6 +17,11 @@ public class UpgradeCards {
|
|||
Upgrades.add(AEItems.ENERGY_CARD, ModItems.ENTITY_TICKER_PART_ITEM.get(), 8, "group.entity_ticker.name");
|
||||
// 使用单一的 UpgradeCard Item 作为注册键,总共允许安装 4 张(不同等级由 ItemStack NBT 区分)
|
||||
Upgrades.add(ModItems.ENTITY_SPEED_CARD.get(), ModItems.ENTITY_TICKER_PART_ITEM.get(), 4, "group.entity_ticker.name");
|
||||
|
||||
// 新增:频道卡仅允许安装在 ME 接口(方块与部件)上,每台最多 1 张
|
||||
String interfaceGroup = GuiText.Interface.getTranslationKey();
|
||||
Upgrades.add(ModItems.CHANNEL_CARD.get(), AEBlocks.INTERFACE, 1, interfaceGroup);
|
||||
Upgrades.add(ModItems.CHANNEL_CARD.get(), AEParts.INTERFACE, 1, interfaceGroup);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package com.extendedae_plus.mixin.ae2.helpers;
|
||||
|
||||
import appeng.api.upgrades.IUpgradeInventory;
|
||||
import appeng.helpers.InterfaceLogic;
|
||||
import appeng.helpers.InterfaceLogicHost;
|
||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
||||
import com.extendedae_plus.init.ModItems;
|
||||
import com.extendedae_plus.wireless.IWirelessEndpoint;
|
||||
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
||||
import com.extendedae_plus.wireless.endpoint.InterfaceNodeEndpointImpl;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
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.callback.CallbackInfo;
|
||||
|
||||
@Mixin(InterfaceLogic.class)
|
||||
public abstract class InterfaceLogicChannelCardMixin implements InterfaceWirelessLinkBridge {
|
||||
|
||||
@Shadow(remap = false) public abstract IUpgradeInventory getUpgrades();
|
||||
|
||||
@Shadow(remap = false) public abstract appeng.api.networking.IGridNode getActionableNode();
|
||||
|
||||
@Shadow(remap = false) protected InterfaceLogicHost host;
|
||||
|
||||
@Unique
|
||||
private WirelessSlaveLink extendedae_plus$link;
|
||||
|
||||
@Inject(method = "onUpgradesChanged", at = @At("TAIL"), remap = false)
|
||||
private void extendedae_plus$onUpgradesChangedTail(CallbackInfo ci) {
|
||||
handleChannelCardChange();
|
||||
}
|
||||
|
||||
@Inject(method = "readFromNBT", at = @At("TAIL"), remap = false)
|
||||
private void extendedae_plus$afterReadNBT(net.minecraft.nbt.CompoundTag tag, CallbackInfo ci) {
|
||||
// 重载后根据卡状态恢复连接
|
||||
handleChannelCardChange();
|
||||
}
|
||||
|
||||
@Inject(method = "clearContent", at = @At("HEAD"), remap = false)
|
||||
private void extendedae_plus$onClearContent(CallbackInfo ci) {
|
||||
if (extendedae_plus$link != null) {
|
||||
extendedae_plus$link.onUnloadOrRemove();
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void handleChannelCardChange() {
|
||||
var inv = getUpgrades();
|
||||
long channel = 0L;
|
||||
for (ItemStack stack : inv) {
|
||||
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
|
||||
channel = ChannelCardItem.getChannel(stack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (extendedae_plus$link == null) {
|
||||
IWirelessEndpoint endpoint = new InterfaceNodeEndpointImpl(host, this::getActionableNode);
|
||||
extendedae_plus$link = new WirelessSlaveLink(endpoint);
|
||||
}
|
||||
extendedae_plus$link.setFrequency(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extendedae_plus$updateWirelessLink() {
|
||||
if (extendedae_plus$link != null) {
|
||||
extendedae_plus$link.updateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.extendedae_plus.bridge;
|
||||
|
||||
/**
|
||||
* 旧名兼容:已迁移到非 mixin 包,避免 Mixin 处理器禁止直接引用。
|
||||
*/
|
||||
public interface InterfaceLogicChannelLinkBridge {
|
||||
void extendedae_plus$updateWirelessLink();
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.extendedae_plus.mixin.ae2.helpers;
|
||||
|
||||
import appeng.helpers.InterfaceLogic;
|
||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
/**
|
||||
* 注入到 InterfaceLogic.Ticker 的每tick回调,驱动无线链接状态更新。
|
||||
*/
|
||||
@Mixin(targets = "appeng.helpers.InterfaceLogic$Ticker")
|
||||
public abstract class InterfaceLogicTickerMixin {
|
||||
|
||||
// Mixin 访问内部类的外部引用字段(javac 生成名 this$0)
|
||||
@Shadow(remap = false)
|
||||
@Final
|
||||
private InterfaceLogic this$0;
|
||||
|
||||
@Inject(method = "tickingRequest", at = @At("TAIL"), remap = false)
|
||||
private void extendedae_plus$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall,
|
||||
CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
|
||||
if (this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
||||
bridge.extendedae_plus$updateWirelessLink();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.extendedae_plus.wireless.endpoint;
|
||||
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.helpers.InterfaceLogicHost;
|
||||
import com.extendedae_plus.wireless.IWirelessEndpoint;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* IWirelessEndpoint 实现:基于 InterfaceLogicHost 与节点提供者。
|
||||
*/
|
||||
public class InterfaceNodeEndpointImpl implements IWirelessEndpoint {
|
||||
private final InterfaceLogicHost host;
|
||||
private final Supplier<IGridNode> nodeSupplier;
|
||||
|
||||
public InterfaceNodeEndpointImpl(InterfaceLogicHost host, Supplier<IGridNode> nodeSupplier) {
|
||||
this.host = Objects.requireNonNull(host);
|
||||
this.nodeSupplier = Objects.requireNonNull(nodeSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerLevel getServerLevel() {
|
||||
var be = host.getBlockEntity();
|
||||
if (be == null) return null;
|
||||
Level lvl = be.getLevel();
|
||||
return (lvl instanceof ServerLevel) ? (ServerLevel) lvl : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getBlockPos() {
|
||||
var be = host.getBlockEntity();
|
||||
return be != null ? be.getBlockPos() : BlockPos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGridNode getGridNode() {
|
||||
return nodeSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEndpointRemoved() {
|
||||
var be = host.getBlockEntity();
|
||||
return be == null || be.isRemoved();
|
||||
}
|
||||
}
|
||||
|
|
@ -87,5 +87,10 @@
|
|||
"config.extendedae_plus.option.entityTickerBlackList": "Entity Ticker Blacklist",
|
||||
"config.extendedae_plus.option.entityTickerMultipliers": "Entity Ticker Extra Consumption Multipliers",
|
||||
"config.extendedae_plus.option.craftingPauseThreshold": "AE synthesis calculation pause check threshold",
|
||||
"block.extendedae_plus.assembler_matrix_upload_core": "Assembler Matrix Upload Core"
|
||||
"block.extendedae_plus.assembler_matrix_upload_core": "Assembler Matrix Upload Core",
|
||||
|
||||
"item.extendedae_plus.channel_card": "Channel Card",
|
||||
"item.extendedae_plus.channel_card.channel": "Frequency: %s",
|
||||
"item.extendedae_plus.channel_card.channel.unset": "Frequency: Unset",
|
||||
"item.extendedae_plus.channel_card.set": "Frequency set to: %s"
|
||||
}
|
||||
|
|
@ -92,5 +92,10 @@
|
|||
"block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_success": "样板已上传到装配矩阵",
|
||||
"block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_not_crafting": "仅支持上传合成样板,处理样板将被忽略",
|
||||
"block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_no_matrix": "未在当前网络中找到已成型的装配矩阵",
|
||||
"block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_full": "装配矩阵的样板仓已满或无法插入"
|
||||
"block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_full": "装配矩阵的样板仓已满或无法插入",
|
||||
|
||||
"item.extendedae_plus.channel_card": "频道卡",
|
||||
"item.extendedae_plus.channel_card.channel": "频率:%s",
|
||||
"item.extendedae_plus.channel_card.channel.unset": "频率:未设置",
|
||||
"item.extendedae_plus.channel_card.set": "已设置频率:%s"
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "extendedae_plus:item/channel_card"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 455 B |
|
|
@ -67,7 +67,9 @@
|
|||
"extendedae.common.TileExPatternProviderMixin",
|
||||
"extendedae.container.ContainerExPatternProviderMixin",
|
||||
"extendedae.container.ContainerExPatternTerminalMixin",
|
||||
"extendedae.container.ContainerWirelessExPatternTerminalMixin"
|
||||
"extendedae.container.ContainerWirelessExPatternTerminalMixin",
|
||||
"ae2.helpers.InterfaceLogicChannelCardMixin",
|
||||
"ae2.helpers.InterfaceLogicTickerMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user