import { ConstNumType } from '../../game/GameDataEnums'; /** 第一战场引导关(花果山) */ export function isLevel1Tutorial(levelId: number): boolean { return levelId === 1; } /** @deprecated 使用 isLevel1Tutorial */ export function isChapter1NormalOnly(levelId: number): boolean { return isLevel1Tutorial(levelId); } /** Weapon2.id — 旧扩展格(新产品不使用) */ export const GRID_WEAPON2_ID = 5; /** Text.id — 蟠桃树(type=3) */ export const PEACH_TREE_WEAPON2_ID = 102; /** 蟠桃树可合成等级上限(对齐 Hero.102 与普攻 11021–11025) */ export const PEACH_TREE_MAX_LEVEL = 5; /** Text.id — 铲子(type=14) */ export const SHOVEL_WEAPON2_ID = 3003; const DEFAULT_AD_LIMITS = [3, 3, 3, 3, 3, 3, 3]; /** 解析战场广告次数上限(Const 或默认) */ export function parseLevelAdvertiseLimit(_levelId: number): number[] { return DEFAULT_AD_LIMITS; } /** @deprecated */ export function parseChapterAdvertiseLimit(levelId: number): number[] { return parseLevelAdvertiseLimit(levelId); } /** 高阶刷新已下线,恒为 0 */ export function getBagAdRefreshMax(_levelId: number): number { return 0; } /** 局内铲子广告次数上限(Const id=10) */ export function getShovelAdMax(_levelId: number): number { const max = Math.floor(Number(gg.data.table.getConst(ConstNumType.BattleShovelAdMax)) || 0); if (!(max > 0)) { console.log('[BagPrepConfig] Const 局内铲子广告上限无效', ConstNumType.BattleShovelAdMax); return 0; } return max; } /** 盾牌广告触发距离(Const id=23) */ export function getShieldAdTriggerDist(): number { const dist = Math.floor(Number(gg.data.table.getConst(ConstNumType.BattleShieldAdTriggerDist)) || 0); if (!(dist > 0)) { console.log('[BagPrepConfig] Const 盾牌广告触发距离无效', ConstNumType.BattleShieldAdTriggerDist); return 0; } return dist; } /** 盾牌广告次数上限(Const id=25) */ export function getShieldAdMax(): number { const max = Math.floor(Number(gg.data.table.getConst(ConstNumType.BattleShieldAdMax)) || 0); if (!(max > 0)) { console.log('[BagPrepConfig] Const 局内盾牌广告上限无效', ConstNumType.BattleShieldAdMax); return 0; } return max; } /** 盾牌推怪格数(Const id=24) */ export function getShieldPushCells(): number { const cells = Math.floor(Number(gg.data.table.getConst(ConstNumType.BattleShieldPushCells)) || 0); if (!(cells > 0)) { console.log('[BagPrepConfig] Const 盾牌推怪格数无效', ConstNumType.BattleShieldPushCells); return 0; } return cells; } /** * 战斗看视频加金币奖励序列(Const id=38 para1)。 * 次数=数组长度,第 N 次奖励=元素 N-1;非法项丢弃,全空则广告不可用。 */ export function getBattleCoinAdRewards(): number[] { const raw = gg.data.table.getConstArray(ConstNumType.BattleCoinAdRewards); const out: number[] = []; for (let i = 0; i < raw.length; i++) { const n = Math.floor(Number(raw[i]) || 0); if (n > 0) out.push(n); } if (out.length <= 0) { console.log('[BagPrepConfig] Const 局内金币广告奖励无效', ConstNumType.BattleCoinAdRewards); } return out; } /** 免费格子已下线 */ export function getFreeGridAdMax(_levelId: number): number { return 0; } /** 芭蕉扇看广告推回次数上限 */ export function getBajiaoFanAdMax(levelId: number): number { const limits = parseLevelAdvertiseLimit(levelId); return limits[6] ?? 0; } /** 本局免费格子已下线 */ export function getLevelFreeBox(_levelId: number): number { return 0; } /** @deprecated */ export function getChapterFreeBox(levelId: number): number { return getLevelFreeBox(levelId); } /** 本局免费摆放提示次数 */ export function getLevelFreeTips(_levelId: number): number { return 0; } /** @deprecated */ export function getChapterFreeTips(levelId: number): number { return getLevelFreeTips(levelId); } /** P2 普通刷新保底已下线 */ export function resolveRefreshGuaranteeWeapon2Id(_levelId: number, _refreshIndex: number): number | null { return null; } /** 普通刷新 Const 消耗分量 */ export type BagNormalRefreshCostParts = { /** Const 初始消耗 */ base: number; /** Const 每次已成功刷新递增量 */ step: number; }; /** * 普通刷新消耗分量:仅 Const 初始(递增值已从表删除,step 恒 0)。 */ export function getBagNormalRefreshCostParts(): BagNormalRefreshCostParts { const base = gg.data.table.getConst(ConstNumType.BagRefreshBaseCost); if (!(base > 0)) { console.log('[BagPrepConfig] Const 初始刷新消耗无效', ConstNumType.BagRefreshBaseCost, base); return { base: 0, step: 0 }; } return { base, step: 0 }; } /** * 普通刷新消耗:Const id4 初始(无递增)。 * @param usedCount 本局已成功普通刷新次数(保留形参,兼容调用方) */ export function getBagNormalRefreshCost(usedCount: number): number { const { base, step } = getBagNormalRefreshCostParts(); return calcBagRefreshCostFromParts(base, step, usedCount); } /** 由 Const 分量与已成功次数计算召唤消耗(不含 buff) */ export function calcBagRefreshCostFromParts(base: number, step: number, usedCount: number): number { const used = Math.max(0, Math.floor(usedCount)); return Math.max(0, Math.floor(base)) + Math.max(0, Math.floor(step)) * used; } /** * 携带 functiontype=26:先算当档原消耗,再对该档总消耗按万分比减免。 * @param usedCount 本局已成功普通刷新次数 * @param reduceWan 降低比例万分比累加 */ export function getDiscountedBagNormalRefreshCost(usedCount: number, reduceWan: number): number { const tierCost = getBagNormalRefreshCost(usedCount); return applyWanReduceToRefreshCost(tierCost, reduceWan); } /** * 对当次召唤档位总消耗按万分比减免(10→9,12→11,14→13 @1000)。 * @param tierCost 当档原消耗(Const 初始 + 递增×次数) * @param reduceWan 降低比例万分比累加(上限 10000) */ export function applyWanReduceToRefreshCost(tierCost: number, reduceWan: number): number { const cost = Math.max(0, Math.floor(tierCost)); const wan = Math.max(0, Math.min(10000, Math.floor(reduceWan) || 0)); if (cost <= 0 || wan <= 0) return cost; const reduced = cost - Math.floor(cost * wan / 10000); return reduced > 0 ? Math.max(1, reduced) : 0; } /** 召唤按钮一次最多补的空开启格数量(满额对应 Const 刷新消耗) */ export const BAG_SUMMON_SLOT_MAX = 5; /** * 按实际补格数折算召唤消耗(满额 5 格付满费;3 格 → floor(满费×3/5))。 * @param fullCost 满额消耗(已含省金等减免) * @param fillCount 本次实际补入空格数 * @param maxCount 满额格数,默认 {@link BAG_SUMMON_SLOT_MAX} */ export function scaleBagRefreshCostByFillCount(fullCost: number, fillCount: number, maxCount: number = BAG_SUMMON_SLOT_MAX): number { const full = Math.max(0, Math.floor(fullCost)); const max = Math.max(1, Math.floor(maxCount)); const fill = Math.max(0, Math.min(max, Math.floor(fillCount))); if (full <= 0 || fill <= 0) return 0; if (fill >= max) return full; return Math.floor((full * fill) / max); }