myspace / Data /AIArchetype.lua
sirnii's picture
Upload 1816 files
b6a38d7 verified
raw
history blame
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",
})