CAF V2.3.7 开发者指南
Custom Action Framework · 自定义作战框架
适用:CAF V2.3.7 Base ·《七日杀》V3.2 · 作者:猫猫鱼 / Nanami
面向使用 XML 制作武器、技能、Buff 和战斗效果的 MOD 作者。本指南介绍接入方式、关键参数、事件上下文与升级注意事项;完整字段、默认值和别名见配套《CAF V2.3.7 参数字典》。以下能力不要求安装 CAF Affix。
配置入口 · HUB · 开火模块 · 智能武器 · MinEvent · 触发器 · 条件判断 · 伤害反馈 · 旧版迁移 · 资源排错 · 参数字典 · 模板示例
1. 配置入口与文件位置
| 入口 | 写在哪里 | 用途 |
|---|---|---|
| 原版 XML | Config/items.xml、buffs.xml 等 | 定义物品、Buff、效果组、条件与触发时机 |
| CAF MinEventAction | effect_group 中的 triggered_effect | 追加范围伤害、投射物、持续区域及状态动作 |
| HUB 武器模板 | Config/CAF_Templates.xml | 选择开火模块,配置 CR、DR、LASER 与 CONTLASER 字段 |
| 智能武器属性 | 武器 item 根级 property | 虚拟弹匣、能量、锁定、HUD、奔跑瞄准 |
| 能量罐动作 | 消耗品 Action 属性 | 为当前手持武器补充备用能量 |
正确名称是 MinEventAction;“MiniEvent”是旧称,不是 XML 类型名。HUB 参数名不能直接当作 MinEventAction 属性,CAF_SW_ 属性也不能放进 HUB 模板代替物品属性。
客户端、主机与专属服务器须安装一致的 CAF 和相关资源。制作依赖 CAF 的 MOD 时,只携带自己的 XML 与资源,并声明 CAF V2.3.7 前置;不要重复携带另一份 CAF DLL。升级先完整移除旧版 CAF。
2. HUB:模板、弹药路由与叠加
2.1 模板结构
Config/CAF_Templates.xml 是 CAF 专用配置,不使用 XPath。根节点下直接放 template,template 下直接放 property。模板名称应加自己的 MOD 前缀;重名时后加载者覆盖前者。
<template name=”Example_SmartRay”>
<property name=”CAF_FireModuleType” value=”CustomRanged”/>
<property name=”CR_NativeHitscan” value=”true”/>
</template>
</caf_templates>
2.2 武器动作接入
以下片段用于已有远程武器的 Action0;保留该武器原有的射程、射速、弹匣、动画等原版属性。新建 item 时还需完整的原版武器定义。
<property name=”Class” value=”ItemActionFireModuleHub, CustomAoeParticleEffect”/>
<property name=”Magazine_items” value=”ammo9mmBulletBall”/>
<property name=”CAF_Default_Template” value=”Example_SmartRay”/>
<property name=”CAF_Ammo_ammo9mmBulletBall_Template” value=”Example_SmartRay”/>
</property>
路由先查 CAF_Ammo_[当前弹药 item 名]_Template,未设置或为空才查 CAF_Default_Template。专属映射指向不存在的模板时,不会自动改用默认模板。键中的弹药名是 item name,不是显示名或本地化键。路由属性放在武器 Action 中,不能靠模板引用自身,也不能靠配件改写 Snapshot 中同名值来完成模板切换。
2.3 数值公式和覆盖顺序
基础值优先级由低到高:Action 属性 → 所选模板 → 普通配件 → 扩展提供者。普通配件包含功能配件和外观配件;同层多次赋值以后读入的值为准。配件直接属性、针对武器名称的覆盖与通配覆盖都会参与,因此避免用相互冲突的 set 值依赖安装顺序。
支持数值后缀的字段按以下规则求值:
例:基础值 100,_add=10,_mult=1.2,结果为 132。
_mult 是实际乘数,1.2 表示乘以 1.2。只有字典标记支持的键接受 _add 和 _mult;未注册键和不允许的后缀不会产生效果。HUB 当前共有 389 个基础键,其中 216 个允许这两个后缀;弹药路由动态键与 CAF_SW_ 不计入此数。
HUB 数值基础值和后缀可写 @CVar名,从当前持有者取值。缺少基础 CVar 时回退字段默认值;缺少后缀 CVar 时忽略该项。HUB 整数求值后向零截断。布尔字段的 CVar 大于 0 视为 true;不要用数值 CVar 拼资源路径、标签列表或模块名称。
3. 四种开火模块
| 模块值 | 参数前缀 | 主要行为 |
|---|---|---|
| CustomRanged | CR_ | 自定义投射物、枪口 AOE、分裂与命中区域;也可选择原版即时射线 |
| DynamicRanged | DR_ | 在投射物或即时射线上增加动态射速、散布与开火阶段表现 |
| Laser | LASER_ | 瞬时光束、实体穿透、表面反弹、命中载荷与敌人间弹射 |
| ContinuousLaser | LASER_ 与 CONTLASER_ | 按伤害间隔持续执行光束,跟随枪口与视线,停火后清理 |
CR/DR 的自定义投射物与枪口 AOE 可以同时触发;没有这两类载荷时会回退到原版射线。不要通过旧版 CR_Proj_Ammo、DR_Proj_Ammo 或 LASER_Ammo 筛选弹药,改用 HUB 的弹药模板路由。
投射物的 HitRadius、命中 AOE 与自定义 HitBox 是不同控制面;普通投射物穿透、子弹体分裂和激光表面反弹也不能混用字段。ZoneLifetime 不大于 0 时,不创建对应持续区域。
3.1 智能即时射线
| 字段 | 默认值 | 行为 |
|---|---|---|
| CR_NativeHitscan | false | 强制使用原版即时射线,跳过 CR 投射物与枪口 AOE |
| DR_NativeHitscan | false | 同样跳过 DR 自定义载荷,保留动态开火状态 |
这两个布尔开关不支持 _add/_mult。即时射线的射程、伤害和穿透按原版远程武器路径处理,不使用自定义飞行物的速度、重力和命中伤害字段。智能目标有效时修正瞄准方向;没有有效目标时沿原本瞄准方向射击。
3.2 激光弹射
| 字段 | 默认值 | 范围与条件 |
|---|---|---|
| LASER_ConductionCount | 0 | 每条初始射线最多追加 0..64 次弹射命中;0 关闭 |
| LASER_ConductionBranches | 1 | 每个命中节点最多执行 1..8 个后继分叉 |
| LASER_ConductionRadius | 5 | 从每次实际命中点搜索,0..100 米;0 禁用 |
| LASER_ConductionAllowRepeat | false | 允许回到本链先前目标;排除当前起点与同节点重复目标 |
| LASER_ConductionHitAOE | false | 另需开启 LASER_Hit_AOE_Enable,才触发弹射命中的 AOE |
前三项支持 _add/_mult。所有分叉共用次数上限,主束穿透和延迟反弹产生的弹射起点也共享它;主束自身的穿透、反弹不扣该弹射额度。连续激光每个实际伤害 tick 的初始射线重新取得额度,多条初始射线分别计数。
弹射选择存活、可伤害且敌对的实体,并应用激光目标与排除标签;搜索范围不受 HUD 八个候选的限制。子射线不继续穿透或表面反弹,也不自动追加主束的命中预制体、音效、RayHit 事件、投射物或 Zone。弹射 AOE 不创建持续区域。
在已有 Laser 或 ContinuousLaser 模板中加入:
<property name=”LASER_ConductionBranches” value=”2″/>
<property name=”LASER_ConductionRadius” value=”8″/>
<property name=”LASER_ConductionAllowRepeat” value=”true”/>
这组配置最多追加五次命中,每个节点至多分成两路,每跳搜索八米。它不会额外扣除弹药。主束的伤害、光束资源和标签仍由原有 LASER 配置提供。
4. 智能武器:放在物品根级
非空 CAF_SW_VirtualMagCVar 启用虚拟弹匣。锁定使用独立的 CAF_SW_LockEnabled 开关;新版 HUD 与候选扫描还要求武器 Tags 包含 cyber_scope。把此标签追加到原有标签中,不要覆盖武器原有标签集合。
4.1 弹匣与备用能量
| 属性 | 默认值 | 含义 |
|---|---|---|
| CAF_SW_VirtualMagCVar | 空 | 虚拟弹匣 CVar 基名;非空才启用智能资源 |
| CAF_SW_VirtualMagMax | 100 | 容量,至少 1 |
| CAF_SW_EnergyPoolCVar | 空 | 可选备用能量 CVar 基名 |
| CAF_SW_EnergyPoolMax | 1000 | 备用能量上限,至少 0;能量罐补充应显式填写正值 |
| CAF_SW_ChargeTimeFull | 5 | 从空到满所需秒数,至少 0.1 |
| CAF_SW_ChargeDelay | 0.5 | 扣弹后开始充能的等待秒数,至少 0 |
| CAF_SW_ChargeUsesAmmo | true | 配置能量池时,每充一发消耗一单位能量;不是背包实体弹药 |
| CAF_SW_ChargeAudio | 空 | 充能音效资源 |
| CAF_SW_HideVanillaAmmo | false | 显式隐藏原版弹药显示 |
弹匣和能量的持久状态随武器保存,CVar 是显示与兼容投影。系统为基名附加武器实例身份;不要自行给同型号武器共用一个最终状态键,也不要把内部 metadata 名当作 XML 配置。全新实例按容量初始化;旧实例迁移会保留其可读状态。
按住射击期间暂停充能。配置了能量池且 ChargeUsesAmmo 为 true 时,没有至少一单位能量就不能继续补弹;未配置能量池时充能不收费。容量、充能时间和延迟等数值支持 @CVar 以及配件 _add/_mult;布尔项使用物品根级 true/false。
<property name=”CAF_SW_VirtualMagMax” value=”30″/>
<property name=”CAF_SW_EnergyPoolCVar” value=”exampleEnergy”/>
<property name=”CAF_SW_EnergyPoolMax” value=”120″/>
<property name=”CAF_SW_ChargeTimeFull” value=”5″/>
<property name=”CAF_SW_ChargeDelay” value=”0.5″/>
<property name=”CAF_SW_ChargeUsesAmmo” value=”true”/>
4.2 锁定与精确瞄准
| 属性 | 默认值 | 含义与边界 |
|---|---|---|
| CAF_SW_LockEnabled | false | 启用锁定;独立于虚拟弹匣 |
| CAF_SW_LockRingRadius | 150 | 屏幕锁定环半径,至少 1;不是世界米数 |
| CAF_SW_LockAimPart | body | head、body、center;无效值回退 body |
| CAF_SW_LockThroughWalls | false | 候选扫描是否忽略视线阻挡 |
| CAF_SW_LockHologramEnabled | true | 目标全息高亮 |
| CAF_SW_LockHologramMaterial | 空 | 可选全息材质资源 |
| CAF_SW_PrecisionLockTime | 0.8 | 精确锁定时间,0.05..5 秒 |
| CAF_SW_PrecisionMaxTargets | 8 | 会话目标上限,1..8 |
| CAF_SW_PrecisionExitGrace | 0.2 | 丢失目标后的显示宽限,0..1 秒 |
| CAF_SW_TargetSwitchThreshold | 1.25 | 方向切换输入阈值,0.05..20 |
| CAF_SW_TargetSwitchStep | 1.5 | 多步切换输入步长,0.05..20 |
| CAF_SW_TargetSwitchStickyTime | 0.3 | 切换后保持时间,0..1 秒 |
| CAF_SW_PrecisionStaminaResumePercent | 0.2 | 精准锁定恢复所需体力比例,0..1 |
普通锁定使用 LockAimPart;满足精准锁定及体力资格时按精准头部目标处理。显示宽限不会让已丢失的目标继续作为本次开火的有效主目标。穿墙候选不等于光束穿墙,最终碰撞仍由武器模块处理。
4.3 威胁、反馈与曲线重试
| 属性 | 默认值 | 含义与限制 |
|---|---|---|
| CAF_SW_ThreatRadius | 3 | 近身威胁半径,0.5..10 米 |
| CAF_SW_ThreatVerticalTolerance | 2 | 近身威胁高度容差,0..10 米 |
| CAF_SW_CombatFeedbackWindow | 0.1 | 战斗反馈归并窗口,0.05..0.25 秒 |
| CAF_SW_CurveRetryEnabled | false | 启用曲线投射物重试策略 |
| CAF_SW_CurveRetryFailures | 2 | 失败次数阈值,1..8 |
| CAF_SW_CurveRetrySlots | 8 | 重试记录槽数,2..16 |
| CAF_SW_CurveRetryFailureTTL | 1.25 | 失败记录有效期,0.1..5 秒 |
威胁半径与高度只限制近身预警;正在攻击玩家的敌人可通过紧迫威胁判断进入提示。该感知不使用锁定的视线选项。重试参数不是增加射击次数、弹射次数或命中伤害的开关。
4.4 奔跑、瞄准与旧界面兼容
CAF_SW_RunWhileAiming 与 CAF_SW_NoAimMovePenalty 默认 false,分别允许奔跑时维持瞄准、移除瞄准移动惩罚。CAF_SW_RunAndShoot 是同时开启两者的兼容开关;这些选项不要求虚拟弹匣,但仍受体力、游泳、蹲伏、载具等原版状态约束。
新版主 HUD 的视觉系统不由旧 UIShow、UIColor 或 UIEnergyBarPos 参数控制。这些旧项只在备用 XUi 界面生效,完整列表见字典的兼容章节。CAF_SW_UIColorMarkerNormal、CAF_SW_UIColorMarkerLocked 与 CAF_SW_CurveRetryVisualTime 当前没有有效显示或重试用途,不应作为新版界面调节参数。
4.5 能量罐
消耗品动作使用 ItemActionChargeHeldWeapon, CustomAoeParticleEffect。其 Action 属性 CAF_EnergyAmount 默认 500,表示一次补充量;不使用智能武器的 _add/_mult 公式。目标是当前手持、配置了能量池的武器,补充受上限限制。须显式设置武器的 CAF_SW_EnergyPoolMax 为正值,成功写入后才消耗能量罐。
5. MinEventAction 全部入口
| Action 短名称 | 用途与使用前提 |
|---|---|
| AOEDamage | 一次实体范围伤害,可附带持续区域 |
| SpawnZone | 固定或追踪的伤害、推力、Buff、视觉区域 |
| CustomProjectile | 自定义飞行物、追踪、穿透、分裂与命中载荷 |
| AddWeaponAmmo | 从后备实体弹药装入当前弹匣,受容量与储备限制 |
| VPCAddWeaponAmmo | AddWeaponAmmo 的兼容别名 |
| ConsumeWeaponAmmo | 对事件对应的当前手持远程武器额外扣弹,可保留最低弹量 |
| VPCLoseEnemyTargets | 主机侧清除敌人的目标、调查与警戒 |
| ModifyCAFRobotState | 修改当前归属机器人实例状态 |
| ModifyCAFRobotStat | 修改当前机器人实例的属性叠加层 |
| ModifyCAFRobotHealth | 修改存活机器人的生命值 |
| ConsumeOwnerWeaponAmmo | 扣除机器人所有者当前手持远程武器弹药 |
| ModifyCAFRobotAction | 在匹配的机器人动作中修改伤害、推力或 Buff |
| ApplyCAFRobotAura | 对主人及合格盟友施加 Buff、属性层或状态投影 |
| ModifyCAFCombatState | 修改当前武器或武器与目标组合的临时战斗状态 |
| ConsumeCAFWeaponShockScope | 消费匹配的电击作用域,成功后移除目标 buffShocked |
完整写法示例:
action=”AOEDamage, CustomAoeParticleEffect”
damage=”20″ radius=”3″ ignore_self=”true”
target_tags=”zombie”/>
trigger 决定执行时机,action 决定行为。并非每个 CAF 动作都接受原版 target 属性:ConsumeCAFWeaponShockScope 使用原版目标选择,ApplyCAFRobotAura 有自己的目标列表,其余动作按自身规则定位和筛选。不要用一个通用 target 写法套全部动作。
5.1 动态值规则
| 动作家族 | 动态数值来源 |
|---|---|
| AOEDamage | 支持的数值字段只把 |
| SpawnZone、CustomProjectile | 支持 @名称,裸非数字字符串也会被当作 Self 的 CVar 名 |
| 武器弹药动作 | 标为支持的字段读取 Self CVar |
| 机器人动作 | 标为支持的字段读取机器人所有者 CVar |
| ModifyCAFCombatState | 不读 @CVar,使用字面值或 value_field |
中文 CVar 名可用,前提是对应实体上确实存在同名变量。不要把 HUB 的乘数语法套给 MinEvent:例如 AOEDamage 的 damage_mult 为增量,实际先算 damage × (1 + damage_mult)。
5.2 AOE、Zone 和投射物的易错点
AOEDamage 仅在最终即时伤害大于 0 或 add_buff 非空时扫描实体,因此只写 force 不会产生即时推力。其 hit_particle 用于附带 Zone 的视觉,需 zone_lifetime 大于 0,并不是每个命中目标各播放一次。武器面板伤害贡献与固定伤害相加;Zone 分支不肢解。
SpawnZone 的 zone_damage 默认 0,zone_lifetime 默认 10 秒。radius 控制判定,particle_radius 控制表现;有粒子不代表伤害大于 0。Zone 的 TickRate 表示间隔秒数,数值越小频率越高。标签和 ignore_self 仍参与目标排除,正向 target_tags 不会绕过排除规则。
CustomProjectile 的 closest_player、attacker 方向要求 monster_mode=true;普通模式按瞄准或朝向发射。monster_mode 默认 false,怪物扫描半径默认 30,默认仅找玩家;direction_mode 的最近玩家扫描仍以玩家集合为范围。普通动作没有可写的 lockAimPart XML 属性,不要与智能武器 CAF_SW_LockAimPart 混淆。
5.3 弹药与状态动作
AddWeaponAmmo 不是凭空造弹,也不是直接增加智能能量。ConsumeWeaponAmmo 的 count 和 reserve 默认都为 1;buff 仅在扣弹成功后添加,result_cvar 先写 0、成功写 1,以下划线开头的结果名被拒绝。
机器人动作要求主机侧、当前归属实例与匹配的机器人事件上下文。ModifyCAFRobotHealth 不能复活,最终生命至少为 1,且不超过机器人原始物品允许的生命上限。
ModifyCAFCombatState 的 consume 删除整个记录,min/max 仅限制 add,ttl 不大于 0 时采用 30 秒默认值,最多 300 秒。ModifyCAFRobotState 的 consume 则按量扣减并保留记录;不要把这两种状态系统当作同一种计数器。
6. CAF 自定义触发器与上下文
CAF 提供 21 个自定义 trigger。原版 onSelfKilledOther、onSelfPrimaryActionRayHit 等名称仍属于游戏事件;不要因为 CAF 会使用它们就把它们列为 CAF 新增触发器。
6.1 暴击、命中与移动
| Trigger | 条件 |
|---|---|
| onCriticalDamageHit | 启用暴击功能且造成正生命伤害,本次命中为暴击 |
| onNonCriticalDamageHit | 同类伤害命中未暴击 |
| onCAFWeaponHitResolved | 可信的武器直接命中已完成结算 |
| onVPCMoveDistance | 累计移动距离达到阈值 |
| onVPCStill | 连续静止达到时间阈值 |
这一组可从当前武器、配件、成长配置及激活的 Buff 调用。通常 Self 为攻击者或移动玩家,Other 为命中目标;移动事件不提供可任意套用的受击目标。
移动阈值写 value:MoveDistance 默认 0、不触发;Still 默认 1 秒。tick_interval 可用 repeat_interval 或 distance_interval 别名;非正间隔回退阈值。tolerance 默认 0.05,只影响静止判断。
MoveDistance 的 repeat 默认等于 reset;Still 默认等于 !reset_on_move。reset_on_move、reset_on_stance_mismatch 默认 true。movement_tags 与 stance_tags 各按任一标签匹配,required_tags 要求全部匹配。max_stacks 不是有效的移动叠层开关。
6.2 武器战斗与机器人
| Trigger | 事件 |
|---|---|
| onCAFWeaponReloadStarted | 被跟踪的换弹开始 |
| onCAFWeaponReloadCancelled | 已跟踪换弹取消 |
| onCAFWeaponReloadCompleted | 换弹结果已提交 |
| onCAFWeaponAmmoConsumed | 观察到弹药实际消耗 |
| onCAFWeaponKillResolved | 武器直接命中产生可信击杀 |
| onCAFWeaponExplosionResolved | 有武器归属的爆炸聚合结算完成 |
| onCAFWeaponShockResolved | 武器电击完成归因与结算 |
| onCAFOwnedRobotActionStart | 归属机器人的一次动作开始 |
| onCAFOwnedRobotActionResolved | 机器人动作结算完成 |
| onCAFOwnedRobotHitResolved | 机器人对某目标造成正生命伤害 |
| onCAFOwnedRobotKillResolved | 机器人击杀结算完成 |
| onCAFOwnedRobotPulse | 已部署机器人的周期脉冲 |
| onCAFOwnerAttackNearOwnedRobot | 所有者在归属机器人附近攻击 |
| onCAFOwnerKillNearOwnedRobot | 所有者在归属机器人附近击杀 |
这十四项应配置在事件武器及其配件上,不应放到普通 Buff 或 progression 后就期待执行。Self 是武器所有者;机器人事件的 Self 也不是机器人实体。ActionStart、ActionResolved 和主人附近攻击等事件不保证 Other 非空。Pulse 的 Other 是机器人当前目标,Others 则是本条脉冲筛出的盟友。
6.3 武器持有者受击
onCAFWeaponOwnerAttacked 表示持有者遭到有效攻击,最终没有掉血也可能触发;onCAFWeaponOwnerDamaged 还要求实际生命值下降。这两项只接受武器和配件配置。Self 是防守方,Other 与 Instigator 是攻击者,ItemValue 是防守方当前武器。
6.4 机器人 Pulse 与 Aura
Pulse 的 interval 默认 1 秒,限制 0.05..3600;range_mode 默认 weapon,fixed 或 value 模式需显式填写 range。ally_count 默认 -1,表示不设最低盟友数。ally_types 默认 allied_robot,可选 owner、allied_robot/robot、drone、companion;exclude_self 默认 true,排除发起脉冲的机器人。
Pulse 的 range 用于盟友筛选和数量门槛;ApplyCAFRobotAura 的实际作用范围独立使用机器人真实最大射程。它们并非同一个半径。显式 Aura ttl/duration 同时控制 Buff 时长和属性层寿命,未显式设置时 Buff 使用自身默认时长。
Combat 触发器会占用 interval、pulse_interval、range_mode、range、ally_count、ally_types、exclude_self 这些属性名,动作不能在同一个节点再独立使用同名参数。Pulse 配合 Aura 时,exclude_self 通过脉冲上下文传递。其他组合若需要动作自己的 range,应拆成不冲突的触发流程。
7. 条件判断与战斗状态
| Requirement 完整类型 | 专属字段 | 注意事项 |
|---|---|---|
| RequirementCAFCombatContextCompare, CustomAoeParticleEffect | field;require_host_observed 默认 true | 必须显式给比较 operation,读取当前战斗上下文 |
| RequirementCAFCombatState, CustomAoeParticleEffect | key/state_key;scope 默认 weapon;consume 默认 false | target/weapon_target 按武器与目标组合;消费会删除整条匹配记录 |
| RequirementCAFRobotState, CustomAoeParticleEffect | key/state_key;consume;consume_amount | consume_amount 支持所有者 CVar;要求当前机器人实例上下文 |
三者的比较 value 使用数字字面量,不支持继承形式的 value=”@CVar”。operation 可用 EQ、NEQ、LT、LTE、GT、GTE;invert 可反转结果,但状态条件中 consume=true 与 invert=true 组合失败。条件既可放在 effect_group,也可放在 triggered_effect 子节点。
action=”ModifyCAFCombatState, CustomAoeParticleEffect”
key=”exampleHits” operation=”add” value=”1″ max=”10″ ttl=”5″>
<requirement name=”RequirementCAFCombatContextCompare, CustomAoeParticleEffect”
field=”actual_health_damage” operation=”GT” value=”0″/>
</triggered_effect>
value_field 和 ContextCompare 可读取实际生命伤害、weakpoint/fatal、动作或射线序号、机器人状态、距离、速度、角度与位置分量。字段必须由当前事件提供;并不是每个事件都有每个空间值。完整名称见参数字典。
8. 伤害、暴击与联机反馈
HUB 的 CAF_CriticalDamage 默认 1.5,是基础倍率;模块和分支的 CriticalDamage 默认 0,是额外增量。概率通常用 0..1,0.25 表示 25%;倍率 1.2 表示 120%。不要把 MinEvent 的 critical_damage 默认 1.5 当作 HUB 分支的默认增量。
VPCriticalChance、VPCriticalDamage 是 CAF 提供的被动效果名,可用于原版效果组;它们与具体开火模块的字段不是同一种 XML 入口。普通伤害、元素和爆炸飘字由实际伤害反馈产生,不需要为每个伤害颜色编造额外字段。
联机伤害、弹射选敌和表现同步由各自执行侧负责。收到表现的一端不应再手动配置一份重复伤害。安装一致版本后,应分别检查命中结果、远程光束或飞行物、飘字和击杀归属;看到粒子不能证明伤害配置正确。
9. 从 V2.3.0 字典升级
旧参数字典不能只替换封面版本号。以下旧字段不再作为当前模板参数使用:
| 旧字段 | 当前处理方式 |
|---|---|
| CAF_ModuleType | 使用 CAF_FireModuleType |
| LASER_Ammo、CR_Proj_Ammo、DR_Proj_Ammo、CR_TargetAmmo、DR_TargetAmmo、CR_AOE_Ammo、DR_AOE_Ammo | 改为 CAF_Ammo_[ammoName]_Template 路由 |
| LASER_Continuous、CONTLASER_Enable | 用 CAF_FireModuleType 选择 Laser 或 ContinuousLaser |
| LASER_BounceReturnHeight、LASER_RayhitTargetsOnly | 不再填写,当前没有对应行为 |
| CR_AOE_Buff、DR_AOE_Buff | 使用当前字典的 AOE_AddBuff 字段 |
| CR_AOE_HitBlocks、DR_AOE_HitBlocks、CR_OnAim | 不应作为当前模块控制项 |
旧版默认值另有修正:LASER_BounceDelay 为 0.1 秒;CR/DR 的 ChainVelocity 为 15、ChainGravity 为 9.8、ChainScale 为 1。LASER_Rayhit 与 LASER_RayhitCooldown 仅用于瞬时 Laser,ContinuousLaser 使用自己的固定射线事件路径。
10. 资源路径与排错
资源放在自己的 MOD Resources 目录。路径示例为 #@modfolder:Resources/effects.unity3d?bolt.prefab;在 CAF 模板中,短路径按声明模板的 MOD 解析。跨 MOD 引用时显式写 #@modfolder(MOD名称):,名称使用真实 MOD 标识。示例资源名须替换为自己的资源,不要复制本机绝对路径。
排错顺序:确认游戏与 CAF 版本 → 确认 XML 入口和字段拼写 → 确认模板被找到且模块已选择 → 检查 CVar 持有者及默认值 → 检查目标过滤和事件上下文 → 检查资源 → 分别验证单机、房主、远程客户端和专服行为。
建议先做无特效的固定伤害或即时射线,再加入单发投射物、资源、第二种弹药、分裂与持续区域。每个示例片段都需要放进相应完整的物品或 Buff 定义;引用的 Buff、模板及资源必须由你的 MOD 定义或实际存在。
11. 配套参数字典
《CAF V2.3.7 参数字典》统一收录 HUB 的 389 个基础键、四个开火模块、智能武器与兼容界面属性、15 个 MinEventAction 名称、21 个自定义触发器及相关 Requirement。按完整英文标识检索,数值默认与作用条件分别列出。
V2.3.0 的四册 PDF 仅适合历史版本对照;为 V2.3.7 制作新配置时,请使用与本指南同版的字典。
12. HUB 模板与 MinEvent 用法示例
本章提供四种 HUB 模块和十五个 MinEventAction 名称的示例。数字用于演示配置关系,并非平衡推荐;每例可单独采用,不要把所有开火和扣弹效果一次性堆到同一武器上。
HUB 模板写在 Config/CAF_Templates.xml。物品补丁写在 Config/items.xml,用 configs 与 append/set 包装;下方只给 effect_group 的段落,需要放入对应物品的 append 中。两个完整补丁分别示范普通步枪和部署机器人接入方式。
资源说明:example_fx.unity3d、rifle_bolt.prefab、beam.prefab 是本章约定的示例资源名,不是 CAF 自带资源。使用涉及它们的视觉配置时,换成自己 MOD 中真实存在的资源包和预制体;普通即时射线示例不需要这些资源。
12.1 共用接入:把 AK-47 的主射击交给 HUB
保存为自己 MOD 的 Config/items.xml。该补丁针对原版 gunMGT1AK47,保留枪械模型、动画和原版弹药列表,只改主动作类型并增加模板选择。
<set xpath=”/items/item[@name='gunMGT1AK47']/property[@class='Action0']/property[@name='Class']/@value”>ItemActionFireModuleHub, CustomAoeParticleEffect</set>
<append xpath=”/items/item[@name='gunMGT1AK47']/property[@class='Action0']”>
<property name=”CAF_Default_Template” value=”Example_Rifle”/>
</append>
</configs>
工作过程:扣动扳机后,HUB 用当前弹药寻找专属映射;本例没有专属映射,因此所有弹种使用 Example_Rifle。下一节创建该模板。切换为后续模块时,把这里的模板名改为对应名称,不要重复追加多个 CAF_Default_Template。
如果需要按弹种切换,可在同一 Action0 中另加下面两项:普通弹使用步枪,穿甲弹使用激光,其余弹种仍走默认模板。两个目标模板必须同时存在。
<property name=”CAF_Ammo_ammo762mmBulletAP_Template” value=”Example_PulseLaser”/>
12.2 CustomRanged:即时射线步枪及飞行物变体
下面是无需额外特效资源的步枪模板,保存到 CAF_Templates.xml。文件中已有 caf_templates 根节点时,只合并 template 子节点。
<template name=”Example_Rifle”>
<property name=”CAF_FireModuleType” value=”CustomRanged”/>
<property name=”CR_NativeHitscan” value=”true”/>
<property name=”CR_Delay” value=”0.15″/>
<property name=”CR_ConsumeMultiplier” value=”1″/>
</template>
</caf_templates>
解释:CR_NativeHitscan 把本次伤害交给原版即时射线路径;间隔 0.15 秒,消费倍率为 1。原版武器与弹药决定射线伤害、射程和穿透,CR_HitDamage 不会替换此模式的射线伤害。若再配置智能锁定属性,合格的当前目标可用于修正射线方向。
要改成有飞行时间的步枪弹,删除上例 CR_NativeHitscan=true 的属性,改为下面这组内容;其他模板项保留。该变体需要自己的 rifle_bolt 预制体。
<property name=”CR_Count” value=”1″/>
<property name=”CR_Particle” value=”#@modfolder:Resources/example_fx.unity3d?rifle_bolt.prefab”/>
<property name=”CR_Velocity” value=”90″/>
<property name=”CR_Gravity” value=”0″/>
<property name=”CR_ProjectileLifetime” value=”3″/>
<property name=”CR_HitDamage” value=”25″/>
<property name=”CR_Proj_UseWeaponDamage” value=”false”/>
<property name=”CR_HitRadius” value=”0″/>
<property name=”CR_IgnoreSelf” value=”true”/>
这时每次生成一个初速 90、无重力、最长存活 3 秒的弹体,使用 25 点固定基础命中伤害;最终伤害仍受目标防御等结算影响。HitRadius 为 0,不附带命中范围伤害。不要保留 true 开关后期待这些投射物字段生效。
12.3 DynamicRanged:越射越快的步枪
将共用补丁的默认模板改为 Example_SpinRifle。此例仍用原版即时射线,因此无需准备自定义弹体。
<template name=”Example_SpinRifle”>
<property name=”CAF_FireModuleType” value=”DynamicRanged”/>
<property name=”DR_NativeHitscan” value=”true”/>
<property name=”DR_WindUpPerShot” value=”0.1″/>
<property name=”DR_WindDownTime” value=”2″/>
<property name=”DR_MinDelay” value=”0.08″/>
<property name=”DR_MaxDelay” value=”0.4″/>
<property name=”DR_SpreadMultiplierMax” value=”1.5″/>
<property name=”DR_ConsumeMultiplier” value=”1″/>
</template>
</caf_templates>
参数关系:MinDelay 是最高射速对应的短间隔,MaxDelay 是低速时的长间隔,不能把大小关系写反。每次射击推进 0.1 蓄转进度;WindDownTime 控制停火后的降速过程。SpreadMultiplierMax 给满蓄转阶段的散布倍率,1.5 并非额外增加 150%。伤害仍来自原版步枪与所选弹药。
12.4 Laser:脉冲光束与敌人间弹射
选择 Example_PulseLaser,并将 BeamPrefab 换成真实光束资源。这个例子只配置主束伤害和弹射,不附加 AOE 或持续区域。
<template name=”Example_PulseLaser”>
<property name=”CAF_FireModuleType” value=”Laser”/>
<property name=”LASER_Range” value=”50″/>
<property name=”LASER_Delay” value=”0.3″/>
<property name=”LASER_UseWeaponDamage” value=”false”/>
<property name=”LASER_HitDamage” value=”30″/>
<property name=”LASER_TargetTags” value=”zombie”/>
<property name=”LASER_IgnoreSelf” value=”true”/>
<property name=”LASER_HitBlocks” value=”true”/>
<property name=”LASER_BeamPrefab” value=”#@modfolder:Resources/example_fx.unity3d?beam.prefab”/>
<property name=”LASER_ConductionCount” value=”3″/>
<property name=”LASER_ConductionBranches” value=”2″/>
<property name=”LASER_ConductionRadius” value=”6″/>
<property name=”LASER_ConductionAllowRepeat” value=”false”/>
</template>
</caf_templates>
主束射程 50 米、固定基础伤害 30,方块会参与阻挡。命中后每跳搜索六米内的合格敌人,每个节点至多两路,整条初始射线总共最多追加三次弹射命中;不是每一条分叉再得到三次额度。目标不足或被阻挡时,实际弹射可少于上限。
12.5 ContinuousLaser:按住输出的持续光束
将模板选择改为 Example_Beam。沿用已有枪械的原版弹匣和弹药,先验证持续射击,再按需要接入智能能量系统。
<template name=”Example_Beam”>
<property name=”CAF_FireModuleType” value=”ContinuousLaser”/>
<property name=”LASER_Range” value=”35″/>
<property name=”LASER_Delay” value=”0.2″/>
<property name=”LASER_ConsumeMultiplier” value=”1″/>
<property name=”LASER_UseWeaponDamage” value=”false”/>
<property name=”LASER_HitDamage” value=”8″/>
<property name=”LASER_IgnoreSelf” value=”true”/>
<property name=”LASER_HitBlocks” value=”true”/>
<property name=”LASER_BeamPrefab” value=”#@modfolder:Resources/example_fx.unity3d?beam.prefab”/>
<property name=”CONTLASER_OriginFollowMuzzle” value=”true”/>
<property name=”CONTLASER_OriginUseLookDirection” value=”true”/>
<property name=”CONTLASER_StopLoopOnNoAmmo” value=”true”/>
</template>
</caf_templates>
正常连续开火时按 0.2 秒间隔结算,8 是每次基础伤害而非每秒伤害。光束起点跟随枪口,方向按视线更新;停火或弹药不足后结束相应持续表现。不要再加入 CONTLASER_Enable,它不是当前启用入口。
12.6 AOEDamage:每次主动作结束追加范围打击
下面给出完整 items.xml 外壳。它在原版 AK-47 的主动作结束事件上添加一次范围打击;并不要求先把该武器接到 HUB。
<append xpath=”/items/item[@name='gunMGT1AK47']”>
<effect_group name=”Example_AreaStrike”>
<triggered_effect trigger=”onSelfPrimaryActionEnd”
action=”AOEDamage, CustomAoeParticleEffect”
on_aim=”true” aim_distance=”40″
radius=”2.5″ damage=”20″ force=”1″
ignore_self=”true” target_tags=”zombie”/>
</effect_group>
</append>
</configs>
on_aim 使本次范围打击按瞄准落点定位,aim_distance 限制瞄准查询距离,radius 是实体范围而非特效大小。示例没有 particle,所以只演示伤害判定;20 点是基础值。触发次数取决于原版主动作结束事件,不应把它等同于每个命中目标一次。
12.7 SpawnZone:在瞄准点留下五秒伤害区
把此 effect_group 放入自己的武器 item,或放进上一例 append 的内部;先单独采用本例。
<triggered_effect trigger=”onSelfPrimaryActionEnd”
action=”SpawnZone, CustomAoeParticleEffect”
on_aim=”true” aim_distance=”30″ radius=”3″
zone_lifetime=”5″ zone_damage=”8″ zone_tick_rate=”1″
zone_id=”exampleRifleField” zone_can_overlap=”false”
zone_is_ground=”true” ignore_self=”true”
target_tags=”zombie”/>
</effect_group>
持续时间、每跳基础伤害、跳间隔分别为 5 秒、8 点、1 秒。zone_id 给同组区域一个明确标识;false 让同冷却组共享目标 Tick 冷却,不表示所有同名区域都只能生成一个。需要可见法阵时加入自己的 particle 资源;不要因为没填粒子就误以为伤害区不会执行。
12.8 CustomProjectile:追加一枚直线技能弹
普通 MinEvent 投射物使用小写属性;它不是 CR_ 前缀模板。下面同样放在武器 effect_group 所在位置。
<triggered_effect trigger=”onSelfPrimaryActionEnd”
action=”CustomProjectile, CustomAoeParticleEffect”
count=”1″ on_aim=”true” use_muzzle=”true”
particle=”#@modfolder:Resources/example_fx.unity3d?rifle_bolt.prefab”
velocity=”35″ gravity=”0″ projectile_lifetime=”4″
hit_damage=”18″ hit_radius=”0″
ignore_self=”true” target_tags=”zombie”
trigger_hit_event=”false”/>
</effect_group>
弹体从可解析的枪口出发,沿瞄准方向飞行;命中使用固定基础伤害 18。未启用 hit event,避免示例额外触发原版 RayHit 链。它是武器主攻击之外的附加弹,不会自动替代原本那发子弹,也不会自动为该技能另扣一次弹药。
12.9 AddWeaponAmmo:爆头后从后备弹药补一发
适用于仍使用原版实体弹匣的远程武器,将效果组追加到该武器 item。
<triggered_effect trigger=”onSelfPrimaryActionRayHit”
action=”AddWeaponAmmo, CustomAoeParticleEffect”
count=”1″ require_headshot=”true” headshot_compat=”true”/>
</effect_group>
一次符合头部条件的主攻击射线命中,尝试从背包或工具栏的当前弹种中取一发装入弹匣。没有后备弹药或弹匣已满时不增加;这不是无限弹药。多弹丸或穿透武器可能产生多个命中事件,因此不能把一次事件必然当作一整次扣扳机。
12.10 VPCAddWeaponAmmo:兼容名称的补弹写法
保留旧 XML 名称时可使用下面这例;新配置通常直接选择 AddWeaponAmmo。
<triggered_effect trigger=”onSelfPrimaryActionEnd”
action=”VPCAddWeaponAmmo, CustomAoeParticleEffect”
count=”1″ require_headshot=”false”/>
</effect_group>
兼容名执行同一套后备弹药转入弹匣逻辑。本例取消头部条件,在主动作结束时尝试补一发。它与上一例是两种独立示范,不要同时安装后又把两次补弹理解为重复计算错误。
12.11 ConsumeWeaponAmmo:射击前尝试额外扣两发
用于当前手持、事件物品也指向同一实例的远程武器。结果 CVar 留给后续效果判断。
<triggered_effect trigger=”onSelfPrimaryActionStart”
action=”ConsumeWeaponAmmo, CustomAoeParticleEffect”
count=”2″ reserve=”1″ result_cvar=”exampleExtraAmmoPaid”/>
</effect_group>
弹匣至少有三发时,额外消耗两发并保留一发给原版射击,成功结果为 1;不足时结果为 0,不执行这次额外扣弹。这个动作本身不取消原版开火,因此不能仅靠它保证“没交齐三发就绝对不开枪”。它修改实体弹匣,不是智能能量池的扣费接口。
12.12 VPCLoseEnemyTargets:清除附近敌人的追踪
采用原版触发器,避免 Combat 事件占用 range 属性。
<triggered_effect trigger=”onSelfPrimaryActionEnd”
action=”VPCLoseEnemyTargets, CustomAoeParticleEffect”
range=”15″ enemies_only=”true” only_targeting_self=”true”
clear_investigate=”true” clear_alert=”true” clear_revenge=”true”
duration=”3″ detect_scale=”0.25″/>
</effect_group>
主机执行时,清理十五米内正在以使用者为目标的敌人相关追踪状态;玩家随后获得三秒的侦测缩放 0.25。它不是无敌或永久隐身,后续攻击和其他感知仍可能重新建立仇恨。写到普通远程客户端单独执行的事件上,不会绕过此动作的主机权限条件。
12.13 ModifyCAFRobotState:炮塔每五次有效命中尝试修复
这是机器人完整接入外壳。effect_group 必须放在用于部署炮塔的原始物品 gunBotT2JunkTurret 上,而不是主人当时手持的步枪上。
<append xpath=”/items/item[@name='gunBotT2JunkTurret']”>
<effect_group name=”Example_RobotHitCounter”>
<triggered_effect trigger=”onCAFOwnedRobotHitResolved”
action=”ModifyCAFRobotState, CustomAoeParticleEffect”
key=”exampleRobotHits” operation=”add” value=”1″
min=”0″ max=”5″ ttl=”10″/>
<triggered_effect trigger=”onCAFOwnedRobotHitResolved”
action=”ModifyCAFRobotHealth, CustomAoeParticleEffect”
operation=”add” value=”10″>
<requirement name=”RequirementCAFRobotState, CustomAoeParticleEffect”
key=”exampleRobotHits” operation=”GTE” value=”5″
consume=”true” consume_amount=”5″/>
</triggered_effect>
</effect_group>
</append>
</configs>
先累加当前部署实例的命中计数,再检查是否达到五次。条件满足时扣除五点状态并尝试修复十点生命;状态超过十秒未刷新会过期。此处按有效目标命中计数,不能把多目标的一次机器人动作固定视为一次。满血时仍可消费计数,实际回复受生命上限限制。
12.14 ModifyCAFRobotStat:部署期间维持伤害倍率
此组同样追加到炮塔原始物品;使用 Pulse 提前维持属性,影响之后的伤害读取。
<triggered_effect trigger=”onCAFOwnedRobotPulse” interval=”1″
action=”ModifyCAFRobotStat, CustomAoeParticleEffect”
stat=”EntityDamage” operation=”multiply” value=”1.2″
key=”exampleDamageLayer” max_stacks=”1″ refresh=”true” ttl=”1.5″/>
</effect_group>
每秒给当前机器人刷新一个 1.2 倍伤害层,层数上限为一、有效期为 1.5 秒,因此不会每秒无上限相乘。key 标识该属性层,不与另一个增益共用名字;停止刷新后会过期。这里不是永久改写原始物品属性。
12.15 ModifyCAFRobotHealth:机器人击杀后修复
如果只想做简单击杀回复,可以独立使用这组,不必安装前面的计数示例。
<triggered_effect trigger=”onCAFOwnedRobotKillResolved”
action=”ModifyCAFRobotHealth, CustomAoeParticleEffect”
operation=”add” value=”15″ result_cvar=”exampleRobotHealthAfter”/>
</effect_group>
归属机器人确认击杀后,修复的是本次事件里的机器人,结果 CVar 写到主人身上。最终生命不超过原始物品允许上限,也不能用此动作复活死亡机器人;result_cvar 是操作后生命值,不是成功布尔值。
12.16 ConsumeOwnerWeaponAmmo:用主人弹药加强机器人动作
放入部署物品的效果组。使用同一次动作开始事件,先扣主人当前手持远程武器的实体弹药,成功后才允许增伤请求执行。
<triggered_effect trigger=”onCAFOwnedRobotActionStart”
action=”ConsumeOwnerWeaponAmmo, CustomAoeParticleEffect”
count=”1″ reserve=”1″ result_cvar=”exampleRobotBoostPaid”/>
<triggered_effect trigger=”onCAFOwnedRobotActionStart”
action=”ModifyCAFRobotAction, CustomAoeParticleEffect”
entity_damage=”1.5″ entity_damage_operation=”multiply”
first_valid_hit_only=”true”>
<requirement name=”CVarCompare” cvar=”exampleRobotBoostPaid”
operation=”Equals” value=”1″/>
</triggered_effect>
</effect_group>
机器人开始动作时,尝试从主人手持武器扣一发并留下至少一发;成功后,为本次动作的第一个有效命中请求 1.5 倍实体伤害。扣的是主人武器,不是炮塔自身弹药;手持非远程物品或余额不足会失败。它是提前付费,动作最终没有命中也不会返弹。结果键仅用于这段相邻动作,不要让其他效果写入同名 CVar,也不要改成两个各自节流的 Pulse 来假定扣费与收益必然同步。
12.17 ModifyCAFRobotAction:加强机器人当前这一击
此例可放在机器人锤 gunBotT1JunkSledge 的原始物品上,使用动作开始事件。
<triggered_effect trigger=”onCAFOwnedRobotActionStart”
action=”ModifyCAFRobotAction, CustomAoeParticleEffect”
entity_damage=”1.3″ entity_damage_operation=”multiply”
force=”1.5″ force_operation=”multiply”
first_valid_hit_only=”true”/>
</effect_group>
在当前机器人动作的第一个有效命中上使用 1.3 倍实体伤害和 1.5 倍推力请求。它需要动作开始时仍开放的修改上下文;改写成 ActionResolved 属于结算结束以后,不能据此倒改已完成的伤害。first_valid_hit_only 防止同动作多个有效命中全部套用。
12.18 ApplyCAFRobotAura:给附近友方机器人提供增伤
以炮塔 Pulse 驱动,目标只选 allied_robot,不需要另外定义 Buff 就能演示属性光环。
<triggered_effect trigger=”onCAFOwnedRobotPulse” interval=”1″
ally_types=”allied_robot” exclude_self=”true”
action=”ApplyCAFRobotAura, CustomAoeParticleEffect”
target=”allied_robot” robot_stat=”EntityDamage”
robot_operation=”multiply” robot_value=”1.1″
key=”exampleSupportAura” max_stacks=”1″ refresh=”true” ttl=”1.5″/>
</effect_group>
每秒为发起者真实最大射程内的合格友方机器人刷新 1.1 倍伤害层,持续 1.5 秒,排除发起炮塔自身。target 是 Aura 的目标词汇,不是普通 target=”other”。本例没有填写 range,避免误把 Pulse 的盟友筛选半径当成光环半径;没有合格盟友时不会凭空产生收益。
12.19 ModifyCAFCombatState:五次直接命中尝试补三发
追加到普通实体弹匣武器的 item。它使用武器战斗状态,不与前面的机器人实例计数共用存储。
<triggered_effect trigger=”onCAFWeaponHitResolved”
action=”ModifyCAFCombatState, CustomAoeParticleEffect”
key=”exampleWeaponHits” scope=”weapon”
operation=”add” value=”1″ min=”0″ max=”5″ ttl=”4″>
<requirement name=”RequirementCAFCombatContextCompare, CustomAoeParticleEffect”
field=”actual_health_damage” operation=”GT” value=”0″/>
</triggered_effect>
<triggered_effect trigger=”onCAFWeaponHitResolved”
action=”AddWeaponAmmo, CustomAoeParticleEffect” count=”3″>
<requirement name=”RequirementCAFCombatState, CustomAoeParticleEffect”
key=”exampleWeaponHits” scope=”weapon” operation=”GTE” value=”5″
consume=”true”/>
</triggered_effect>
</effect_group>
造成正生命伤害的直接命中增加计数,四秒未刷新就过期;达到五次后消费整条记录,尝试从后备弹药装入三发。缺少后备弹药或弹匣已满时,不保证得到三发,状态条件仍已经消费。scope=weapon 按武器隔离,改为 target 或 weapon_target 则需要同一目标的状态。
12.20 ConsumeCAFWeaponShockScope:消费本武器刚结算的电击
下面的效果组用于原版电击棒 meleeWpnBatonT2StunBaton。必须先按电击棒正常玩法蓄满电,并让一次有效电击被 CAF 归因;它不是给任意武器直接清除任意电击 Buff 的通用动作。
<triggered_effect trigger=”onCAFWeaponShockResolved”
action=”ConsumeCAFWeaponShockScope, CustomAoeParticleEffect”
target=”other”/>
</effect_group>
该事件里 Other 是已归因的受电击目标。当前武器与动作拥有可消费的独占电击作用域、且目标仍有 buffShocked 时,动作消费该记录并移除 Buff。因此安装本例会主动结束相应电击状态;它演示消费语义,不是增加电击持续时间。若电击来源无法独占归因,动作拒绝消费。
12.21 组合前的核对
先选一个 HUB 主模板,再按需要添加少量独立 MinEvent。HUB 的命中载荷与 MinEvent 如果都配置了相同伤害,两边会分别执行。机器人系列必须从对应部署事件进入;普通原版射击事件不能凭空提供机器人上下文。
凡是例子通过 result_cvar 或状态条件串联动作,都按给出的顺序放在同一效果组。结果变量不是跨机器人持久钱包,也不应拿延迟事件复用旧值。资源、武器名、后备弹药和事件条件应逐项对照自己的 MOD,最后分别确认单机、房主与远程客户端的实际表现。










鄂公网安备42011202002543号



好想摸鱼啊...
万般皆是利
接模组定制 +Q 1079703478
好想摸鱼啊...
这种对电脑好啊,他那个代码太烂了
好想摸鱼啊...
这个逼装的我给82分,剩下的用666的方式打给你!
好想摸鱼啊...
好 很好
品赛博烧鸡,做电子魅魔