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.
 
 
 
 
AdLike2048/assets/script/game/Player.ts

116 lines
3.7 KiB

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);
}
}