import { _ECommonState, _IBehaviorTreeConfig } from "../Data/CommonDataType"; import { EventName } from "../Event/EventName"; import EventManager from "../Event/EventManager"; import Tool from "../Tool/Tool"; import BasicTreeBehaviorNode from "./BasicTreeBehaviorNode"; import BasicTreePreconditionNode from "./BasicTreePreconditionNode"; /** * 基础行为树控制节点 - 逻辑层 */ export default abstract class BasicTreeControlNode extends BasicTreeBehaviorNode { /**子节点列表 */ protected childs: Map; /**当前运行的子节点列表 */ protected _currentChilds: Array; /**行为树配置 */ public readonly behaviorTreeConfig: _IBehaviorTreeConfig; /**前提 */ protected _precondition: BasicTreePreconditionNode; constructor (node: cc.Node, behaviorType: string, unitID: string, behaviorTreeConfig: _IBehaviorTreeConfig, childs?: Map, precondition?: BasicTreePreconditionNode) { super(node, behaviorType, precondition); this._id = unitID; this.childs = childs || new Map(); this._currentChilds = new Array(); this.behaviorTreeConfig = behaviorTreeConfig; this.childs.forEach((value: BasicTreeBehaviorNode, key: any) => { value.id = this.id; value.precondition && (value.precondition.priority = this.behaviorTreeConfig.priority[key]); }); this.childs.forEach((value: BasicTreeBehaviorNode, key: any) => { this.addComponentIntance(value); }); EventManager.onEvent(EventName.Behavior.Behavior_SetBehaviorData, this, this.onSetBehaviorData); EventManager.onEvent(EventName.Behavior.Behavior_SetPreconditionData, this, this.onPreconditionData); EventManager.onEvent(EventName.Behavior.Behavior_GetBehaviorData, this, this.onGetBehaviorData); EventManager.onEvent(EventName.Behavior.Behavior_EnterBehavior, this, this.enter); EventManager.onEvent(EventName.Behavior.Behavior_ForceEnterBehavior, this, this.forceEnter); EventManager.onEvent(EventName.Behavior.Behavior_LeaveBehavior, this, this.leave); EventManager.onEvent(EventName.Behavior.Behavior_ForceLeaveBehavior, this, this.forceLeave); } public _update (dt: number): void { for (let index in this._currentChilds) { if (this.childs.get(this.currentChilds[index]).isEnabled == true || this.childs.get(this.currentChilds[index]).enabled == true) { this.childs.get(this.currentChilds[index])._update(dt); } } } /**获得当前运行的子节点列表 */ public get currentChilds (): Array { return [].concat(this._currentChilds); } /**子节点是否正在运行 */ public isCurrentChild (behavior: any): boolean { return this._currentChilds.includes(behavior); } /**设置子节点 */ public setChild (behavior: any, behaviorNode: BasicTreeBehaviorNode): void { let _child: BasicTreeBehaviorNode = this.childs.get(behavior); if (_child != null) { _child._destroy(); } this.childs.set(behavior, behaviorNode); } /**获得子节点 */ public getChild (behavior: any): BasicTreeBehaviorNode { return this.childs.get(behavior); } /**设置行为数据响应方法 */ public onSetBehaviorData (behavior: any, data: any): void { // 是否有该行为 if (this.getChild(behavior) == null) { return; } this.getChild(behavior).customData = Tool.dataAllCover(this.getChild(behavior).customData, data); } /**设置前提数据响应方法 */ public onPreconditionData (behavior: any, data: any): void { // 是否有该行为 if (this.getChild(behavior) == null) { return; } this.getChild(behavior).precondition.customData = Tool.dataAllCover(this.getChild(behavior).precondition.customData, data); } /**获得行为数据响应方法 */ private onGetBehaviorData (id: string, callback: Function): void { if (this.id == id) { callback(this._currentChilds); } } /**是否可以进入 */ public isEnter (behavior: any, ...args: any): _ECommonState { // 是否有该行为 if (this.childs.has(behavior) == false) { return _ECommonState.Fail; } // 遍历当前所有子节点,判断能否进入 let commonState: _ECommonState = _ECommonState.None; if (this._currentChilds.length == 0 || this._currentChilds.includes(behavior) == true) { if (this.childs.get(behavior).getPreconditionResule(behavior, ...args) == _ECommonState.Success) { commonState = _ECommonState.Success; } else { commonState = _ECommonState.Fail; } } else { let child: BasicTreeBehaviorNode; for (let index in this._currentChilds) { child = this.childs.get(this._currentChilds[index]); if (child != null && child.getPreconditionResule(behavior, ...args) == _ECommonState.Success) { commonState = _ECommonState.Success; } else { commonState = _ECommonState.Fail; break; } } } return commonState; } /**强制进入行为 */ public forceEnter (behavior: any, ...args: any): void { this._enter(behavior, ...args); } /**强制离开行为 */ public forceLeave (behavior: any, ...args: any): void { this._leave(behavior, ...args); } public enter (behavior: any, ...args: any): void { // 是否有该行为 if (this.childs.has(behavior) == false) { return; } if (this.isEnter(behavior, ...args) == _ECommonState.Success) { this._enter(behavior, ...args); } else { let child: BasicTreeBehaviorNode = this.childs.get(behavior); child.enterFail(...args); } } protected _enter (behavior: any, ...args: any): void { // 是否有该行为 if (this.childs.has(behavior) == false) { return; } let child: BasicTreeBehaviorNode = this.childs.get(behavior); if (this._currentChilds.includes(behavior) == true) { child.enterAgain(...args); } else { this._currentChilds.push(behavior); this.leaveMutexChild(behavior); child.enter(...args); } } protected _leave (behavior: any, ...args: any): void { // 是否有该行为 if (this.childs.has(behavior) == false) { return; } let child: BasicTreeBehaviorNode = this.childs.get(behavior); child.leave(...args); let index: number = this._currentChilds.indexOf(behavior); if (index != -1) { this._currentChilds.splice(index, 1); } } /**离开互斥子节点 */ protected leaveMutexChild (behavior: any): void { if (this.behaviorTreeConfig != null) { let mutexChild: Array = this.behaviorTreeConfig.mutexChild[behavior]; let compatibilityChild: Array = this.behaviorTreeConfig.compatibilityChild[behavior]; // 若两者为空,排斥其他所有子节点 if (mutexChild == null && compatibilityChild == null) { this.currentChilds.forEach((value: any, index: number) => { if (value != behavior) { this._leave(value); } }); } else if (mutexChild != null) { for (let index: number = 0; index < this.currentChilds.length; index++) { // 若是互斥行为 if (this.currentChilds[index] != behavior && mutexChild.includes(this.currentChilds[index]) == true) { if (this.isCurrentChild(this.currentChilds[index]) == true) { this._leave(this.currentChilds[index]); index--; } } } } else if (compatibilityChild != null) { for (let index: number = 0; index < this.currentChilds.length; index++) { // 若不是兼容行为 if (this.currentChilds[index] != behavior && compatibilityChild.includes(this.currentChilds[index]) == false) { if (this.isCurrentChild(this.currentChilds[index]) == true) { this._leave(this.currentChilds[index]); index--; } } } } } } }