CD Code Digest Hub /GTA V · v2

任务族谱(Task Catalogue)

78 分钟阅读 7 个章节 5 张图

game/task 约 700 个文件、60 万行,包含 400 多个任务类型。本页不逐文件总结,而是按目录给出“族谱”:每个子目录的关键任务类、职责、它们之间的父子/调用关系,以及配套的元数据(Metadata.psc)与管理器;随后对最核心的五个机制给出状态机级说明:战斗(CTaskCombat)、导航跟随(CTaskNavBase/CTaskMoveFollowNavMesh)、上车(CTaskEnterVehicle)、动作/运动(CTaskMotionPed/CTaskHumanLocomotion)以及场景系统(CScenarioManager/CScenarioPointManager/CTaskUseScenario)。

背景与相关页面#

盘点#

子目录文件数行数(不含空行,约)主题
Combat114124k战斗、掩体、近战、伤亡、搜索、载具战斗/追逐、战术分析
Movement8788k导航跟随、goto、闲逛移动、攀爬/梯子/翻越/跳跃/坠落、跳伞、喷气背包
Vehicle4987k上下车、车内动作、车载武器、骑马、火车
Scenario8356k场景点、场景类型元数据、场景任务、链/簇、编辑器
Motion4943k动作树任务:人形/动物运动、瞄准动作、游泳、跳伞动作
Default3638k默认/环境任务:玩家、闲逛、未警觉、巡逻、逮捕/手铐、环境片段
Physics7934kNM 行为任务、从 NM 混出、附着、起身数据
Response6930k逃跑、惊吓反应、激怒系统、推搡、爆炸反应
System3829k内核(见 task-system)
Weapons4228k枪械/瞄准/装弹/换枪/投掷/炸弹
Service1316k警察/SWAT/消防/救护/军队/目击者
Animation1213k脚本动画、同步场景、过场、MoVE 脚本网络
General1312k基础任务、次要任务、手机、序列
Crimes113k随机事件(犯罪)管理、偷车、追捕
Helpers62k对话、道具管理、人行道洪泛辅助
Debug2<0.1k片段距离测试任务

以上数字由本次分析对目录逐文件计数得到(PowerShell Measure-Object -Line,不计空行),仅作规模参考。每个任务目录都有一个 Metadata.psc 定义该目录任务的 Tunables(基类 CTuning),统一由 TaskClassInfo.cpp 引入生成代码 game/task/System/TaskClassInfo.cpp:260-275,加载机制见 task-system §10。

阅读约定:下表“类 < 基类 @行”取自头文件的类声明行;CTaskFSMClone 基类意味着该任务可在网络克隆上运行(见 task-system §9);CTaskMove/CTaskMoveBase/CTaskNavBase 基类意味着它只能进入移动树;CTaskMotionBase 意味着它只能进入动作树。

1. 任务之间的典型组合#

证据:CTaskThreatResponse 创建 CTaskCombat/CTaskSmartFlee game/task/Combat/TaskThreatResponse.cpp:1256、TaskThreatResponse.cpp:1351;CTaskCombat 的各状态创建 CTaskCover、CTaskShootAtTarget、CTaskComplexControlMovement 等(§3.1);CTaskWander 用 CTaskComplexControlMovement(CTaskMoveWander, CTaskAmbientClips) game/task/Default/TaskWander.cpp:600-615;CTaskUseScenario 在 PlayAmbients 中创建 CTaskAmbientClips game/task/Scenario/Types/TaskUseScenario.cpp:4108;CTaskNavBase 跟随路线时创建 CTaskMoveGoToPointAndStandStill 等 goto 子任务 game/task/Movement/TaskNavBase.cpp:4259-4330;CTaskMotionPed 在 OnFoot 创建 CTaskHumanLocomotion game/task/Motion/Locomotion/TaskMotionPed.cpp:1510-1519;心跳与 MBR 写入见 task-system §5.1。

2. 按目录的族谱#

2.1 System(内核)#

CTask、CTaskFSMClone、CTaskMove/CTaskMoveBase、CTaskComplex、树/管理器、CTuning,以及 TaskHelpers.h 中的通用辅助(CTaskTimer、CPathNodeRouteSearchHelper、CGetupProbeHelper、CSimpleBlendHelper、CGenericClipHelper、CFindNearestCarNodeHelper、CCoverPointStatusHelper、CScenarioClipHelper)game/task/System/TaskHelpers.h:151-3760。详见 task-system。

2.2 General(基础/次要/手机/序列)#

类 < 基类职责
CTaskComplexControlMovement < CTaskComplex @100主树中托管一个移动任务(心跳)并可并行跑一个主子任务;终止条件可选移动结束/子任务结束/任一/全部 game/task/General/TaskBasic.h:100-121
CTaskDoNothing < CTask @505默认任务(任务行人/不闲逛的行人)
CTaskNetworkClone < CTask @64克隆行人的默认任务
CTaskUseSequence < CTaskFSMClone @1499、CTaskMoveSequence < CTaskMove @764脚本序列(主任务序列/移动序列)
CTaskSetCharState 族、CTaskSetPedDefensiveArea、CTaskSetCharDecisionMaker设置行人状态/防御区/决策制定器的“瞬时任务”
CTaskPause、CTaskUninterruptable、CTaskCrouchToggle、CTaskSayAudio、CTaskOpenDoor、CTaskShovePed、CTaskClearLookAt杂项基础任务
CTaskComplexUseMobilePhone(AndMovement)、CTaskMobilePhone、CTaskCallPolice手机行为(含报警)
CTaskAffectSecondaryBehaviour、CTaskCrouch、CTaskPutOnHelmet/TakeOffHelmet、CTaskAggressiveRubberneck、CTaskGeneralSweep次树任务(叠加行为)

类声明见 TaskBasic.h:33-1736、game/task/General/TaskSecondary.h:33-224、game/task/General/Phone/TaskMobilePhone.h:9、game/task/General/Phone/TaskCallPolice.h:22、game/task/General/TaskVehicleSecondary.h:19、game/task/General/TaskGeneralSweep.h:12。

