CD Code Digest Hub /CS:GO

投掷物与 C4

11 分钟阅读 5 个章节 2 张图

投掷物与 C4 都是“武器 → 世界实体”的两段式设计:玩家手中的武器负责输入与动画,触发后生成独立的投射物/已放置实体,由后者在世界中计时、碰撞、爆炸,并通过游戏事件通知规则、Bot 与客户端。

相关页面:武器与射击 · 规则与回合 · Bot · 实体系统

相关源码文件#

  • 投掷:game/shared/cstrike15/weapon_basecsgrenade.cpp、game/shared/cstrike15/basecsgrenade_projectile.cpp、*_projectile.cpp、weapon_*grenade.cpp、weapon_molotov.cpp、weapon_decoy.cpp
  • 火焰:game/server/cstrike15/Effects/inferno.cpp
  • C4:game/shared/cstrike15/weapon_c4.cpp、game/server/cstrike15/func_bomb_target.cpp、game/server/cstrike15/func_no_defuse.cpp

1. 投掷物通用流程#

  • 主攻拉环;副攻在未拉环时把投掷力度设为 0(低抛),力度随按键逐步逼近目标值:game/shared/cstrike15/weapon_basecsgrenade.cpp:331。ThrowGrenade 以“基础速度 × 0.9(钳制到 15–750)”为初速,再按投掷力度在副攻衰减系数 0.3 与 1 之间插值(GRENADE_UNDERHAND_FEATURE_ENABLED 在 CS:GO 中已定义):game/shared/cstrike15/weapon_basecsgrenade.cpp:586-594、game/shared/cstrike15/weapon_basecsgrenade.cpp:82、game/shared/cstrike15/cs_shareddefs.h:48;最终速度叠加玩家自身速度的 1.25 倍:game/shared/cstrike15/weapon_basecsgrenade.cpp:614;随后调用 EmitGrenade 并触发 grenade_thrown 事件:game/shared/cstrike15/weapon_basecsgrenade.cpp:196-230、game/shared/cstrike15/weapon_basecsgrenade.cpp:555-650。
  • 基类的 EmitGrenade 只做断言,要求子类实现:game/shared/cstrike15/weapon_basecsgrenade.cpp:693-695;各子类分别创建对应投射物,例如 HE(带 GRENADE_TIMER)、烟雾、燃烧瓶/燃烧弹(共用 CMolotovProjectile):game/shared/cstrike15/weapon_hegrenade.cpp:49-51、game/shared/cstrike15/weapon_smokegrenade.cpp:45-47、game/shared/cstrike15/weapon_molotov.cpp:42-48、game/shared/cstrike15/weapon_molotov.cpp:189-195。
  • 投射物基类处理反弹碰撞、引爆计时、爆炸:game/shared/cstrike15/basecsgrenade_projectile.cpp:330-347、game/shared/cstrike15/basecsgrenade_projectile.cpp:651-654。
投掷物引爆行为证据
HE 手雷触发 hegrenade_detonate 后走基类爆炸(范围伤害)game/shared/cstrike15/hegrenade_projectile.cpp:91-109
闪光弹触发 flashbang_detonate,按 sv_flashbang_strength 调用 RadiusFlash 并统计命中敌我人数,然后移除game/shared/cstrike15/flashbang_projectile.cpp:409-438
烟雾弹通知 Bot 烟雾半径,触发 smokegrenade_detonate,记录统计,进入淡出 Thinkgame/shared/cstrike15/smokegrenade_projectile.cpp:175-233
燃烧瓶/燃烧弹触发 molotov_detonate;落在世界上则就地起火,在空中时向下追踪 128 单位找地面,太高只播放音效;起火时创建 inferno 实体game/shared/cstrike15/molotov_projectile.cpp:314-404
诱饵弹自定义引爆 Thinkgame/shared/cstrike15/decoy_projectile.cpp:225-259
侦察手雷自定义引爆game/shared/cstrike15/sensorgrenade_projectile.cpp:167

