跳转至

脚本创建NPC

命令概述

使用脚本动态创建和删除NPC,常用于副本、活动、任务等场景。


NpcGenEx - 创建NPC

命令格式

NpcGenEx NPC编号 唯一ID 地图编号 坐标 存活时间(秒) [自动弹窗]

参数说明

参数 类型 说明 特殊值
NPC编号 ushort NPC模板编号(守卫编号) 必须存在于守卫数据表
唯一ID int NPC的唯一标识符 用于后续删除,同一玩家不能重复
地图编号 byte/string 目标地图编号 * = 玩家当前地图
坐标 string 生成坐标 * = 玩家前方1格
X,Y = 指定坐标
X,Y\|X,Y\|X,Y = 随机选择
存活时间 int NPC存活秒数 默认3秒
自动弹窗 int 是否自动弹出对话框(可选) 0 = 不弹窗(默认)
1 = 自动弹窗

核心特性

  1. 唯一ID管理
  2. 每个玩家的NPC通过唯一ID管理
  3. 如果唯一ID已存在,会先删除旧NPC再创建新的
  4. 不同玩家可以使用相同的唯一ID

  5. 坐标系统

  6. 支持单个固定坐标
  7. 支持多个坐标随机选择(用 | 分隔)
  8. 支持相对玩家位置(* = 前方1格)

  9. 自动弹窗功能(GameServer_Dev 特有)

  10. 第6个参数设为 1 时,NPC创建后会自动弹出对话框
  11. 仅对创建者玩家生效

使用示例

示例1:在玩家前方创建NPC

[@使用道具]
#IF
#ACT
DelNpcGen 888888
NpcGenEx 4773 888888 * * 60
TopMessage "召唤NPC成功!" FALSE
BREAK

示例2:在指定地图坐标创建NPC

[@传送到比奇]
#IF
#ACT
NpcGenEx 4773 999999 3 330,330 300
TopMessage "已在比奇省(330,330)召唤NPC!" FALSE
BREAK

示例3:随机坐标创建NPC

[@随机召唤]
#IF
#ACT
NpcGenEx 4773 777777 * 330,330|335,335|340,340 180
TopMessage "已随机召唤NPC!" FALSE
BREAK

示例4:使用变量动态创建

[@动态召唤]
#IF
#ACT
MOV N71 <$MAP>
MOV N72 <$X_COORD>
MOV N73 <$Y_COORD>
DelNpcGen 111111
NpcGenEx 6721 111111 <$STR(N71)> <$STR(N72)>,<$STR(N73)> 100
TopMessage "在地图(<$STR(N71)>)坐标(<$STR(N72)>,<$STR(N73)>)创建NPC,100秒后消失" FALSE
BREAK

示例5:自动弹窗NPC(GameServer_Dev)

[@召唤隐身NPC]
#IF
#ACT
DelNpcGen 888888
NpcGenEx 4773 888888 * * 30 1
TopMessage "召唤NPC成功!" FALSE
BREAK

DelNpcGen - 删除NPC

命令格式

DelNpcGen 唯一ID

参数说明

参数 类型 说明
唯一ID int 要删除的NPC唯一标识符

使用示例

[@删除NPC]
#IF
#ACT
DelNpcGen 111
TopMessage "成功删除唯一ID为111的NPC" FALSE
BREAK

实现细节

数据结构

  • NPC存储在 玩家.个人NPC字典
  • 键:唯一ID(int)
  • 值:守卫实例对象

生命周期管理

  1. 创建时
  2. 检查NPC模板是否存在
  3. 如果唯一ID已存在,先删除旧NPC
  4. 解析地图和坐标
  5. 创建守卫实例并设置存活时间

  6. 删除时

  7. 从玩家个人字典中移除
  8. 设置 存活时间 = DateTime.MinValue 标记立即删除

  9. 自动清理

  10. 存活时间 到期时,系统自动删除NPC

错误处理

  • NPC模板不存在:记录命令日志
  • 地图未找到:记录命令日志
  • 坐标解析失败:记录命令日志
  • 删除不存在的NPC:记录调试日志(如果开启)

版本差异

GameServer_Dev(开发版)

  • ✅ 支持6个参数(含自动弹窗)
  • ✅ 完整的调试日志
  • ✅ 详细的异常处理

GameServer_Prod/Custom(生产版)

  • ⚠️ 仅支持5个参数(无自动弹窗)
  • ⚠️ 简化的日志输出

其他版本(mir3d_xy、BYYH_new、CQYH_TT)

  • ⚠️ 基础功能相同
  • ⚠️ 实现细节略有差异

常见问题

Q1: 为什么NPC无法删除?

A: 检查以下几点: 1. 唯一ID是否正确 2. NPC是否已经过期自动删除 3. 是否在正确的玩家上下文中执行

Q2: 可以创建多个相同编号的NPC吗?

A: 可以,只要使用不同的唯一ID即可。

Q3: NPC会跟随玩家吗?

A: 不会,NPC创建后固定在指定坐标,不会移动。

Q4: 如何实现NPC跟随玩家?

A: 使用 随身NPC 命令,详见 随身NPC文档

Q5: 自动弹窗功能在哪些版本可用?

A: 仅 GameServer_Dev 支持第6个参数的自动弹窗功能。


最佳实践

1. ID 管理策略(重要)⭐

推荐方案:使用个人变量

避免使用固定ID(如 888888),会导致多个玩家冲突。推荐使用个人变量自动生成唯一ID:

[@召唤NPC_推荐方式]
#IF
#ACT
; 使用个人变量 U100 作为ID计数器
CALCVAR PERSONAL U100 + 1
DelNpcGen <$STR(U100)>
NpcGenEx 4773 <$STR(U100)> * * 60
TopMessage "召唤NPC成功!ID=<$STR(U100)>" FALSE
BREAK

优势: - ✅ 每个玩家有独立的ID序列 - ✅ 自动递增,永不冲突 - ✅ 无需管理复杂的字典 - ✅ 玩家下线自动保存 - ✅ 避免内存泄漏

详见:NpcGenEx优化方案-使用个人变量


2. 唯一ID规划

如果仍需使用固定ID,建议规划ID范围:

  • 使用有意义的ID范围(如:任务NPC用10xxxx,活动NPC用20xxxx)
  • 避免ID冲突

3. 重复召唤处理

创建前先调用 DelNpcGen 删除旧NPC:

[@召唤NPC]
#IF
#ACT
DelNpcGen 888888  ; 先删除旧的
NpcGenEx 4773 888888 * * 60  ; 再创建新的
BREAK

4. 存活时间设置

  • 临时NPC:30-60秒
  • 任务NPC:180-300秒
  • 活动NPC:根据活动时长设置

5. 坐标验证

  • 确保坐标在地图有效范围内
  • 避免在障碍物上生成NPC

相关命令

  • 随身NPC - 跟随玩家的NPC
  • NpcGen - 简化版NPC创建(如果存在)