2.3 Default(默认与环境行为)#

类 < 基类职责
CTaskPlayerOnFoot < CTask @36本地玩家的根任务:把输入映射为跳跃、近战、换枪、掩体、梯子、开枪、上车、逮捕、骑乘、跳伞/喷气背包脱卸、滑坡等 20 多个状态 game/task/Default/TaskPlayer.h:36-64;它由当前动作任务的 CreatePlayerControlTask() 创建为默认任务(见 task-system §5.1)
CTaskMovePlayer < CTaskMove @716玩家移动输入→移动树
CTaskWander < CTask @34环境闲逛:Wander/CrossRoadAtLights/CrossRoadJayWalking/MoveToShelterAndWait/Crime/BlockedByVehicle… 状态 game/task/Default/TaskWander.h:75-84,内部用 CTaskMoveWander 并可插入场景使用
CTaskUnalerted < CTaskFSMClone @27场景/闲逛行人的“未警觉”根任务:在闲逛、搜索场景、沿场景链、使用场景、车内、等待载具着陆、走向消失等状态间切换 game/task/Default/TaskUnalerted.h:87-100;由 CScenarioManager 包装 CTaskUseScenario 生成 game/task/Scenario/ScenarioManager.cpp:5179
CTaskAmbientClips < CTaskFSMClone @560基于“条件动画”(CConditionalAnimsGroup)的环境片段/道具播放(场景、闲逛共用)
CTaskPatrol、CTaskStandGuardFSM、CPatrolNode/CPatrolLink巡逻路线与站岗 game/task/Default/Patrol/TaskPatrol.h:50-137、Patrol/PatrolRoutes.h:28-96
CTaskArrest、CTaskCuffed、CTaskInCustody、CTaskIncapacitated逮捕/手铐/羁押/失能(部分由 ENABLE_TASKS_ARREST_CUFFED、CNC_MODE_ENABLED 等宏控制)
CTaskChat、CTaskSlopeScramble、CTaskSwimmingWander、CTaskFlyingWander、CTaskWanderInArea其他环境行为
CAmbientAudioManager、AmbientAnimationManager环境对白/动画流送管理(CTask::StaticUpdate 每帧更新环境片段流送)game/task/System/Task.cpp:148-151

类声明行见 TaskPlayer.h:36-823、TaskWander.h:34-593、TaskUnalerted.h:27、TaskAmbient.h:560、TaskCuffed.h:41-491、TaskArrest.h:55、TaskIncapacitated.h:12。

2.4 Combat(战斗)#

类 < 基类职责
CTaskThreatResponse < CTask @31事件处理器产生的威胁响应入口:Analysis 决定战/逃,进入 Combat、Flee 或 ReactAndFlee game/task/Combat/TaskThreatResponse.h:49-66。决策链依次:规则→战斗行为→属性→性格→兜底 TaskThreatResponse.cpp:647-720
CTaskCombat < CTaskFSMClone(TaskNewCombat.h)@124主战斗任务(§3.1)
CTaskCombatFlank、CTaskCombatSeekCover、CTaskCombatChargeSubtask、CTaskSetAndGuardArea、CTaskStandGuard、CTaskSeparate、CTaskCombatClosestTargetInArea、CTaskCombatAdditionalTask(TaskCombat.h)旧战斗文件中保留的辅助/子任务;CTaskCombatAdditionalTask 是移动时并行执行的瞄射/手势子任务 game/task/Combat/TaskCombat.h:42-878
CTaskCover、CTaskEnterCover、CTaskExitCover、CTaskInCover、CTaskMotionInCover、CTaskAimGunFromCoverIntro/Outro、CTaskAimGunBlindFire、CDynamicCoverHelper掩体全流程(TaskCover.cpp 单文件约 3 万行)game/task/Combat/Cover/TaskCover.h:51-4291
CCover/CCoverPoint、CCoverFinder(CCoverFinderFSM : CTaskHelperFSM)、CCoverPointFilter*掩体点存储:导航网格掩体点 2560 + 脚本掩体点 64,边界区域 40 个 game/task/Combat/Cover/cover.h:757-771;掩体点从 pathserver 后台线程抽取(见导航页)
CTaskMelee、CTaskMeleeActionResult、CTaskMoveMeleeMovement、CTaskMeleeUpperbodyAnims、CTaskMeleeUninterruptable近战(TaskCombatMelee.cpp 约 9.5k 行)game/task/Combat/TaskCombatMelee.h:152-1176
CTaskDyingDead、CTaskHitResponse、CTaskComplexOnFire、CTaskDamageElectric、CTaskRevive受伤与死亡(TASK_DYING_DEAD 在克隆树上被强制应用)game/task/Combat/TaskDamageDeath.h:98-907
CTaskSearch(Base/OnFoot/InAutomobile/InBoat/InHeli)、CTaskInvestigate、CTaskSearchForUnknownThreat丢失目标后的搜索与调查
CTaskVehicleCombat、CTaskVehiclePersuit、CTaskVehicleChase(+CVehicleChaseDirector)、CTaskBoat*、CTaskHeli*、CTaskPlaneChase、CTaskSubmarine*、CTaskShootOutTire载具中的战斗与追逐
CTaskAdvance、CTaskCharge、CTaskShootAtTarget、CTaskVariedAimPose、CTaskTargetUnreachable(InInterior/Exterior)、CTaskReactToBuddyShot、CTaskShellShocked、CTaskStealthKill、CTaskDraggingToSafety/DraggedToSafety、CTaskAimFromGroundCombat/Subtasks 中供 CTaskCombat 各状态使用的子任务
CTaskWrithe、CTaskToHurtTransit、CTaskReactAimWeapon、CTaskSharkAttack/SharkCircle、CTaskCombatMounted(带骑乘转移表)、CTaskAnimatedHitByExplosion其他战斗相关任务
CCombatManager(CCombatMountedManager、CCombatMeleeManager、CCombatTaskManager)全局:近战组(每组最多 10 个对手)、战斗行人统计(数组 64、联机同时战斗上限 24)game/task/Combat/CombatManager.h:248-289、CombatManager.h:455-496
CCombatDirector、CCombatSituation{Normal,FallBack,Lull,Escalate}、CCombatOrders一组敌人共享的“导演”:协调射击、局势切换 game/task/Combat/CombatDirector.h:31-70、game/task/Combat/CombatSituation.h:69-139
CTacticalAnalysis(导航网格点 64、掩体点 64)针对目标的战术点分析,供 CTaskMoveToTacticalPoint 使用 game/task/Combat/TacticalAnalysis.h:399-401、TacticalAnalysis.h:950-973

