feat: 添加实体加速卡替换加速卡
This commit is contained in:
parent
e697552b6b
commit
fb2a2a831d
|
|
@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G
|
|||
loom.platform = forge
|
||||
|
||||
# Mod properties
|
||||
mod_version = 1.4.1
|
||||
mod_version = 1.4.1-entitySpeedTicker
|
||||
maven_group = com.extendedae_plus
|
||||
archives_name = extendedae_plus
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ public class ExtendedAEPlus {
|
|||
public ExtendedAEPlus() {
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
// 在客户端尽早注册内置模型,保证首次资源加载前映射已建立(仿照 AE2 的 AppEngClient 构造期注册)
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientRegistrar::initBuiltInModels);
|
||||
// 客户端的内置模型注册将在客户端事件阶段执行(见 ClientModEvents),不要在构造器中提前执行
|
||||
|
||||
// 注册mod初始化事件
|
||||
modEventBus.addListener(this::commonSetup);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
package com.extendedae_plus.ae.definitions.upgrades;
|
||||
|
||||
import appeng.items.materials.UpgradeCardItem;
|
||||
import com.extendedae_plus.init.ModItems;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单一的实体加速卡 Item,通过 ItemStack 的 NBT 存储 exponent(0/1/2/3)来区分等级
|
||||
*/
|
||||
public class EntitySpeedCardItem extends UpgradeCardItem {
|
||||
public static final String NBT_MULTIPLIER = "EAS:mult";
|
||||
|
||||
public EntitySpeedCardItem(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
public static ItemStack withMultiplier(int multiplier) {
|
||||
ItemStack s = new ItemStack(ModItems.ENTITY_SPEED_CARD.get());
|
||||
CompoundTag t = s.getOrCreateTag();
|
||||
t.putInt(NBT_MULTIPLIER, multiplier);
|
||||
s.setTag(t);
|
||||
return s;
|
||||
}
|
||||
|
||||
public static int readMultiplier(ItemStack stack) {
|
||||
if (stack == null || stack.isEmpty()) return 1;
|
||||
CompoundTag t = stack.getTag();
|
||||
if (t == null) return 1;
|
||||
int v = t.getInt(NBT_MULTIPLIER);
|
||||
return v <= 0 ? 1 : v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component getName(@NotNull ItemStack stack) {
|
||||
int mult = readMultiplier(stack);
|
||||
String key;
|
||||
switch (mult) {
|
||||
case 2 -> key = "item." + com.extendedae_plus.ExtendedAEPlus.MODID + ".entity_speed_card.x2";
|
||||
case 4 -> key = "item." + com.extendedae_plus.ExtendedAEPlus.MODID + ".entity_speed_card.x4";
|
||||
case 8 -> key = "item." + com.extendedae_plus.ExtendedAEPlus.MODID + ".entity_speed_card.x8";
|
||||
case 16 -> key = "item." + com.extendedae_plus.ExtendedAEPlus.MODID + ".entity_speed_card.x16";
|
||||
default -> key = "item." + com.extendedae_plus.ExtendedAEPlus.MODID + ".entity_speed_card.x1";
|
||||
}
|
||||
return Component.translatable(key);
|
||||
}
|
||||
|
||||
|
||||
public List<Component> getTooltipLines(ItemStack stack) {
|
||||
int mult = readMultiplier(stack);
|
||||
long cap = 1L;
|
||||
switch (mult) {
|
||||
case 16 -> cap = 1024L;
|
||||
case 8 -> cap = 256L;
|
||||
case 4 -> cap = 64L;
|
||||
case 2 -> cap = 8L;
|
||||
}
|
||||
MutableComponent line1 = Component.translatable("tooltip." + com.extendedae_plus.ExtendedAEPlus.MODID + ".entity_speed_card.multiplier", "x" + mult);
|
||||
MutableComponent line2 = Component.translatable("tooltip." + com.extendedae_plus.ExtendedAEPlus.MODID + ".entity_speed_card.max", cap);
|
||||
return List.of(line1, line2);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Override
|
||||
public void appendHoverText(ItemStack stack, Level level, List<Component> lines, TooltipFlag flag) {
|
||||
super.appendHoverText(stack, level, lines, flag);
|
||||
// add our custom tooltip lines (multiplier and max)
|
||||
lines.addAll(this.getTooltipLines(stack));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -7,8 +7,10 @@ import appeng.menu.slot.OptionalFakeSlot;
|
|||
import com.extendedae_plus.ae.parts.EntitySpeedTickerPart;
|
||||
import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen;
|
||||
import com.extendedae_plus.config.ModConfigs;
|
||||
import com.extendedae_plus.init.ModItems;
|
||||
import com.extendedae_plus.init.ModMenuTypes;
|
||||
import com.extendedae_plus.util.ConfigParsingUtils;
|
||||
import com.extendedae_plus.util.PowerUtils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
|
@ -16,16 +18,15 @@ import net.minecraftforge.registries.ForgeRegistries;
|
|||
|
||||
// 实体加速器菜单,负责与客户端界面同步数据
|
||||
public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart> {
|
||||
// 已安装的速度卡数量
|
||||
public int speedCardCount;
|
||||
@GuiSync(716) public boolean accelerateEnabled = true;
|
||||
// 已安装的实体加速卡数量(用于能耗计算)
|
||||
@GuiSync(717) public int entitySpeedCardCount;
|
||||
// 已安装的能量卡数量
|
||||
public int energyCardCount;
|
||||
// 当前生效的倍率(从配置中读取并同步)
|
||||
public double multiplier = 1.0;
|
||||
|
||||
@GuiSync(716)
|
||||
public boolean accelerateEnabled = true;
|
||||
|
||||
@GuiSync(718) public int energyCardCount;
|
||||
// 当前生效的配置倍率(从配置中读取并同步)
|
||||
// 当前计算出的生效速度(product of multipliers),同步给客户端用于显示
|
||||
@GuiSync(719) public int effectiveSpeed = 1;
|
||||
@GuiSync(720) public double multiplier = 1.0;
|
||||
|
||||
public boolean getAccelerateEnabled() {
|
||||
return this.accelerateEnabled;
|
||||
|
|
@ -51,8 +52,8 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
|
|||
@Override
|
||||
public void onServerDataSync() {
|
||||
super.onServerDataSync();
|
||||
// 重新统计速度卡和能量卡数量
|
||||
this.speedCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.SPEED_CARD);
|
||||
// 重新统计实体加速卡和能量卡数量
|
||||
this.entitySpeedCardCount = this.getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get());
|
||||
this.energyCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD);
|
||||
|
||||
// 计算当前面向方块的倍率(服务器端),并同步给客户端
|
||||
|
|
@ -70,6 +71,9 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
|
|||
} catch (Exception ignored) {}
|
||||
this.multiplier = mult;
|
||||
|
||||
// 计算生效速度:使用工具类从菜单直接计算 product with cap(最多 8 张)
|
||||
this.effectiveSpeed = (int) PowerUtils.computeProductWithCapFromMenu(this, 8);
|
||||
|
||||
// 如果在客户端,刷新界面
|
||||
if (isClientSide()) {
|
||||
if (Minecraft.getInstance().screen instanceof EntitySpeedTickerScreen screen) {
|
||||
|
|
@ -84,8 +88,10 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
|
|||
super.onSlotChange(slot);
|
||||
// 客户端重新统计卡数量并刷新界面
|
||||
if (isClientSide()) {
|
||||
this.speedCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.SPEED_CARD);
|
||||
this.entitySpeedCardCount = this.getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get());
|
||||
this.energyCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD);
|
||||
// 立即在客户端计算生效速度以便界面即时反馈(使用与服务端相同的工具方法,最多 8 张卡)
|
||||
this.effectiveSpeed = (int) PowerUtils.computeProductWithCapFromMenu(this, 8);
|
||||
if (Minecraft.getInstance().screen instanceof EntitySpeedTickerScreen screen) {
|
||||
screen.refreshGui();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import appeng.parts.automation.UpgradeablePart;
|
|||
import com.extendedae_plus.ExtendedAEPlus;
|
||||
import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu;
|
||||
import com.extendedae_plus.config.ModConfigs;
|
||||
import com.extendedae_plus.init.ModItems;
|
||||
import com.extendedae_plus.init.ModMenuTypes;
|
||||
import com.extendedae_plus.util.ConfigParsingUtils;
|
||||
import com.extendedae_plus.util.PowerUtils;
|
||||
|
|
@ -209,18 +210,22 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
|||
.getTicker(this.getLevel(), (BlockEntityType<T>) blockEntity.getType());
|
||||
if (blockEntityTicker == null) return;
|
||||
|
||||
int speedCardCount = getUpgrades().getInstalledUpgrades(AEItems.SPEED_CARD);
|
||||
// 使用集中定义的 CardDef 列表,支持以后添加等级或改倍率而无需修改此逻辑
|
||||
int energyCardCount = getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD);
|
||||
|
||||
// 计算本次 tick 所需能量
|
||||
// - 基础消耗为 512
|
||||
// - 加速卡的数量对能耗有分段增长:
|
||||
// 0: 无增长
|
||||
// 1: 翻倍
|
||||
// 2-6: 指数增长(较快)
|
||||
// 7-8: 幂级数增长(极高)
|
||||
// 使用工具类统一计算增长因子与原始功耗,并从网络中抽取对应能量
|
||||
double requiredPower = PowerUtils.getFinalPower(speedCardCount, energyCardCount);
|
||||
// 使用已注册的单一 Item 计算已安装卡数量(总计,用于能耗计算)
|
||||
int entitySpeedCardCount = getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get());
|
||||
|
||||
// 使用工具方法从槽位直接计算乘积并应用 cap(最多 8 张卡)
|
||||
long product = PowerUtils.computeProductWithCapFromStacks(this.getUpgrades(), 8);
|
||||
|
||||
// 如果没有任何实体加速卡,则不进行加速且不消耗额外能量(只保留部件的被动功耗)
|
||||
if (entitySpeedCardCount <= 0) return;
|
||||
|
||||
// 计算本次 tick 所需能量:使用工具类根据 product 计算最终能耗
|
||||
double requiredPower = PowerUtils.computeFinalPowerForProduct(product, energyCardCount);
|
||||
|
||||
int speed = (int) product;
|
||||
|
||||
double multiplier = 1.0;
|
||||
for (ConfigParsingUtils.MultiplierEntry me : ConfigParsingUtils.getCachedMultiplierEntries(ModConfigs.EntitySpeedTickerMultipliers.get())) {
|
||||
|
|
@ -241,7 +246,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
|||
if (extractedPower < requiredPower) return;
|
||||
|
||||
// 计算加速倍数:基于 2 的次方,并把 8 张映射到最大 1024x(2^10)
|
||||
int speed = PowerUtils.getSpeedMultiplier(speedCardCount);
|
||||
// 已由 product 计算得到 speed;上面已在没有卡时提前返回
|
||||
|
||||
// 执行 tick 操作
|
||||
for (int i = 0; i < speed - 1; i++) {
|
||||
|
|
|
|||
|
|
@ -76,15 +76,14 @@ public class EntitySpeedTickerScreen<C extends EntitySpeedTickerMenu> extends Up
|
|||
}
|
||||
|
||||
private void textData() {
|
||||
int speedCardCount = getMenu().speedCardCount;
|
||||
int energyCardCount = getMenu().energyCardCount;
|
||||
double multiplier = getMenu().multiplier;
|
||||
int effectiveSpeed = getMenu().effectiveSpeed;
|
||||
|
||||
double finalPower = PowerUtils.getFinalPower(speedCardCount, energyCardCount);
|
||||
int speed = PowerUtils.getSpeedMultiplier(speedCardCount);
|
||||
double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount);
|
||||
double remainingRatio = PowerUtils.getRemainingRatio(energyCardCount);
|
||||
|
||||
setTextContent("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", speed));
|
||||
setTextContent("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", effectiveSpeed));
|
||||
setTextContent("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(finalPower, false)));
|
||||
setTextContent("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(remainingRatio)));
|
||||
setTextContent("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", multiplier)));
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ package com.extendedae_plus.client;
|
|||
import appeng.client.render.crafting.CraftingCubeModel;
|
||||
import appeng.init.client.InitScreens;
|
||||
import com.extendedae_plus.ExtendedAEPlus;
|
||||
import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem;
|
||||
import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu;
|
||||
import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen;
|
||||
import com.extendedae_plus.client.render.crafting.EPlusCraftingCubeModelProvider;
|
||||
import com.extendedae_plus.client.screen.GlobalProviderModesScreen;
|
||||
import com.extendedae_plus.content.crafting.EPlusCraftingUnitType;
|
||||
import com.extendedae_plus.hooks.BuiltInModelHooks;
|
||||
import com.extendedae_plus.init.ModItems;
|
||||
import com.extendedae_plus.init.ModMenuTypes;
|
||||
import net.minecraft.client.gui.screens.MenuScreens;
|
||||
import net.minecraft.client.renderer.item.ItemProperties;
|
||||
import net.minecraftforge.client.ConfigScreenHandler;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
|
||||
|
|
@ -28,6 +31,9 @@ public final class ClientRegistrar {
|
|||
public static void initBuiltInModels() {
|
||||
if (REGISTERED) return;
|
||||
REGISTERED = true;
|
||||
// 注册 Item property,用于根据 ItemStack 的 NBT exponent 切换模型
|
||||
ItemProperties.register(ModItems.ENTITY_SPEED_CARD.get(), ExtendedAEPlus.id("mult"),
|
||||
(stack, world, entity, seed) -> (float) EntitySpeedCardItem.readMultiplier(stack));
|
||||
// 注册四种形成态模型为内置模型
|
||||
BuiltInModelHooks.addBuiltInModel(
|
||||
ExtendedAEPlus.id("block/crafting/4x_accelerator_formed_v2"),
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ public final class ModCreativeTabs {
|
|||
output.accept(ModItems.ACCELERATOR_256x.get());
|
||||
output.accept(ModItems.ACCELERATOR_1024x.get());
|
||||
output.accept(ModItems.ENTITY_TICKER_PART_ITEM.get());
|
||||
|
||||
// 放入四个预设的 stacks(x2,x4,x8,x16),使用 ModItems 工厂创建
|
||||
output.accept(ModItems.createEntitySpeedCardStack(2));
|
||||
output.accept(ModItems.createEntitySpeedCardStack(4));
|
||||
output.accept(ModItems.createEntitySpeedCardStack(8));
|
||||
output.accept(ModItems.createEntitySpeedCardStack(16));
|
||||
})
|
||||
.build());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import appeng.api.parts.IPart;
|
|||
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.EntitySpeedTickerPartItem;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
|
@ -52,9 +53,17 @@ public final class ModItems {
|
|||
() -> new BlockItem(ModBlocks.ACCELERATOR_1024x.get(), new Item.Properties())
|
||||
);
|
||||
|
||||
public static final RegistryObject<EntitySpeedTickerPartItem> ENTITY_TICKER_PART_ITEM =
|
||||
ITEMS.register("entity_speed_ticker",
|
||||
() -> new EntitySpeedTickerPartItem(new Item.Properties()));
|
||||
public static final RegistryObject<EntitySpeedTickerPartItem> ENTITY_TICKER_PART_ITEM = ITEMS.register(
|
||||
"entity_speed_ticker",
|
||||
() -> new EntitySpeedTickerPartItem(new Item.Properties())
|
||||
);
|
||||
|
||||
// AE Upgrade Cards: 实体加速卡(四个等级:x2,x4,x8,x16)
|
||||
// 单一实体加速卡 Item(不同等级由 ItemStack.nbt 存储)
|
||||
public static final RegistryObject<EntitySpeedCardItem> ENTITY_SPEED_CARD = ITEMS.register(
|
||||
"entity_speed_card",
|
||||
() -> new EntitySpeedCardItem(new Item.Properties())
|
||||
);
|
||||
|
||||
/**
|
||||
* 为 PartItem 注册 AE2 部件模型。
|
||||
|
|
@ -67,4 +76,11 @@ public final class ModItems {
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 工厂:创建带 multiplier 的实体加速卡 ItemStack(2/4/8/16)
|
||||
*/
|
||||
public static net.minecraft.world.item.ItemStack createEntitySpeedCardStack(int multiplier) {
|
||||
return EntitySpeedCardItem.withMultiplier(multiplier);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@ import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
|||
public class UpgradeCards {
|
||||
public UpgradeCards(final FMLCommonSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
Upgrades.add(AEItems.SPEED_CARD, ModItems.ENTITY_TICKER_PART_ITEM.get(), 8, "group.entity_ticker.name");
|
||||
// 现有:把 Entity Ticker 的部件注册为处理 SPEED/ENERGY 卡的宿主
|
||||
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");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.extendedae_plus.util;
|
||||
|
||||
import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem;
|
||||
import com.extendedae_plus.config.ModConfigs;
|
||||
|
||||
/**
|
||||
|
|
@ -7,23 +8,111 @@ import com.extendedae_plus.config.ModConfigs;
|
|||
*/
|
||||
public final class PowerUtils {
|
||||
private PowerUtils() {}
|
||||
|
||||
// ---- 重构后的 API ----
|
||||
/**
|
||||
* 计算加速卡数量对应的加速倍率(返回 2 的幂次方)
|
||||
* 0 张卡 = 1x,8 张卡 = 1024x
|
||||
* 将 card multipliers(按插槽序)计算乘积并应用 cap 规则(见 capForHighestMultiplier)
|
||||
* @param multipliers iterable of per-card multipliers
|
||||
* @param maxCards 最多计入的卡数
|
||||
* @return 被 cap 约束后的乘积
|
||||
*/
|
||||
public static int getSpeedMultiplier(int speedCardCount) {
|
||||
if (speedCardCount <= 0) return 1;
|
||||
// 线性映射 0~8 -> 0~10,最大 2^10=1024
|
||||
int exponent = (int) Math.round((10.0 / 8.0) * speedCardCount);
|
||||
exponent = Math.min(exponent, 10);
|
||||
return (int) Math.pow(2, exponent);
|
||||
public static long computeProductWithCap(Iterable<Integer> multipliers, int maxCards) {
|
||||
long product = 1L;
|
||||
int considered = 0;
|
||||
int highest = 1;
|
||||
for (Integer m : multipliers) {
|
||||
if (m == null) continue;
|
||||
if (considered >= maxCards) break;
|
||||
int mult = m.intValue();
|
||||
if (mult <= 0) mult = 1;
|
||||
product *= mult;
|
||||
highest = Math.max(highest, mult);
|
||||
considered++;
|
||||
}
|
||||
long cap = capForHighestMultiplier(highest);
|
||||
return Math.min(product, cap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算加速卡数量对应的能耗增长因子
|
||||
* 0: 1x,1: 2x,2-6: 2^(2*count),7-8: 2^(3*count)
|
||||
* 根据最高单卡 multiplier 返回 cap 值
|
||||
*/
|
||||
public static long capForHighestMultiplier(int highestMultiplier) {
|
||||
if (highestMultiplier >= 16) return 1024L;
|
||||
if (highestMultiplier >= 8) return 256L;
|
||||
if (highestMultiplier >= 4) return 64L;
|
||||
if (highestMultiplier >= 2) return 8L;
|
||||
return 1L;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从菜单对象读取前 maxCards 个加速卡的 multiplier 并计算 product with cap
|
||||
*/
|
||||
public static long computeProductWithCapFromMenu(appeng.menu.implementations.UpgradeableMenu<?> menu, int maxCards) {
|
||||
java.util.List<Integer> list = new java.util.ArrayList<>();
|
||||
int considered = 0;
|
||||
for (var stack : menu.getUpgrades()) {
|
||||
if (considered >= maxCards) break;
|
||||
if (stack != null && !stack.isEmpty() && stack.getItem() instanceof EntitySpeedCardItem) {
|
||||
int multVal = EntitySpeedCardItem.readMultiplier(stack);
|
||||
int count = Math.min(stack.getCount(), maxCards - considered);
|
||||
for (int i = 0; i < count; i++) {
|
||||
list.add(multVal);
|
||||
considered++;
|
||||
if (considered >= maxCards) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return computeProductWithCap(list, maxCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从一组 ItemStack(升级槽)直接计算 product with cap(最多 maxCards)
|
||||
*/
|
||||
public static long computeProductWithCapFromStacks(Iterable<net.minecraft.world.item.ItemStack> stacks, int maxCards) {
|
||||
java.util.List<Integer> list = new java.util.ArrayList<>();
|
||||
int considered = 0;
|
||||
for (var stack : stacks) {
|
||||
if (considered >= maxCards) break;
|
||||
if (stack != null && !stack.isEmpty() && stack.getItem() instanceof EntitySpeedCardItem) {
|
||||
int multVal = EntitySpeedCardItem.readMultiplier(stack);
|
||||
int count = Math.min(stack.getCount(), maxCards - considered);
|
||||
for (int i = 0; i < count; i++) {
|
||||
list.add(multVal);
|
||||
considered++;
|
||||
if (considered >= maxCards) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return computeProductWithCap(list, maxCards);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算最终消耗:把 product 转换为等效卡数(log2)并调用 getFinalPower
|
||||
*/
|
||||
public static double computeFinalPowerForProduct(long product, int energyCardCount) {
|
||||
if (product <= 1L) return 0.0;
|
||||
double base = ModConfigs.EntitySpeedTickerCost.get();
|
||||
|
||||
// 计算以2为底的对数(用于分档与公式)
|
||||
double log2 = Math.log(product) / Math.log(2.0);
|
||||
|
||||
// 分档:product==2 为一档;4..256 为中档;512..1024 为高档
|
||||
double raw;
|
||||
if (product == 2L) {
|
||||
// 轻量档:线性小幅增长
|
||||
raw = base * 4;
|
||||
} else if (product <= 256L) {
|
||||
// 中档:增长放缓(使用 1.5 * log2)
|
||||
raw = base * Math.pow(2.0, 1.5 * log2) * 2;
|
||||
} else {
|
||||
// 高档:增长较快(使用 2.5 * log2)
|
||||
raw = base * Math.pow(2.0, 2.5 * log2);
|
||||
}
|
||||
|
||||
double reduction = getReductionPercent(energyCardCount);
|
||||
return raw * (1.0 - reduction) / 8.0;
|
||||
}
|
||||
|
||||
/* ----------------- legacy helpers (restored) ----------------- */
|
||||
public static double getGrowthFactor(int speedCardCount) {
|
||||
if (speedCardCount <= 0) return 1.0;
|
||||
if (speedCardCount == 1) return 2.0;
|
||||
|
|
@ -31,20 +120,11 @@ public final class PowerUtils {
|
|||
return Math.pow(2.0, 3.0 * speedCardCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算加速卡数量对应的原始能耗(未减免)
|
||||
* @param speedCardCount 加速卡数量
|
||||
* @return 原始能耗
|
||||
*/
|
||||
public static double getRawPower(int speedCardCount) {
|
||||
double base = ModConfigs.EntitySpeedTickerCost.get();
|
||||
return base * getGrowthFactor(speedCardCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算能源卡数量对应的能耗减免百分比
|
||||
* 0: 0%,1: 10%,8: 50%,2-7: 0.5*(1-0.7^n)
|
||||
*/
|
||||
public static double getReductionPercent(int energyCardCount) {
|
||||
if (energyCardCount <= 0) return 0.0;
|
||||
if (energyCardCount == 1) return 0.1;
|
||||
|
|
@ -52,16 +132,9 @@ public final class PowerUtils {
|
|||
return 0.5 * (1.0 - Math.pow(0.7, energyCardCount));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算最终能耗(浮点数)
|
||||
* @param speedCardCount 加速卡数量
|
||||
* @param energyCardCount 能源卡数量
|
||||
* @return 最终能耗(double)
|
||||
*/
|
||||
public static double getFinalPower(int speedCardCount, int energyCardCount) {
|
||||
double raw = getRawPower(speedCardCount);
|
||||
double reduction = getReductionPercent(energyCardCount);
|
||||
// 返回与实际抽取值一致的浮点能耗(在原实现基础上再除以 2,以降低能耗)
|
||||
return raw * (1.0 - reduction) / 4.0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,13 @@
|
|||
"item.extendedae_plus.256x_crafting_accelerator": "256x Crafting Accelerator",
|
||||
"item.extendedae_plus.1024x_crafting_accelerator": "1024x Crafting Accelerator",
|
||||
"item.extendedae_plus.network_pattern_controller": "Pattern Supplier State Controller",
|
||||
"item.extendedae_plus.entity_speed_card": "Entity Acceleration Card",
|
||||
"item.extendedae_plus.entity_speed_card.x2": "Entity Acceleration Card (x2)",
|
||||
"item.extendedae_plus.entity_speed_card.x4": "Entity Acceleration Card (x4)",
|
||||
"item.extendedae_plus.entity_speed_card.x8": "Entity Acceleration Card (x8)",
|
||||
"item.extendedae_plus.entity_speed_card.x16": "Entity Acceleration Card (x16)",
|
||||
"tooltip.extendedae_plus.entity_speed_card.multiplier": "Multiplier: %s",
|
||||
"tooltip.extendedae_plus.entity_speed_card.max": "Max effective: %s x",
|
||||
|
||||
"block.extendedae_plus.wireless_transceiver": "Wireless Transceiver",
|
||||
"block.extendedae_plus.4x_crafting_accelerator": "4x Crafting Accelerator",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,13 @@
|
|||
"item.extendedae_plus.256x_crafting_accelerator": "256x并行处理单元",
|
||||
"item.extendedae_plus.1024x_crafting_accelerator": "1024x并行处理单元",
|
||||
"item.extendedae_plus.network_pattern_controller": "样板供应器状态控制器",
|
||||
"item.extendedae_plus.entity_speed_card": "实体加速卡",
|
||||
"item.extendedae_plus.entity_speed_card.x2": "实体加速卡 (x2)",
|
||||
"item.extendedae_plus.entity_speed_card.x4": "实体加速卡 (x4)",
|
||||
"item.extendedae_plus.entity_speed_card.x8": "实体加速卡 (x8)",
|
||||
"item.extendedae_plus.entity_speed_card.x16": "实体加速卡 (x16)",
|
||||
"tooltip.extendedae_plus.entity_speed_card.multiplier": "乘数: %s",
|
||||
"tooltip.extendedae_plus.entity_speed_card.max": "最大生效: %s 倍",
|
||||
|
||||
"block.extendedae_plus.wireless_transceiver": "无线收发器",
|
||||
"block.extendedae_plus.4x_crafting_accelerator": "4x并行处理单元",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"overrides": [
|
||||
{ "predicate": { "extendedae_plus:mult": 2.0 }, "model": "extendedae_plus:item/entity_speed_card_x2" },
|
||||
{ "predicate": { "extendedae_plus:mult": 4.0 }, "model": "extendedae_plus:item/entity_speed_card_x4" },
|
||||
{ "predicate": { "extendedae_plus:mult": 8.0 }, "model": "extendedae_plus:item/entity_speed_card_x8" },
|
||||
{ "predicate": { "extendedae_plus:mult": 16.0 }, "model": "extendedae_plus:item/entity_speed_card_x16" }
|
||||
],
|
||||
"textures": {
|
||||
"layer0": "extendedae_plus:item/entity_speed_card_x2"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": { "layer0": "extendedae_plus:item/entity_speed_card_x2" }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": { "layer0": "extendedae_plus:item/entity_speed_card_x16" }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": { "layer0": "extendedae_plus:item/entity_speed_card_x2" }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": { "layer0": "extendedae_plus:item/entity_speed_card_x4" }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": { "layer0": "extendedae_plus:item/entity_speed_card_x8" }
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Loading…
Reference in New Issue
Block a user