diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index e72efda2..4ff9d469 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -14,7 +14,6 @@ + fix the vibes Stability Movement penalty while swinging weapon - Only have ai strafe if its outside attack range Ticketed randomizer node for BTs to more heavily weight attacking and waiting Slow down strafe movement somehow diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 251529ec..484557d0 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -574,6 +574,8 @@ True behavior trees - Colections - Combat Melee ai using BT framework +Server block nullchecks +Melee AI tweaks # TODO diff --git a/src/main/java/electrosphere/entity/state/block/ServerBlockTree.java b/src/main/java/electrosphere/entity/state/block/ServerBlockTree.java index ea88cd0a..76fc6741 100644 --- a/src/main/java/electrosphere/entity/state/block/ServerBlockTree.java +++ b/src/main/java/electrosphere/entity/state/block/ServerBlockTree.java @@ -101,12 +101,14 @@ public class ServerBlockTree implements BehaviorTree { this.stateTransitionUtil.reset(); setState(BlockState.COOLDOWN); //activate hitboxes - List attachedEntities = AttachUtils.getChildrenList(parent); - for(Entity currentAttached : attachedEntities){ - if(HitboxCollectionState.hasHitboxState(currentAttached)){ - HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached); - currentState.setActive(false); - currentState.setBlockOverride(false); + if(AttachUtils.hasChildren(parent)){ + List attachedEntities = AttachUtils.getChildrenList(parent); + for(Entity currentAttached : attachedEntities){ + if(HitboxCollectionState.hasHitboxState(currentAttached)){ + HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached); + currentState.setActive(false); + currentState.setBlockOverride(false); + } } } } @@ -131,12 +133,14 @@ public class ServerBlockTree implements BehaviorTree { } break; case COOLDOWN: { //activate hitboxes - List attachedEntities = AttachUtils.getChildrenList(parent); - for(Entity currentAttached : attachedEntities){ - if(HitboxCollectionState.hasHitboxState(currentAttached)){ - HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached); - currentState.setActive(false); - currentState.setBlockOverride(false); + if(AttachUtils.hasChildren(parent)){ + List attachedEntities = AttachUtils.getChildrenList(parent); + for(Entity currentAttached : attachedEntities){ + if(HitboxCollectionState.hasHitboxState(currentAttached)){ + HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached); + currentState.setActive(false); + currentState.setBlockOverride(false); + } } } this.stateTransitionUtil.simulate(BlockState.COOLDOWN); diff --git a/src/main/java/electrosphere/server/ai/nodes/meta/decorators/TimerNode.java b/src/main/java/electrosphere/server/ai/nodes/meta/decorators/TimerNode.java index 38800cbe..266cb1d8 100644 --- a/src/main/java/electrosphere/server/ai/nodes/meta/decorators/TimerNode.java +++ b/src/main/java/electrosphere/server/ai/nodes/meta/decorators/TimerNode.java @@ -44,7 +44,6 @@ public class TimerNode implements DecoratorNode { this.child = child; this.frameCount = frameCount; this.timerId = Globals.aiManager.getTimerService().createTimer(); - System.out.println("Created timer node with id " + this.timerId); } @Override diff --git a/src/main/java/electrosphere/server/ai/trees/creature/melee/MeleeAITree.java b/src/main/java/electrosphere/server/ai/trees/creature/melee/MeleeAITree.java index 67ec6e26..1eff6602 100644 --- a/src/main/java/electrosphere/server/ai/trees/creature/melee/MeleeAITree.java +++ b/src/main/java/electrosphere/server/ai/trees/creature/melee/MeleeAITree.java @@ -44,65 +44,148 @@ public class MeleeAITree { //preconditions here new HasWeaponNode(), new MeleeTargetingNode(attackerTreeData.getAggroRange()), - //determine strategy - new RandomizerNode( - //wait - new SequenceNode( - new PublishStatusNode("Waiting"), - new FaceTargetNode(), - new TimerNode(new SucceederNode(null), 1200) - ), - //move to hover distance - new SequenceNode( - new PublishStatusNode("Strafing right"), - new InverterNode(new OnFailureNode( - new WalkStartNode(MovementRelativeFacing.RIGHT), - new FailerNode(null) - )), - new FaceTargetNode(), - new TimerNode(new SucceederNode(null), 600), - new SucceederNode(new WalkStopNode()) - ), + //perform different actions based on distance to target + new SelectorNode( - //move from hover distance to melee range + //in attack range new SequenceNode( - new PublishStatusNode("Strafing left"), - new InverterNode(new OnFailureNode( - new WalkStartNode(MovementRelativeFacing.LEFT), - new FailerNode(null) - )), - new FaceTargetNode(), - new TimerNode(new SucceederNode(null), 600), - new SucceederNode(new WalkStopNode()) - ), + //check prior to performing action + new MeleeRangeCheckNode(attackerTreeData,MeleeRangeCheckType.ATTACK), - //move towards target and attack - new SequenceNode( - new PublishStatusNode("Attack target"), - //move towards target if its outside of melee range - new UntilNode(AITreeNodeResult.SUCCESS, - //or - new SelectorNode( - //in range - new MeleeRangeCheckNode(attackerTreeData,MeleeRangeCheckType.ATTACK), - //approaching target - new SequenceNode( - new PublishStatusNode("Approaching target"), - new FaceTargetNode(), - new OnFailureNode(new IsMovingNode(), new WalkStartNode(MovementRelativeFacing.FORWARD)), - new MeleeRangeCheckNode(attackerTreeData,MeleeRangeCheckType.ATTACK) - ) - ) - ), + //set state //stop walking now that we're in range new PublishStatusNode("Slowing down"), new WalkStopNode(), new UntilNode(AITreeNodeResult.FAILURE, new IsMovingNode()), - new PublishStatusNode("Attacking"), - new AttackStartNode() + + //select action to perform + new RandomizerNode( + //wait + new SequenceNode( + new PublishStatusNode("Waiting"), + new FaceTargetNode(), + new TimerNode(new SucceederNode(null), 1200) + ), + //attack + new SequenceNode( + new PublishStatusNode("Attacking"), + new FaceTargetNode(), + new AttackStartNode(), + new TimerNode(new SucceederNode(null), 150) + ) + ) + ), + + //in aggro range + new SequenceNode( + //check prior to performing action + new MeleeRangeCheckNode(attackerTreeData,MeleeRangeCheckType.AGGRO), + + //select action to perform + new RandomizerNode( + + //wait + new SequenceNode( + new PublishStatusNode("Waiting"), + new FaceTargetNode(), + new TimerNode(new SucceederNode(null), 1200) + ), + + //strafe to the right + new SequenceNode( + new PublishStatusNode("Strafing right"), + new InverterNode(new OnFailureNode( + new WalkStartNode(MovementRelativeFacing.RIGHT), + new FailerNode(null) + )), + new FaceTargetNode(), + new TimerNode(new SucceederNode(null), 600), + new SucceederNode(new WalkStopNode()) + ), + + //strafe to the left + new SequenceNode( + new PublishStatusNode("Strafing left"), + new InverterNode(new OnFailureNode( + new WalkStartNode(MovementRelativeFacing.LEFT), + new FailerNode(null) + )), + new FaceTargetNode(), + new TimerNode(new SucceederNode(null), 600), + new SucceederNode(new WalkStopNode()) + ), + + //approach target + //move towards target and attack + new SequenceNode( + new PublishStatusNode("Move into attack range"), + new FaceTargetNode(), + new SucceederNode(new WalkStartNode(MovementRelativeFacing.FORWARD)), + new TimerNode(new SucceederNode(null), 600) + ) + ) ) ) + // //determine strategy + // new RandomizerNode( + // //wait + // new SequenceNode( + // new PublishStatusNode("Waiting"), + // new FaceTargetNode(), + // new TimerNode(new SucceederNode(null), 1200) + // ), + + // //move to hover distance + // new SequenceNode( + // new PublishStatusNode("Strafing right"), + // new InverterNode(new OnFailureNode( + // new WalkStartNode(MovementRelativeFacing.RIGHT), + // new FailerNode(null) + // )), + // new FaceTargetNode(), + // new TimerNode(new SucceederNode(null), 600), + // new SucceederNode(new WalkStopNode()) + // ), + + // //move from hover distance to melee range + // new SequenceNode( + // new PublishStatusNode("Strafing left"), + // new InverterNode(new OnFailureNode( + // new WalkStartNode(MovementRelativeFacing.LEFT), + // new FailerNode(null) + // )), + // new FaceTargetNode(), + // new TimerNode(new SucceederNode(null), 600), + // new SucceederNode(new WalkStopNode()) + // ), + + // //move towards target and attack + // new SequenceNode( + // new PublishStatusNode("Attack target"), + // //move towards target if its outside of melee range + // new UntilNode(AITreeNodeResult.SUCCESS, + // //or + // new SelectorNode( + // //in range + // new MeleeRangeCheckNode(attackerTreeData,MeleeRangeCheckType.ATTACK), + // //approaching target + // new SequenceNode( + // new PublishStatusNode("Approaching target"), + // new FaceTargetNode(), + // new OnFailureNode(new IsMovingNode(), new WalkStartNode(MovementRelativeFacing.FORWARD)), + // new MeleeRangeCheckNode(attackerTreeData,MeleeRangeCheckType.ATTACK) + // ) + // ) + // ), + // //stop walking now that we're in range + // new PublishStatusNode("Slowing down"), + // new WalkStopNode(), + // new UntilNode(AITreeNodeResult.FAILURE, new IsMovingNode()), + // new PublishStatusNode("Attacking"), + // new AttackStartNode() + // ) + // ) ); }