2.5 Response(响应)#

类 < 基类职责
CTaskSmartFlee < CTaskFSMClone @83主逃跑任务:步行/滑雪/载具三张转移表;状态含下车、步行逃、找掩体蹲伏、回到起点、上车逃/急停/倒车/加速、举手、畏缩 game/task/Response/TaskFlee.h:42-221
CTaskEscapeBlast、CTaskScenarioFlee、CTaskFlyAway、CTaskExhaustedFlee、CTaskWalkAway其他逃离形式 TaskFlee.h:793-1206
CTaskReactAndFlee、CTaskReactInDirection、CTaskReactToExplosion、CTaskReactToImminentExplosion、CTaskReactToDeadPed/CTaskCheckPedIsDead、CTaskDiveToGround、CTaskDuckAndCover、CTaskSidestep、CTaskGrowlAndFlee先反应后逃/躲
CTaskShockingEvent 及 …Watch/Goto/HurryAway/React/BackAway/StopAndStare/ReactToAircraft/ThreatResponse/Flee、CTaskShockingPoliceInvestigate、CTaskShockingNiceCarPicture惊吓事件反应族 game/task/Response/TaskShockingEvents.h:22-1275
CTaskAgitated、CTaskAgitatedAction、CTaskConfront、CTaskIntimidate、CTaskShove、CTaskShoved、CTaskGangPatrol被冒犯/激怒后的对峙、推搡、挑衅
Response/Info/*:CAgitatedManager、CAgitatedAction*(约 35 种)、CAgitatedCondition*(约 90 种)、CAgitatedPersonality/Response/Trigger/State/Say/Situation激怒系统的数据驱动行为树:从 common:/data/ai/agitatedpersonalities|agitatedresponses|agitatedtriggers.meta 加载 game/task/Response/Info/AgitatedManager.cpp:38-52;条件/动作类声明见 Info/AgitatedConditions.h:31-1769、Info/AgitatedActions.h:35-903

2.6 Movement(移动)#

类 < 基类职责
CTaskNavBase < CTaskMove @487 → CTaskMoveFollowNavMesh @198、CTaskMoveWander @63基于 pathserver 的路线请求与跟随(§3.2)game/task/Movement/TaskNavBase.h:487、TaskNavMesh.h:198、TaskMoveWander.h:63
CTaskUseClimbOnRoute、CTaskUseDropDownOnRoute、CTaskUseLadderOnRoute、CTaskMoveWaitForNavMeshSpecialActionEvent、CTaskMoveReturnToRoute、CTaskMoveGetOntoMainNavMesh路线上的特殊动作(由导航任务发事件触发)TaskNavMesh.h:422-719
CTaskMoveGoToPoint < CTaskMoveBase @50 及 …OnRoute/AndStandStill/RelativeToEntity…/StandStillAchieveHeading直线 goto 的底层移动 game/task/Movement/TaskGotoPoint.h:50-841
CTaskMoveStandStill、CTaskMoveAchieveHeading、CTaskMoveFaceTarget、CTaskTurnToFaceEntityOrCoord原地/转向 game/task/Movement/TaskIdle.h:12-254
CTaskGoToPointAnyMeans、CTaskFollowPatrolRoute、CTaskGetOutOfWater、CTaskGoToScenario 等复合 goto(TaskGoTo.h)
CTaskFollowLeaderInFormation/AnyMeans、CTaskSeekEntityAiming、CEntitySeekPosCalculator* 模板、CTaskMoveFollowEntityOffset、CTaskMoveBeInFormation、CTaskMoveTrackingEntity跟随实体/编队
CTaskMoveToTacticalPoint、CTaskMoveWithinAttackWindow、CTaskMoveWithinDefensiveArea、CTaskGoToPointAiming战斗中的移动
CTaskWalkRoundEntity/Vehicle/VehicleDoor/Fire、CTaskComplexEvasiveStep、CTaskCower、CTaskHitWall碰撞/避让响应(多作为移动事件响应)
Climbing/*:CTaskVault、CTaskDropDown、CTaskClimbLadder、CTaskGoToAndClimbLadder、CTaskRappel/CTaskHeliPassengerRappel、CClimbDetector、CDropDownDetector、CLadderMetadataManager攀爬/梯子/降索
Jumping/*:CTaskJump、CTaskJumpVault、CTaskFallOver、CTaskFallAndGetUp、CTaskDropOverEdge、CTaskComplexStuckInAir;CTaskFall、CTaskGetUp、CTaskCrawl跳跃、坠落、起身
CTaskParachute/CTaskParachuteObject、CTaskJetpack/CJetpack跳伞与喷气背包
CTaskFollowWaypointRecording、CTaskSlideToCoord、CTaskTakeOffPedVariation、CTaskFlyToPoint、CTaskGenericMoveToPoint、CTaskAnimatedFallback其他

2.7 Motion(动作树)#

所有类继承 CTaskMotionBase(动作状态接口 SupportsMotionState/IsInMotionState、移动速度、备用片段等)game/task/Motion/TaskMotionBase.h:34-140:CTaskMotionPed/CTaskMotionPedLowLod(人形根)、CTaskHumanLocomotion、CTaskMotionAiming(+Transition)、CTaskMotionStrafing、CTaskMotionSwimming/CTaskMotionDiving、CTaskMotionParachuting、CTaskMotionJetpack、CTaskMotionDrunk、CTaskRepositionMove、CTaskCombatRoll、CTaskMotionInTurret,以及动物:CTaskMotionAnimal、四足/鸟/鱼/马/狗/鹿运动任务(TaskQuadLocomotion、TaskBirdLocomotion…)。载具内动作任务 CTaskMotionInVehicle/InAutomobile/OnBicycle 在 Vehicle/TaskInVehicle.h game/task/Vehicle/TaskInVehicle.h:130-1803。§3.4 详述。

2.8 Vehicle(车辆/骑乘/火车)#

类 < 基类职责
CTaskVehicleFSM < CTaskFSMClone @141上下车类任务的公共基(门/座位保留、片段集请求等)game/task/Vehicle/TaskVehicleBase.h:141
CTaskEnterVehicle 及子任务 CTaskEnterVehicleAlign、CTaskOpenVehicleDoorFromOutside、CTaskEnterVehicleSeat、CTaskCloseVehicleDoorFromInside、CTaskInVehicleSeatShuffle上车(§3.3)
CTaskExitVehicle 及 CTaskOpenVehicleDoorFromInside、CTaskExitVehicleSeat、CTaskCloseVehicleDoorFromOutside、CTaskReactToBeingJacked、CTaskReactToBeingAskedToLeaveVehicle下车与被劫 game/task/Vehicle/TaskExitVehicle.h:33-1278
CTaskGoToCarDoorAndStandStill、CTaskMoveGoToVehicleDoor走到车门 game/task/Vehicle/TaskGoToVehicleDoor.h:30-142
CTaskControlVehicle、CTaskCarDrive(Wander)、CTaskPlayerDrive、CTaskInVehicleBasic、CTaskLeaveAnyCar、CTaskComplexCarDriveUsingNavMesh…行人侧驾驶控制(把 VehicleAI 驾驶任务交给载具任务树)game/task/Vehicle/TaskCar.h:41-943
CTaskVehicleMountedWeapon、CTaskVehicleGun、CTaskVehicleProjectile车载武器/车内射击
CTaskMountAnimal/DismountAnimal/RideHorse/MotionRideHorse/PlayerOnHorse/MoveDraftAnimal…骑乘(多数受 ENABLE_HORSE 宏控制,属继承自早期项目的代码)
CTaskRideTrain、CTaskGetOnTrain/OffTrain乘坐火车
CVehicleHullAI、CFollowNearestPathHelper、TaskCarUtils车辆船体避让、跟随最近路径辅助

2.9 Physics(NM 布娃娃)#

CTaskNMControl < CTaskFSMClone @1203 是 NM 行为的控制/起身容器,CTaskNMBehaviour < CTaskFSMClone @458 是各 NM 行为的基类(TaskNM.h)game/task/Physics/TaskNM.h:458、TaskNM.h:1203。派生行为约 25 个:Balance、Brace、Shot(3.5k 行)、HighFall、Explosion、OnFire、Electrocute、Flinch、Relax/RollUpAndRelax、InjuredOnGround、JumpRollFromRoadVehicle、ThroughWindscreen、RiverRapids、Buoyancy、Dangle、Drunk、Sit、SlungOverShoulder、DraggingToSafety、ScriptControl、Simple、Pose、Prototype、FallDown、GenericAttach、BindPose(__DEV)。辅助:CTaskBlendFromNM(从布娃娃混回动画并选择起身集 BlendFromNmData.psc)、CTaskRageRagdoll(非 NM 的 RAGE 布娃娃)、CTaskAnimatedAttach、CGrabHelper、CAnimPoseHelper、ThreatenedHelper。布娃娃任务类型集中在 TASK_NM_RELAX…TASK_RAGDOLL_LAST 区间(见 task-system §8.1)。NM 行为与物理世界的接口见 game-physics-and-ragdoll。

2.10 Weapons(武器)#

类 < 基类职责
CTaskWeapon、CTaskPlayerWeapon武器行为的通用根(行人/玩家)game/task/Weapons/TaskWeapon.h:13
CTaskGun < CTaskFSMClone @26枪械总控:Decide → AimIntro → Aim → Reload/Swap/BulletReaction → Quit game/task/Weapons/Gun/TaskGun.h:35-41
CTaskAimGun → CTaskAimGunOnFoot、CTaskAimGunVehicleDriveBy、CTaskAimGunScripted、CTaskAimGunBlindFire、CTaskMountThrowProjectile具体瞄准实现,由 CTaskAimGunFactory::CreateTask(type, …) 按任务类型 switch 创建 game/task/Weapons/Gun/TaskAimGunFactory.cpp:19-49
CTaskReloadGun、CTaskSwapWeapon、CTaskWeaponBlocked、CTaskAimSweep装弹、换武器、武器被阻挡
CTaskAimAndThrowProjectile、CTaskThrowProjectile、CTaskBomb、CTaskDetonator投掷物与炸弹
CWeaponController(Fixed/Player)、CWeaponTarget < CAITarget射击控制源(AI 固定/玩家输入)与目标描述 game/task/Weapons/WeaponController.h:57-79、game/task/Weapons/WeaponTarget.h:11
ScriptedGunTaskInfo(MetadataMgr)脚本枪械任务的元数据

2.11 Service、Crimes、Animation、Helpers、Debug#

  • Service:CTaskPolice/CTaskPoliceOrderResponse/CTaskPoliceWantedResponse/CTaskArrestPed(2)/CTaskBusted game/task/Service/Police/TaskPolicePatrol.h:50-792;CTaskSwat 及 …OrderResponse/FollowInLine/GoToStagingArea/WantedResponse、CTaskHeliOrderResponse game/task/Service/Swat/TaskSwat.h:28-422;CTaskFirePatrol、CTaskAmbulancePatrol、CTaskArmy、CTaskWitness。这些任务接收派遣系统的命令(CPoliceOrder 等),派遣逻辑见 wanted-crime-dispatch。
  • Crimes:CRandomEventManager(随机事件计时、生成警车追逐等,参数来自元数据)game/task/Crimes/RandomEventManager.h:65-129、CDefaultCrimeInfo/CStealVehicleCrime、CTaskStealVehicle、CTaskPursueCriminal、CTaskReactToPursuit。
  • Animation:CTaskScriptedAnimation(脚本动画多优先级片段)、CTaskSynchronizedScene(同步场景)、CTaskCutScene、CTaskMoVEScripted(脚本驱动的 MoVE 网络)、CTaskClip/CTaskRunClip/CTaskRunNamedClip、CTaskReachArm、调试用 CTaskPreviewMoveNetwork/CTaskTestMoveNetwork(BANK)game/task/Animation/TaskAnims.h:35-1126;动画系统本身见 game-animation-and-ik。
  • Helpers:CTaskConversationHelper : CTaskHelperFSM(环境对话)、CPropManagementHelper(场景/环境道具的生成、附着与释放)、PavementFloodFillHelper game/task/Helpers/TaskConversationHelper.h:9。
  • Debug:仅 CTaskTestClipDistance game/task/Debug/TaskDebug.h:12。

2.12 Scenario(场景)#

见 §3.5。

3. 核心任务的状态机#

3.1 战斗:CTaskThreatResponse → CTaskCombat#

入口:可编辑事件经决策制定器选出 TASK_COMBAT/TASK_THREAT_RESPONSE/TASK_SMART_FLEE 后,由响应工厂创建 CTaskThreatResponse(逃跑时带覆盖)(见事件页 §7.3)。威胁响应在 Analysis 状态中调用 DetermineThreatResponseState:覆盖值 → 规则(ChooseThreatResponseFromRules)→ 战斗行为 → 属性 → 性格 → 兜底,任一环节得出结论即返回 game/task/Combat/TaskThreatResponse.cpp:647-720。战斗分支创建 CTaskCombat(target, 0, flags) TaskThreatResponse.cpp:1256。

状态(CTaskCombat::CombatState)game/task/Combat/TaskNewCombat.h:132-172:Start, Resume, Fire, InCover, MoveToCover, Retreat, Advance, AdvanceFrustrated, ChaseOnFoot, ChargeTarget, Flank, MeleeAttack, MoveWithinAttackWindow, MoveWithinDefensiveArea, PersueInVehicle, WaitingForEntryPointToBeClear, GoToEntryPoint, PullTargetFromVehicle, EnterVehicle, Search, DecideTargetLossResponse, DragInjuredToSafety, Mounted, MeleeToArmed, ReactToImminentExplosion, ReactToExplosion, ReactToBuddyShot, GetOutOfWater, WaitingForCoverExit, AimIntro, TargetUnreachable, ArrestTarget, MoveToTacticalPoint, ThrowSmokeGrenade, Victory, ReturnToInitialPosition, Finish。

状态→子任务(*_OnEnter 中的 SetNewTask):

状态子任务证据
FireCTaskShootAtTargetTaskNewCombat.cpp:3046-3049
InCover / MoveToCoverCTaskCoverTaskNewCombat.cpp:3202-3220、TaskNewCombat.cpp:3659-3704
RetreatCTaskCombatSeekCoverTaskNewCombat.cpp:3816-3822
MeleeAttackCTaskMeleeTaskNewCombat.cpp:3836-3864
AdvanceCTaskAdvanceTaskNewCombat.cpp:3948-3964
ChargeTargetCTaskChargeTaskNewCombat.cpp:4049-4108
ChaseOnFootCTaskComplexControlMovement(移动任务, CTaskCombatAdditionalTask)TaskNewCombat.cpp:4163-4216
FlankCTaskCombatFlankTaskNewCombat.cpp:4348-4350
MoveWithinAttackWindow / MoveWithinDefensiveArea同名移动任务TaskNewCombat.cpp:4376-4388、TaskNewCombat.cpp:4516-4525
PersueInVehicleCTaskVehiclePersuitTaskNewCombat.cpp:4577-4593
PullTargetFromVehicle / EnterVehicleCTaskEnterVehicleTaskNewCombat.cpp:4983-5006、TaskNewCombat.cpp:5135-5181
SearchCTaskSearchTaskNewCombat.cpp:5247-5254
DragInjuredToSafetyCTaskDraggingToSafetyTaskNewCombat.cpp:5333-5348
MountedCTaskCombatMountedTaskNewCombat.cpp:5374-5376
ArrestTargetCTaskArrestPedTaskNewCombat.cpp:5653-5659
MoveToTacticalPointCTaskMoveToTacticalPointTaskNewCombat.cpp:5691-5700
TargetUnreachableCTaskTargetUnreachableTaskNewCombat.cpp:3569-3572
ReturnToInitialPositionCTaskComplexControlMovement(移动, CTaskWeaponBlocked)TaskNewCombat.cpp:5844-5855

决策方式:状态转移主要由 §task-system 2.5 的转移表驱动。条件位 ConditionFlags(如 CF_LosClear、CF_WillUseCover、CF_HasDesiredCover、CF_TargetLocationLost、CF_InVehicle、CF_CanArrestTarget,以及超出 32 位的 CF_CanMoveWithinDefensiveArea 等 64 位宏)由 GenerateTransitionConditionFlags 每次生成 TaskNewCombat.h:44-82、TaskNewCombat.cpp:1542。表的选择依据 CCombatBehaviour::GetCombatType:CT_OnFootArmed、CT_OnFootArmedSeekCoverOnly、CT_OnFootUnarmed、CT_Underwater 对应四张静态表 TaskNewCombat.cpp:671-683、game/Peds/CombatBehaviour.h:104-112。表内容例如“持械 Start 状态:有理想掩体→MoveToCover(权重 9)、视线清楚→Fire(1)、在车内→PersueInVehicle、骑乘→Mounted、可劫车→等待入口、可逮捕→ArrestTarget” TaskNewCombat.cpp:12651-12659;徒手表以近战为主 TaskNewCombat.cpp:12609-12639。各状态 OnUpdate 用 PeriodicallyCheckForStateTransitions(ScaleReactionTime(...)) 周期查表、在子任务结束时用 PickNewStateTransition(..., true)。ScaleReactionTime 忽略传入的 AVERAGE_STATE_SEARCH_TIME = 2.0f,直接按战斗能力返回 {5.0, 2.5, 1.0} 秒(CA_Poor/Average/Professional)TaskNewCombat.cpp:669、TaskNewCombat.cpp:686、TaskNewCombat.cpp:2112-2117、game/Peds/CombatData.psc:12-16。

退出条件:ProcessPreFSM 在目标无法更新/丢失、目标友好、不能攻击、目标已无通缉等情况下 FSM_Quit;若在车内、没有威胁响应父任务且被要求“总是逃跑”,则通过 CEventGivePedTask 给自己一个 CTaskThreatResponse 后退出 TaskNewCombat.cpp:1104-1145。克隆端有单独的 ProcessPreFSM_Clone 与 UpdateClonedFSM TaskNewCombat.cpp:1519、TaskNewCombat.cpp:2427。调优数据 CTaskCombat::Tunables 在 Combat/Metadata.psc game/task/Combat/Metadata.psc:950。

图为简化示意:从 Start 出发的边来自持械/徒手转移表 TaskNewCombat.cpp:12612-12659;InCover/Fire/Search 之间的边为示意性(完整边集需阅读 COnFootArmedTransitions::Init 全部条目 TaskNewCombat.cpp:12651 之后),Finish 来自各处 PickNewStateTransition(State_Finish) TaskNewCombat.cpp:3152。

3.2 导航:CTaskNavBase / CTaskMoveFollowNavMesh#

CTaskNavBase 是所有“请求 pathserver 路线并沿路线移动”的移动任务基类,CTaskMoveFollowNavMesh(TASK_MOVE_FOLLOW_NAVMESH)与 CTaskMoveWander 继承它。路线 CNavMeshRoute 最多 16 个路点(与 pathserver 返回的 MAX_NUM_PATH_POINTS = 16 一致)game/task/Movement/TaskNavBase.h:51-78。

状态 TaskNavBase.h:545-563:Initial, WaitingInVehiclePriorToRequest, RequestPath, MovingWhilstWaitingForPath, StationaryWhilstWaitingForPath, WaitingToLeaveVehicle, WaitingAfterFailureToObtainPath, FollowingPath, SlideToCoord, StoppingAtTarget, WaitingForWaypointActionEvent, WaitingAfterFailedWaypointAction, GetOntoMainNavMesh, AchieveHeading, UsingLadder;CTaskMoveFollowNavMesh 追加 WaitingBetweenSearchAttempts, WaitingBetweenRepeatSearches, SlidingToCoord, GetOntoMainNavMesh, AttemptTeleportToLeader game/task/Movement/TaskNavMesh.h:237-241。

证据与要点:

  • Initial 依据是否需要先在车里等待选择下一状态,并初始化前瞻距离与最大可行坡度 game/task/Movement/TaskNavBase.cpp:1171-1195。
  • RequestPath_OnEnter:首次运行时若站在带动态导航网格的载具上,则把目标转到载具局部空间以便随车移动;然后 RequestPath() TaskNavBase.cpp:1260-1333。RequestPath 用 InitPathRequestPathStruct 填 TRequestPathStruct、按行人 LOD 修改路径标志,再调用 CPathServer::RequestPath;句柄为 PATH_HANDLE_NULL(请求槽满)时走失败等待 TaskNavBase.cpp:3918-3964。
  • RequestPath_OnUpdate 选择“边等边走”(ShouldKeepMovingWhilstWaitingForPath)或原地等待 TaskNavBase.cpp:1334-1372。原地等待时每帧轮询 CPathServer::IsRequestResultReady;就绪后 RetrievePath 通过 LockPathResult 拷出路点与标志(是否以目标结束、是否含水域等),成功进入 FollowingPath,失败交给 OnFailedRoute TaskNavBase.cpp:1545-1620、TaskNavBase.cpp:4008-4060。
  • FollowingPath_OnEnter 创建路线跟随子任务(若路线含攀爬/下落路点则以 CTaskMoveGoToPointAndStandStill 在路点前停下),并预先流送梯子片段 TaskNavBase.cpp:1648-1697、TaskNavBase.cpp:4259-4330。
  • FollowingPath_OnUpdate:按 CalcScanForObstructionsFreq 周期前向扫描障碍,发现障碍则从障碍前方重新请求路线 TaskNavBase.cpp:2198-2250;路线不以目标结束(pathserver 只返回有限路点)且剩余距离 < ms_fDistanceFromRouteEndToRequestNextSection(默认 6 m)时,以“前方一段距离”为起点在跟随中预请求下一段(NB_CalculatingPathOnTheFly)TaskNavBase.cpp:2890-2907、TaskNavBase.cpp:571、TaskNavBase.cpp:3966-4006;到达特殊路点时进入 WaitingForWaypointActionEvent,并向自身添加 CEventClimbLadderOnRoute/CEventClimbNavMeshOnRoute,由事件处理器在主树临时槽插入 CTaskUseLadderOnRoute/CTaskUseClimbOnRoute/CTaskUseDropDownOnRoute TaskNavBase.cpp:3424-3425、TaskNavBase.cpp:3506-3518、game/event/EventMovement.cpp:66-79。
  • 主线程在 pathserver 处理前会用行人的 CNavMeshTrackedObject 刷新尚未开始处理的请求起点(KEEP_UPDATING_PED_START_POSITION),并在请求完成时为等待中的行人置 WaitingForCompletedPathRequest 复位标志以取消 AI 时间切片(见导航页 §4.4)。

3.3 上车:CTaskEnterVehicle#

状态由 ENTER_VEHICLE_STATES(X) 列出 38 个 game/task/Vehicle/TaskEnterVehicle.h:313-356。主线路径(其余为分支:摩托扶车、攀爬/翻越上车顶、等待组长、等待网络同步、布娃娃等):

证据:各 *_OnUpdate 中的 SetTaskState(State_X) 调用(例如 PickDoor_OnUpdate 起于 TaskEnterVehicle.cpp:3009,EnterSeat_OnUpdate 在子任务完成后进入 WaitForPedToLeaveSeat TaskEnterVehicle.cpp:7408-7421,SetPedInSeat_OnUpdate 计算 iDesiredState 后切换 TaskEnterVehicle.cpp:8560-8790)。子任务:GoToDoor→CTaskGoToCarDoorAndStandStill TaskEnterVehicle.cpp:3691;Align→CTaskEnterVehicleAlign TaskEnterVehicle.cpp:10308;OpenDoor→CTaskOpenVehicleDoorFromOutside TaskEnterVehicle.cpp:5852;EnterSeat→CTaskEnterVehicleSeat TaskEnterVehicle.cpp:7279;CloseDoor→CTaskCloseVehicleDoorFromInside TaskEnterVehicle.cpp:8888;ShuffleToSeat→CTaskInVehicleSeatShuffle TaskEnterVehicle.cpp:10683;TryToGrabVehicleDoor→CTaskTryToGrabVehicleDoor TaskEnterVehicle.cpp:10758。

关键机制:

  • 组件保留:门与座位用 CComponentReservation 保留/释放(ReserveSeat/ReserveDoorToOpen/ReserveDoorToClose/UnReserve* 状态),避免多人同时操作同一门/座(类前向声明 TaskEnterVehicle.h:25)。
  • 劫车是跨行人协作:JackPedFromOutside_OnEnter 通过 CEventGivePedTask(PED_TASK_PRIORITY_EVENT_RESPONSE_TEMP, CTaskExitVehicle(...)) 让车内的人执行被拖出动作 TaskEnterVehicle.cpp:6832-6900。
  • 共享 MoVE 网络:主任务持有 m_moveNetworkHelper 并传给开门/入座/关门/换座子任务,使整个上车过程在一个动画网络内连续过渡(见上面子任务构造参数)。
  • 超时保护:入座状态超过 MAX_TIME_TO_GET_IN = 8 s 断言并回退 TaskEnterVehicle.cpp:7381-7395;入座退出时若载具对该玩家上锁则立即给退出任务 TaskEnterVehicle.cpp:7425-7437。
  • 网络:作为 CTaskVehicleFSM(CTaskFSMClone)派生类,克隆端根据 GetStateFromNetwork() 与查询接口推进(如换座时等待远端换座任务进入特定状态)TaskEnterVehicle.cpp:8746-8776。

3.4 动作树:CTaskMotionPed / CTaskHumanLocomotion#

  • 选择:CPed::ComputePrimaryMotionTask 依据模型的 CMotionTaskDataSet(peds.meta 引用,结构见 MotionTaskData.psc)选择:骑乘→CTaskMotionRideHorse;游泳且有水中数据→水中类型;否则用步行数据 game/Peds/Ped.cpp:875-907、game/task/System/MotionTaskData.psc:4-74。人类(PED_ON_FOOT/PED_IN_WATER)一律使用 CTaskMotionPed,低 LOD 时用 CTaskMotionPedLowLod,两者互换时复制片段集与备用片段并以 0.25 s 插入混合 Ped.cpp:909-972。动物类型(鸟、鱼、马、四足…)选择对应运动任务(同一 switch 的其余分支)。
  • CTaskMotionPed 状态 game/task/Motion/Locomotion/TaskMotionPed.h:34-57:Start, OnFoot, Strafing, StrafeToOnFoot, Swimming, SwimToRun, DiveToSwim, Diving, DoNothing, AnimatedVelocity, Crouch, Stealth, InVehicle, Aiming, StandToCrouch, CrouchToStand, ActionMode, Parachuting, Jetpack, Drunk, Dead, Exit(部分受宏控制)。各状态的子任务:OnFoot/ActionMode/Crouch/Stealth→CTaskHumanLocomotion(不同片段集)TaskMotionPed.cpp:1510-1519、TaskMotionPed.cpp:2796、TaskMotionPed.cpp:5884;Strafing→CTaskMotionStrafing TaskMotionPed.cpp:3351;Swimming→CTaskMotionSwimming TaskMotionPed.cpp:3656;Diving→CTaskMotionDiving TaskMotionPed.cpp:4079;InVehicle→CTaskMotionInVehicle TaskMotionPed.cpp:4410;Aiming→CTaskMotionAiming TaskMotionPed.cpp:4768;Parachuting/Jetpack/Drunk→对应动作任务 TaskMotionPed.cpp:5549-5657。
  • MoVE 网络嵌套:CTaskMotionPed 创建 ms_NetworkMotionPed 网络玩家 TaskMotionPed.cpp:712;进入 OnFoot 时向父网络发送 OnFoot 请求,并让子任务网络 SetupDeferredInsert 到父网络的 OnFootNetwork 槽 TaskMotionPed.cpp:1517-1519。也就是说,动作树任务链与 MoVE 网络树一一嵌套,状态切换=网络请求+子网络插入。
  • 输入:期望移动混合比由移动树写入 CPedMotionData,CTaskMotionPed 读取 TaskMotionPed.cpp:830;网络玩家克隆从同步数据读取 TaskMotionPed.cpp:2289。
  • CTaskHumanLocomotion 状态 game/task/Motion/Locomotion/TaskHumanLocomotion.h:98-110:Initial, Idle, IdleTurn, Start, Moving, Turn180, Stop, RepositionMove, FromStrafe, CustomIdle——起步/行进/急转/停步/原地调整,对应 MoVE 运动网络中的子状态(动画参数细节见动画页)。
  • 游戏性参数:动作任务数据集给出步行/跑/冲刺转向速率、跳跃/坠落/滑坡/游泳片段集、四足步态切换时间等 MotionTaskData.psc:27-61;Motion/Metadata.psc 存放动作任务的 Tunables。

3.5 场景系统:CScenarioPointManager / CScenarioInfoManager / CScenarioManager / CTaskUseScenario#

场景(scenario)= 世界中可供行人/载具“使用”的点(坐长椅、抽烟、站岗、加油站洗车…),是城市氛围的主要来源。

  • 数据:
    • CScenarioPointManager 读取场景点清单(CScenarioPointManifest:区域定义、点组、内部名表),每个区域定义 CScenarioPointRegionDef{名称, AABB} 通过 g_fwMetaDataStore.MakeSlotStreamable(name, AABB) 注册为按包围盒流送的元数据槽 game/task/Scenario/ScenarioPointManager.h:43-80、game/task/Scenario/ScenarioPointManager.cpp:788-796;清单为 PSO,注册 SCENARIO_POINTS_PSO_FILE/SCENARIO_POINTS_OVERRIDE_PSO_FILE 两种数据文件挂载(DLC 追加/覆盖)ScenarioPointManager.cpp:156-157、ScenarioPointManager.cpp:1037-1048;-notscenariopointsstreaming 参数可关闭流送 ScenarioPointManager.cpp:50。schema 见 ScenarioPointManager.psc:4-188(区域、簇、点、链节点/边/图、点组)。场景类型与模型集各占 9 位(各最多 512 种)game/task/Scenario/ScenarioPoint.h:36-44。
    • CScenarioInfoManager 从 commoncrc:/data/ai/scenarios.meta 及 DLC 的 SCENARIO_INFO(_OVERRIDE)_FILE 加载场景类型 game/task/Scenario/info/ScenarioInfoManager.cpp:35-80、ScenarioInfoManager.cpp:488;CScenarioInfo 子类决定任务类型:PlayAnims、Wandering、WanderingInRadius、Group、Couple、ControlAmbient、Skiing、SkiLift、MoveBetween、Sniper、Jogging、ParkedVehicle、Vehicle/VehiclePark、Flee、LookAt、DeadPed game/task/Scenario/info/ScenarioInfo.h:338-703;条件系统 CScenarioCondition*(约 70 种:天气、时间、模型、性别、持枪、在车内、电台音乐…)info/ScenarioInfoConditions.h:72-1198;场景中受事件打断时的行为由 CScenarioAction* + CScenarioActionCondition* 数据描述(立即退出、正常退出后响应、懦弱退出、逃跑、转头…)info/ScenarioAction.h:17-251。
    • 条件动画 common:/data/ai/conditionalanims.meta 与环境模型集在 game/ai/ambient 中(见导航页 game/ai 盘点)game/ai/ambient/ConditionalAnimManager.cpp:142-152。
  • 调度:CScenarioManager::Update 每帧更新条件、流送压力、链测试、生成检查缓存、生成历史、链使用信息、簇(SCENARIOCLUSTERING)、实体覆盖、车辆生成器与非区域点空间数组 game/task/Scenario/ScenarioManager.cpp:569-631;刷人入口 GiveScenarioToScenarioPoint/CreateScenarioPed/SetupScenarioAndTask,给停车/行驶车辆分配场景 GiveScenarioToParkedCar/DrivingCar game/task/Scenario/ScenarioManager.h:248-299。脚本可抑制场景退出/吸引/突发退出 ScenarioManager.h:202-213。初始化通过 gameSkeleton 注册 game/Core/game.cpp:2130、game.cpp:2301。
  • 任务工厂:CScenarioManager::CreateTask(point, scenario) 按 CScenarioInfo 子类创建:Flee→CTaskUseScenario(SF_StartInCurrentPosition|SF_SkipEnterClip);WanderingInRadius→CTaskWanderingInRadiusScenario;PlayAnims→CTaskUseScenario(环境用途加 SF_FlagsForAmbientUsage,联机加 SF_AddToHistory);MoveBetween→CTaskMoveBetweenPointsScenario;Jogging/Wandering→CTaskWanderingScenario;DeadPed→CTaskDeadBodyScenario;其他断言 ScenarioManager.cpp:5431-5488;生成的场景任务可再被 CTaskUnalerted 包装以支持场景链与闲逛 ScenarioManager.cpp:5179。
  • CTaskUseScenario 状态 game/task/Scenario/Types/TaskUseScenario.h:298-317:Start → GoToStartPosition(CTaskGoToScenario)→ Enter(入场片段)→ PlayAmbients(CTaskAmbientClips 播放条件动画/道具)→ Exit / PanicExit / NMExit / PanicNMExit / AggroOrCowardIntro/Outro / ScenarioTransition → Finish,外加 WaitingOnExit/StreamWaitClip/WaitForProbes/WaitForPath 等异步等待状态 TaskUseScenario.cpp:3365-3427、TaskUseScenario.cpp:4070-4108。中止后默认从 Start 恢复 TaskUseScenario.h:347。
  • 其他场景模块:ScenarioChaining(场景链图与使用者跟踪)、ScenarioClustering(簇一次性生成)、ScenarioSpawnHistory、ScenarioVehicleManager、ScenarioEntityOverride、ScenarioFinder(CTaskHelperFSM)、ScenarioEditor/ScenarioDebug/ScenarioAnimDebugHelper(BANK 编辑器与调试)。

约束与边界行为#

  • 新任务的“注册清单”:新增一个任务通常要同时改 TaskTypes.h(类型)、TaskClassInfo.cpp(T2N)、可能的 Metadata.psc(Tunables)、若需联网还要在 CQueriableInterface::CreateEmptyTaskInfo/IsTaskSentOverNetwork 中登记(game/Peds/QueriableInterface.cpp:927、QueriableInterface.cpp:1839),若作为事件响应还要在 CEventResponseFactory 或 FindTaskTypeForResponse 中登记。遗漏任一处只会在断言版暴露。
  • 任务大小:所有任务共享一个固定槽大小的池,大型任务(掩体、上车、战斗)要注意 GetLargestTaskSize 的断言阈值(见 task-system §7.1)。
  • 宏控制的“死代码”:骑马(ENABLE_HORSE)、手铐/羁押(ENABLE_TASKS_ARREST_CUFFED)、CnC 模式(CNC_MODE_ENABLED)相关任务是否参与编译取决于宏;本页未逐一核对这些宏在各构建中的取值。

未决问题 / 证据不足#

  • 本页对 Combat、Movement、Vehicle 中约 200 个任务只给出族谱级描述;CTaskCover(约 3 万行)、CTaskMelee、CTaskParachute、CTaskInVehicle 的内部状态机未展开。
  • CTaskCombat 转移表的完整边集未逐条列出(图为简化示意)。
  • 场景刷人与人口系统的配额/距离参数属于 06-peds 页范围,本页未深入。