You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
5.8 KiB
131 lines
5.8 KiB
|
3 weeks ago
|
import type { EntityId } from 'db://assets/mx/module/ecs';
|
||
|
|
import { TableNames } from '../../game/ConfigTableData';
|
||
|
|
import type { BattleBagSession } from '../bag/BattleBagSession';
|
||
|
|
import { WeaponComposeConfigProvider } from '../bag/WeaponComposeConfigProvider';
|
||
|
|
import { findEntityIdByGridIndex } from '../runtime/DeployEntityQuery';
|
||
|
|
import type { ProjectBattleHandle } from '../runtime/BattleRuntime';
|
||
|
|
import type { BattleBuffSkillDropTarget } from '../view/CocosBagBoardView';
|
||
|
|
import { getTowerExpHost, needTowerExpForLevel } from './TowerExpHost';
|
||
|
|
import { getTowerLoadoutService } from './TowerLoadoutService';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 封神榜(functiontype=2)/ 授仙箓(functiontype=7):
|
||
|
|
* 多格组合字武将、普通 type1 单字(含已上场单字塔)可施放;type2 未合成英雄散字不可。
|
||
|
|
* 攻速符/千里眼等拖到字块类主动 buff 共用 MergeSession.canApplyBattleBuffSkillDrop* 落点校验。
|
||
|
|
* 对已部署多格合成武将升级时补剩余经验;授仙箓降级时清空累计经验。
|
||
|
|
*/
|
||
|
|
|
||
|
|
/** 是否地图多格合成武将(已部署时走补经验) */
|
||
|
|
export function isBattleBuffLevelUpExpFillMapTarget(bagSession: BattleBagSession, gridIndex: number): boolean {
|
||
|
|
return bagSession.merge.isMultiCellCompositionAt(gridIndex);
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 地图格 → 已部署塔实体;未部署则 null */
|
||
|
|
export function resolveBattleBuffLevelUpMapEntity(
|
||
|
|
battle: ProjectBattleHandle,
|
||
|
|
bagSession: BattleBagSession,
|
||
|
|
gridIndex: number,
|
||
|
|
): EntityId | null {
|
||
|
|
const map = battle.Map;
|
||
|
|
const player = battle.getPlayer(bagSession.ownerPlayerId);
|
||
|
|
if (!map || !player) return null;
|
||
|
|
const entityId = findEntityIdByGridIndex(gridIndex, battle.session, map, player);
|
||
|
|
if (entityId == null || !battle.session.world.isAlive(entityId)) return null;
|
||
|
|
return entityId;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 是否应对该落点走「补剩余升级经验」 */
|
||
|
|
export function shouldBattleBuffLevelUpViaExpFill(
|
||
|
|
battle: ProjectBattleHandle | null,
|
||
|
|
bagSession: BattleBagSession,
|
||
|
|
target: BattleBuffSkillDropTarget,
|
||
|
|
): boolean {
|
||
|
|
if (target.kind !== 'map' || !battle) return false;
|
||
|
|
if (!isBattleBuffLevelUpExpFillMapTarget(bagSession, target.gridIndex)) return false;
|
||
|
|
return resolveBattleBuffLevelUpMapEntity(battle, bagSession, target.gridIndex) != null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 授仙箓降级:是否须清空已部署多格合成武将经验 */
|
||
|
|
export function shouldBattleBuffLevelDownClearExp(
|
||
|
|
battle: ProjectBattleHandle,
|
||
|
|
bagSession: BattleBagSession,
|
||
|
|
target: BattleBuffSkillDropTarget,
|
||
|
|
): boolean {
|
||
|
|
return shouldBattleBuffLevelUpViaExpFill(battle, bagSession, target);
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 授仙箓降级:清空已部署多格合成武将累计经验 */
|
||
|
|
export function applyBattleBuffLevelDownClearExp(
|
||
|
|
battle: ProjectBattleHandle,
|
||
|
|
bagSession: BattleBagSession,
|
||
|
|
gridIndex: number,
|
||
|
|
): void {
|
||
|
|
const entityId = resolveBattleBuffLevelUpMapEntity(battle, bagSession, gridIndex);
|
||
|
|
if (entityId == null) return;
|
||
|
|
getTowerExpHost().clearExp(entityId);
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 已部署多格合成武将:是否可补剩余升级经验 */
|
||
|
|
export function canApplyBattleBuffLevelUpViaExpFill(
|
||
|
|
battle: ProjectBattleHandle,
|
||
|
|
bagSession: BattleBagSession,
|
||
|
|
gridIndex: number,
|
||
|
|
levelDelta: number,
|
||
|
|
): boolean {
|
||
|
|
if (levelDelta <= 0) return false;
|
||
|
|
if (bagSession.merge.canApplyBattleBuffUnitLevelUp(gridIndex, levelDelta) != null) return false;
|
||
|
|
const entityId = resolveBattleBuffLevelUpMapEntity(battle, bagSession, gridIndex);
|
||
|
|
if (entityId == null) return false;
|
||
|
|
const loadout = getTowerLoadoutService().getLoadout(entityId);
|
||
|
|
if (!loadout) return false;
|
||
|
|
const hero = gg.data.table.getTableData<ITableHero>(TableNames.Hero, loadout.weapon1Id);
|
||
|
|
if (!hero) return false;
|
||
|
|
const max = WeaponComposeConfigProvider.instance.getMaxWeaponLevel(loadout.weapon1Id);
|
||
|
|
if (loadout.level >= max) return false;
|
||
|
|
return needTowerExpForLevel(hero, loadout.level) > 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 已部署多格合成武将:补剩余升级经验(可触发正常经验升级) */
|
||
|
|
export function applyBattleBuffLevelUpViaExpFill(
|
||
|
|
battle: ProjectBattleHandle,
|
||
|
|
bagSession: BattleBagSession,
|
||
|
|
gridIndex: number,
|
||
|
|
): boolean {
|
||
|
|
const entityId = resolveBattleBuffLevelUpMapEntity(battle, bagSession, gridIndex);
|
||
|
|
if (entityId == null) return false;
|
||
|
|
return getTowerExpHost().grantRemainingExpForNextLevel(battle, entityId);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 授仙箓:掷骰并写盘;已部署合成武将若掷到升级则补剩余经验。
|
||
|
|
* @param rollWan 0~9999
|
||
|
|
*/
|
||
|
|
export function applyBattleBuffRandomLevelWithExpFill(
|
||
|
|
battle: ProjectBattleHandle,
|
||
|
|
bagSession: BattleBagSession,
|
||
|
|
target: BattleBuffSkillDropTarget,
|
||
|
|
levelUpProbsWan: readonly number[],
|
||
|
|
rollWan: number,
|
||
|
|
): number | null {
|
||
|
|
const merge = bagSession.merge;
|
||
|
|
if (target.kind === 'map') {
|
||
|
|
const rolled = merge.rollBattleBuffRandomLevelMap(target.gridIndex, levelUpProbsWan, rollWan);
|
||
|
|
if (typeof rolled !== 'number') return null;
|
||
|
|
if (rolled > 0 && shouldBattleBuffLevelUpViaExpFill(battle, bagSession, target)) {
|
||
|
|
if (canApplyBattleBuffLevelUpViaExpFill(battle, bagSession, target.gridIndex, rolled)) {
|
||
|
|
return applyBattleBuffLevelUpViaExpFill(battle, bagSession, target.gridIndex) ? rolled : null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const result = merge.applyBattleBuffRandomLevelMapDelta(target.gridIndex, rolled);
|
||
|
|
if (typeof result === 'number' && result < 0 && shouldBattleBuffLevelDownClearExp(battle, bagSession, target)) {
|
||
|
|
applyBattleBuffLevelDownClearExp(battle, bagSession, target.gridIndex);
|
||
|
|
}
|
||
|
|
return typeof result === 'number' ? result : null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const rolled = merge.rollBattleBuffRandomLevelBag(target.slotIndex, levelUpProbsWan, rollWan);
|
||
|
|
if (typeof rolled !== 'number') return null;
|
||
|
|
const result = merge.applyBattleBuffRandomLevelBagDelta(target.slotIndex, rolled);
|
||
|
|
return typeof result === 'number' ? result : null;
|
||
|
|
}
|