投掷物与 C4
投掷物与 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,记录统计,进入淡出 Think | game/shared/cstrike15/smokegrenade_projectile.cpp:175-233 |
| 燃烧瓶/燃烧弹 | 触发 molotov_detonate;落在世界上则就地起火,在空中时向下追踪 128 单位找地面,太高只播放音效;起火时创建 inferno 实体 | game/shared/cstrike15/molotov_projectile.cpp:314-404 |
| 诱饵弹 | 自定义引爆 Think | game/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:
- 判断是否站在地面上;站在玩家、可推动物体、可破坏物体或可被推开的物体上视为不在地面:
game/shared/cstrike15/weapon_c4.cpp:1542-1556。 - 未开始布置且位于炸弹区并着地时开始布置,设置
m_fArmedTime = now + WEAPON_C4_ARM_TIME,触发bomb_beginplant:game/shared/cstrike15/weapon_c4.cpp:1570-1600。 - 布置中离开炸弹区或离地则取消:
game/shared/cstrike15/weapon_c4.cpp:1656-1660;到达布置时间后放置:game/shared/cstrike15/weapon_c4.cpp:1691。 - 放置成功:发放
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 团灭获胜。