Download Data/AIArchetype.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 43.4 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/Data/AIArchetype.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/Data/AIArchetype.lua
-
curl -L -o AIArchetype.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/Data/AIArchetype.lua
43.4 kB
| -- ========== GENERATED BY AIArchetype Editor DO NOT EDIT MANUALLY! ========== | |
| PlaceObj('AIArchetype', { | |
| BaseAttackWeight = 0, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'Weight', 600, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 300, | |
| 'RangeBase', "Absolute", | |
| 'RangeMin', 2, | |
| 'RangeMax', 2, | |
| }), | |
| }, | |
| }), | |
| }, | |
| MoveStance = "", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeBase', "Absolute", | |
| 'RangeMin', 2, | |
| 'RangeMax', 2, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "", | |
| TargetChangePolicy = "restart", | |
| group = "Beasts", | |
| id = "Beast_Crocodile", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackWeight = 0, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'Weight', 600, | |
| }), | |
| }, | |
| 'SignatureActions', { | |
| PlaceObj('AIActionHyenaCharge', nil), | |
| }, | |
| }), | |
| }, | |
| MoveStance = "", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeBase', "Melee", | |
| 'RangeMin', 1000, | |
| 'RangeMax', 1000, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "", | |
| SignatureActions = { | |
| PlaceObj('AIActionCharge', { | |
| 'BiasId', "HyenaCharge", | |
| 'Weight', 200, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "HyenaCharge", | |
| 'Effect', "disable", | |
| }), | |
| }, | |
| 'ForbiddenInState', set( "RainHeavy" ), | |
| 'DestPreference', "nearest", | |
| }), | |
| }, | |
| TargetChangePolicy = "restart", | |
| group = "Beasts", | |
| id = "Beast_Hyena", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('CustomAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 100, | |
| 'EnumDests', function (self, unit, context, debug_data) | |
| if g_Encounter then | |
| return g_Encounter:EnumDestsInAssignedArea(unit, context) | |
| end | |
| end, | |
| 'PickEndTurnPolicies', function (self, unit, context, debug_data) | |
| if g_Encounter then | |
| return g_Encounter:SelectEndTurnPolicies(unit, context) | |
| end | |
| end, | |
| 'PickOptimalLoc', function (self, unit, context, debug_data) | |
| if g_Encounter then | |
| return g_Encounter:FindOptimalLocationInAssignedArea(unit, context) | |
| end | |
| end, | |
| 'PickEndTurnLoc', function (self, unit, context, debug_data) | |
| AITacticCalcPathDistances(unit, context, "disable bias") | |
| local policies = self:PickEndTurnPolicies(unit, context) or self.EndTurnPolicies | |
| context.ai_destination = AIScoreReachableVoxels(context, policies, self.OptLocWeight, nil, "prefer") | |
| return true | |
| end, | |
| 'SelectSignatureActions', function (self, unit, context, debug_data) | |
| if g_Encounter then | |
| return g_Encounter:SelectSignatureActions(unit, context) | |
| end | |
| end, | |
| }), | |
| }, | |
| Comment = "generic implementation, try reaching assigned area, valid positions are in assigned & current areas only", | |
| group = "BossFights", | |
| id = "Bossfight_GuardArea", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('CustomAI', { | |
| 'turn_phase', "Early", | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 100, | |
| 'EnumDests', function (self, unit, context, debug_data) | |
| if not g_Encounter then return end | |
| return CorazonEnumDestsInAssignedArea(unit, context) | |
| end, | |
| 'PickOptimalLoc', function (self, unit, context, debug_data) | |
| if g_Encounter:GetUnitArea(unit) == g_Encounter.areaFinalRoom then | |
| context.best_dest = GetPackedPosAndStance(unit) | |
| return true | |
| end | |
| local _, positions = CorazonGetAreaMarkerPositions(g_Encounter.areaFinalRoom) | |
| positions = positions or empty_table | |
| if #positions > 0 then | |
| local goto_pos = table.interaction_rand(positions, "Behavior") | |
| local x, y, z = point_unpack(goto_pos) | |
| context.best_dest = stance_pos_pack(x, y, z, StancesList.Standing) | |
| return true | |
| end | |
| end, | |
| 'PickEndTurnLoc', function (self, unit, context, debug_data) | |
| CorazonCalcPathDistances(unit, context, "disable bias") | |
| end, | |
| }), | |
| }, | |
| group = "BossFights", | |
| id = "Corazon_BossRetreating", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('CustomAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 100, | |
| 'EnumDests', function (self, unit, context, debug_data) | |
| if not g_Encounter then return end | |
| return CorazonEnumDestsInAssignedArea(unit, context) | |
| end, | |
| 'PickEndTurnPolicies', function (self, unit, context, debug_data) | |
| if IsKindOf(g_Encounter, "BossfightCorazon") then | |
| return g_Encounter:SelectEndTurnPolicies(unit, context) | |
| end | |
| end, | |
| 'PickOptimalLoc', function (self, unit, context, debug_data) | |
| return CorazonOptimalLocationInAssignedArea(unit, context) | |
| end, | |
| 'PickEndTurnLoc', function (self, unit, context, debug_data) | |
| CorazonCalcPathDistances(unit, context, "disable bias") | |
| local policies = self:PickEndTurnPolicies(unit, context) or self.EndTurnPolicies | |
| context.ai_destination = AIScoreReachableVoxels(context, policies, self.OptLocWeight, nil, "prefer") | |
| return true | |
| end, | |
| 'SelectSignatureActions', function (self, unit, context, debug_data) | |
| if IsKindOf(g_Encounter, "BossfightCorazon") then | |
| return g_Encounter:SelectSignatureActions(unit, context) | |
| end | |
| end, | |
| 'Execute', function (self, unit, context, debug_data) | |
| -- todo: set context.force_max_aim if smoke | |
| -- todo: swap to shotgun if in close range, out of it if not | |
| end, | |
| }), | |
| }, | |
| Comment = "basic logic: move to assigned area, engange enemies in/from it until assigned elsewhere", | |
| group = "BossFights", | |
| id = "Corazon_GuardArea", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('CustomAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 100, | |
| 'EnumDests', function (self, unit, context, debug_data) | |
| if not g_Encounter then return end | |
| return CorazonEnumDestsInAssignedArea(unit, context) | |
| end, | |
| 'PickOptimalLoc', function (self, unit, context, debug_data) | |
| return CorazonOptimalLocationInAssignedArea(unit, context) | |
| end, | |
| 'PickEndTurnLoc', function (self, unit, context, debug_data) | |
| CorazonCalcPathDistances(unit, context, "disable bias") | |
| end, | |
| 'SelectSignatureActions', function (self, unit, context, debug_data) | |
| if IsKindOf(g_Encounter, "BossfightCorazon") then | |
| return g_Encounter:SelectSignatureActions(unit, context) | |
| end | |
| end, | |
| 'Execute', function (self, unit, context, debug_data) | |
| -- todo: set context.force_max_aim if smoke | |
| -- todo: swap to shotgun if in close range, out of it if not | |
| end, | |
| }), | |
| }, | |
| Comment = "right corridor kite back - similar to GuardArea but maybe more defensive?", | |
| group = "BossFights", | |
| id = "Corazon_KiteBack", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('CustomAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 100, | |
| 'EnumDests', function (self, unit, context, debug_data) | |
| if not g_Encounter then return end | |
| return CorazonEnumDestsInAssignedArea(unit, context) | |
| end, | |
| 'EvalDamageScore', function (self, unit, context, debug_data) | |
| context.max_attacks = 1 | |
| AIPrecalcDamageScore(context) | |
| end, | |
| 'PickOptimalLoc', function (self, unit, context, debug_data) | |
| return CorazonOptimalLocationInAssignedArea(unit, context) | |
| end, | |
| 'PickEndTurnLoc', function (self, unit, context, debug_data) | |
| -- we need 2 destinations: attack one and end turn one | |
| local hide_dests = {} | |
| local attack_dest, attack_score, scoot_ap | |
| for _, dest in ipairs(context.destinations) do | |
| if not g_AIDestEnemyLOSCache[dest] then | |
| hide_dests[#hide_dests+1] = dest | |
| else | |
| local score = context.dest_target_score or 0 | |
| if score > 0 then | |
| -- modify score by remaining ap at dest | |
| local move_stance_idx = context.dest_combat_path[dest] | |
| local cpath = context.combat_paths[move_stance_idx] | |
| local ap_at_dest = cpath:GetAP(dest) | |
| score = MulDivRound(score, ap_at_dest, Max(1, unit.ActionPoints)) | |
| if score > (attack_score or 0) then | |
| attack_dest, attack_score, scoot_ap = dest, score, ap_at_dest - context.default_attack_cost | |
| end | |
| end | |
| end | |
| end | |
| if not attack_dest or #hide_dests < 1 or not scoot_ap then return end | |
| -- pick a reachable hiding dest | |
| local x, y, z, stance_idx = stance_pos_unpack(attack_dest) | |
| local atk_pos = point(x, y, z) | |
| local combat_path = CombatPath:new() | |
| local weights, total_weight = {}, 0 | |
| local hide_dest | |
| combat_path:RebuildPaths(unit, scoot_ap, atk_pos, StancesList[stance_idx]) | |
| for i, dest in ipairs(hide_dests) do | |
| local x, y, z = stance_pos_unpack(dest) | |
| local pos = point_pack(x, y, z) | |
| local ap = combat_path:GetAP(pos) | |
| weights[i] = ap | |
| total_weight = total_weight + ap | |
| end | |
| if total_weight < 1 then return end | |
| local roll = unit:Random(total_weight) | |
| for i = 1, #hide_dests - 1 do | |
| local w = weights[i] | |
| if w >= roll then | |
| hide_dest = hide_dests[i] | |
| break | |
| end | |
| end | |
| context.ai_destination = attack_dest | |
| context.scoot_and_shoot_dest = hide_dest or hide_dests[#hide_dests] | |
| DoneObject(combat_path) | |
| return true | |
| end, | |
| 'SelectSignatureActions', function (self, unit, context, debug_data) | |
| if IsKindOf(g_Encounter, "BossfightCorazon") then | |
| return g_Encounter:SelectSignatureActions(unit, context) | |
| end | |
| end, | |
| 'Execute', function (self, unit, context, debug_data) | |
| if not context.scoot_and_shoot_dest then return end | |
| -- do a single attack, then scoot to the hidey place | |
| local dest = GetPackedPosAndStance(unit) | |
| AIPrecalcDamageScore(context, {dest}) | |
| local target = (context.dest_target or empty_table)[dest] | |
| local args = { target = target }--, voiceResponse = voice_response } | |
| AIPlayCombatAction(context.default_attack.id, unit, nil, args) | |
| -- recalc path to make sure the position is free | |
| local x, y, z = stance_pos_unpack(context.scoot_and_shoot_dest) | |
| local combat_path = CombatPath:new() | |
| combat_path:RebuildPaths(unit) | |
| if not combat_path:GetAP(point_pack(x, y, z)) then | |
| local hide_dests = {} | |
| for _, dest in ipairs(context.destinations) do | |
| local x, y, z = stance_pos_unpack(dest) | |
| if not g_AIDestEnemyLOSCache[dest] and combat_path:GetAP(point_pack(x, y, z)) then | |
| hide_dests[#hide_dests+1] = dest | |
| end | |
| end | |
| if #hide_dests > 0 then | |
| local dest = table.interaction_rand(hide_dests, "Behavior") | |
| local x, y, z = stance_point_unpack(dest) | |
| AIPlayCombatAction("Move", unit, unit.ActionPoints, { goto_pos = point(x, y, z) }) | |
| else | |
| AIPlayAttacks(unit, context) | |
| end | |
| else | |
| AIPlayCombatAction("Move", unit, unit.ActionPoints, { goto_pos = point(x, y, z) }) | |
| end | |
| AITakeCover(unit) | |
| DoneObject(combat_path) | |
| return "done" | |
| end, | |
| }), | |
| }, | |
| Comment = "right corridor shoot-and-scoot action", | |
| group = "BossFights", | |
| id = "Corazon_ShootAndScoot", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('CustomAI', { | |
| 'turn_phase', "Early", | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 100, | |
| 'EnumDests', function (self, unit, context, debug_data) | |
| if g_TacticalMap then | |
| return g_TacticalMap:EnumDestsInAssignedArea(unit, context) | |
| end | |
| end, | |
| 'PickOptimalLoc', function (self, unit, context, debug_data) | |
| if g_TacticalMap then | |
| return g_TacticalMap:FindOptimalLocationInAssignedArea(unit, context) | |
| end | |
| end, | |
| 'PickEndTurnLoc', function (self, unit, context, debug_data) | |
| AITacticCalcPathDistances(unit, context, "disable bias") | |
| local policies = self:PickEndTurnPolicies(unit, context) or self.EndTurnPolicies | |
| context.ai_destination = AIScoreReachableVoxels(context, policies, self.OptLocWeight, nil, "avoid") | |
| return true | |
| end, | |
| 'SelectSignatureActions', function (self, unit, context, debug_data) | |
| return AITacticSelectSignatureActions(unit, context) | |
| end, | |
| }), | |
| }, | |
| group = "BossFights", | |
| id = "Faucheaux_BossRetreating", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackWeight = 0, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'Weight', 50, | |
| }), | |
| PlaceObj('AIPolicyProximity', { | |
| 'MinScore', 12, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Invert', true, | |
| }), | |
| }, | |
| }), | |
| }, | |
| MoveStance = "Crouch", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyProximity', { | |
| 'MinScore', 12, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Invert', true, | |
| }), | |
| PlaceObj('AIPolicyTakeCover', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| group = "Civilian", | |
| id = "ActiveCivilian", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackWeight = 0, | |
| Behaviors = { | |
| PlaceObj('HoldPositionAI', { | |
| 'Priority', true, | |
| }), | |
| PlaceObj('StandardAI', { | |
| 'Weight', 0, | |
| }), | |
| }, | |
| MoveStance = "Crouch", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyTakeCover', nil), | |
| }, | |
| PrefStance = "Crouch", | |
| group = "Civilian", | |
| id = "AnimTestDummy_Crouched", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackWeight = 0, | |
| Behaviors = { | |
| PlaceObj('HoldPositionAI', { | |
| 'Priority', true, | |
| }), | |
| PlaceObj('StandardAI', { | |
| 'Weight', 0, | |
| }), | |
| }, | |
| MoveStance = "Prone", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyTakeCover', nil), | |
| }, | |
| PrefStance = "Prone", | |
| group = "Civilian", | |
| id = "AnimTestDummy_Prone", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackWeight = 0, | |
| Behaviors = { | |
| PlaceObj('HoldPositionAI', { | |
| 'Priority', true, | |
| }), | |
| PlaceObj('StandardAI', { | |
| 'Weight', 0, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyTakeCover', nil), | |
| }, | |
| group = "Civilian", | |
| id = "AnimTestDummy_Standing", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| PlaceObj('AIPolicyProximity', { | |
| 'Weight', 1000, | |
| 'MinScore', 10, | |
| }), | |
| }, | |
| 'TakeCoverChance', 100, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| PlaceObj('AIPolicyProximity', { | |
| 'Weight', 1000, | |
| 'MinScore', 10, | |
| }), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| SignatureActions = { | |
| PlaceObj('AIActionMobileShot', { | |
| 'Weight', 200, | |
| 'NotificationText', "", | |
| 'action_id', "RunAndGun", | |
| }), | |
| }, | |
| TargetScoreRandomization = 40, | |
| group = "Lieutenants", | |
| id = "CorazonBoss", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Neck", "Torso" ), | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeBase', "Melee", | |
| 'RangeMin', 0, | |
| 'RangeMax', 6, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| SignatureActions = { | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "StunGrenade", | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "StunGrenade", | |
| 'Effect', "disable", | |
| }), | |
| }, | |
| 'min_score', 100, | |
| 'MinDist', 3000, | |
| 'AllowedAoeTypes', set( "fire", "none", "teargas", "toxicgas" ), | |
| }), | |
| PlaceObj('AIActionCharge', { | |
| 'BiasId', "PierreCharge", | |
| 'Weight', 300, | |
| }), | |
| }, | |
| TargetChangePolicy = "restart", | |
| TargetScoreRandomization = 10, | |
| group = "Lieutenants", | |
| id = "Pierre", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Arms", "Groin", "Legs", "Torso" ), | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'BiasId', "Standard", | |
| 'Weight', 150, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'Weight', 50, | |
| 'visibility_mode', "team", | |
| }), | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| }), | |
| }, | |
| MoveStance = "Crouch", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyTakeCover', nil), | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Weight', 300, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 10, | |
| 'RangeMin', 10, | |
| 'RangeMax', 25, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 20, | |
| 'RangeMin', 26, | |
| 'RangeMax', 49, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeMin', 50, | |
| 'RangeMax', 100, | |
| }), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| SignatureActions = { | |
| PlaceObj('AIActionHeavyWeaponAttack', { | |
| 'BiasId', "PierreGuardLauncherFire", | |
| 'Weight', 1000, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "PierreGuardLauncherFire", | |
| 'Effect', "disable", | |
| 'Period', 10, | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "PierreGuardLauncherFire", | |
| 'Effect', "disable", | |
| 'Value', -50, | |
| 'Period', 10, | |
| 'ApplyTo', "Team", | |
| }), | |
| }, | |
| 'self_score_mod', -1000, | |
| 'min_score', 100, | |
| 'MinDist', 5000, | |
| }), | |
| }, | |
| TargetScoreRandomization = 10, | |
| group = "Lieutenants", | |
| id = "PierreGuard", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'BiasId', "Standard", | |
| 'Weight', 80, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'Weight', 50, | |
| 'visibility_mode', "team", | |
| }), | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'Weight', 400, | |
| }), | |
| }, | |
| }), | |
| PlaceObj('StandardAI', { | |
| 'Fallback', false, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'SignatureActions', { | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "Autofire", | |
| 'Weight', 70, | |
| 'Priority', true, | |
| 'NotificationText', "", | |
| 'action_id', "AutoFire", | |
| 'AttackTargeting', set( "Torso" ), | |
| }), | |
| }, | |
| }), | |
| }, | |
| Comment = "basic flank and attack AI", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 600, | |
| 'RangeBase', "Absolute", | |
| 'RangeMin', 4, | |
| 'RangeMax', 8, | |
| }), | |
| PlaceObj('AIPolicyHighGround', { | |
| 'Weight', 30, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| SignatureActions = { | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "Autofire", | |
| 'Weight', 70, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "Autofire", | |
| 'Value', -500, | |
| 'Period', 2, | |
| }), | |
| }, | |
| 'NotificationText', "", | |
| 'action_id', "AutoFire", | |
| 'Aiming', "Remaining AP", | |
| 'AttackTargeting', set( "Torso" ), | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "WildThrowGrenade", | |
| 'Weight', 300, | |
| 'Priority', true, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "WildThrowGrenade", | |
| 'Effect', "disable", | |
| 'Value', -300, | |
| 'Period', 0, | |
| }), | |
| }, | |
| 'team_score', 0, | |
| 'self_score_mod', -1000, | |
| 'AllowedAoeTypes', set( "fire", "none", "teargas", "toxicgas" ), | |
| }), | |
| }, | |
| TargetingPolicies = { | |
| PlaceObj('AITargetingCancelShot', { | |
| 'Weight', 80, | |
| }), | |
| }, | |
| group = "Lieutenants", | |
| id = "TheMajor", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Torso" ), | |
| BaseAttackWeight = 50, | |
| BaseMovementWeight = 0, | |
| Behaviors = { | |
| PlaceObj('HoldPositionAI', { | |
| 'BiasId', "HoldPositionBehavior", | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'SignatureActions', { | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "LegShot", | |
| 'Weight', 120, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "LegShot", | |
| 'Effect', "disable", | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "DefensiveOverwatch", | |
| 'Effect', "priority", | |
| 'Period', 0, | |
| }), | |
| }, | |
| 'Aiming', "Remaining AP", | |
| 'AttackTargeting', set( "Legs" ), | |
| }), | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "ArmShot", | |
| 'Weight', 120, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "ArmShot", | |
| 'Effect', "disable", | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "DefensiveOverwatch", | |
| 'Effect', "priority", | |
| 'Period', 0, | |
| }), | |
| }, | |
| 'Aiming', "Remaining AP", | |
| 'AttackTargeting', set( "Groin" ), | |
| }), | |
| PlaceObj('AIConeAttack', { | |
| 'BiasId', "DefensiveOverwatch", | |
| 'Weight', 10, | |
| 'team_score', 0, | |
| 'min_score', 100, | |
| 'action_id', "Overwatch", | |
| }), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeMin', 25, | |
| 'RangeMax', 100, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| group = "Lieutenants", | |
| id = "TurretBoss", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'CheckLOS', false, | |
| }), | |
| }, | |
| }), | |
| }, | |
| MoveStance = "Crouch", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeBase', "Absolute", | |
| 'RangeMin', 20, | |
| 'RangeMax', 50, | |
| }), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| SignatureActions = { | |
| PlaceObj('AIActionHeavyWeaponAttack', { | |
| 'BiasId', "MortarShot", | |
| 'Priority', true, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "MortarShot", | |
| 'Effect', "disable", | |
| }), | |
| }, | |
| 'team_score', 0, | |
| 'self_score_mod', 0, | |
| 'MinDist', 12000, | |
| 'action_id', "Bombard", | |
| }), | |
| }, | |
| TargetScoreRandomization = 10, | |
| group = "Simplified", | |
| id = "Artillery", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Neck", "Torso" ), | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| Comment = "Keywords: Explosives", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeBase', "Melee", | |
| 'RangeMin', 0, | |
| 'RangeMax', 6, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| SignatureActions = { | |
| PlaceObj('AIActionMobileShot', { | |
| 'Priority', true, | |
| 'NotificationText', "", | |
| 'RequiredKeywords', { | |
| "RunAndGun", | |
| }, | |
| 'action_id', "RunAndGun", | |
| }), | |
| PlaceObj('AIActionMobileShot', { | |
| 'Priority', true, | |
| 'NotificationText', "", | |
| 'RequiredKeywords', { | |
| "MobileShot", | |
| }, | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "StunGrenade", | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "StunGrenade", | |
| 'Effect', "disable", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Explosives", | |
| }, | |
| 'min_score', 100, | |
| 'MinDist', 3000, | |
| 'AllowedAoeTypes', set( "fire", "none", "teargas", "toxicgas" ), | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "Nova", | |
| 'Weight', 300, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "Nova", | |
| 'Effect', "disable", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Nova", | |
| }, | |
| 'team_score', 0, | |
| 'self_score_mod', 100, | |
| 'MinDist', 0, | |
| 'MaxDist', 3000, | |
| 'AllowedAoeTypes', set( "fire", "none", "teargas", "toxicgas" ), | |
| }), | |
| }, | |
| TargetChangePolicy = "restart", | |
| TargetScoreRandomization = 10, | |
| group = "Simplified", | |
| id = "Brute", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Torso" ), | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'Weight', 1000, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeMin', 30, | |
| 'RangeMax', 80, | |
| }), | |
| }, | |
| 'SignatureActions', { | |
| PlaceObj('AIActionMGSetup', { | |
| 'Priority', true, | |
| 'team_score', 0, | |
| 'min_score', 100, | |
| 'cur_zone_mod', 140, | |
| }), | |
| PlaceObj('AIActionMGBurstFire', { | |
| 'AttackTargeting', set( "Torso" ), | |
| }), | |
| }, | |
| 'TakeCoverChance', 0, | |
| 'override_attack_id', "BurstFire", | |
| 'override_cost_id', "MGSetup", | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 600, | |
| 'RangeMin', 40, | |
| 'RangeMax', 80, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Weight', 200, | |
| }), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Prone", | |
| TargetScoreRandomization = 10, | |
| TargetingPolicies = { | |
| PlaceObj('AITargetingEnemyHealth', { | |
| 'Health', 50, | |
| 'AboveHealth', true, | |
| }), | |
| PlaceObj('AITargetingEnemyWeapon', nil), | |
| PlaceObj('AITargetingEnemyWeapon', { | |
| 'EnemyWeapon', "SMG", | |
| }), | |
| PlaceObj('AITargetingEnemyWeapon', { | |
| 'EnemyWeapon', "Shotgun", | |
| }), | |
| }, | |
| group = "Simplified", | |
| id = "HeavyGunner", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Arms", "Torso" ), | |
| BaseAttackWeight = 80, | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'BiasId', "Standard", | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'Weight', 20, | |
| }), | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeMin', 60, | |
| 'RangeMax', 100, | |
| }), | |
| }, | |
| 'SignatureActions', { | |
| PlaceObj('AIActionMobileShot', { | |
| 'Priority', true, | |
| 'NotificationText', "", | |
| }), | |
| }, | |
| 'TakeCoverChance', 50, | |
| }), | |
| PlaceObj('StandardAI', { | |
| 'BiasId', "Healer", | |
| 'Priority', true, | |
| 'Fallback', false, | |
| 'Score', function (self, unit, proto_context, debug_data) | |
| for _, ally in ipairs(unit.team.units) do | |
| if not ally:IsDead() and ally.HitPoints < MulDivRound(ally.MaxHitPoints, 70, 100) then | |
| return self.Weight | |
| end | |
| end | |
| return 0 | |
| end, | |
| 'turn_phase', "Late", | |
| 'OptLocWeight', 1, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyHealingRange', { | |
| 'Weight', 300, | |
| 'CanUseMod', 1000, | |
| }), | |
| }, | |
| 'SignatureActions', { | |
| PlaceObj('AIActionBandage', { | |
| 'Priority', true, | |
| 'RequiredKeywords', { | |
| "Heal", | |
| }, | |
| 'CanUseMod', 1000, | |
| }), | |
| PlaceObj('AIActionStim', { | |
| 'Priority', true, | |
| 'RequiredKeywords', { | |
| "Stim", | |
| }, | |
| 'TargetRules', { | |
| PlaceObj('AIStimRule', { | |
| 'Keyword', "Flank", | |
| 'Weight', 100, | |
| }), | |
| PlaceObj('AIStimRule', { | |
| 'Keyword', "Control", | |
| 'Weight', 50, | |
| }), | |
| PlaceObj('AIStimRule', { | |
| 'Keyword', "Explosives", | |
| 'Weight', 50, | |
| }), | |
| PlaceObj('AIStimRule', { | |
| 'Keyword', "Ordnance", | |
| 'Weight', 50, | |
| }), | |
| PlaceObj('AIStimRule', { | |
| 'Keyword', "RunAndGun", | |
| 'Weight', 100, | |
| }), | |
| }, | |
| }), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| TargetScoreRandomization = 10, | |
| TargetingPolicies = { | |
| PlaceObj('AITargetingCancelShot', { | |
| 'Weight', 200, | |
| }), | |
| }, | |
| group = "Simplified", | |
| id = "Medic", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Arms", "Legs", "Torso" ), | |
| BaseAttackWeight = 10, | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'Weight', 10, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 50, | |
| }), | |
| PlaceObj('PositioningAI', { | |
| 'BiasId', "Flanking", | |
| 'Weight', 500, | |
| 'Fallback', false, | |
| 'RequiredKeywords', { | |
| "Flank", | |
| }, | |
| 'OptLocWeight', 20, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyFlanking', { | |
| 'Weight', 1000, | |
| 'Required', true, | |
| 'ReserveAttackAP', true, | |
| }), | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'TakeCoverChance', 0, | |
| 'VoiceResponse', "AIFlanking", | |
| }), | |
| }, | |
| Comment = "Keywords: Flank, Explosives", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 300, | |
| 'RangeBase', "Absolute", | |
| 'RangeMin', 2, | |
| 'RangeMax', 8, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| SignatureActions = { | |
| PlaceObj('AIActionMobileShot', { | |
| 'Priority', true, | |
| 'NotificationText', "", | |
| 'RequiredKeywords', { | |
| "RunAndGun", | |
| }, | |
| 'action_id', "RunAndGun", | |
| }), | |
| PlaceObj('AIActionMobileShot', { | |
| 'Priority', true, | |
| 'NotificationText', "", | |
| 'RequiredKeywords', { | |
| "MobileShot", | |
| }, | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "AssaultGrenadeThrow", | |
| 'Weight', 200, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "AssaultGrenadeThrow", | |
| 'Effect', "disable", | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "AssaultGrenadeThrow", | |
| 'Value', -50, | |
| 'Period', 0, | |
| 'ApplyTo', "Team", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Explosives", | |
| }, | |
| 'AllowedAoeTypes', set( "fire", "none", "teargas", "toxicgas" ), | |
| }), | |
| }, | |
| TargetScoreRandomization = 10, | |
| TargetingPolicies = { | |
| PlaceObj('AITargetingEnemyHealth', { | |
| 'Health', 50, | |
| }), | |
| PlaceObj('AITargetingEnemyWeapon', { | |
| 'EnemyWeapon', "Sniper", | |
| }), | |
| }, | |
| group = "Simplified", | |
| id = "Skirmisher", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Torso" ), | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'BiasId', "Standard", | |
| 'Weight', 150, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'Weight', 50, | |
| 'visibility_mode', "team", | |
| }), | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'TakeCoverChance', 50, | |
| }), | |
| }, | |
| Comment = "Keywords: Soldier, Sniper, Control, Ordnance, Smoke, Explosives", | |
| MoveStance = "Crouch", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'Weight', 50, | |
| }), | |
| PlaceObj('AIPolicyHighGround', { | |
| 'RequiredKeywords', { | |
| "Sniper", | |
| }, | |
| 'Weight', 200, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Weight', 300, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 50, | |
| 'RangeMin', 10, | |
| 'RangeMax', 25, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeMin', 26, | |
| 'RangeMax', 49, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 150, | |
| 'RangeMin', 50, | |
| 'RangeMax', 100, | |
| }), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| SignatureActions = { | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "Autofire", | |
| 'Weight', 150, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "Autofire", | |
| 'Effect', "disable", | |
| 'Period', 0, | |
| 'ApplyTo', "Team", | |
| }), | |
| }, | |
| 'NotificationText', "", | |
| 'RequiredKeywords', { | |
| "Soldier", | |
| }, | |
| 'action_id', "AutoFire", | |
| 'AttackTargeting', set( "Torso" ), | |
| }), | |
| PlaceObj('AIActionPinDown', { | |
| 'BiasId', "PinDownAttack", | |
| 'Weight', 80, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "PinDownAttack", | |
| 'Value', -50, | |
| 'ApplyTo', "Team", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Sniper", | |
| }, | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "AssaultGrenadeThrow", | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "AssaultGrenadeThrow", | |
| 'Effect', "disable", | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "AssaultGrenadeThrow", | |
| 'Effect', "disable", | |
| 'Period', 0, | |
| 'ApplyTo', "Team", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Explosives", | |
| }, | |
| 'self_score_mod', -1000, | |
| 'AllowedAoeTypes', set( "fire", "none", "teargas", "toxicgas" ), | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "SmokeGrenade", | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "SmokeGrenade", | |
| 'Effect', "disable", | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "SmokeGrenade", | |
| 'Effect', "disable", | |
| 'Period', 0, | |
| 'ApplyTo', "Team", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Smoke", | |
| }, | |
| 'enemy_score', 0, | |
| 'team_score', 100, | |
| 'self_score_mod', 100, | |
| 'MinDist', 0, | |
| 'AllowedAoeTypes', set( "smoke" ), | |
| }), | |
| PlaceObj('AIActionHeavyWeaponAttack', { | |
| 'BiasId', "LauncherFire", | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "LauncherFire", | |
| 'Effect', "disable", | |
| 'Period', 0, | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "LauncherFire", | |
| 'Value', -50, | |
| 'Period', 0, | |
| 'ApplyTo', "Team", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Ordnance", | |
| }, | |
| 'self_score_mod', -1000, | |
| 'MinDist', 5000, | |
| 'LimitRange', true, | |
| 'MaxTargetRange', 30, | |
| }), | |
| PlaceObj('AIActionHeavyWeaponAttack', { | |
| 'BiasId', "RocketFire", | |
| 'Weight', 200, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "RocketFire", | |
| 'Effect', "disable", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Ordnance", | |
| }, | |
| 'self_score_mod', -1000, | |
| 'MinDist', 5000, | |
| 'action_id', "RocketLauncherFire", | |
| 'LimitRange', true, | |
| 'MaxTargetRange', 30, | |
| }), | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "GroinShot", | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "GroinShot", | |
| 'Effect', "disable", | |
| 'Period', 0, | |
| 'ApplyTo', "Team", | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "GroinShot", | |
| 'Effect', "disable", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Sniper", | |
| }, | |
| 'Aiming', "Remaining AP", | |
| 'AttackTargeting', set( "Groin" ), | |
| }), | |
| PlaceObj('AIConeAttack', { | |
| 'BiasId', "Overwatch", | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "Overwatch", | |
| 'Value', -50, | |
| 'ApplyTo', "Team", | |
| }), | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "Overwatch", | |
| 'Effect', "disable", | |
| 'Value', -50, | |
| 'Period', 2, | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Soldier", | |
| }, | |
| 'team_score', 0, | |
| 'min_score', 300, | |
| 'action_id', "Overwatch", | |
| }), | |
| PlaceObj('AIConeAttack', { | |
| 'BiasId', "SpamOverwatch", | |
| 'Weight', 200, | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "SpamOverwatch", | |
| 'Effect', "disable", | |
| 'Value', -50, | |
| 'ApplyTo', "Team", | |
| }), | |
| }, | |
| 'RequiredKeywords', { | |
| "Control", | |
| }, | |
| 'team_score', 0, | |
| 'min_score', 100, | |
| 'action_id', "Overwatch", | |
| }), | |
| }, | |
| TargetScoreRandomization = 10, | |
| group = "Simplified", | |
| id = "Soldier", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseAttackTargeting = set( "Arms", "Legs", "Torso" ), | |
| BaseAttackWeight = 50, | |
| BaseMovementWeight = 0, | |
| Behaviors = { | |
| PlaceObj('HoldPositionAI', { | |
| 'BiasId', "HoldPositionBehavior", | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| SignatureActions = { | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "Autofire", | |
| 'OnActivationBiases', { | |
| PlaceObj('AIBiasModification', { | |
| 'BiasId', "Autofire", | |
| 'Effect', "disable", | |
| }), | |
| }, | |
| 'NotificationText', "", | |
| 'action_id', "AutoFire", | |
| 'Aiming', "Remaining AP", | |
| 'AttackTargeting', set( "Torso" ), | |
| }), | |
| }, | |
| TargetScoreRandomization = 10, | |
| group = "Simplified", | |
| id = "Turret", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'Required', true, | |
| }), | |
| }, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Required', true, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Required', true, | |
| 'RangeBase', "Melee", | |
| 'RangeMin', 1, | |
| 'RangeMax', 5, | |
| }), | |
| }, | |
| OptLocSearchRadius = 10, | |
| SignatureActions = { | |
| PlaceObj('AIActionBasicAttack', { | |
| 'BiasId', "MeleeAttack", | |
| 'Priority', true, | |
| }), | |
| PlaceObj('AIActionMGSetup', { | |
| 'BiasId', "MGSetup", | |
| 'team_score', 0, | |
| 'min_score', 100, | |
| 'cur_zone_mod', 140, | |
| }), | |
| PlaceObj('AIActionMGBurstFire', { | |
| 'BiasId', "MGBurst", | |
| }), | |
| PlaceObj('AIActionBandage', { | |
| 'BiasId', "Bandage", | |
| 'MaxHp', 90, | |
| 'SelfHealMod', 500, | |
| }), | |
| PlaceObj('AIActionHeavyWeaponAttack', { | |
| 'BiasId', "RPGFire", | |
| 'action_id', "RocketLauncherFire", | |
| }), | |
| PlaceObj('AIActionHeavyWeaponAttack', { | |
| 'BiasId', "LauncherFire", | |
| }), | |
| PlaceObj('AIActionHeavyWeaponAttack', { | |
| 'BiasId', "MortarShot", | |
| 'action_id', "Bombard", | |
| }), | |
| PlaceObj('AIActionMobileShot', { | |
| 'BiasId', "RunAndGun", | |
| 'NotificationText', "", | |
| 'action_id', "RunAndGun", | |
| }), | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "SingleShot", | |
| }), | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "BurstFire", | |
| 'action_id', "BurstFire", | |
| }), | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "Autofire", | |
| 'NotificationText', "", | |
| 'action_id', "AutoFire", | |
| }), | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "Buckshot", | |
| 'action_id', "Buckshot", | |
| }), | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "DoubleBarrel", | |
| 'NotificationText', "", | |
| 'action_id', "DoubleBarrel", | |
| }), | |
| PlaceObj('AIActionPinDown', { | |
| 'BiasId', "PinDown", | |
| }), | |
| PlaceObj('AIConeAttack', { | |
| 'BiasId', "Overwatch", | |
| 'team_score', 0, | |
| 'min_score', 1, | |
| 'action_id', "Overwatch", | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "FragGrenade", | |
| 'team_score', 0, | |
| 'AllowedAoeTypes', set( "fire", "none", "teargas", "toxicgas" ), | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "SmokeGrenade", | |
| 'team_score', 0, | |
| 'AllowedAoeTypes', set( "smoke" ), | |
| }), | |
| }, | |
| group = "System", | |
| id = "AITestArchetype", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'Weight', 50, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| Comment = "morale-related (cloned Assault)", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 600, | |
| 'RangeBase', "Absolute", | |
| 'RangeMin', 4, | |
| 'RangeMax', 8, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| PrefStance = "Crouch", | |
| SignatureActions = { | |
| PlaceObj('AIAttackSingleTarget', { | |
| 'BiasId', "Autofire", | |
| 'Weight', 200, | |
| 'NotificationText', "", | |
| 'action_id', "AutoFire", | |
| 'AttackTargeting', set( "Torso" ), | |
| }), | |
| PlaceObj('AIActionThrowGrenade', { | |
| 'BiasId', "AssaultGrenadeThrow", | |
| 'AllowedAoeTypes', set( "fire", "none", "teargas", "toxicgas" ), | |
| }), | |
| }, | |
| group = "System", | |
| id = "Berserk", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('RetreatAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'Weight', 10, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Weight', 300, | |
| 'Invert', true, | |
| }), | |
| PlaceObj('AIRetreatPolicy', { | |
| 'Weight', 1000, | |
| 'Required', false, | |
| }), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| Comment = "retreat", | |
| OptLocPolicies = { | |
| PlaceObj('AIRetreatPolicy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| group = "System", | |
| id = "Deserter", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('ApproachInteractableAI', { | |
| 'Comment', "approach/man the selected emplacement", | |
| 'Score', function (self, unit, proto_context, debug_data) | |
| local emplacement = g_Combat and g_Combat:GetEmplacementAssignment(unit) | |
| if not emplacement or emplacement.manned_by then | |
| return 0 | |
| end | |
| return self.Weight | |
| end, | |
| 'OptLocWeight', 1000, | |
| 'TakeCoverChance', 0, | |
| }), | |
| PlaceObj('HoldPositionAI', { | |
| 'Comment', "when manning emplacement", | |
| 'Score', function (self, unit, proto_context, debug_data) | |
| local emplacement = g_Combat and g_Combat:GetEmplacementAssignment(unit) | |
| if not emplacement or emplacement.manned_by ~= unit then | |
| return 0 | |
| end | |
| return self.Weight | |
| end, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| OptLocSearchRadius = 80, | |
| group = "System", | |
| id = "EmplacementGunner", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('CustomAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 100, | |
| 'EnumDests', function (self, unit, context, debug_data) | |
| if g_TacticalMap then | |
| return g_TacticalMap:EnumDestsInAssignedArea(unit, context) | |
| end | |
| end, | |
| 'PickEndTurnPolicies', function (self, unit, context, debug_data) | |
| return AITacticSelectEndTurnPolicies(unit, context) | |
| end, | |
| 'PickOptimalLoc', function (self, unit, context, debug_data) | |
| if g_TacticalMap then | |
| return g_TacticalMap:FindOptimalLocationInAssignedArea(unit, context) | |
| end | |
| end, | |
| 'PickEndTurnLoc', function (self, unit, context, debug_data) | |
| AITacticCalcPathDistances(unit, context, "disable bias") | |
| local policies = self:PickEndTurnPolicies(unit, context) or self.EndTurnPolicies | |
| local weight = self.OptLocWeight | |
| if context.optimal_dest_in_assigned_area and context.assigned_area_unreachable then | |
| weight = weight * 10 | |
| end | |
| context.ai_destination = AIScoreReachableVoxels(context, policies, weight, debug_data and debug_data.reachable_scores, "prefer") | |
| return true | |
| end, | |
| 'SelectSignatureActions', function (self, unit, context, debug_data) | |
| return AITacticSelectSignatureActions(unit, context) | |
| end, | |
| }), | |
| }, | |
| FallbackAction = "overwatch", | |
| group = "System", | |
| id = "GuardArea", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('RetreatAI', { | |
| 'turn_phase', "Early", | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'Weight', 10, | |
| }), | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Weight', 300, | |
| 'Invert', true, | |
| }), | |
| PlaceObj('AIPolicyProximity', { | |
| 'Weight', 1000, | |
| }), | |
| }, | |
| 'TakeCoverChance', 50, | |
| 'DespawnAllowed', false, | |
| }), | |
| }, | |
| Comment = "morale-related (based on Deserter)", | |
| OptLocPolicies = { | |
| PlaceObj('AIRetreatPolicy', nil), | |
| }, | |
| OptLocSearchRadius = 100, | |
| group = "System", | |
| id = "Panicked", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'Priority', true, | |
| 'Comment', "breaking pindown", | |
| 'Score', function (self, unit, proto_context, debug_data) | |
| local enemies = {} | |
| for _, descr in pairs(g_Pindown) do | |
| if descr.target == self then | |
| enemies[#enemies + 1] = enemy | |
| end | |
| end | |
| return #enemies > 0 and self.Weight or 0 | |
| end, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyLosToEnemy', { | |
| 'Invert', true, | |
| }), | |
| PlaceObj('AIPolicyDealDamage', nil), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| PlaceObj('StandardAI', { | |
| 'Comment', "fallback (aggressive)", | |
| 'Fallback', false, | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'Weight', 600, | |
| }), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'RangeBase', "Absolute", | |
| 'RangeMin', 0, | |
| 'RangeMax', 5, | |
| }), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyLosToEnemy', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| group = "System", | |
| id = "PinnedDown", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| BaseMovementWeight = 10, | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| Comment = "used to advance toward last known enemy location", | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyLastEnemyPos', nil), | |
| }, | |
| OptLocSearchRadius = 80, | |
| group = "System", | |
| id = "Scout_LastLocation", | |
| }) | |
| PlaceObj('AIArchetype', { | |
| Behaviors = { | |
| PlaceObj('StandardAI', { | |
| 'EndTurnPolicies', { | |
| PlaceObj('AIPolicyDealDamage', { | |
| 'Weight', 600, | |
| }), | |
| PlaceObj('AIPolicyTakeCover', { | |
| 'visibility_mode', "team", | |
| }), | |
| }, | |
| 'TakeCoverChance', 0, | |
| }), | |
| }, | |
| OptLocPolicies = { | |
| PlaceObj('AIPolicyTakeCover', nil), | |
| PlaceObj('AIPolicyWeaponRange', { | |
| 'Weight', 600, | |
| 'RangeMin', 25, | |
| 'RangeMax', 50, | |
| }), | |
| }, | |
| OptLocSearchRadius = 80, | |
| group = "Tutorial", | |
| id = "TutorialMinion", | |
| }) | |