384 lines
18 KiB
JavaScript
Raw Permalink Normal View History

2023-09-21 01:32:11 +08:00
"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;