Targeting
查看 Markdown人物与载具目标扫描、中键锁定、六槽动作轮盘及宿主生命周期。
用公共值类型扫描人物与载具,锁定目标后通过六槽轮盘提交动作;宿主负责配置与生命周期,游戏实体操作留在 XBase 后端。
入口为 include/XBase/Targeting.h,命名空间 XBase::Targeting,已由 XBase.h 聚合。扫描与交互实现在 src/controllers/Targeting.cpp 和对应三作的私有 Targeting 后端。
Targeting 不是 BulletAssist 的瞄准/子弹追踪配置,也不等于对玩家当前车辆调用 Vehicle::。它作用于扫描列表中的非玩家人物及非玩家当前载具。死亡人物和血量为零的车辆不进入正常候选列表。
当前没有 Core::Domain::Targeting,也没有独立 FeatureCapability::Targeting。 Core 不分发该模块;宿主单独驱动它,用 GetActions(kind) 的 supported 判断具体动作。不要把后台菜单编辑、存档持久化或 i18n 词条管理放进后端。
std::vector<ActionInfo> GetActions(Kind kind);
void SetConfig(const Config& config);
Config GetConfig();
void SetLabels(const Labels& labels);
void Process();
void Draw();
void Shutdown();
void NotifyGameInit();
std::vector<Target> GetTargets();
bool Select(Kind kind, EntityId id);
void ClearSelection();
bool GetSelected(Target& target);
bool SetSelectedHealth(float health);
bool DeleteSelected();Kind 为 Ped 或 Vehicle。Target 包含 kind/id/modelId/position/distance/health/selected;id 是不透明 EntityId,不要还原为游戏指针或跨存档保存。GetTargets() 返回扫描快照,GetSelected() 返回最近的选择快照,不保证对象在下一帧仍然存在。
Select() 只接受当前列表中存在的非零 ID,失败返回假。SetConfig() 会清除当前选择及交互输入状态,宿主只在配置变化时提交,不能每帧提交后又期待锁定保持。
| Config 字段 | 默认值 | 边界 |
|---|---|---|
enabled | false | 总开关 |
drawLinks | true | 绘制屏幕中心到目标的链路 |
includePeds / includeVehicles | true | 扫描种类 |
mouseSelect | true | 准星候选、中键锁定与轮盘交互 |
radius | 80 | 世界扫描半径,约束到 5–250,非有限数退回 80 |
hitRadius | 160 | 准星命中半径,约束到 40–400,后端按显示高度相对 1080 缩放 |
maxTargets | 16 | 快照数量限制,约束到 1–64 |
pedMenu / vehicleMenu | 六槽默认菜单 | Menu = std::array<Binding, SlotCount>,SlotCount = 6 |
默认人物槽位顺序为 Restore, Armour, Disarm, Kill, Bring, Teleport;载具为 Restore, Upright, Unlock, Ignite, Bring, Teleport。第一槽位于轮盘顶部,其余顺时针排列。
struct Binding {
Action action = Action::None;
float value = 0.0f;
int secondary = 0;
int tertiary = 0;
int quaternary = 0;
bool enabled = true;
};| 参数类型 | Binding 编码 |
|---|---|
None | 无参数;空槽使用 Action::None |
Number | value 为数值,按 ActionInfo 的范围约束 |
Toggle | enabled 为开关意图,不是槽位启用标志;false 可执行关闭防护/引擎等动作 |
Colors | value/secondary/tertiary/quaternary 为四色编号,SA 使用四个,VC/III 只使用前两个 |
Weapon | value 为武器类型,secondary 为弹药数,约束到 0–99999 |
Door | value 为门索引,0–5 |
Seat | value 为座位索引,0 是驾驶位,1 起是乘客位;实际可用座位还需实体校验 |
ActionInfo 提供 action/labelKey/parameter/minimum/maximum/defaultValue/supported。GetActions() 返回的条目不保证均可用,必须检查 supported。SetConfig() 会把不存在、类型不匹配或不支持的动作改为空槽;有限 value 按动作范围约束,非有限值改为动作默认值。Binding{action} 的值为零,不会自动套用 defaultValue,编辑器新建参数动作时应主动复制默认值。
| 目标/分组 | Action |
|---|---|
| 两种目标 | None, Restore, Health, MaxHealth, Bring, Teleport, Stop, Freeze, Delete, Visible, Proofs, BulletProof, FireProof, ExplosionProof, CollisionProof, MeleeProof |
| 人物 | Kill, Armour, Disarm, Weapon |
| 载具基础 | Ignite, Upright, Unlock, Lock, Colors, Explode, Engine, Lights, Speed, WarpToSeat, EnterVehicle, Heavy, Watertight |
| 载具车门 | OpenDoor,由 VehicleDoors 门控,当前 VC/III 不支持 |
| SA 专属标志/车门 | PopDoor, SkidMarks, Particles, DriverTargetable, HeatSeekingTargetable, PetrolTankWeakPoint, Siren, TakeLessDamage |
| 载具改装 | Paintjob, AddUpgrade, RemoveUpgrade, RemoveAllUpgrades,按 VehiclePaintjob/VehicleUpgrades 门控,当前仅 SA |
全部动作先受 PedBasic 或 VehicleBasic 门控;Delete 还查询对应删除能力,Weapon 查询 WeaponGive,Colors 查询 VehicleColors。当前三作均有目标基础后端,具体动作以运行时返回表为准,不因后端存在一个实现分支而绕过能力门控。
主要数值范围:Health 为 0–100000、MaxHealth 为 1–100000、Armour 为 0–100000、Speed 为 0–300、Paintjob 为 -1–2、Upgrade 模型为 1000–1193;武器类型上限 SA 为 43、VC 为 33、III 为 12。范围合法不代表模型可用或改装适配该车型,动作仍可能失败。
| 动作/调用 | 实际语义 |
|---|---|
人物 Restore | 恢复到目标的登记血量上限,未登记时为 100,不复活已排除的死亡人物 |
载具 Restore | 修复车辆并恢复血量,登记上限存在时使用该上限 |
Ignite / Explode | 前者取消火焰防护并把车辆血量设为 249 以触发燃烧;后者调用车辆爆炸操作,不是同一个动作 |
MaxHealth | 设置当前血量并登记持续上限;SA 人物还写原生最大血量字段,不是单纯 UI 显示值 |
Bring | 把目标拉到玩家旁边;人物有载具关联时搬动其载具,并清零移动/转动速度 |
Teleport | 玩家传到目标旁边;玩家仍有载具关联时返回失败,不自动携带玩家车辆 |
EnterVehicle | 进入驾驶位;已有驾驶员先移到车旁,玩家在别的车上先移出,再跨帧重试 |
WarpToSeat | 进入指定空座位,不替换已有驾驶员或乘客;超过该车辆实际座位数失败 |
轮盘 Action::Delete | 执行脚本实体删除 |
DeleteSelected() | 当前三作后端将选中实体血量设为零,成功后清选择;不是轮盘 Delete 的实体删除操作 |
换车等待最多处理 60 帧,超时或目标失效即丢弃请求。上车成功后更新游戏相机目标并跳切恢复,XBase 自定义 Camera 活跃时不覆盖它;接受了轮盘命令不代表最终已上车。
MaxHealth 的上限在 Process() 中持续校验,实体失效时移除记录;仅将 enabled 设为 false 不清除已登记上限,效果处理仍继续。NotifyGameInit() / Shutdown() 清空上限记录与待处理换车请求,不恢复已经写入的实体血量、SA 最大血量、冻结、防护等动作结果。不能把 Shutdown 当作全部动作撤销。
游戏线程的 Process() 扫描对象、刷新锁定目标、验证待处理轮盘命令并执行实体动作;Hooks 回调里的 Draw() 负责绘制、选择和登记轮盘意图,不在该绘制路径直接改实体。SetSelectedHealth() / DeleteSelected() 则是立即操作接口,宿主应从游戏逻辑安全点调用,不能因为内部有快照锁就从任意线程修改实体。
准星附近目标由中键边沿锁定,轮盘使用相对鼠标输入;普通扫描不接管全局鼠标与镜头,锁定轮盘时后端消费操作指针增量。右键或 Escape 取消,菜单可见、键盘输入被捕获或窗口不在前台时停止交互。Targeting 按状态管理 Hooks 中键抑制,停用/卸载时释放。
锁定目标不会因距离排序或 maxTargets 截断被静默换成另一对象;离开扫描半径后仍尝试通过对象池刷新。轮盘执行前再次检查种类、ID、模型与当前选择,过期输入直接丢弃。此校验不是允许永久缓存 EntityId 的保证。
Labels::actions 按 Action 枚举索引存放动作文本,Restore 分别使用 heal/restore 字段,人物/载具类型使用 ped/vehicle。宿主使用 ActionInfo::labelKey 翻译并调用 SetLabels(),语言切换时重新提交标签;模块不自动读取宿主语言包。
以下函数应接入宿主已有的游戏初始化、处理与卸载回调,不再创建第二套 Host 事件循环:
#include <XBase/XBase.h>
static XBase::Hooks::DrawCallbackId g_target_draw;
void EnableTargeting() {
XBase::Targeting::Config config;
config.enabled = true;
XBase::Targeting::SetConfig(config);
g_target_draw = XBase::Hooks::RegisterDrawCallback([] {
XBase::Targeting::Draw();
});
}
void ProcessTargeting() {
if (!XBase::Core::IsWorldReady()) return;
XBase::Targeting::Process();
}
void ResetTargeting() {
XBase::Targeting::NotifyGameInit();
}
void StopTargeting() {
if (g_target_draw) {
XBase::Hooks::UnregisterDrawCallback(g_target_draw);
g_target_draw = {};
}
XBase::Targeting::Shutdown();
}EnableTargeting() 只执行一次,Hooks 初始化仍归宿主。默认 enabled = false,忘记 SetConfig 不会显示链路。自定义菜单只修改 GetConfig() 返回副本中的六槽数组,再调用 SetConfig;没有公共 ExecuteBinding(),不要引用私有 backend 来执行动作。
评论