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.
117 lines
3.7 KiB
117 lines
3.7 KiB
|
3 weeks ago
|
import type { EntityId } from 'db://assets/mx/module/ecs';
|
||
|
|
import type { BattleSession, PlayerSlot } from 'db://assets/mx/module/battle';
|
||
|
|
import type { ComposedUnit } from 'db://assets/mx/module/merge';
|
||
|
|
import type { BattleBagSession } from '../battle/bag/BattleBagSession';
|
||
|
|
import type { BattleDeployParams } from '../battle/types/ProjectBattleTypes';
|
||
|
|
import { TableNames } from './ConfigTableData';
|
||
|
|
import { heroUltSkillId } from '../battle/config/BattleHeroTable';
|
||
|
|
|
||
|
|
/** 玩家上下文可访问的对局句柄(避免 Player ↔ IBattleRuntimeHandle 循环依赖) */
|
||
|
|
export interface IPlayerMatch {
|
||
|
|
readonly session: BattleSession;
|
||
|
|
bagSession: BattleBagSession | null;
|
||
|
|
deploy(params: BattleDeployParams): boolean;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 项目层玩家上下文(PVP 兼容)
|
||
|
|
* 每个 PlayerSlot 对应一个实例;闯关模式仅本地玩家 isLocal=true。
|
||
|
|
*/
|
||
|
|
export class Player {
|
||
|
|
readonly playerId: number;
|
||
|
|
readonly isLocal: boolean;
|
||
|
|
readonly match: IPlayerMatch;
|
||
|
|
|
||
|
|
/** 技能表现控制器(由 SkillController 注入;此处不 import 该类以免 Player 拉战斗表现环) */
|
||
|
|
skillController: object | null = null;
|
||
|
|
|
||
|
|
/** @deprecated 词条表已删,保留空数组兼容快照 */
|
||
|
|
readonly selectedSkills: ITableSkill[] = [];
|
||
|
|
|
||
|
|
/** 非本机玩家可挂独立 bag(AI 无头背包) */
|
||
|
|
private _attachedBag: BattleBagSession | null = null;
|
||
|
|
|
||
|
|
constructor(match: IPlayerMatch, playerId: number, isLocal: boolean) {
|
||
|
|
this.match = match;
|
||
|
|
this.playerId = playerId;
|
||
|
|
this.isLocal = isLocal;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 挂接独立背包会话(供 AI 等非本机玩家)。
|
||
|
|
* @param bag 无头 bag;传 null 解除
|
||
|
|
*/
|
||
|
|
attachBagSession(bag: BattleBagSession | null): void {
|
||
|
|
this._attachedBag = bag;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** MX 玩家槽(金币、城墙、已部署单位) */
|
||
|
|
get slot(): PlayerSlot | undefined {
|
||
|
|
return this.match.session.players[this.playerId];
|
||
|
|
}
|
||
|
|
|
||
|
|
get deployedUnits(): readonly EntityId[] {
|
||
|
|
return this.slot?.deployedUnits ?? [];
|
||
|
|
}
|
||
|
|
|
||
|
|
get gold(): number {
|
||
|
|
return this.slot?.gold ?? 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
get wallHp(): number {
|
||
|
|
return this.slot?.wallHp ?? 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
get wallMaxHp(): number {
|
||
|
|
return this.slot?.wallMaxHp ?? 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 本机用 match.bagSession;AI 用 attachBagSession */
|
||
|
|
get bagSession(): BattleBagSession | null {
|
||
|
|
if (this._attachedBag) return this._attachedBag;
|
||
|
|
if (!this.isLocal) return null;
|
||
|
|
return this.match.bagSession ?? null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 地图上已合成的攻击单位 */
|
||
|
|
get compositions(): readonly ComposedUnit[] {
|
||
|
|
return this.bagSession?.compositions ?? [];
|
||
|
|
}
|
||
|
|
|
||
|
|
deploy(params: Omit<BattleDeployParams, 'playerId'>): boolean {
|
||
|
|
return this.match.deploy({ ...params, playerId: this.playerId });
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @deprecated 词条已删 */
|
||
|
|
addSelectedSkill(_skill: ITableSkill): boolean {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 英雄主动技能 id(按合成等级)。
|
||
|
|
* @param heroId Hero.id
|
||
|
|
* @param composeLevel 合成等级,默认 1
|
||
|
|
*/
|
||
|
|
getActiveSkillBaseAtkId(heroId: number, composeLevel = 1): number {
|
||
|
|
const hero = gg.data.table.getTableData<ITableHero>(TableNames.Hero, heroId);
|
||
|
|
return heroUltSkillId(hero, composeLevel);
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @deprecated 词条替换已删 */
|
||
|
|
replaceActiveSkill(_weapon1Id: number, _baseAtkId: number): void {
|
||
|
|
/* no-op */
|
||
|
|
}
|
||
|
|
|
||
|
|
hasActiveSkillOverride(_weapon1Id: number): boolean {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
exportActiveSkillOverrides(): Record<string, number> {
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
|
||
|
|
get selectedSkillIds(): readonly number[] {
|
||
|
|
return this.selectedSkills.map(s => s.id);
|
||
|
|
}
|
||
|
|
}
|