烟火互动:CInferno 监听 smokegrenade_detonate,熄灭烟雾范围内的火焰,全部熄灭时记录统计:game/server/cstrike15/Effects/inferno.cpp:228-260、game/server/cstrike15/Effects/inferno.cpp:686;火焰蔓延时也会判断新火点是否位于烟雾中:game/server/cstrike15/Effects/inferno.cpp:361、game/server/cstrike15/Effects/inferno.cpp:519。燃烧瓶在烟雾中生成时会检查 WasCreatedInSmoke:game/shared/cstrike15/molotov_projectile.cpp:404。

2. C4:下包#

CC4::PrimaryAttack:

  1. 判断是否站在地面上;站在玩家、可推动物体、可破坏物体或可被推开的物体上视为不在地面:game/shared/cstrike15/weapon_c4.cpp:1542-1556。
  2. 未开始布置且位于炸弹区并着地时开始布置,设置 m_fArmedTime = now + WEAPON_C4_ARM_TIME,触发 bomb_beginplant:game/shared/cstrike15/weapon_c4.cpp:1570-1600。
  3. 布置中离开炸弹区或离地则取消:game/shared/cstrike15/weapon_c4.cpp:1656-1660;到达布置时间后放置:game/shared/cstrike15/weapon_c4.cpp:1691。
  4. 放置成功:发放 BOMB_PLANTED 个人奖励、触发 bomb_planted、规则对象标记 m_bBombPlanted、移除手中 C4,并调用 CheckWinConditions:game/shared/cstrike15/weapon_c4.cpp:1794-1839。

已放置的 CPlantedC4 计时长度取自 mp_c4timer,爆炸时刻 m_flC4Blow = now + timer:game/shared/cstrike15/weapon_c4.cpp:152-154。

3. C4:计时、拆除与爆炸#

  • C4Think 每 0.05 秒运行一次:同步拆弹者句柄与模型部件,触发 bomb_beep(供 Bot 听到),临近爆炸时让附近玩家喊话:game/shared/cstrike15/weapon_c4.cpp:351-420。
  • 到达 m_flC4Blow 时 Explode 并触发 bomb_exploded:game/shared/cstrike15/weapon_c4.cpp:453-497。Explode 设置 m_bTargetBombed,安装 MVP 计算钩子后调用 CheckWinConditions,然后计算爆炸伤害:game/shared/cstrike15/weapon_c4.cpp:795-870。
  • 拆除:Use 要求炸弹仍在计时、未到爆炸时间、未禁用拆弹;使用者必须是 CT 且不在禁拆区;真人玩家还必须对炸弹附近若干点之一有视线(防止隔层拆弹):game/shared/cstrike15/weapon_c4.cpp:948-1001。已有他人在拆时提示并拒绝:game/shared/cstrike15/weapon_c4.cpp:1003-1013。开始拆弹时触发 bomb_begindefuse,拆弹时间有拆弹器 5 秒、否则 10 秒,并触发地图输出 OnBombBeginDefuse:game/shared/cstrike15/weapon_c4.cpp:1021-1070。
  • 拆弹完成时触发 bomb_defused、给拆弹者 BOMB_DEFUSED 奖励、设置 m_bBombDefused 并调用 CheckWinConditions:game/shared/cstrike15/weapon_c4.cpp:521-748。

规则对象据此判定回合结果(见 规则与回合):爆炸 → Target_Bombed;拆除 → Bomb_Defused;C4 处于激活状态时 CT 不能因 T 团灭获胜。

约束与边界#

  • WEAPON_C4_ARM_TIME、mp_c4timer 默认值、爆炸半径等数值未在本页列出;它们由宏、ConVar 或内容文件决定。
  • 训练模式下 C4 的特殊处理(爆炸后移除等)只在代码中点到:game/shared/cstrike15/weapon_c4.cpp:371-392。
  • 烟雾遮罩与闪光致盲的画面效果在客户端渲染管线中实现,见 客户端视图渲染管线;Bot 对投掷物与炸弹事件的反应见 Bot 决策。