# Ground Control 指令文档
本文档基于 `groundcontrol/gamemode` 内的 `concommand.Add`、`CreateConVar`、客户端按键绑定和无线电命令注册逻辑整理。
路径中的 `cl_` 表示客户端文件,`sv_` 表示服务器端文件,`sh_` 表示客户端/服务器共享文件。
## 快速分类
| 类型 | 说明 |
| — | — |
| 玩家 UI 指令 | 玩家可直接绑定或在控制台输入,用于打开菜单、切换旁观目标、包扎、投掷手雷等。 |
| 内部同步指令 | 通常由客户端 UI 自动调用,用于向服务器提交队伍、投票、配装、附件、特质等选择。 |
| 管理/配置指令 | 主要是服务器 ConVar,用于控制玩法参数、回合、地图/模式轮换、语音、服务器名等。 |
| 无线电指令 | `gc_radio_menu` 打开菜单,`gc_radio_command <category> <id>` 提交菜单编号。 |
## 玩家可用 Console Commands
| 指令 | 参数 | 端 | 作用 | 触发/来源 |
| — | — | — | — | — |
| `gc_team_selection` | 无 | 客户端 | 打开/关闭队伍选择菜单;如果当前 gametype 禁止手动选队则无效。 | `gamemode/cl_team.lua`;默认按键入口为 `gm_showhelp`。 |
| `gc_loadout_menu` | 无 | 客户端 | 打开/关闭配装菜单;如果玩家是旁观者则改为打开队伍选择。关闭菜单时会自动请求服务器发放配装。 | `gamemode/cl_loadout.lua`;默认按键入口为 `gm_showteam`。 |
| `gc_voice_menu` | 无 | 客户端 | 打开/关闭语音角色选择菜单,写入 `gc_desired_voice`。 | `gamemode/cl_voice_selection.lua`;代码中 `gm_showspare1` 调用的是该菜单。 |
| `gc_radio_menu` | 无 | 客户端 | 打开/关闭无线电菜单;只有活着的玩家能打开。 | `gamemode/cl_radio.lua`;默认动作绑定为 `+menu_context`。 |
| `gc_bandage` | 无 | 客户端 | 如果自己正在流血,或准星指向可包扎的队友,则自动切到 `gc_medkit`。实际治疗逻辑由医疗武器处理。 | `gamemode/sh_player_bleeding.lua`;默认动作绑定为 `+menu`。 |
| `gc_quickgrenade` | 无 | 客户端 | 客户端快速投掷 CW2.0 手雷;成功后会调用服务器端 `gc_quickgrenade_sv`。准备阶段前不可用。 | `gamemode/sh_loadout.lua`;默认动作绑定为 `gmod_undo`。 |
| `gc_spectate_next` | 无 | 服务器 | 死亡后切换到下一个可旁观目标。活着或旁观延迟未结束时无效。 | `gamemode/sv_spectate.lua`;死亡状态下按攻击键也会触发。 |
## 客户端/服务器内部 Commands
这些命令可以手动输入,但主要是 UI 和客户端代码调用。大多没有管理员权限检查,依赖玩家状态、现金、是否存活、回合阶段等条件限制。
| 指令 | 参数 | 端 | 作用 | 主要校验 |
| — | — | — | — | — |
| `gc_attempt_join_team <team_id>` | `team_id`: `1` 红队,`2` 蓝队 | 服务器 | 请求加入指定队伍。成功后发送 `GC_TEAM_SELECTION_SUCCESS`,队伍人数差过大时要求重选。 | 不能在当前 gametype 禁止手动选队时加入;活着时不能换队;目标队伍人数差不能超过 `GM.MaxPlayerCountTeamDifference`。 |
| `gc_ask_for_loadout` | 无 | 服务器 | 请求按客户端 ConVar 发放当前配装。 | 玩家必须存活;只能在开局配装时间内,且距离出生点不超过 `GM.LoadoutDistance`。 |
| `gc_request_data` | 无 | 服务器 | 向客户端刷新现金、经验、附件、附件槽、特质等玩家数据。 | 每名玩家 1 秒冷却。 |
| `gc_buy_attachment <attachment_name>` | CW2.0 附件 id | 服务器 | 购买/解锁附件。 | 附件必须存在且非免费/未拥有;玩家现金必须足够。 |
| `gc_buy_trait <trait_id>` | 特质 id,例如 `medic`、`conditioned` | 服务器 | 首次购买特质或升级已拥有特质。 | 特质存在;现金足够;未超过最大等级。 |
| `gc_use_gadget <slot_index>` | 玩家 gadget 数组序号 | 服务器 | 使用指定 gadget。目前主要用于备用弹药补给。 | 玩家必须存活;gadget 存在;对应 gadget 自身 `canUse` 通过。 |
| `gc_radio_command <category> <id>` | 无线电分类编号 + 命令编号 | 服务器 | 发送无线电语音/标记给队友。 | 玩家必须存活;受 `GM.RadioDelay` 或单条命令 `radioWait` 冷却限制。 |
| `gc_vote <option_index>` | 投票选项编号 | 服务器 | 提交当前投票选项。 | 必须存在投票;玩家未投过;选项编号有效。 |
| `gc_request_gametype` | 无 | 服务器 | 向调用玩家发送当前 gametype id。 | 无额外限制。 |
## 管理/调试 Commands
| 指令 | 参数 | 端 | 作用 | 注意 |
| — | — | — | — | — |
| `gc_gametypelist` | 无 | 服务器 | 在服务器控制台打印可用 gametype 列表。 | 当前代码注册了 `Rush`、`Assault`、`Urban Warfare`、`Ghetto Drug Bust`。 |
| `gc_gametype_maplist` | 无 | 服务器 | 在服务器控制台打印每个 gametype 支持的地图,并标记未安装地图及 workshop id。 | 用于服务器配置和排查地图缺失。 |
| `gc_gametype_random` | 无 | 服务器 | 随机选择一个有可用地图的 gametype,并执行 `gc_gametype <id>` 后切图到随机地图。 | 没有权限检查,建议只从服务器控制台使用。 |
| `assignbotstoteam` | 无 | 服务器 | 将所有 bot 随机分配到红/蓝队并重生。 | 调试命令;没有权限检查。 |
| `gc_quickgrenade_sv` | 无 | 服务器 | 服务器端快速手雷执行入口,由客户端 `gc_quickgrenade` 成功后调用。 | 准备阶段前不可用;需要当前武器支持 CW2.0 quick grenade。 |
## 无线电菜单编号
`gc_radio_menu` 先打开分类菜单,玩家用数字槽位选择分类和命令。代码里可见分类如下:
| 分类编号 | 分类名 | 是否显示在菜单 |
| — | — | — |
| `1` | `Combat` | 是 |
| `2` | `Reply` | 是 |
| `3` | `Orders` | 是 |
| `4` | `Status` | 是 |
| `9` | `special` | 否;用于特殊事件,例如手雷 `Frag out`。 |
可提交格式为:
“`text
gc_radio_command <category> <command_id>
“`
常用无线电命令:
| 分类 | 编号 | 内部 id | 菜单文本 | 特殊行为 |
| — | — | — | — | — |
| Combat `1` | `1` | `enemy_spotted` | Enemy spotted | 标记准星位置附近敌人;可给现金/经验奖励。 |
| Combat `1` | `2` | `enemy_down` | Enemy down | 报告最近击杀位置或普通语音。 |
| Combat `1` | `3` | `needmedic` | Need medic | 在自己位置创建医疗请求标记。 |
| Combat `1` | `4` | `needammo` | Need ammo | 在自己位置创建弹药请求标记。 |
| Reply `2` | `1` | `affirmative` | Affirmative | 普通语音。 |
| Reply `2` | `2` | `negative` | Negative | 普通语音。 |
| Reply `2` | `3` | `thanks` | Thanks | 普通语音。 |
| Reply `2` | `4` | `wait_for_me` | Wait for me | 普通语音。 |
| Reply `2` | `5` | `moving` | Moving | 普通语音。 |
| Orders `3` | `1` | `suppress` | Suppress this position | 标记准星位置。 |
| Orders `3` | `2` | `defend` | Defend this position | 标记准星位置。 |
| Orders `3` | `3` | `followme` | Follow me | 普通语音。 |
| Orders `3` | `4` | `flank` | Flank them | 普通语音。 |
| Orders `3` | `5` | `move` | Move | 普通语音。 |
| Status `4` | `1` | `needhelp` | Need help | 在自己位置创建求援标记。 |
| Status `4` | `2` | `pinneddown` | Pinned down | 在自己位置创建被压制标记。 |
| Status `4` | `3` | `approachingenemy` | Approaching enemy | 在自己位置创建接敌标记,冷却为 2.5 秒。 |
| Status `4` | `4` | `clear` | Area clear | 在自己位置创建区域安全标记。 |
| special `9` | `1` | `fragout` | Frag out | 不在菜单显示;开始投掷手雷时自动发送。 |
## 客户端 ConVars
这些变量通常由菜单写入并保存在客户端,服务器通过 `Player:GetInfo*` 读取。
| ConVar | 默认值 | 作用 |
| — | — | — |
| `gc_hud_scale` | `1` | HUD 缩放,客户端限制为 `0.5` 到 `2`。 |
| `gc_desired_team` | `0` | 客户端记录期望队伍;实际加入通过 `gc_attempt_join_team`。 |
| `gc_desired_voice` | `0` | 语音角色选择;`0` 表示随机可见语音。 |
| `gc_primary_weapon` | `GM.DefaultPrimaryIndex` | 主武器索引。 |
| `gc_primary_mags` | `GM.DefaultPrimaryMagCount` | 主武器备用弹匣数,服务器限制在 `1..GM.MaxPrimaryMags`。 |
| `gc_secondary_weapon` | `GM.DefaultSecondaryIndex` | 副武器索引。 |
| `gc_secondary_mags` | `GM.DefaultSecondaryMagCount` | 副武器备用弹匣数,服务器限制在 `1..GM.MaxSecondaryMags`。 |
| `gc_tertiary_weapon` | `GM.DefaultTertiaryIndex` | 第三栏装备索引,例如闪光、烟雾、备用破片手雷。 |
| `gc_spare_ammo` | `GM.DefaultSpareAmmoCount` | 备用补给弹药量,服务器限制在 `GM.MinSpareAmmo..GM.MaxSpareAmmo`。 |
| `gc_bandages` | `GM.DefaultBandages` | 出生携带绷带数量,限制在 `GM.MinBandages..GM.MaxBandages`。 |
| `gc_armor_vest` | `GM.DefaultArmor` | 防弹衣索引。 |
| `gc_armor_helmet` | `GM.DefaultHelmet` | 头盔索引。 |
| `gc_primary_attachment_1` 到 `gc_primary_attachment_6` | `”0″` | 主武器附件槽保存的附件 id。 |
| `gc_secondary_attachment_1` 到 `gc_secondary_attachment_6` | `”0″` | 副武器附件槽保存的附件 id。 |
| `gc_trait` | `0` | 特质槽位之一;当前包含 `medic`、`covert_ops` 等。 |
| `gc_trait2` | `0` | 特质槽位之一;当前包含 `war_hardened`、`conditioned`、`will_to_live` 等。 |
## 服务器/共享 ConVars
| ConVar | 默认值 | 作用 | 生效方式 |
| — | — | — | — |
| `gc_gametype` | `1` | 下一张图/当前配置使用的 gametype。可填数字 id、内部名或显示名。 | 变更时调用 `GAMEMODE:changeGametype`;当前地图支持该模式时会广播 “NEXT MAP GAMETYPE”。 |
| `gc_allow_gametype_votes` | `1` | 是否允许在倒数第二回合开始下一模式投票。 | `>= 1` 开启。 |
| `gc_randomly_pick_gametype_and_map` | `0` | 到达轮换点时随机选择可用 gametype 和地图,且禁用普通地图/模式投票流程。 | `>= 1` 开启。 |
| `gc_rounds` | `10` | 每张地图回合数。 | 变更后更新 `GM.RoundsPerMap`。 |
| `gc_round_prep_time` | `15` | 新回合准备阶段秒数。 | 变更后更新 `GM.RoundPreparationTime`。 |
| `gc_round_restart_time` | `10` | 回合结束到下一回合/切图的等待秒数。 | 变更后更新 `GM.RoundRestartTime`。 |
| `gc_walkspeed` | `130` | 玩家基础走路速度。 | 新回合/重生相关逻辑使用。 |
| `gc_runspeed` | `280` | 玩家基础跑步速度。 | 移动逻辑实时读取更新后的 `GM.BaseRunSpeed`。 |
| `gc_damage_scale` | `1.55` | 敌对伤害倍率。 | 变更后更新 `GM.DamageMultiplier`。 |
| `gc_damagemult` | `1.55` | 旧/重复伤害倍率 ConVar。 | 代码中未注册自动更新回调,实际应优先使用 `gc_damage_scale`。 |
| `gc_crippling` | `1` | 是否启用手臂受伤导致掉主武器的 “crippling” 机制。 | `> 0` 开启。 |
| `gc_door_move_speed` | `350` | 地图门实体速度。 | 变更后遍历 `func_door_rotating`、`prop_door_rotating` 并设置 `Speed`。 |
| `gc_team_damage` | `1` | 是否启用友伤。 | `<= 0` 会关闭友伤。 |
| `gc_team_damage_scale` | `0.5` | 友伤倍率。 | 仅友军伤害使用。 |
| `gc_invincibility_time_period` | `3` | 出生后无敌秒数。 | 用于反出生点击杀。 |
| `gc_afk_timer` | `240` | AFK 踢出秒数。 | 无输入倒计时,剩 30 秒时警告。 |
| `gc_proximity_voicechat` | `0` | 是否启用敌方近距离语音可听。 | `>= 1` 开启。 |
| `gc_proximity_voicechat_distance` | `256` | 近距离语音距离,Source 单位。 | 配合近距离语音使用。 |
| `gc_proximity_voicechat_global` | `0` | 是否让所有语音都按距离限制,包括队友。 | `>= 1` 开启。 |
| `gc_proximity_voicechat_directional` | `0` | 是否启用 3D 方向语音。 | 近距离敌方语音场景下使用。 |
| `gc_meme_radio_chance` | `1` | 出生时随机切到隐藏语音包的概率,单位为千分之一。 | `1` 表示 1/1000。 |
| `gc_ghetto_cum_chance` | `10` | `Ghetto Drug Bust` 防守方获得特殊武器的概率,百分比。 | 仅该 gametype 使用。 |
| `gc_ghetto_fists_only_chance` | `20` | `Ghetto Drug Bust` 拳头局概率,百分比。 | 仅该 gametype 使用。 |
| `gc_ghetto_knife_chance` | `30` | `Ghetto Drug Bust` 防守方获得刀而不是拳头的概率,百分比。 | 仅该 gametype 使用。 |
| `gc_autopunish_teamdamage` | `300` | 自动惩罚投票触发的累计友伤阈值。 | 达到后对该玩家发起队内惩罚投票。 |
| `gc_auto_adjust_server_name` | `0` | 是否自动根据 gametype 和回合更新服务器名。 | `> 0` 开启。 |
| `gc_base_server_name` | `””` | 自动服务器名使用的基础名称。 | 空值时使用 `Ground Control`。 |
| `gc_insert_to_front` | `1` | 自动服务器名拼接顺序。 | `>= 1` 为 `基础名 – 模式/回合`,否则反过来。 |
| `gc_trashprop_mass_threshold` | `20` | 小垃圾物理物体质量阈值。 | 符合质量和 AABB 条件的 prop 会被设为 debris collision。 |
| `gc_trashprop_aabb_size_threshold` | `55` | 小垃圾物理物体 AABB 尺寸阈值。 | 配合质量阈值使用。 |
## Gametype 设置
`gc_gametype` 支持数字 id、内部名和显示名。当前注册顺序如下:
| id | 内部名 | 显示名 |
| — | — | — |
| `1` | `onesiderush` | `Rush` |
| `2` | `assault` | `Assault` |
| `3` | `urbanwarfare` | `Urban Warfare` |
| `4` | `ghettodrugbust` | `Ghetto Drug Bust` |
示例:
“`text
gc_gametype 3
gc_gametype urbanwarfare
gc_gametype “Urban Warfare”
gc_gametypelist
gc_gametype_maplist
“`
如果输入不存在的 gametype,代码会打印错误和帮助文本,并在部分路径中回退到默认 id `1`。
## 默认按键入口
| 动作 | 默认 bind 名 | 调用指令 |
| — | — | — |
| 队伍选择 | `gm_showhelp` | `gc_team_selection` |
| 配装菜单 | `gm_showteam` | `gc_loadout_menu` |
| 语音选择菜单 | `gm_showspare1` | `gc_voice_menu` |
| 包扎/切医疗包 | `+menu` | `gc_bandage` |
| 快速手雷 | `gmod_undo` | `gc_quickgrenade` |
| 无线电菜单 | `+menu_context` | `gc_radio_menu` |
| 备用弹药补给 | `slot0` | `gc_use_gadget <slot>` |
## 使用注意
– `gc_attempt_join_team`、`gc_buy_attachment`、`gc_buy_trait`、`gc_use_gadget`、`gc_vote` 等服务器命令没有显式管理员权限检查,但它们大多只修改调用玩家自己的状态,并依赖现金、存活、冷却、投票状态等逻辑约束。
– `gc_gametype_random`、`assignbotstoteam` 更像服务器管理/调试入口,代码中没有权限限制。公网服务器建议通过 ULX、server.cfg、控制台权限或额外封装限制普通玩家执行。
– `gc_damagemult` 和 `gc_damage_scale` 同时存在,但自动更新回调只接到 `gc_damage_scale`。调伤害倍率时优先改 `gc_damage_scale`。
– 部分客户端 ConVar 的值是“索引”而不是内部 id,例如武器、防具、特质槽;具体显示和可选项由菜单根据已注册数据生成。