behavior-eden-coco-plugin/dist/runtime/component/BehaviorManager.js
2023-09-21 01:32:33 +08:00

384 lines
18 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BehaviorManager = void 0;
// @ts-ignore
const cc_1 = require("cc");
const Composite_1 = require("../base/Composite");
const Condition_1 = require("../base/Condition");
const ParentNode_1 = require("../base/ParentNode");
const enum_1 = require("../core/enum");
const BehaviorTree_1 = require("../core/BehaviorTree");
const { ccclass } = cc_1._decorator;
/***
* 该组件会自动添加到场景上,用来驱动、管理场景中所有行为树
*/
let BehaviorManager = class BehaviorManager extends cc_1.Component {
constructor() {
super(...arguments);
this.behaviorTrees = [];
// behavior是用户使用的组件BehaviorTree是真正的行为树数据结构
this.behaviorTreesMap = new Map();
// 存储被暂停运行的行为树
this.pausedBehaviorTreesMap = new Map();
}
restart(behaviorTree) {
if (behaviorTree.behavior.logNodeChange) {
console.log("restart重启行为树");
}
this.removeChildConditionalReevaluate(behaviorTree, -1);
this.pushNode(behaviorTree, 0, 0);
}
/***
* 不传isPause的话默认删掉行为树
*/
disableBehavior(behavior, isPause = false) {
const behaviorTree = this.behaviorTreesMap.get(behavior);
if (!behaviorTree) {
return;
}
const index = this.behaviorTrees.findIndex((tree) => tree === behaviorTree);
// 数组删除该树,停止运行
index > -1 && this.behaviorTrees.splice(index, 1);
if (isPause) {
// 存进暂停map里
this.pausedBehaviorTreesMap.set(behavior, behaviorTree);
}
else {
this.behaviorTreesMap.delete(behavior);
}
}
enableBehavior(behavior) {
behavior.parse();
const rootNode = behavior.behaviorSource.rootNode;
if (!rootNode) {
if (behavior.logNodeChange) {
console.warn("该行为树没有根节点");
}
return;
}
// 仅被暂停的树从map里拿出来继续运行
if (this.pausedBehaviorTreesMap.has(behavior)) {
const behaviorTree = this.pausedBehaviorTreesMap.get(behavior);
this.pausedBehaviorTreesMap.delete(behavior);
this.behaviorTrees.push(behaviorTree);
this.behaviorTreesMap.set(behavior, behaviorTree);
return;
}
// 全新的树
const behaviorTree = new BehaviorTree_1.BehaviorTree();
behaviorTree.behavior = behavior;
this.behaviorTrees.push(behaviorTree);
this.behaviorTreesMap.set(behavior, behaviorTree);
behaviorTree.activeStack.push([]);
behaviorTree.parentIndex.push(-1);
behaviorTree.relativeChildIndex.push(-1);
behaviorTree.parentCompositeIndex.push(-1);
this.addToNodeList(behaviorTree, rootNode, { parentCompositeIndex: -1 });
this.pushNode(behaviorTree, 0, 0);
}
addToNodeList(behaviorTree, node, data) {
behaviorTree.nodeList.push(node);
const index = behaviorTree.nodeList.length - 1;
if (node instanceof ParentNode_1.ParentNode) {
behaviorTree.childrenIndex.push([]);
behaviorTree.childConditionalIndex.push([]);
for (let i = 0; i < node.children.length; i++) {
behaviorTree.parentIndex.push(index);
behaviorTree.relativeChildIndex.push(i);
behaviorTree.childrenIndex[index].push(behaviorTree.nodeList.length);
if (node instanceof Composite_1.Composite) {
data.parentCompositeIndex = index;
}
behaviorTree.parentCompositeIndex.push(data.parentCompositeIndex);
this.addToNodeList(behaviorTree, node.children[i], data);
}
}
else {
behaviorTree.childrenIndex.push(null);
behaviorTree.childConditionalIndex.push(null);
if (node instanceof Condition_1.Condition) {
const parentCompositeIndex = behaviorTree.parentCompositeIndex[index];
if (parentCompositeIndex !== -1) {
behaviorTree.childConditionalIndex[parentCompositeIndex].push(index);
}
}
}
}
update() {
this.tick();
}
tick() {
// this.reevaluateConditionalNode()
for (const behaviorTree of this.behaviorTrees) {
for (let i = behaviorTree.activeStack.length - 1; i >= 0; i--) {
const stack = behaviorTree.activeStack[i];
let prevNodeIndex = -1;
let prevStatus = enum_1.NodeStatus.Inactive;
while (prevStatus !== enum_1.NodeStatus.Running && i < behaviorTree.activeStack.length && stack.length) {
const curNodeIndex = stack[stack.length - 1];
// console.log("prevStatus", prevStatus, "curNodeIndex", curNodeIndex);
if (curNodeIndex === prevNodeIndex) {
break;
}
prevNodeIndex = curNodeIndex;
prevStatus = this.runNode(behaviorTree, curNodeIndex, i, prevStatus);
}
}
}
}
runNode(behaviorTree, index, stackIndex, prevStatus) {
this.pushNode(behaviorTree, index, stackIndex);
const node = behaviorTree.nodeList[index];
let status = prevStatus;
if (node instanceof ParentNode_1.ParentNode) {
status = this.runParentNode(behaviorTree, index, stackIndex, status);
if (node.canRunParallelChildren()) {
status = node.status;
}
}
else {
status = node.onUpdate();
}
if (status !== enum_1.NodeStatus.Running) {
status = this.popNode(behaviorTree, index, stackIndex, status);
}
return status;
}
runParentNode(behaviorTree, index, stackIndex, status) {
const node = behaviorTree.nodeList[index];
if (!node.canRunParallelChildren() || node.status !== enum_1.NodeStatus.Running) {
let childStatus = enum_1.NodeStatus.Inactive;
let preIndex = -1;
while (node.canExecute() && childStatus !== enum_1.NodeStatus.Running) {
const childIndex = node.index;
let curIndex = childIndex;
if (curIndex === preIndex) {
status = enum_1.NodeStatus.Running;
break;
}
preIndex = curIndex;
childStatus = status = this.runNode(behaviorTree, behaviorTree.childrenIndex[index][childIndex], stackIndex, status);
}
}
return status;
}
pushNode(behaviorTree, index, stackIndex) {
const stack = behaviorTree.activeStack[stackIndex];
if (stack.length === 0 || stack[stack.length - 1] !== index) {
stack.push(index);
const node = behaviorTree.nodeList[index];
if (behaviorTree.behavior.logNodeChange) {
console.log("pushNode", node);
}
node.onStart();
}
}
popNode(behaviorTree, index, stackIndex, status, popChildren = true) {
const stack = behaviorTree.activeStack[stackIndex];
stack.pop();
const node = behaviorTree.nodeList[index];
node.onEnd();
if (behaviorTree.behavior.logNodeChange) {
console.log("popNode", node);
}
const parentIndex = behaviorTree.parentIndex[index];
if (parentIndex !== -1) {
if (node instanceof Condition_1.Condition) {
const parentCompositeIndex = behaviorTree.parentCompositeIndex[index];
if (parentCompositeIndex !== -1) {
const composite = behaviorTree.nodeList[parentCompositeIndex];
//自己是条件节点并且父级的中断类型存在,创建重判断实例
if (composite.abortType !== enum_1.AbortType.None) {
if (behaviorTree.conditionalReevaluateMap.has(index)) {
const conditionalReevaluate = behaviorTree.conditionalReevaluateMap.get(index);
// @ts-ignore
conditionalReevaluate.compositeIndex = -1;
// @ts-ignore
conditionalReevaluate.status = status;
}
else {
const conditionalReevaluate = new BehaviorTree_1.ConditionalReevaluate(index, stackIndex, status, composite.abortType === enum_1.AbortType.LowerPriority ? -1 : parentCompositeIndex);
behaviorTree.conditionalReevaluate.push(conditionalReevaluate);
behaviorTree.conditionalReevaluateMap.set(index, conditionalReevaluate);
}
}
}
}
const parentNode = behaviorTree.nodeList[parentIndex];
if (node instanceof ParentNode_1.ParentNode) {
status = node.decorate(status);
}
parentNode.onChildExecuted(status, behaviorTree.relativeChildIndex[index]);
}
if (node instanceof Composite_1.Composite) {
//类型是Self或者自己是None但是子Composite是LowPriority结束的时候清空所有中断
if (node.abortType === enum_1.AbortType.Self || node.abortType === enum_1.AbortType.None || !stack.length) {
this.removeChildConditionalReevaluate(behaviorTree, index);
}
else if (node.abortType === enum_1.AbortType.LowerPriority || node.abortType === enum_1.AbortType.Both) {
//自己是有中断类型的组合节点,把直接孩子使用权交给自己的父级
for (let i = 0; i < behaviorTree.childConditionalIndex[index].length; i++) {
const childConditionalIndex = behaviorTree.childConditionalIndex[index][i];
if (behaviorTree.conditionalReevaluateMap.has(childConditionalIndex)) {
const conditionalReevaluate = behaviorTree.conditionalReevaluateMap.get(childConditionalIndex);
// @ts-ignore
conditionalReevaluate.compositeIndex = this.parentCompositeIndex[index];
}
}
//所有重条件使用权是自己的话,交给自己的父级
for (let i = 0; i < behaviorTree.conditionalReevaluate.length; i++) {
const conditionalReevaluate = behaviorTree.conditionalReevaluate[i];
if (conditionalReevaluate.compositeIndex === index) {
conditionalReevaluate.compositeIndex = behaviorTree.parentCompositeIndex[index];
}
}
}
}
if (popChildren) {
//并行节点删除其他正在运行的子节点
for (let i = behaviorTree.activeStack.length - 1; i > stackIndex; i--) {
const stack = behaviorTree.activeStack[i];
if (stack.length > 0 && this.isParentNode(behaviorTree, index, stack[stack.length - 1])) {
for (let j = stack.length - 1; j >= 0; j--) {
this.popNode(behaviorTree, stack[stack.length - 1], i, enum_1.NodeStatus.Failure, false);
}
}
}
}
if (stack.length === 0) {
if (stackIndex === 0) {
if (behaviorTree.behavior.restartWhenComplete) {
this.restart(behaviorTree);
}
}
else {
behaviorTree.activeStack.splice(stackIndex, 1);
}
}
return status;
}
reevaluateConditionalNode(behaviorTree) {
for (let i = behaviorTree.conditionalReevaluate.length - 1; i >= 0; i--) {
const { index, compositeIndex, status: prevStatus } = behaviorTree.conditionalReevaluate[i];
//爸爸组合节点索引不存在
if (compositeIndex === -1) {
continue;
}
const node = behaviorTree.nodeList[index];
const status = node.onUpdate();
//条件一致
if (status === prevStatus) {
continue;
}
for (let j = behaviorTree.activeStack.length - 1; j >= 0; j--) {
const stack = behaviorTree.activeStack[j];
if (!stack.length) {
continue;
}
let curNodeIndex = stack[stack.length - 1];
const commonParentIndex = this.findCommonParentIndex(behaviorTree, curNodeIndex, index);
//当前节点及他到公共父节点之类所有父节点pop出去
if (this.isParentNode(behaviorTree, compositeIndex, commonParentIndex)) {
const stackLen = behaviorTree.activeStack.length;
while (curNodeIndex !== -1 &&
curNodeIndex !== commonParentIndex &&
behaviorTree.activeStack.length === stackLen) {
this.popNode(behaviorTree, curNodeIndex, j, enum_1.NodeStatus.Failure, false);
curNodeIndex = behaviorTree.parentIndex[curNodeIndex];
}
}
}
//右边的包括自己的重评估条件删除掉
for (let j = behaviorTree.conditionalReevaluate.length - 1; j >= i; j--) {
const conditionalReevaluate = behaviorTree.conditionalReevaluate[j];
if (this.isParentNode(behaviorTree, compositeIndex, conditionalReevaluate.index)) {
behaviorTree.conditionalReevaluateMap.delete(conditionalReevaluate.index);
behaviorTree.conditionalReevaluate.splice(j, 1);
}
}
//同一低优先级中断父级下的左边元素都不执行了
const compositeNode = behaviorTree.nodeList[behaviorTree.parentCompositeIndex[index]];
for (let j = i - 1; j >= 0; j--) {
const conditionalReevaluate = behaviorTree.conditionalReevaluate[j];
if (behaviorTree.parentCompositeIndex[conditionalReevaluate.index] === behaviorTree.parentCompositeIndex[index]) {
if (compositeNode.abortType === enum_1.AbortType.LowerPriority) {
conditionalReevaluate.compositeIndex = -1;
// this.conditionalReevaluateMap.delete(conditionalReevaluate.index)
// this.conditionalReevaluate.splice(j, 1)
// i--;
}
else {
// for (let k = 0; k < this.childrenIndex[compositeIndex].length; k++) {
// let num4 = this.childrenIndex[compositeIndex][k]
// if (this.isParentNode(num4, conditionalReevaluate.index)) {
// while (this.nodeList[num4] instanceof Decorator) {
// num4 = this.childrenIndex[num4][0];
// }
// if (this.nodeList[num4] instanceof Composite) {
// conditionalReevaluate.compositeIndex = num4;
// }
// break;
// }
// }
}
}
}
//中断节点以上到组合节点执行onConditionalAbort
const conditionalParentIndex = [];
for (let m = behaviorTree.parentIndex[index]; m != compositeIndex; m = behaviorTree.parentIndex[m]) {
conditionalParentIndex.push(m);
}
conditionalParentIndex.push(compositeIndex);
for (let n = conditionalParentIndex.length - 1; n >= 0; n--) {
const parentTask = behaviorTree.nodeList[conditionalParentIndex[n]];
if (n === 0) {
parentTask.onConditionalAbort(behaviorTree.relativeChildIndex[index]);
}
else {
parentTask.onConditionalAbort(behaviorTree.relativeChildIndex[conditionalParentIndex[n - 1]]);
}
}
}
}
removeChildConditionalReevaluate(behaviorTree, compositeIndex) {
for (let i = behaviorTree.conditionalReevaluate.length - 1; i >= 0; i--) {
if (behaviorTree.conditionalReevaluate[i].compositeIndex === compositeIndex) {
behaviorTree.conditionalReevaluateMap.delete(behaviorTree.conditionalReevaluate[i].index);
behaviorTree.conditionalReevaluate.splice(i, 1);
}
}
}
findCommonParentIndex(behaviorTree, index1, index2) {
const set = new Set();
let num = index1;
while (num !== -1) {
set.add(num);
num = behaviorTree.parentIndex[num];
}
num = index2;
while (!set.has(num)) {
num = behaviorTree.parentIndex[num];
}
return num;
}
isParentNode(behaviorTree, possibleParent, possibleChild) {
for (let num = possibleChild; num !== -1; num = behaviorTree.parentIndex[num]) {
if (num === possibleParent) {
return true;
}
}
return false;
}
};
BehaviorManager.instance = null;
BehaviorManager = __decorate([
ccclass("BehaviorManager")
], BehaviorManager);
exports.BehaviorManager = BehaviorManager;