Files
esengine/extensions/cocos/cocos-ecs/assets/scripts/components/RTSBehaviorHandler.ts

334 lines
11 KiB
TypeScript
Raw Normal View History

import { _decorator, Component, Vec3, Node } from 'cc';
import { UnitController } from './UnitController';
const { ccclass } = _decorator;
/**
2025-06-25 17:50:40 +08:00
* -
* -
*/
@ccclass('RTSBehaviorHandler')
export class RTSBehaviorHandler extends Component {
private unitController: UnitController | null = null;
private minerDemo: any = null; // MinerDemo组件引用
2025-06-25 17:50:40 +08:00
private lastActionTime: number = 0;
private actionCooldown: number = 0.5; // 动作冷却时间,避免频繁切换
private minerIndex: number = -1; // 矿工索引,用于找到对应的家
start() {
this.unitController = this.getComponent(UnitController);
// 获取场景中的MinerDemo组件
this.minerDemo = this.node.parent?.getComponent('MinerDemo');
if (!this.unitController) {
console.error('RTSBehaviorHandler: 未找到UnitController组件');
}
if (!this.minerDemo) {
console.error('RTSBehaviorHandler: 未找到MinerDemo组件');
}
2025-06-25 17:50:40 +08:00
// 从节点名称中提取矿工索引
const match = this.node.name.match(/Miner_(\d+)/);
if (match) {
this.minerIndex = parseInt(match[1]) - 1; // 转换为0基索引
}
this.lastActionTime = Date.now();
}
/**
*
*/
private isActionOnCooldown(): boolean {
return (Date.now() - this.lastActionTime) < (this.actionCooldown * 1000);
}
/**
2025-06-25 17:50:40 +08:00
*
*/
private updateActionTime() {
this.lastActionTime = Date.now();
}
/**
*
* @param params
*/
2025-06-25 17:50:40 +08:00
onMineGoldOre(params: any = {}): string {
if (!this.unitController || !this.minerDemo) {
return 'failure';
}
2025-06-25 17:50:40 +08:00
// 检查体力是否充足
if (this.unitController.currentStamina < this.unitController.staminaCostPerMining) {
return 'failure';
}
// 检查是否已经携带矿石
const hasOre = this.unitController.getBlackboardValue('hasOre');
if (hasOre) {
return 'failure';
}
2025-06-25 17:50:40 +08:00
// 动作冷却检查
if (this.isActionOnCooldown()) {
return 'running';
}
2025-06-25 17:50:40 +08:00
// 获取所有金矿
const goldMines = this.minerDemo.getAllGoldMines();
if (goldMines.length === 0) {
return 'failure';
}
2025-06-25 17:50:40 +08:00
// 寻找最近的金矿
const currentPos = this.node.worldPosition;
2025-06-25 17:50:40 +08:00
let nearestMine: Node | null = null;
let minDistance = Infinity;
2025-06-25 17:50:40 +08:00
for (const mine of goldMines) {
if (!mine || !mine.isValid) continue;
const distance = Vec3.distance(currentPos, mine.worldPosition);
if (distance < minDistance) {
minDistance = distance;
2025-06-25 17:50:40 +08:00
nearestMine = mine;
}
}
2025-06-25 17:50:40 +08:00
if (!nearestMine) {
return 'failure';
}
2025-06-25 17:50:40 +08:00
// 检查是否已经到达金矿位置
if (minDistance < 2.0) {
// 检查是否正在移动
const isMoving = this.unitController.getBlackboardValue('isMoving');
if (isMoving) {
return 'running';
}
// 消耗体力
this.unitController.currentStamina = Math.max(0, this.unitController.currentStamina - this.unitController.staminaCostPerMining);
2025-06-25 17:50:40 +08:00
// 设置携带矿石状态
this.unitController.setBlackboardValue('hasOre', true);
2025-06-25 17:50:40 +08:00
// 通知演示管理器
this.minerDemo.mineGoldOre(this.node);
// 清除移动目标
this.unitController.clearTarget();
2025-06-25 17:50:40 +08:00
this.unitController.setBlackboardValue('isMoving', false);
2025-06-25 17:50:40 +08:00
this.updateActionTime();
return 'success';
} else {
2025-06-25 17:50:40 +08:00
// 设置移动目标
this.unitController.setTarget(nearestMine.worldPosition);
return 'running';
}
}
/**
*
* @param params
*/
onStoreOre(params: any = {}): string {
2025-06-25 17:50:40 +08:00
if (!this.unitController || !this.minerDemo) {
return 'failure';
}
2025-06-25 17:50:40 +08:00
// 检查是否携带矿石
const hasOre = this.unitController.getBlackboardValue('hasOre');
if (!hasOre) {
return 'failure';
}
2025-06-25 17:50:40 +08:00
// 动作冷却检查
if (this.isActionOnCooldown()) {
return 'running';
}
const warehouse = this.minerDemo.getWarehouse();
2025-06-25 17:50:40 +08:00
if (!warehouse || !warehouse.isValid) {
return 'failure';
}
// 计算到仓库的距离
const currentPos = this.node.worldPosition;
const warehousePos = warehouse.worldPosition;
const distance = Vec3.distance(currentPos, warehousePos);
// 检查是否已经到达仓库
if (distance < 2.5) {
2025-06-25 17:50:40 +08:00
// 检查是否正在移动
const isMoving = this.unitController.getBlackboardValue('isMoving');
if (isMoving) {
return 'running';
}
2025-06-25 17:50:40 +08:00
// 清除携带矿石状态
this.unitController.setBlackboardValue('hasOre', false);
// 清除移动目标
this.unitController.clearTarget();
2025-06-25 17:50:40 +08:00
this.unitController.setBlackboardValue('isMoving', false);
2025-06-25 17:50:40 +08:00
this.updateActionTime();
return 'success';
} else {
2025-06-25 17:50:40 +08:00
// 设置移动目标
this.unitController.setTarget(warehousePos);
2025-06-25 17:50:40 +08:00
return 'running';
}
}
/**
*
* @param params
*/
onGoHomeRest(params: any = {}): string {
if (!this.unitController || !this.minerDemo) {
return 'failure';
}
// 动作冷却检查
if (this.isActionOnCooldown()) {
return 'running';
}
// 获取矿工的家
const home = this.minerDemo.getMinerHome(this.minerIndex);
if (!home || !home.isValid) {
return 'failure';
}
// 计算到家的距离
const currentPos = this.node.worldPosition;
const homePos = home.worldPosition;
const distance = Vec3.distance(currentPos, homePos);
// 检查是否已经到达家
if (distance < 2.0) {
// 检查是否正在移动
const isMoving = this.unitController.getBlackboardValue('isMoving');
if (isMoving) {
return 'running';
}
// 设置休息状态
this.unitController.setBlackboardValue('isResting', true);
// 清除移动目标
this.unitController.clearTarget();
this.unitController.setBlackboardValue('isMoving', false);
this.updateActionTime();
return 'success';
} else {
// 设置移动目标
this.unitController.setTarget(homePos);
return 'running';
}
}
/**
*
* @param params
*/
onRecoverStamina(params: any = {}): string {
if (!this.unitController) {
return 'failure';
}
// 检查是否在家中
const isResting = this.unitController.getBlackboardValue('isResting');
if (!isResting) {
return 'failure';
}
// 恢复体力
const oldStamina = this.unitController.currentStamina;
this.unitController.currentStamina = Math.min(this.unitController.maxStamina,
this.unitController.currentStamina + this.unitController.staminaRecoveryRate * 0.1); // 每次恢复2点体力
const isFullyRested = this.unitController.currentStamina >= this.unitController.maxStamina;
if (isFullyRested) {
// 清除休息状态
this.unitController.setBlackboardValue('isResting', false);
// 通知演示管理器
this.minerDemo.completeRestCycle();
this.updateActionTime();
return 'success';
} else {
// 体力还在恢复中
return 'running';
}
}
/**
*
* @param params
*/
onIdleBehavior(params: any = {}): string {
2025-06-25 17:50:40 +08:00
if (!this.unitController) {
return 'failure';
}
// 清除移动目标,确保停止移动
this.unitController.clearTarget();
this.unitController.setBlackboardValue('isMoving', false);
return 'success';
}
2025-06-25 17:50:40 +08:00
/**
*
*/
getMinerStatus(): string {
if (!this.unitController) return 'Unknown';
const hasOre = this.unitController.getBlackboardValue('hasOre');
const isMoving = this.unitController.getBlackboardValue('isMoving');
const isResting = this.unitController.getBlackboardValue('isResting');
const stamina = this.unitController.currentStamina;
const maxStamina = this.unitController.maxStamina;
let status = '';
if (isResting) {
status = '😴休息中';
} else if (hasOre) {
status = isMoving ? '🚚运输中' : '📦携带矿石';
} else {
status = isMoving ? '🚶移动中' : '⛏️挖矿';
}
return `${status} (体力:${stamina.toFixed(0)}/${maxStamina})`;
}
/**
*
*/
getDebugInfo(): any {
if (!this.unitController) return {};
return {
name: this.node.name,
hasOre: this.unitController.getBlackboardValue('hasOre'),
isMoving: this.unitController.getBlackboardValue('isMoving'),
isResting: this.unitController.getBlackboardValue('isResting'),
stamina: this.unitController.currentStamina,
maxStamina: this.unitController.maxStamina,
staminaPercentage: this.unitController.currentStamina / this.unitController.maxStamina,
isLowStamina: this.unitController.currentStamina < this.unitController.maxStamina * 0.2,
status: this.getMinerStatus()
};
}
}