123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311 |
- /** @format */
- import {ComAttackable} from '../ECS/components/ComAttackable'
- import {ComCocosNode} from '../ECS/components/ComCocosNode'
- import {ComMovable} from '../ECS/components/ComMovable'
- import {ComTransform} from '../ECS/components/ComTransform'
- import {SysBehaviorTree} from '../ECS/systems/SysBehaviorTree'
- import {EventAttack, EventDie, EventSkill, EventStopSkill} from '../ECS/core/NodeEvent'
- import {ComFindEnemy} from '../ECS/components/ComFindEnemy'
- import {ComRole} from '../ECS/components/ComRole'
- import {ComDizzy} from '../ECS/components/ComDizzy'
- import {ComSkillAbel} from '../ECS/components/ComSkillAbel'
- import {ccUtils} from '../utils/ccUtils'
- import {FightWorld} from '../ECS/worlds/FightWorld'
- import {Data} from '../GameControl'
- import {FILTER_CAN_ATTACK_ENEMY, FILTER_CAN_ATTACK_FRIEND} from '../ECS/systems/SysFindEnemy'
- import {Log} from '../utils/LogUtils'
- import {BUFF_EFFECT_TYPE, ENTRY, ROLE_TYPE, SKILL_TYPE} from '../enums/Enum'
- import {EventProcess} from '../ECS/core/EventProcess'
- export namespace BT {
- export class BlackBoard {}
- export class ExecuteContext {
- executor: SysBehaviorTree
- world: FightWorld
- bb: BlackBoard
- entity: number
- dt: number
- public init(executor: SysBehaviorTree, world: FightWorld) {
- this.executor = executor
- this.world = world
- }
- public set(entity: number, dt: number, bb: BlackBoard) {
- this.entity = entity
- this.dt = dt
- this.bb = bb
- }
- }
- /** 节点状态 */
- export enum NodeState {
- Executing, // 执行中
- Success, // 成功
- Fail, // 失败
- }
- /** 节点类型 */
- export enum NodeType {
- // 组合节点
- LockedSequence, // 锁状态顺序节点
- Sequence, //
- Selector, // 选择节点
- RandomSelector, // 随机选择节点
- Parallel, // 并行节点
- RootSelector, //行为树根选择节点,每帧会循环进入所有子节点
- // 修饰节点
- Inverter, // 逆变节点
- Success, // 成功节点
- Fail, // 失败节点
- Repeater, // 重复节点
- RetryTillSuccess, // 重复直到成功
- // 叶子结点
- Wait, // 等待
- Action,
- WalkToCloseTarget, // 往最近的敌人移动 往敌方X方向移动,到达条件会往敌方X,Y方向一起移动
- MeleeWalkToTarget, // 近战移动到即将攻击目标的攻击点
- MeleeMonitor, // 近战监测目标敌人是否进入近战接触范围,进入近战接触范围,会往敌方X,Y方向一起移动
- MeleeXMonitor, // 当X轴没有敌人再去判断近战监测范围
- AttackMonitor, // 监测目标敌人是否进入攻击范围
- Attack, // 攻击
- WillAttackNotWillAttack, // 将要攻击的敌人将要攻击
- WillAttack, //将要攻击敌人
- WillBeAttack, //将要被攻击
- HasAttackEnemy, //有正在攻击的敌人
- FindEnemy, // 有没有最近的敌人
- HasBeAttack, // 有没有最近的敌人
- BeDizzy, // 被晕眩
- Dizzy, // 晕眩中
- HasSkill, // 是否有技能能施放
- CastSkill, // 技能施放中
- Skill, // 技能施放
- Stop, //停止移动
- StopAttack, //停止攻击
- StopSkill, //停止吟唱技能
- }
- export class NodeBase {
- public type: NodeType
- public state: NodeState = NodeState.Success
- public failLog: string
- public successLog: string
- constructor(type: NodeType) {
- this.type = type
- }
- }
- let debug = CC_DEV
- /** 组合节点 */
- class CombineNode extends NodeBase {
- public children: NodeBase[] = []
- public constructor(type: NodeType, children: NodeBase[]) {
- super(type)
- this.children = children
- }
- }
- export class SequenceNode extends CombineNode {
- public currIdx = 0
- public ignoreFailure = false
- constructor(children: NodeBase[], ignoreFailture = false) {
- super(NodeType.Sequence, children)
- this.ignoreFailure = ignoreFailture
- }
- }
- /** 依次执行子节点, 遇到执行失败的则退出并返回失败, 全部执行成功则返回成功 */
- export class LockedSequenceNode extends CombineNode {
- public currIdx = 0
- public ignoreFailure = false
- constructor(children: NodeBase[], ignoreFailture = false) {
- super(NodeType.LockedSequence, children)
- this.ignoreFailure = ignoreFailture
- }
- }
- /** 依次执行子节点, 遇到执行成功的则退出并返回成功, 全部执行失败则返回失败 */
- export class SelectorNode extends CombineNode {
- public currIdx: number = -1
- constructor(children: NodeBase[]) {
- super(NodeType.Selector, children)
- }
- }
- /** 行为树根节点,类似SelectorNode,但是会比SelectorNode多一些逻辑,进入节点后会直接update子节点 */
- export class RootSelectorNode extends CombineNode {
- public currIdx: number = -1
- public isMelee = true
- constructor(children: NodeBase[], isMelee = true) {
- super(NodeType.RootSelector, children)
- this.isMelee = isMelee
- }
- }
- /** 根据权重随机选择执行某个子节点 */
- export class RandomSelectorNode extends CombineNode {
- public weights: number[] // 权重
- public currIdx = -1 // 选中的节点
- constructor(children: NodeBase[], weigets?: number[]) {
- super(NodeType.RandomSelector, children)
- this.weights = weigets ? weigets : new Array(children.length).fill(1)
- }
- }
- /** 并行执行所有子节点, 全部执行完毕后返回 */
- export class ParallelNode extends CombineNode {
- public ignoreFailture = true
- constructor(children: NodeBase[], ignoreFailture?: boolean) {
- super(NodeType.Parallel, children)
- this.ignoreFailture = ignoreFailture
- }
- }
- /** 修饰节点 */
- class DecoratorNode extends NodeBase {
- public child: NodeBase = null
- public constructor(type: NodeType, child: NodeBase) {
- super(type)
- this.child = child
- }
- }
- /** 返回子节点执行结果的取反值 */
- export class InverterNode extends DecoratorNode {
- constructor(child: NodeBase) {
- super(NodeType.Inverter, child)
- }
- }
- /** 子节点执行完毕后, 必定返回成功 */
- export class SuccessNode extends DecoratorNode {
- constructor(child: NodeBase) {
- super(NodeType.Success, child)
- }
- }
- /** 子节点执行完毕后, 必定返回失败 */
- export class FailNode extends DecoratorNode {
- constructor(child: NodeBase) {
- super(NodeType.Fail, child)
- }
- }
- /** 子节点执行重复repeatCount次后返回成功 */
- export class RepeaterNode extends DecoratorNode {
- public repeatCount = 1
- public currRepeatCount = 0
- public mustSuccess = false // 子节点必须支持成功才增加重复次数
- constructor(child: NodeBase, repeatCount: number, mustSuccess = false) {
- super(NodeType.Repeater, child)
- this.repeatCount = repeatCount
- this.mustSuccess = mustSuccess
- }
- }
- /** 子节点重复执行直到返回成功 */
- export class RetryTillSuccess extends DecoratorNode {
- timeout: number // 超时时间
- countDown: number // 剩余时间
- constructor(child: NodeBase, timeout: number) {
- super(NodeType.RetryTillSuccess, child)
- this.timeout = timeout
- }
- }
- /** 叶子结点 */
- export class WaitNode extends NodeBase {
- public waitSeconds: number
- public countDown: number
- constructor(seconds: number) {
- super(NodeType.Wait)
- this.waitSeconds = seconds
- }
- }
- export class WalkToCloseTargetNode extends NodeBase {
- public speed: number
- public isCloseX: boolean
- constructor(speed: number, isCloseX: boolean) {
- super(NodeType.WalkToCloseTarget)
- this.speed = speed
- this.isCloseX = isCloseX
- }
- }
- /** 移动到目标攻击位置后 返回成功 */
- export class MeleeWalkToTargetNode extends NodeBase {
- public speed: number
- constructor(speed: number) {
- super(NodeType.MeleeWalkToTarget)
- this.speed = speed
- }
- }
- export class MeleeMonitorNode extends NodeBase {
- constructor() {
- super(NodeType.MeleeMonitor)
- }
- }
- export class MeleeXMonitorNode extends NodeBase {
- constructor() {
- super(NodeType.MeleeXMonitor)
- }
- }
- export class AttackMonitorNode extends NodeBase {
- constructor() {
- super(NodeType.AttackMonitor)
- }
- }
- export class AttackNode extends NodeBase {
- constructor() {
- super(NodeType.Attack)
- }
- }
- /** 将要攻击的目标 */
- export class WillAttackNode extends NodeBase {
- constructor() {
- super(NodeType.WillAttack)
- }
- }
- /** 将要被攻击的目标 */
- export class WillBeAttackNode extends NodeBase {
- constructor() {
- super(NodeType.WillBeAttack)
- }
- }
- /** 有正在攻击的目标 */
- export class HasAttackEnemyNode extends NodeBase {
- constructor() {
- super(NodeType.HasAttackEnemy)
- }
- }
- export class WillAttackNotWillAttackNode extends NodeBase {
- constructor() {
- super(NodeType.WillAttackNotWillAttack)
- }
- }
- export class BeDizzyNode extends NodeBase {
- constructor() {
- super(NodeType.BeDizzy)
- }
- }
- export class DizzyNode extends NodeBase {
- constructor() {
- super(NodeType.Dizzy)
- }
- }
- export class HasSkillNode extends NodeBase {
- constructor() {
- super(NodeType.HasSkill)
- }
- }
- export class SkillNode extends NodeBase {
- constructor() {
- super(NodeType.Skill)
- }
- }
- export class CastSkillNode extends NodeBase {
- constructor() {
- super(NodeType.CastSkill)
- }
- }
- export class FindEnemyNode extends NodeBase {
- constructor() {
- super(NodeType.FindEnemy)
- }
- }
- export class HasBeAttackNode extends NodeBase {
- constructor() {
- super(NodeType.HasBeAttack)
- }
- }
- export class StopNode extends NodeBase {
- constructor() {
- super(NodeType.Stop)
- }
- }
- export class StopAttackNode extends NodeBase {
- constructor() {
- super(NodeType.StopAttack)
- }
- }
- export class StopSkillNode extends NodeBase {
- constructor() {
- super(NodeType.StopSkill)
- }
- }
- class NodeHandler {
- onEnter: (node: NodeBase, context: ExecuteContext) => void
- onUpdate: (node: NodeBase, context: ExecuteContext) => void
- }
- export const NodeHandlers: NodeHandler[] = []
- /** Sequence node */
- NodeHandlers[NodeType.Sequence] = {
- onEnter(node: SequenceNode, context: ExecuteContext): void {
- node.currIdx = 0
- context.executor.onEnterBTNode(node.children[node.currIdx], context)
- node.state = NodeState.Executing
- },
- onUpdate(node: SequenceNode, context: ExecuteContext): void {
- if (node.currIdx < 0 || node.currIdx >= node.children.length) {
- // 越界了, 不应该发生, 直接认为是失败了
- node.state = NodeState.Fail
- if (debug) node.failLog = '越界了, 不应该发生, 直接认为是失败了'
- return
- }
- // 检查前置条件是否满足
- for (let i = 0; i < node.currIdx; i++) {
- context.executor.updateBTNode(node.children[i], context)
- if (node.children[i].state !== NodeState.Success) {
- //当前置条件不满足,节点应该失败
- node.state = NodeState.Fail
- if (debug) node.failLog = '队列行为被前置打断===Sequence Fail==>' + node.children[i].failLog
- return
- }
- }
- context.executor.updateBTNode(node.children[node.currIdx], context)
- const state = node.children[node.currIdx].state
- if (node.currIdx == 4 && context.entity == debugEntity)
- console.log('state', state, state == NodeState.Executing)
- if (state == NodeState.Executing) return
- if (state == NodeState.Fail && !node.ignoreFailure) {
- node.state = NodeState.Fail
- if (debug) node.failLog = '队列中断==>' + node.children[node.currIdx].failLog
- return
- }
- if (state == NodeState.Success && node.currIdx == node.children.length - 1) {
- node.state = NodeState.Success
- if (debug) node.successLog = '队列成功==>' + node.children[node.currIdx].successLog
- return
- }
- context.executor.onEnterBTNode(node.children[++node.currIdx], context)
- },
- }
- // 子节点某个节点在中途失败,不影响后续节点执行,后续节点执行完结束队列,举个例子 攻击动作1秒 --》 等待2秒,如果攻击动作在0.5秒被打断,这个队列节点也要等到2秒后结束
- /** LockedSequence node */
- NodeHandlers[NodeType.LockedSequence] = {
- onEnter(node: LockedSequenceNode, context: ExecuteContext): void {
- node.currIdx = 0
- context.executor.onEnterBTNode(node.children[node.currIdx], context)
- node.state = NodeState.Executing
- },
- onUpdate(node: LockedSequenceNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- if (node.currIdx < 0 || node.currIdx >= node.children.length) {
- // 越界了, 不应该发生, 直接认为是失败了
- node.state = NodeState.Fail
- return
- }
- context.executor.updateBTNode(node.children[node.currIdx], context)
- let state = node.children[node.currIdx].state
- if (state == NodeState.Executing) return
- if (state === NodeState.Fail && !node.ignoreFailure) {
- node.state = NodeState.Fail
- return
- }
- if (state === NodeState.Success && node.currIdx == node.children.length - 1) {
- node.state = NodeState.Success
- return
- }
- context.executor.onEnterBTNode(node.children[++node.currIdx], context)
- },
- }
- /** Selector node */
- NodeHandlers[NodeType.Selector] = {
- onEnter(node: SelectorNode, context: ExecuteContext): void {
- node.currIdx = 0
- context.executor.onEnterBTNode(node.children[node.currIdx], context)
- node.state = NodeState.Executing
- },
- onUpdate(node: SelectorNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- if (node.currIdx < 0 || node.currIdx >= node.children.length) {
- // 越界了, 认为是失败了
- node.state = NodeState.Fail
- return
- }
- context.executor.updateBTNode(node.children[node.currIdx], context)
- let state = node.children[node.currIdx].state
- if (state == NodeState.Executing) return
- // 执行到最后一个都失败了, 那边selector失败了
- if (state === NodeState.Fail && node.currIdx == node.children.length - 1) {
- node.state = NodeState.Fail
- return
- }
- if (state == NodeState.Success) {
- node.state = NodeState.Success
- return
- }
- context.executor.onEnterBTNode(node.children[++node.currIdx], context)
- },
- }
- export let debugEntity: number = -1
- let debugEntityCurIdx: number = -1
- let rootSelectorLog = ['晕眩', '放技能', '攻击', '往X轴敌人移动', '停止']
- let meleeRootSelectorLog = [
- '晕眩',
- '放技能',
- '寻敌',
- '往X轴敌人移动',
- '往敌人移动',
- '将被攻击',
- '将攻击敌人',
- '攻击',
- '停止',
- ]
- /** UpdateSelector node */
- NodeHandlers[NodeType.RootSelector] = {
- onEnter(node: RootSelectorNode, context: ExecuteContext): void {
- node.currIdx = 0
- context.executor.onEnterBTNode(node.children[node.currIdx], context)
- node.state = NodeState.Executing
- this.onUpdate(node, context)
- },
- onUpdate(node: RootSelectorNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- if (node.currIdx < 0 || node.currIdx >= node.children.length) {
- // 越界了, 认为是失败了
- node.state = NodeState.Fail
- return
- }
- while (node.currIdx < node.children.length) {
- context.executor.updateBTNode(node.children[node.currIdx], context)
- let state = node.children[node.currIdx].state
- if (state == NodeState.Executing) break
- // 执行到最后一个都失败了, 那边selector失败了
- if (state === NodeState.Fail && node.currIdx == node.children.length - 1) {
- node.state = NodeState.Fail
- break
- }
- if (state == NodeState.Success) {
- if (context.entity == debugEntity && node.currIdx != debugEntityCurIdx) {
- let failStr = ''
- let debugRootLog = node.isMelee ? meleeRootSelectorLog : rootSelectorLog
- for (let i = 0; i < node.currIdx; i++) {
- failStr += `[${debugRootLog[i]}]` + '(' + node.children[i].failLog + ')'
- }
- console.log('--------', context.entity, '--------', 'RootSelector Fail ', failStr)
- console.log(
- 'RootSelector Success ',
- debugRootLog[node.currIdx],
- node.children[node.currIdx].successLog,
- '--------',
- context.entity,
- '--------',
- )
- node.currIdx = debugEntityCurIdx
- }
- node.state = NodeState.Success
- break
- }
- context.executor.onEnterBTNode(node.children[++node.currIdx], context)
- }
- },
- }
- /** Selector node */
- NodeHandlers[NodeType.RandomSelector] = {
- onEnter(node: RandomSelectorNode, context: ExecuteContext): void {
- // 根据权重随机获取idx
- let totalWeight = 0
- for (const weight of node.weights) {
- totalWeight += weight
- }
- let randomWeight = Math.random() * totalWeight
- for (let i = 0; i < node.weights.length; i++) {
- randomWeight -= node.weights[i]
- if (randomWeight <= 0) {
- node.currIdx = i
- break
- }
- }
- context.executor.onEnterBTNode(node.children[node.currIdx], context)
- node.state = NodeState.Executing
- },
- onUpdate(node: RandomSelectorNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- let n = node.children[node.currIdx]
- context.executor.updateBTNode(n, context)
- node.state = n.state
- },
- }
- /** Parallel node */
- NodeHandlers[NodeType.Parallel] = {
- onEnter(node: ParallelNode, context: ExecuteContext): void {
- for (const n of node.children) {
- context.executor.onEnterBTNode(n, context)
- }
- node.state = NodeState.Executing
- },
- onUpdate(node: ParallelNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- let end = true
- for (const child of node.children) {
- context.executor.updateBTNode(child, context)
- if (child.state === NodeState.Executing) {
- end = false
- continue
- }
- if (child.state == NodeState.Fail) {
- node.state = NodeState.Fail
- return
- }
- }
- if (end) {
- node.state = NodeState.Success
- }
- },
- }
- /** Inverter node */
- NodeHandlers[NodeType.Inverter] = {
- onEnter(node: InverterNode, context: ExecuteContext): void {
- context.executor.onEnterBTNode(node.child, context)
- node.state = NodeState.Executing
- },
- onUpdate(node: InverterNode, context: ExecuteContext): void {
- context.executor.updateBTNode(node.child, context)
- if (node.child.state === NodeState.Executing) return
- if (node.child.state == NodeState.Success) {
- node.state = NodeState.Fail
- if (debug) node.failLog = node.child.successLog
- }
- if (node.child.state == NodeState.Fail) {
- node.state = NodeState.Success
- if (debug) node.successLog = node.child.failLog
- }
- },
- }
- /** Success node */
- NodeHandlers[NodeType.Success] = {
- onEnter(node: SuccessNode, context: ExecuteContext): void {
- context.executor.onEnterBTNode(node.child, context)
- node.state = NodeState.Executing
- },
- onUpdate(node: SuccessNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- context.executor.updateBTNode(node.child, context)
- if (node.child.state === NodeState.Executing) return
- node.state = NodeState.Success
- },
- }
- /** Fail node */
- NodeHandlers[NodeType.Fail] = {
- onEnter(node: FailNode, context: ExecuteContext): void {
- context.executor.onEnterBTNode(node.child, context)
- node.state = NodeState.Executing
- },
- onUpdate(node: FailNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- context.executor.updateBTNode(node.child, context)
- if (node.child.state === NodeState.Executing) return
- node.state = NodeState.Fail
- },
- }
- /** Repeater node */
- NodeHandlers[NodeType.Repeater] = {
- onEnter(node: RepeaterNode, context: ExecuteContext): void {
- node.currRepeatCount = 0
- context.executor.onEnterBTNode(node.child, context)
- node.state = NodeState.Executing
- },
- onUpdate(node: RepeaterNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- context.executor.updateBTNode(node.child, context)
- if (node.child.state === NodeState.Executing) return
- if (!node.mustSuccess || node.child.state == NodeState.Success) node.currRepeatCount++
- if (node.currRepeatCount >= node.repeatCount) {
- node.state = NodeState.Success
- return
- }
- context.executor.onEnterBTNode(node.child, context)
- },
- }
- /** RetryTillSuccess node */
- NodeHandlers[NodeType.RetryTillSuccess] = {
- onEnter(node: RetryTillSuccess, context: ExecuteContext): void {
- node.countDown = node.timeout
- context.executor.onEnterBTNode(node.child, context)
- node.state = NodeState.Executing
- },
- onUpdate(node: RetryTillSuccess, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- node.countDown -= context.dt
- context.executor.updateBTNode(node.child, context)
- if (node.child.state === NodeState.Executing) return
- if (node.child.state == NodeState.Success) {
- node.state = NodeState.Success
- return
- }
- if (node.countDown > 0) {
- context.executor.onEnterBTNode(node.child, context)
- return
- }
- node.state = NodeState.Fail
- },
- }
- /** Wait node */
- NodeHandlers[NodeType.Wait] = {
- onEnter(node: WaitNode, context: ExecuteContext): void {
- node.countDown = node.waitSeconds
- node.state = NodeState.Executing
- },
- onUpdate(node: WaitNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- node.countDown -= context.dt
- if (node.countDown <= 0) {
- node.state = NodeState.Success
- }
- },
- }
- //-------------------------------------行为能执行的条件,每次行为update要执行条件--------------------------------------------------
- /** FindEnemy node 战场上有没有敌人 */
- NodeHandlers[NodeType.FindEnemy] = {
- onEnter(node: FindEnemyNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: FindEnemyNode, context: ExecuteContext): void {
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- node.state = !context.world.isDie(comFindEnemy?.enemy) ? NodeState.Success : NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '找到敌人==>' + comFindEnemy.enemy.toString()
- } else {
- node.failLog = '战场上没有敌人'
- }
- }
- },
- }
- /** MeleeMonitor node 是否进入Y轴近战监视区域 */
- NodeHandlers[NodeType.MeleeMonitor] = {
- onEnter(node: MeleeMonitorNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: MeleeMonitorNode, context: ExecuteContext): void {
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- node.state =
- comFindEnemy && comFindEnemy.cObject && comFindEnemy.cObject.containsBody.size > 0
- ? BT.NodeState.Success
- : BT.NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog =
- '敌人进入Y轴近战监视区域==>' + comFindEnemy.cObject.containsBody.keysArr().toString()
- } else {
- node.failLog = 'Y轴近战监视区域没有敌人'
- }
- }
- },
- }
- /** MeleeMonitor node 是否进入X轴近战监视区域 */
- NodeHandlers[NodeType.MeleeXMonitor] = {
- onEnter(node: MeleeXMonitorNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: MeleeXMonitorNode, context: ExecuteContext): void {
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- node.state =
- comFindEnemy && comFindEnemy.cObjectMeleeX && comFindEnemy.cObjectMeleeX.containsBody.size > 0
- ? BT.NodeState.Success
- : BT.NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog =
- '敌人进入X轴近战监视区域==>' + comFindEnemy.cObjectMeleeX.containsBody.keysArr().toString()
- } else {
- node.failLog = 'X轴近战监视区域没有敌人'
- }
- }
- },
- }
- /** AttackMonitor node 是否进入攻击范围*/
- NodeHandlers[NodeType.AttackMonitor] = {
- onEnter(node: AttackMonitorNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: AttackMonitorNode, context: ExecuteContext): void {
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- node.state =
- comFindEnemy && comFindEnemy.attackCObject && comFindEnemy.attackCObject.containsBody.size > 0
- ? BT.NodeState.Success
- : BT.NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog =
- '敌人进入攻击范围==>' + comFindEnemy.attackCObject.containsBody.keysArr().toString()
- } else {
- node.failLog = '没有敌人进入攻击范围'
- }
- }
- },
- }
- /** WillAttackNotWillAttack node 近战即将攻击的目标有没有即将攻击的目标*/
- NodeHandlers[NodeType.WillAttackNotWillAttack] = {
- onEnter(node: WillAttackNotWillAttackNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: WillAttackNotWillAttackNode, context: ExecuteContext): void {
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- let comMovable = context.world.getComponent(comFindEnemy?.willAttackMelee, ComMovable)
- node.state = comMovable.speed ? NodeState.Fail : NodeState.Success
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '近战即将攻击的目标正在走路==>' + comFindEnemy?.willAttackMelee
- } else {
- node.failLog = '近战即将攻击的目标停止了==>' + comFindEnemy?.willAttackMelee
- }
- }
- },
- }
- /** WillAttackNode node 近战即将攻击敌人*/
- NodeHandlers[NodeType.WillAttack] = {
- onEnter(node: WillAttackNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: WillAttackNode, context: ExecuteContext): void {
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- node.state = !context.world.isDie(comFindEnemy?.willAttackMelee) ? BT.NodeState.Success : BT.NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '近战有即将攻击的敌人==>' + comFindEnemy?.willAttackMelee
- } else {
- node.failLog = '近战没有即将攻击敌人'
- }
- }
- },
- }
- /** WillAttackNode node 近战即将被敌人攻击*/
- NodeHandlers[NodeType.WillBeAttack] = {
- onEnter(node: WillBeAttackNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: WillBeAttackNode, context: ExecuteContext): void {
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- node.state = !context.world.isDie(comFindEnemy?.willBeAttackMelee)
- ? BT.NodeState.Success
- : BT.NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '近战即将被敌人攻击==>' + comFindEnemy?.willBeAttackMelee
- } else {
- node.failLog = '近战没有近战即将被敌人攻击'
- }
- }
- },
- }
- /** HasAttackEnemy node 近战有没有正在攻击的敌人*/
- NodeHandlers[NodeType.HasAttackEnemy] = {
- onEnter(node: HasAttackEnemyNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: HasAttackEnemyNode, context: ExecuteContext): void {
- let comAttackable = context.world.getComponent(context.entity, ComAttackable)
- node.state = !context.world.isDie(comAttackable?.curAttack) ? BT.NodeState.Success : BT.NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '近战正在攻击的敌==>' + comAttackable?.curAttack
- } else {
- node.failLog = '近战没有正在攻击的敌人'
- }
- }
- },
- }
- /** BeDizzy node 是否被晕眩*/
- NodeHandlers[NodeType.BeDizzy] = {
- onEnter(node: BeDizzyNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: BeDizzyNode, context: ExecuteContext): void {
- let comDizzy = context.world.getComponent(context.entity, ComDizzy)
- node.state = comDizzy && comDizzy.countDown > 0 ? NodeState.Success : NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '被晕眩='
- } else {
- node.failLog = '没被晕眩'
- }
- }
- },
- }
- /** HasSkill node 有没有技能可以施放*/
- // 所有的判断条件每次都要判断
- NodeHandlers[NodeType.HasSkill] = {
- onEnter(node: HasSkillNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: HasSkillNode, context: ExecuteContext): void {
- let comSkillAbel = context.world.getComponent(context.entity, ComSkillAbel)
- if (!comSkillAbel) {
- //console.log('HasSkill onUpdate', '目标没有ComSkillAbel', context.entity)
- node.state = NodeState.Fail
- return
- }
- node.state =
- comSkillAbel &&
- comSkillAbel.skillConfig &&
- comSkillAbel.roles.length >= comSkillAbel.skillConfig.minRole
- ? NodeState.Success
- : NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = `有技能可以施放===>${
- comSkillAbel.skillConfig.name
- }==>技能目标${comSkillAbel.roles.toString()}`
- } else {
- node.failLog = `没有技能可以施放===>技能目标人数:${comSkillAbel.roles.length}技能:${comSkillAbel.skillConfig?.name}正在施放:${comSkillAbel.dirty}`
- }
- }
- },
- }
- /** CastSkill node 正在施放技能*/
- // 所有的判断条件每次都要判断
- NodeHandlers[NodeType.CastSkill] = {
- onEnter(node: HasSkillNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: HasSkillNode, context: ExecuteContext): void {
- let comSkillAbel = context.world.getComponent(context.entity, ComSkillAbel)
- if (!comSkillAbel) {
- //console.log('HasSkill onUpdate', '目标没有ComSkillAbel', context.entity)
- node.state = NodeState.Fail
- return
- }
- node.state = comSkillAbel.dirty ? NodeState.Success : NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '正在施放技能'
- } else {
- node.failLog = '没有正在施放技能'
- }
- }
- },
- }
- /** BeDizzy node 是否即将被攻击*/
- NodeHandlers[NodeType.HasBeAttack] = {
- onEnter(node: HasBeAttackNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: HasBeAttackNode, context: ExecuteContext): void {
- let comAttackable = context.world.getComponent(context.entity, ComAttackable)
- node.state = comAttackable && comAttackable.beAttacks.length > 0 ? BT.NodeState.Success : BT.NodeState.Fail
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '被近战包围==>' + comAttackable.beAttacks.toString()
- } else {
- node.failLog = '没有被近战包围'
- }
- }
- },
- }
- //-------------------------------------行为--------------------------------------------------
- /** MeleeWalkToTarget node */
- NodeHandlers[NodeType.MeleeWalkToTarget] = {
- onEnter(node: MeleeWalkToTargetNode, context: ExecuteContext): void {
- let comTrans = context.world.getComponent(context.entity, ComTransform)
- let comMovable = context.world.getComponent(context.entity, ComMovable)
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- let targetComTrans = context.world.getComponent(comFindEnemy.willAttackMelee, ComTransform)
- let targetComMovable = context.world.getComponent(comFindEnemy.willAttackMelee, ComMovable)
- let targetPos = context.world.moveToMeleeAttackPos(
- context.entity,
- comTrans,
- targetComTrans,
- targetComMovable,
- )
- comMovable.pointIdx = 0
- comMovable.points.length = 0
- comMovable.points.push(targetPos)
- //加速前往近战攻击点
- context.world.changeMoveSpeed(context.entity, node.speed)
- node.state = NodeState.Executing
- //console.log(' onEnter comFindEnemy.willAttackMelee', context.entity, comFindEnemy.willAttackMelee)
- },
- onUpdate(node: MeleeWalkToTargetNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- let comMovable = context.world.getComponent(context.entity, ComMovable)
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- let comAttackable = context.world.getComponent(context.entity, ComAttackable)
- //在进入行为之前满足条件,这时候运行到下一帧,可能在SysFindEnemy系统中修改了死亡的敌人comFindEnemy.willAttackMelee=0
- if (context.world.isDie(comFindEnemy.willAttackMelee)) {
- Log.error('MeleeWalkToTarget onUpdate', '将要攻击的敌人不存在', comFindEnemy.willAttackMelee)
- node.state = BT.NodeState.Fail
- return
- }
- if (
- comMovable.points.length == 0 ||
- comMovable.pointIdx < 0 ||
- comMovable.pointIdx >= comMovable.points.length
- ) {
- // 把将要击打变成击打
- comAttackable.curAttack = comFindEnemy.willAttackMelee
- let enemyComFindEnemy = context.world.getComponent(comAttackable.curAttack, ComFindEnemy)
- let enemyComAttackable = context.world.getComponent(comAttackable.curAttack, ComAttackable)
- // 敌人击打数组加入自己
- enemyComAttackable.beAttacks.push(context.entity)
- //如果敌人等待着自己将敌人攻击赋值
- if (enemyComFindEnemy && enemyComFindEnemy.willBeAttackMelee == context.entity) {
- enemyComFindEnemy.willBeAttackMelee = 0
- enemyComAttackable.curAttack = context.entity
- comAttackable.beAttacks.push(comAttackable.curAttack)
- }
- comFindEnemy.willAttackMelee = 0
- node.state = BT.NodeState.Success
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '走到了近战攻击点==>' + comAttackable.curAttack.toString()
- }
- }
- }
- },
- }
- /** WalkToClosedTarget node */
- NodeHandlers[NodeType.WalkToCloseTarget] = {
- onEnter(node: WalkToCloseTargetNode, context: ExecuteContext): void {
- let comTrans = context.world.getComponent(context.entity, ComTransform)
- let comMovable = context.world.getComponent(context.entity, ComMovable)
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- let comCocosNode = context.world.getComponent(context.entity, ComCocosNode)
- let comRole = context.world.getComponent(context.entity, ComRole)
- let comSpComCocosNode = context.world.getComponent(comRole.spineEntity, ComCocosNode)
- let targetComTrans = context.world.getComponent(comFindEnemy.enemy, ComTransform)
- comMovable.pointIdx = 0
- comMovable.points.length = 0
- comMovable.points.push(
- cc.v2(comTrans.x, comTrans.y),
- cc.v2(targetComTrans.x, node.isCloseX ? comTrans.y : targetComTrans.y),
- )
- context.world.changeMoveSpeed(context.entity, node.speed)
- comMovable.closeTarget = comFindEnemy.enemy
- comTrans.dir.x = targetComTrans.x > comTrans.x ? 1 : -1
- comCocosNode.node?.getComponent(EventProcess)?.syncDir(comTrans.dir)
- comSpComCocosNode?.node?.getComponent(EventProcess)?.syncDir(comTrans.dir)
- node.state = NodeState.Executing
- },
- onUpdate(node: WalkToCloseTargetNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- let comTrans = context.world.getComponent(context.entity, ComTransform)
- let comMovable = context.world.getComponent(context.entity, ComMovable)
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- let targetComTrans = context.world.getComponent(comFindEnemy.enemy, ComTransform)
- if (comMovable.points[1]) {
- comMovable.points[1].x = targetComTrans.x
- comMovable.points[1].y = node.isCloseX ? comTrans.y : targetComTrans.y
- }
- if (
- comMovable.points.length == 0 ||
- comMovable.pointIdx < 0 ||
- comMovable.pointIdx >= comMovable.points.length
- ) {
- node.state = BT.NodeState.Success
- }
- },
- }
- /** Attack node */
- NodeHandlers[NodeType.Attack] = {
- onEnter(node: AttackNode, context: ExecuteContext): void {
- //当攻击目标死亡,前置条件被打断,被再次执行攻击行为,这个时候要return
- if (node.state == NodeState.Executing) {
- return
- }
- let comCocosNode = context.world.getComponent(context.entity, ComCocosNode)
- let comAttackable = context.world.getComponent(context.entity, ComAttackable)
- let comRole = context.world.getComponent(context.entity, ComRole)
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- //远程每次切换最近的目标
- if (!comAttackable.isMelee) {
- comAttackable.curAttack = comFindEnemy.enemy
- }
- let enemyComTransform = context.world.getComponent(comAttackable.curAttack, ComTransform)
- let comTransform = context.world.getComponent(context.entity, ComTransform)
- //console.log('攻击节点 ------------------->', context.entity)
- comTransform.dir.x = comTransform?.x - enemyComTransform?.x < 0 ? 1 : -1
- let comSpineTransform = context.world.getComponent(comRole.spineEntity, ComTransform)
- if (comSpineTransform) {
- comSpineTransform.dir.x = comTransform.dir.x
- }
- let attackSpeed = Math.clampValue(comRole.attackSpeed, Data.game.minAttackSpeed, Data.game.maxAttackSpeed)
- let attackScale = Data.game.rateNum / attackSpeed
- let buffs = comRole.buffs
- let attackIndex = 0
- for (let i = 0; i < buffs.length; i++) {
- let tmpIndex = buffs[i].buffCfg.effectType.indexOf(BUFF_EFFECT_TYPE.changeSpineAttack)
- if (tmpIndex >= 0) {
- attackIndex = buffs[i].buffCfg.effectParm[tmpIndex][0]
- }
- }
- comCocosNode.events.push(
- new EventAttack(comTransform.dir, !comAttackable.isMelee, attackScale, attackIndex),
- )
- //同步spine攻击
- let comSpineNode = context.world.getComponent(comRole.spineEntity, ComCocosNode)
- comSpineNode?.events.push(
- new EventAttack(comTransform.dir, !comAttackable.isMelee, attackScale, attackIndex),
- )
- comAttackable.countDown = (comRole.attackTime + comRole.attackCD) * attackScale * Data.game.gameSpeed
- comAttackable.dirty = true
- comAttackable.hurtFrame =
- comAttackable.countDown - comRole.roleCfg.hurtFrame * attackScale * comRole.attackTime
- comAttackable.hurtFrameCompleted = false
- node.state = NodeState.Executing
- },
- onUpdate(node: AttackNode, context: ExecuteContext): void {
- if (node.state != NodeState.Executing) return
- let comAttackable = context.world.getComponent(context.entity, ComAttackable)
- let comFindEnemy = context.world.getComponent(context.entity, ComFindEnemy)
- let comRole = context.world.getComponent(context.entity, ComRole)
- //可能当前攻击敌人死亡
- // if (context.world.isDie(comAttackable?.curAttack)) {
- // //console.log('Attack onUpdate', '当前攻击敌人死亡', context.entity, comAttackable?.curAttack)
- // comAttackable.dirty = false
- // comAttackable.countDown = 0
- // node.state = NodeState.Fail
- // }
- if (comAttackable && comAttackable.countDown <= 0) {
- node.state = NodeState.Success
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '攻击行为成功==>' + comAttackable?.curAttack
- }
- }
- let comBeAttackRole: ComRole = context.world.getComponent(comAttackable.curAttack, ComRole)
- //当正在攻击对面基地的时候,敌军有别的单位,不在打基地了--》修改为Y轴探测范围内有人不再攻击基地
- if (context.world.isBase(comBeAttackRole)) {
- let filter = context.world.getFilter(
- comRole.group == Data.game.gFriend ? FILTER_CAN_ATTACK_ENEMY : FILTER_CAN_ATTACK_FRIEND,
- )
- if (filter.entities.size > 1 && comFindEnemy.cObject.containsBody.size > 1) {
- comAttackable.curAttack = 0
- }
- }
- }
- },
- }
- /** Skill node */
- NodeHandlers[NodeType.Skill] = {
- onEnter(node: SkillNode, context: ExecuteContext): void {
- let comSkillAbel = context.world.getComponent(context.entity, ComSkillAbel)
- let comCocosNode = context.world.getComponent(context.entity, ComCocosNode)
- let comRole = context.world.getComponent(context.entity, ComRole)
- if (!comSkillAbel || !comCocosNode || !comRole) {
- !comSkillAbel && console.log('Skill onEnter', '目标没有ComSkillAbel', context.entity)
- !comCocosNode && console.log('Skill onEnter', '目标没有ComCocosNode', context.entity)
- return
- }
- //console.log('施放技能', comSkillAbel.skillConfig.name)
- if (CC_DEV) ccUtils.setLabel(comSkillAbel.skillConfig.name, comCocosNode.node, 'skill')
- //技能无CD的buff只放一次
- let curSkillIndex = 0
- for (let i = 0; i < comRole.skills.length; i++) {
- if (comRole.skills[i].ID == comSkillAbel.skillConfig.ID) {
- curSkillIndex = i
- let cd = comRole.skillCDs[i]
- if (cd > 0 && cd != Data.game.cdMax && comRole.entryMap.get(ENTRY.skillCD)?.num) {
- cd *= 1 - comRole.entryMap.get(ENTRY.skillCD).num / Data.game.rateNum
- if (cd < 0) cd = 0
- }
- comRole.skillCountDowns[i] =
- (cd == 0 && comSkillAbel.skillConfig.type != SKILL_TYPE.holo) || cd == Data.game.cdMax
- ? Infinity
- : cd
- }
- }
- comSkillAbel.dirty = true
- comSkillAbel.startDirty = true
- comSkillAbel.skillDirty = true
- //吟唱时间
- comSkillAbel.countDown =
- comSkillAbel.skillConfig.castDuration > comRole.castTime[curSkillIndex]
- ? comSkillAbel.skillConfig.castDuration
- : comRole.castTime[curSkillIndex]
- let timeScale = 1 - comSkillAbel.skillConfig.castFrame
- if (timeScale > 1) timeScale = 1
- if (timeScale < 0) timeScale = 0
- comSkillAbel.castSkillTime = timeScale * comSkillAbel.countDown
- comCocosNode.events.push(
- new EventSkill(comSkillAbel.countDown, comRole.skills.indexOf(comSkillAbel.skillConfig)),
- )
- //同步spine吟唱
- let comSpineNode = context.world.getComponent(comRole.spineEntity, ComCocosNode)
- comSpineNode?.events.push(
- new EventSkill(comSkillAbel.countDown, comRole.skills.indexOf(comSkillAbel.skillConfig)),
- )
- node.state = NodeState.Executing
- },
- onUpdate(node: SkillNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- let comSkillAbel = context.world.getComponent(context.entity, ComSkillAbel)
- let comCocosNode = context.world.getComponent(context.entity, ComCocosNode)
- // 技能开始的时候没有技能施放目标停止施放技能
- if (comSkillAbel.skillConfig && comSkillAbel.roles.length == 0 && comSkillAbel.skillConfig.minRole > 0) {
- Log.error('Skill onUpdate', '没有技能施放目标停止施放技能', context.entity, comSkillAbel.skillConfig)
- let comRole = context.world.getComponent(context.entity, ComRole)
- let curSkillIndex = comRole.skills.findIndex(value => value.ID == comSkillAbel.skillConfig.ID)
- if (curSkillIndex >= 0) {
- //让技能可以重新被施放
- comRole.skillCountDowns[curSkillIndex] = 0
- }
- comSkillAbel.dirty = false
- node.state = NodeState.Fail
- }
- if (comSkillAbel && comSkillAbel.countDown <= 0) {
- comSkillAbel.dirty = false
- node.state = NodeState.Success
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '技能行为成功==>' + context.entity
- }
- }
- if (debug) ccUtils.setLabel('', comCocosNode.node, 'skill')
- }
- },
- }
- /** Dizzy node */
- NodeHandlers[NodeType.Dizzy] = {
- onEnter(node: DizzyNode, context: ExecuteContext): void {
- let comDizzy = context.world.getComponent(context.entity, ComDizzy)
- if (!comDizzy) {
- //console.log('Dizzy onEnter', '目标没有ComDizzy', context.entity)
- return
- }
- comDizzy.dirty = true
- node.state = NodeState.Executing
- },
- onUpdate(node: DizzyNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- },
- }
- /** StopNode node */
- NodeHandlers[NodeType.Stop] = {
- onEnter(node: StopNode, context: ExecuteContext): void {
- node.state = NodeState.Executing
- },
- onUpdate(node: StopNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- context.world.changeMoveSpeed(context.entity, 0)
- node.state = NodeState.Success
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '停止行为成功==>' + context.entity
- }
- }
- },
- }
- /** StopAttack node */
- NodeHandlers[NodeType.StopAttack] = {
- onEnter(node: StopAttackNode, context: ExecuteContext): void {
- let comAttackable = context.world.getComponent(context.entity, ComAttackable)
- if (!comAttackable) {
- Log.error('StopAttack onEnter', '目标没有ComAttackable', context.entity)
- return
- }
- node.state = NodeState.Executing
- },
- onUpdate(node: StopAttackNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- let comAttackable = context.world.getComponent(context.entity, ComAttackable)
- comAttackable.dirty = false
- comAttackable.countDown = 0
- node.state = NodeState.Success
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '停止攻击行为成功==>' + context.entity
- }
- }
- },
- }
- /** StopAttack node */
- NodeHandlers[NodeType.StopSkill] = {
- onEnter(node: StopAttackNode, context: ExecuteContext): void {
- let comSkill = context.world.getComponent(context.entity, ComSkillAbel)
- if (!comSkill) {
- Log.error('StopSkill onEnter', '目标没有ComSkill', context.entity)
- return
- }
- node.state = NodeState.Executing
- },
- onUpdate(node: StopAttackNode, context: ExecuteContext): void {
- if (node.state !== NodeState.Executing) return
- let comSkill = context.world.getComponent(context.entity, ComSkillAbel)
- let comRole = context.world.getComponent(context.entity, ComRole)
- let comSpineCocosNode = context.world.getComponent(comRole?.spineEntity, ComCocosNode)
- comSpineCocosNode.events.push(new EventStopSkill())
- comSkill.dirty = false
- comSkill.countDown = Infinity
- comSkill.skillConfig = null
- comSkill.isInShield = false
- node.state = NodeState.Success
- if (debug) {
- if (node.state == NodeState.Success) {
- node.successLog = '停止技能行为成功==>' + context.entity
- }
- }
- },
- }
- }
|