项目空间

项目笔记N-207

状态都有什么

更新
内容块
76
阅读
约 5 分钟
路径
项目笔记 / CS / 2026.7.7 / AI 模组

5.1 AIState:粗粒度状态机

AIState 是 Bot 当前所处的粗状态:

代码块C++
enum class AIState {
    Freeze,
    PlanRoute,
    MoveToObjective,
    EngageEnemy,
    TakeCover,
    PlantBomb,
    DefuseBomb,
    PostPlantHold,
    Retake,
    Rotate,
    Dead
};

5.2 BotRole:队内职责

BotRole 描述 Bot 在队伍里的长期角色:

代码块C++
enum class BotRole {
    Entry,
    Support,
    Lurker,
    Sniper,
    Objective
};
  • •Entry:突破手,先拉出去,占空间,吃第一波交火。(一突)
  • •Support:补枪位,跟 Entry,必要时丢闪。(二突)
  • •Lurker:绕后/侧翼,制造牵制。(先锋)
  • •Sniper:长枪线架点。(哨位)
  • •Objective:目标位,优先带包、下包、拆包。(哨位,烟位)

5.3 BotIntent:当前意图

BotIntent 是当前帧或当前短时间内 Bot 具体想做的事:

代码块C++
enum class BotIntent {
    None,
    TakeSpace,抢占空间 / 占位
    TradeEntry,补枪突入 / 协同进入
    Lurk,潜伏 / 阴人
    HoldAngle,架点 / 卡住角度
    RotateByIntel,根据情报转点
    Engage,交战 / 接敌
    TakeCover,寻找掩体 / 躲避
    Plant,安放炸弹
    Defuse, 拆弹
    PostPlantHold, 安放后防守 / 守包
    SearchLastKnown,搜索最后已知位置
    Repath,重新寻路
    IdleScan 空闲扫描 / 闲置观察
};

5.4 ObjectiveType:目标优先级分类

ObjectiveType 比 BotIntent 更偏“任务重要性”:

代码块C++
enum class ObjectiveType {
    None,
    Combat,
    PlantBomb,
    RecoverBomb,
    DefuseBomb,
    DefendBomb,
    TakeSpace,
    Rotate,
    HoldAngle,
    Trade,
    Lurk,
    TakeCover,
    SearchLastKnown,
    ExitSpawn
};

objectivePriority() 给不同任务打优先级:

代码块C++
DefuseBomb = 120
PlantBomb = 110
RecoverBomb = 105
DefendBomb = 95
Trade = 88
Combat = 82
TakeCover = 80
ExitSpawn = 50
TakeSpace = 45
...

5.5 BotObjective:当前选中的黑板目标

BotObjective 是本项目 AI 最接近“行为树黑板任务”的结构:

代码块C++
struct BotObjective {
    ObjectiveType type;
    BotIntent intent;
    AIState state;
    Vec3 moveTarget;
    Vec3 aimTarget;
    Vec3 fireTarget;
    int targetNode;
    float score;
    float lockTimer;
    bool interruptible;
    const char* source;
};

字段解释:

  • •type:任务类型,例如 PlantBomb。
  • •intent:执行意图,例如 Plant。
  • •state:粗状态,例如 AIState::PlantBomb。
  • •moveTarget:移动目标位置。
  • •aimTarget:预瞄目标位置。
  • •fireTarget:开火目标位置。
  • •targetNode:导航图目标节点。
  • •score:该目标得分或权重。
  • •lockTimer:短时间锁定,防止每帧来回切换。
  • •interruptible:是否允许低优先级行为打断。
  • •source:谁设置了这个目标,用于调试,例如 "VisibleEnemy"、"CarrierAtSite"。

5.6 Bot:每个 Bot 的完整状态

Bot 是 AI 的主体,里面混合了位置、生命、武器、路线、记忆、战斗状态和当前目标:

