Commit 894a4630 authored by Nemo Ma's avatar Nemo Ma

cleanup

parent 18636ac8
# 种火部署功能修复记录
## 问题描述
在侧边面板中使用种火部署功能时,点击"部署种火"按钮后,command.php 在新窗口中打开,显示原始 HTML 代码而不是正确执行命令。这个问题也影响了种火物品获取和种火强化功能。
## 问题原因
问题出在表单提交方式上。原来的代码使用了创建隐藏表单并直接提交的方式,这导致了浏览器打开新窗口并显示原始 HTML 内容,而不是正确处理命令。
## 修复方法
将表单提交方式从直接提交改为使用 AJAX 方式提交,这样可以在后台处理命令而不会导致页面跳转或打开新窗口。
修改了以下三个 JavaScript 函数:
1. `deployFireseed()` - 处理种火部署
2. `getFireseedItem()` - 处理种火物品获取
3. `enhanceFireseed()` - 处理种火强化
每个函数都做了以下改动:
- 移除了创建隐藏表单的代码
- 使用 FormData 对象收集表单数据
- 使用 XMLHttpRequest 对象通过 AJAX 方式提交数据
- 添加了成功和错误处理逻辑
- 在命令执行后更新 clbpara 数据
- 显示操作状态消息
## 修复文件
- templates/default/slidingpanel.htm
## 注意事项
- 这种修复方法保持了原有的命令处理逻辑不变,只是改变了命令的提交方式
- 使用 AJAX 提交后,命令的执行结果会显示在游戏主界面的命令窗口中,而不是打开新窗口
- 添加了错误处理和状态反馈,提高了用户体验
# 种火 clbpara 数据格式修复记录
## 问题描述
在收纳种火后,其 clbpara 数据没有正确处理,数据库中的 clbpara 键值成为了类似于 `czoyMzoiNCJza2lsbCI6WyJmaXJlc2VlZDMiXX0iOw==` 这样的 base64 编码的序列化数据,导致大部分逻辑无法生效。
## 问题原因
问题出在 FireseedRecruit 函数中处理 NPC 的 clbpara 数据的方式。当前代码使用了 serialize 和 base64_encode 来处理 clbpara 数据,但是系统中处理 clbpara 的标准方式是使用 JSON 格式。
## 修复方法
1. 修改 FireseedRecruit 函数中更新 NPC clbpara 的代码,将 base64_encode(serialize()) 改为 json_encode()
2. 创建一个修复函数 fix_fireseed_data(),用于修复已经存在的错误数据
3. 在 command.php 中添加一个特殊命令 sp_fireseed_fix,用于执行修复函数
4. 在侧边面板中添加一个修复按钮,方便用户执行修复操作
## 修复文件
1. include/game/club22.func.php - 修改 FireseedRecruit 函数
2. include/game/club22_fix.func.php - 新增修复函数
3. command.php - 添加特殊命令
4. templates/default/slidingpanel.htm - 添加修复按钮和 JavaScript 函数
## 修复详情
1. 在 FireseedRecruit 函数中,将:
```php
$encoded_clbpara = base64_encode(serialize($npc_clbpara));
```
修改为:
```php
$encoded_clbpara = json_encode($npc_clbpara, JSON_UNESCAPED_UNICODE);
```
2. 创建 club22_fix.func.php 文件,实现 fix_fireseed_data 函数,该函数会:
- 查找所有种火 NPC(type=92)
- 检查 clbpara 是否为 base64 编码的序列化数据
- 如果是,则解码、反序列化,然后重新以 JSON 格式编码
- 更新数据库中的记录
- 同时检查所有拥有种火的玩家,确保种火的 owner 字段正确
3. 在 command.php 中添加特殊命令:
```php
elseif($sp_cmd == 'sp_fireseed_fix' && $club == 22){
include_once GAME_ROOT.'./include/game/club22_fix.func.php';
fix_fireseed_data();
$mode = 'command';
}
```
4. 在侧边面板中添加"种火维护"部分,包含修复按钮和 fixFireseedData JavaScript 函数
## 注意事项
- 修复操作只能由枫火歌者(club=22)执行
- 修复操作会尝试修复所有种火的数据格式问题
- 修复操作会显示修复的记录数量
- 修复按钮有确认提示,防止误操作
# 种火 clbpara 数据格式修复记录 (第二次)
## 问题描述
在收纳种火后,其 clbpara 中的 skill 数据仍然没有正确处理,数据库中的 clbpara 键值成为了类似于 `"4"skill":[fireseed3]}"` 这样的格式,而不是正确的 JSON 格式 `{"skill":["fireseed3"]}`。
## 问题原因
问题出在 FireseedRecruit 函数中处理 NPC 的 clbpara 数据的方式。虽然我们已经将 base64_encode(serialize()) 改为 json_encode(),但是在读取 NPC 的 clbpara 数据时没有正确处理 skill 字段。
## 修复方法
1. 修改 FireseedRecruit 函数,确保正确处理 NPC 的 clbpara 数据:
- 添加对 NPC clbpara 的检查,确保它是数组格式
- 添加对 skill 字段的检查,确保它是数组格式
2. 修改 club22_fix.func.php 文件,增强修复功能:
- 添加对 skill 字段的特殊处理,将字符串格式的 skill 字段转换为数组格式
- 添加对非 base64 编码的 clbpara 数据的处理
- 添加对玩家 clbpara 中 fireseed 数据的修复
## 修复文件
1. include/game/club22.func.php - 修改 FireseedRecruit 函数
2. include/game/club22_fix.func.php - 增强修复功能
## 修复详情
1. 在 FireseedRecruit 函数中,添加对 NPC clbpara 的检查:
```php
// 确保 NPC 的 clbpara 是数组格式
if(!is_array($npc['clbpara'])) {
$npc['clbpara'] = get_clbpara($npc['clbpara']);
}
```
2. 在 FireseedRecruit 函数中,修改对 skill 字段的处理:
```php
'skills' => isset($npc['clbpara']['skill']) && is_array($npc['clbpara']['skill']) ? $npc['clbpara']['skill'] : array(),
```
3. 在 club22_fix.func.php 文件中,添加对 skill 字段的特殊处理:
```php
// 确保 skill 字段是数组
if(isset($unserialized['skill']) && !is_array($unserialized['skill'])) {
// 如果 skill 字段不是数组,尝试修复
$skill_str = $unserialized['skill'];
// 尝试从字符串中提取技能数组
if(preg_match('/\[(.*?)\]/', $skill_str, $matches)) {
$skills = explode(',', str_replace('"', '', $matches[1]));
$unserialized['skill'] = array_map('trim', $skills);
} else {
$unserialized['skill'] = array();
}
}
```
4. 在 club22_fix.func.php 文件中,添加对非 base64 编码的 clbpara 数据的处理:
```php
// 如果不是 base64 编码,尝试直接解析
$clbpara_data = json_decode($npc['clbpara'], true);
if(is_array($clbpara_data)) {
// 确保 skill 字段是数组
if(isset($clbpara_data['skill']) && !is_array($clbpara_data['skill'])) {
// 如果 skill 字段不是数组,尝试修复
$skill_str = $clbpara_data['skill'];
// 尝试从字符串中提取技能数组
if(preg_match('/\[(.*?)\]/', $skill_str, $matches)) {
$skills = explode(',', str_replace('"', '', $matches[1]));
$clbpara_data['skill'] = array_map('trim', $skills);
} else {
$clbpara_data['skill'] = array();
}
}
// 重新编码为JSON格式
$json_clbpara = json_encode($clbpara_data, JSON_UNESCAPED_UNICODE);
// 更新数据库
$db->query("UPDATE {$tablepre}players SET clbpara='$json_clbpara' WHERE pid='{$npc['pid']}'");
$fixed_count++;
}
```
5. 在 club22_fix.func.php 文件中,添加对玩家 clbpara 中 fireseed 数据的修复:
```php
// 检查种火的skills字段是否为数组
if(isset($fs_data['skills']) && !is_array($fs_data['skills'])) {
// 如果 skills 字段不是数组,尝试修复
$skills_str = $fs_data['skills'];
// 尝试从字符串中提取技能数组
if(preg_match('/\[(.*?)\]/', $skills_str, $matches)) {
$skills = explode(',', str_replace('"', '', $matches[1]));
$clbpara['fireseed'][$fs_id]['skills'] = array_map('trim', $skills);
} else {
$clbpara['fireseed'][$fs_id]['skills'] = array();
}
$updated = true;
}
```
## 注意事项
- 修复操作只能由枫火歌者(club=22)执行
- 修复操作会尝试修复所有种火的数据格式问题,包括 skill 字段的格式问题
- 修复操作会显示修复的记录数量
- 修复按钮有确认提示,防止误操作
# 种火探物和索敌逻辑移动记录
## 问题描述
在将种火设定在探物或索敌模式时,没有返回任何反馈,效果也没有生效。这是因为这些功能的触发逻辑在 game.php 中,但只有在玩家执行 command=move 时才会触发,而不会在其他移动或探索操作中触发。
## 问题原因
原来的代码在 game.php 中判断 `$mode == 'command' && $command == 'move'` 时才会触发种火的探物和索敌逻辑,但这种判断方式不够全面,无法覆盖所有的移动和探索场景。
## 修复方法
将种火的探物和索敌逻辑从 game.php 移动到 search.func.php 中的 move() 和 search() 函数中,这样无论玩家通过什么方式移动或探索,都能触发种火的相关功能。
## 修改文件
1. include/game/search.func.php - 在 move() 和 search() 函数中添加种火逻辑
2. game.php - 移除原有的种火逻辑判断
## 修改详情
1. 在 search.func.php 的 move() 函数中添加:
```php
# 如果是种火歌者,处理种火相关逻辑
if($club == 22) {
include_once GAME_ROOT.'./include/game/club22.func.php';
FireseedSearch($pls);
FireseedDrainNPC($pls);
}
```
2. 在 search.func.php 的 search() 函数中添加:
```php
# 如果是种火歌者,处理种火相关逻辑
if($club == 22) {
include_once GAME_ROOT.'./include/game/club22.func.php';
FireseedSearch($pls);
FireseedDrainNPC($pls);
}
```
3. 从 game.php 中移除:
```php
// 如果是种火歌者,处理种火相关逻辑
if($club == 22) {
include_once GAME_ROOT.'./include/game/club22.func.php';
// 如果玩家在移动时,触发种火探物和索敌逻辑
if($mode == 'command' && $command == 'move') {
FireseedSearch($pls);
FireseedDrainNPC($pls);
}
}
```
## 优势
1. 无论玩家通过什么方式移动或探索,都能触发种火的探物和索敌逻辑
2. 代码逻辑更加清晰,将相关功能放在更合适的位置
3. 修复了种火探物和索敌功能不生效的问题
## 注意事项
- 这个修改不会影响其他功能,只是将种火的逻辑移动到更合适的位置
- 种火的探物和索敌功能现在会在每次移动和探索时都触发,而不仅仅是在执行 command=move 时
# 种火管理面板更新功能修复记录
## 问题描述
通过侧面板对种火进行操作后,面板上的数据不会自动更新,必须重新加载整个页面才能看到变化。这与之前 charge 进度条的问题类似。点击面板上的更新信息按钮也不会更新种火标签页的内容。
## 问题原因
虽然已经有 `fetchLatestClbpara()` 函数来获取最新的 clbpara 数据,但是种火标签页的内容没有在数据更新后刷新。需要添加一个函数来更新种火标签页的内容,并在获取最新数据后调用它。
## 修复方法
1. 添加 `updateFireseedTab()` 函数,用于更新种火标签页的内容
2. 在 `fetchLatestClbpara()` 函数中调用 `updateFireseedTab()`
3. 在 `openPanel()` 函数中调用 `updateFireseedTab()`
4. 在 `manualUpdate()` 函数中调用 `updateFireseedTab()`
5. 在 `deployFireseed()`、`getFireseedItem()` 和 `enhanceFireseed()` 函数中添加延迟调用 `updateFireseedTab()`
## 修改文件
1. templates/default/slidingpanel.htm - 添加 `updateFireseedTab()` 函数及相关辅助函数
## 修改详情
1. 添加 `updateFireseedTab()` 函数,用于更新种火标签页的内容:
- 更新种火状态表格
- 更新种火选择下拉框
- 更新种火物品列表
2. 添加辅助函数:
- `updateFireseedStatusTable()` - 更新种火状态表格
- `getPlsName()` - 获取位置名称
- `updateFireseedSelects()` - 更新种火选择下拉框
- `updateFireseedItemsList()` - 更新种火物品列表
3. 在以下位置调用 `updateFireseedTab()` 函数:
- `fetchLatestClbpara()` 函数中
- `openPanel()` 函数中
- `manualUpdate()` 函数中
- `deployFireseed()`、`getFireseedItem()` 和 `enhanceFireseed()` 函数中(延迟调用)
## 优势
1. 种火标签页的内容会在数据更新后自动刷新
2. 用户可以通过点击更新信息按钮手动刷新种火标签页
3. 用户可以在操作种火后立即看到变化,无需刷新整个页面
4. 提高了用户体验,使种火管理更加方便
## 注意事项
- 由于 AJAX 请求的异步性质,在某些情况下可能需要等待一段时间才能看到更新后的数据
- 为了确保数据更新后能够正确显示,在某些操作后添加了延迟调用 `updateFireseedTab()` 函数
# 种火部署位置修复记录
## 问题描述
1. 种火部署位置选择下拉框显示了所有位置,包括禁区和隐藏位置,而不是只显示玩家可以移动到的位置
2. 种火部署后没有正确移动到选择的位置
## 问题原因
1. 位置选择下拉框没有过滤掉禁区和隐藏位置
2. FireseedDeploy 函数只更新了 clbpara 中的种火位置,但没有更新数据库中对应 NPC 的位置
## 修复方法
1. 修改 slidingpanel.htm 中的位置选择下拉框,使其只显示玩家可以移动到的位置
2. 修改 club22.func.php 中的 FireseedDeploy 函数,确保种火正确移动到选择的位置
## 修改文件
1. templates/default/slidingpanel.htm - 修改位置选择下拉框
2. include/game/club22.func.php - 修改 FireseedDeploy 函数
## 修改详情
1. 在 slidingpanel.htm 中修改位置选择下拉框:
```html
<select id="deploy_pls_panel">
<!--{loop $plsinfo $pls_id $pls_name}-->
<!--{if $pls_id > 0 && !in_array($pls_id, $deepzones) && $pls_id < 100}-->
<option value="$pls_id" <!--{if $pls_id == $pls}-->selected<!--{/if}-->>$pls_name</option>
<!--{/if}-->
<!--{/loop}-->
</select>
```
2. 在 club22.func.php 中修改 FireseedDeploy 函数:
- 添加对位置有效性的检查
- 添加更新数据库中 NPC 位置的代码
```php
// 检查位置是否有效(不是禁区或隐藏地图)
if(in_array($pls, $deepzones) || $pls < 0 || $pls >= 100) {
$log .= "<span class='red'>无法部署到指定位置!</span><br>";
return false;
}
// 如果种火有对应的NPC,更新NPC的位置
$result = $db->query("SELECT * FROM {$tablepre}players WHERE pid='$fireseed_id'");
if($db->num_rows($result) > 0) {
$db->query("UPDATE {$tablepre}players SET pls='$pls' WHERE pid='$fireseed_id'");
}
```
## 优势
1. 位置选择下拉框只显示玩家可以移动到的位置,避免玩家选择无效位置
2. 种火部署后会正确移动到选择的位置,使得探物和索敌功能能够正常工作
3. 添加了位置有效性检查,避免玩家部署到无效位置
## 注意事项
- 这个修复不会影响其他功能,只是修复了种火部署的问题
- 种火部署后,如果有对应的 NPC,会更新 NPC 的位置,使得探物和索敌功能能够正常工作
# 种火 clbpara 保存修复记录
## 问题描述
在部署种火后,种火的位置信息没有正确更新。虽然 FireseedDeploy 函数更新了 clbpara 中的种火位置信息,但没有将更新后的 clbpara 保存到数据库中,导致种火的位置信息在页面刷新后丢失。
## 问题原因
FireseedDeploy、FireseedSearch 和 FireseedEnhance 函数更新了 clbpara 数组,但没有将更新后的 clbpara 保存到数据库中。
## 修复方法
修改 FireseedDeploy、FireseedSearch 和 FireseedEnhance 函数,在更新 clbpara 数组后,将其使用 JSON 格式编码并保存到数据库中。
## 修改文件
1. include/game/club22.func.php - 修改 FireseedDeploy、FireseedSearch 和 FireseedEnhance 函数
## 修改详情
1. 在 FireseedDeploy 函数中添加:
```php
// 将更新后的 clbpara 保存到数据库
$encoded_clbpara = json_encode($clbpara, JSON_UNESCAPED_UNICODE);
$db->query("UPDATE {$tablepre}players SET clbpara='$encoded_clbpara' WHERE pid='$pid'");
```
2. 在 FireseedSearch 函数中添加:
```php
// 将更新后的 clbpara 保存到数据库
$encoded_clbpara = json_encode($clbpara, JSON_UNESCAPED_UNICODE);
$db->query("UPDATE {$tablepre}players SET clbpara='$encoded_clbpara' WHERE pid='$pid'");
```
3. 在 FireseedEnhance 函数中添加:
```php
// 将更新后的 clbpara 保存到数据库
$encoded_clbpara = json_encode($clbpara, JSON_UNESCAPED_UNICODE);
$db->query("UPDATE {$tablepre}players SET clbpara='$encoded_clbpara' WHERE pid='$pid'");
```
## 优势
1. 种火的位置信息会正确保存到数据库中,不会在页面刷新后丢失
2. 种火的探物和索敌功能能够正常工作,因为种火的位置信息已经正确保存
3. 种火的强化信息也会正确保存到数据库中
## 注意事项
- 这个修复不会影响其他功能,只是修复了种火相关功能的数据保存问题
- 使用 json_encode($clbpara, JSON_UNESCAPED_UNICODE) 的方式保存 clbpara 数据,与系统其他部分的处理方式保持一致
# NPC技能实装:洁净(npc_purity)
## 功能概述
实现了一个专为NPC设计的技能:
- **洁净(npc_purity)**:被动技,战斗时无法获得经验值。
## 实装内容
1. 在 `gamedata/cache/clubskills_1.php` 文件中添加了 `npc_purity` 技能的定义
2. 在 `include/state.func.php` 文件中修改了 `expup_rev` 函数,使其检查是否有 `npc_purity` 技能
## 实装细节
### 1. 技能定义
在 `clubskills_1.php` 文件中添加了以下技能定义:
```php
'npc_purity' => Array
(
'name' => '洁净',
'tags' => Array('passive'),
'desc' => '战斗时无法获得经验值。',
),
```
### 2. 经验值获取逻辑修改
在 `state.func.php` 文件的 `expup_rev` 函数中添加了对 `npc_purity` 技能的检查:
```php
# 「洁净」技能判定:战斗时无法获得经验值
if(!empty($pa['clbpara']['skill']) && in_array('npc_purity', $pa['clbpara']['skill']))
{
$log.='<span class="yellow">「洁净」使'.$pa['nm'].'无法获得经验值!</span><br>';
return;
}
```
## 使用方法
### 为NPC添加洁净技能
```php
$npc['clbpara']['skill'][] = 'npc_purity';
```
## 注意事项
1. 这个技能专为NPC设计,玩家不应该获得这个技能
2. 技能会在战斗中完全阻止经验值获取,包括通过「反思」技能或「解构」技能获得的经验值
3. 技能效果会在战斗日志中显示提示信息
# 种火部署位置修复记录
## 问题描述
在选择部署位置时,无论选择了什么位置,什么操作,实际上都只会将种火部署到玩家的目前位置而非选择的位置。
## 问题原因
1. 在 slidingpanel.htm 中的 deployFireseed 函数中,只有当部署模式不是跟随模式(mode != 0)时,才会将位置参数添加到表单数据中。
2. 在 club22.func.php 中的 FireseedDeploy 函数中,当模式不是跟随模式时,没有正确使用传入的 pls 参数。
## 修复方法
1. 修改 slidingpanel.htm 中的 deployFireseed 函数,无论什么模式都添加位置字段。
2. 修改 club22.func.php 中的 FireseedDeploy 函数,确保在非跟随模式下正确使用传入的位置参数。
3. 在 command.php 中添加调试信息,显示部署位置参数。
## 修改文件
1. templates/default/slidingpanel.htm - 修改 deployFireseed 函数
2. include/game/club22.func.php - 修改 FireseedDeploy 函数
3. command.php - 添加调试信息
## 修改详情
1. 在 slidingpanel.htm 中修改 deployFireseed 函数:
```javascript
// 无论什么模式,都添加位置字段
formData.append('deploy_pls', deployPls);
```
2. 在 club22.func.php 中修改 FireseedDeploy 函数:
```php
// 确保使用传入的位置参数,而不是玩家当前位置
$pls = intval($pls);
```
3. 在 command.php 中添加调试信息:
```php
$log .= "<span class='yellow'>DEBUG: 部署位置 $deploy_pls</span><br>";
```
## 优势
1. 种火部署后会正确移动到选择的位置,使得探物和索敌功能能够正常工作
2. 修复了种火部署位置不正确的问题
3. 添加了调试信息,方便排查问题
## 注意事项
- 这个修复不会影响其他功能,只是修复了种火部署位置不正确的问题
- 调试信息可以在确认问题解决后移除
# 种火部署位置修复记录(第二次)
## 问题描述
在选择部署位置时,无论选择了什么位置,什么操作,实际上都只会将种火部署到玩家的目前位置而非选择的位置。第一次修复没有解决问题。
## 问题原因
在 club22.func.php 中的 FireseedDeploy 函数中,如果部署模式是跟随模式(mode == 0),位置会被强制设置为玩家当前位置:
```php
// 如果是跟随模式,位置设为玩家当前位置
if($mode == 0) {
$pls = $data['pls'];
} else {
// 检查位置是否有效(不是禁区或隐藏地图)
if(in_array($pls, $deepzones) || $pls < 0 || $pls >= 100) {
$log .= "<span class='red'>无法部署到指定位置!</span><br>";
return false;
}
// 确保使用传入的位置参数,而不是玩家当前位置
$pls = intval($pls);
}
```
## 修复方法
修改 club22.func.php 中的 FireseedDeploy 函数,使其在跟随模式下也使用传入的位置参数:
```php
// 确保使用传入的位置参数,而不是玩家当前位置
$pls = intval($pls);
// 检查位置是否有效(不是禁区或隐藏地图)
if(in_array($pls, $deepzones) || $pls < 0 || $pls >= 100) {
$log .= "<span class='red'>无法部署到指定位置!</span><br>";
return false;
}
// 如果是跟随模式,记录一下但仍然使用传入的位置
if($mode == 0) {
$log .= "<span class='yellow'>DEBUG: 跟随模式,部署位置 $pls</span><br>";
}
```
同时,修复了 FireseedBuffBonus 函数中的一个未使用变量警告:
```php
// 计算跟随模式的种火加成
foreach($clbpara['fireseed'] as $fs_id => $fs_data) {
```
改为:
```php
// 计算跟随模式的种火加成
foreach($clbpara['fireseed'] as $fs_data) {
```
## 修改文件
1. include/game/club22.func.php - 修改 FireseedDeploy 函数和 FireseedBuffBonus 函数
## 优势
1. 种火部署后会正确移动到选择的位置,使得探物和索敌功能能够正常工作
2. 修复了种火部署位置不正确的问题
3. 修复了未使用变量警告
## 注意事项
- 这个修复不会影响其他功能,只是修复了种火部署位置不正确的问题
- 调试信息可以在确认问题解决后移除
# 种火部署位置修复记录(第三次)
## 问题描述
在选择部署位置时,无论选择了什么位置,什么操作,实际上都只会将种火部署到玩家的目前位置而非选择的位置。前两次修复没有解决问题。
## 问题原因
1. 部署种火的逻辑顺序不正确,应该先更新NPC的位置,再更新玩家的clbpara中种火的位置。
2. 种火的动作使用的是mode,但实际上为了防止和其他NPC相关功能冲突,应该使用pose。
## 修复方法
1. 修改部署种火的逻辑顺序,先更新NPC的位置和姿态,再更新玩家的clbpara中种火的位置。
2. 将种火的动作从mode改为pose,对应数值如下:
- 跟随:1(作战姿态)
- 探物:3(探物姿态)
- 索敌:2(强袭姿态)
- 隐藏:4(偷袭姿态)
3. 修改FireseedSearch、FireseedDrainNPC和FireseedBuffBonus函数,使其使用pose而不是mode来判断种火的动作。
## 修改文件
1. include/game/club22.func.php - 修改FireseedDeploy、FireseedSearch、FireseedDrainNPC和FireseedBuffBonus函数
## 修改详情
1. 在FireseedDeploy函数中:
```php
// 将模式转换为姿态值
$pose_map = array(
0 => 1, // 跟随 -> 作战姿态
1 => 3, // 探物 -> 探物姿态
2 => 2, // 索敌 -> 强袭姿态
3 => 4 // 隐藏 -> 偷袭姿态
);
$pose = isset($pose_map[$mode]) ? $pose_map[$mode] : 1;
// 先更新NPC的位置和姿态
$result = $db->query("SELECT * FROM {$tablepre}players WHERE pid='$fireseed_id'");
if($db->num_rows($result) > 0) {
$db->query("UPDATE {$tablepre}players SET pls='$pls', pose='$pose' WHERE pid='$fireseed_id'");
$log .= "<span class='yellow'>DEBUG: 更新NPC位置 $pls 和姿态 {$poseinfo[$pose]}</span><br>";
} else {
$log .= "<span class='red'>警告:找不到对应的种火NPC!</span><br>";
}
// 再更新种火部署状态
$clbpara['fireseed'][$fireseed_id]['mode'] = $mode;
$clbpara['fireseed'][$fireseed_id]['pls'] = $pls;
$clbpara['fireseed'][$fireseed_id]['pose'] = $pose;
```
2. 在FireseedSearch函数中:
```php
// 查找在当前地图处于探物模式的种火
$search_fireseeds = array();
foreach($clbpara['fireseed'] as $fs_id => $fs_data) {
// 使用 pose 值 3 表示探物姿态
if(isset($fs_data['pose']) && $fs_data['pose'] == 3 && $fs_data['pls'] == $pls) {
$search_fireseeds[$fs_id] = $fs_data;
} else if($fs_data['mode'] == 1 && $fs_data['pls'] == $pls) {
// 兼容旧数据,如果没有 pose 字段,则使用 mode
$search_fireseeds[$fs_id] = $fs_data;
}
}
```
3. 在FireseedDrainNPC函数中:
```php
// 查找在当前地图处于索敌模式的种火
$drain_fireseeds = array();
foreach($clbpara['fireseed'] as $fs_id => $fs_data) {
// 使用 pose 值 2 表示强袭姿态(索敌)
if(isset($fs_data['pose']) && $fs_data['pose'] == 2 && $fs_data['pls'] == $pls) {
$drain_fireseeds[$fs_id] = $fs_data;
} else if($fs_data['mode'] == 2 && $fs_data['pls'] == $pls) {
// 兼容旧数据,如果没有 pose 字段,则使用 mode
$drain_fireseeds[$fs_id] = $fs_data;
}
}
```
4. 在FireseedBuffBonus函数中:
```php
// 计算跟随模式的种火加成
foreach($clbpara['fireseed'] as $fs_data) {
// 使用 pose 值 1 表示作战姿态(跟随)
if((isset($fs_data['pose']) && $fs_data['pose'] == 1 && $fs_data['pls'] == $pls) ||
($fs_data['mode'] == 0 && $fs_data['pls'] == $pls)) {
// 加成 = 数量(1) × 强化层数 × 1%
$bonus_percent = 1 * $fs_data['level'] * $fireseed_follow_bonus_rate;
$att_bonus += ceil($att * $bonus_percent / 100);
$def_bonus += ceil($def * $bonus_percent / 100);
}
}
```
## 优势
1. 种火部署后会正确移动到选择的位置,使得探物和索敌功能能够正常工作
2. 修复了种火部署位置不正确的问题
3. 使用pose而不是mode来判断种火的动作,避免和其他NPC相关功能冲突
4. 兼容旧数据,如果没有pose字段,则使用mode
## 注意事项
- 这个修复不会影响其他功能,只是修复了种火部署位置不正确的问题
- 调试信息可以在确认问题解决后移除
# 侧边栏(Sliding Panel)功能改进记录
## 修改内容
1. **优化数据更新逻辑**
- 移除了定时更新 clbpara 数据的功能,改为只在打开侧边栏或点击更新按钮时更新
- 这样可以减少不必要的网络请求和资源消耗
2. **种火信息显示改进**
- 在种火信息表格中添加了 ID 列,显示种火的 NPC ID
- 在所有种火选择下拉框中添加了 ID 信息,方便玩家识别不同的种火
- 修复了种火信息表格中的 colspan 值,确保空行显示正确
3. **修复种火物品列表中的空行问题**
- 增加了对 item.itm 是否为 undefined 的检查,防止显示空行
- 这解决了截图中显示的 undefined/undefined 问题
## 修改文件
- templates/default/slidingpanel.htm
## 具体修改
1. 在种火状态表格中添加 ID 列:
```html
<tr>
<th>名称</th>
<th>等级</th>
<th>状态</th>
<th>位置</th>
<th>生命</th>
<th>体力</th>
<th>攻击</th>
<th>防御</th>
<th>ID</th>
</tr>
```
2. 在种火信息行中添加 ID 列:
```html
<td><span class="lime">$fs_id</span></td>
```
3. 修改空行的 colspan 值:
```html
<td colspan="9">你还没有收纳任何种火。</td>
```
4. 在种火选择下拉框中添加 ID 信息:
```html
<option value="$fs_id">$fs_data['name'] (等级: $fs_data['level'], ID: $fs_id)</option>
```
5. 移除定时更新,只在打开面板和点击更新按钮时更新:
```javascript
// 初始化面板
initPanel();
// 初始更新进度条(仅一次)
updateChargeProgressBars();
```
6. 修改 updateFireseedStatusTable 函数,修复空行问题并添加 ID 列:
```javascript
// 如果没有种火数据,显示提示行
if (!clbpara.fireseed || Object.keys(clbpara.fireseed).length === 0) {
const row = statusTable.insertRow();
const cell = row.insertCell();
cell.colSpan = 9; // 更新为9列
cell.textContent = '你还没有收纳任何种火。';
return;
}
```
7. 在动态生成的种火信息行中添加 ID 列:
```javascript
// ID
const idCell = row.insertCell();
const idSpan = document.createElement('span');
idSpan.className = 'lime';
idSpan.textContent = fsId;
idCell.appendChild(idSpan);
```
8. 在动态生成的种火选择下拉框中添加 ID 信息:
```javascript
option.textContent = fsData.name + ' (等级: ' + fsData.level + ', ID: ' + fsId + ')';
```
9. 修复种火物品列表中的空行问题:
```javascript
// 添加物品行
for (let itemId = 0; itemId < fsData.items.length; itemId++) {
const item = fsData.items[itemId];
if (!item || item.itm === undefined) continue;
// ...
}
```
## 优势
1. 减少了不必要的网络请求和资源消耗
2. 提供了更多的种火信息,方便玩家识别不同的种火
3. 修复了种火物品列表中的空行问题
4. 保持了与原有功能的兼容性
# 侧边栏(Sliding Panel)undefined 行问题修复记录
## 问题描述
在种火状态表格中,出现了显示为 "undefined/undefined" 的行,同时 ID 列显示为 "toJSONString"。这表明 clbpara.fireseed 对象中包含了无效的条目,导致显示了错误的数据。
## 修复内容
1. **修复种火状态表格中的 undefined 行问题**
- 在遍历 clbpara.fireseed 对象时,添加了对无效数据的检查和过滤
- 跳过非对象类型的条目或缺少必要属性(name、level)的数据
- 在控制台输出调试信息,帮助识别问题数据
2. **修复种火选择下拉框中的无效选项**
- 在生成种火选择下拉框选项时,添加了对无效数据的检查和过滤
- 确保只有有效的种火数据才会被添加到选择框中
3. **修复种火物品列表中的无效条目**
- 在生成种火物品列表时,添加了对无效数据的检查和过滤
- 确保只有有效的种火数据才会被处理
4. **修复首个种火物品列表的显示逻辑**
- 修改了首个种火物品列表的获取方式,确保只使用有效的种火 ID
- 创建了一个有效种火 ID 的数组,从中选择第一个进行显示
## 修改文件
- templates/default/slidingpanel.htm
## 具体修改
1. 在 updateFireseedStatusTable 函数中添加对无效数据的检查:
```javascript
// 添加种火数据行
for (const fsId in clbpara.fireseed) {
// 跳过非对象类型的条目或无效数据
if (!clbpara.fireseed[fsId] || typeof clbpara.fireseed[fsId] !== 'object' ||
!clbpara.fireseed[fsId].name || !clbpara.fireseed[fsId].level) {
console.log('跳过无效种火数据:', fsId, clbpara.fireseed[fsId]);
continue;
}
const fsData = clbpara.fireseed[fsId];
// ... 后续代码 ...
}
```
2. 在 updateFireseedSelects 函数中添加对无效数据的检查:
```javascript
// 添加种火选项
for (const fsId in clbpara.fireseed) {
// 跳过非对象类型的条目或无效数据
if (!clbpara.fireseed[fsId] || typeof clbpara.fireseed[fsId] !== 'object' ||
!clbpara.fireseed[fsId].name || !clbpara.fireseed[fsId].level) {
console.log('跳过无效种火数据(选择框):', fsId, clbpara.fireseed[fsId]);
continue;
}
const fsData = clbpara.fireseed[fsId];
// ... 后续代码 ...
}
```
3. 在 updateFireseedItemsList 函数中添加对无效数据的检查:
```javascript
// 为每个种火创建物品列表
for (const fsId in clbpara.fireseed) {
// 跳过非对象类型的条目或无效数据
if (!clbpara.fireseed[fsId] || typeof clbpara.fireseed[fsId] !== 'object' ||
!clbpara.fireseed[fsId].name || !clbpara.fireseed[fsId].level) {
console.log('跳过无效种火数据(物品列表):', fsId, clbpara.fireseed[fsId]);
continue;
}
const fsData = clbpara.fireseed[fsId];
// ... 后续代码 ...
}
```
4. 修改首个种火物品列表的显示逻辑:
```javascript
// 显示第一个有效种火的物品列表
let validFireseeds = [];
for (const fsId in clbpara.fireseed) {
if (clbpara.fireseed[fsId] && typeof clbpara.fireseed[fsId] === 'object' &&
clbpara.fireseed[fsId].name && clbpara.fireseed[fsId].level) {
validFireseeds.push(fsId);
}
}
if (validFireseeds.length > 0) {
const firstFsId = validFireseeds[0];
const firstItemsList = document.getElementById('fireseed-items-' + firstFsId);
if (firstItemsList) {
firstItemsList.style.display = 'block';
}
}
```
## 优势
1. 解决了种火状态表格中显示 undefined 行的问题
2. 提高了代码的健壮性,能够处理无效的数据
3. 添加了调试信息,方便开发者识别和解决问题
4. 保持了与原有功能的兼容性
# 侧边栏(Sliding Panel)种火物品显示优化记录
## 问题描述
在种火物品列表中,物品类型和特殊属性栏位显示的是原始数据(如 "HH"、"f"),而不是对应的可读文本(如 "生命恢复"、"灼焰")。这使得玩家难以理解物品的实际功能。
## 修复内容
1. **优化物品类型显示**
- 修改了物品类型的显示逻辑,使其显示 resources_1.php 中 $iteminfo 数组对应的可读文本
- 例如,将 "HH" 显示为 "生命恢复","DA" 显示为 "手臂装备"
2. **优化物品特殊属性显示**
- 修改了物品特殊属性的显示逻辑,使其显示 resources_1.php 中 $itemspkinfo 数组对应的可读文本
- 对于多个特殊属性,会将它们以逗号分隔显示
- 例如,将 "f" 显示为 "灼焰","fu" 显示为 "灼焰, 火焰"
3. **添加数据传递**
- 在页面加载时,将 PHP 中的 $iteminfo 和 $itemspkinfo 数组传递给 JavaScript
- 这样 JavaScript 可以使用这些数据来显示可读的物品信息
## 修改文件
- templates/default/slidingpanel.htm
## 具体修改
1. 在页面顶部添加 iteminfo 和 itemspkinfo 数据:
```html
<!--{eval echo "<script>var clbpara_data = ".json_encode($clbpara).";</script>";}-->
<!--{eval echo "<script>var iteminfo = ".json_encode($iteminfo).";</script>";}-->
<!--{eval echo "<script>var itemspkinfo = ".json_encode($itemspkinfo).";</script>";}-->
```
2. 修改物品类型的显示逻辑:
```javascript
// 类型
const typeCell = row.insertCell();
// 使用iteminfo显示物品类型
if (typeof window.iteminfo !== 'undefined' && window.iteminfo[item.itmk]) {
typeCell.textContent = window.iteminfo[item.itmk];
} else {
typeCell.textContent = item.itmk;
}
```
3. 修改物品特殊属性的显示逻辑:
```javascript
// 特殊
const specialCell = row.insertCell();
// 使用itemspkinfo显示物品特殊属性
if (item.itmsk && item.itmsk !== '--') {
if (typeof window.itemspkinfo !== 'undefined') {
let spkText = '';
// 遍历每个特殊属性字符
for (let i = 0; i < item.itmsk.length; i++) {
const spk = item.itmsk[i];
if (window.itemspkinfo[spk]) {
if (spkText) spkText += ', ';
spkText += window.itemspkinfo[spk];
} else {
if (spkText) spkText += ', ';
spkText += spk;
}
}
specialCell.innerHTML = spkText;
} else {
specialCell.textContent = item.itmsk;
}
} else {
specialCell.textContent = '--';
}
```
## 优势
1. 提高了种火物品列表的可读性,使玩家能够更容易理解物品的功能
2. 保持了与游戏其他部分的一致性,使用相同的物品类型和特殊属性描述
3. 代码具有健壮性,能够处理未定义的物品类型和特殊属性
4. 保持了与原有功能的兼容性
# 种火部署位置问题修复记录
## 问题描述
在对 club22.func.php 进行修改解决种火无法部署到选择的位置的问题后,引入了一个新的问题:只有玩家处于和正在部署的种火相同的位置时,该位置的索敌与探物动作才会处理。根据设计,不管玩家本人在哪个位置,全部位置的种火的索敌与探物动作都应该处理。
## 修复内容
1. **修改 FireseedSearch 函数**
- 移除了对玩家当前位置的限制,使其能够处理所有位置的种火探物动作
- 按位置分组处理种火,对每个位置分别执行探物逻辑
- 在日志中显示种火探物的位置信息,方便玩家了解种火在哪个位置发现了物品
2. **修改 FireseedDrainNPC 函数**
- 移除了对玩家当前位置的限制,使其能够处理所有位置的种火索敌动作
- 按位置分组处理种火,对每个位置分别执行索敌逻辑
- 在日志中显示种火索敌的位置信息,方便玩家了解种火在哪个位置削弱了NPC
3. **保留 FireseedBuffBonus 函数的位置限制**
- 对于战斗加成,仍然只考虑与玩家在同一位置的种火,因为这是战斗相关的功能
- 添加了注释说明这一设计决策
4. **移除调试输出**
- 删除了 FireseedDeploy 函数中的 `echo $fspls;` 调试输出
## 修改文件
- include/game/club22.func.php
## 具体修改
1. 修改 FireseedSearch 函数,使其处理所有位置的种火:
```php
// 查找所有处于探物模式的种火,不限制地图位置
$search_fireseeds = array();
foreach($clbpara['fireseed'] as $fs_id => $fs_data) {
// 使用 pose 值 3 表示探物姿态
if(isset($fs_data['pose']) && $fs_data['pose'] == 3) {
$search_fireseeds[$fs_id] = $fs_data;
} else if($fs_data['mode'] == 1) {
// 兼容旧数据,如果没有 pose 字段,则使用 mode
$search_fireseeds[$fs_id] = $fs_data;
}
}
// 按位置分组处理种火
$fireseeds_by_location = array();
foreach($search_fireseeds as $fs_id => $fs_data) {
$location = $fs_data['pls'];
if(!isset($fireseeds_by_location[$location])) {
$fireseeds_by_location[$location] = array();
}
$fireseeds_by_location[$location][$fs_id] = $fs_data;
}
// 对每个位置分别处理
foreach($fireseeds_by_location as $location => $location_fireseeds) {
// 获取该位置的物品
$result = $db->query("SELECT * FROM {$tablepre}mapitem WHERE pls='$location' LIMIT 1");
if(!$db->num_rows($result)) {
continue; // 该位置没有物品,继续检查下一个位置
}
// ... 处理该位置的种火探物逻辑 ...
}
```
2. 修改 FireseedDrainNPC 函数,使其处理所有位置的种火:
```php
// 查找所有处于索敌模式的种火,不限制地图位置
$drain_fireseeds = array();
foreach($clbpara['fireseed'] as $fs_id => $fs_data) {
// 使用 pose 值 2 表示强袭姿态(索敌)
if(isset($fs_data['pose']) && $fs_data['pose'] == 2) {
$drain_fireseeds[$fs_id] = $fs_data;
} else if($fs_data['mode'] == 2) {
// 兼容旧数据,如果没有 pose 字段,则使用 mode
$drain_fireseeds[$fs_id] = $fs_data;
}
}
// 按位置分组处理种火
$fireseeds_by_location = array();
foreach($drain_fireseeds as $fs_id => $fs_data) {
$location = $fs_data['pls'];
if(!isset($fireseeds_by_location[$location])) {
$fireseeds_by_location[$location] = array();
}
$fireseeds_by_location[$location][$fs_id] = $fs_data;
}
// 对每个位置分别处理
foreach($fireseeds_by_location as $location => $location_fireseeds) {
// 获取该位置的NPC
$result = $db->query("SELECT * FROM {$tablepre}players WHERE type>0 AND hp>1 AND pls='$location'");
if(!$db->num_rows($result)) {
continue; // 该位置没有NPC,继续检查下一个位置
}
// ... 处理该位置的种火索敌逻辑 ...
}
```
3. 在日志中添加位置信息:
```php
$log .= "<span class='lime'>你的种火「{$clbpara['fireseed'][$finder_id]['name']}」在「{$plsinfo[$location]}」发现了物品「{$item_data['itm']}」!</span><br>";
$log .= "<span class='lime'>你的种火「{$clbpara['fireseed'][$drainer_id]['name']}」在「{$plsinfo[$location]}」削弱了「{$npc['name']}」,造成了{$drain_amount}点伤害!</span><br>";
```
## 优势
1. 修复了种火无法在玩家不在场的位置执行索敌和探物动作的问题
2. 保持了设计的一致性,使种火能够在不同位置独立工作
3. 通过在日志中添加位置信息,提高了用户体验,使玩家能够更好地了解种火的活动
4. 代码结构更加清晰,按位置分组处理种火,提高了代码的可维护性
# 种火跟随功能实现记录
## 功能描述
实现种火跟随功能,使玩家每次移动时,所有处于跟随状态的种火也会一并移动到目标位置,并输出提示。
## 实现内容
1. **新增 FireseedFollow 函数**
- 在 include/game/club22.func.php 中添加了 FireseedFollow 函数
- 该函数接收目标位置 ID 作为参数
- 查找所有处于跟随模式的种火(pose=1 或 mode=0)
- 将这些种火的位置更新为玩家的目标位置
- 同时更新数据库中的种火位置和玩家 clbpara 中的种火位置
- 显示移动提示,告知玩家有多少个种火随行
2. **修改 move 函数**
- 在 include/game/search.func.php 的 move 函数中调用 FireseedFollow 函数
- 确保在玩家移动后,所有跟随状态的种火也会移动到相同位置
## 具体实现
1. FireseedFollow 函数实现:
```php
/**
* 玩家移动时,将所有处于跟随状态的种火一并移动到目标位置
*
* @param int $target_pls 目标位置ID
* @return void
*/
function FireseedFollow($target_pls) {
global $log, $db, $tablepre, $plsinfo;
if(!isset($data)) {
global $pdata;
$data = &$pdata;
}
extract($data, EXTR_REFS);
// 检查是否有种火
if(empty($clbpara['fireseed'])) {
return;
}
// 查找所有处于跟随模式的种火
$follow_fireseeds = array();
foreach($clbpara['fireseed'] as $fs_id => $fs_data) {
// 使用 pose 值 1 表示作战姿态(跟随)
if((isset($fs_data['pose']) && $fs_data['pose'] == 1) ||
($fs_data['mode'] == 0)) {
$follow_fireseeds[$fs_id] = $fs_data;
}
}
if(empty($follow_fireseeds)) {
return;
}
// 移动所有跟随种火到目标位置
$moved_count = 0;
foreach($follow_fireseeds as $fs_id => $fs_data) {
// 如果种火已经在目标位置,则跳过
if($fs_data['pls'] == $target_pls) {
continue;
}
// 更新数据库中的种火位置
$db->query("UPDATE {$tablepre}players SET pls='$target_pls' WHERE pid='$fs_id'");
// 更新clbpara中的种火位置
$clbpara['fireseed'][$fs_id]['pls'] = $target_pls;
$moved_count++;
}
// 如果有种火被移动,则更新clbpara并显示提示
if($moved_count > 0) {
// 将更新后的 clbpara 保存到数据库
$encoded_clbpara = json_encode($clbpara, JSON_UNESCAPED_UNICODE);
$db->query("UPDATE {$tablepre}players SET clbpara='$encoded_clbpara' WHERE pid='$pid'");
// 显示提示
$log .= "<span class='lime'>{$moved_count}个跟随状态的种火随你一起移动到了「{$plsinfo[$target_pls]}」。</span><br>";
}
}
```
2. 在 move 函数中调用 FireseedFollow:
```php
# 如果是种火歌者,处理种火相关逻辑
if($club == 22) {
include_once GAME_ROOT.'./include/game/club22.func.php';
// 移动跟随状态的种火
FireseedFollow($pls);
// 处理探物和索敌逻辑
FireseedSearch($pls);
FireseedDrainNPC($pls);
}
```
## 优势
1. 实现了种火跟随功能,使玩家移动时,跟随状态的种火也会一并移动
2. 保持了与原有功能的兼容性,不影响其他种火功能
3. 提供了清晰的提示,让玩家知道有多少种火随行
4. 代码结构清晰,易于维护和扩展
# 枫火歌者"种火管理"按钮修复记录
## 问题描述
点击界面上的"种火管理"按钮时没有作用,控制台输出以下错误:
```
Uncaught TypeError: Cannot read properties of null (reading 'showModal')
at showModalDialog (common.js:12:5)
at HTMLInputElement.onclick (game.php:1:1)
```
这是因为按钮点击事件使用了 `showModalDialog($('fireseedpage'))` 来显示模态对话框,但是 `$('fireseedpage')` 返回 null,因为找不到 ID 为 "fireseedpage" 的元素。
## 修复内容
1. **修改"种火管理"按钮的点击事件**
- 将原来的 `onclick="showModalDialog($('fireseedpage'));"` 修改为 `onclick="openSidePanelToFireseedTab();"`
- 这样点击按钮时会调用新增的 `openSidePanelToFireseedTab` 函数
2. **添加 openSidePanelToFireseedTab 函数**
- 在 slidingpanel.htm 文件末尾添加了 `openSidePanelToFireseedTab` 函数
- 该函数会打开侧边栏,切换到种火管理标签页,并更新种火数据
## 修改文件
- templates/default/command.htm
- templates/default/slidingpanel.htm
## 具体修改
1. 修改 command.htm 中的"种火管理"按钮:
```html
<input type="button" class="cmdbutton" id="fireseed_manage" name="fireseed_manage" value="种火管理" onclick="openSidePanelToFireseedTab();">
```
2. 在 slidingpanel.htm 中添加 openSidePanelToFireseedTab 函数:
```javascript
// 打开侧边栏并切换到种火管理标签页
function openSidePanelToFireseedTab() {
// 打开侧边栏
document.getElementById('sliding-panel').classList.add('open');
document.getElementById('side-panel-button').style.display = 'none';
// 切换到种火管理标签页
showTab('fireseed-tab', { target: document.querySelector('.tab-button[onclick*="fireseed-tab"]') });
// 更新种火数据
updateFireseedTab();
}
```
## 优势
1. 修复了点击"种火管理"按钮时的错误
2. 提供了更好的用户体验,点击按钮后自动打开侧边栏并切换到种火管理标签页
3. 保持了与原有功能的一致性,使用现有的侧边栏而不是创建新的模态对话框
4. 代码简洁明了,易于维护
# 枫火歌者(Club 22)实装记录
实装时间:2024年7月19日
## 实装内容
1. 配置文件:
- 在 gamedata/cache/club22cfg.php 中创建了枫火歌者社团的配置文件
- 包含收为随从的成功率、跟随时强化玩家倍率、探物检定成功率、削减NPC HP检定成功率、强化倍率等配置
2. 后端逻辑:
- 在 include/game/club22.func.php 中实现了以下功能:
- FireseedRecruit($npc):将目标种火复活,并进行收纳种火
- FireseedDeploy($npc, $mode, $pls):设置部署状态并标记姿态(探物、索敌、隐藏、跟随)
- FireseedSearch($pls):玩家行动时触发探物逻辑,将对应道具加入该种火clbpara中的道具池
- FireseedDrainNPC($pls):玩家行动时触发索敌逻辑,对NPC造成伤害(最低留1血)
- FireseedEnhance($npc, $item):消耗焰火物品,更新该种火的强化倍率
- FireseedBuffBonus():根据所有跟随种火的数量与强化层数,为玩家加成攻击防御
3. 前端逻辑:
- 修改 command.htm 中隐藏 Club 22 玩家使用的"组队"按钮并添加禁止组队判断逻辑
- 修改 corpse.htm 中加入判断,若目标尸体为"种火"(type==92)且 club == 22,便显示"收纳种火"按钮
- 在 slidingpanel.htm 中添加种火状态管理标签页
- 创建 fireseedpage.htm 提供种火管理界面
4. 战斗系统整合:
- 修改 revattr.func.php 中的 get_base_att_modifier 和 get_base_def_modifier 函数,添加种火加成逻辑
- 在 game.php 中添加种火探物和索敌的触发逻辑
5. 社团技能:
- 在 clubskills_1.php 中添加了 c22_fireseed 技能,描述枫火歌者的核心机制
## 核心机制
Club 22玩家不能进行组队,可以通过在遭遇特定NPC"种火"(type = 92)的尸体进行操作,消耗体力值将其收为"随从",纳入队伍。
种火具备四种部署状态:
- 跟随:在战斗时增加玩家攻击/防御,按"数量 × 强化层数 × 1%"叠加
- 探物:部署在地图上,为玩家收集该地的掉落物品(叠加将影响发现速率)
- 索敌:部署后稳定按照比率削减该地图NPC生命至最低1点(叠加将影响削血速率)
- 隐藏:没有额外效果(玩法上因为其他玩家会遭遇它们,有探索干扰作用)
种火可被升级,升级后将显著提升数值,通过消耗指定焰火类物品(共5种:◆焰火,✦烈焰火,★华焰火★,☾真焰火☽,☼焰火☼)来升级特定种火,倍率为:1x、8x、32x、64x、128x。
## 注意事项
1. 种火收纳后,会在种火的 clbpara 中记录所有者信息,防止被其他玩家重复收纳
2. 种火部署在地图上时,会根据部署模式执行不同的功能
3. 种火收集的物品会存储在种火的 clbpara 中,玩家可以通过界面获取这些物品
4. 种火强化后,其属性会根据强化倍率提升
5. 跟随模式的种火会在战斗中为玩家提供攻击和防御加成
# 滑动面板修复记录
修复时间:2024年7月19日
## 问题描述
在 slidingpanel.htm 文件中,种火状态表格的表头和数据行的列数不匹配,导致生成的 tpl.php 文件出现语法错误:
```
Parse error: syntax error, unexpected ')' in /volume1/web/gamedata/templates/1_slidingpanel.tpl.php on line 376
```
## 修复内容
1. 在种火状态表格中,表头只有7列(名称、等级、状态、位置、生命、攻击、防御),但数据行有8列(多了一个"体力"列)。
2. 修复方法:
- 在表头中添加了"体力"列,使表头和数据行的列数一致(都是8列)
- 将"没有收纳任何种火"提示行的 colspan 从 7 改为 8,以匹配新的列数
## 修复结果
修复后,slidingpanel.htm 文件可以正确生成 tpl.php 文件,不再出现语法错误。种火状态表格现在可以正确显示所有数据,包括种火的体力值。
# 滑动面板修复记录 2
修复时间:2024年7月19日
## 问题描述
在 slidingpanel.htm 文件中,种火强化部分的 for 循环和条件判断语法有问题,导致生成的 tpl.php 文件出现语法错误:
```
Parse error: syntax error, unexpected ')' in /volume1/web/gamedata/templates/1_slidingpanel.tpl.php on line 378
```
## 问题分析
问题出在种火强化部分的物品选择下拉框中,当检查物品是否为焰火类物品时,没有先检查变量是否存在就直接进行比较,导致在 PHP 解析时出现语法错误。
原代码:
```html
<!--{for $i=1; $i<=6; $i++}-->
<!--{if ${'itm'.$i} == '◆焰火' || ${'itm'.$i} == '✦烈焰火' || ${'itm'.$i} == '★华焰火★' || ${'itm'.$i} == '☾真焰火☽' || ${'itm'.$i} == '☼焰火☼'}-->
<option value="$i">${'itm'.$i} (效果: ${'itme'.$i}, 数量: ${'itms'.$i})</option>
<!--{/if}-->
<!--{/for}-->
```
## 修复内容
修复方法是在比较前先使用 isset() 函数检查变量是否存在:
```html
<!--{for $i=1; $i<=6; $i++}-->
<!--{if isset(${'itm'.$i}) && (${'itm'.$i} == '◆焰火' || ${'itm'.$i} == '✦烈焰火' || ${'itm'.$i} == '★华焰火★' || ${'itm'.$i} == '☾真焰火☽' || ${'itm'.$i} == '☼焰火☼')}-->
<option value="$i">${'itm'.$i} (效果: ${'itme'.$i}, 数量: ${'itms'.$i})</option>
<!--{/if}-->
<!--{/for}-->
```
## 修复结果
修复后,slidingpanel.htm 文件可以正确生成 tpl.php 文件,不再出现语法错误。种火强化部分的物品选择下拉框现在可以正确显示所有符合条件的焰火类物品。
# 滑动面板修复记录 3
修复时间:2024年7月19日
## 问题描述
在 slidingpanel.htm 文件中,种火强化部分的物品选择下拉框代码仍然存在问题,导致生成的 tpl.php 文件出现语法错误:
```
Parse error: syntax error, unexpected ')' in /volume1/web/gamedata/templates/1_slidingpanel.tpl.php on line 378
```
生成的 tpl.php 文件中的问题代码如下:
```php
{for <?php echo $i?>=1; <?php echo $i?><=6; <?php echo $i?>++}
<?php if(isset(${'itm'.$i) { ?>
) && (${'itm'.<?php echo $i?>} == '◆焰火' || ${'itm'.<?php echo $i?>} == '✦烈焰火' || ${'itm'.<?php echo $i?>} == '★华焰火★' || ${'itm'.<?php echo $i?>} == '☾真焰火☽' || ${'itm'.<?php echo $i?>} == '☼焰火☼')}
```
## 问题分析
问题出在模板引擎处理循环和变量拼接时的混淆。模板引擎在处理 for 循环和动态变量名(如 `${'itm'.$i}`)时,无法正确解析这种复杂的嵌套结构,导致生成的 PHP 代码出现语法错误。
## 修复内容
修复方法是避免使用循环和动态变量名,而是直接展开所有可能的条件判断:
```html
<!--{if isset($itm1) && ($itm1 == '◆焰火' || $itm1 == '✦烈焰火' || $itm1 == '★华焰火★' || $itm1 == '☾真焰火☽' || $itm1 == '☼焰火☼')}-->
<option value="1">$itm1 (效果: $itme1, 数量: $itms1)</option>
<!--{/if}-->
<!--{if isset($itm2) && ($itm2 == '◆焰火' || $itm2 == '✦烈焰火' || $itm2 == '★华焰火★' || $itm2 == '☾真焰火☽' || $itm2 == '☼焰火☼')}-->
<option value="2">$itm2 (效果: $itme2, 数量: $itms2)</option>
<!--{/if}-->
<!-- ... 以此类推到 itm6 -->
```
这种方式虽然代码量增加,但避免了模板引擎在处理复杂结构时的问题。
## 修复结果
修复后,slidingpanel.htm 文件可以正确生成 tpl.php 文件,不再出现语法错误。种火强化部分的物品选择下拉框现在可以正确显示所有符合条件的焰火类物品。
# 滑动面板(Sliding Panel)功能最终实装总结
日期:2024年7月19日
## 功能概述
滑动面板是一个位于游戏界面右侧的可滑动面板,用于显示玩家的任务信息和其他游戏数据。该功能的主要目的是提供一个不干扰主游戏界面的方式来查看额外信息,并为未来的任务系统和其他功能提供扩展性。
## 主要功能
1. **界面元素**:
- 屏幕右侧的"副面板"按钮
- 从右侧滑入的面板,宽度为550px
- 面板顶部的标签栏,支持多个标签页
- 面板右上角的关闭按钮
- 面板底部的"更新信息"按钮
2. **标签页**:
- **任务窗体**:显示玩家的任务信息(目前为示例数据)
- **其他信息**:显示玩家的charge1-4值,以进度条形式展示
3. **交互功能**:
- 点击"副面板"按钮打开面板,同时隐藏按钮
- 点击关闭按钮关闭面板,同时显示"副面板"按钮
- 点击面板外区域自动关闭面板
- 点击标签页切换不同的内容
- 点击"更新信息"按钮手动更新数据
4. **数据更新机制**:
- 打开面板时自动获取最新数据
- 点击"更新信息"按钮手动更新数据
- 定期自动更新数据(当面板打开时)
- 更新成功/失败时显示相应的消息提示
## 技术实现
1. **HTML结构**:
- 使用div元素创建面板和各个组件
- 使用button元素创建按钮
- 使用CSS类和ID标识不同的元素
2. **CSS样式**:
- 使用固定定位(position: fixed)将面板和按钮固定在屏幕右侧
- 使用transform和transition实现面板的滑入滑出动画
- 使用flex布局组织面板内的元素
- 使用自定义字体和颜色保持与游戏整体风格一致
3. **JavaScript功能**:
- 使用事件监听器处理按钮点击和面板交互
- 使用AJAX请求获取最新的clbpara数据
- 使用正则表达式从响应中提取数据
- 使用定时器实现定期更新和动画效果
4. **数据处理**:
- 从game.php页面获取最新的clbpara数据
- 解析JSON格式的数据
- 更新进度条和其他显示元素
- 处理可能的错误情况
## 关键文件
1. **templates/default/slidingpanel.htm**:
- 包含滑动面板的HTML结构、CSS样式和JavaScript功能
- 负责面板的显示、交互和数据更新
## 实装过程中的主要挑战与解决方案
1. **样式问题**:
- **挑战**:任务窗体内容过窄,显示不完整
- **解决方案**:增加面板宽度,优化内容区域的样式,添加文本换行和行高设置
2. **交互问题**:
- **挑战**:点击"副面板"文字时面板不会滑出,显示面板时副面板按钮仍然可见
- **解决方案**:为span元素添加事件处理器,在打开面板时隐藏按钮,关闭面板时显示按钮
3. **数据更新问题**:
- **挑战**:无法从服务器获取最新的clbpara数据
- **解决方案**:直接从game.php页面获取数据,使用更精确的正则表达式提取数据,添加错误处理机制
## 未来扩展
滑动面板的设计考虑了未来的扩展性:
1. **标签系统**:
- 支持添加更多标签页,如成就系统、统计信息等
- 标签容器支持水平滚动,可容纳更多标签
2. **内容区域**:
- 使用统一的区块设计,便于添加新的内容
- 支持不同类型的数据展示,如列表、进度条、图表等
3. **数据更新机制**:
- 可用于其他类型的数据,如玩家状态、物品信息等
- 支持实时更新,为未来的实时任务系统做准备
4. **消息提示系统**:
- 可用于显示各种类型的消息,如任务完成、成就解锁等
- 支持不同的消息类型和样式
## 结论
滑动面板功能已成功实装,提供了一个美观、实用的界面元素,用于显示玩家的任务信息和其他游戏数据。该功能的设计考虑了未来的扩展性,为游戏的后续开发提供了良好的基础。通过解决实装过程中遇到的各种挑战,我们不仅实现了预期的功能,还提高了代码的质量和可维护性。
修改日期:2024年7月19日
修改内容:完全重新设计slidingpanel.htm的外观和功能
需求概述:
1. 一般状态时,在屏幕右侧显示"副面板"按钮,点击后,该面板从屏幕右侧滑入
2. 面板上有着可切换的标签页,目前包括"任务窗体"和"其他信息"
3. 面板的右上方是关闭按钮,点击后面板滑动隐藏至屏幕外,只剩下"副面板"按钮
4. 为未来实装的新标签页预留空间
修改文件:
- templates/default/slidingpanel.htm
主要改进:
1. 整体布局改进:
- 将面板改为全高设计,从屏幕顶部到底部
- 增加面板宽度至450px,提供更宽敞的显示空间
- 添加了专门的面板头部区域,包含标签和关闭按钮
- 添加了滚动条样式,使长内容可以平滑滚动
2. 标签系统改进:
- 标签按钮放置在面板顶部,水平排列
- 添加了标签容器的水平滚动功能,支持更多标签
- 预留了标签空间,为未来添加更多标签做准备
- 优化了标签切换的视觉反馈
3. 内容区域改进:
- 统一了内容区块的样式,使用section-container包装
- 每个区块都有标题栏和内容区
- 为列表项添加了项目符号和缩进,提高可读性
- 优化了进度条的视觉效果,添加了内阴影
4. 交互体验改进:
- 添加了专门的关闭按钮,位于面板右上角
- 点击面板外区域可以自动关闭面板
- 优化了按钮的悬停效果
- 添加了滚动条样式,使其与整体设计协调
5. 代码结构改进:
- 重构了JavaScript代码,使其更加模块化
- 添加了initPanel函数,集中处理面板初始化逻辑
- 添加了isPanelOpen函数,简化状态检查
- 优化了事件处理,减少不必要的事件监听
6. 样式优化:
- 使用更现代的CSS布局技术,如flex布局
- 添加了更多的过渡效果,使界面变化更加平滑
- 统一了颜色方案,保持与游戏整体风格一致
- 优化了移动设备上的显示效果
这次重新设计使得滑动面板更加美观、功能更加清晰,并为未来的扩展做好了准备。新的设计更加符合现代UI设计标准,同时保持了游戏原有的视觉风格。
# 滑动面板(Sliding Panel)功能实装与除错总结
日期:2024年7月19日
## 功能概述
滑动面板是一个位于游戏界面右侧的可滑动面板,包含以下功能:
1. 在屏幕右侧显示"副面板"按钮,点击后面板从右侧滑入
2. 面板包含可切换的标签页,目前有"任务窗体"和"其他信息"两个标签
3. 面板右上角有关闭按钮,点击后面板滑出并隐藏
4. 面板中显示玩家的charge1-4值,以进度条形式展示
5. 面板底部有"更新信息"按钮,可手动更新面板中的数据
## 实装过程
### 1. 初始实装
- 创建了基本的滑动面板结构,包括副面板按钮、面板容器和标签页
- 实现了面板的滑入滑出动画效果
- 添加了标签页切换功能
- 添加了charge1-4进度条显示
### 2. 界面优化
- 重新设计了面板的整体布局,使其更加美观
- 增加了面板宽度,提供更宽敞的显示空间
- 优化了标签系统,支持更多标签的扩展
- 改进了内容区域的样式,使用统一的区块设计
- 优化了进度条的视觉效果
### 3. 交互优化
- 修复了点击"副面板"文字时面板不会滑出的问题
- 实现了显示面板时隐藏副面板按钮,关闭面板时显示按钮的功能
- 添加了点击面板外区域自动关闭面板的功能
- 添加了"更新信息"按钮,可手动更新面板中的数据
### 4. 数据更新机制
- 实现了从服务器获取最新clbpara数据的功能
- 添加了定期自动更新数据的功能
- 添加了手动更新数据的功能
- 添加了更新成功/失败的消息提示
## 除错过程
### 1. 样式问题修复
- 修复了任务窗体内容过窄的问题
- 统一了任务窗体和其他信息窗体的样式
- 优化了列表项的样式,添加了文本换行和行高设置
### 2. 交互问题修复
- 修复了点击"副面板"文字时面板不会滑出的问题
- 修复了显示面板时副面板按钮仍然可见的问题
### 3. 数据更新问题修复
- 最初尝试使用额外的PHP文件(get_clbpara.php)获取数据,但遇到了会话识别问题
- 修改为直接从game.php页面获取数据,解决了会话识别问题
- 修复了"Could not find clbpara_data in response"错误,使用更精确的正则表达式提取数据
- 添加了错误处理机制,在更新失败时提供友好的用户反馈
## 最终实现
1. **界面结构**:
- 屏幕右侧的"副面板"按钮
- 从右侧滑入的面板,包含标签页和关闭按钮
- 标签页包含"任务窗体"和"其他信息"两个标签
- 面板底部的"更新信息"按钮
2. **数据显示**:
- 任务窗体显示任务列表(目前为示例数据)
- 其他信息窗体显示charge1-4的进度条
- 进度条根据不同的charge值类型使用不同的颜色和显示方式
3. **交互功能**:
- 点击"副面板"按钮打开面板
- 点击关闭按钮或面板外区域关闭面板
- 点击标签页切换不同的内容
- 点击"更新信息"按钮更新数据
4. **数据更新机制**:
- 打开面板时自动获取最新数据
- 点击"更新信息"按钮手动更新数据
- 定期自动更新数据(当面板打开时)
- 更新成功/失败时显示相应的消息提示
## 未来扩展
滑动面板的设计考虑了未来的扩展性:
1. 标签系统支持添加更多标签页
2. 内容区域使用统一的区块设计,便于添加新的内容
3. 数据更新机制可用于其他类型的数据
4. 消息提示系统可用于显示各种类型的消息
这些设计为未来实装实时更新的任务记录等功能提供了良好的基础。
修改日期:2024年7月19日
问题描述:
滑动面板中的charge值不会随着玩家的行动进行实时更新,必须重新刷新整个game.php才能看到最新值。需要一种简单的方式让用户手动更新面板中的信息。
修改内容:
1. 在滑动面板底部添加了"更新信息"按钮,用于手动更新面板中的信息
2. 添加了manualUpdate函数,用于处理按钮点击事件
3. 添加了showUpdateMessage函数,用于显示更新成功的消息
4. 添加了相关的CSS样式,确保按钮与面板整体风格一致
修改文件:
- templates/default/slidingpanel.htm
修改细节:
1. 添加更新按钮HTML:
```html
<!-- 更新按钮 -->
<div class="update-button-container">
<button id="update-button" class="update-button" onclick="manualUpdate()">更新信息</button>
</div>
```
2. 添加按钮样式:
```css
/* 更新按钮样式 */
.update-button-container {
text-align: center;
padding: 15px 0;
margin-top: 10px;
border-top: 1px solid rgba(225, 124, 226, 0.2);
}
.update-button {
background-color: rgba(225, 124, 226, 0.8);
color: #fff;
border: none;
border-radius: 5px;
padding: 8px 20px;
font: bold 11pt "FusionPixel10px";
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
}
.update-button:hover {
background-color: rgba(225, 124, 226, 1);
box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);
transform: translateY(-2px);
}
.update-button:active {
transform: translateY(1px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
```
3. 添加manualUpdate函数:
```javascript
// 手动更新函数
function manualUpdate() {
// 显示加载效果
const updateButton = document.getElementById('update-button');
if (updateButton) {
updateButton.textContent = '正在更新...';
updateButton.disabled = true;
}
// 从服务器获取最新数据
fetchLatestClbpara();
// 更新显示
setTimeout(function() {
updateChargeProgressBars();
// 恢复按钮状态
if (updateButton) {
updateButton.textContent = '更新信息';
updateButton.disabled = false;
}
// 显示更新成功消息
showUpdateMessage('信息已更新');
}, 500);
}
```
4. 添加showUpdateMessage函数,用于显示更新成功的消息:
```javascript
// 显示更新消息
function showUpdateMessage(message) {
// 创建消息元素
const messageElement = document.createElement('div');
messageElement.className = 'update-message';
messageElement.textContent = message;
// 添加到面板
const panel = document.getElementById('sliding-panel');
if (panel) {
panel.appendChild(messageElement);
// 添加样式
messageElement.style.position = 'absolute';
messageElement.style.bottom = '20px';
messageElement.style.left = '50%';
messageElement.style.transform = 'translateX(-50%)';
messageElement.style.backgroundColor = 'rgba(0, 200, 0, 0.8)';
messageElement.style.color = 'white';
messageElement.style.padding = '8px 15px';
messageElement.style.borderRadius = '5px';
messageElement.style.fontWeight = 'bold';
messageElement.style.zIndex = '1002';
messageElement.style.boxShadow = '0 2px 5px rgba(0, 0, 0, 0.3)';
messageElement.style.opacity = '0';
messageElement.style.transition = 'opacity 0.3s';
// 显示消息
setTimeout(function() {
messageElement.style.opacity = '1';
}, 10);
// 延时后移除
setTimeout(function() {
messageElement.style.opacity = '0';
setTimeout(function() {
if (panel.contains(messageElement)) {
panel.removeChild(messageElement);
}
}, 300);
}, 2000);
}
}
```
这些修改提供了一种简单的方式让用户手动更新面板中的信息,而不必刷新整个页面。当用户点击"更新信息"按钮时,系统会从服务器获取最新的clbpara数据,并更新面板中的显示。同时,系统会显示一个简短的成功消息,提供良好的用户反馈。
修改日期:2024年7月19日
问题描述:
在点击"更新信息"按钮后,控制台显示错误信息:"Could not find clbpara_data in response",表明无法从响应中找到clbpara_data变量。
修改内容:
1. 修改了fetchLatestClbpara函数,使用更可靠的方法获取最新的clbpara数据
2. 重写了manualUpdate函数,直接在函数内部处理AJAX请求,而不是调用fetchLatestClbpara函数
3. 添加了handleUpdateError函数,用于处理更新失败的情况
4. 修改了showUpdateMessage函数,使其能够显示不同类型的消息(成功/错误)
修改文件:
- templates/default/slidingpanel.htm
修改细节:
1. 修改fetchLatestClbpara函数,使用更可靠的方法获取最新数据:
```javascript
// 从服务器获取最新的clbpara数据
function fetchLatestClbpara() {
// 创建XHR对象
const xhr = new XMLHttpRequest();
// 请求当前页面,以获取最新的clbpara数据
// 添加时间戳防止缓存
xhr.open('GET', 'game.php?t=' + new Date().getTime(), true);
// 处理响应
xhr.onload = function() {
if (xhr.status === 200) {
// 尝试从响应中提取clbpara_data
const responseText = xhr.responseText;
// 使用更精确的正则表达式
const scriptRegex = /var clbpara_data = ([\\s\\S]*?);/;
const match = responseText.match(scriptRegex);
if (match && match[1]) {
try {
// 尝试解析JSON
const newClbpara = JSON.parse(match[1]);
clbpara = newClbpara;
console.log('clbpara updated from page:', clbpara);
} catch (e) {
console.error('Failed to parse clbpara data:', e);
}
} else {
console.error('Could not find clbpara_data in response');
// 如果无法找到数据,尝试刷新整个页面
console.log('Attempting to refresh the page...');
setTimeout(function() {
window.location.reload();
}, 1000);
}
} else {
console.error('Failed to fetch page data:', xhr.statusText);
}
};
// 处理错误
xhr.onerror = function() {
console.error('Network error when fetching page data');
};
// 发送请求
xhr.send();
}
```
2. 重写manualUpdate函数,直接在函数内部处理AJAX请求:
```javascript
// 手动更新函数
function manualUpdate() {
// 显示加载效果
const updateButton = document.getElementById('update-button');
if (updateButton) {
updateButton.textContent = '正在更新...';
updateButton.disabled = true;
}
// 创建XHR对象
const xhr = new XMLHttpRequest();
// 请求当前页面,以获取最新的clbpara数据
// 添加时间戳防止缓存
xhr.open('GET', 'game.php?t=' + new Date().getTime(), true);
// 处理响应
xhr.onload = function() {
if (xhr.status === 200) {
// 尝试从响应中提取clbpara_data
const responseText = xhr.responseText;
// 使用更精确的正则表达式
const scriptRegex = /var clbpara_data = ([\\s\\S]*?);/;
const match = responseText.match(scriptRegex);
if (match && match[1]) {
try {
// 尝试解析JSON
const newClbpara = JSON.parse(match[1]);
clbpara = newClbpara;
console.log('clbpara updated from page:', clbpara);
// 更新显示
updateChargeProgressBars();
// 恢复按钮状态
if (updateButton) {
updateButton.textContent = '更新信息';
updateButton.disabled = false;
}
// 显示更新成功消息
showUpdateMessage('信息已更新');
} catch (e) {
console.error('Failed to parse clbpara data:', e);
handleUpdateError(updateButton);
}
} else {
console.error('Could not find clbpara_data in response');
handleUpdateError(updateButton);
}
} else {
console.error('Failed to fetch page data:', xhr.statusText);
handleUpdateError(updateButton);
}
};
// 处理错误
xhr.onerror = function() {
console.error('Network error when fetching page data');
handleUpdateError(updateButton);
};
// 发送请求
xhr.send();
}
```
3. 添加handleUpdateError函数,用于处理更新失败的情况:
```javascript
// 处理更新错误
function handleUpdateError(updateButton) {
// 恢复按钮状态
if (updateButton) {
updateButton.textContent = '更新信息';
updateButton.disabled = false;
}
// 显示错误消息
showUpdateMessage('更新失败,请刷新页面', 'error');
// 使用当前数据更新显示
updateChargeProgressBars();
}
```
4. 修改showUpdateMessage函数,使其能够显示不同类型的消息:
```javascript
// 显示更新消息
function showUpdateMessage(message, type = 'success') {
// 创建消息元素
const messageElement = document.createElement('div');
messageElement.className = 'update-message';
messageElement.textContent = message;
// 添加到面板
const panel = document.getElementById('sliding-panel');
if (panel) {
panel.appendChild(messageElement);
// 添加样式
messageElement.style.position = 'absolute';
messageElement.style.bottom = '20px';
messageElement.style.left = '50%';
messageElement.style.transform = 'translateX(-50%)';
// 根据消息类型设置颜色
if (type === 'error') {
messageElement.style.backgroundColor = 'rgba(200, 0, 0, 0.8)';
} else {
messageElement.style.backgroundColor = 'rgba(0, 200, 0, 0.8)';
}
// 其他样式...
}
}
```
这些修改解决了"Could not find clbpara_data in response"错误,使"更新信息"按钮能够正常工作。现在,当用户点击按钮时,系统会尝试从当前页面获取最新的clbpara数据,并更新面板中的显示。如果无法获取数据,系统会显示错误消息,提示用户刷新页面。
# 枫火歌者(Club 22)社团实装与修复总结
## 实装概述
枫火歌者(Club 22)是一个特殊的社团,其核心机制是收纳"种火"作为随从,而不能像其他玩家一样组队。种火具有四种部署状态(跟随、探物、索敌、隐藏),每种状态提供不同的功能。玩家可以通过消耗焰火类物品来强化种火,提升其属性和效果。
## 基础实装
### 1. 配置文件
- 在 `gamedata/cache/club22cfg.php` 中创建了枫火歌者社团的配置文件
- 包含收为随从的成功率、跟随时强化玩家倍率、探物检定成功率、削减NPC HP检定成功率、强化倍率等配置
### 2. 后端逻辑
在 `include/game/club22.func.php` 中实现了以下功能:
- **FireseedRecruit($npc)**:将目标种火复活,并进行收纳种火
- **FireseedDeploy($npc, $mode, $pls)**:设置部署状态并标记姿态(探物、索敌、隐藏、跟随)
- **FireseedSearch($pls)**:玩家行动时触发探物逻辑,将对应道具加入该种火clbpara中的道具池
- **FireseedDrainNPC($pls)**:玩家行动时触发索敌逻辑,对NPC造成伤害(最低留1血)
- **FireseedEnhance($npc, $item)**:消耗焰火物品,更新该种火的强化倍率
- **FireseedBuffBonus()**:根据所有跟随种火的数量与强化层数,为玩家加成攻击防御
- **FireseedFollow($target_pls)**:玩家移动时,将所有处于跟随状态的种火一并移动到目标位置
### 3. 前端逻辑
- 修改 `command.htm` 中隐藏 Club 22 玩家使用的"组队"按钮并添加禁止组队判断逻辑
- 修改 `corpse.htm` 中加入判断,若目标尸体为"种火"(type==92)且 club == 22,便显示"收纳种火"按钮
- 在 `slidingpanel.htm` 中添加种火状态管理标签页,提供种火管理界面
- 实现种火管理按钮,点击后自动打开侧边栏并切换到种火管理标签页
### 4. 战斗系统整合
- 修改 `revattr.func.php` 中的 `get_base_att_modifier` 和 `get_base_def_modifier` 函数,添加种火加成逻辑
- 在 `game.php` 中添加种火探物和索敌的触发逻辑
### 5. 社团技能
- 在 `clubskills_1.php` 中添加了 `c22_fireseed` 技能,描述枫火歌者的核心机制
## 种火系列技能与套装实装
### 1. 种火I/II/III技能实装
- 在 `gamedata/cache/clubskills_1.php` 文件中添加了三个技能的定义:
- 种火I(fireseed1):战斗伤害降低为75%
- 种火II(fireseed2):战斗伤害降低为50%
- 种火III(fireseed3):战斗伤害变为1
- 在 `include/game/revattr.func.php` 文件中的 `get_final_dmg_p` 函数中添加了种火I和种火II的伤害减免逻辑
- 在 `include/game/revattr.func.php` 文件中的 `get_final_dmg_fix` 函数中添加了种火III的伤害固定为1的逻辑
### 2. 种火IV技能实装
- 在 `gamedata/cache/clubskills_1.php` 文件中添加了种火IV(fireseed4)技能的定义,该技能使所有伤害变为0
- 在 `include/game/revattr.func.php` 文件中的 `get_final_dmg_p` 函数中添加了种火IV的标记设置逻辑
- 在 `include/game/revattr.func.php` 文件中的 `get_final_dmg_fix` 函数中添加了种火IV的伤害固定为0的逻辑
- 在 `include/game/item.poison.php` 文件中添加了种火IV对毒物伤害的免疫逻辑
- 在 `include/game/itemmain.func.php` 文件中添加了种火IV对陷阱伤害的免疫逻辑
### 3. 套装与技能关联实装
- 创建了新文件 `include/game/setitems.func.php`,实现了 `process_set_item_effects` 函数,用于处理套装效果
- 在 `include/game/itemmain.func.php` 文件中修改了 `reload_set_items` 和 `reload_single_set_item` 函数,调用新的套装效果处理函数
- 设置了套装与技能的对应关系:
- fs2(种火Ⅰ套装)→ fireseed1(种火I技能)
- fs3(种火Ⅱ套装)→ fireseed2(种火II技能)
- fs4(种火Ⅲ套装)→ fireseed3(种火III技能)
- fs5(种火Ⅳ套装)→ fireseed4(种火IV技能)
## 问题修复
### 1. 种火部署位置问题
**问题描述**:种火无法部署到选择的位置,总是部署到玩家当前位置。
**修复内容**:
- 修改了 `FireseedDeploy` 函数,使其使用传入的位置参数而不是玩家当前位置
- 更新了数据库中的种火位置和玩家 clbpara 中的种火位置
- 添加了位置参数验证,确保部署位置有效
### 2. 种火索敌与探物问题
**问题描述**:只有玩家处于和正在部署的种火相同的位置时,该位置的索敌与探物动作才会处理。
**修复内容**:
- 修改了 `FireseedSearch` 和 `FireseedDrainNPC` 函数,移除了对玩家当前位置的限制
- 按位置分组处理种火,对每个位置分别执行探物和索敌逻辑
- 在日志中显示种火探物和索敌的位置信息,方便玩家了解种火的活动
### 3. 种火跟随功能
**问题描述**:玩家移动时,跟随状态的种火不会自动跟随移动。
**实现内容**:
- 添加了 `FireseedFollow` 函数,在玩家移动时将所有处于跟随状态的种火一并移动到目标位置
- 在 `search.func.php` 的 `move` 函数中调用 `FireseedFollow` 函数
- 显示移动提示,告知玩家有多少个种火随行
### 4. 侧边栏种火管理按钮问题
**问题描述**:点击"种火管理"按钮时没有作用,控制台输出错误。
**修复内容**:
- 修改了 `command.htm` 中的"种火管理"按钮,使其点击时调用 `openSidePanelToFireseedTab` 函数
- 在 `slidingpanel.htm` 中添加了 `openSidePanelToFireseedTab` 函数,该函数会打开侧边栏,切换到种火管理标签页,并更新种火数据
### 5. 侧边栏种火显示问题
**问题描述**:在种火状态表格中,出现了显示为 "undefined/undefined" 的行,同时 ID 列显示为 "toJSONString"。
**修复内容**:
- 在遍历 clbpara.fireseed 对象时,添加了对无效数据的检查和过滤
- 跳过非对象类型的条目或缺少必要属性(name、level)的数据
- 在控制台输出调试信息,帮助识别问题数据
### 6. 种火物品显示问题
**问题描述**:在种火物品列表中,物品类型和特殊属性栏位显示的是原始数据(如 "HH"、"f"),而不是对应的可读文本。
**修复内容**:
- 修改了物品类型的显示逻辑,使其显示 resources_1.php 中 $iteminfo 数组对应的可读文本
- 修改了物品特殊属性的显示逻辑,使其显示 resources_1.php 中 $itemspkinfo 数组对应的可读文本
- 在页面加载时,将 PHP 中的 $iteminfo 和 $itemspkinfo 数组传递给 JavaScript
## 核心机制
1. **种火收纳**:
- Club 22玩家不能进行组队,可以通过在遭遇特定NPC"种火"(type = 92)的尸体进行操作,消耗体力值将其收为"随从",纳入队伍。
2. **种火部署**:
- 种火具备四种部署状态:
- **跟随**:在战斗时增加玩家攻击/防御,按"数量 × 强化层数 × 1%"叠加
- **探物**:部署在地图上,为玩家收集该地的掉落物品(叠加将影响发现速率)
- **索敌**:部署后稳定按照比率削减该地图NPC生命至最低1点(叠加将影响削血速率)
- **隐藏**:没有额外效果(玩法上因为其他玩家会遭遇它们,有探索干扰作用)
3. **种火强化**:
- 种火可被升级,升级后将显著提升数值
- 通过消耗指定焰火类物品(共5种:◆焰火,✦烈焰火,★华焰火★,☾真焰火☽,☼焰火☼)来升级特定种火
- 倍率为:1x、8x、32x、64x、128x
4. **种火技能**:
- 种火I(fireseed1):战斗伤害降低为75%
- 种火II(fireseed2):战斗伤害降低为50%
- 种火III(fireseed3):战斗伤害变为1
- 种火IV(fireseed4):所有伤害变为0
5. **套装效果**:
- fs2(种火Ⅰ套装)→ fireseed1(种火I技能)
- fs3(种火Ⅱ套装)→ fireseed2(种火II技能)
- fs4(种火Ⅲ套装)→ fireseed3(种火III技能)
- fs5(种火Ⅳ套装)→ fireseed4(种火IV技能)
## 注意事项
1. 种火收纳后,会在种火的 clbpara 中记录所有者信息,防止被其他玩家重复收纳
2. 种火部署在地图上时,会根据部署模式执行不同的功能
3. 种火收集的物品会存储在种火的 clbpara 中,玩家可以通过界面获取这些物品
4. 种火强化后,其属性会根据强化倍率提升
5. 跟随模式的种火会在战斗中为玩家提供攻击和防御加成
6. 玩家移动时,所有处于跟随状态的种火会自动跟随移动
7. 种火技能可以通过学习或装备对应套装获得,提供不同程度的伤害减免
## 未来可能的改进
1. **技能来源标记**:可以在 `clbpara` 中添加标记,区分技能是通过学习获得还是通过套装获得,这样可以更精确地控制技能的移除
2. **UI提示优化**:可以优化技能获得和失去时的UI提示,使其更加明显和信息丰富
3. **技能效果扩展**:可以为种火系列技能添加更多效果,如反伤、状态免疫等,进一步丰富技能系统
4. **套装效果扩展**:可以为其他套装添加类似的技能激活效果,创建更多有趣的套装-技能组合
5. **种火AI优化**:可以为种火添加更智能的AI,使其在探物和索敌时有更多的策略性选择
6. **种火交互扩展**:可以添加更多种火之间的交互,如合并、分裂、交换物品等功能
# 种火系列技能与套装实装总结
## 实装内容概述
本次实装了四个种火系列技能(fireseed1-4)以及它们与对应套装(fs2-fs5)的关联。种火系列技能提供不同程度的伤害减免效果,从降低战斗伤害到完全免疫所有伤害。
## 实装步骤
### 1. 种火I/II/III技能实装
1. 在 `gamedata/cache/clubskills_1.php` 文件中添加了三个技能的定义:
- 种火I(fireseed1):战斗伤害降低为75%
- 种火II(fireseed2):战斗伤害降低为50%
- 种火III(fireseed3):战斗伤害变为1
2. 在 `include/game/revattr.func.php` 文件中的 `get_final_dmg_p` 函数中添加了种火I和种火II的伤害减免逻辑
3. 在 `include/game/revattr.func.php` 文件中的 `get_final_dmg_fix` 函数中添加了种火III的伤害固定为1的逻辑
### 2. 种火IV技能实装
1. 在 `gamedata/cache/clubskills_1.php` 文件中添加了种火IV(fireseed4)技能的定义,该技能使所有伤害变为0
2. 在 `include/game/revattr.func.php` 文件中的 `get_final_dmg_p` 函数中添加了种火IV的标记设置逻辑
3. 在 `include/game/revattr.func.php` 文件中的 `get_final_dmg_fix` 函数中添加了种火IV的伤害固定为0的逻辑
4. 在 `include/game/item.poison.php` 文件中添加了种火IV对毒物伤害的免疫逻辑
5. 在 `include/game/itemmain.func.php` 文件中添加了种火IV对陷阱伤害的免疫逻辑
### 3. 套装与技能关联实装
1. 创建了新文件 `include/game/setitems.func.php`,实现了 `process_set_item_effects` 函数,用于处理套装效果
2. 在 `include/game/itemmain.func.php` 文件中修改了 `reload_set_items` 和 `reload_single_set_item` 函数,调用新的套装效果处理函数
3. 设置了套装与技能的对应关系:
- fs2(种火Ⅰ套装)→ fireseed1(种火I技能)
- fs3(种火Ⅱ套装)→ fireseed2(种火II技能)
- fs4(种火Ⅲ套装)→ fireseed3(种火III技能)
- fs5(种火Ⅳ套装)→ fireseed4(种火IV技能)
## 除错过程
### 1. 套装效果不生效问题
**问题描述**:在玩家装备或移除物品时,未出现获得或失去技能的提示,也并没有获得或失去技能。
**问题原因**:问题出在 `setitems.func.php` 文件中使用 `check_skill_unlock` 函数的方式上。这个函数不仅检查玩家是否拥有技能,还会检查技能是否可用(是否解锁),这导致了即使玩家没有技能,函数也可能返回非零值(表示技能未解锁),从而导致条件判断失败。
**解决方案**:
1. 修改了 `setitems.func.php` 文件中的条件判断逻辑,不再使用 `check_skill_unlock` 函数,而是直接检查玩家的 `clbpara['skill']` 数组中是否包含对应的技能
2. 对于获得技能的条件,改为检查 `empty($pa['clbpara']['skill']) || !in_array('fireseed1', $pa['clbpara']['skill'])`
3. 对于失去技能的条件,改为检查 `!empty($pa['clbpara']['skill']) && in_array('fireseed1', $pa['clbpara']['skill'])`
### 2. 种火IV陷阱伤害免疫问题
**问题描述**:在种火IV生效时,踩到陷阱仍然正常受到了伤害,而该伤害应该下降为0。
**问题原因**:问题出在 `itemmain.func.php` 文件中的陷阱伤害计算逻辑。原来的代码先计算陷阱伤害,然后再检查种火IV技能,这导致在某些情况下,种火IV的效果没有正确应用。
**解决方案**:
1. 修改了 `itemmain.func.php` 文件中的陷阱伤害计算逻辑,将种火IV的检查移到了伤害计算之前
2. 使用了 `if-else` 结构,确保当种火IV技能存在时,直接将伤害设为0,不再进行后续的伤害计算
3. 改进了检查种火IV技能的方式,不再使用 `check_skill_unlock` 函数,而是直接检查玩家的 `clbpara['skill']` 数组中是否包含 'fireseed4'
## 实装特点
1. **渐进式伤害减免**:种火系列技能提供了从75%、50%、1到0的渐进式伤害减免,玩家可以根据需要选择不同级别的保护
2. **全面伤害免疫**:种火IV技能提供了对所有类型伤害(包括战斗、陷阱、毒物等)的完全免疫,是一个非常强大的防御技能
3. **套装激活机制**:通过套装激活技能的机制,玩家可以通过收集和装备特定套装来获得对应的种火技能,增加了游戏的收集和策略元素
4. **技能与套装分离**:玩家可以通过学习直接获得种火技能,也可以通过装备套装获得,两种方式互不干扰,增加了游戏的灵活性
## 代码实现要点
1. **伤害计算流程**:种火技能的实现涉及到游戏的伤害计算流程,需要在适当的位置插入伤害修正逻辑
2. **技能检查方式**:在实现过程中,发现直接检查技能数组比使用 `check_skill_unlock` 函数更可靠,特别是在套装效果和陷阱伤害计算中
3. **优先级处理**:种火系列技能之间有优先级关系,种火IV > 种火III > 种火II > 种火I,这通过条件判断的顺序来实现
4. **套装效果处理**:套装效果的处理需要在装备和卸下物品时触发,通过修改 `reload_set_items` 和 `reload_single_set_item` 函数实现
## 未来可能的改进
1. **技能来源标记**:可以在 `clbpara` 中添加标记,区分技能是通过学习获得还是通过套装获得,这样可以更精确地控制技能的移除
2. **UI提示优化**:可以优化技能获得和失去时的UI提示,使其更加明显和信息丰富
3. **技能效果扩展**:可以为种火系列技能添加更多效果,如反伤、状态免疫等,进一步丰富技能系统
4. **套装效果扩展**:可以为其他套装添加类似的技能激活效果,创建更多有趣的套装-技能组合
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment