在GOM引擎单机传奇中解决装备回收验证问题、删除防脱机怪以及实现地图随机飞行

来源: 作者: 点击:
本文将彻底解决:
1. **装备回收验证**:去除放入两件装备的繁琐步骤
2. **防脱机怪骚扰**:永久删除地图中的跟屁虫怪物
3. **地图随机限制**:强制开启所有地图的随机传送

---

### 一、秒删装备回收验证

#### 1. 定位回收脚本
找到NPC脚本(通常在`\MirServer\Envir\Market_Def\回收NPC-3.txt`),搜索关键词:

```lua
[@Main]
#if
CheckItemCount > 1 -- 验证装备数量
#act
OPENRECYCLEDIALOG
```


#### 2. 暴力删除验证逻辑
修改为:
```lua
[@Main]
#act
OPENRECYCLEDIALOG -- 直接打开回收界面
```


**重要提醒**:同步修改`QFunction-0.txt`中的回收触发,删除所有`#if`条件判断

---

### 二、永久清除防脱机怪

#### 1. 禁用刷怪配置
打开`\MirServer\Envir\MonGen.txt`,查找并删除包含以下特征的行:
```
地图代码 坐标 坐标 防脱机刀卫 数量 范围 刷新时间
```

**示例**:
```
3 333 333 防脱机刀卫 1 10 60 --> 删除该行
```


#### 2. 关闭AI追踪
在`QManage.txt`中添加全局屏蔽:
```lua
[@Login]
#act
SetOnTimer 801 5 -- 每5秒检测

[@Timer801]
#IF
CheckMapMonCount 防脱机刀卫 > 0
#ACT
KillMapMon 防脱机刀卫
```


---

### 三、强制开启全图随机传送

#### 1. 地图属性修改
打开`\MirServer\Envir\MapInfo.txt`,找到目标地图行:
```
[0110 祖玛神殿] NORANDOMMOVE --> 改为 [0110 祖玛神殿]
```


#### 2. 脚本解锁限制
在`QFunction-0.txt`中覆盖传送规则:
```lua
[@UseRandomMoveItem]
#act
CHANGEMAP <$MAP> <$X> <$Y>
BREAK
```


**高阶方案**:指定坐标随机范围
```lua
CALCULATE N$随机X = <$RANDOM(100)> + 100
CALCULATE N$随机Y = <$RANDOM(100)> + 100
MAPMOVE <$MAP> <$STR(N$随机X)> <$STR(N$随机Y)>
```


---

### 四、效果验证与问题排查

| **功能** | 验证方法 | 常见错误处理 |
|------------------|----------------------------|--------------------------|
| 装备回收 | 放入单件装备测试是否直接回收 | 检查NPC脚本是否有多重嵌套 |
| 防脱机怪清除 | 在地图停留5分钟观察刷新 | 确认MonGen.txt无残留条目 |
| 随机传送 | 使用随机石或命令@传送 | 确保MapInfo.txt无冲突标记 |


---

### 五、终极工具包(评论区自取)
1. **脚本清洗器**:自动删除所有回收验证条件
2. **怪物清除插件**:一键移除指定名称怪物
3. **地图解锁工具**:批量去除NORANDOMMOVE标签

---

#### 结语
通过脚本拦截+配置清洗,可彻底解决GOM单机版三大顽疾。关键点:
1. **回收验证**:删除所有CheckItemCount和条件判断
2. **防脱机怪**:双重保险(MonGen删除+定时清杀)
3. **随机传送**:覆盖引擎原生限制

修改前务必备份`Envir`文件夹,建议使用Notepad++等专业工具编辑脚本,避免编码错误。

#### 1. 准备工作
在开始之前,请确保你已经安装了GOM引擎,并且有一个基本的游戏框架搭建完成。此外,还需要准备好所有必要的客户端和服务器端文件。

#### 2. 删除装备回收时要放入随意两个装备验证问题

##### 问题分析
装备回收时要求放入两个特定装备的验证机制可能导致用户体验不佳。我们需要移除这种验证,使得玩家可以自由选择回收哪些装备。

##### 解决步骤

###### 步骤一:修改装备回收逻辑
打开`src\item_manager.cpp`文件,找到处理装备回收的部分,移除验证逻辑。

```cpp
void CItemManager::RecycleItems(CCharacter* character, std::vector<CItem*> items)
{
// 移除原有的验证逻辑
/*
if (items.size() != 2)
{
character->SendSystemMessage("请放入两个装备进行回收");
return;
}
*/

int totalValue = 0;
for (CItem* item : items)
{
totalValue += item->GetSellPrice();
}

character->AddGold(totalValue);
for (CItem* item : items)
{
character->RemoveItem(item);
delete item;
}

character->SendSystemMessage("装备回收成功,获得金币: " + std::to_string(totalValue));
}
```

###### 步骤二:编译并测试
确保所有修改后的代码都能成功编译。

```sh
g++ -o server src/server_main.cpp src/item_manager.cpp -lengine
```

启动服务器和客户端,测试装备回收是否能够正常工作。

```sh
start login_server.exe
start server.exe
start client.exe
```

#### 3. 删除地图里面的防脱机怪

##### 问题分析
防脱机怪(如跟随玩家移动的怪物)可能会干扰玩家的游戏体验。我们需要删除这些怪物,使其不再出现在游戏中。

##### 解决步骤

###### 步骤一:查找防脱机怪配置
打开`data\mob_proto.txt`文件,查找并删除或注释掉防脱机怪的配置。

```plaintext
# vnum name level exp range attack_defense damage resist_magic magic_defense poison_resist hp_recovery sp_recovery special_effect ai_script
# 1003 防脱机怪 50 1000 10 10 100 0 0 0 10 10 0 stay_with_player_ai.cpp
```

###### 步骤二:删除或禁用AI脚本
如果存在专门用于防脱机怪的AI脚本,删除或禁用这些脚本。

```cpp
// stay_with_player_ai.cpp
/*
#include "monster.h"

class CStayWithPlayerAI : public CMonsterAI
{
public:
void OnInit(CMonster* monster) override
{
// 初始化逻辑
}

void OnUpdate(CMonster* monster, float dt) override
{
// 更新逻辑
HandleMovement(monster);
}

void HandleMovement(CMonster* monster)
{
CCharacter* player = GetNearestPlayer(monster);
if (player)
{
Vector3f direction = CalculateChaseDirection(monster, player);
monster->Move(direction.x, direction.y, direction.z);
}
}
};

extern "C" __declspec(dllexport) CMonsterAI* CreateStayWithPlayerAI()
{
return new CStayWithPlayerAI();
}
*/
```

###### 步骤三:编译并测试
确保所有修改后的代码都能成功编译。

```sh
g++ -o server src/server_main.cpp src/monster.cpp -lengine
```

启动服务器和客户端,测试防脱机怪是否已经被移除。

```sh
start login_server.exe
start server.exe
start client.exe
```

#### 4. 让不能随机飞的地图可以随机飞

##### 问题分析
某些地图可能被设置为不允许随机飞行,这限制了玩家的行动自由。我们需要修改这些地图的配置,使其支持随机飞行。

##### 解决步骤

###### 步骤一:修改地图配置
打开`data\map_info.txt`文件,查找需要修改的地图配置,并添加允许随机飞行的标志。

```plaintext
index map_name file_name width height tile_width tile_height min_x max_x min_y max_y flags
1 出生地 start.map start.wld 200 200 16 16 0 200 0 200 MAP_FLAG_ALLOW_RANDOM_FLY
```

- `flags`: 地图标志位,添加`MAP_FLAG_ALLOW_RANDOM_FLY`表示允许随机飞行。

###### 步骤二:更新地图标志定义
确保`common_types.h`文件中定义了`MAP_FLAG_ALLOW_RANDOM_FLY`标志。

```cpp
#define MAP_FLAG_NONE 0x00000000
#define MAP_FLAG_PVP 0x00000001
#define MAP_FLAG_NO_RECALL 0x00000002
#define MAP_FLAG_NO_TELEPORT 0x00000004
#define MAP_FLAG_NO_SUMMON 0x00000008
#define MAP_FLAG_NO_ENTER 0x00000010
#define MAP_FLAG_NO_LEAVE 0x00000020
#define MAP_FLAG_ALLOW_RANDOM_FLY 0x00000040
```

###### 步骤三:修改地图加载逻辑
打开`src\world.cpp`文件,确保地图加载时正确读取并应用标志位。

```cpp
void CWorld::LoadMap(int index, const char* mapName, const char* fileName, int width, int height, int tileWidth, int tileHeight, int minX, int maxX, int minY, int maxY, unsigned int flags)
{
CMap* map = new CMap(index, mapName, fileName, width, height, tileWidth, tileHeight, minX, maxX, minY, maxY, flags);
m_maps[index] = map;

// 加载地图数据
LoadMapData(map);
}

void CWorld::LoadMapData(CMap* map)
{
// 加载地图数据的逻辑
// ...
}
```

###### 步骤四:修改飞行逻辑
打开`src\character.cpp`文件,确保角色飞行逻辑考虑了地图标志位。

```cpp
bool CCharacter::TeleportToRandomLocation()
{
if (!HasFlag(MAP_FLAG_ALLOW_RANDOM_FLY))
{
SendSystemMessage("当前地图不允许随机飞行");
return false;
}

CMap* currentMap = GetCurrentMap();
if (!currentMap)
{
SendSystemMessage("无法获取当前地图信息");
return false;
}

int randomX = RandomInt(currentMap->GetMinX(), currentMap->GetMaxX());
int randomY = RandomInt(currentMap->GetMinY(), currentMap->GetMaxY());

SetPosition(randomX, randomY, GetCurrentZ());
SendTeleportPacket(this);

return true;
}
```

###### 步骤五:编译并测试
确保所有修改后的代码都能成功编译。

```sh
g++ -o server src/server_main.cpp src/world.cpp src/character.cpp -lengine
```

启动服务器和客户端,测试是否能够在指定地图上随机飞行。

```sh
start login_server.exe
start server.exe
start client.exe
```

#### 总结
通过以上步骤,你可以在GOM引擎单机传奇中解决装备回收验证问题、删除防脱机怪以及实现地图随机飞行。这不仅提升了游戏的流畅性和可玩性,还能提供更好的游戏体验。希望这篇教程对你有所帮助!