代码块C++
struct Bot {
Team team;                     // 队伍(所属阵营)
BotRole role;                  // Bot角色(如突破、支援、狙击等)
BotIntent intent;              // Bot意图(当前选中的行为意图)
BotObjective objective;        // Bot目标(具体的任务目标,如安包点、拆弹点等)
Vec3 pos;                      // 位置(三维坐标)
float yaw;                     // 偏航角(朝向)
int health;                    // 生命值
bool alive;                    // 是否存活
bool hasBomb;                  // 是否携带炸弹
WeaponState gun;               // 武器状态(当前武器、弹夹、备弹等)
AIState state;                 // AI状态(行为子状态或阶段)
std::vector<int> route;        // 路径点列表(导航节点索引序列)
int routeIndex;                // 当前路径点索引(正在前往的目标节点位置)
int targetEnemy;               // 目标敌人实体ID
DuelState duel;                // 对决状态(与敌人交火时的子状态)
float reaction;                // 反应时间(用于模拟人类反应延迟)
float plantProgress;           // 安放炸弹进度(0~1)
float defuseProgress;          // 拆弹进度(0~1)
float memoryAge;               // 记忆年龄(上次看到/听到敌人的时间衰减)
float heardAge;                // 听觉信息年龄(上次听到声音的时间)
float stuckTimer;              // 卡住计时器(用于检测是否被障碍物卡住)
Vec3 lastKnownEnemy;           // 最后已知敌人位置
Vec3 objectivePos;             // 目标位置(与objective对应的具体坐标)
Vec3 moveTarget;               // 移动目标点(当前导航目标)
Vec3 aimTarget;                // 瞄准目标点(准星指向)
Vec3 fireTarget;               // 开火目标点(射击瞄准点)
...
};

从行为树角度看,Bot 就是单个 AI 的 Blackboard。

5.7 SharedIntel:团队共享情报

SharedIntel 存团队级信息:

代码块C++
struct SharedIntel {
bool enemySpotted;          // 是否发现敌人(至少一名可见敌人)
Vec3 lastEnemyPos;          // 最后已知敌人位置(最后被看到或听到的位置)
float age;                  // 信息年龄(该条情报的时效,单位秒)
bool bombKnown;             // 是否已知炸弹位置(已探明或队友报告)
Vec3 bombPos;               // 炸弹位置(已安放或掉落时的坐标)
bool bombSiteA;             // 是否为A包点(标识炸弹所在包点是A还是B)
int aliveCT;                // CT方存活人数(警家剩余人数)
int aliveT;                 // T方存活人数(匪家剩余人数)
int pressureA;              // A区压力值(敌人活动强度或进攻权重,数值越高威胁越大)
int pressureB;              // B区压力值(同上,B区)
Vec3 ctCentroid;            // CT方重心位置(所有存活CT的平均坐标)
Vec3 tCentroid;             // T方重心位置(所有存活T的平均坐标)
};

5.8 RoundPlan:T 方回合战术

RoundPlan 是 T 方本回合计划:

代码块C++
struct RoundPlan {
TeamTactic tactic;          // 当前团队战术(如推进、防守、转点等)
bool targetSiteA;           // 是否以A包点为目标(true为A,false为B)
int rallyNode;              // 集结节点(队员集合汇合的导航节点)
int mainGoalNode;           // 主要目标节点(主攻/主防的路径节点)
int supportGoalNode;        // 支援目标节点(辅助位置的路径节点)
int sniperNode;             // 狙击手位置节点(负责架狙的站位)
int flankNode;              // 侧翼节点(绕后或侧翼包抄的位置)
float tacticAge;            // 战术存活时间(当前战术方案已持续的时间,秒)
float reevaluateTimer;      // 重新评估计时器(距离下次重新评估战术的剩余时间)
bool flashIssued;           // 是否已发出闪光弹指令(或已部署闪光弹支援)
};

它由 buildRoundPlan() 创建。tactic 可能是:

  • •Default
  • •RushA
  • •RushB
  • •FakeRotate
  • •EcoPick
  • •Auto 解析后的具体战术

5.9 TeamTacticalPlan:每帧动态团队计划

TeamTacticalPlan 是比 RoundPlan 更实时的计划:

代码块C++
struct TeamTacticalPlan {
    TeamPlanIntent tIntent;      // T方战术意图
    TeamPlanIntent ctIntent;     // CT方战术意图
    int tPrimaryNode;            // T方主要目标节点
    int tSecondaryNode;          // T方次要目标节点
    int ctPrimaryNode;           // CT方主要目标节点
    int ctSecondaryNode;         // CT方次要目标节点
    int defuserIndex;            // 拆弹者索引(负责拆弹的Bot编号)
    float tPressureA;            // T方在A点的压力值
    float tPressureB;            // T方在B点的压力值
    float ctPressureA;           // CT方在A点的压力值
    float ctPressureB;           // CT方在B点的压力值
};

5.10 Map / NavNode:导航图

AI 不是自由寻路,而是在手写导航图上走:

代码块C++
struct NavNode {
    Vec3 pos;
    std::vector<int> links;
    bool siteA;
    bool siteB;
    bool cover;
    bool valid;
    std::string label;
};

struct Map {
    std::vector<Box> boxes;
    std::vector<NavNode> nodes;
    std::vector<NavEdgeInfo> edgeInfo;
    Vec3 ctSpawn;
    Vec3 tSpawn;
    Vec3 siteA;
    Vec3 siteB;
    bool authoredNavLinks;
};