1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327 |
- /** @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, BUFF_TYPE, BULLET_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) {
- //词条减CD
- if (comRole.entryMap.get(ENTRY.skillCD)?.num) {
- cd *= 1 - comRole.entryMap.get(ENTRY.skillCD).num / Data.game.rateNum
- }
- //buff减CD
- for (let j = 0; j < comRole.buffs.length; j++) {
- let buffCfg = comRole.buffs[j].buffCfg
- if (
- buffCfg.buffType == BUFF_TYPE.skillCD &&
- ((buffCfg.effectType.includes(BUFF_EFFECT_TYPE.normalSkill) &&
- !comSkillAbel.skillConfig.isSpecial) ||
- (buffCfg.effectType.includes(BUFF_EFFECT_TYPE.specialSkill) &&
- comSkillAbel.skillConfig.isSpecial))
- ) {
- cd *= 1 - buffCfg.attrRate[0] / 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
- }
- }
- },
- }
- }
|