diff --git a/src/components/ModularFactoryDrawerContent.tsx b/src/components/ModularFactoryDrawerContent.tsx index 8c4fd23..bf67603 100644 --- a/src/components/ModularFactoryDrawerContent.tsx +++ b/src/components/ModularFactoryDrawerContent.tsx @@ -121,6 +121,28 @@ function createColumns({ ) }, }, + { + title: t('clockSpeed'), + key: 'clockSpeed', + minWidth: 120, + width: 140, + render: (row) => { + return ( + { + row.clockSpeed = value + ? new Decimal(value).div(100).toNumber() + : null // todo + }} + min={1} + max={250} + /> + ) + }, + }, { title: t('building'), key: 'building', diff --git a/src/locales/en.yml b/src/locales/en.yml index 5d2e9ab..5c3bb2d 100644 --- a/src/locales/en.yml +++ b/src/locales/en.yml @@ -37,3 +37,4 @@ itemUnitName: unit | units fluidUnitName: m³ unitsPerMinute: '{0} {1}/min' seconds: s +clockSpeed: Clock Speed (%) diff --git a/src/locales/zh-CN.yml b/src/locales/zh-CN.yml index 4a5b11c..a148b98 100644 --- a/src/locales/zh-CN.yml +++ b/src/locales/zh-CN.yml @@ -37,3 +37,4 @@ itemUnitName: 个 fluidUnitName: 立方米 unitsPerMinute: '每分钟 {0} {1}' seconds: 秒 +clockSpeed: 超频 (%) diff --git a/src/stores/modularFactoryList.ts b/src/stores/modularFactoryList.ts index ce9c47c..efe2acf 100644 --- a/src/stores/modularFactoryList.ts +++ b/src/stores/modularFactoryList.ts @@ -1,6 +1,7 @@ import { computed, ref } from 'vue' import { defineStore } from 'pinia' import { syncRef, useLocalStorage } from '@vueuse/core' +import Decimal from 'decimal.js' import type { AssemblyLine, @@ -27,73 +28,97 @@ export const useModularFactoryList = defineStore('modularFactoryList', () => { const assemblyLineComputedList = computed(() => { const assemblyLineComputed: Record = {} data.value.forEach(({ data }) => { - data.forEach(({ id, targetItemId, targetItemSpeed, recipeId }) => { - if (recipeId && targetItemId && targetItemSpeed) { - const recipe = getRecipeById(recipeId) - const building = getBuildingById(recipe.producedInId) - - // 100%频率下目标物品每次生产数量 - const targetItemQuantityPerCycle = recipe.outputs.find( - ({ itemId }) => itemId === targetItemId, - )!.quantityPerCycle - - // 100%频率下单个建筑每秒产出的目标物品数量 - const targetItemQuantityPerMinutePerBuilding = - calculateQuantityPerMinute( - targetItemQuantityPerCycle, - recipe.productionDuration, + data.forEach( + ({ id, targetItemId, targetItemSpeed, recipeId, clockSpeed }) => { + if (recipeId && targetItemId && targetItemSpeed && clockSpeed) { + const recipe = getRecipeById(recipeId) + const building = getBuildingById(recipe.producedInId) + + // 目标物品每周期生产数量 + const targetItemQuantityPerCycle = recipe.outputs.find( + ({ itemId }) => itemId === targetItemId, + )!.quantityPerCycle + + // 目标物品 100% 频率每分钟生产数量 + const targetItemQuantityPerMinutePerBuilding = + calculateQuantityPerMinute( + targetItemQuantityPerCycle, + recipe.productionDuration, + ) + + // 达到目标产量需要的总频率 + const totalClockSpeed = new Decimal(targetItemSpeed) + .div(targetItemQuantityPerMinutePerBuilding) + .toNumber() + + // 需要的建筑数量 + const buildingQuantity = new Decimal(targetItemSpeed) + .div( + new Decimal(targetItemQuantityPerMinutePerBuilding).mul( + clockSpeed, + ), + ) + .toNumber() + + // 目标物品 100% 频率的功率 + const powerUsage = + building.powerUsage === 'variable' + ? recipe.powerUsage + : building.powerUsage + + // 总功率 + const totalPowerUsage = + powerUsage && + calculateTotalPowerUsage(powerUsage, buildingQuantity, clockSpeed) + const averageTotalPowerUsage = + totalPowerUsage && calculateAveragePowerUsage(totalPowerUsage) + + // 流水线总输入 + const inputs = recipe.inputs.map(({ itemId, quantityPerCycle }) => { + return { + itemId, + quantityPerMinute: new Decimal( + calculateQuantityPerMinute( + quantityPerCycle, + recipe.productionDuration, + ), + ) + .mul(totalClockSpeed) + .toNumber(), + } + }) + + // 流水线总输出 + const outputs = recipe.outputs.map( + ({ itemId, quantityPerCycle }) => { + return { + itemId, + quantityPerMinute: new Decimal( + calculateQuantityPerMinute( + quantityPerCycle, + recipe.productionDuration, + ), + ) + .mul(totalClockSpeed) + .toNumber(), + } + }, ) - // 100%频率下需要的建筑数量 - const buildingQuantity = - targetItemSpeed / targetItemQuantityPerMinutePerBuilding - - const powerUsage = - building.powerUsage === 'variable' - ? recipe.powerUsage - : building.powerUsage - const totalPowerUsage = - powerUsage && calculateTotalPowerUsage(powerUsage, buildingQuantity) - const averageTotalPowerUsage = - totalPowerUsage && calculateAveragePowerUsage(totalPowerUsage) - - // 流水线总输入 - const inputs = recipe.inputs.map(({ itemId, quantityPerCycle }) => { - return { - itemId, - quantityPerMinute: - calculateQuantityPerMinute( - quantityPerCycle, - recipe.productionDuration, - ) * buildingQuantity, + assemblyLineComputed[id] = { + buildingId: building.id, + buildingQuantity, + powerUsage, + totalPowerUsage, + averageTotalPowerUsage, + inputs, + outputs, } - }) - - // 流水线总输出 - const outputs = recipe.outputs.map(({ itemId, quantityPerCycle }) => { - return { - itemId, - quantityPerMinute: - calculateQuantityPerMinute( - quantityPerCycle, - recipe.productionDuration, - ) * buildingQuantity, - } - }) - - assemblyLineComputed[id] = { - buildingId: building.id, - buildingQuantity, - powerUsage, - totalPowerUsage, - averageTotalPowerUsage, - inputs, - outputs, + } else { + assemblyLineComputed[id] = null } - } else { - assemblyLineComputed[id] = null - } - }) + }, + ) }) return assemblyLineComputed }) @@ -136,6 +161,7 @@ export const useModularFactoryList = defineStore('modularFactoryList', () => { targetItemId: null, targetItemSpeed: null, recipeId: null, + clockSpeed: 1, }) return id } diff --git a/src/types.ts b/src/types.ts index 3aad3e7..a419063 100644 --- a/src/types.ts +++ b/src/types.ts @@ -46,6 +46,7 @@ export interface AssemblyLine { targetItemId: Id | null targetItemSpeed: number | null recipeId: Id | null + clockSpeed: number | null } export interface AssemblyLineComputed { diff --git a/src/utils/dataCalculators.ts b/src/utils/dataCalculators.ts index 4abb5bf..c0a2b9f 100644 --- a/src/utils/dataCalculators.ts +++ b/src/utils/dataCalculators.ts @@ -2,6 +2,8 @@ import { Decimal } from 'decimal.js' import type { PowerUsage } from '@/types' +const overclockingPowerIndex = 1.321928 + export const calculateQuantityPerMinute = ( quantityPerCycle: number, productionDuration: number, @@ -13,13 +15,15 @@ export const calculateQuantityPerMinute = ( export const calculateTotalPowerUsage = ( powerUsage: PowerUsage, buildingQuantity: number, + clockSpeed: number, ): PowerUsage => { + const powerMul = new Decimal(clockSpeed).pow(overclockingPowerIndex) if (typeof powerUsage === 'number') { - return new Decimal(powerUsage).mul(buildingQuantity).toNumber() + return powerMul.mul(powerUsage).mul(buildingQuantity).toNumber() } return [ - new Decimal(powerUsage[0]).mul(buildingQuantity).toNumber(), - new Decimal(powerUsage[1]).mul(buildingQuantity).toNumber(), + powerMul.mul(powerUsage[0]).mul(buildingQuantity).toNumber(), + powerMul.mul(powerUsage[1]).mul(buildingQuantity).toNumber(), ] }