combat.py (13206B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\behaviors\trees\combat.py 2 from behaviors import composites 3 from behaviors.actions import WaitAction 4 from behaviors.actions.ballparks import OrbitAtDistanceAction, ManageMicroWarpDriveToTarget, ModifyOrbitVelocity 5 from behaviors.actions.blackboards import BlackboardCopyMessageAction 6 from behaviors.actions.combat import ActivateCombatEffectsOnTarget, OwnerListFilterAction 7 from behaviors.actions.combat import StopCombatEffectsOnTarget, GetCombatEffectsForRole 8 from behaviors.actions.combatnavigation import GetCombatOrbitAndAttackRange, GetFleetCombatOrbitRangeByRole 9 from behaviors.actions.combatnavigation import GetTargetToOrbit 10 from behaviors.actions.combattargets import FindTarget, UnlockTarget, AcquireTargetLock, GetMyMinOptimalAndFalloff 11 from behaviors.blackboards.scopes import ScopeTypes 12 from behaviors.conditions.ballparks import IsBallPresentInMyBubbleCondition 13 from behaviors.conditions.blackboards import BlackboardMessagesEqualCondition, IsBlackboardValueInCollectionCondition 14 from behaviors.conditions.blackboards import IsBlackboardValueNotNone 15 from behaviors.conditions.combat import HasAvailableTargetCapacity 16 from behaviors.conditions.effects import HasAnyEffectCondition 17 from behaviors.const.blackboardchannels import GROUP_PRIMARY_TARGET, MY_COMBAT_TARGET, COMMANDER_ADDRESS 18 from behaviors.const.blackboardchannels import COMBAT_TARGETS_SET_ADDRESS, COMBAT_MIN_FALLOFF_ADDRESS 19 from behaviors.const.blackboardchannels import COMBAT_MIN_OPTIMAL_ADDRESS 20 from behaviors.const.combat import THREAT_TARGET_EVALUATOR 21 from behaviors.decorators import modifiers 22 from behaviors.decorators.modifiers import ForceSuccess 23 from behaviors.decorators.repeaters import RepeatWhileFailing 24 from behaviors.decorators.timers import CooldownTimer 25 from behaviors.monitors.ballparks import MonitorProximitySensors, MonitorInvulnerabilityCanceledInBubble 26 from behaviors.monitors.ballparks import TargetChangingBubbleMonitor, TargetLeavingParkMonitor 27 from behaviors.monitors.ballparks import TargetWithOwnerEnteredBubbleMonitor 28 from behaviors.monitors.blackboards import BlackboardMessageMonitor 29 from behaviors.monitors.combat import MaxLockedTargetsChangedMonitor, MonitorAssistanceToTargets 30 from behaviors.monitors.combat import WaitForAggressiveAct, ClearValueAndResetIfTargetCloaks 31 from behaviors.monitors.targeting import TargetLostMonitor 32 from behaviors.trees.role import ROLE_ADDRESS 33 from brennivin.itertoolsext import Bundle 34 from dogma.const import effectModifyTargetSpeed2, effectEntityCapacitorDrain, effectWarpScrambleForEntity, effectBehaviorWarpDisrupt, effectNpcBehaviorWebifier, effectNpcBehaviorMicroJumpAttack, effectNpcBehaviorSmartBomb, effectEntityChainLightning 35 from dogma.const import effectBehaviorWarpScramble, effectBehaviorTargetPainter, effectNpcBehaviorGuidanceDisruptor, effectNpcBehaviorTrackingDisruptor 36 from dogma.const import effectNpcBehaviorEnergyNeutralizer, effectBehaviorSensorDampener, effectBehaviorECM 37 from dogma.const import effectTargetAttack, effectMissileLaunchingForEntity, effectNpcBehaviorEnergyNosferatu 38 from dogma.const import effectWarpScrambleTargetMWDBlockActivationForEntity, effectEntityTargetPaint 39 from inventorycommon.const import categoryShip, categoryDrone, groupCapsule, categoryFighter 40 from npcs.server.tags import DRIFTER_TAG 41 COMBAT_TARGETS_SET = COMBAT_TARGETS_SET_ADDRESS 42 TARGETS_MONITORED_FOR_ASSISTANCE_SET = (ScopeTypes.EntityGroup, 'TARGETS_MONITORED_FOR_ASSISTANCE_SET') 43 COMBAT_WARP_TO_LOCATION = (ScopeTypes.EntityGroup, 'COMBAT_WARP_TO_LOCATION') 44 POTENTIAL_TARGET = (ScopeTypes.Item, 'POTENTIAL_TARGET') 45 GROUP_TARGET_SWITCH_TIMER = (ScopeTypes.EntityGroup, 'GROUP_TARGET_SWITCH_TIMER') 46 TARGET_SWITCH_TIMER = (ScopeTypes.Item, 'TARGET_SWITCH_TIMER') 47 COMBAT_ORBIT_RANGE = (ScopeTypes.Item, 'COMBAT_ORBIT_RANGE') 48 COMBAT_ATTACK_RANGE = (ScopeTypes.Item, 'COMBAT_ATTACK_RANGE') 49 COMBAT_ORBIT_TARGET = (ScopeTypes.Item, 'COMBAT_ORBIT_TARGET') 50 COMBAT_WARP_AT_DISTANCE = (ScopeTypes.Item, 'COMBAT_WARP_AT_DISTANCE') 51 COMBAT_EFFECTS_ADDRESS = (ScopeTypes.Item, 'COMBAT_EFFECTS') 52 COMBAT_EFFECTS = (effectEntityCapacitorDrain, 53 effectEntityTargetPaint, 54 effectMissileLaunchingForEntity, 55 effectModifyTargetSpeed2, 56 effectTargetAttack, 57 effectWarpScrambleForEntity, 58 effectWarpScrambleTargetMWDBlockActivationForEntity, 59 effectBehaviorECM, 60 effectNpcBehaviorEnergyNeutralizer, 61 effectNpcBehaviorEnergyNosferatu, 62 effectNpcBehaviorGuidanceDisruptor, 63 effectBehaviorSensorDampener, 64 effectBehaviorTargetPainter, 65 effectNpcBehaviorTrackingDisruptor, 66 effectBehaviorWarpDisrupt, 67 effectBehaviorWarpScramble, 68 effectNpcBehaviorWebifier, 69 effectNpcBehaviorMicroJumpAttack, 70 effectNpcBehaviorSmartBomb, 71 effectEntityChainLightning) 72 73 def CreateTargetSwitchingBehavior(targetEvaluationFunction = THREAT_TARGET_EVALUATOR, preferredModuleGroups = [], targetAddress = GROUP_PRIMARY_TARGET, groupPrimaryAddress = GROUP_PRIMARY_TARGET, targetSwitchTimerAddress = GROUP_TARGET_SWITCH_TIMER): 74 return modifiers.ForceFailure(Bundle(name='Target Switching')).AddSubTask(CooldownTimer(Bundle(timerAddress=targetSwitchTimerAddress, timeoutSeconds=60)).AddSubTask(composites.Sequence().AddSubTask(FindTarget(Bundle(name='Get A Target', selectedTargetAddress=POTENTIAL_TARGET, potentialTargetListAddress=COMBAT_TARGETS_SET, includedCategories=[], onlyCheckLocalBubble=True, targetEvaluationFunction=targetEvaluationFunction, roleAddress=ROLE_ADDRESS, preferredModuleGroups=preferredModuleGroups, primaryTargetIdAddress=groupPrimaryAddress))).AddSubTask(modifiers.Not().AddSubTask(BlackboardMessagesEqualCondition(Bundle(firstMessageAddress=targetAddress, secondMessageAddress=POTENTIAL_TARGET)))).AddSubTask(BlackboardCopyMessageAction(Bundle(sourceMessageAddress=POTENTIAL_TARGET, targetMessageAddress=targetAddress))).AddSubTask(StopCombatEffectsOnTarget(Bundle(name='Stop All Combat Effects', effectIds=COMBAT_EFFECTS))))) 75 76 77 def CreateCombatBehavior(validOwnerIds = [], orbitVelocity = None, orbitRange = None, attackRange = None, targetAddress = GROUP_PRIMARY_TARGET, groupPrimaryAddress = GROUP_PRIMARY_TARGET, targetEvaluationFunction = THREAT_TARGET_EVALUATOR, preferredModuleGroups = [], proximitySensorTags = (DRIFTER_TAG,)): 78 return composites.Sequence(Bundle(name='Combat')).AddSubTask(WaitForAggressiveAct(Bundle(name='Aggression Monitor', combatTargetsAddress=COMBAT_TARGETS_SET))).AddSubTask(MonitorAssistanceToTargets(Bundle(name='Monitor Enemy Assistance', combatTargetsAddress=COMBAT_TARGETS_SET))).AddSubTask(MonitorProximitySensors(Bundle(objectListAddress=COMBAT_TARGETS_SET, includedCategories=[categoryShip, categoryDrone, categoryFighter], excludedGroups=[groupCapsule], validOwnerIds=validOwnerIds, invalidOwnerIds=None, tags=proximitySensorTags))).AddSubTask(MonitorInvulnerabilityCanceledInBubble(Bundle(targetIdListAddress=COMBAT_TARGETS_SET))).AddSubTask(MaxLockedTargetsChangedMonitor()).AddSubTask(BlackboardMessageMonitor(Bundle(messageAddress=COMBAT_TARGETS_SET))).AddSubTask(CreateSelectTargetBehavior(targetAddress, targetEvaluationFunction, preferredModuleGroups, groupPrimaryAddress)).AddSubTask(CreateGetCombatNavigationBehavior(orbitRange, attackRange, targetAddress)).AddSubTask(CreateAttackTargetBehavior(orbitVelocity, targetAddress)) 79 80 81 def CreateOwnerAggressionBehavior(ownerIds): 82 return modifiers.ForceFailure(Bundle(name='Owner Aggression')).AddSubTask(TargetWithOwnerEnteredBubbleMonitor(Bundle(targetSetAddress=COMBAT_TARGETS_SET, ownerIds=ownerIds))) 83 84 85 def CreateFriendlyTargetFilterBehavior(friendlyOwnerIds): 86 return modifiers.ForceFailure(Bundle(name='Friendly Target Filter')).AddSubTask(OwnerListFilterAction(Bundle(ownerIdSet=friendlyOwnerIds, itemIdSetAddress=COMBAT_TARGETS_SET))) 87 88 89 def CreateEntityCombatBehavior(orbitVelocity = None, orbitRange = None, attackRange = None, targetAddress = GROUP_PRIMARY_TARGET, groupPrimaryAddress = GROUP_PRIMARY_TARGET, targetEvaluationFunction = THREAT_TARGET_EVALUATOR, preferredModuleGroups = []): 90 root = composites.Sequence(Bundle(name='Combat')) 91 root.AddSubTask(WaitForAggressiveAct(Bundle(name='Aggression Monitor', combatTargetsAddress=COMBAT_TARGETS_SET))) 92 root.AddSubTask(HasAnyEffectCondition(Bundle(name='Can I fight?', effectIds=COMBAT_EFFECTS))) 93 root.AddSubTask(MaxLockedTargetsChangedMonitor()) 94 root.AddSubTask(BlackboardMessageMonitor(Bundle(messageAddress=COMBAT_TARGETS_SET))) 95 root.AddSubTask(CreateSelectTargetBehavior(targetAddress, targetEvaluationFunction, preferredModuleGroups, groupPrimaryAddress)) 96 root.AddSubTask(CreateGetCombatNavigationBehavior(orbitRange, attackRange, targetAddress)) 97 root.AddSubTask(CreateAttackTargetBehavior(orbitVelocity, targetAddress=targetAddress)) 98 return root 99 100 101 def CreateSelectTargetBehavior(selectedTargetAddress, targetEvaluationFunction, preferredModuleGroups, groupPrimaryAddress): 102 return composites.PrioritySelector(Bundle(name='Select Target')).AddSubTask(composites.Sequence().AddSubTask(IsBlackboardValueNotNone(Bundle(valueAddress=selectedTargetAddress))).AddSubTask(IsBlackboardValueInCollectionCondition(Bundle(valueAddress=selectedTargetAddress, collectionAddress=COMBAT_TARGETS_SET))).AddSubTask(IsBallPresentInMyBubbleCondition(Bundle(ballIdAddress=selectedTargetAddress)))).AddSubTask(FindTarget(Bundle(name='Get A Target', selectedTargetAddress=selectedTargetAddress, potentialTargetListAddress=COMBAT_TARGETS_SET, includedCategories=[], onlyCheckLocalBubble=True, targetEvaluationFunction=targetEvaluationFunction, roleAddress=ROLE_ADDRESS, preferredModuleGroups=preferredModuleGroups, primaryTargetIdAddress=groupPrimaryAddress))) 103 104 105 def CreateAttackTargetBehavior(orbitVelocity, targetAddress = GROUP_PRIMARY_TARGET): 106 root = composites.Sequence() 107 root.AddSubTask(modifiers.ForceSuccess(Bundle(name='Disengage obsolete targets')).AddSubTask(composites.Sequence().AddSubTask(modifiers.Not().AddSubTask(BlackboardMessagesEqualCondition(Bundle(firstMessageAddress=MY_COMBAT_TARGET, secondMessageAddress=targetAddress)))).AddSubTask(StopCombatEffectsOnTarget(Bundle(name='Stop All Combat Effects', effectIds=COMBAT_EFFECTS))))) 108 root.AddSubTask(ClearValueAndResetIfTargetCloaks(Bundle(targetAddress=targetAddress, valueAddress=targetAddress))) 109 root.AddSubTask(TargetLeavingParkMonitor(Bundle(targetAddress=targetAddress, clearValue=True))) 110 root.AddSubTask(BlackboardCopyMessageAction(Bundle(sourceMessageAddress=targetAddress, targetMessageAddress=MY_COMBAT_TARGET))) 111 root.AddSubTask(BlackboardMessageMonitor(Bundle(messageAddress=targetAddress))) 112 root.AddSubTask(TargetLostMonitor(Bundle(targetAddress=targetAddress))) 113 root.AddSubTask(TargetChangingBubbleMonitor(Bundle(targetAddress=targetAddress, resetOnEnter=False))) 114 root.AddSubTask(ModifyOrbitVelocity(Bundle(orbitVelocity=orbitVelocity))) 115 root.AddSubTask(OrbitAtDistanceAction(Bundle(orbitTargetAddress=COMBAT_ORBIT_TARGET, orbitRangeAddress=COMBAT_ORBIT_RANGE, blocking=False, blockUntilRange=COMBAT_ATTACK_RANGE))) 116 root.AddSubTask(ManageMicroWarpDriveToTarget(Bundle(targetAddress=targetAddress, orbitRangeAddress=COMBAT_ORBIT_RANGE, microWarpDriveDuration=5000, microWarpDriveChance=1.0))) 117 root.AddSubTask(composites.PrioritySelector(Bundle(name='Release target if required')).AddSubTask(HasAvailableTargetCapacity()).AddSubTask(UnlockTarget())) 118 root.AddSubTask(RepeatWhileFailing(Bundle(name='Retry', maxRepetitions=7)).AddSubTask(AcquireTargetLock(Bundle(selectedTargetAddress=targetAddress)))) 119 root.AddSubTask(ActivateCombatEffectsOnTarget(Bundle(name='Start all Combat Effects on Target', effectIds=COMBAT_EFFECTS, selectedTargetAddress=targetAddress, repeat=1000))).AddSubTask(WaitAction(Bundle())) 120 return root 121 122 123 def CreateGetCombatNavigationBehavior(orbitRange = None, attackRange = None, targetAddress = GROUP_PRIMARY_TARGET): 124 return composites.Sequence().AddSubTask(GetTargetToOrbit(Bundle(name='Get Target To Orbit In Combat', commanderAddress=COMMANDER_ADDRESS, combatTargetAddress=targetAddress, orbitTargetAddress=COMBAT_ORBIT_TARGET, roleAddress=ROLE_ADDRESS))).AddSubTask(composites.Sequence().AddSubTask(ForceSuccess().AddSubTask(composites.Sequence(Bundle(name='Get Combat Effects & Orbit Range')).AddSubTask(GetCombatEffectsForRole(Bundle(combatEffectsAddress=COMBAT_EFFECTS_ADDRESS, roleAddress=ROLE_ADDRESS))).AddSubTask(GetMyMinOptimalAndFalloff(Bundle(minOptimalAddress=COMBAT_MIN_OPTIMAL_ADDRESS, minFalloffAddress=COMBAT_MIN_FALLOFF_ADDRESS, combatEffectsAddress=COMBAT_EFFECTS_ADDRESS))).AddSubTask(GetCombatOrbitAndAttackRange(Bundle(orbitRangeAddress=COMBAT_ORBIT_RANGE, attackRangeAddress=COMBAT_ATTACK_RANGE, orbitRange=orbitRange, attackRange=attackRange, minOptimalAddress=COMBAT_MIN_OPTIMAL_ADDRESS, minFalloffAddress=COMBAT_MIN_FALLOFF_ADDRESS))))).AddSubTask(ForceSuccess().AddSubTask(composites.Sequence(Bundle(name='Overwriting Orbit Range if Orbiting Commander')).AddSubTask(BlackboardMessagesEqualCondition(Bundle(firstMessageAddress=COMBAT_ORBIT_TARGET, secondMessageAddress=COMMANDER_ADDRESS))).AddSubTask(GetFleetCombatOrbitRangeByRole(Bundle(roleAddress=ROLE_ADDRESS, orbitRangeAddress=COMBAT_ORBIT_RANGE))))))